当前位置: 首页 > news >正文

第12讲、Odoo 18 权限控制机制详解

目录

  1. 引言
  2. 权限机制概述
  3. 权限组(Groups)
  4. 访问控制列表(ACL)
  5. 记录规则(Record Rules)
  6. 字段级权限控制
  7. 按钮级权限控制
  8. 菜单级权限控制
  9. 综合案例:多层级权限控制
  10. 最佳实践与注意事项
  11. 总结

引言

Odoo 18 提供了一套完整而灵活的权限控制机制,可以精确控制用户对系统各个层面的访问权限。本文将深入介绍 Odoo 18 的权限控制机制,从权限组到记录规则,从字段级别到按钮级别,再到菜单级别,全面解析其工作原理,并附上实际案例说明。

权限机制概述

Odoo 的权限控制体系是多层次的,从粗到细可以分为以下几个层级:

  1. 菜单级权限:控制用户是否可以看到特定菜单
  2. 模型级权限(ACL):控制用户对整个模型的读、写、创建、删除权限
  3. 记录级权限(Record Rules):控制用户可以访问模型中的哪些记录
  4. 字段级权限:控制用户可以查看或编辑模型中的哪些字段
  5. 按钮级权限:控制用户可以使用界面上的哪些功能按钮

这些权限控制机制相互配合,形成了一个完整的权限管理体系。下面我们将逐一深入介绍每个层级的权限控制机制。

权限组(Groups)

权限组是 Odoo 权限控制的基础,所有权限都是通过权限组来分配的。用户被分配到不同的权限组,从而获得相应的权限。

工作原理

  1. 每个权限组都是 res.groups 模型的一条记录
  2. 用户可以同时属于多个权限组,权限是累加的
  3. 权限组可以继承其他权限组的权限
  4. 权限组可以按类别进行分组

实现方式

权限组通常在模块的 XML 文件中定义:

<record id="group_project_manager" model="res.groups"><field name="name">项目经理</field><field name="category_id" ref="base.module_category_project_management"/><field name="implied_ids" eval="[(4, ref('group_project_user'))]"/><field name="users" eval="[(4, ref('base.user_admin'))]"/>
</record>

字段说明

  • name: 权限组名称
  • category_id: 权限组所属类别
  • implied_ids: 该权限组隐含的其他权限组(继承关系)
  • users: 默认分配到该权限组的用户

案例:项目管理模块的权限组设计

<!-- 项目用户组 -->
<record id="group_project_user" model="res.groups"><field name="name">项目用户</field><field name="category_id" ref="base.module_category_project_management"/>
</record><!-- 项目经理组 -->
<record id="group_project_manager" model="res.groups"><field name="name">项目经理</field><field name="category_id" ref="base.module_category_project_management"/><field name="implied_ids" eval="[(4, ref('group_project_user'))]"/>
</record><!-- 项目总监组 -->
<record id="group_project_director" model="res.groups"><field name="name">项目总监</field><field name="category_id" ref="base.module_category_project_management"/><field name="implied_ids" eval="[(4, ref('group_project_manager'))]"/><field name="users" eval="[(4, ref('base.user_admin'))]"/>
</record>

在这个案例中,我们定义了三个权限组:项目用户、项目经理和项目总监。项目经理继承了项目用户的权限,项目总监继承了项目经理的权限,形成了一个权限层级结构。

访问控制列表(ACL)

访问控制列表(ACL)是模型级别的权限控制,用于控制用户对整个模型的读、写、创建、删除权限。

工作原理

  1. ACL 定义了特定权限组对特定模型的权限
  2. 每个 ACL 规则都是 ir.model.access 模型的一条记录
  3. 权限是累加的,如果用户属于多个权限组,则拥有这些权限组的所有权限
  4. 如果没有明确授予权限,则默认没有权限

实现方式

ACL 通常在模块的 security/ir.model.access.csv 文件中定义:

id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_project_task_user,project.task.user,model_project_task,group_project_user,1,0,0,0
access_project_task_manager,project.task.manager,model_project_task,group_project_manager,1,1,1,1

字段说明

  • id: ACL 规则的唯一标识符
  • name: ACL 规则的名称
  • model_id:id: 目标模型的外部 ID
  • group_id:id: 权限组的外部 ID
  • perm_read: 是否有读取权限(0 或 1)
  • perm_write: 是否有修改权限(0 或 1)
  • perm_create: 是否有创建权限(0 或 1)
  • perm_unlink: 是否有删除权限(0 或 1)

案例:项目任务的 ACL 设计

id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_project_task_user,project.task.user,model_project_task,group_project_user,1,1,1,0
access_project_task_manager,project.task.manager,model_project_task,group_project_manager,1,1,1,1
access_project_milestone_user,project.milestone.user,model_project_milestone,group_project_user,1,0,0,0
access_project_milestone_manager,project.milestone.manager,model_project_milestone,group_project_manager,1,1,1,1

在这个案例中,项目用户可以读取、修改和创建任务,但不能删除任务;项目经理可以读取、修改、创建和删除任务。对于里程碑,项目用户只能查看,而项目经理可以完全控制。

记录规则(Record Rules)

记录规则是记录级别的权限控制,用于控制用户可以访问模型中的哪些记录。

工作原理

  1. 记录规则定义了特定权限组可以访问模型中的哪些记录
  2. 每个记录规则都是 ir.rule 模型的一条记录
  3. 记录规则使用域表达式(domain)来过滤记录
  4. 如果用户属于多个权限组,则可以访问满足任一记录规则的记录
  5. 记录规则可以针对读取、修改、创建和删除操作分别设置

实现方式

记录规则通常在模块的 XML 文件中定义:

<record id="project_task_rule_user" model="ir.rule"><field name="name">项目任务:用户只能看到自己的任务</field><field name="model_id" ref="model_project_task"/><field name="domain_force">[('user_id', '=', user.id)]</field><field name="groups" eval="[(4, ref('group_project_user'))]"/><field name="perm_read" eval="1"/><field name="perm_write" eval="1"/><field name="perm_create" eval="1"/><field name="perm_unlink" eval="0"/>
</record>

字段说明

  • name: 记录规则的名称
  • model_id: 目标模型的引用
  • domain_force: 域表达式,用于过滤记录
  • groups: 适用的权限组
  • perm_read: 是否适用于读取操作
  • perm_write: 是否适用于修改操作
  • perm_create: 是否适用于创建操作
  • perm_unlink: 是否适用于删除操作

案例:项目任务的记录规则设计

<!-- 项目用户只能看到自己负责的任务 -->
<record id="project_task_rule_user" model="ir.rule"><field name="name">项目任务:用户只能看到自己的任务</field><field name="model_id" ref="model_project_task"/><field name="domain_force">[('user_id', '=', user.id)]</field><field name="groups" eval="[(4, ref('group_project_user'))]"/>
</record><!-- 项目经理可以看到自己项目中的所有任务 -->
<record id="project_task_rule_manager" model="ir.rule"><field name="name">项目任务:经理可以看到自己项目中的所有任务</field><field name="model_id" ref="model_project_task"/><field name="domain_force">[('project_id.user_id', '=', user.id)]</field><field name="groups" eval="[(4, ref('group_project_manager'))]"/>
</record><!-- 项目总监可以看到所有任务 -->
<record id="project_task_rule_director" model="ir.rule"><field name="name">项目任务:总监可以看到所有任务</field><field name="model_id" ref="model_project_task"/><field name="domain_force">[(1, '=', 1)]</field><field name="groups" eval="[(4, ref('group_project_director'))]"/>
</record>

在这个案例中,项目用户只能看到分配给自己的任务,项目经理可以看到自己负责的项目中的所有任务,而项目总监可以看到所有任务。

字段级权限控制

字段级权限控制用于控制用户可以查看或编辑模型中的哪些字段。

工作原理

  1. 字段级权限通过字段的 groups 属性来控制
  2. 只有属于指定权限组的用户才能查看或编辑该字段
  3. 字段级权限可以在模型定义中设置,也可以在视图中设置

实现方式

在模型定义中设置字段级权限
class ProjectTask(models.Model):_name = 'project.task'_description = '项目任务'name = fields.Char('任务名称', required=True)description = fields.Text('任务描述')priority = fields.Selection([('0', '低'),('1', '中'),('2', '高'),], string='优先级', default='1')budget = fields.Float('预算', groups='project.group_project_manager')actual_cost = fields.Float('实际成本', groups='project.group_project_director')
在视图中设置字段级权限
<field name="budget" groups="project.group_project_manager"/>
<field name="actual_cost" groups="project.group_project_director"/>

案例:项目任务的字段级权限设计

class ProjectTask(models.Model):_name = 'project.task'_description = '项目任务'name = fields.Char('任务名称', required=True)description = fields.Text('任务描述')user_id = fields.Many2one('res.users', string='负责人')date_deadline = fields.Date('截止日期')priority = fields.Selection([('0', '低'),('1', '中'),('2', '高'),], string='优先级', default='1')# 只有项目经理及以上权限才能看到预算字段budget = fields.Float('预算', groups='project.group_project_manager')# 只有项目总监才能看到实际成本字段actual_cost = fields.Float('实际成本', groups='project.group_project_director')# 只有项目总监才能看到利润率字段profit_margin = fields.Float('利润率 (%)', compute='_compute_profit_margin', groups='project.group_project_director')@api.depends('budget', 'actual_cost')def _compute_profit_margin(self):for task in self:if task.budget and task.actual_cost:task.profit_margin = (task.budget - task.actual_cost) / task.budget * 100else:task.profit_margin = 0.0

在视图中的应用:

<record id="view_task_form" model="ir.ui.view"><field name="name">project.task.form</field><field name="model">project.task</field><field name="arch" type="xml"><form><sheet><group><field name="name"/><field name="user_id"/><field name="date_deadline"/><field name="priority"/><!-- 只有项目经理及以上权限才能看到预算字段 --><field name="budget" groups="project.group_project_manager"/><!-- 只有项目总监才能看到实际成本和利润率字段 --><field name="actual_cost" groups="project.group_project_director"/><field name="profit_margin" groups="project.group_project_director"/></group><field name="description"/></sheet></form></field>
</record>

在这个案例中,预算字段只对项目经理及以上权限可见,而实际成本和利润率字段只对项目总监可见。

按钮级权限控制

按钮级权限控制用于控制用户可以使用界面上的哪些功能按钮。

工作原理

  1. 按钮级权限通过按钮的 groups 属性来控制
  2. 只有属于指定权限组的用户才能看到和使用该按钮
  3. 按钮级权限在视图中设置

实现方式

<button name="action_approve" string="批准" type="object" groups="project.group_project_manager"/>

案例:项目任务的按钮级权限设计

<record id="view_task_form" model="ir.ui.view"><field name="name">project.task.form</field><field name="model">project.task</field><field name="arch" type="xml"><form><header><field name="state" widget="statusbar"/><!-- 任何用户都可以提交任务 --><button name="action_submit" string="提交" type="object" attrs="{'invisible': [('state', '!=', 'draft')]}"/><!-- 只有项目经理才能批准任务 --><button name="action_approve" string="批准" type="object" groups="project.group_project_manager"attrs="{'invisible': [('state', '!=', 'submitted')]}"/><!-- 只有项目总监才能关闭任务 --><button name="action_close" string="关闭" type="object" groups="project.group_project_director"attrs="{'invisible': [('state', '!=', 'approved')]}"/><!-- 任何用户都可以取消任务,但需要确认 --><button name="action_cancel" string="取消" type="object" confirm="确定要取消这个任务吗?"attrs="{'invisible': [('state', 'in', ['cancelled', 'done'])]}"/></header><sheet><!-- 表单内容 --></sheet></form></field>
</record>

对应的 Python 方法:

class ProjectTask(models.Model):_name = 'project.task'_description = '项目任务'state = fields.Selection([('draft', '草稿'),('submitted', '已提交'),('approved', '已批准'),('done', '已完成'),('cancelled', '已取消'),], string='状态', default='draft', tracking=True)def action_submit(self):self.write({'state': 'submitted'})def action_approve(self):self.write({'state': 'approved'})def action_close(self):self.write({'state': 'done'})def action_cancel(self):self.write({'state': 'cancelled'})

在这个案例中,任何用户都可以提交和取消任务,但只有项目经理才能批准任务,只有项目总监才能关闭任务。

菜单级权限控制

菜单级权限控制用于控制用户可以看到哪些菜单项。

工作原理

  1. 菜单级权限通过菜单的 groups 属性来控制
  2. 只有属于指定权限组的用户才能看到该菜单
  3. 菜单级权限在菜单定义中设置

实现方式

<menuitem id="menu_project_task" name="任务" parent="menu_project" action="action_project_task" groups="group_project_user"/>

案例:项目管理模块的菜单级权限设计

<!-- 主菜单:所有项目用户可见 -->
<menuitem id="menu_project_root" name="项目" sequence="40" groups="group_project_user"/><!-- 项目菜单:所有项目用户可见 -->
<menuitem id="menu_project" name="项目" parent="menu_project_root" sequence="10"/>
<menuitem id="menu_project_list" name="项目列表" parent="menu_project" action="action_project_list" sequence="10"/>
<menuitem id="menu_project_task" name="任务" parent="menu_project" action="action_project_task" sequence="20"/><!-- 报告菜单:只有项目经理可见 -->
<menuitem id="menu_project_report" name="报告" parent="menu_project_root" sequence="20" groups="group_project_manager"/>
<menuitem id="menu_project_task_analysis" name="任务分析" parent="menu_project_report" action="action_project_task_analysis" sequence="10"/><!-- 配置菜单:只有项目总监可见 -->
<menuitem id="menu_project_config" name="配置" parent="menu_project_root" sequence="30" groups="group_project_director"/>
<menuitem id="menu_project_tags" name="标签" parent="menu_project_config" action="action_project_tags" sequence="10"/>
<menuitem id="menu_project_stages" name="阶段" parent="menu_project_config" action="action_project_stages" sequence="20"/>

在这个案例中,所有项目用户都可以看到项目和任务菜单,但只有项目经理才能看到报告菜单,只有项目总监才能看到配置菜单。

综合案例:多层级权限控制

下面我们通过一个完整的项目需求管理系统案例,展示如何综合运用各种权限控制机制。

业务场景

我们要开发一个项目需求管理系统,包含模型 project.requirement,需求如下:

用户角色权限需求
普通员工(Employee)只能查看和创建需求,只能看到自己创建的需求记录,不能看到预算和成本信息
部门经理(Manager)可以查看、创建、修改需求,可以看到本部门所有员工的需求,可以看到预算信息但不能看到成本信息,可以批准需求
高级管理层(Director)拥有所有权限,可以看到所有需求,可以看到预算和成本信息,可以批准和关闭需求

实现步骤

1. 定义权限组
<!-- 需求用户组 -->
<record id="group_requirement_user" model="res.groups"><field name="name">需求用户</field><field name="category_id" ref="base.module_category_project_management"/>
</record><!-- 需求经理组 -->
<record id="group_requirement_manager" model="res.groups"><field name="name">需求经理</field><field name="category_id" ref="base.module_category_project_management"/><field name="implied_ids" eval="[(4, ref('group_requirement_user'))]"/>
</record><!-- 需求总监组 -->
<record id="group_requirement_director" model="res.groups"><field name="name">需求总监</field><field name="category_id" ref="base.module_category_project_management"/><field name="implied_ids" eval="[(4, ref('group_requirement_manager'))]"/><field name="users" eval="[(4, ref('base.user_admin'))]"/>
</record>
2. 定义访问控制列表(ACL)
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_project_requirement_user,project.requirement.user,model_project_requirement,group_requirement_user,1,0,1,0
access_project_requirement_manager,project.requirement.manager,model_project_requirement,group_requirement_manager,1,1,1,0
access_project_requirement_director,project.requirement.director,model_project_requirement,group_requirement_director,1,1,1,1
3. 定义记录规则
<!-- 普通用户只能看到自己创建的需求 -->
<record id="rule_requirement_user_own" model="ir.rule"><field name="name">需求用户只能看到自己的需求</field><field name="model_id" ref="model_project_requirement"/><field name="domain_force">[('create_uid', '=', user.id)]</field><field name="groups" eval="[(4, ref('group_requirement_user'))]"/>
</record><!-- 经理可以看到本部门所有需求 -->
<record id="rule_requirement_manager_department" model="ir.rule"><field name="name">需求经理可以看到本部门的需求</field><field name="model_id" ref="model_project_requirement"/><field name="domain_force">[('department_id', '=', user.employee_id.department_id.id)]</field><field name="groups" eval="[(4, ref('group_requirement_manager'))]"/>
</record><!-- 总监可以看到所有需求 -->
<record id="rule_requirement_director_all" model="ir.rule"><field name="name">需求总监可以看到所有需求</field><field name="model_id" ref="model_project_requirement"/><field name="domain_force">[(1, '=', 1)]</field><field name="groups" eval="[(4, ref('group_requirement_director'))]"/>
</record>
4. 定义模型和字段级权限
class ProjectRequirement(models.Model):_name = 'project.requirement'_description = '项目需求'name = fields.Char('需求名称', required=True)description = fields.Text('需求描述')department_id = fields.Many2one('hr.department', string='所属部门', default=lambda self: self.env.user.employee_id.department_id)priority = fields.Selection([('0', '低'),('1', '中'),('2', '高'),], string='优先级', default='1')state = fields.Selection([('draft', '草稿'),('submitted', '已提交'),('approved', '已批准'),('done', '已完成'),('cancelled', '已取消'),], string='状态', default='draft', tracking=True)# 只有经理及以上权限才能看到预算字段budget = fields.Float('预算', groups='project_requirement.group_requirement_manager')# 只有总监才能看到成本字段cost = fields.Float('成本', groups='project_requirement.group_requirement_director')# 只有总监才能看到利润率字段profit_margin = fields.Float('利润率 (%)', compute='_compute_profit_margin', groups='project_requirement.group_requirement_director')@api.depends('budget', 'cost')def _compute_profit_margin(self):for req in self:if req.budget and req.cost:req.profit_margin = (req.budget - req.cost) / req.budget * 100else:req.profit_margin = 0.0def action_submit(self):self.write({'state': 'submitted'})def action_approve(self):self.write({'state': 'approved'})def action_done(self):self.write({'state': 'done'})def action_cancel(self):self.write({'state': 'cancelled'})
5. 定义视图和按钮级权限
<record id="view_requirement_form" model="ir.ui.view"><field name="name">project.requirement.form</field><field name="model">project.requirement</field><field name="arch" type="xml"><form><header><field name="state" widget="statusbar"/><!-- 任何用户都可以提交需求 --><button name="action_submit" string="提交" type="object" attrs="{'invisible': [('state', '!=', 'draft')]}"/><!-- 只有经理及以上才能批准需求 --><button name="action_approve" string="批准" type="object" groups="project_requirement.group_requirement_manager"attrs="{'invisible': [('state', '!=', 'submitted')]}"/><!-- 只有总监才能完成需求 --><button name="action_done" string="完成" type="object" groups="project_requirement.group_requirement_director"attrs="{'invisible': [('state', '!=', 'approved')]}"/><!-- 任何用户都可以取消需求 --><button name="action_cancel" string="取消" type="object" confirm="确定要取消这个需求吗?"attrs="{'invisible': [('state', 'in', ['cancelled', 'done'])]}"/></header><sheet><group><field name="name"/><field name="department_id"/><field name="priority"/><!-- 只有经理及以上才能看到预算 --><field name="budget" groups="project_requirement.group_requirement_manager"/><!-- 只有总监才能看到成本和利润率 --><field name="cost" groups="project_requirement.group_requirement_director"/><field name="profit_margin" groups="project_requirement.group_requirement_director"/></group><field name="description"/></sheet></form></field>
</record>
6. 定义菜单级权限
<!-- 主菜单:所有需求用户可见 -->
<menuitem id="menu_requirement_root" name="需求管理" sequence="50" groups="project_requirement.group_requirement_user"/><!-- 需求菜单:所有需求用户可见 -->
<menuitem id="menu_requirement" name="需求" parent="menu_requirement_root" sequence="10"/>
<menuitem id="menu_requirement_list" name="需求列表" parent="menu_requirement" action="action_requirement_list" sequence="10"/><!-- 报告菜单:只有经理及以上可见 -->
<menuitem id="menu_requirement_report" name="报告" parent="menu_requirement_root" sequence="20" groups="project_requirement.group_requirement_manager"/>
<menuitem id="menu_requirement_analysis" name="需求分析" parent="menu_requirement_report" action="action_requirement_analysis" sequence="10"/><!-- 配置菜单:只有总监可见 -->
<menuitem id="menu_requirement_config" name="配置" parent="menu_requirement_root" sequence="30" groups="project_requirement.group_requirement_director"/>
<menuitem id="menu_requirement_tags" name="标签" parent="menu_requirement_config" action="action_requirement_tags" sequence="10"/>

权限效果

  1. 普通员工

    • 可以看到需求管理菜单和需求列表菜单
    • 可以查看和创建需求,但不能修改和删除
    • 只能看到自己创建的需求
    • 看不到预算、成本和利润率字段
    • 可以提交和取消需求,但不能批准和完成需求
  2. 部门经理

    • 可以看到需求管理菜单、需求列表菜单和报告菜单
    • 可以查看、创建和修改需求,但不能删除
    • 可以看到本部门所有员工的需求
    • 可以看到预算字段,但看不到成本和利润率字段
    • 可以提交、批准和取消需求,但不能完成需求
  3. 高级管理层

    • 可以看到所有菜单
    • 可以查看、创建、修改和删除需求
    • 可以看到所有需求
    • 可以看到预算、成本和利润率字段
    • 可以执行所有操作(提交、批准、完成和取消需求)

最佳实践与注意事项

  1. 权限设计原则

    • 遵循最小权限原则,只给用户必要的权限
    • 使用权限组继承关系简化权限管理
    • 权限控制应该从粗到细,先控制菜单和模型级权限,再控制记录级和字段级权限
  2. 性能考虑

    • 记录规则会影响查询性能,特别是复杂的域表达式
    • 避免使用过于复杂的记录规则
    • 考虑使用索引优化记录规则的性能
  3. 安全注意事项

    • 菜单级权限只是隐藏菜单,不是真正的安全控制
    • 必须结合 ACL 和记录规则来实现完整的权限控制
    • 不要依赖客户端的权限控制,服务器端必须进行权限验证
  4. 调试技巧

    • 使用开发者模式查看权限问题
    • 检查用户所属的权限组
    • 检查模型的 ACL 规则
    • 检查记录规则的域表达式

总结

Odoo 18 提供了一套完整而灵活的权限控制机制,可以从多个层面精确控制用户的权限:

  1. 权限组(Groups):权限控制的基础,用户通过所属的权限组获得相应的权限
  2. 访问控制列表(ACL):模型级别的权限控制,控制用户对整个模型的读、写、创建、删除权限
  3. 记录规则(Record Rules):记录级别的权限控制,控制用户可以访问模型中的哪些记录
  4. 字段级权限:控制用户可以查看或编辑模型中的哪些字段
  5. 按钮级权限:控制用户可以使用界面上的哪些功能按钮
  6. 菜单级权限:控制用户可以看到哪些菜单项

这些权限控制机制相互配合,形成了一个完整的权限管理体系,可以满足各种复杂的业务需求。通过合理设计和配置这些权限控制机制,可以确保系统的安全性和可用性,同时提供良好的用户体验。

http://www.xdnf.cn/news/743347.html

相关文章:

  • kafka核心组件
  • Java数据结构之ArrayList(如果想知道Java中有关ArrayList的知识点,那么只看这一篇就足够了!)
  • MySql(九)
  • 【stm32开发板】单片机最小系统原理图设计
  • 基于大模型的数据库MCP Server设计与实现
  • 自动驾驶系统研发系列—端到端自动驾驶:愿景、陷阱与现实博弈
  • 跟单业务并发量分析
  • MonitorSDK_性能监控(从Web Vital性能指标、PerformanceObserver API和具体代码实现)
  • vue3 el-input type=“textarea“ 字体样式 及高度设置
  • 《Effective Python》第六章 推导式和生成器——避免在推导式中使用超过两个控制子表达式
  • 生活小记啊
  • 核心机制三:连接管理(三次握手)
  • Ollama:本地大模型推理与应用的创新平台
  • 2025年- H62-Lc170--34.在排序数组中查找元素的第一个和最后一个位置(2次二分查找,标记向左寻找,标记向右寻找)--Java版
  • 记一次idea中lombok无法使用的解决方案
  • 设计模式——简单工厂模式(创建型)
  • 【深度学习】16. Deep Generative Models:生成对抗网络(GAN)
  • Windows上用FFmpeg采集摄像头推流 → MediaMTX服务器转发流 → WSL2上拉流播放
  • GIS常见数据及主要应用综述:类型解析、应用案例与未来趋势全景解读
  • 通过mqtt 发布温湿度
  • 【机器学习基础】机器学习入门核心算法:XGBoost 和 LightGBM
  • 江科大IIC读取MPU6050hal库实现
  • C++中 newdelete 与 mallocfree 的异同详解
  • 【深度学习】14. DL在CV中的应用章:目标检测: R-CNN, Fast R-CNN, Faster R-CNN, MASK R-CNN
  • 【Linux 学习计划】-- 进程地址空间
  • 使用 Let‘s Encrypt 和 Certbot 为 Cloudflare 托管的域名申请 SSL 证书
  • Reactor 和 Preactor
  • LeetCode - 876. 链表的中间结点
  • Mybatis Plus JSqlParser解析sql语句及JSqlParser安装步骤
  • 第六十二节:深度学习-加载 TensorFlow/PyTorch/Caffe 模型