From 868979a423bf99b0977cc13912d38a72f9e8c324 Mon Sep 17 00:00:00 2001 From: abearxiong Date: Thu, 25 Dec 2025 16:59:45 +0800 Subject: [PATCH] update --- src/auth/models/user.ts | 4 ++ src/routes/user/admin/user.ts | 75 ++++++++++++++++++++++------------- src/routes/user/me.ts | 14 +++++-- src/routes/user/wx-login.ts | 2 +- 4 files changed, 63 insertions(+), 32 deletions(-) diff --git a/src/auth/models/user.ts b/src/auth/models/user.ts index c37fea2..1304f23 100644 --- a/src/auth/models/user.ts +++ b/src/auth/models/user.ts @@ -14,6 +14,7 @@ type UserData = { orgs?: string[]; wxUnionId?: string; phone?: string; + canChangeUsername?: boolean; }; export enum UserTypes { 'user' = 'user', @@ -182,6 +183,9 @@ export class User extends Model { avatar: this.avatar, orgs, }; + if(this.data?.canChangeUsername) { + info.canChangeUsername = this.data.canChangeUsername; + } const tokenUser = this.tokenUser; if (uid) { info.uid = uid; diff --git a/src/routes/user/admin/user.ts b/src/routes/user/admin/user.ts index a1bb1d7..ebeca65 100644 --- a/src/routes/user/admin/user.ts +++ b/src/routes/user/admin/user.ts @@ -8,21 +8,58 @@ import { AppModel } from '@/routes/app-manager/index.ts'; export const checkUsername = (username: string) => { if (username.length > 30) { - throw new CustomError(400, 'Username cannot be too long'); + throw new CustomError(400, '用户名不能过长'); } if (!/^[a-zA-Z0-9_@]+$/.test(username)) { - throw new CustomError(400, 'Username cannot contain special characters'); + throw new CustomError(400, '用户名包含非法字符'); } if (username.includes(' ')) { - throw new CustomError(400, 'Username cannot contain spaces'); + throw new CustomError(400, '用户名不能包含空格'); } }; export const checkUsernameShort = (username: string) => { - if (username.length < 3) { - throw new CustomError(400, 'Username cannot be too short'); + if (username.length <= 3) { + throw new CustomError(400, '用户名不能过短'); } }; +export const toChangeName = async (opts: { id: number; newName: string; admin?: boolean, ctx: any }) => { + const { id, newName, admin = false, ctx } = opts; + if (!admin) { + checkUsernameShort(newName); + } + const user = await User.findByPk(id); + if (!user) { + ctx.throw(404, 'User not found'); + } + const oldName = user.username; + checkUsername(newName); + const findUserByUsername = await User.findOne({ where: { username: newName } }); + if (findUserByUsername) { + ctx.throw(400, 'Username already exists'); + } + user.username = newName; + const data = user.data || {}; + data.canChangeUsername = false; + user.data = data; + try { + await user.save({ fields: ['username', 'data'] }); + // 迁移文件数据 + await backupUserA(oldName, user.id); // 备份文件数据 + await mvUserAToUserB(oldName, newName, true); // 迁移文件数据 + // await mvAppFromUserAToUserB(oldName, newName); // 迁移应用数据 + + if (['org', 'user'].includes(user.type)) { + const type = user.type === 'org' ? 'org' : 'user'; + await User.clearUserToken(user.id, type); // 清除旧token + } + await AppModel.moveToNewUser(oldName, newName); // 更新用户数据 + } catch (error) { + console.error('迁移文件数据失败', error); + ctx.throw(500, 'Failed to change username'); + } + return user; +} app .route({ path: 'user', @@ -31,34 +68,16 @@ app }) .define(async (ctx) => { const { id, newName } = ctx.query.data || {}; - const user = await User.findByPk(id); - if (!user) { - ctx.throw(404, 'User not found'); - } - const oldName = user.username; - checkUsername(newName); - const findUserByUsername = await User.findOne({ where: { username: newName } }); - if (findUserByUsername) { - ctx.throw(400, 'Username already exists'); - } - user.username = newName; try { - await user.save(); - // 迁移文件数据 - await backupUserA(oldName, user.id); // 备份文件数据 - await mvUserAToUserB(oldName, newName, true); // 迁移文件数据 - // await mvAppFromUserAToUserB(oldName, newName); // 迁移应用数据 - - if (['org', 'user'].includes(user.type)) { - const type = user.type === 'org' ? 'org' : 'user'; - await User.clearUserToken(user.id, type); // 清除旧token + if (!id || !newName) { + ctx.throw(400, '参数错误'); } - await AppModel.moveToNewUser(oldName, newName); // 更新用户数据 + const user = await toChangeName({ id, newName, admin: true, ctx }); + ctx.body = await user?.getInfo?.(); } catch (error) { - console.error('迁移文件数据失败', error); + console.error('changeName error', error); ctx.throw(500, 'Failed to change username'); } - ctx.body = user; }) .addTo(app); diff --git a/src/routes/user/me.ts b/src/routes/user/me.ts index f90cd9b..35e18fc 100644 --- a/src/routes/user/me.ts +++ b/src/routes/user/me.ts @@ -209,7 +209,7 @@ app middleware: ['auth'], }) .define(async (ctx) => { - const { username, password, description, avatar, email } = ctx.query.data || {}; + const { username, nickname, password, description, avatar, email } = ctx.query.data || {}; const tokenUser = ctx.state?.tokenUser || {}; const { id } = tokenUser; const user = await User.findByPk(id); @@ -217,8 +217,16 @@ app ctx.throw(404, 'user not found'); } user.setTokenUser(tokenUser); - if (username) { + if (username && user.data?.canChangeUsername) { user.username = username; + const data = user.data || {}; + data.canChangeUsername = false; + user.data = data; + } else if (username && username !== user.username) { + ctx.throw(400, '请求更改用户名失败,用户名不可再更改,请联系管理员'); + } + if (nickname) { + user.nickname = nickname; } if (password && user.type !== 'org') { user.createPassword(password); @@ -232,7 +240,7 @@ app if (email) { user.email = email; } - await user.save(); + await user.save({ fields: ['username', 'nickname', 'data', 'password', 'description', 'avatar', 'email'] }); ctx.body = await user.getInfo(); }) .addTo(app); diff --git a/src/routes/user/wx-login.ts b/src/routes/user/wx-login.ts index 15937ef..18ddf68 100644 --- a/src/routes/user/wx-login.ts +++ b/src/routes/user/wx-login.ts @@ -53,7 +53,7 @@ app .route({ path: 'wx', key: 'mp-get-openid', - description: '微信公众平台获取openid', + description: '微信公众平台获取openid, 根据code回调去获取openid', }) .define(async (ctx) => { const code = ctx.query.code;