Files
material_texture/internal/handlers/material.go
likegears 85ba15c564 Initial commit: Material Texture API service
- Go + Gin + GORM + PostgreSQL backend
- RESTful API for material management
- Docker deployment support
- Database partitioning for billion-scale data
- API documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 15:29:49 +08:00

179 lines
4.2 KiB
Go

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})
}