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'}