134 lines
4.8 KiB
Python
134 lines
4.8 KiB
Python
from odoo import api, fields, models
|
||
|
||
class PermissionRole(models.Model):
|
||
_name = 'permission.role'
|
||
_description = '权限角色'
|
||
_rec_name = 'name'
|
||
_order = 'sequence, id'
|
||
name = fields.Char(string='角色名称', required=True)
|
||
code = fields.Char(string='角色代码', required=True, help='如:student, teacher, admin')
|
||
sequence = fields.Integer(string='序号', default=10)
|
||
description = fields.Text(string='角色描述')
|
||
active = fields.Boolean(string='启用', default=True)
|
||
# 角色类型
|
||
role_type = fields.Selection([
|
||
('student', '学生'),
|
||
('teacher', '教师'),
|
||
('admin', '管理员'),
|
||
('custom', '自定义'),
|
||
], string='角色类型', default='custom')
|
||
# 关联的权限组
|
||
group_ids = fields.Many2many('res.groups', string='权限组')
|
||
# 可见菜单
|
||
menu_ids = fields.Many2many('ir.ui.menu', string='可见菜单')
|
||
# 用户
|
||
user_ids = fields.Many2many('res.users', string='用户')
|
||
user_count = fields.Integer(string='用户数', compute='_compute_user_count')
|
||
# 统计字段
|
||
group_count = fields.Integer(string='权限组数', compute='_compute_group_count')
|
||
menu_count = fields.Integer(string='菜单数', compute='_compute_menu_count')
|
||
|
||
@api.depends('user_ids')
|
||
def _compute_user_count(self):
|
||
for record in self:
|
||
record.user_count = len(record.user_ids)
|
||
|
||
@api.depends('group_ids')
|
||
def _compute_group_count(self):
|
||
for record in self:
|
||
record.group_count = len(record.group_ids)
|
||
|
||
@api.depends('menu_ids')
|
||
def _compute_menu_count(self):
|
||
for record in self:
|
||
record.menu_count = len(record.menu_ids)
|
||
|
||
def action_assign_users(self):
|
||
"""分配用户"""
|
||
return {
|
||
'type': 'ir.actions.act_window',
|
||
'name': '分配用户',
|
||
'res_model': 'res.users',
|
||
'view_mode': 'list,form',
|
||
'target': 'new',
|
||
'domain': [('id', 'not in', self.user_ids.ids)],
|
||
'context': {
|
||
'default_role_ids': [(4, self.id)],
|
||
},
|
||
}
|
||
|
||
def action_view_users(self):
|
||
"""查看角色下的用户"""
|
||
return {
|
||
'type': 'ir.actions.act_window',
|
||
'name': f'角色用户 - {self.name}',
|
||
'res_model': 'res.users',
|
||
'view_mode': 'list,form',
|
||
'domain': [('id', 'in', self.user_ids.ids)],
|
||
}
|
||
|
||
def action_copy_permissions(self):
|
||
"""复制权限(从其他角色)"""
|
||
return {
|
||
'type': 'ir.actions.act_window',
|
||
'name': '复制权限',
|
||
'res_model': 'permission.copy.wizard',
|
||
'view_mode': 'form',
|
||
'target': 'new',
|
||
'context': {'default_target_role_id': self.id},
|
||
}
|
||
|
||
|
||
class ResUsersInherit(models.Model):
|
||
_inherit = 'res.users'
|
||
|
||
role_ids = fields.Many2many('permission.role', string='权限角色')
|
||
role_count = fields.Integer(string='角色数', compute='_compute_role_count')
|
||
|
||
@api.depends('role_ids')
|
||
def _compute_role_count(self):
|
||
for record in self:
|
||
record.role_count = len(record.role_ids)
|
||
|
||
def action_view_roles(self):
|
||
"""查看用户角色"""
|
||
return {
|
||
'type': 'ir.actions.act_window',
|
||
'name': '用户角色',
|
||
'res_model': 'permission.role',
|
||
'view_mode': 'list,form',
|
||
'domain': [('id', 'in', self.role_ids.ids)],
|
||
}
|
||
|
||
def action_sync_permissions(self):
|
||
"""同步权限:将角色的权限组和菜单同步到用户"""
|
||
for user in self:
|
||
groups = user.role_ids.mapped('group_ids')
|
||
menus = user.role_ids.mapped('menu_ids')
|
||
user.write({
|
||
'groups_id': [(6, 0, groups.ids)],
|
||
})
|
||
# 菜单权限需要单独处理
|
||
for menu in menus:
|
||
# 这里可以添加自定义菜单权限逻辑
|
||
pass
|
||
|
||
|
||
class PermissionCopyWizard(models.TransientModel):
|
||
_name = 'permission.copy.wizard'
|
||
_description = '复制权限向导'
|
||
|
||
target_role_id = fields.Many2one('permission.role', string='目标角色', readonly=True)
|
||
source_role_id = fields.Many2one('permission.role', string='源角色', required=True)
|
||
copy_groups = fields.Boolean(string='复制权限组', default=True)
|
||
copy_menus = fields.Boolean(string='复制菜单权限', default=True)
|
||
|
||
def action_copy(self):
|
||
self.ensure_one()
|
||
vals = {}
|
||
if self.copy_groups:
|
||
vals['group_ids'] = [(6, 0, self.source_role_id.group_ids.ids)]
|
||
if self.copy_menus:
|
||
vals['menu_ids'] = [(6, 0, self.source_role_id.menu_ids.ids)]
|
||
self.target_role_id.write(vals)
|
||
return {'type': 'ir.actions.act_window_close'} |