feat(import): 报名模板按「小项 × 组别」分工作表;号码布判重改认证件号;备份改原子落盘
三件事合成一次提交(其中两件都落在 handlers_config.go,无法按文件拆开): 一、分工作表报名模板(新增能力) - 新增 GET /api/entries/template.xlsx:按当前赛事的「小项 × 组别」生成模板, 一个小项组别一张工作表,工作表名 = <小项>@<组别>(31 字符上限、重名自动去重)。 - 导入解析器认工作表名还原小项 + 组别;若与表内列冲突则报错,不静默取其一。 - 小项名与组别名禁用 @,基础数据界面 / 规则包导入 / 服务端校验三处一并拦截。 - 单表 CSV/XLSX 导入路径不回归。 二、号码布判重(修误判) - 旧逻辑依赖证件号本身,而证件号是可选字段 → 同一个人报多个项目会被整块拦下。 - 改为:号码布相同且证件号相同 → 判定为同一人报多项,放行; 号码布相同且证件号都能填且不同 → 仍报错(真抢号);一方证件号为空 → 放行并给提示。 - 团体行的号码布一并纳入查重。 三、自动备份的关停与落盘(修数据安全隐患) - export.Service 增加 Wait():StartAuto 的协程进 WaitGroup,关停时 join(10 秒上限, 超时只记 WARN 不拖死关闭),不再在备份写到一半时退出。 - vacuumInto 改为先写 <最终名>.tmp-<随机> 再 rename,失败则删临时文件; Backup / SafetySnapshot / ExportProjectZip 三个调用方一并受益。 - 新增 isFinalBackupName,ListBackups / safetyCopies / KindOfBackupName 统一过滤中间文件, 避免半截 .db 被列进备份列表、进而被「一键恢复」选中。 文档:docs/ 五份(使用手册 / 报名名单导入规范 / 升级说明 / 部署指南 / 上线检查清单)同步。
This commit is contained in:
1 parent
b74768b7d5
commit
1b8a37ff8c
32 files changed
+3302
-233
No files matched your search
@@ -146,6 +146,37 @@ export function templateFileName(language: TemplateLanguage): string {
|
||||
return `entries-template-${language}.csv`
|
||||
}
|
||||
|
||||
/**
|
||||
* 分工作表模板(xlsx)的文件名:与单表 CSV 模板同一个命名口径,后缀区分成 xlsx。
|
||||
*
|
||||
* 两种模板**不是二选一**:单表 CSV 照样能用(老填表人不用改习惯),分工作表模板只是多了一种
|
||||
* 「一个小项组别一张表」的组织方式,见 docs/报名名单导入规范.md。
|
||||
*/
|
||||
export function templateSheetFileName(language: TemplateLanguage): string {
|
||||
return `entries-template-${language}.xlsx`
|
||||
}
|
||||
|
||||
/**
|
||||
* 小项名 / 组别名里出现 @ 的说明,没出现时返回 null。
|
||||
*
|
||||
* 与服务端 atSignNameMessage(entries_sheet_template.go)说的是同一件事、同一个理由:
|
||||
* @ 是分工作表报名模板里「小项名称@组别名称」的分隔符,名字里再出现它,工作表名就拆不开。
|
||||
* 只说「不能含 @」现场会以为是输入法问题,一定要把「为什么」写出来。
|
||||
*/
|
||||
export function atSignNameError(kind: string, name: string): string | null {
|
||||
if (!name.includes('@') && !name.includes('@')) return null
|
||||
return `${kind}「${name}」里不能有 @:@ 是分工作表模板中小项与组别的分隔符(表名要写成「小项名称@组别名称」)`
|
||||
}
|
||||
|
||||
/**
|
||||
* 示例数据模式下点「分工作表模板」的提示。
|
||||
*
|
||||
* 分工作表工作簿要按当前赛事的小项 × 组别逐张建表,浏览器里造不出 xlsx(也不该为此引一个库),
|
||||
* 所以这里明确说「连上服务端才有」,而不是给一份假的下载文件。
|
||||
*/
|
||||
export const TEMPLATE_SHEET_MOCK_HINT =
|
||||
'示例数据模式无法生成分工作表模板:它由服务端按当前赛事的小项与组别逐张建表。请连接服务端后重试,或继续用单表 CSV 模板'
|
||||
|
||||
/** 模板里的示例行:两种语言共用,只有表头不同。 */
|
||||
const TEMPLATE_ROWS: readonly string[][] = [
|
||||
['M100', '男子组', 'F1', '张伟', '110101199001011234', '男', '26', '101', '', '1', 'registered', ''],
|
||||
|
||||
Reference in new issue
Block a user