package handlers import ( "errors" "strconv" "material_texture/internal/models" "material_texture/internal/repository" "material_texture/pkg/response" "github.com/gin-gonic/gin" "gorm.io/gorm" ) type MaterialHandler struct { repo *repository.MaterialRepository } func NewMaterialHandler(repo *repository.MaterialRepository) *MaterialHandler { return &MaterialHandler{repo: repo} } // List 获取材质列表 // GET /api/v1/materials?page=1&page_size=20&name=xxx func (h *MaterialHandler) List(c *gin.Context) { var query models.MaterialListQuery if err := c.ShouldBindQuery(&query); err != nil { response.BadRequest(c, "invalid query parameters") return } // 设置默认值 if query.Page < 1 { query.Page = 1 } if query.PageSize < 1 || query.PageSize > 100 { query.PageSize = 20 } materials, total, err := h.repo.List(query) if err != nil { response.InternalError(c, "failed to fetch materials") return } response.SuccessPaged(c, materials, total, query.Page, query.PageSize) } // GetByID 获取单个材质详情 // GET /api/v1/materials/:id func (h *MaterialHandler) GetByID(c *gin.Context) { id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { response.BadRequest(c, "invalid material id") return } material, err := h.repo.GetByID(id) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { response.NotFound(c, "material not found") return } response.InternalError(c, "failed to fetch material") return } response.Success(c, material) } // Create 创建材质 // POST /api/v1/materials func (h *MaterialHandler) Create(c *gin.Context) { var req models.MaterialRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "invalid request body: "+err.Error()) return } material := &models.Material{ Name: req.Name, DiffuseR: req.DiffuseR, DiffuseG: req.DiffuseG, DiffuseB: req.DiffuseB, Alpha: req.Alpha, Shininess: req.Shininess, SpecularR: req.SpecularR, SpecularG: req.SpecularG, SpecularB: req.SpecularB, AmbientR: req.AmbientR, AmbientG: req.AmbientG, AmbientB: req.AmbientB, Metallic: req.Metallic, Roughness: req.Roughness, Reflectance: req.Reflectance, } if err := h.repo.Create(material); err != nil { response.InternalError(c, "failed to create material") return } response.Created(c, material) } // Update 更新材质 (优化: 单次查询) // PUT /api/v1/materials/:id func (h *MaterialHandler) Update(c *gin.Context) { id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { response.BadRequest(c, "invalid material id") return } var req models.MaterialRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "invalid request body: "+err.Error()) return } // 直接更新,通过 RowsAffected 判断是否存在 updates := map[string]interface{}{ "name": req.Name, "diffuse_r": req.DiffuseR, "diffuse_g": req.DiffuseG, "diffuse_b": req.DiffuseB, "alpha": req.Alpha, "shininess": req.Shininess, "specular_r": req.SpecularR, "specular_g": req.SpecularG, "specular_b": req.SpecularB, "ambient_r": req.AmbientR, "ambient_g": req.AmbientG, "ambient_b": req.AmbientB, "metallic": req.Metallic, "roughness": req.Roughness, "reflectance": req.Reflectance, } rowsAffected, err := h.repo.UpdateByID(id, updates) if err != nil { response.InternalError(c, "failed to update material") return } if rowsAffected == 0 { response.NotFound(c, "material not found") return } // 返回更新后的数据 material, _ := h.repo.GetByID(id) response.Success(c, material) } // Delete 删除材质 (优化: 单次查询,通过 RowsAffected 判断) // DELETE /api/v1/materials/:id func (h *MaterialHandler) Delete(c *gin.Context) { id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { response.BadRequest(c, "invalid material id") return } // 直接删除,通过 RowsAffected 判断是否存在 rowsAffected, err := h.repo.DeleteByID(id) if err != nil { response.InternalError(c, "failed to delete material") return } if rowsAffected == 0 { response.NotFound(c, "material not found") return } response.Success(c, gin.H{"id": id}) }