fix(users): 只校验"真的改过"的姓名/账号名,修回"管理员无法编辑其他用户"

站长反馈:管理员无法编辑其他用户信息了。

根因:「姓名/账号名必须纯中文」的校验是**每次编辑都重新做一遍**的,
所以历史账号(早期用拼音/英文建的、名字里带「·」或空格的)连"改个年级"
都会被这条规则拦死 —— 管理员等于没法维护这些账号。admin 账号之前也是同一个毛病。

改成与服务端同一口径的"只校验改动过的字段":
- 没改动 → 不校验(历史数据原样保留,不强迫改名);
- 改了 → 必须满足规则(纯中文;admin 账号的姓名例外);
- 主动把中文名改成拼音/带空格 → 仍然拦。

初始管理员(ID=1)的规则不变:登录名必须保持 admin、角色锁死、密码不在这里改。

(对应的小程序端同样改成"只校验改动字段":编辑时记下原始姓名/账号名,
提交时比对;新增时两个字段都校验。)
This commit is contained in:
2026-09-30 22:02:14 +08:00
parent 792b3d4ef6
commit dfb4891022
+31 -10
View File
@@ -29,14 +29,6 @@ export default defineEventHandler(async (event) => {
}) })
} }
// 账号名必须是纯中文;**admin 账号例外**(以前没有例外,连它自己都编辑不了)
if (!isValidPersonName(name, username) || !isValidUsername(username)) {
throw createError({
statusCode: 400,
statusMessage: NAME_RULE_MESSAGE + ';' + USERNAME_RULE_MESSAGE
})
}
// 检查用户是否存在 // 检查用户是否存在
const existingUser = await db const existingUser = await db
.select() .select()
@@ -55,6 +47,35 @@ export default defineEventHandler(async (event) => {
const currentLevel = getRoleLevel(user.role) const currentLevel = getRoleLevel(user.role)
const targetLevel = getRoleLevel(targetUser.role) const targetLevel = getRoleLevel(targetUser.role)
/*
* 姓名 / 账号名的中文规则:**只校验"这次真的改了"的字段**。
*
* 站长反馈「管理员无法编辑其他用户信息了」——根因就在这里:
* 原来(以及我上一版照搬的写法)是"每次编辑都重新校验姓名和账号名",
* 于是**历史账号**(早期用拼音/英文建的、或者名字里带「·」「空格」的)
* 连"改个年级"都会撞「必须纯中文」而被拦死,管理员等于没法维护这些账号。
* 现在的口径:
* · 没改动 → 不校验(历史数据**原样保留**,不强迫改名);
* · 改了 → 必须满足规则(纯中文;admin 账号例外)。
*/
const nextUsername = String(username || '').trim()
const nextName = String(name || '').trim()
const usernameChanged = nextUsername !== String(targetUser.username || '')
const nameChanged = nextName !== String(targetUser.name || '')
if (usernameChanged && !isValidUsername(nextUsername)) {
throw createError({
statusCode: 400,
statusMessage: USERNAME_RULE_MESSAGE
})
}
if (nameChanged && !isValidPersonName(nextName, nextUsername)) {
throw createError({
statusCode: 400,
statusMessage: NAME_RULE_MESSAGE
})
}
/* /*
* 系统初始超级管理员(ID=1,登录名 admin)的处理 —— 第 90 轮按站长要求放宽。 * 系统初始超级管理员(ID=1,登录名 admin)的处理 —— 第 90 轮按站长要求放宽。
* *
@@ -67,8 +88,8 @@ export default defineEventHandler(async (event) => {
* · 锁死:密码不在这里改(避免被其它管理员顺手重置)。 * · 锁死:密码不在这里改(避免被其它管理员顺手重置)。
*/ */
if (targetUser.id === 1) { if (targetUser.id === 1) {
const nextUsername = String(username || '').trim() // 登录名必须还是 admin(usernameChanged 已在上面的中文规则里判过"有没有改")
if (nextUsername && nextUsername !== targetUser.username) { if (usernameChanged) {
throw createError({ throw createError({
statusCode: 400, statusCode: 400,
statusMessage: '初始超级管理员的登录名必须保持 admin(应急登录通道,改了就无法用它登录)' statusMessage: '初始超级管理员的登录名必须保持 admin(应急登录通道,改了就无法用它登录)'