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)
This commit is contained in:
1 parent
8dae63ee70
commit
7f9701c465
61 files changed
+3844
-333
No files matched your search
+31
-70
@@ -2,11 +2,11 @@
|
||||
REM ============================================================================
|
||||
REM Scoreboard 一键备份(Windows)
|
||||
REM
|
||||
REM 用 sqlite3.exe 的 VACUUM INTO 生成一致性快照,服务运行中也能安全执行,
|
||||
REM 不需要停服务、不需要重启。产物落在 data\backups\,滚动保留最近 20 份。
|
||||
REM
|
||||
REM 依赖:sqlite3.exe(放到本脚本同目录、项目根目录,或加入 PATH 均可)。
|
||||
REM 下载地址 https://www.sqlite.org/download.html 的 sqlite-tools-win-x64。
|
||||
REM 调用 scoreboard.exe 的 backup 子命令(内置 VACUUM INTO),服务运行中也能
|
||||
REM 安全执行,不需要停服务、不依赖外部 sqlite3.exe。
|
||||
REM 产物落在 data\backups\,服务端按库(system / 各赛事)各自滚动保留 20 份。
|
||||
REM 注意:只快照 .db,不含 event_projs\<项目>\uploads\ 里的背景图/会标等资源;
|
||||
REM 需要连资源一起留档时,请另行拷贝 data\event_projs\<项目>\uploads\。
|
||||
REM
|
||||
REM 用法:deploy\backup.bat 手动备份(原因记 manual)
|
||||
REM deploy\backup.bat publish 发布前备份(原因记 publish)
|
||||
@@ -17,8 +17,6 @@ chcp 65001 >nul 2>&1
|
||||
cd /d "%~dp0.."
|
||||
set "ROOT=%CD%"
|
||||
set "DATA=%ROOT%\data"
|
||||
set "OUT=%DATA%\backups"
|
||||
set "KEEP=20"
|
||||
set "REASON=manual"
|
||||
|
||||
if not "%~1"=="" set "REASON=%~1"
|
||||
@@ -33,57 +31,51 @@ if not exist "%DATA%" (
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM ---- 定位 sqlite3.exe -------------------------------------------------------
|
||||
set "SQLITE="
|
||||
if exist "%~dp0sqlite3.exe" set "SQLITE=%~dp0sqlite3.exe"
|
||||
if not defined SQLITE if exist "%ROOT%\sqlite3.exe" set "SQLITE=%ROOT%\sqlite3.exe"
|
||||
if not defined SQLITE for %%I in (sqlite3.exe) do if exist "%%~$PATH:I" set "SQLITE=%%~$PATH:I"
|
||||
if not defined SQLITE (
|
||||
echo [错误] 找不到 sqlite3.exe。
|
||||
echo 请把它放到 deploy\ 目录或加入 PATH 后重试。
|
||||
REM ---- 定位 scoreboard.exe ----------------------------------------------------
|
||||
set "EXE="
|
||||
if exist "%~dp0..\dist\scoreboard.exe" set "EXE=%~dp0..\dist\scoreboard.exe"
|
||||
if not defined EXE if exist "%ROOT%\scoreboard.exe" set "EXE=%ROOT%\scoreboard.exe"
|
||||
if not defined EXE if exist "%~dp0scoreboard.exe" set "EXE=%~dp0scoreboard.exe"
|
||||
if not defined EXE for %%I in (scoreboard.exe) do if exist "%%~$PATH:I" set "EXE=%%~$PATH:I"
|
||||
if not defined EXE (
|
||||
echo [错误] 找不到 scoreboard.exe。
|
||||
echo 请先执行 deploy\build.bat,或把它放到项目根目录 / 加入 PATH。
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM ---- 时间戳:优先 PowerShell,避免受区域设置影响 -----------------------------
|
||||
set "TS="
|
||||
for /f "usebackq delims=" %%I in (`powershell -NoProfile -Command "Get-Date -Format yyyyMMdd-HHmmss" 2^>nul`) do set "TS=%%I"
|
||||
if not defined TS call :fallback_ts
|
||||
if not defined TS (
|
||||
echo [错误] 无法生成时间戳。
|
||||
REM dataDir 是相对路径,服务端按当前工作目录解析,所以必须在项目根目录调用
|
||||
if not exist "%ROOT%\config.yaml" (
|
||||
echo [错误] 找不到 %ROOT%\config.yaml,无法定位 dataDir。
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if not exist "%OUT%" mkdir "%OUT%"
|
||||
|
||||
echo === Scoreboard 备份 ===
|
||||
echo 数据目录:%DATA%
|
||||
echo 备份目录:%OUT%
|
||||
echo 时间戳 :%TS%
|
||||
echo 服务端 :%EXE%
|
||||
echo 原因 :%REASON%
|
||||
echo.
|
||||
|
||||
set /a OK=0
|
||||
set /a FAIL=0
|
||||
|
||||
if exist "%DATA%\system.db" call :backup "system" "%DATA%\system.db"
|
||||
|
||||
REM 服务端一次只备份一个赛事库(system.db 每次都会一并快照),按目录逐个调用;
|
||||
REM 部署形态通常只有一个 default 项目,这里就只跑一次。
|
||||
set "FOUND="
|
||||
for /d %%D in ("%DATA%\event_projs\*") do (
|
||||
if exist "%%~fD\event.db" call :backup "%%~nxD" "%%~fD\event.db"
|
||||
set "FOUND=1"
|
||||
echo 备份赛事 %%~nxD
|
||||
"%EXE%" backup -config config.yaml -project "%%~nxD" -reason "%REASON%"
|
||||
if errorlevel 1 (set /a FAIL+=1) else (set /a OK+=1)
|
||||
)
|
||||
|
||||
echo.
|
||||
echo === 滚动清理(保留最近 %KEEP% 份)===
|
||||
set /a N=0
|
||||
for /f "delims=" %%F in ('dir /b /o-d /a-d "%OUT%\*.db" 2^>nul') do (
|
||||
set /a N+=1
|
||||
if !N! GTR %KEEP% (
|
||||
echo 删除 %%F
|
||||
del /f /q "%OUT%\%%F" >nul 2>&1
|
||||
)
|
||||
if not defined FOUND (
|
||||
echo 备份默认赛事
|
||||
"%EXE%" backup -config config.yaml -reason "%REASON%"
|
||||
if errorlevel 1 (set /a FAIL+=1) else (set /a OK+=1)
|
||||
)
|
||||
|
||||
echo.
|
||||
echo === 备份完成:成功 !OK! 个,失败 !FAIL! 个 ===
|
||||
dir /b "%OUT%\*.db" 2>nul
|
||||
dir /b "%DATA%\backups\*.db" 2>nul
|
||||
|
||||
if !FAIL! GTR 0 (
|
||||
endlocal
|
||||
@@ -91,34 +83,3 @@ if !FAIL! GTR 0 (
|
||||
)
|
||||
endlocal
|
||||
exit /b 0
|
||||
|
||||
REM ---- 备份单个库:%1 文件名前缀,%2 数据库路径 -------------------------------
|
||||
:backup
|
||||
set "PREFIX=%~1"
|
||||
set "DBFILE=%~2"
|
||||
set "TARGET=%OUT%\%PREFIX%-%REASON%-%TS%.db"
|
||||
if exist "%TARGET%" set "TARGET=%OUT%\%PREFIX%-%REASON%-%TS%-%RANDOM%.db"
|
||||
|
||||
echo 备份 %DBFILE%
|
||||
echo -^> %TARGET%
|
||||
"%SQLITE%" "%DBFILE%" "VACUUM INTO '%TARGET%'"
|
||||
if errorlevel 1 (
|
||||
echo [失败] sqlite3 返回错误
|
||||
set /a FAIL+=1
|
||||
) else (
|
||||
set /a OK+=1
|
||||
)
|
||||
exit /b 0
|
||||
|
||||
REM ---- %DATE%/%TIME% 兜底:只保证名字不重复 -----------------------------------
|
||||
:fallback_ts
|
||||
set "D=%DATE%"
|
||||
set "T=%TIME%"
|
||||
set "D=%D:/=%"
|
||||
set "D=%D:-=%"
|
||||
set "D=%D:.=%"
|
||||
set "T=%T::=%"
|
||||
set "T=%T:.=%"
|
||||
set "T=%T: =0%"
|
||||
set "TS=%D%-%T%"
|
||||
exit /b 0
|
||||
Reference in new issue
Block a user