refactor: P4c 批次4 服务层改造(role/menu/user_role/role_menu)
- role/menu 走 codemod(get_role_page/get_menu_detail 等 + get_info 委托 Repository) - menu get_menu_list params 化返回 list;权限函数(get_user_permissions/ get_user_permission_menus/invalidate_*)保持完整未动 - user_role 已符合新范式(参数化+返回 list)仅验证 - role_menu save_role_menu(data) 改 BizError + router 取参包 R 【验收】flake8 零告警;应用启动;权限函数跨模块运行正常;12 passed Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude
parent
d97e456744
commit
3dbce04eb1
@@ -57,15 +57,20 @@ from flask import Blueprint
|
||||
from application.middleware import check_permission
|
||||
from application.middleware.check_demo import check_demo
|
||||
from src.modules.system.role import service as role_menu
|
||||
role_menu_blue = Blueprint('role_menu', __name__, url_prefix='/role/menu')
|
||||
|
||||
from src.common.utils.request import parse_request_body
|
||||
|
||||
from src.core import response as R
|
||||
|
||||
role_menu_blue = Blueprint("role_menu", __name__, url_prefix="/role/menu")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 角色菜单列表查询
|
||||
# ============================================================
|
||||
|
||||
@role_menu_blue.route('/list/<int:role_id>', methods=["GET"])
|
||||
|
||||
@role_menu_blue.route("/list/<int:role_id>", methods=["GET"])
|
||||
@check_permission("sys:role:list")
|
||||
def list(role_id):
|
||||
"""
|
||||
@@ -88,7 +93,8 @@ def list(role_id):
|
||||
# 角色菜单权限保存
|
||||
# ============================================================
|
||||
|
||||
@role_menu_blue.route('/save', methods=["POST"])
|
||||
|
||||
@role_menu_blue.route("/save", methods=["POST"])
|
||||
@check_permission("sys:role:save")
|
||||
@check_demo
|
||||
def save():
|
||||
@@ -101,5 +107,8 @@ def save():
|
||||
Returns:
|
||||
JSON: 操作结果
|
||||
"""
|
||||
result = role_menu.save_role_menu()
|
||||
return result
|
||||
json_data, err = parse_request_body()
|
||||
if err:
|
||||
return R.failed(msg=err)
|
||||
role_menu.save_role_menu(json_data)
|
||||
return R.ok(msg="保存成功")
|
||||
|
||||
@@ -64,10 +64,8 @@ from src.modules.association.role_menu.schema import RoleMenuForm
|
||||
from src.modules.system.menu.models import Menu
|
||||
from src.modules.association.role_menu.models import RoleMenu
|
||||
from src.modules.system.menu.service import invalidate_role_users_cache
|
||||
from src.core.database import db
|
||||
from src.common.utils import regular
|
||||
from src.core import response as R
|
||||
from src.common.utils.request import parse_request_body
|
||||
from src.core.exceptions import BizError
|
||||
|
||||
# 获取日志记录器
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -77,6 +75,7 @@ logger = logging.getLogger(__name__)
|
||||
# 角色菜单树查询
|
||||
# ============================================================
|
||||
|
||||
|
||||
def get_role_menus(role_id):
|
||||
"""
|
||||
根据角色ID查询菜单权限树
|
||||
@@ -106,9 +105,7 @@ def get_role_menus(role_id):
|
||||
|
||||
try:
|
||||
# 获取全部启用的菜单列表(按排序升序)
|
||||
menu_list = Menu.query.filter(
|
||||
and_(Menu.is_delete == 0, Menu.status == 0)
|
||||
).order_by(Menu.sort.asc()).all()
|
||||
menu_list = Menu.query.filter(and_(Menu.is_delete == 0, Menu.status == 0)).order_by(Menu.sort.asc()).all()
|
||||
|
||||
if not menu_list:
|
||||
return []
|
||||
@@ -121,12 +118,12 @@ def get_role_menus(role_id):
|
||||
result = []
|
||||
for menu in menu_list:
|
||||
data = {
|
||||
'id': menu.id,
|
||||
'name': menu.name,
|
||||
'parentId': menu.parent_id,
|
||||
"id": menu.id,
|
||||
"name": menu.name,
|
||||
"parentId": menu.parent_id,
|
||||
}
|
||||
if menu.id in assigned_menu_ids:
|
||||
data['checked'] = True
|
||||
data["checked"] = True
|
||||
result.append(data)
|
||||
|
||||
return result
|
||||
@@ -140,54 +137,40 @@ def get_role_menus(role_id):
|
||||
# 角色菜单权限保存
|
||||
# ============================================================
|
||||
|
||||
def save_role_menu():
|
||||
|
||||
def save_role_menu(data: dict) -> None:
|
||||
"""
|
||||
保存角色菜单权限分配
|
||||
|
||||
流程:
|
||||
1. 解析请求体JSON数据
|
||||
2. 表单验证
|
||||
3. 删除该角色原有的所有菜单权限
|
||||
4. 重新创建新的菜单权限关联
|
||||
1. 表单验证
|
||||
2. 删除该角色原有的所有菜单权限
|
||||
3. 重新创建新的菜单权限关联
|
||||
|
||||
Returns:
|
||||
R: 操作结果
|
||||
Args:
|
||||
data: 请求体数据 dict
|
||||
|
||||
Raises:
|
||||
BizError: 表单验证失败时
|
||||
"""
|
||||
try:
|
||||
# 获取参数
|
||||
json_data, error = parse_request_body()
|
||||
if error:
|
||||
return R.failed(msg=error)
|
||||
form = RoleMenuForm(data=data)
|
||||
if not form.validate():
|
||||
raise BizError(regular.get_err(form))
|
||||
|
||||
# 表单验证
|
||||
form = RoleMenuForm(data=json_data)
|
||||
if not form.validate():
|
||||
err_msg = regular.get_err(form)
|
||||
return R.failed(msg=err_msg)
|
||||
role_id = form.roleId.data
|
||||
menu_ids = form.menuIds.data
|
||||
|
||||
role_id = form.roleId.data
|
||||
menu_ids = form.menuIds.data
|
||||
# 删除当前角色ID相关的所有菜单权限
|
||||
RoleMenu.query.filter(RoleMenu.role_id == role_id).delete()
|
||||
|
||||
# 删除当前角色ID相关的所有菜单权限
|
||||
RoleMenu.query.filter(RoleMenu.role_id == role_id).delete()
|
||||
# 处理菜单数据
|
||||
if menu_ids and menu_ids != "":
|
||||
for menu_id in menu_ids:
|
||||
if not menu_id or menu_id <= 0:
|
||||
continue
|
||||
# 创建角色菜单关联数据
|
||||
role_menu = RoleMenu(role_id=role_id, menu_id=menu_id)
|
||||
role_menu.save()
|
||||
|
||||
# 处理菜单数据
|
||||
if menu_ids and menu_ids != "":
|
||||
for menu_id in menu_ids:
|
||||
if not menu_id or menu_id <= 0:
|
||||
continue
|
||||
# 创建角色菜单关联数据
|
||||
role_menu = RoleMenu(
|
||||
role_id=role_id,
|
||||
menu_id=menu_id
|
||||
)
|
||||
role_menu.save()
|
||||
|
||||
# 清除该角色下所有用户的权限缓存
|
||||
invalidate_role_users_cache(role_id)
|
||||
|
||||
return R.ok(msg="保存成功")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"保存角色菜单权限异常: {str(e)}")
|
||||
return R.failed(msg="保存角色菜单权限失败,请稍后重试")
|
||||
# 清除该角色下所有用户的权限缓存
|
||||
invalidate_role_users_cache(role_id)
|
||||
|
||||
@@ -16,8 +16,8 @@ from flask import Blueprint
|
||||
from application.middleware.check_demo import check_demo
|
||||
from application.middleware.check_permission import check_permission
|
||||
from src.modules.system.user import service as user_role
|
||||
user_role_blue = Blueprint('user_role', __name__, url_prefix='/user/role')
|
||||
from src.core import response as R
|
||||
user_role_blue = Blueprint('user_role', __name__, url_prefix='/user/role')
|
||||
|
||||
|
||||
# ============================================================
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
"""
|
||||
Menu 仓储模块
|
||||
=============================================================
|
||||
|
||||
数据访问层,继承 BaseRepository 获得通用 CRUD 能力。
|
||||
"""
|
||||
|
||||
from src.common.base_repository import BaseRepository
|
||||
from src.modules.system.menu.models import Menu
|
||||
|
||||
|
||||
class MenuRepository(BaseRepository):
|
||||
"""Menu 仓储"""
|
||||
|
||||
model = Menu
|
||||
@@ -53,21 +53,25 @@
|
||||
application.middleware.check_permission - 权限校验中间件
|
||||
"""
|
||||
|
||||
from flask import Blueprint
|
||||
from flask import Blueprint, request
|
||||
|
||||
from application.middleware.check_demo import check_demo
|
||||
from application.middleware.check_permission import check_permission
|
||||
from src.modules.system.menu import service as menu
|
||||
menu_blue = Blueprint('menu', __name__, url_prefix='/menu')
|
||||
|
||||
from src.common.utils.request import parse_request_body
|
||||
|
||||
from src.core import response as R
|
||||
|
||||
menu_blue = Blueprint("menu", __name__, url_prefix="/menu")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 菜单列表查询
|
||||
# ============================================================
|
||||
|
||||
@menu_blue.route('/list', methods=["GET"])
|
||||
|
||||
@menu_blue.route("/list", methods=["GET"])
|
||||
@check_permission("sys:menu:list")
|
||||
def list():
|
||||
"""
|
||||
@@ -79,15 +83,15 @@ def list():
|
||||
Returns:
|
||||
JSON: 菜单列表数据
|
||||
"""
|
||||
result = menu.get_menu_list()
|
||||
return result
|
||||
return R.ok(data=menu.get_menu_list(request.args))
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 菜单详情查询
|
||||
# ============================================================
|
||||
|
||||
@menu_blue.route('/detail/<int:id>', methods=["GET"])
|
||||
|
||||
@menu_blue.route("/detail/<int:id>", methods=["GET"])
|
||||
@check_permission("sys:menu:detail")
|
||||
def detail(id):
|
||||
"""
|
||||
@@ -107,7 +111,8 @@ def detail(id):
|
||||
# 菜单添加
|
||||
# ============================================================
|
||||
|
||||
@menu_blue.route('/add', methods=["POST"])
|
||||
|
||||
@menu_blue.route("/add", methods=["POST"])
|
||||
@check_permission("sys:menu:add")
|
||||
@check_demo
|
||||
def add():
|
||||
@@ -120,15 +125,19 @@ def add():
|
||||
Returns:
|
||||
JSON: 操作结果
|
||||
"""
|
||||
result = menu.add_menu()
|
||||
return result
|
||||
json_data, err = parse_request_body()
|
||||
if err:
|
||||
return R.failed(msg=err)
|
||||
menu.add_menu(json_data)
|
||||
return R.ok(msg="添加成功")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 菜单更新
|
||||
# ============================================================
|
||||
|
||||
@menu_blue.route('/update', methods=["PUT"])
|
||||
|
||||
@menu_blue.route("/update", methods=["PUT"])
|
||||
@check_permission("sys:menu:update")
|
||||
@check_demo
|
||||
def update():
|
||||
@@ -141,15 +150,19 @@ def update():
|
||||
Returns:
|
||||
JSON: 操作结果
|
||||
"""
|
||||
result = menu.update_menu()
|
||||
return result
|
||||
json_data, err = parse_request_body()
|
||||
if err:
|
||||
return R.failed(msg=err)
|
||||
menu.update_menu(json_data)
|
||||
return R.ok(msg="更新成功")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 菜单删除
|
||||
# ============================================================
|
||||
|
||||
@menu_blue.route('/delete/<string:id>', methods=["DELETE"])
|
||||
|
||||
@menu_blue.route("/delete/<string:id>", methods=["DELETE"])
|
||||
@check_permission("sys:menu:delete")
|
||||
@check_demo
|
||||
def delete(id):
|
||||
@@ -162,5 +175,5 @@ def delete(id):
|
||||
Returns:
|
||||
JSON: 操作结果
|
||||
"""
|
||||
result = menu.delete_menus(id)
|
||||
return result
|
||||
count = menu.delete_menus(id)
|
||||
return R.ok(msg=f"本次共删除{count}条数据")
|
||||
|
||||
+125
-165
@@ -66,19 +66,19 @@
|
||||
import logging
|
||||
|
||||
from datetime import datetime, timezone
|
||||
from flask import request
|
||||
from sqlalchemy import and_
|
||||
|
||||
from src.modules.system.menu.schema import MenuForm
|
||||
from src.modules.system.menu.models import Menu
|
||||
from src.modules.system.menu.repository import MenuRepository
|
||||
from src.core.exceptions import BizError
|
||||
from src.modules.association.role_menu.models import RoleMenu
|
||||
from src.modules.association.user_role.models import UserRole
|
||||
from src.core.database import db
|
||||
from src.core import response as R
|
||||
from src.common.utils import regular
|
||||
from src.common.utils.case_converter import convert_camel_to_snake
|
||||
from src.core.redis_client import redis
|
||||
from src.common.utils.request import parse_request_body, parse_id_list, like_contains
|
||||
from src.common.utils.request import parse_id_list, like_contains
|
||||
from src.common.utils.model_utils import models_to_list, model_to_dict
|
||||
from src.core.security import get_username
|
||||
|
||||
@@ -101,8 +101,10 @@ _CACHE_EXPIRE = 7200
|
||||
# 权限节点常量映射
|
||||
# ============================================================
|
||||
|
||||
|
||||
class PermissionNode:
|
||||
"""权限节点常量定义"""
|
||||
|
||||
QUERY = 1 # 查询
|
||||
ADD = 5 # 添加
|
||||
UPDATE = 10 # 修改
|
||||
@@ -121,20 +123,20 @@ class PermissionNode:
|
||||
|
||||
# 权限节点配置映射
|
||||
PERMISSION_CONFIG = {
|
||||
PermissionNode.QUERY: {'suffix': '查询', 'action': 'list', 'perm_suffix': 'list'},
|
||||
PermissionNode.ADD: {'suffix': '添加', 'action': 'add', 'perm_suffix': 'add'},
|
||||
PermissionNode.UPDATE: {'suffix': '修改', 'action': 'update', 'perm_suffix': 'update'},
|
||||
PermissionNode.DELETE: {'suffix': '删除', 'action': 'delete', 'perm_suffix': 'delete'},
|
||||
PermissionNode.DETAIL: {'suffix': '详情', 'action': 'detail', 'perm_suffix': 'detail'},
|
||||
PermissionNode.STATUS: {'suffix': '设置状态', 'action': 'status', 'perm_suffix': 'status'},
|
||||
PermissionNode.BATCH_DELETE: {'suffix': '批量删除', 'action': 'dall', 'perm_suffix': 'dall'},
|
||||
PermissionNode.ADD_CHILD: {'suffix': '添加子级', 'action': 'addz', 'perm_suffix': 'addz'},
|
||||
PermissionNode.EXPAND: {'suffix': '全部展开', 'action': 'expand', 'perm_suffix': 'expand'},
|
||||
PermissionNode.COLLAPSE: {'suffix': '全部折叠', 'action': 'collapse', 'perm_suffix': 'collapse'},
|
||||
PermissionNode.EXPORT: {'suffix': '导出', 'action': 'export', 'perm_suffix': 'export'},
|
||||
PermissionNode.IMPORT: {'suffix': '导入', 'action': 'import', 'perm_suffix': 'import'},
|
||||
PermissionNode.PERMISSION: {'suffix': '分配权限', 'action': 'permission', 'perm_suffix': 'permission'},
|
||||
PermissionNode.RESET_PWD: {'suffix': '重置密码', 'action': 'resetPwd', 'perm_suffix': 'resetPwd'},
|
||||
PermissionNode.QUERY: {"suffix": "查询", "action": "list", "perm_suffix": "list"},
|
||||
PermissionNode.ADD: {"suffix": "添加", "action": "add", "perm_suffix": "add"},
|
||||
PermissionNode.UPDATE: {"suffix": "修改", "action": "update", "perm_suffix": "update"},
|
||||
PermissionNode.DELETE: {"suffix": "删除", "action": "delete", "perm_suffix": "delete"},
|
||||
PermissionNode.DETAIL: {"suffix": "详情", "action": "detail", "perm_suffix": "detail"},
|
||||
PermissionNode.STATUS: {"suffix": "设置状态", "action": "status", "perm_suffix": "status"},
|
||||
PermissionNode.BATCH_DELETE: {"suffix": "批量删除", "action": "dall", "perm_suffix": "dall"},
|
||||
PermissionNode.ADD_CHILD: {"suffix": "添加子级", "action": "addz", "perm_suffix": "addz"},
|
||||
PermissionNode.EXPAND: {"suffix": "全部展开", "action": "expand", "perm_suffix": "expand"},
|
||||
PermissionNode.COLLAPSE: {"suffix": "全部折叠", "action": "collapse", "perm_suffix": "collapse"},
|
||||
PermissionNode.EXPORT: {"suffix": "导出", "action": "export", "perm_suffix": "export"},
|
||||
PermissionNode.IMPORT: {"suffix": "导入", "action": "import", "perm_suffix": "import"},
|
||||
PermissionNode.PERMISSION: {"suffix": "分配权限", "action": "permission", "perm_suffix": "permission"},
|
||||
PermissionNode.RESET_PWD: {"suffix": "重置密码", "action": "resetPwd", "perm_suffix": "resetPwd"},
|
||||
}
|
||||
|
||||
|
||||
@@ -142,37 +144,31 @@ PERMISSION_CONFIG = {
|
||||
# 菜单列表查询
|
||||
# ============================================================
|
||||
|
||||
def get_menu_list():
|
||||
|
||||
def get_menu_list(params: dict) -> list:
|
||||
"""
|
||||
查询菜单列表
|
||||
|
||||
用于菜单管理页面的列表展示,支持按名称模糊搜索。
|
||||
|
||||
Args:
|
||||
request: Flask request对象,包含查询参数
|
||||
params: 查询参数
|
||||
- name: 菜单名称(可选,模糊查询)
|
||||
|
||||
Returns:
|
||||
R: 包含菜单列表的JSON响应
|
||||
list: 菜单字典列表
|
||||
"""
|
||||
try:
|
||||
# 应用筛选条件
|
||||
query = _apply_filters()
|
||||
# 应用筛选条件
|
||||
query = _apply_filters(params)
|
||||
|
||||
# 查询数据(按排序升序)
|
||||
menu_list = query.order_by(Menu.sort.asc()).all()
|
||||
# 查询数据(按排序升序)
|
||||
menu_list = query.order_by(Menu.sort.asc()).all()
|
||||
|
||||
# 转换为字典列表
|
||||
records = models_to_list(menu_list)
|
||||
|
||||
return R.ok(data=records)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"查询菜单列表异常: {str(e)}")
|
||||
return R.failed(msg="查询失败,请稍后重试")
|
||||
# 转换为字典列表
|
||||
return models_to_list(menu_list)
|
||||
|
||||
|
||||
def _apply_filters():
|
||||
def _apply_filters(params: dict):
|
||||
"""
|
||||
应用查询筛选条件
|
||||
|
||||
@@ -187,9 +183,9 @@ def _apply_filters():
|
||||
query = Menu.query.filter(Menu.is_delete == 0)
|
||||
|
||||
# 菜单名称模糊筛选
|
||||
name = request.args.get('name')
|
||||
name = params.get("name")
|
||||
if name:
|
||||
query = query.filter(Menu.name.like(like_contains(name), escape='\\'))
|
||||
query = query.filter(Menu.name.like(like_contains(name), escape="\\"))
|
||||
|
||||
return query
|
||||
|
||||
@@ -198,6 +194,7 @@ def _apply_filters():
|
||||
# 菜单详情查询
|
||||
# ============================================================
|
||||
|
||||
|
||||
def get_menu_detail(menu_id):
|
||||
"""
|
||||
根据ID查询菜单详情(返回字典格式)
|
||||
@@ -221,15 +218,13 @@ def get_menu_detail(menu_id):
|
||||
data = model_to_dict(menu)
|
||||
|
||||
# 查询菜单权限节点(type=1 表示权限节点)
|
||||
permission_list = Menu.query.filter(
|
||||
and_(Menu.parent_id == menu_id, Menu.type == 1, Menu.is_delete == 0)
|
||||
).all()
|
||||
permission_list = Menu.query.filter(and_(Menu.parent_id == menu_id, Menu.type == 1, Menu.is_delete == 0)).all()
|
||||
|
||||
# 选中的权限节点(按sort值收集)
|
||||
checked_list = [p.sort for p in permission_list] if permission_list else []
|
||||
|
||||
# 权限节点
|
||||
data['checked_list'] = checked_list
|
||||
data["checked_list"] = checked_list
|
||||
|
||||
return data
|
||||
|
||||
@@ -242,6 +237,7 @@ def get_menu_detail(menu_id):
|
||||
# 菜单信息查询(根据ID)- 核心查询方法
|
||||
# ============================================================
|
||||
|
||||
|
||||
def get_info(menu_id: int):
|
||||
"""
|
||||
根据ID查询菜单信息(返回模型对象)
|
||||
@@ -267,26 +263,10 @@ def get_info(menu_id: int):
|
||||
if menu:
|
||||
print(menu.title)
|
||||
"""
|
||||
# 参数有效性验证
|
||||
if not menu_id or menu_id <= 0:
|
||||
return None
|
||||
|
||||
try:
|
||||
# 查询未删除的菜单
|
||||
menu = Menu.query.filter(
|
||||
and_(Menu.id == menu_id, Menu.is_delete == 0)
|
||||
).first()
|
||||
return menu
|
||||
except Exception as e:
|
||||
logger.error(f"查询菜单信息异常,ID: {menu_id}, 错误: {str(e)}")
|
||||
return None
|
||||
return MenuRepository.get_by_id(menu_id)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 菜单添加
|
||||
# ============================================================
|
||||
|
||||
def add_menu():
|
||||
def add_menu(data: dict) -> None:
|
||||
"""
|
||||
添加菜单
|
||||
|
||||
@@ -299,52 +279,41 @@ def add_menu():
|
||||
Returns:
|
||||
R: 操作结果
|
||||
"""
|
||||
try:
|
||||
# 获取参数
|
||||
json_data, error = parse_request_body()
|
||||
if error:
|
||||
return R.failed(msg=error)
|
||||
|
||||
# 表单验证
|
||||
form = MenuForm(data=json_data)
|
||||
if not form.validate():
|
||||
err_msg = regular.get_err(form)
|
||||
return R.failed(msg=err_msg)
|
||||
# 表单验证
|
||||
form = MenuForm(data=data)
|
||||
if not form.validate():
|
||||
raise BizError(regular.get_err(form))
|
||||
|
||||
# 权限节点
|
||||
checked_list = form.data.get('checked_list')
|
||||
menu_type = form.data.get('type')
|
||||
title = form.data.get('title')
|
||||
path = form.data.get('path', '')
|
||||
# 权限节点
|
||||
checked_list = form.data.get("checked_list")
|
||||
menu_type = form.data.get("type")
|
||||
title = form.data.get("title")
|
||||
path = form.data.get("path", "")
|
||||
|
||||
# 移除不需要直接保存到Menu表的字段
|
||||
form_data = form.data.copy()
|
||||
form_data.pop('checked_list', None)
|
||||
# 移除不需要直接保存到Menu表的字段
|
||||
form_data = form.data.copy()
|
||||
form_data.pop("checked_list", None)
|
||||
|
||||
# 创建菜单
|
||||
menu = Menu(**form_data)
|
||||
menu.create_user = get_username()
|
||||
db.session.add(menu)
|
||||
db.session.flush()
|
||||
# 创建菜单
|
||||
menu = Menu(**form_data)
|
||||
menu.create_user = get_username()
|
||||
db.session.add(menu)
|
||||
db.session.flush()
|
||||
|
||||
# 保存权限节点数据
|
||||
_create_permission_nodes(menu_type, checked_list, title, path, menu.id)
|
||||
# 保存权限节点数据
|
||||
_create_permission_nodes(menu_type, checked_list, title, path, menu.id)
|
||||
|
||||
# 菜单变更,递增全局版本号使所有用户缓存失效
|
||||
invalidate_all_cache()
|
||||
|
||||
return R.ok(msg="添加成功")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"添加菜单异常: {str(e)}")
|
||||
return R.failed(msg="添加菜单失败,请稍后重试")
|
||||
# 菜单变更,递增全局版本号使所有用户缓存失效
|
||||
invalidate_all_cache()
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 菜单更新
|
||||
# ============================================================
|
||||
|
||||
def update_menu():
|
||||
|
||||
def update_menu(data: dict) -> None:
|
||||
"""
|
||||
更新菜单
|
||||
|
||||
@@ -358,66 +327,56 @@ def update_menu():
|
||||
Returns:
|
||||
R: 操作结果
|
||||
"""
|
||||
try:
|
||||
# 获取参数
|
||||
json_data, error = parse_request_body()
|
||||
if error:
|
||||
return R.failed(msg=error)
|
||||
|
||||
# 表单验证
|
||||
form = MenuForm(data=json_data)
|
||||
if not form.validate():
|
||||
return R.failed(msg=regular.get_err(form))
|
||||
# 表单验证
|
||||
form = MenuForm(data=data)
|
||||
if not form.validate():
|
||||
raise BizError(regular.get_err(form))
|
||||
|
||||
# 获取菜单ID
|
||||
menu_id = form.data.get('id')
|
||||
if not menu_id or int(menu_id) <= 0:
|
||||
return R.failed("菜单ID无效")
|
||||
menu_id = int(menu_id)
|
||||
# 获取菜单ID
|
||||
menu_id = form.data.get("id")
|
||||
if not menu_id or int(menu_id) <= 0:
|
||||
raise BizError("菜单ID无效")
|
||||
menu_id = int(menu_id)
|
||||
|
||||
# 复用 get_info 方法验证菜单是否存在
|
||||
menu = get_info(menu_id)
|
||||
if not menu:
|
||||
return R.failed("菜单不存在")
|
||||
# 复用 get_info 方法验证菜单是否存在
|
||||
menu = get_info(menu_id)
|
||||
if not menu:
|
||||
raise BizError("菜单不存在")
|
||||
|
||||
# 权限节点
|
||||
checked_list = form.data.get('checked_list')
|
||||
menu_type = form.data.get('type')
|
||||
title = form.data.get('title')
|
||||
path = form.data.get('path', '')
|
||||
# 权限节点
|
||||
checked_list = form.data.get("checked_list")
|
||||
menu_type = form.data.get("type")
|
||||
title = form.data.get("title")
|
||||
path = form.data.get("path", "")
|
||||
|
||||
# 移除不需要直接更新到Menu表的字段
|
||||
form_data = convert_camel_to_snake(form.data.copy())
|
||||
form_data.pop('id', None)
|
||||
form_data.pop('checked_list', None)
|
||||
# 移除不需要直接更新到Menu表的字段
|
||||
form_data = convert_camel_to_snake(form.data.copy())
|
||||
form_data.pop("id", None)
|
||||
form_data.pop("checked_list", None)
|
||||
|
||||
form_data['update_time'] = datetime.now(tz=timezone.utc)
|
||||
form_data['update_user'] = get_username()
|
||||
form_data["update_time"] = datetime.now(tz=timezone.utc)
|
||||
form_data["update_user"] = get_username()
|
||||
|
||||
# 更新菜单信息
|
||||
result = Menu.query.filter_by(id=menu_id).update(form_data)
|
||||
# 更新菜单信息
|
||||
result = Menu.query.filter_by(id=menu_id).update(form_data)
|
||||
|
||||
if not result:
|
||||
return R.failed("更新失败")
|
||||
if not result:
|
||||
raise BizError("更新失败")
|
||||
|
||||
# 保存权限节点数据
|
||||
_create_permission_nodes(menu_type, checked_list, title, path, menu_id)
|
||||
# 保存权限节点数据
|
||||
_create_permission_nodes(menu_type, checked_list, title, path, menu_id)
|
||||
|
||||
# 菜单变更,递增全局版本号使所有用户缓存失效
|
||||
invalidate_all_cache()
|
||||
|
||||
return R.ok(msg="更新成功")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"更新菜单异常: {str(e)}")
|
||||
return R.failed(msg="更新菜单失败,请稍后重试")
|
||||
# 菜单变更,递增全局版本号使所有用户缓存失效
|
||||
invalidate_all_cache()
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 菜单删除
|
||||
# ============================================================
|
||||
|
||||
def delete_menus(menu_ids):
|
||||
|
||||
def delete_menus(menu_ids: str) -> int:
|
||||
"""
|
||||
删除菜单(批量删除)
|
||||
|
||||
@@ -431,20 +390,18 @@ def delete_menus(menu_ids):
|
||||
R: 操作结果
|
||||
"""
|
||||
if not menu_ids:
|
||||
return R.failed("记录ID不存在")
|
||||
raise BizError("记录ID不存在")
|
||||
|
||||
# 解析ID列表
|
||||
id_list = parse_id_list(menu_ids)
|
||||
if not id_list:
|
||||
return R.failed("无效的记录ID")
|
||||
raise BizError("无效的记录ID")
|
||||
|
||||
# 检查是否有子菜单
|
||||
for menu_id in id_list:
|
||||
child_count = Menu.query.filter(
|
||||
and_(Menu.parent_id == menu_id, Menu.is_delete == 0)
|
||||
).count()
|
||||
child_count = Menu.query.filter(and_(Menu.parent_id == menu_id, Menu.is_delete == 0)).count()
|
||||
if child_count > 0:
|
||||
return R.failed(f"菜单ID {menu_id} 存在子菜单,请先删除子菜单")
|
||||
raise BizError(f"菜单ID {menu_id} 存在子菜单,请先删除子菜单")
|
||||
|
||||
result = Menu.batch_delete_r(menu_ids)
|
||||
|
||||
@@ -458,6 +415,7 @@ def delete_menus(menu_ids):
|
||||
# 权限节点管理
|
||||
# ============================================================
|
||||
|
||||
|
||||
def _create_permission_nodes(menu_type, checked_list, title, path, parent_id):
|
||||
"""
|
||||
创建权限节点
|
||||
@@ -477,15 +435,13 @@ def _create_permission_nodes(menu_type, checked_list, title, path, parent_id):
|
||||
|
||||
try:
|
||||
# 删除现有权限节点
|
||||
Menu.query.filter(
|
||||
and_(Menu.parent_id == parent_id, Menu.type == 1, Menu.is_delete == 0)
|
||||
).delete()
|
||||
Menu.query.filter(and_(Menu.parent_id == parent_id, Menu.type == 1, Menu.is_delete == 0)).delete()
|
||||
|
||||
# 模块名称(去掉"管理"后缀)
|
||||
module_title = title.replace("管理", "") if title else ""
|
||||
|
||||
# 请求path处理,获取模块名
|
||||
path_arr = path.split('/')
|
||||
path_arr = path.split("/")
|
||||
if len(path_arr) < 3:
|
||||
return
|
||||
module_name = path_arr[-1]
|
||||
@@ -501,11 +457,17 @@ def _create_permission_nodes(menu_type, checked_list, title, path, parent_id):
|
||||
# 构建节点标题
|
||||
if value in [PermissionNode.DETAIL]:
|
||||
node_title = f"{module_title}{config['suffix']}"
|
||||
elif value in [PermissionNode.QUERY, PermissionNode.ADD, PermissionNode.UPDATE,
|
||||
PermissionNode.DELETE, PermissionNode.EXPORT, PermissionNode.IMPORT]:
|
||||
elif value in [
|
||||
PermissionNode.QUERY,
|
||||
PermissionNode.ADD,
|
||||
PermissionNode.UPDATE,
|
||||
PermissionNode.DELETE,
|
||||
PermissionNode.EXPORT,
|
||||
PermissionNode.IMPORT,
|
||||
]:
|
||||
node_title = f"{config['suffix']}{module_title}"
|
||||
else:
|
||||
node_title = config['suffix']
|
||||
node_title = config["suffix"]
|
||||
|
||||
# 构建路径
|
||||
node_path = f"/{module_name}/{config['action']}"
|
||||
@@ -523,7 +485,7 @@ def _create_permission_nodes(menu_type, checked_list, title, path, parent_id):
|
||||
status=1,
|
||||
target="_self",
|
||||
sort=value,
|
||||
create_user=get_username()
|
||||
create_user=get_username(),
|
||||
)
|
||||
permission_menu.save()
|
||||
|
||||
@@ -536,6 +498,7 @@ def _create_permission_nodes(menu_type, checked_list, title, path, parent_id):
|
||||
# 用户权限节点获取
|
||||
# ============================================================
|
||||
|
||||
|
||||
def get_user_permissions(user_id):
|
||||
"""
|
||||
获取用户权限节点列表(带Redis缓存)
|
||||
@@ -566,9 +529,7 @@ def get_user_permissions(user_id):
|
||||
|
||||
# 缓存未命中,查询数据库
|
||||
if user_id == 1:
|
||||
permission_list = Menu.query.filter(
|
||||
and_(Menu.is_delete == 0, Menu.type == 1, Menu.status == 0)
|
||||
).all()
|
||||
permission_list = Menu.query.filter(and_(Menu.is_delete == 0, Menu.type == 1, Menu.status == 0)).all()
|
||||
result = [item.permission for item in permission_list if item.permission]
|
||||
else:
|
||||
rows = (
|
||||
@@ -580,7 +541,7 @@ def get_user_permissions(user_id):
|
||||
Menu.type == 1,
|
||||
Menu.status == 0,
|
||||
Menu.is_delete == 0,
|
||||
Menu.permission != ''
|
||||
Menu.permission != "",
|
||||
)
|
||||
.all()
|
||||
)
|
||||
@@ -599,6 +560,7 @@ def get_user_permissions(user_id):
|
||||
# 用户菜单树获取
|
||||
# ============================================================
|
||||
|
||||
|
||||
def get_user_permission_menus(user_id):
|
||||
"""
|
||||
根据用户ID获取权限菜单树(带Redis缓存)
|
||||
@@ -629,20 +591,17 @@ def get_user_permission_menus(user_id):
|
||||
|
||||
# 缓存未命中,查询数据库
|
||||
if user_id == 1:
|
||||
menu_list = Menu.query.filter(
|
||||
and_(Menu.is_delete == 0, Menu.status == 0, Menu.type == 0)
|
||||
).order_by(Menu.sort.asc()).all()
|
||||
menu_list = (
|
||||
Menu.query.filter(and_(Menu.is_delete == 0, Menu.status == 0, Menu.type == 0))
|
||||
.order_by(Menu.sort.asc())
|
||||
.all()
|
||||
)
|
||||
else:
|
||||
menu_list = (
|
||||
db.session.query(Menu)
|
||||
.join(RoleMenu, Menu.id == RoleMenu.menu_id)
|
||||
.join(UserRole, UserRole.role_id == RoleMenu.role_id)
|
||||
.filter(
|
||||
UserRole.user_id == user_id,
|
||||
Menu.type == 0,
|
||||
Menu.status == 0,
|
||||
Menu.is_delete == 0
|
||||
)
|
||||
.filter(UserRole.user_id == user_id, Menu.type == 0, Menu.status == 0, Menu.is_delete == 0)
|
||||
.order_by(Menu.sort.asc())
|
||||
.all()
|
||||
)
|
||||
@@ -683,8 +642,8 @@ def _build_menu_tree(menu_data, parent_id):
|
||||
def _build(pid):
|
||||
children = children_map.get(pid, [])
|
||||
for item in children:
|
||||
item['children'] = _build(item["id"])
|
||||
children.sort(key=lambda x: x.get('sort', 0))
|
||||
item["children"] = _build(item["id"])
|
||||
children.sort(key=lambda x: x.get("sort", 0))
|
||||
return children
|
||||
|
||||
return _build(parent_id)
|
||||
@@ -694,6 +653,7 @@ def _build_menu_tree(menu_data, parent_id):
|
||||
# 权限缓存失效
|
||||
# ============================================================
|
||||
|
||||
|
||||
def invalidate_user_cache(user_id):
|
||||
"""
|
||||
清除指定用户的权限和菜单缓存
|
||||
|
||||
@@ -50,7 +50,6 @@ from src.common.base_db import BaseDB
|
||||
from src.common.base_model import BaseModel
|
||||
from config import DB_PREFIX
|
||||
from src.core.database import db
|
||||
from src.common.utils.case_converter import convert_camel_to_snake
|
||||
|
||||
|
||||
# ============================================================
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
"""
|
||||
Role 仓储模块
|
||||
=============================================================
|
||||
|
||||
数据访问层,继承 BaseRepository 获得通用 CRUD 能力。
|
||||
"""
|
||||
|
||||
from src.common.base_repository import BaseRepository
|
||||
from src.modules.system.role.models import Role
|
||||
|
||||
|
||||
class RoleRepository(BaseRepository):
|
||||
"""Role 仓储"""
|
||||
|
||||
model = Role
|
||||
@@ -55,22 +55,24 @@
|
||||
依赖模块: application.services.role - 角色业务逻辑层
|
||||
application.middleware.check_permission - 权限校验中间件
|
||||
"""
|
||||
from flask import Blueprint
|
||||
from flask import Blueprint, request
|
||||
|
||||
from application.middleware.check_demo import check_demo
|
||||
from application.middleware.check_permission import check_permission
|
||||
from src.modules.system.role import service as role
|
||||
from src.common.utils.request import parse_batch_ids
|
||||
role_blue = Blueprint('role', __name__, url_prefix='/role')
|
||||
from src.common.utils.request import parse_batch_ids, parse_request_body
|
||||
|
||||
from src.core import response as R
|
||||
|
||||
role_blue = Blueprint("role", __name__, url_prefix="/role")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 角色分页查询
|
||||
# ============================================================
|
||||
|
||||
@role_blue.route('/page', methods=["GET"])
|
||||
|
||||
@role_blue.route("/page", methods=["GET"])
|
||||
@check_permission("sys:role:page")
|
||||
def page():
|
||||
"""
|
||||
@@ -82,15 +84,15 @@ def page():
|
||||
Returns:
|
||||
JSON: 角色分页数据,包含 records(数据列表)、total(总记录数)等
|
||||
"""
|
||||
result = role.get_role_page()
|
||||
return result
|
||||
return R.ok(data=role.get_role_page(request.args))
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 角色详情查询
|
||||
# ============================================================
|
||||
|
||||
@role_blue.route('/detail/<int:id>', methods=["GET"])
|
||||
|
||||
@role_blue.route("/detail/<int:id>", methods=["GET"])
|
||||
@check_permission("sys:role:detail")
|
||||
def detail(id):
|
||||
"""
|
||||
@@ -110,7 +112,8 @@ def detail(id):
|
||||
# 角色添加
|
||||
# ============================================================
|
||||
|
||||
@role_blue.route('/add', methods=["POST"])
|
||||
|
||||
@role_blue.route("/add", methods=["POST"])
|
||||
@check_permission("sys:role:add")
|
||||
@check_demo
|
||||
def add():
|
||||
@@ -123,15 +126,19 @@ def add():
|
||||
Returns:
|
||||
JSON: 操作结果
|
||||
"""
|
||||
result = role.add_role()
|
||||
return result
|
||||
json_data, err = parse_request_body()
|
||||
if err:
|
||||
return R.failed(msg=err)
|
||||
role.add_role(json_data)
|
||||
return R.ok(msg="添加成功")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 角色更新
|
||||
# ============================================================
|
||||
|
||||
@role_blue.route('/update', methods=["PUT"])
|
||||
|
||||
@role_blue.route("/update", methods=["PUT"])
|
||||
@check_permission("sys:role:update")
|
||||
@check_demo
|
||||
def update():
|
||||
@@ -144,15 +151,19 @@ def update():
|
||||
Returns:
|
||||
JSON: 操作结果
|
||||
"""
|
||||
result = role.update_role()
|
||||
return result
|
||||
json_data, err = parse_request_body()
|
||||
if err:
|
||||
return R.failed(msg=err)
|
||||
role.update_role(json_data)
|
||||
return R.ok(msg="更新成功")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 角色删除
|
||||
# ============================================================
|
||||
|
||||
@role_blue.route('/delete/<string:id>', methods=["DELETE"])
|
||||
|
||||
@role_blue.route("/delete/<string:id>", methods=["DELETE"])
|
||||
@check_permission("sys:role:delete")
|
||||
@check_demo
|
||||
def delete(id):
|
||||
@@ -165,15 +176,16 @@ def delete(id):
|
||||
Returns:
|
||||
JSON: 操作结果
|
||||
"""
|
||||
result = role.delete_roles(id)
|
||||
return result
|
||||
count = role.delete_roles(id)
|
||||
return R.ok(msg=f"本次共删除{count}条数据")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 角色批量删除
|
||||
# ============================================================
|
||||
|
||||
@role_blue.route('/batchDelete', methods=["DELETE"])
|
||||
|
||||
@role_blue.route("/batchDelete", methods=["DELETE"])
|
||||
@check_permission("sys:role:batch_delete")
|
||||
@check_demo
|
||||
def batch_delete():
|
||||
@@ -199,7 +211,8 @@ def batch_delete():
|
||||
# 角色列表获取(无分页)
|
||||
# ============================================================
|
||||
|
||||
@role_blue.route('/list', methods=["GET"])
|
||||
|
||||
@role_blue.route("/list", methods=["GET"])
|
||||
def get_role_list():
|
||||
"""
|
||||
获取角色数据列表(无分页)
|
||||
|
||||
@@ -65,20 +65,18 @@
|
||||
import logging
|
||||
|
||||
from datetime import datetime, timezone
|
||||
from flask import request
|
||||
from sqlalchemy import and_
|
||||
|
||||
from src.common.constants.common import PAGE_SIZE
|
||||
from src.modules.system.role.schema import RoleForm
|
||||
from src.modules.system.role.models import Role
|
||||
from src.modules.system.role.repository import RoleRepository
|
||||
from src.core.exceptions import BizError
|
||||
from src.modules.association.user_role.models import UserRole
|
||||
from src.modules.system.menu.service import invalidate_user_cache
|
||||
from src.core.database import db
|
||||
from src.core import response as R
|
||||
from src.common.utils import regular
|
||||
from src.common.utils.case_converter import convert_camel_to_snake
|
||||
from src.common.utils.model_utils import models_to_list, model_to_dict
|
||||
from src.common.utils.request import parse_request_body, parse_id_list, like_contains
|
||||
from src.common.utils.request import parse_id_list, like_contains
|
||||
from src.core.security import get_username
|
||||
|
||||
# 获取日志记录器
|
||||
@@ -89,7 +87,8 @@ logger = logging.getLogger(__name__)
|
||||
# 角色分页查询
|
||||
# ============================================================
|
||||
|
||||
def get_role_page():
|
||||
|
||||
def get_role_page(params: dict) -> dict:
|
||||
"""
|
||||
查询角色分页数据
|
||||
|
||||
@@ -109,31 +108,26 @@ def get_role_page():
|
||||
"pages": 总页数
|
||||
}
|
||||
"""
|
||||
try:
|
||||
# 获取分页参数
|
||||
page_no = int(request.args.get('pageNo', 1))
|
||||
page_size = int(request.args.get('pageSize', PAGE_SIZE))
|
||||
# 获取分页参数
|
||||
page_no = int(params.get("pageNo", 1))
|
||||
page_size = int(params.get("pageSize", PAGE_SIZE))
|
||||
|
||||
# 应用筛选条件
|
||||
query = _apply_filters()
|
||||
# 应用筛选条件
|
||||
query = _apply_filters(params)
|
||||
|
||||
# 记录总数
|
||||
total = query.count()
|
||||
# 计算总页数
|
||||
pages = (total + page_size - 1) // page_size if total > 0 else 0
|
||||
# 记录总数
|
||||
total = query.count()
|
||||
# 计算总页数
|
||||
pages = (total + page_size - 1) // page_size if total > 0 else 0
|
||||
|
||||
# 分页查询
|
||||
role_list = query.limit(page_size).offset((page_no - 1) * page_size).all()
|
||||
# 构建返回数据
|
||||
page_data = _build_page_data(role_list, total, page_size, page_no, pages)
|
||||
return R.ok(data=page_data)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"查询角色分页数据异常: {str(e)}")
|
||||
return R.failed(msg="查询失败,请稍后重试")
|
||||
# 分页查询
|
||||
role_list = query.limit(page_size).offset((page_no - 1) * page_size).all()
|
||||
# 构建返回数据
|
||||
page_data = _build_page_data(role_list, total, page_size, page_no, pages)
|
||||
return page_data
|
||||
|
||||
|
||||
def _apply_filters():
|
||||
def _apply_filters(params: dict):
|
||||
"""
|
||||
应用查询筛选条件
|
||||
|
||||
@@ -150,9 +144,9 @@ def _apply_filters():
|
||||
query = Role.query.filter(Role.is_delete == 0)
|
||||
|
||||
# 角色名称模糊筛选
|
||||
name = request.args.get('name')
|
||||
name = params.get("name")
|
||||
if name:
|
||||
query = query.filter(Role.name.like(like_contains(name), escape='\\'))
|
||||
query = query.filter(Role.name.like(like_contains(name), escape="\\"))
|
||||
|
||||
# 按排序值升序排列
|
||||
return query.order_by(Role.sort.asc())
|
||||
@@ -175,19 +169,14 @@ def _build_page_data(role_list, total, page_size, page_no, pages):
|
||||
# 将模型对象列表转换为字典列表
|
||||
records = models_to_list(role_list)
|
||||
|
||||
return {
|
||||
'records': records,
|
||||
'total': total,
|
||||
'size': page_size,
|
||||
'current': page_no,
|
||||
'pages': pages
|
||||
}
|
||||
return {"records": records, "total": total, "size": page_size, "current": page_no, "pages": pages}
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 角色详情查询
|
||||
# ============================================================
|
||||
|
||||
|
||||
def get_role_detail(role_id):
|
||||
"""
|
||||
根据ID查询角色详情(返回字典格式)
|
||||
@@ -218,6 +207,7 @@ def get_role_detail(role_id):
|
||||
# 角色信息查询(根据ID)- 核心查询方法
|
||||
# ============================================================
|
||||
|
||||
|
||||
def get_info(role_id: int):
|
||||
"""
|
||||
根据ID查询角色信息(返回模型对象)
|
||||
@@ -242,26 +232,10 @@ def get_info(role_id: int):
|
||||
if role:
|
||||
print(role.name)
|
||||
"""
|
||||
# 参数有效性验证
|
||||
if not role_id or role_id <= 0:
|
||||
return None
|
||||
|
||||
try:
|
||||
# 查询未删除的角色
|
||||
role = Role.query.filter(
|
||||
and_(Role.id == role_id, Role.is_delete == 0)
|
||||
).first()
|
||||
return role
|
||||
except Exception as e:
|
||||
logger.error(f"查询角色信息异常,ID: {role_id}, 错误: {str(e)}")
|
||||
return None
|
||||
return RoleRepository.get_by_id(role_id)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 角色添加
|
||||
# ============================================================
|
||||
|
||||
def add_role():
|
||||
def add_role(data: dict) -> None:
|
||||
"""
|
||||
添加角色
|
||||
|
||||
@@ -273,35 +247,24 @@ def add_role():
|
||||
Returns:
|
||||
R: 操作结果
|
||||
"""
|
||||
try:
|
||||
# 获取参数
|
||||
json_data, error = parse_request_body()
|
||||
if error:
|
||||
return R.failed(msg=error)
|
||||
|
||||
# 表单验证
|
||||
form = RoleForm(data=json_data)
|
||||
if not form.validate():
|
||||
err_msg = regular.get_err(form)
|
||||
return R.failed(msg=err_msg)
|
||||
# 表单验证
|
||||
form = RoleForm(data=data)
|
||||
if not form.validate():
|
||||
raise BizError(regular.get_err(form))
|
||||
|
||||
# 创建角色
|
||||
role = Role(**form.data)
|
||||
role.create_user = get_username()
|
||||
role.save()
|
||||
|
||||
return R.ok(msg="添加成功")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"添加角色异常: {str(e)}")
|
||||
return R.failed(msg="添加失败,请稍后重试")
|
||||
# 创建角色
|
||||
role = Role(**form.data)
|
||||
role.create_user = get_username()
|
||||
role.save()
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 角色更新
|
||||
# ============================================================
|
||||
|
||||
def update_role():
|
||||
|
||||
def update_role(data: dict) -> None:
|
||||
"""
|
||||
更新角色
|
||||
|
||||
@@ -314,52 +277,42 @@ def update_role():
|
||||
Returns:
|
||||
R: 操作结果
|
||||
"""
|
||||
try:
|
||||
# 获取参数
|
||||
json_data, error = parse_request_body()
|
||||
if error:
|
||||
return R.failed(msg=error)
|
||||
|
||||
# 表单验证
|
||||
form = RoleForm(data=json_data)
|
||||
if not form.validate():
|
||||
return R.failed(msg=regular.get_err(form))
|
||||
# 表单验证
|
||||
form = RoleForm(data=data)
|
||||
if not form.validate():
|
||||
raise BizError(regular.get_err(form))
|
||||
|
||||
# 获取角色ID
|
||||
role_id = form.data.get('id')
|
||||
if not role_id or int(role_id) <= 0:
|
||||
return R.failed("角色ID无效")
|
||||
role_id = int(role_id)
|
||||
# 获取角色ID
|
||||
role_id = form.data.get("id")
|
||||
if not role_id or int(role_id) <= 0:
|
||||
raise BizError("角色ID无效")
|
||||
role_id = int(role_id)
|
||||
|
||||
# 复用 get_info 方法验证角色是否存在
|
||||
role = get_info(role_id)
|
||||
if not role:
|
||||
return R.failed("角色不存在")
|
||||
# 复用 get_info 方法验证角色是否存在
|
||||
role = get_info(role_id)
|
||||
if not role:
|
||||
raise BizError("角色不存在")
|
||||
|
||||
# 更新角色信息(移除ID,避免更新主键)
|
||||
form_data = convert_camel_to_snake(form.data.copy())
|
||||
form_data.pop('id', None)
|
||||
# 更新角色信息(移除ID,避免更新主键)
|
||||
form_data = convert_camel_to_snake(form.data.copy())
|
||||
form_data.pop("id", None)
|
||||
|
||||
form_data['update_time'] = datetime.now(tz=timezone.utc)
|
||||
form_data['update_user'] = get_username()
|
||||
form_data["update_time"] = datetime.now(tz=timezone.utc)
|
||||
form_data["update_user"] = get_username()
|
||||
|
||||
result = Role.query.filter_by(id=role_id).update(form_data)
|
||||
result = Role.query.filter_by(id=role_id).update(form_data)
|
||||
|
||||
if not result:
|
||||
return R.failed("更新失败")
|
||||
|
||||
return R.ok(msg="更新成功")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"更新角色异常: {str(e)}")
|
||||
return R.failed(msg="更新角色失败,请稍后重试")
|
||||
if not result:
|
||||
raise BizError("更新失败")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 角色删除
|
||||
# ============================================================
|
||||
|
||||
def delete_roles(role_ids):
|
||||
|
||||
def delete_roles(role_ids: str) -> int:
|
||||
"""
|
||||
删除角色(批量删除)
|
||||
|
||||
@@ -379,13 +332,17 @@ def delete_roles(role_ids):
|
||||
for uid in user_ids:
|
||||
invalidate_user_cache(uid)
|
||||
|
||||
return Role.batch_delete_r(role_ids)
|
||||
role_ids_list = parse_id_list(role_ids)
|
||||
if not role_ids_list:
|
||||
raise BizError("无效的记录ID")
|
||||
return Role.batch_delete(role_ids_list)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 角色列表获取(无分页)
|
||||
# ============================================================
|
||||
|
||||
|
||||
def get_role_list():
|
||||
"""
|
||||
获取所有启用的角色列表(无分页)
|
||||
@@ -398,9 +355,7 @@ def get_role_list():
|
||||
"""
|
||||
try:
|
||||
# 查询所有启用的角色
|
||||
role_list = Role.query.filter(
|
||||
Role.is_delete == 0
|
||||
).order_by(Role.sort.asc()).all()
|
||||
role_list = Role.query.filter(Role.is_delete == 0).order_by(Role.sort.asc()).all()
|
||||
|
||||
# 转换为字典列表
|
||||
return models_to_list(role_list)
|
||||
|
||||
Reference in New Issue
Block a user