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 配置的说明与实现对齐
This commit is contained in:
1 parent
4d56c73ae6
commit
2c9ff65fc4
42 files changed
+1271
-275
No files matched your search
@@ -1,7 +1,5 @@
|
||||
package httpapi
|
||||
|
||||
import "git.yeij.top/AskaEth/Scoreboard/server/internal/domain"
|
||||
|
||||
// 本文件是 REST 的 JSON 契约(camelCase,与 web/src/shared/types.ts 一一对应)。
|
||||
// 数据库列是 snake_case,转换集中放在 repo.go 的扫描函数里。
|
||||
|
||||
@@ -135,22 +133,6 @@ type resultDTO struct {
|
||||
Points *float64 `json:"points,omitempty"`
|
||||
}
|
||||
|
||||
type standingRowDTO struct {
|
||||
TeamID int64 `json:"teamId"`
|
||||
TeamCode string `json:"teamCode"`
|
||||
TeamName string `json:"teamName"`
|
||||
ShortName *string `json:"shortName"`
|
||||
Color *string `json:"color"`
|
||||
LogoPath *string `json:"logoPath"`
|
||||
Rank int `json:"rank"`
|
||||
Gold int `json:"gold"`
|
||||
Silver int `json:"silver"`
|
||||
Bronze int `json:"bronze"`
|
||||
MedalTotal int `json:"medalTotal"`
|
||||
TotalPoints float64 `json:"totalPoints"`
|
||||
RankChange *int `json:"rankChange"`
|
||||
}
|
||||
|
||||
type athleteStandingDTO struct {
|
||||
Rank int `json:"rank"`
|
||||
AthleteID int64 `json:"athleteId"`
|
||||
@@ -254,37 +236,7 @@ type backupResultDTO struct {
|
||||
CreatedAt string `json:"createdAt"`
|
||||
}
|
||||
|
||||
// eventSettingsDTO 是 GET/PUT /api/settings 的响应;服务端把 settings 表的点号键聚合成嵌套对象。
|
||||
type eventSettingsDTO struct {
|
||||
Event eventSettingsEvent `json:"event"`
|
||||
Display eventSettingsDisplay `json:"display"`
|
||||
Standings eventSettingsStandings `json:"standings"`
|
||||
DefaultProfileID *int64 `json:"defaultProfileId"`
|
||||
RequireApproval bool `json:"requireApproval"`
|
||||
}
|
||||
|
||||
type eventSettingsEvent struct {
|
||||
Name string `json:"name"`
|
||||
Subtitle *string `json:"subtitle"`
|
||||
Host *string `json:"host"`
|
||||
LogoPath *string `json:"logoPath"`
|
||||
PrimaryColor *string `json:"primaryColor"`
|
||||
}
|
||||
|
||||
type eventSettingsDisplay struct {
|
||||
Background *string `json:"background"`
|
||||
Logo *string `json:"logo"`
|
||||
Title string `json:"title"`
|
||||
Subtitle *string `json:"subtitle"`
|
||||
PrimaryColor *string `json:"primaryColor"`
|
||||
RotateSecond int `json:"rotateSeconds"`
|
||||
}
|
||||
|
||||
type eventSettingsStandings struct {
|
||||
IndividualToTeamWeight float64 `json:"individualToTeamWeight"`
|
||||
RankingMode string `json:"rankingMode"`
|
||||
ShowIndividualBoard bool `json:"showIndividualBoard"`
|
||||
}
|
||||
// GET/PUT /api/settings 的线上结构见 internal/dto.EventSettings(与 snapshot.settings 共用)。
|
||||
|
||||
// ---------- 用户管理 ----------
|
||||
|
||||
@@ -362,41 +314,6 @@ type revisionTeamDeltaDTO struct {
|
||||
|
||||
// ---------- domain → DTO ----------
|
||||
|
||||
func standingRowsDTO(rows []domain.StandingsRow, teams map[int64]teamDTO) []standingRowDTO {
|
||||
out := make([]standingRowDTO, 0, len(rows))
|
||||
for _, r := range rows {
|
||||
t := teams[r.TeamID]
|
||||
dto := standingRowDTO{
|
||||
TeamID: r.TeamID,
|
||||
TeamCode: r.Code,
|
||||
TeamName: r.Name,
|
||||
ShortName: nilIfEmpty(r.ShortName),
|
||||
Rank: r.Rank,
|
||||
Gold: r.Gold,
|
||||
Silver: r.Silver,
|
||||
Bronze: r.Bronze,
|
||||
MedalTotal: r.Medals,
|
||||
TotalPoints: r.Points,
|
||||
RankChange: nil,
|
||||
}
|
||||
if t.ID != 0 {
|
||||
dto.Color = t.Color
|
||||
dto.LogoPath = t.LogoPath
|
||||
if dto.TeamCode == "" {
|
||||
dto.TeamCode = t.Code
|
||||
}
|
||||
if dto.TeamName == "" {
|
||||
dto.TeamName = t.Name
|
||||
}
|
||||
if dto.ShortName == nil {
|
||||
dto.ShortName = t.ShortName
|
||||
}
|
||||
}
|
||||
out = append(out, dto)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func nilIfEmpty(s string) *string {
|
||||
if s == "" {
|
||||
return nil
|
||||
|
||||
Reference in new issue
Block a user