支持项目编码访问单项目公示屏

需求:无需查询公示 Token,直接通过项目编码打开单项目公示页。

实现:规范化项目编码并按 code 查询,同时保留既有 Token 哈希查询;补充前后端及集成回归测试。
This commit is contained in:
2026-07-31 17:11:21 +08:00
parent 78df07e074
commit 9948c23bef
8 changed files with 108 additions and 8 deletions

View File

@@ -288,14 +288,27 @@ type displaySnapshotDTO struct {
LastUpdatedAt time.Time `json:"last_updated_at"`
}
func (s *Server) displaySnapshot(w http.ResponseWriter, r *http.Request) {
token := strings.TrimSpace(r.PathValue("token"))
if len(token) < 40 || len(token) > 128 {
writeError(w, &apiError{Status: http.StatusNotFound, Code: "DISPLAY_NOT_FOUND", Message: "公示屏绑定不存在"})
return
func normalizeDisplayProjectCode(value string) (string, bool) {
code := strings.ToUpper(strings.TrimSpace(value))
if !projectCodePattern.MatchString(code) {
return "", false
}
return code, true
}
func (s *Server) displaySnapshot(w http.ResponseWriter, r *http.Request) {
identifier := strings.TrimSpace(r.PathValue("token"))
var project model.Project
err := s.db.WithContext(r.Context()).Where("display_token_hash = ?", security.HashToken(token)).First(&project).Error
var err error
if code, ok := normalizeDisplayProjectCode(identifier); ok {
err = s.db.WithContext(r.Context()).Where("code = ?", code).First(&project).Error
} else {
if len(identifier) < 40 || len(identifier) > 128 {
writeError(w, &apiError{Status: http.StatusNotFound, Code: "DISPLAY_NOT_FOUND", Message: "公示屏绑定不存在"})
return
}
err = s.db.WithContext(r.Context()).Where("display_token_hash = ?", security.HashToken(identifier)).First(&project).Error
}
if err != nil {
writeError(w, mapNotFound(err, "DISPLAY_NOT_FOUND", "公示屏绑定不存在"))
return