feat(名字): 界面上不再显示 ks + 班号前缀,混着几个班的地方名字后面写班级
Deploy / deploy (push) Canceled after 0s

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xuyueandClaude Opus 5.5 committed 2026-11-02 23:41:49 +08:00
1 parent 221d264701
commit 2bda05a978
32 files changed
+229 -111

No files matched your search

+4 -2
View File
@@ -40,6 +40,8 @@ const props = defineProps<{
minis: MiniRank[]
/** 手机:前后一名的说明换到名字下面一行,别被截断 */
compact?: boolean
/** 本年级 / 全服的榜混着好几个班:名字后面淡写班级(本班榜不写) */
showClass?: boolean
}>()
const emit = defineEmits<{ moodSaved: [mood: string | null] }>()
@@ -153,7 +155,7 @@ function threatNote(me: RankRow, behind: RankRow) {
<RankAvatar :username="ahead.user.username" :avatar="ahead.avatar" :size="20" />
<div class="rival-body">
<div class="rival-line">
<UserName :username="ahead.user.username" class="rival-name" />
<UserName :username="ahead.user.username" :class-name="showClass ? ahead.className : null" class="rival-name" />
<span class="note">{{ chaseNote(me, ahead) }}</span>
</div>
<span v-if="ahead.mood" class="rival-mood" :title="ahead.mood">“{{ ahead.mood }}”</span>
@@ -164,7 +166,7 @@ function threatNote(me: RankRow, behind: RankRow) {
<RankAvatar :username="behind.user.username" :avatar="behind.avatar" :size="20" />
<div class="rival-body">
<div class="rival-line">
<UserName :username="behind.user.username" class="rival-name" />
<UserName :username="behind.user.username" :class-name="showClass ? behind.className : null" class="rival-name" />
<span class="note">{{ threatNote(me, behind) }}</span>
</div>
<span v-if="behind.mood" class="rival-mood" :title="behind.mood">“{{ behind.mood }}”</span>
@@ -19,6 +19,8 @@ const props = defineProps<{
chaseId?: number
threatId?: number
teacher?: boolean
/** 本年级 / 全服的榜混着好几个班:名字后面淡写班级(本班榜不写) */
showClass?: boolean
}>()
defineEmits<{ open: [username: string]; clearMood: [row: RankRow] }>()
@@ -59,7 +61,7 @@ const HEIGHTS: Record<number, number> = { 1: 56, 2: 44, 3: 34 }
<div class="words">
<div class="name-line">
<button class="name" @click="$emit('open', row.user.username)">
<UserName :username="row.user.username" />
<UserName :username="row.user.username" :class-name="showClass ? row.className : null" />
</button>
<span v-if="row.user.id === chaseId" class="tag chase">前一名</span>
<span v-else-if="row.user.id === threatId" class="tag threat">后一名</span>
@@ -43,6 +43,8 @@ const props = defineProps<{
expanding?: boolean
/** 手机上只有末尾一段折起来时按钮上的字,比如「看全班 39 人」 */
wholeLabel?: string
/** 本年级 / 全服的榜混着好几个班:名字后面淡写班级(本班榜不写) */
showClass?: boolean
}>()
const emit = defineEmits<{
open: [username: string]
@@ -188,7 +190,7 @@ function onMenu(key: string, row: RankRow) {
<div class="pmain">
<div class="pname">
<button class="who" @click="emit('open', item.row.user.username)">
<UserName :username="item.row.user.username" />
<UserName :username="item.row.user.username" :class-name="showClass ? item.row.className : null" />
</button>
<span v-if="item.row.user.id === chaseId" class="tag chase">前一名</span>
<span v-else-if="item.row.user.id === threatId" class="tag threat">后一名</span>
@@ -211,7 +213,7 @@ function onMenu(key: string, row: RankRow) {
<span class="rank">{{ item.row.solved ? item.row.rank : '—' }}</span>
<RankAvatar :username="item.row.user.username" :avatar="item.row.avatar" :size="20" :me="item.row.user.id === meId" />
<button class="who" @click="emit('open', item.row.user.username)">
<UserName :username="item.row.user.username" />
<UserName :username="item.row.user.username" :class-name="showClass ? item.row.className : null" />
</button>
<span class="bar-box" :style="{ background: palette.track }">
<span class="bar" :style="{ width: width(item.row), background: barColor(item.row) }" />
+5 -2
View File
@@ -287,7 +287,7 @@ function openSubmissions(username: string) {
function hide(row: RankRow) {
dialog.warning({
title: '不计入排名',
content: `${row.user.username} 会从所有排名里消失(本班、本年级、全服、首页周榜),本人会看到「不计入排名」。比赛排名不受影响,随时能恢复。`,
content: `${displayName(row.user.username)} 会从所有排名里消失(本班、本年级、全服、首页周榜),本人会看到「不计入排名」。比赛排名不受影响,随时能恢复。`,
positiveText: '不计入排名',
negativeText: '取消',
onPositiveClick: async () => {
@@ -314,7 +314,7 @@ function onMoodSaved(mood: string | null) {
function confirmClearMood(row: RankRow) {
dialog.warning({
title: '清空个性签名',
content: `${row.user.username} 的签名「${row.mood}」会被清空。只清这一句,之后还能重新写。`,
content: `${displayName(row.user.username)} 的签名「${row.mood}」会被清空。只清这一句,之后还能重新写。`,
positiveText: '清空',
negativeText: '取消',
onPositiveClick: async () => {
@@ -369,6 +369,7 @@ async function restore(userId: number) {
</div>
<RankPodium
:rows="podium"
:show-class="board.scope !== 'class'"
:me-id="meId"
:chase-id="board.ahead?.user.id"
:threat-id="board.behind?.user.id"
@@ -377,6 +378,7 @@ async function restore(userId: number) {
@clear-mood="confirmClearMood"
/>
<RankTrack
:show-class="board.scope !== 'class'"
:key="`${board.scope}|${board.period}|${board.className}`"
:rows="trackRows"
:whole-label="board.scope === 'class' ? `看全班 ${board.total} 人` : undefined"
@@ -407,6 +409,7 @@ async function restore(userId: number) {
<template v-if="board">
<RankMe
v-if="me"
:show-class="board.scope !== 'class'"
:me="me"
:ahead="board.ahead"
:behind="board.behind"