@@ -58,17 +58,34 @@ async def pager(
5858 status : Optional [int ] = Query (None , description = f"{ PLACEHOLDER_PREFIX } status" ),
5959 origins : Optional [list [int ]] = Query (None , description = f"{ PLACEHOLDER_PREFIX } origin" ),
6060 oidlist : Optional [list [int ]] = Query (None , description = f"{ PLACEHOLDER_PREFIX } oid" ),
61+ order_by : Optional [str ] = Query (None , description = "排序字段" ),
62+ desc : Optional [bool ] = Query (False , description = "是否降序" ),
6163):
6264 pagination = PaginationParams (page = pageNum , size = pageSize )
6365 paginator = Paginator (session )
64- filters = {}
65-
66+
67+ # 允许排序的字段白名单(防止 SQL 注入)
68+ SORT_COLUMNS = {
69+ 'account' : UserModel .account ,
70+ 'create_time' : UserModel .create_time ,
71+ 'name' : UserModel .name ,
72+ 'email' : UserModel .email ,
73+ 'status' : UserModel .status ,
74+ }
75+ sort_field = SORT_COLUMNS .get (order_by , UserModel .account )
76+ sort_clause = sort_field .desc () if desc else sort_field .asc ()
77+
78+ # SELECT 列必须包含 ORDER BY 列(PostgreSQL DISTINCT 约束)
79+ select_columns = [UserModel .id , UserModel .account ]
80+ if order_by and order_by != 'account' :
81+ select_columns .append (sort_field )
82+
6683 origin_stmt = (
67- select (UserModel . id , UserModel . account )
84+ select (* select_columns )
6885 .join (UserWsModel , UserModel .id == UserWsModel .uid , isouter = True )
6986 .where (UserModel .id != 1 )
7087 .distinct ()
71- .order_by (UserModel . account )
88+ .order_by (sort_clause )
7289 )
7390
7491 if oidlist :
@@ -89,16 +106,15 @@ async def pager(
89106
90107 user_page = await paginator .get_paginated_response (
91108 stmt = origin_stmt ,
92- pagination = pagination ,
93- ** filters )
109+ pagination = pagination )
94110 uid_list = [item .get ('id' ) for item in user_page .items ]
95111 if not uid_list :
96112 return user_page
97113 stmt = (
98114 select (UserModel , UserWsModel .oid .label ('ws_oid' ))
99115 .join (UserWsModel , UserModel .id == UserWsModel .uid , isouter = True )
100116 .where (UserModel .id .in_ (uid_list ))
101- .order_by (UserModel . account , UserModel . create_time )
117+ .order_by (sort_clause )
102118 )
103119 user_workspaces = session .exec (stmt ).all ()
104120 merged = defaultdict (list )
0 commit comments