feat: 8 条功能 + 身份口径改为号码布为准(含批量退赛/移出、基础数据导入导出、登录有效期)
用户给出的 8 条功能 + 一条口径变更,全部带真机/真浏览器验证:
① 录入页姓名后直接显示号码布(原「号码」列保留)
② 录入页批次进度条:`第 2 批 已录 5/8 · 3 条有错`,录完变绿;已录判据复用
entryGuards.judgeEntryRow(与发布防呆同源,不会出现"进度条说录完、发布说缺 8 条")
⑦ 小项列表双击 → 跳到该小项的组别(编辑/删除按钮不误触)
③ 赛事开关 `standings.live_on_publish`(默认开=保持原行为):关闭后分批发布只上屏成绩,
名次/流水/榜单一起等该组录完再结算 —— 代理实读代码后纠正了我的前提:
奖牌榜读的是 results.rank(buildRanked)而非流水汇总,只延迟流水会出现
「有金牌但 0 分」。另提供 POST /api/results/settle 人工兜底 + GET /api/results/settlement 未结算清单
④ 组别「就地更新」PUT /api/events/{id}/categories/{categoryId}:有报名数据时也能改名/改年龄/
改性别/改权重(旧路径是整表替换,一改就被 409 拦下);改名不动报名/成绩/流水(真机逐字节比对);
权重真的变了才触发该组重算(容差 1e-9)
④辅 运动员列表多选+全选,POST /api/athletes/batch 一次请求完成整批停用/彻底删除(逐条回报,
dryRun 预览走同一段 SQL 但不提交、不写审计)——这才是绕开限流的正解
新增 报名项批量:POST /api/entries/batch(scratch/restore/remove)。退赛只动 registered、
跳过 dq/dns 并说明原因;移出是物理删除,必须显式清 score_ledger(该表 entry_id 是
ON DELETE SET NULL,不显式删会留下"人没了分还在"的孤儿流水,验证基线 orphan=0);
退赛同时清 results.rank(否则出现"0 分还挂着金牌")
⑤ GET /api/export/entries.xlsx 报名名单导出(13 列含批次,状态中文与录入页逐字一致)
⑥ 基础数据包:GET /api/export/basedata.xlsx + POST /api/export/basedata/import
(四张表、表头只有一份定义、表头行自动定位、列缺席≠写空、按编码 upsert、绝不删除、
行级中文错误带真实 Excel 行号、枚举走既有校验、新增单位一定是启用)
⑧ 登录有效期面板可配:系统设置新页签,1–720 小时,默认 12h → 24h;滑动续期 +
Cookie 同步刷新(只服务端续期是假的,浏览器侧的 Max-Age 到点仍会丢 Cookie)
身份口径:号码布为唯一标识、证件号退出匹配(号码布不同=同名的两个人,新建并单独报告);
同一份表重复证件号不再报错;两个不同的人共用证件号仍报行级错误(唯一索引保留)
其它对齐:分项成绩表草稿行不再消失(成绩列「分数未录入」、名次/积分 `—`,没成绩的行同占位);
大屏实时赛况单栏铺满(留白 370→78px)、字号上限 56→96px、≥7 行自动拆左右两块;
删除报名项/退赛/权重等改动都会重算并推榜单。
测试:服务端 13 包(连跑两遍)、前端 335 例、vue-tsc + build、Console 18 文件 —— 全绿。
文档:README、docs/ 四份(含 debug/使用说明 副本)、devdocs 05/08/04/13。
版本号 dev_0.1.5 → dev_0.1.6。
This commit is contained in:
1 parent
8dd599bd97
commit
631c8dd8e1
80 files changed
+12468
-519
No files matched your search
+27
-11
@@ -25,10 +25,10 @@
|
||||
| `category` | **必须** | 组别**名称**(中文,要跟系统里一字不差) | `男子30岁以下` |
|
||||
| `team_code` | **必须** | 参赛单位编码,抄系统里配好的 | `F1` |
|
||||
| `athlete_name` | **必须** | 运动员姓名。**团体项目这一列留空** | `张伟` |
|
||||
| `id_card` | 可选 | 证件号(身份证号) | `110101199001011234` |
|
||||
| `id_card` | 可选 | 证件号(身份证号)。**只是档案信息,不参与认人**;一个证件号只能属于一个人 | `110101199001011234` |
|
||||
| `gender` | 可选 | 性别,只写「男」或「女」 | `男` |
|
||||
| `age` | 可选 | 年龄,0–120 的整数 | `26` |
|
||||
| `bib` | 可选 | 号码布 | `101` |
|
||||
| `bib` | 可选 | 号码布,**单人的唯一标识**(同名同姓的人靠它区分) | `101` |
|
||||
| `seed` | 可选 | 道次 / 种子,随便写或留空 | `种子1` |
|
||||
| `heat` | 可选 | 批次号:1–999 的整数;**留空 = 未分批**(不参与算分,见下) | `1` |
|
||||
| `status` | 可选 | 报名状态:4 个英文词(大小写都行)或等价的中文别名(见下) | `registered` |
|
||||
@@ -60,11 +60,14 @@
|
||||
- **团体项目**:**这一列留空**,表示"这是某个单位的一条团体报名",队员写在 `member_names` 里。
|
||||
- 姓名为空的行,系统只建一条单位报名,不会去建运动员档案。
|
||||
|
||||
### `id_card` 证件号 / `bib` 号码布 —— 二选一,至少填一个
|
||||
只要有姓名,**证件号与号码布至少要填一个**,否则无法区分同名同姓的两个人,这一行会被跳过,提示「填写了 athlete_name 就必须填 id_card 或 bib」。
|
||||
### `id_card` 证件号 / `bib` 号码布 —— 有姓名就至少填一个
|
||||
只要有姓名,**证件号与号码布至少要填一个**,否则无法确认是哪一个人,这一行会被跳过,提示「填写了 athlete_name 就必须填 id_card 或 bib」。
|
||||
|
||||
- 优先认证件号;没有证件号就认号码布(比如没有身份证的、外聘人员)。
|
||||
- **同一份表里,同一个证件号或同一个号码布只能出现一次**,重复的会被跳过并报错。
|
||||
- **号码布是单人的唯一标识,也是系统认人的依据**:先按号码布找人,号码布为空或没找到时,再按「姓名 + 单位」找(完整顺序见本节的「系统怎么认人」)。
|
||||
- **证件号是可选的档案信息,不参与认人**:它只写进 / 更新人员档案,用来登记身份;没有身份证、外聘人员只填号码布就行。
|
||||
- **但一个证件号在系统里只能属于一个人**:如果表里给的证件号已经登记在**另一个人**名下(姓名、号码布都对不上),这一行会报 `证件号 X 已被另一个人占用(姓名 Y,号码布 Z)` 并跳过——证件号不会被抢过来,那个人也不会被改成表里的人。
|
||||
- **同一个证件号在同一份表里重复出现不再报错**(同一个人报多项时本来就会重复),照常导入。
|
||||
- **号码布不能在一份表里重复出现**:重号说明要么是填错、要么是把号码布给了两个人,重复的行会被跳过并报错。
|
||||
- 号码布会同时写进人员档案和报名记录。
|
||||
|
||||
### `gender` 性别
|
||||
@@ -114,6 +117,16 @@
|
||||
- 团体项目**可以只报单位、不写队员**(这一列留空即可),队员名单以后还能补。
|
||||
- 系统界面里会把这条名单显示成「张三、李四、王五」。
|
||||
|
||||
### 系统怎么认人(号码布 → 姓名 + 单位)
|
||||
有姓名的行,系统按下面的顺序认人。**号码布是唯一标识,证件号只当档案信息,不参与这一步**:
|
||||
|
||||
| 情况 | 系统怎么处理 |
|
||||
|---|---|
|
||||
| 表里的号码布在系统里已有 | 认作**同一个人**;若表里的姓名 / 性别 / 年龄 / 单位 / 号码布与他的档案对不上,会进「冲突」列表等你逐条决定(保留哪一侧),该行本轮不写入 |
|
||||
| 号码布为空,或按号码布没找到 | 按「**姓名 + 单位**」找:<br>· 找不到 → 新建人员档案;<br>· 恰好一人、且他**还没有号码布** → 认定是同一人,此时若表里给了号码布,会**回填**到他的档案;<br>· 恰好一人、且他**已有号码布** → 仍认定是同一人(重传不带号码布的名单不会把每个人复制一份);<br>· 恰好一人、但他已有号码布**且与表里不同** → 按「**同名的另一个人**」**新建档案**,并在导入结果里单独列出(姓名 / 单位 / 原号码布 / 新号码布)提醒你核对,**不拦截、不报错**;<br>· 多人 → 分不清是谁,进「冲突」列表等逐条决定 |
|
||||
|
||||
> 「同名的另一个人」多半是号码布写错了。收到这条提醒时,先核对新号码布是不是本人:是别人(真的同名),确认无误即可;是本人写错了号,到「基础数据 → 运动员」把档案里的号码布改回来,并把多出来的那条新档案删掉。
|
||||
|
||||
---
|
||||
|
||||
## 四、三个完整例子
|
||||
@@ -157,7 +170,8 @@
|
||||
- [ ] `event_code`、`team_code` 都是从系统里抄的编码,没有空格
|
||||
- [ ] `category` 与系统里的组别名一字不差
|
||||
- [ ] 个人行都有姓名,且都有证件号或号码布
|
||||
- [ ] 一份表里没有重复的证件号、没有重复的号码布
|
||||
- [ ] 一份表里**没有重复的号码布**(号码布是唯一标识,重号会报错)
|
||||
- [ ] 证件号可以重复(同一个人报多项很正常),但每个证件号在系统里只属于一个人,别和别人的档案重号
|
||||
- [ ] `status` 只用那 4 个英文词(大小写都行)或第三节列的中文别名,不写别的词;拿不准就留空
|
||||
- [ ] `heat` 要么留空,要么是 1–999 的整数(不参与算分,只是录入分组)
|
||||
- [ ] 全表没有因为"怕麻烦"把某些列删掉——**表头 8 个必须列一个都不能少**(哪怕整列是空的)
|
||||
@@ -179,10 +193,11 @@
|
||||
| 第 N 行:组别 XXX 不存在 | 组别名和系统里不一致,或该小项还没有这个组别 | 到「基础数据 → 组别」核对名称(注意别多字少字) |
|
||||
| 第 N 行:小项 XXX 没有组别 | 该小项一个组别都没配 | 先在「组别」里配好,再导入 |
|
||||
| 第 N 行:填写了 athlete_name 就必须填 id_card 或 bib | 个人行缺两项唯一标识 | 补证件号或号码布;确实都没有的,请先在「运动员」里登记 |
|
||||
| 第 N 行:证件号 / 号码布 … 在报名表内重复出现 | 同一份表里同一个人出现了两次 | 删掉重复行(同一个人报多个项目时,`event_code` 必须不同) |
|
||||
| 第 N 行:号码布 XX 在报名表内重复出现 | 同一份表里同一个号码布出现了两次 | 删掉重复行(同一个人报多个项目时,`event_code` 必须不同;同一个号码布也不能给两个人) |
|
||||
| 第 N 行:证件号 X 已被另一个人占用(姓名 Y,号码布 Z) | 表里给的证件号已经登记在**另一个人**名下。证件号不参与认人,但系统里一个证件号只能属于一个人 | 先核对证件号是不是抄错了:**不是这个人**的,把这一格留空即可(只填号码布也能导入);**是他的**,先到「基础数据 → 运动员」把另一条档案里的证件号清掉或改对,再重新上传这一步列出的行 |
|
||||
| 第 N 行:status「xxx」无法识别 | `status` 填了系统不认的词(4 个标准词以外的英文,或第三节没列的中文) | 改成 `registered` / `scratched` / `dq` / `dns`(大小写都行)或第三节列的中文别名,也可以留空(= 正常参赛);改完重新上传 |
|
||||
| 第 N 行:heat 需要是 1-999 的整数(留空表示未分批) | `heat` 填了非整数、0、负数或超过 999 的值(如 `第1批`、`一组`、`1000`) | 改成 1–999 的整数,或者整格留空(= 未分批);批次只影响录入分组,不参与算分 |
|
||||
| 提示「冲突」,人员没有写入 | 这个人在系统里已有记录,但姓名 / 性别 / 年龄 / 单位 / 号码布跟表里**对不上** | 在导入结果里逐条选「保留已有数据」或「使用新数据」,选完再提交 |
|
||||
| 提示「冲突」,人员没有写入 | 按号码布(或「姓名 + 单位」唯一命中)的人在系统里已有记录,但姓名 / 性别 / 年龄 / 单位 / 号码布跟表里**对不上** | 在导入结果里逐条选「保留已有数据」或「使用新数据」,选完再提交 |
|
||||
| 文件传不上去 | 超过 16MB | 拆分上传,或改用 xlsx |
|
||||
| 只导入了第一张表 | xlsx 只读第一个工作表 | 把要导入的数据放在第一个工作表里 |
|
||||
|
||||
@@ -194,10 +209,11 @@
|
||||
- **新增**:这次新建的报名;
|
||||
- **更新**:这个人本来就有这个项目的报名,用表里的信息覆盖了(**不会产生重复报名**);
|
||||
- **跳过**:没能导入的行,会带着**行号**列出来,改好那几行重新上传即可。
|
||||
- 另有一份**「按同名的另一个人新建了档案(号码布不同)」**清单,单独列出姓名 / 单位 / 原号码布 / 新号码布。它不是错误:这些行**已经导入成功**,只是提醒你核对号码布有没有写错(见第三节的「系统怎么认人」)。
|
||||
2. **重复上传同一份表是安全的**,不会把名单变成两份。改完再传一遍就行。
|
||||
- ⚠️ 但要注意「更新」是**整条覆盖**:表里空着的格会把系统里原来的值清掉(队员名单、道次、号码布、**批次**都会被清空),`status` 空着会被重置成「正常参赛」。如果之前手工调整过某些人的状态或批次,**重传前请在表里把 `status`、`heat` 写清楚**。
|
||||
3. 名单导入后,到「成绩录入」里录成绩、发布,积分榜就会自动更新。
|
||||
4. **被「彻底删除」的人,导入时会以新人员建档**:管理员彻底删除某个人时,他的档案连同他名下的报名与成绩会一起从库里删掉;之后表里再出现同一个证件号或号码布,系统匹配不到旧档案,会把他当作**新人员**重新建档——名单里多出一条「以前删过的人」通常就是这么来的。新档案是全新的,他以前的报名、成绩与积分不会回来,需要重新录。
|
||||
4. **被「彻底删除」的人,导入时会以新人员建档**:管理员彻底删除某个人时,他的档案连同他名下的报名与成绩会一起从库里删掉;之后表里再出现同一个号码布(或同一「姓名 + 单位」),系统匹配不到旧档案,会把他当作**新人员**重新建档——名单里多出一条「以前删过的人」通常就是这么来的。新档案是全新的,他以前的报名、成绩与积分不会回来,需要重新录。
|
||||
5. **被「彻底删除」的单位则相反,导入时会「复活」**:管理员彻底删除某个单位,只是把它从单位列表里移除,它的报名与成绩一条都没删;表里再出现这个 `team_code`,系统按编码复用原来那条单位记录,清掉删除标记并让它重新出现在列表里,**原有的报名、成绩与积分都还在**,也不会新建第二个同名单位。
|
||||
6. **别一口气连传几十次**:写操作限 **120 次/分钟/用户**,超了会返回「操作过于频繁,请稍后再试」。正常一次导入只算一次;真被限了就等一分钟再传,不要连点。
|
||||
|
||||
@@ -208,7 +224,7 @@
|
||||
> 1. 用系统里下载的模板,**第一行不要动**;
|
||||
> 2. **一个人一行**;一个人报几项就写几行;
|
||||
> 3. `event_code`(小项)、`team_code`(单位)、`category`(组别)照抄系统里配好的,不自己编;
|
||||
> 4. 每人要有**证件号或号码布**,至少一个;
|
||||
> 4. 每人要有**证件号或号码布**,至少一个;**号码布是系统认人的唯一标识**(优先填、别重号),证件号只是可选档案信息、也不能和别人重号;
|
||||
> 5. 团体项目:姓名列留空,队员写进 `member_names`,多人用 `/` 隔开;
|
||||
> 6. 拿不准的列**留空**,不要写「无」「/」「—」这类符号;
|
||||
> 7. 表里**不要合并单元格**、不要加标题行、不要插图;
|
||||
|
||||
Reference in new issue
Block a user