package handler import ( "photowall/internal/middleware" "photowall/internal/model" "photowall/internal/service" "photowall/pkg/response" "strconv" "strings" "github.com/gin-gonic/gin" ) type SchoolHandler struct { svc *service.SchoolService } func NewSchoolHandler(svc *service.SchoolService) *SchoolHandler { return &SchoolHandler{svc: svc} } // List GET /api/schools or /api/admin/schools func (h *SchoolHandler) List(c *gin.Context) { var q service.SchoolQuery if err := c.ShouldBindQuery(&q); err != nil { response.BadRequest(c, "参数错误") return } result, err := h.svc.List(&q) if err != nil { response.Internal(c, err.Error()) return } response.OK(c, result) } // Stats GET /api/admin/schools/stats func (h *SchoolHandler) Stats(c *gin.Context) { stats, err := h.svc.Stats() if err != nil { response.Internal(c, err.Error()) return } response.OK(c, stats) } // Create POST /api/schools or /api/admin/schools func (h *SchoolHandler) Create(c *gin.Context) { var body struct { RegionID uint `json:"region_id"` Name string `json:"name"` NameEn string `json:"name_en"` SchoolType model.SchoolType `json:"school_type"` // 兼容旧的单选提交 SchoolTypes []string `json:"school_types"` // 新的多选提交 Address string `json:"address"` Status model.SchoolStatus `json:"status"` } if err := c.ShouldBindJSON(&body); err != nil { response.BadRequest(c, "参数错误") return } types := model.NormalizeSchoolTypes(body.SchoolTypes) if len(types) == 0 && body.SchoolType != "" { types = model.NormalizeSchoolTypes([]string{string(body.SchoolType)}) } if len(types) == 0 { response.BadRequest(c, "请选择学校类型") return } school := model.School{ RegionID: body.RegionID, Name: strings.TrimSpace(body.Name), NameEn: strings.TrimSpace(body.NameEn), SchoolType: types[0], SchoolTypes: model.JoinSchoolTypes(types), Address: strings.TrimSpace(body.Address), Status: body.Status, } if uid := middleware.CurrentUserID(c); uid > 0 { school.CreatedBy = uid } if err := h.svc.Create(&school); err != nil { response.BadRequest(c, err.Error()) return } response.Created(c, school) } // Get GET /api/schools/:id func (h *SchoolHandler) Get(c *gin.Context) { id, _ := strconv.ParseUint(c.Param("id"), 10, 64) school, err := h.svc.GetByID(uint(id)) if err != nil { response.NotFound(c, err.Error()) return } // 附带学院列表 colleges, _ := h.svc.ListColleges(uint(id)) response.OK(c, gin.H{"school": school, "colleges": colleges}) } // Update PUT /api/schools/:id func (h *SchoolHandler) Update(c *gin.Context) { id, _ := strconv.ParseUint(c.Param("id"), 10, 64) var body map[string]interface{} if err := c.ShouldBindJSON(&body); err != nil { response.BadRequest(c, "参数错误") return } updates := map[string]interface{}{} if v, ok := body["name"]; ok { updates["name"] = v } if v, ok := body["name_en"]; ok { updates["name_en"] = v } // 多学段:优先取数组形式的 school_types if v, ok := body["school_types"]; ok { switch raw := v.(type) { case []interface{}: items := make([]string, 0, len(raw)) for _, item := range raw { if s, ok := item.(string); ok { items = append(items, s) } } updates["school_types"] = model.JoinSchoolTypes(model.NormalizeSchoolTypes(items)) case string: updates["school_types"] = raw } } else if v, ok := body["school_type"]; ok { // 兼容旧的单选提交:同步写入两个字段 if s, ok := v.(string); ok { updates["school_types"] = s } } if v, ok := body["address"]; ok { updates["address"] = v } if v, ok := body["region_id"]; ok { updates["region_id"] = v } if v, ok := body["status"]; ok { updates["status"] = v } if v, ok := body["reject_reason"]; ok { updates["reject_reason"] = v } if err := h.svc.Update(uint(id), updates); err != nil { response.BadRequest(c, err.Error()) return } response.OK(c, gin.H{"message": "更新成功"}) } // Approve POST /api/admin/schools/:id/approve func (h *SchoolHandler) Approve(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil || id == 0 { response.BadRequest(c, "无效的学校ID") return } if err := h.svc.Approve(uint(id)); err != nil { response.BadRequest(c, err.Error()) return } response.OK(c, gin.H{"message": "审核通过"}) } // Reject POST /api/admin/schools/:id/reject func (h *SchoolHandler) Reject(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil || id == 0 { response.BadRequest(c, "无效的学校ID") return } var body struct { Reason string `json:"reason" binding:"required"` } if err := c.ShouldBindJSON(&body); err != nil || strings.TrimSpace(body.Reason) == "" { response.BadRequest(c, "请输入打回原因") return } if err := h.svc.Reject(uint(id), strings.TrimSpace(body.Reason)); err != nil { response.BadRequest(c, err.Error()) return } response.OK(c, gin.H{"message": "打回成功"}) } // Delete DELETE /api/schools/:id func (h *SchoolHandler) Delete(c *gin.Context) { id, _ := strconv.ParseUint(c.Param("id"), 10, 64) if err := h.svc.Delete(uint(id)); err != nil { response.BadRequest(c, err.Error()) return } response.OK(c, gin.H{"message": "删除成功"}) } // ---- 学院 ---- // ListColleges GET /api/schools/:id/colleges func (h *SchoolHandler) ListColleges(c *gin.Context) { id, _ := strconv.ParseUint(c.Param("id"), 10, 64) list, err := h.svc.ListColleges(uint(id)) if err != nil { response.Internal(c, err.Error()) return } response.OK(c, list) } // CreateCollege POST /api/schools/:id/colleges func (h *SchoolHandler) CreateCollege(c *gin.Context) { id, _ := strconv.ParseUint(c.Param("id"), 10, 64) var body struct { Name string `json:"name" binding:"required"` } if err := c.ShouldBindJSON(&body); err != nil { response.BadRequest(c, "学院名称不能为空") return } college, err := h.svc.CreateCollege(uint(id), body.Name) if err != nil { response.BadRequest(c, err.Error()) return } response.Created(c, college) } // UpdateCollege PUT /api/colleges/:id func (h *SchoolHandler) UpdateCollege(c *gin.Context) { id, _ := strconv.ParseUint(c.Param("id"), 10, 64) var body struct { Name string `json:"name" binding:"required"` } if err := c.ShouldBindJSON(&body); err != nil { response.BadRequest(c, "学院名称不能为空") return } if err := h.svc.UpdateCollege(uint(id), body.Name); err != nil { response.BadRequest(c, err.Error()) return } response.OK(c, gin.H{"message": "更新成功"}) } // DeleteCollege DELETE /api/colleges/:id func (h *SchoolHandler) DeleteCollege(c *gin.Context) { id, _ := strconv.ParseUint(c.Param("id"), 10, 64) if err := h.svc.DeleteCollege(uint(id)); err != nil { response.BadRequest(c, err.Error()) return } response.OK(c, gin.H{"message": "删除成功"}) }