feat(backend): knowledge iteration + vision + neo4j + response contract source
dependencies.py 拆分为 dependencies/ 包; 新增 vision/ragflow_ingestion/neo4j 客户端与 h5_ai_task; alembic 045 图置信度迁移; 响应契约统一收尾。
This commit is contained in:
@@ -144,26 +144,32 @@ async def list_user_role_assignments(
|
||||
Returns:
|
||||
List of user role assignments with employee_id, role info, source, etc.
|
||||
"""
|
||||
# 使用 LEFT OUTER JOIN:即使 user_roles.role_id 在 roles 表中已不存在
|
||||
# (例如角色被重建导致 UUID 变化),也保留该条分配记录,避免已分配用户被静默隐藏。
|
||||
# assigned_at 定义为 NOT NULL,nulls_last() 无意义,直接降序即可(SQLite/PG 通用)。
|
||||
stmt = (
|
||||
select(UserRole, Role)
|
||||
.join(Role, UserRole.role_id == Role.id)
|
||||
.order_by(UserRole.assigned_at.desc().nulls_last())
|
||||
.outerjoin(Role, UserRole.role_id == Role.id)
|
||||
.order_by(UserRole.assigned_at.desc())
|
||||
)
|
||||
result = await db.execute(stmt)
|
||||
rows = result.all()
|
||||
|
||||
|
||||
assignments = []
|
||||
for user_role, role in rows:
|
||||
# role 可能为 None(孤儿记录),做兜底展示,而不是丢弃该用户
|
||||
role_name = role.name if role else "unknown"
|
||||
role_display = (role.display_name or role.name) if role else "未知角色"
|
||||
assignments.append({
|
||||
"employee_id": user_role.employee_id,
|
||||
"role_name": role.name,
|
||||
"role_display_name": role.display_name or role.name,
|
||||
"role_name": role_name,
|
||||
"role_display_name": role_display,
|
||||
"source": user_role.source or "manual",
|
||||
"assigned_by": user_role.assigned_by or "",
|
||||
"assigned_at": user_role.assigned_at.isoformat() if user_role.assigned_at else None,
|
||||
"expires_at": user_role.expires_at.isoformat() if user_role.expires_at else None,
|
||||
})
|
||||
|
||||
|
||||
return success_response(data=assignments)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user