Files
KCGL/inventory-backend/app/services/permission_service.py

108 lines
3.2 KiB
Python
Raw Normal View History

# inventory-backend/app/services/permission_service.py
from app.models.system import SysMenu, SysElement, SysRolePermission
from app.extensions import db
class PermissionService:
@staticmethod
def get_permission_tree():
"""
获取完整的权限树(菜单 -> 元素)
供前端权限配置页面展示
"""
# 1. 获取所有菜单
menus = SysMenu.query.order_by(SysMenu.sort_order).all()
# 2. 获取所有元素
elements = SysElement.query.all()
# 3. 组装树结构
tree_data = []
for menu in menus:
menu_dict = menu.to_dict()
# 找该菜单下的所有元素
children = []
for el in elements:
if el.menu_code == menu.code:
children.append(el.to_dict())
# 如果有子元素,加到 children
if children:
menu_dict['children'] = children
tree_data.append(menu_dict)
return tree_data
@staticmethod
def get_role_permissions(role_code):
"""获取指定角色拥有的所有权限Code"""
perms = SysRolePermission.query.filter_by(role_code=role_code).all()
menu_codes = []
element_codes = []
for p in perms:
if p.type == 'menu':
menu_codes.append(p.target_code)
else:
element_codes.append(p.target_code)
return {
'menus': menu_codes,
'elements': element_codes
}
@staticmethod
def assign_permissions(role_code, permission_codes):
"""
保存角色的权限
permission_codes: 前端传来的 list,包含 menu_code 和 element_code
"""
if not role_code:
raise ValueError("角色代码不能为空")
try:
# ========= 1️⃣ 先删除旧权限 =========
SysRolePermission.query.filter_by(role_code=role_code) \
.delete(synchronize_session=False)
# ========= 2️⃣ 去重(关键修复点) =========
# 防止前端传来重复 code 导致 UNIQUE 冲突
unique_codes = set(permission_codes) if permission_codes else set()
# ========= 3️⃣ 批量添加新权限 =========
if unique_codes:
# 预先获取所有菜单代码,用于判断类型
all_menu_codes = {m.code for m in SysMenu.query.all()}
new_records = []
for code in unique_codes:
if not code:
continue
# 判断类型
p_type = 'menu' if code in all_menu_codes else 'element'
new_records.append(SysRolePermission(
role_code=role_code,
target_code=code,
type=p_type
))
if new_records:
db.session.add_all(new_records)
# ========= 4️⃣ 提交事务 =========
db.session.commit()
return True
except Exception as e:
# 发生异常时回滚,防止脏事务
db.session.rollback()
raise e