Files
OJ2/packages/contract/src/username.ts
T
xuyueandClaude Opus 5.5 2bda05a978
Deploy / deploy (push) Canceled after 0s
feat(名字): 界面上不再显示 ks + 班号前缀,混着几个班的地方名字后面写班级
- 学生名字一律只显示名字(老号 ks232张三 显示成 张三),顶栏、首页问候、悬停提示、请假名单、比赛成绩表都一样
- 全服 / 年级排名、全部提交、几个班同时举手时,名字后面淡写班级;提交列表的名字列窄,只写班号(陈长 258)
- AI 班级分析点名「要多关心的同学」时不再带 ks 前缀
- 建号查重补漏:同班同名也比真名(加过数字的张三2、编号制老号);名字自己带数字(王芳1)也认得出被占;
  导入时后端再拦一次同班同名,建号页要等查重结果对上当前名单才能点
- 登录名单换成新接口 /classes/:c/members(名字按界面规则剥,换过班的老号不再露出全名),
  旧接口原样留给上线时还开着旧登录页的机房电脑
- 后台手写老格式 ks232张三 新建用户、没选班时按前缀补班级;PUT /me/profile 只带真名时不再 500

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 23:41:49 +08:00

42 lines
2.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { z } from 'zod'
/**
* 班级号:3~4 位数字(`232` = 23 级 2 班,`2311` = 23 级 11 班)。存在 `user.class_name`,
* 全站认班级只认这一列。
*/
export const CLASS_NAME_MIN_DIGITS = 3
export const CLASS_NAME_MAX_DIGITS = 4
export const CLASS_NAME_RE = new RegExp(`^\\d{${CLASS_NAME_MIN_DIGITS},${CLASS_NAME_MAX_DIGITS}}$`)
export const classNameSchema = z.string().trim().regex(CLASS_NAME_RE, `班级号要是 ${CLASS_NAME_MIN_DIGITS}~${CLASS_NAME_MAX_DIGITS} 位数字`)
/**
* 老账号的用户名带着班级:`ks232张三`(ks 是「考试」的拼音缩写)。2026-11 起新建的号不再带,
* 用户名就是名字;老账号不改名(学生要换登录名、历史提交里存着当时的用户名),只是界面上不再露出这段。
*
* 这条正则是**唯一**还认 `ks` 的地方:显示名、登录名单、建号查重都从这里剥。新号是中文名,不会误中。
*/
export const LEGACY_CLASS_PREFIX_RE = new RegExp(`^ks\\d{${CLASS_NAME_MIN_DIGITS},${CLASS_NAME_MAX_DIGITS}}`, 'i')
/** 界面上显示的名字:老号剥掉 `ks232`,新号原样。剥完是空串的(只有前缀的怪号)退回原名 */
export function displayName(username: string) {
return username.replace(LEGACY_CLASS_PREFIX_RE, '') || username
}
/**
* 老号用户名里的班号(`ks232张三` → `232`),只给**没明确给班级**的旧调用方兜底(老页面、手粘的 ks 名单)。
* 位数不对返回 undefined,不猜 —— `ks251001` 猜成 2510 班比报错更糟
*/
export function legacyClassOf(username: string): string | null | undefined {
const matched = /^ks(\d+)/i.exec(username)
if (!matched) return null
const digits = matched[1]!
return CLASS_NAME_RE.test(digits) ? digits : undefined
}
/**
* 登录框点名字用的名单(`GET /classes/:className/members`):`name` 是点的那个名字,
* `username` 是拿去登录的。原来只回名字、前端拼 `ks` + 班号 + 名字去登录,新号不带前缀就拼错了
*/
export const classMemberSchema = z.object({ name: z.string(), username: z.string() })
export type ClassMember = z.infer<typeof classMemberSchema>