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
@@ -83,7 +83,57 @@ func queryResults(ctx context.Context, q queryer, query string, args ...any) ([]
|
||||
}
|
||||
out = append(out, r)
|
||||
}
|
||||
return out, rows.Err()
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, internal(err)
|
||||
}
|
||||
if err := attachResultPoints(ctx, q, out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// attachResultPoints 给已发布成绩补上得分(该成绩产生的 result 流水合计)。
|
||||
// 草稿没有流水,保持 nil;录入页据此预览发布后的分值变化。
|
||||
func attachResultPoints(ctx context.Context, q queryer, items []resultDTO) error {
|
||||
ids := make([]any, 0, len(items))
|
||||
index := make(map[int64]int, len(items))
|
||||
for i := range items {
|
||||
if items[i].State != "published" {
|
||||
continue
|
||||
}
|
||||
ids = append(ids, items[i].ID)
|
||||
index[items[i].ID] = i
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
rows, err := q.QueryContext(ctx,
|
||||
`SELECT result_id, SUM(points) FROM score_ledger
|
||||
WHERE voided = 0 AND source_type = 'result' AND result_id IN (`+placeholders(len(ids))+`)
|
||||
GROUP BY result_id`, ids...)
|
||||
if err != nil {
|
||||
return internal(err)
|
||||
}
|
||||
defer func() { _ = rows.Close() }()
|
||||
|
||||
for rows.Next() {
|
||||
var (
|
||||
resultID int64
|
||||
points float64
|
||||
)
|
||||
if err := rows.Scan(&resultID, &points); err != nil {
|
||||
return internal(err)
|
||||
}
|
||||
if i, ok := index[resultID]; ok {
|
||||
v := points
|
||||
items[i].Points = &v
|
||||
}
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return internal(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *server) getResult(ctx context.Context, id int64) (resultDTO, error) {
|
||||
@@ -94,7 +144,11 @@ func (s *server) getResult(ctx context.Context, id int64) (resultDTO, error) {
|
||||
if err != nil {
|
||||
return resultDTO{}, internal(err)
|
||||
}
|
||||
return r, nil
|
||||
items := []resultDTO{r}
|
||||
if err := attachResultPoints(ctx, s.ev, items); err != nil {
|
||||
return resultDTO{}, err
|
||||
}
|
||||
return items[0], nil
|
||||
}
|
||||
|
||||
func (s *server) listResultsPage(ctx context.Context, eventID int64, state string, page, size int) (pageResult[resultDTO], error) {
|
||||
@@ -194,8 +248,8 @@ func joinAnd(parts []string) string {
|
||||
|
||||
// ---------- ledger ----------
|
||||
|
||||
func (s *server) activeLedger(ctx context.Context) ([]domain.LedgerEntry, error) {
|
||||
return queryLedger(ctx, s.ev, `SELECT id, team_id, athlete_id, event_id, entry_id, result_id,
|
||||
func (s *server) activeLedger(ctx context.Context, q queryer) ([]domain.LedgerEntry, error) {
|
||||
return queryLedger(ctx, q, `SELECT id, team_id, athlete_id, event_id, entry_id, result_id,
|
||||
source_type, source_id, points, voided, created_at FROM score_ledger WHERE voided = 0`)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user