- 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>
158 lines
3.9 KiB
Go
158 lines
3.9 KiB
Go
package handlers
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
"material_texture/internal/models"
|
|
"material_texture/internal/repository"
|
|
"material_texture/pkg/response"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type BindingHandler struct {
|
|
bindingRepo *repository.BindingRepository
|
|
materialRepo *repository.MaterialRepository
|
|
}
|
|
|
|
func NewBindingHandler(bindingRepo *repository.BindingRepository, materialRepo *repository.MaterialRepository) *BindingHandler {
|
|
return &BindingHandler{
|
|
bindingRepo: bindingRepo,
|
|
materialRepo: materialRepo,
|
|
}
|
|
}
|
|
|
|
// BindMaterial 绑定材质到多个group_id
|
|
// POST /api/v1/materials/:id/bindings
|
|
// Body: {"group_ids": ["g1", "g2", "g3"]}
|
|
func (h *BindingHandler) BindMaterial(c *gin.Context) {
|
|
materialID, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
|
if err != nil {
|
|
response.BadRequest(c, "invalid material id")
|
|
return
|
|
}
|
|
|
|
// 检查材质是否存在
|
|
exists, err := h.materialRepo.Exists(materialID)
|
|
if err != nil {
|
|
response.InternalError(c, "failed to check material")
|
|
return
|
|
}
|
|
if !exists {
|
|
response.NotFound(c, "material not found")
|
|
return
|
|
}
|
|
|
|
var req models.BindingRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.BadRequest(c, "invalid request body: "+err.Error())
|
|
return
|
|
}
|
|
|
|
if err := h.bindingRepo.BindMaterial(materialID, req.GroupIDs); err != nil {
|
|
response.InternalError(c, "failed to bind material")
|
|
return
|
|
}
|
|
|
|
response.Success(c, gin.H{
|
|
"material_id": materialID,
|
|
"group_ids": req.GroupIDs,
|
|
})
|
|
}
|
|
|
|
// UnbindMaterial 解绑材质与指定group_id
|
|
// DELETE /api/v1/materials/:id/bindings
|
|
// Body: {"group_ids": ["g1", "g2"]}
|
|
func (h *BindingHandler) UnbindMaterial(c *gin.Context) {
|
|
materialID, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
|
if err != nil {
|
|
response.BadRequest(c, "invalid material id")
|
|
return
|
|
}
|
|
|
|
var req models.UnbindRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.BadRequest(c, "invalid request body: "+err.Error())
|
|
return
|
|
}
|
|
|
|
if err := h.bindingRepo.UnbindMaterial(materialID, req.GroupIDs); err != nil {
|
|
response.InternalError(c, "failed to unbind material")
|
|
return
|
|
}
|
|
|
|
response.Success(c, gin.H{
|
|
"material_id": materialID,
|
|
"unbound": req.GroupIDs,
|
|
})
|
|
}
|
|
|
|
// GetGroupsByMaterial 获取材质关联的所有group_id (分页版本)
|
|
// GET /api/v1/materials/:id/groups?page=1&page_size=20
|
|
func (h *BindingHandler) GetGroupsByMaterial(c *gin.Context) {
|
|
materialID, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
|
if err != nil {
|
|
response.BadRequest(c, "invalid material id")
|
|
return
|
|
}
|
|
|
|
// 解析分页参数
|
|
var query models.GroupListQuery
|
|
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
|
|
}
|
|
|
|
// 检查材质是否存在
|
|
exists, err := h.materialRepo.Exists(materialID)
|
|
if err != nil {
|
|
response.InternalError(c, "failed to check material")
|
|
return
|
|
}
|
|
if !exists {
|
|
response.NotFound(c, "material not found")
|
|
return
|
|
}
|
|
|
|
groupIDs, total, err := h.bindingRepo.GetGroupsByMaterialID(materialID, query.Page, query.PageSize)
|
|
if err != nil {
|
|
response.InternalError(c, "failed to get groups")
|
|
return
|
|
}
|
|
|
|
// 返回分页格式
|
|
response.Success(c, models.GroupListResponse{
|
|
Items: groupIDs,
|
|
Total: total,
|
|
Page: query.Page,
|
|
PageSize: query.PageSize,
|
|
})
|
|
}
|
|
|
|
// GetMaterialsByGroups 根据多个group_id获取关联的材质
|
|
// POST /api/v1/groups/materials
|
|
// Body: {"group_ids": ["g1", "g2", "g3"]}
|
|
func (h *BindingHandler) GetMaterialsByGroups(c *gin.Context) {
|
|
var req models.GroupMaterialsRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.BadRequest(c, "invalid request body: "+err.Error())
|
|
return
|
|
}
|
|
|
|
results, err := h.bindingRepo.GetMaterialsByGroupIDs(req.GroupIDs)
|
|
if err != nil {
|
|
response.InternalError(c, "failed to get materials")
|
|
return
|
|
}
|
|
|
|
response.Success(c, results)
|
|
}
|