From 5561e0bc3a28b85503d43d213dc1e27c826536e7 Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Tue, 13 Oct 2026 13:56:03 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=90=8E=E5=8F=B0=E7=94=A8=E6=88=B7):=20?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=88=97=E8=A1=A8=E6=8C=89=E7=8F=AD=E7=BA=A7?= =?UTF-8?q?=E7=9C=8B=E3=80=81=E3=80=8C=E9=87=8D=E7=BD=AE=E5=AF=86=E7=A0=81?= =?UTF-8?q?=E3=80=8D=E5=B8=B8=E9=A9=BB=EF=BC=9B=E6=89=B9=E9=87=8F=E5=BB=BA?= =?UTF-8?q?=E5=8F=B7=E7=B2=98=E8=BF=9B=E5=90=8D=E5=8D=95=E5=BD=93=E5=9C=BA?= =?UTF-8?q?=E5=88=97=E5=87=BA=E4=BC=9A=E5=BB=BA=E6=88=90=E7=9A=84=E8=B4=A6?= =?UTF-8?q?=E5=8F=B7=EF=BC=8C=E9=87=8D=E5=90=8D=E5=92=8C=E5=B7=B2=E6=9C=89?= =?UTF-8?q?=E7=9A=84=E5=85=88=E7=82=B9=E5=87=BA=E6=9D=A5=EF=BC=8C=E5=BB=BA?= =?UTF-8?q?=E5=A5=BD=E8=83=BD=E4=B8=8B=E8=BD=BD=E5=90=8D=E5=8D=95=E3=80=81?= =?UTF-8?q?=E6=89=93=E5=8D=B0=E8=B4=A6=E5=8F=B7=E6=9D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户列表去掉 ID、真名、占位邮箱和四颗彩色按钮。下载的名单开头带 BOM,Excel 打开中文不再乱码。 Co-Authored-By: Claude Opus 5.5 --- apps/web/src/admin/api.ts | 20 +- .../web/src/admin/user/components/Actions.vue | 57 +- .../admin/user/components/UserNameCell.vue | 19 +- apps/web/src/admin/user/generate.vue | 508 +++++++++++++++--- apps/web/src/admin/user/list.vue | 161 ++++-- 5 files changed, 607 insertions(+), 158 deletions(-) diff --git a/apps/web/src/admin/api.ts b/apps/web/src/admin/api.ts index 1c7b8b8..ef7bf3d 100644 --- a/apps/web/src/admin/api.ts +++ b/apps/web/src/admin/api.ts @@ -51,6 +51,7 @@ import type { GenerateTestInputsRequest, GenerateTestInputsResponse, TestCaseFiles, + CheckUsernamesResponse, } from "@oj2/contract" export function getBaseInfo() { @@ -182,7 +183,15 @@ export function getAdminUserRank(offset: number, limit: number, keyword: string) } // 用户列表 -export function getUserList(offset = 0, limit = 10, type = "", keyword: string, orderBy = "") { +export function getUserList( + offset = 0, + limit = 10, + type = "", + keyword: string, + orderBy = "", + /** 班级,NO_CLASS 是「没填班级」 */ + className = "", +) { return api.get("admin/users", { // "-last_login" 是旧接口传下来的取值(路由 query 里可能还存着),改叫 "-lastLogin"; // "-online" 是新增的,原样透传 @@ -192,10 +201,16 @@ export function getUserList(offset = 0, limit = 10, type = "", keyword: string, keyword, type, orderBy: orderBy === "-last_login" ? "-lastLogin" : orderBy, + className: className || undefined, }, }) } +/** 批量建号之前查重:这些用户名哪些已经有了 */ +export function checkUsernames(usernames: string[]) { + return api.post("admin/users/check", { usernames }) +} + // 编辑用户 export function editUser(user: AdminUserForm) { return api.put(`admin/users/${user.id}`, { @@ -216,8 +231,9 @@ export async function resetPassword(userID: number) { } // 导入用户 +/** 批量建号。addedClasses:这批里的新班级,后端已经顺手加进了班级列表 */ export function importUsers(users: string[][]) { - return api.post("admin/users", { users }) + return api.post<{ imported: number; addedClasses: string[] }>("admin/users", { users }) } // 批量删除用户 diff --git a/apps/web/src/admin/user/components/Actions.vue b/apps/web/src/admin/user/components/Actions.vue index ececb14..4c744ff 100644 --- a/apps/web/src/admin/user/components/Actions.vue +++ b/apps/web/src/admin/user/components/Actions.vue @@ -1,7 +1,13 @@ diff --git a/apps/web/src/admin/user/components/UserNameCell.vue b/apps/web/src/admin/user/components/UserNameCell.vue index 69e5685..52f4ead 100644 --- a/apps/web/src/admin/user/components/UserNameCell.vue +++ b/apps/web/src/admin/user/components/UserNameCell.vue @@ -11,20 +11,27 @@ const props = defineProps() const hasRoleTag = computed(() => props.user.adminType !== USER_TYPE.REGULAR_USER) diff --git a/apps/web/src/admin/user/generate.vue b/apps/web/src/admin/user/generate.vue index 8b20c32..c985ac6 100644 --- a/apps/web/src/admin/user/generate.vue +++ b/apps/web/src/admin/user/generate.vue @@ -1,5 +1,7 @@ diff --git a/apps/web/src/admin/user/list.vue b/apps/web/src/admin/user/list.vue index 6126951..0f73064 100644 --- a/apps/web/src/admin/user/list.vue +++ b/apps/web/src/admin/user/list.vue @@ -1,7 +1,7 @@ @@ -357,3 +411,24 @@ watch(() => [query.page, query.limit, query.type, query.orderBy], listUsers) + +