- 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 配置的说明与实现对齐
32 lines
1.9 KiB
Go
32 lines
1.9 KiB
Go
// Package export 负责成绩导出(xlsx)、赛事项目包(zip)与数据库备份。
|
||
//
|
||
// 本包只做三件事:把数据整理成可直接打印的表格、把整场赛事打包/解包、把库
|
||
// 备份成一致性快照。所有业务数值(积分、名次、奖牌)都来自调用方传入的
|
||
// domain 结构体或赛事库本身,这里不重新实现任何计分规则——规则只有一份,
|
||
// 在 internal/domain。
|
||
//
|
||
// 依赖方向:export → domain(只读类型)与 database/sql;domain 不认识 export。
|
||
package export
|
||
|
||
import "errors"
|
||
|
||
// 导出的哨兵错误,调用方据此把失败原因映射成 HTTP 状态码或界面提示。
|
||
var (
|
||
// ErrNoDatabase 表示调用方传入了空的数据库连接。
|
||
ErrNoDatabase = errors.New("export: 数据库连接为空")
|
||
// ErrNoDir 表示未配置备份目录。
|
||
ErrNoDir = errors.New("export: 备份目录为空")
|
||
// ErrInvalidPackage 表示赛事项目包结构非法(缺 meta.yaml、路径穿越、校验信息缺失等)。
|
||
ErrInvalidPackage = errors.New("export: 赛事项目包非法")
|
||
// ErrUnsupportedVersion 表示包内 meta.yaml 的格式版本高于当前程序能读的版本。
|
||
ErrUnsupportedVersion = errors.New("export: 赛事项目包格式版本不受支持")
|
||
// ErrChecksumMismatch 表示包内文件与 meta.yaml 记录的校验和不一致。
|
||
ErrChecksumMismatch = errors.New("export: 赛事项目包校验和不匹配")
|
||
// ErrProjectExists 表示目标目录已有同名赛事项目,且调用方未选择覆盖。
|
||
ErrProjectExists = errors.New("export: 目标赛事项目已存在")
|
||
// ErrUnsafeName 表示赛事项目名含有路径分隔符、保留名等不安全的字符。
|
||
ErrUnsafeName = errors.New("export: 赛事项目名非法")
|
||
// ErrTeamNotFound 表示导出单位积分明细时找不到该单位。
|
||
ErrTeamNotFound = errors.New("export: 单位不存在")
|
||
)
|