Commit Graph
31 Commits
Author SHA1 Message Date
AskaEth 005b51b2ec fix: 数据目录移出安装目录,修掉「覆盖安装/卸载即丢数据」
根因:数据目录是 <安装目录>\data(config.yaml 的 dataDir 相对服务端工作目录),
而 electron-builder 的卸载器结尾执行 RMDir /r $INSTDIR,且覆盖安装会先跑旧卸载器
(installSection.nsh:52 的 uninstallOldVersion)→ 赛事库/规则/用户/审计/上传图片
连同安装目录被整个删除,再装新版。卸载一次同样如此。

- 服务端新增 -data <dir>(主命令、backup、passwd 三处),非空时覆盖 config.yaml 的
  dataDir;不传时行为完全不变(兼容便携/手工运行)
- Console 把数据指到当前用户目录 %LOCALAPPDATA%\ScoreboardConsole\data(卸载器不会碰
  这里;没有用 app.getPath('userData'),因为 %APPDATA%\<AppName> 正是被删的那个)
- 一次性迁移:目标为空且 <安装目录>\data 有数据时整体改名过去;两边都有数据时不动作
  只记警告;任何失败都保留原地数据、绝不删除
- passwd 也带 -data(否则重置的是安装目录下那个空库里的账号)
- deploy/backup.bat 指向同一数据目录
- 文档:部署指南新增「数据放在哪里(升级/卸载都不会删)」+ 备份/恢复/迁移路径改写,
  上线检查清单与使用手册同步

自检:服务端 12 包全绿;console 语法 14 文件 + datadir 单测 11/11;backup.bat 保持纯 ASCII。
2026-09-10 09:17:56 +08:00
AskaEth 6483acf9ad feat: 人员年龄/号码布、图片上传、多显示器菜单、Console 两栏、exe 改名等一批改动
人员与报名:
- 人员唯一标识改为「证件号 或 号码布」二选一(0013/0014 迁移 + 导入匹配/回填/冲突)
- 人员新增「年龄」(0015 迁移):表单/列表/导入模板表头 11 列;冲突比较只在两边
  都有值且不同时才算差异,旧数据不误报
- 冲突决策键改为「证件号优先 → 号码布」(前端原先只用 idCard,号码布行会互相覆盖)
- 报名选择器支持无证件号但有号码布的运动员

大屏与 Console:
- 大屏控制新增「显示器」菜单:可给指定显示器重建全屏窗口;单屏/主显示器强制窗口化,
  限制在 Console 侧判定,不信任页面传参
- Console 服务管理窗口改左右两栏,运行日志独占右栏满高;窗口默认尺寸 1280×860
- 大屏右上角时钟精确到秒(同时把刷新间隔 15s 改为 1s)

图片与配置:
- 新增图片上传 POST /api/uploads(recorder+,png/jpg/webp/gif,≤5MiB)与匿名静态
  访问 GET /uploads/{name}(防目录穿越);文件落赛事项目目录 uploads/,随赛事包
  一起导出/导入
- 「赛事信息」新增赛事会标 / 大屏会标 / 大屏背景图三个上传项
- 参赛单位 logo 输入框右侧加上传按钮

关于页与构建:
- 构建时间打通:version.BuildTime + /api/system/about 返回 + build.bat 注入
  (用 PowerShell 取时间戳,避免本地化 %DATE% 的非 ASCII 星期)

安装包:
- 主程序改名 Scoreboard_Console.exe(win.executableName;productName/显示名不变)
- 记住上次安装目录:自定义 NSIS 宏优先沿用自存路径(卸载不清除),并在 customInit
  里补写回 electron-builder 的键,避免安装模式页把 $INSTDIR 打回默认

自检:服务端 12 包全绿;前端 vue-tsc + build 通过、node --test 58/58;console 12 文件通过。
2026-09-10 09:05:06 +08:00
AskaEth 27bddefaad fix: 上线前快修(大屏自愈 / 奖牌口径 / 聚合作废 / 密码可发现性)
- P0 慢客户端关闭码 1008 → 4000:前端把所有 1008 当「登录失效」并永久停止重连,
  大屏被踢后再也不自愈(服务端 markSlow 改用自定义码,前端逻辑不动)
- P1 REST 与 WS 的奖牌榜补 events.scored = 1 过滤,与导出成绩册口径一致
  (否则「只排名不计分」项目只要挂着通道就会在大屏凭空出奖牌)
- P1 聚合流水作废去掉 source_id 子查询:改通道会重建通道 id,旧聚合流水
  永远匹配不上 → 再插一份 → 分数翻倍
- P1 审核页/历史页的折算系数兜底由 ?? 1 改为 >0 ? : 1:/ws 快照对非 admin
  会把 individualToTeamWeight 置 0,recorder 看到的个人折算分全是 0
- P2 删掉 signature.local.txt 后清理残留的 signature.build.txt,避免继续注入旧署名
- 初始管理员密码:banner 加纯 ASCII 锚 INITIAL ADMIN CREATED,文档改为搜它
  (原来教的 findstr "password=" 已经失效,且中文 findstr 本身不可靠)

自检:服务端 12 包全绿;前端 vue-tsc + build 通过、node --test 24/24;console 语法通过。
2026-09-09 23:13:20 +08:00
AskaEth 8039da384d fix(build): 署名自检改用 Node 字节比对(findstr 在 chcp 65001 下匹配不了 UTF-8 中文)
findstr 会误报 NOT found,而实测 exe 里署名是存在的。改成 verify-signature.mjs
读字节 includes 比对,缺失时让构建硬失败。
2026-09-09 22:21:28 +08:00
AskaEth e7948088df fix(build): 署名注入改走 Node 规范化 + for /f 直读文件
上一版用 PowerShell 管道读取:PS 5.1 的 Get-Content 默认按 ANSI 读,输出再经
cmd(chcp 65001) 解码一次,中文署名被转成乱码 —— 日志写着 injected,但 exe 里的
字节与预期不符(实测 sig_in_exe=False)。
改为 deploy/prepare-signature.mjs 读 UTF-8 并剥 BOM/空白,写出 signature.build.txt
(gitignore),build.bat 用 for /f 直接读文件(不经过任何编码转换)。
另加一条 findstr 自检:注入后若 exe 里找不到署名就打印 [warn]。
2026-09-09 22:19:01 +08:00
AskaEth 13f1f03cd0 fix: 修掉十路审查发现的 9 个 P0 与一批 P1(数据正确性 / 越权 / 现场可用性)
P0(9 条全修):
- 多通道项目奖牌重复计数:domain 层按 (EventID,CategoryID,EntryID/Subject) 去重,
  通道优先级 athlete→team→id
- 「只排名不计分」项目(scored:false)不再进奖牌榜,REST/WS/导出口径统一
- aggregate 流水 entry_id 恒 NULL 导致重算后分数翻倍:作废范围改按 event+category 定位
- 已发布成绩仍可被「存草稿」覆盖并清空 rank:服务端 409 STATE_INVALID + 前端禁编辑
- voidResult / 规则导入重算后名次不回写:接住 Ranked 调 applyComputedRanks
- 赛事包覆盖导入可能「旧项目已删、新项目没成」:先改名成功再清理,失败回滚
- 导入赛事包可覆盖正在运行的赛事目录:name==当前项目直接 400
- Console spawn 失败后守护器永久卡死:清 child/pid + 调度重启 + stop 超时兜底
- /ws 快照向非 admin 下发 admin-only 配置:按角色裁剪 settings

P1(计分口径 / 契约 / 现场):
- standings.tieBreak 三处接线;profiles[].recordBonusMode 生效;破纪录校验
  RecordEligible 与 entry 归属;破纪录登记校验已发布成绩
- export.loadRanked 与主路径对齐;ListBackups reason 解析;CLI backup 前缀修正
  (原来只增不减会撑爆磁盘);单位积分明细/导出统一权重折算;停用单位展示
- 规则导入原子化(重算并入同一事务)+ 返回 compatible/affectedEventCount/
  recalculatedLedgerRows;登录审计 user_id 修正
- WS 策略性断开用 Close(code,reason);HelloMessage 补 page/instanceId;
  实例注册表清理;settings/单位/项目写操作补 change_log 触发大屏刷新
- 大屏:全量快照不再被版本守卫丢弃;个人积分榜刷新;公告返回页/轮播;行数截断;
  REST 竞态;1008 停止重连;握手超时;时区补 Z;401 仅 AUTH_REQUIRED 才登出
- 管理端:published 行禁编辑;saveDraft 补 unit(1:06.33 显示);前端预览改用服务端
  points;空成绩行不再恒「已修改」;修订详情按 id 拉取;切项目请求序号与 dirty 保护;
  发布后刷新项目状态;NAV/路由按角色过滤;recorder 不再打 admin-only 接口
- Console:大屏窗口销毁后重建;大屏 URL 复用 host 归一化;backup.bat 改纯 ASCII
  (已在 Meowhome 实跑验证)

自检:服务端 gofmt/build/vet 通过、12 包测试全绿;前端 vue-tsc + build 通过、
node --test 24/24;console check-syntax 12 文件通过。
2026-09-09 22:16:58 +08:00
AskaEth 2c9ff65fc4 feat: 补齐第一批已知缺口(关闭握手 / 定时备份 / Origin 白名单 / DTO 收敛)
- httpapi:新增 POST /api/shutdown(admin 会话或 X-Shutdown-Token 常量时间比对)
  与 GET /api/rules/switches(recorder 可读,只回布尔开关);settings/standings 的
  重复 DTO 收敛到 internal/dto;standings.showIndividualMedals 贯通到设置读写与前端
- export:抽出 export.Service,新增自动备份定时任务(backup.intervalMinutes/keep),
  自动、手动、发布前三类备份共用同一把互斥锁与滚动清理
- realtime:/ws 去掉 InsecureSkipVerify,改用 OriginPatterns(同源与无 Origin 放行,
  跨站需命中 server.allowedOrigins)
- console:停止服务改走 POST /api/shutdown 优雅关闭(5 秒宽限后回退强杀),
  服务管理器新增「已连接的大屏实例」卡片
- deploy:build.bat 改用 for /f 读内部署名——set /p 在 chcp 65001 下返回空,
  导致最近这次构建的 exe 里根本没注入署名
- docs:备份策略、关闭超时、Origin 配置的说明与实现对齐
2026-09-09 21:41:08 +08:00
AskaEth 4d56c73ae6 fix(build): build.bat 注释改回纯 ASCII
cmd.exe 会错解 .bat 里的 UTF-8 文本,上一版加的中文 REM 让构建日志里
冒出一行 "'PNPM_IGNORED_BUILDS' is not recognized"。文件头部本来就写明必须纯 ASCII。
2026-09-09 21:38:23 +08:00
AskaEth 33d4b39eb9 fix(build): pnpm 11 用 allowBuilds 放行 electron 安装脚本
pnpm 11 起 onlyBuiltDependencies 列表形式被静默忽略,导致
ERR_PNPM_IGNORED_BUILDS 让 pnpm run 的依赖校验直接失败(pnpm run dist 都起不来)。
改为 pnpm 自己写入的 allowBuilds 映射形式,并去掉 build.bat 里的 --ignore-scripts。
另外修复 set VAR=value && ... 的尾随空格:它会把 ELECTRON_MIRROR 变成
'.../electron/ v38.8.6/...' 从而 404。
2026-09-09 21:35:21 +08:00
AskaEth d50f5d7524 fix(build): 恢复安装器许可页文案生成(挪到 prepare-extra.mjs,避免中文进批处理) 2026-09-09 21:19:30 +08:00
AskaEth fc3361f766 fix(build): ensure_electron 始终补写 path.txt 2026-09-09 21:11:50 +08:00
AskaEth d5b45761d7 fix(build): 恢复手动放置 Electron 运行时的步骤(electron-builder 自下会撞 Node 24 bug) 2026-09-09 21:11:02 +08:00
AskaEth c3d2c1416f fix(build): console 安装用 --ignore-scripts,绕开 pnpm 11 的 ERR_PNPM_IGNORED_BUILDS 2026-09-09 21:10:21 +08:00
AskaEth 1399bae59e fix(build): build.bat 全 ASCII + Node 脚本处理中文路径 + pnpm-workspace.yaml 构建脚本白名单 2026-09-09 21:09:38 +08:00
AskaEth de4bd63594 fix(build): build.bat 块内改 ASCII(cmd 对 UTF-8 中文块解析错乱)+ pnpm 允许 electron 构建脚本 2026-09-09 21:09:02 +08:00
AskaEth 7f9701c465 fix: 审查修复波次(P0x4 + P1x30+)
- domain/rules: 计分与排名解耦、破纪录按组别、tieBreak 生效、调整分不丢、移除 aggregate 假能力
- realtime: 新建 internal/dto,快照三项契约对齐,/ws 只认会话身份
- httpapi: 流水幂等、standings 整表载荷、广播接线、强制改密、XFF 防伪造、records 写入、审计、赛事包内容、发布前备份、result.points、实例列表
- web: FormData 上传、YAML 解析、快照归一化、大屏解析层、bootstrap 降级、访客判定、主题切换
- console: 优雅关闭握手、中文化、免验证改管理员账号、选屏与日志轮转修复
- docs: 用户文档三份 + README
- 主代理: 破纪录加分接线(levels 未加载导致恒 0)
2026-09-09 21:06:40 +08:00
AskaEth 7f183d5327 build: 安装器许可页顶部文案自动注入内部署名(构建时生成 .nsh) 2026-09-09 20:39:02 +08:00
AskaEth 2f75c31509 build: 回归 electron-builder 打包(win.icon 写入 PE 图标),下载走 gh-proxy 2026-09-09 20:20:04 +08:00
AskaEth ad3770cfc9 build: 用 rcedit 给 Scoreboard Console.exe 嵌入图标与版本信息 2026-09-09 20:19:02 +08:00
AskaEth 74e48bf5bc build: 署名注入用单引号包裹,支持含空格的值 2026-09-09 20:15:09 +08:00
AskaEth 76e725ca96 feat: 内部署名改为编译期注入(构建机本地文件,不进仓库);关于页展示 2026-09-09 20:07:59 +08:00
AskaEth 5ae55b8057 fix(server): 赛事包导出传入项目名,修复 GET /api/export/project.zip 恒 500 2026-09-09 19:57:23 +08:00
AskaEth e86ca24d0e build: 输出改为 dist\ScoreboardConsole,运行时直接从官方 zip 解压(绕开损坏目录) 2026-09-09 19:36:02 +08:00
AskaEth 7243de93ce build: 运行时只装一次,避免覆盖只读文件被拒 2026-09-09 19:34:28 +08:00
AskaEth 1af62a690e build: build.bat 改用 ASCII 注释 + chcp 65001,避免中文注释被 GBK 解析拆行 2026-09-09 19:33:44 +08:00
AskaEth 29162f5c1d build: Console 改为就地覆盖组装,规避 .pak 只读删除失败 2026-09-09 19:33:07 +08:00
AskaEth 8b792496d6 build: 用 PowerShell 强制清理只读的 Console 产物目录 2026-09-09 19:32:29 +08:00
AskaEth 68ee99a5a2 build: 组装 Console 前先结束旧进程,避免文件占用 2026-09-09 19:31:47 +08:00
AskaEth e47251658b fix(console): 默认端口改 19540;打包改为手动组装便携版(不依赖 GitHub 下载) 2026-09-09 19:15:13 +08:00
AskaEth bc8b1ee6c0 feat: M3-M7 全模块落地 + 集成接线
- M3 认证/权限/审计/限流 + 全部 REST 接口
- M4 管理面板(MIUIx + 成绩录入/积分榜下钻/大屏控制)
- M5a 大屏页面(六页 + 明细覆盖层 + 缩放适配)
- M6 WebSocket 实时同步中心
- M7 xlsx 导出 + 赛事包 zip + 备份
- 规则包 YAML 导入导出(差异预览)
- 字体 vendor 子集化(4 套 x2 字重)
- 集成:realtime/export/rules 接入 main+httpapi;backup 子命令
- 修复:中间件包装 ResponseWriter 丢失 Hijacker,导致 WS 握手 501
2026-09-09 19:02:24 +08:00
AskaEth 0d32903b1a build: 增加 Windows 一键构建脚本 deploy/build.bat 2026-09-09 18:41:03 +08:00