fix:[FL-197][角色管理 - 修复数据库表 user_role 不存在错误]
修复角色创建功能在使用现代表结构(roles)时因硬编码查询 user_role 表而导致的数据库错误。 问题分析: - admin.py:72 直接硬编码查询 user_role 表检查角色是否存在 - legacy_admin_rbac_service.py:201 也硬编码查询 user_role 表 - 实际项目使用的是现代表结构 roles(定义在 rbac.py) - 导致 psycopg.errors.UndefinedTable: relation "user_role" does not exist 修复方案: 1. 移除 admin.py 中的硬编码表查询,将重复检查逻辑委托给 create_role 服务函数 2. 在 create_role 函数中添加 role_source 检测逻辑 3. 根据检测结果使用正确的表名(user_role 或 roles)和字段 4. 确保 legacy 和 modern 模式下都能正常工作 影响范围: - 角色创建功能现在支持两种表结构 - 保持向后兼容性(legacy 模式仍使用 user_role) - 修复 modern 模式下的角色创建功能 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
@@ -67,15 +67,9 @@ def create_role_endpoint(
|
||||
current_user: CurrentUser = Depends(require_permission("role.manage")),
|
||||
db: Session = Depends(get_db),
|
||||
) -> RolePublic:
|
||||
from sqlalchemy import text
|
||||
# Check if role code already exists
|
||||
existing = db.scalar(text("SELECT id FROM user_role WHERE id = :id"), {"id": payload.code.strip()})
|
||||
if existing:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="角色编码已存在,请使用其他编码")
|
||||
|
||||
created = create_role(db, payload, actor_user_id=current_user.user.id)
|
||||
if not created:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="创建角色失败,请检查菜单权限配置是否正确")
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="创建角色失败,角色编码已存在或菜单权限配置不正确")
|
||||
return created
|
||||
|
||||
|
||||
|
||||
@@ -198,32 +198,55 @@ def create_role(db: Session, payload: RoleCreateRequest, *, actor_user_id: str |
|
||||
role_name = payload.name.strip()
|
||||
if not role_name:
|
||||
return None
|
||||
existing = db.scalar(text("SELECT id FROM user_role WHERE id = :id"), {"id": role_id})
|
||||
|
||||
role_source = "legacy" if _legacy_role_table_exists(db) else "modern"
|
||||
|
||||
# Check if role code already exists
|
||||
if role_source == "legacy":
|
||||
existing = db.scalar(text("SELECT id FROM user_role WHERE id = :id"), {"id": role_id})
|
||||
else:
|
||||
existing = db.scalar(text("SELECT id FROM roles WHERE code = :code"), {"code": role_id})
|
||||
|
||||
if existing:
|
||||
return None
|
||||
|
||||
menu_ids = sorted(set(menu_id.strip() for menu_id in payload.menu_ids if menu_id.strip()))
|
||||
if not _menu_ids_exist(db, menu_ids):
|
||||
if not _menu_ids_exist(db, menu_ids, role_source=role_source):
|
||||
return None
|
||||
|
||||
now = datetime.now()
|
||||
try:
|
||||
db.execute(
|
||||
text(
|
||||
"""
|
||||
INSERT INTO user_role (id, name, descr, state, create_date, update_date)
|
||||
VALUES (:id, :name, :descr, 'ENABLED', :create_date, :update_date)
|
||||
"""
|
||||
),
|
||||
{
|
||||
"id": role_id,
|
||||
"name": role_name,
|
||||
"descr": role_name,
|
||||
"create_date": now,
|
||||
"update_date": now,
|
||||
},
|
||||
)
|
||||
_replace_role_menus_internal(db, role_id, menu_ids)
|
||||
if role_source == "legacy":
|
||||
db.execute(
|
||||
text(
|
||||
"""
|
||||
INSERT INTO user_role (id, name, descr, state, create_date, update_date)
|
||||
VALUES (:id, :name, :descr, 'ENABLED', :create_date, :update_date)
|
||||
"""
|
||||
),
|
||||
{
|
||||
"id": role_id,
|
||||
"name": role_name,
|
||||
"descr": role_name,
|
||||
"create_date": now,
|
||||
"update_date": now,
|
||||
},
|
||||
)
|
||||
else:
|
||||
db.execute(
|
||||
text(
|
||||
"""
|
||||
INSERT INTO roles (code, name)
|
||||
VALUES (:code, :name)
|
||||
"""
|
||||
),
|
||||
{
|
||||
"code": role_id,
|
||||
"name": role_name,
|
||||
},
|
||||
)
|
||||
|
||||
_replace_role_menus_internal(db, role_id, menu_ids, role_source=role_source)
|
||||
write_audit_log(
|
||||
db,
|
||||
action="role.create",
|
||||
|
||||
Reference in New Issue
Block a user