mirror of
https://github.com/beilunyang/moemail.git
synced 2026-08-07 06:03:19 +08:00
feat(roles): sort user list by role rank and username
优化 GET /api/roles/users 用户列表的排序: - 主排序:按角色等级 皇帝 → 公爵 → 骑士 → 平民(无角色用户排最后) - 次排序:用户名长度(短者优先) - 末排序:用户名字母序(大小写不敏感) - 查询由 db.query.users.findMany(relational)改为显式 select + leftJoin, 以支持基于角色名的 CASE 排序 Sort the user list returned by GET /api/roles/users: - Primary: by role rank Emperor -> Duke -> Knight -> Civilian (users without a role sort last) - Secondary: username length (shorter first) - Tertiary: username alphabetical order (case-insensitive) - Switch the query from db.query.users.findMany (relational) to an explicit select + leftJoin to enable CASE-based ordering on role name
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import { createDb } from "@/lib/db"
|
||||
import { users } from "@/lib/schema"
|
||||
import { users, userRoles, roles } from "@/lib/schema"
|
||||
import { eq, like, or, sql } from "drizzle-orm"
|
||||
import { checkPermission } from "@/lib/auth"
|
||||
import { PERMISSIONS } from "@/lib/permissions"
|
||||
import { PERMISSIONS, ROLES } from "@/lib/permissions"
|
||||
|
||||
export const runtime = "edge"
|
||||
|
||||
@@ -34,19 +34,30 @@ export async function GET(request: Request) {
|
||||
.where(searchCondition)
|
||||
const total = Number(totalResult[0].count)
|
||||
|
||||
const userList = await db.query.users.findMany({
|
||||
where: searchCondition,
|
||||
with: {
|
||||
userRoles: {
|
||||
with: {
|
||||
role: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
limit: pageSize,
|
||||
offset: (page - 1) * pageSize,
|
||||
orderBy: (users, { desc }) => [desc(users.id)],
|
||||
})
|
||||
const roleRank = sql`CASE COALESCE(${roles.name}, ${ROLES.CIVILIAN})
|
||||
WHEN ${ROLES.EMPEROR} THEN 0
|
||||
WHEN ${ROLES.DUKE} THEN 1
|
||||
WHEN ${ROLES.KNIGHT} THEN 2
|
||||
WHEN ${ROLES.CIVILIAN} THEN 3
|
||||
ELSE 4
|
||||
END`
|
||||
|
||||
const userList = await db
|
||||
.select({
|
||||
id: users.id,
|
||||
name: users.name,
|
||||
username: users.username,
|
||||
email: users.email,
|
||||
image: users.image,
|
||||
role: roles.name,
|
||||
})
|
||||
.from(users)
|
||||
.leftJoin(userRoles, eq(userRoles.userId, users.id))
|
||||
.leftJoin(roles, eq(roles.id, userRoles.roleId))
|
||||
.where(searchCondition)
|
||||
.orderBy(roleRank, sql`LENGTH(COALESCE(${users.username}, ${users.name}))`, sql`LOWER(COALESCE(${users.username}, ${users.name}))`)
|
||||
.limit(pageSize)
|
||||
.offset((page - 1) * pageSize)
|
||||
|
||||
return Response.json({
|
||||
users: userList.map((u) => ({
|
||||
@@ -55,7 +66,7 @@ export async function GET(request: Request) {
|
||||
username: u.username,
|
||||
email: u.email,
|
||||
image: u.image,
|
||||
role: u.userRoles[0]?.role.name || null,
|
||||
role: u.role || null,
|
||||
})),
|
||||
total,
|
||||
page,
|
||||
|
||||
Reference in New Issue
Block a user