Files
material_texture/internal/repository/binding.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

105 lines
2.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package repository
import (
"material_texture/internal/models"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
type BindingRepository struct {
db *gorm.DB
}
func NewBindingRepository(db *gorm.DB) *BindingRepository {
return &BindingRepository{db: db}
}
// BindMaterial 绑定材质到多个group_id幂等操作使用upsert
// 优化: 分批处理,避免单条 SQL 过大
func (r *BindingRepository) BindMaterial(materialID int64, groupIDs []string) error {
const batchSize = 1000 // 每批最多 1000 条
for i := 0; i < len(groupIDs); i += batchSize {
end := i + batchSize
if end > len(groupIDs) {
end = len(groupIDs)
}
batch := groupIDs[i:end]
bindings := make([]models.MaterialBinding, len(batch))
for j, groupID := range batch {
bindings[j] = models.MaterialBinding{
MaterialID: materialID,
GroupID: groupID,
}
}
// 使用 ON CONFLICT DO NOTHING 实现幂等
if err := r.db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "material_id"}, {Name: "group_id"}},
DoNothing: true,
}).Create(&bindings).Error; err != nil {
return err
}
}
return nil
}
// UnbindMaterial 解绑材质与指定的group_id
func (r *BindingRepository) UnbindMaterial(materialID int64, groupIDs []string) error {
return r.db.Where("material_id = ? AND group_id IN ?", materialID, groupIDs).
Delete(&models.MaterialBinding{}).Error
}
// GetGroupsByMaterialID 根据材质ID获取所有关联的group_id (分页版本)
func (r *BindingRepository) GetGroupsByMaterialID(materialID int64, page, pageSize int) ([]string, int64, error) {
var groupIDs []string
var total int64
db := r.db.Model(&models.MaterialBinding{}).Where("material_id = ?", materialID)
// 获取总数
if err := db.Count(&total).Error; err != nil {
return nil, 0, err
}
// 分页查询
offset := (page - 1) * pageSize
err := db.Order("created_at DESC").
Offset(offset).
Limit(pageSize).
Pluck("group_id", &groupIDs).Error
return groupIDs, total, err
}
// GetMaterialsByGroupIDs 根据多个group_id获取关联的材质含材质详情
func (r *BindingRepository) GetMaterialsByGroupIDs(groupIDs []string) ([]models.GroupMaterialResult, error) {
var bindings []models.MaterialBinding
err := r.db.Preload("Material").
Where("group_id IN ?", groupIDs).
Find(&bindings).Error
if err != nil {
return nil, err
}
results := make([]models.GroupMaterialResult, len(bindings))
for i, binding := range bindings {
results[i] = models.GroupMaterialResult{
GroupID: binding.GroupID,
Material: binding.Material,
}
}
return results, nil
}
// DeleteByMaterialID 删除材质的所有绑定(材质删除时级联调用)
func (r *BindingRepository) DeleteByMaterialID(materialID int64) error {
return r.db.Where("material_id = ?", materialID).
Delete(&models.MaterialBinding{}).Error
}