From 0e653e653ff6f365553553decd0d4bac832d272d Mon Sep 17 00:00:00 2001 From: zhouwentao Date: Fri, 19 Dec 2025 08:42:55 +0800 Subject: [PATCH] updates --- .vscode/settings.json | 9 ++- project_doing.md | 18 +++++ project_index.md | 1 + .../yx/controller/yx_user_score_controller.go | 65 +++++++++++++++++++ server/modules/yx/dto/yx_user_score_dto.go | 56 ++++++++++++++++ task_detail.md | 11 ++-- 6 files changed, 154 insertions(+), 6 deletions(-) create mode 100644 server/modules/yx/dto/yx_user_score_dto.go diff --git a/.vscode/settings.json b/.vscode/settings.json index 62ef4f0..de95476 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,13 @@ { "kiroAgent.configureMCP": "Disabled", "cSpell.words": [ - "Cognitio" + "Cognitio", + "Fzby", + "gonic", + "Xjysby", + "Xjysdy", + "Yybyqy", + "Yybysy", + "Yyjy" ] } \ No newline at end of file diff --git a/project_doing.md b/project_doing.md index 7bd74c8..bff4c27 100644 --- a/project_doing.md +++ b/project_doing.md @@ -29,3 +29,21 @@ - **修改结果**: - `server/middleware/cors.go`: 创建了 CORS 中间件,允许 `Origin` 头部指定的来源,并放行 `OPTIONS` 请求。 - `server/main.go`: 全局注册了 CORS 中间件。 + +### [任务执行] 实现用户成绩保存接口 +- **操作目标**: 根据 Task4.md 要求,实现用户成绩信息的保存接口,并包含特定的业务校验逻辑。 +- **影响范围**: `server/modules/yx/controller/yx_user_score_controller.go` +- **修改前记录**: `YxUserScoreController` 仅有基本的 CRUD 接口。 +- **修改结果**: + - 定义了 `SaveScoreRequest` 结构体,包含严格的字段校验逻辑(文理分科、科目限制、成绩范围等)。 + - 实现了 `SaveUserScore` 方法,处理 DTO 到 Entity 的转换(包括科目列表拼接、子专业成绩映射)。 + - 注册了 `POST /yx-user-scores/save-score` 路由。 + +### [任务执行] 重构 DTO 代码结构 +- **操作目标**: 将 `SaveScoreRequest` 结构体从 Controller 中分离到独立的 DTO 包中。 +- **影响范围**: `server/modules/yx/dto/yx_user_score_dto.go`, `server/modules/yx/controller/yx_user_score_controller.go` +- **修改前记录**: DTO 结构体直接定义在 Controller 文件中。 +- **修改结果**: + - 创建了 `server/modules/yx/dto/` 目录。 + - 将 `SaveScoreRequest` 及其校验逻辑移动到 `yx_user_score_dto.go`。 + - Controller 改为引用 `dto` 包。 diff --git a/project_index.md b/project_index.md index cb08062..1b25336 100644 --- a/project_index.md +++ b/project_index.md @@ -19,6 +19,7 @@ - `modules/`: 业务模块目录。 - `system/`: 系统管理模块(用户、权限等)。 - `yx/`: 艺考相关业务模块。 + - `dto/`: 数据传输对象,用于接口请求/响应定义。 - `entity/`: 实体定义。 - `mapper/`: 数据访问层实现。 - `service/`: 业务逻辑层实现。 diff --git a/server/modules/yx/controller/yx_user_score_controller.go b/server/modules/yx/controller/yx_user_score_controller.go index abd4aa0..cef3f43 100644 --- a/server/modules/yx/controller/yx_user_score_controller.go +++ b/server/modules/yx/controller/yx_user_score_controller.go @@ -3,9 +3,11 @@ package controller import ( "server/common" + "server/modules/yx/dto" "server/modules/yx/entity" "server/modules/yx/service" "strconv" + "strings" "github.com/gin-gonic/gin" ) @@ -25,11 +27,74 @@ func (ctrl *YxUserScoreController) RegisterRoutes(rg *gin.RouterGroup) { group.GET("", ctrl.List) group.GET("/:id", ctrl.Get) group.POST("", ctrl.Create) + group.POST("/save-score", ctrl.SaveUserScore) // 新增接口 group.PUT("/:id", ctrl.Update) group.DELETE("/:id", ctrl.Delete) } } +// SaveUserScore 保存用户成绩 +// @Summary 保存用户成绩 +// @Tags 用户分数 +// @Param request body dto.SaveScoreRequest true "成绩信息" +// @Success 200 {object} common.Response +// @Router /yx-user-scores/save-score [post] +func (ctrl *YxUserScoreController) SaveUserScore(c *gin.Context) { + var req dto.SaveScoreRequest + if err := c.ShouldBindJSON(&req); err != nil { + common.Error(c, 400, "参数错误: "+err.Error()) + return + } + if err := req.Validate(); err != nil { + common.Error(c, 400, "校验失败: "+err.Error()) + return + } + + // 转换为 Entity + entityItem := entity.YxUserScore{ + CognitioPolyclinic: req.CognitioPolyclinic, + Subjects: strings.Join(req.SubjectList, ","), + ProfessionalCategory: req.ProfessionalCategory, + ProfessionalCategoryChildren: strings.Join(req.ProfessionalCategoryChildren, ","), + ProfessionalScore: *req.ProfessionalScore, + CulturalScore: *req.CulturalScore, + EnglishScore: *req.EnglishScore, + ChineseScore: *req.ChineseScore, + Province: req.Province, + State: "1", // 默认状态 + Type: "2", // 艺术类 + } + + // 映射子专业成绩 + scoreMap := req.ProfessionalCategoryChildrenScore + if v, ok := scoreMap["音乐表演声乐"]; ok { + entityItem.Yybysy = v + } + if v, ok := scoreMap["音乐表演器乐"]; ok { + entityItem.Yybyqy = v + } + if v, ok := scoreMap["音乐教育"]; ok { + entityItem.Yyjy = v + } + if v, ok := scoreMap["戏剧影视导演"]; ok { + entityItem.Xjysdy = v + } + if v, ok := scoreMap["戏剧影视表演"]; ok { + entityItem.Xjysby = v + } + if v, ok := scoreMap["服装表演"]; ok { + entityItem.Fzby = v + } + + // 调用 Service 保存 + if err := ctrl.service.Create(&entityItem); err != nil { + common.Error(c, 500, "保存失败: "+err.Error()) + return + } + + common.Success(c, entityItem) +} + // List 获取用户分数列表 // @Summary 获取用户分数列表 // @Tags 用户分数 diff --git a/server/modules/yx/dto/yx_user_score_dto.go b/server/modules/yx/dto/yx_user_score_dto.go new file mode 100644 index 0000000..db6fb18 --- /dev/null +++ b/server/modules/yx/dto/yx_user_score_dto.go @@ -0,0 +1,56 @@ +package dto + +import ( + "errors" +) + +// SaveScoreRequest 保存成绩请求 +type SaveScoreRequest struct { + CognitioPolyclinic string `json:"CognitioPolyclinic" binding:"required"` + SubjectList []string `json:"SubjectList" binding:"required"` + ProfessionalCategory string `json:"ProfessionalCategory" binding:"required"` + ProfessionalCategoryChildren []string `json:"ProfessionalCategoryChildren" binding:"required"` + ProfessionalCategoryChildrenScore map[string]float64 `json:"ProfessionalCategoryChildrenScore" binding:"required"` + ProfessionalScore *float64 `json:"ProfessionalScore" binding:"required"` + CulturalScore *float64 `json:"CulturalScore" binding:"required"` + EnglishScore *float64 `json:"EnglishScore" binding:"required"` + ChineseScore *float64 `json:"ChineseScore" binding:"required"` + Province string `json:"Province" binding:"required"` +} + +func (req *SaveScoreRequest) Validate() error { + if req.CognitioPolyclinic != "文科" && req.CognitioPolyclinic != "理科" { + return errors.New("CognitioPolyclinic必须是'文科'或'理科'") + } + if len(req.SubjectList) != 2 { + return errors.New("SubjectList有且只能传两个值") + } + validSubjects := map[string]bool{"地理": true, "政治": true, "历史": true, "化学": true, "生物": true} + for _, s := range req.SubjectList { + if !validSubjects[s] { + return errors.New("SubjectList参数有误") + } + } + if !isValidScore(*req.ProfessionalScore, 300) { + return errors.New("ProfessionalScore必须在0-300之间") + } + if !isValidScore(*req.CulturalScore, 300) { + return errors.New("CulturalScore必须在0-300之间") + } + if !isValidScore(*req.EnglishScore, 150) { + return errors.New("EnglishScore必须在0-150之间") + } + if !isValidScore(*req.ChineseScore, 150) { + return errors.New("ChineseScore必须在0-150之间") + } + for k, v := range req.ProfessionalCategoryChildrenScore { + if !isValidScore(v, 300) { + return errors.New("ProfessionalCategoryChildrenScore[" + k + "]必须在0-300之间") + } + } + return nil +} + +func isValidScore(score float64, max float64) bool { + return score >= 0 && score <= max +} diff --git a/task_detail.md b/task_detail.md index 90f6988..368ccab 100644 --- a/task_detail.md +++ b/task_detail.md @@ -1,8 +1,9 @@ # 任务执行摘要 -## 会话 ID: 20251217-03 -- **执行原因**: 用户在本地调试 Vue3 项目时遇到 CORS 跨域问题,请求无法成功。 +## 会话 ID: 20251217-05 +- **执行原因**: 用户要求重构代码,将 DTO 结构体从 Controller 中分离到独立的包中。 - **执行过程**: - 1. 创建 `server/middleware/cors.go`,实现了一个通用的 CORS 中间件,允许请求携带 Origin 头,支持常用 HTTP 方法,并自动处理 OPTIONS 预检请求。 - 2. 修改 `server/main.go`,在全局中间件链中注册了 `CorsMiddleware`。 -- **执行结果**: 后端服务现在支持跨域请求,Vue3 前端可以正常调用接口。 + 1. 创建了 `server/modules/yx/dto/` 目录。 + 2. 创建了 `server/modules/yx/dto/yx_user_score_dto.go`,将 `SaveScoreRequest` 结构体及 `Validate` 方法移动至此。 + 3. 修改 `server/modules/yx/controller/yx_user_score_controller.go`,引入 `dto` 包并使用 `dto.SaveScoreRequest`。 +- **执行结果**: 代码结构更清晰,符合 DTO 分层规范。