package plant import ( "errors" "sundynix-go/global" "sundynix-go/model/plant" plantReq "sundynix-go/model/plant/request" plantRes "sundynix-go/model/plant/response" "gorm.io/gorm" ) type BadgeConfigService struct{} var BadgeConfigServiceApp = new(BadgeConfigService) // GetBadgeTree 获取徽章树形结构 (无分页) // GetBadgeTree 获取徽章树形结构 (维度和组ID都转换为中文) func (s *BadgeConfigService) GetBadgeTree() (tree []plantRes.BadgeDimensionNode, err error) { var allBadges []plant.BadgeConfig // 1. 查询所有配置 err = global.DB.Order("dimension desc, group_id asc, tier asc, sort asc").Preload("Icon").Find(&allBadges).Error if err != nil { return nil, err } // --- 定义映射字典 --- // 维度中文映射 dimLabelMap := map[string]string{ "PERSISTENCE": "勤勉成就", "EXPERTISE": "专家成就", "JOURNAL": "岁月记录", "DISCOVERY": "探索发现", } // 组ID中文映射 (对应之前的 SQL 数据) groupLabelMap := map[string]string{ // 勤勉系 "water_master": "雨露均沾", // 浇水 "alive_master": "长情陪伴", // 存活天数 // 专家系 "fert_master": "炼金术士", // 施肥 "prune_master": "园艺理发师", // 修剪 "repot_master": "乔迁之喜", // 换盆 "doctor_master": "植物医生", // 医生 // 记录系 "photo_master": "光影捕手", // 拍照 // 发现系 "night_owl": "守夜人", // 深夜养护 } // 定义维度的固定展示顺序 dimOrder := []string{"PERSISTENCE", "EXPERTISE", "JOURNAL", "DISCOVERY"} // --- 数据处理 --- // 辅助 Map: map[Dimension] -> map[GroupId] -> []Badge tempMap := make(map[string]map[string][]plant.BadgeConfig) for _, badge := range allBadges { dim := badge.Dimension group := badge.GroupId if tempMap[dim] == nil { tempMap[dim] = make(map[string][]plant.BadgeConfig) } tempMap[dim][group] = append(tempMap[dim][group], badge) } // --- 构建返回树 --- // 1. 遍历维度顺序 for _, dimKey := range dimOrder { if groupMap, exists := tempMap[dimKey]; exists { var groupNodes []plantRes.BadgeGroupNode // 2. 遍历该维度下的所有组 for groupKey, badges := range groupMap { // 获取组中文名,如果没有则回退到英文 ID gLabel := groupLabelMap[groupKey] if gLabel == "" { gLabel = groupKey // Fallback } groupNodes = append(groupNodes, plantRes.BadgeGroupNode{ GroupId: groupKey, GroupLabel: gLabel, // 赋值中文名 Badges: badges, }) } // 获取维度中文名 dLabel := dimLabelMap[dimKey] if dLabel == "" { dLabel = dimKey } tree = append(tree, plantRes.BadgeDimensionNode{ Dimension: dimKey, Label: dLabel, Groups: groupNodes, }) delete(tempMap, dimKey) } } // 3. 处理剩余的未知维度 (防止数据丢失) for dimKey, groupMap := range tempMap { var groupNodes []plantRes.BadgeGroupNode for groupKey, badges := range groupMap { // 未知组也尝试映射一下,不行就用 key gLabel := groupLabelMap[groupKey] if gLabel == "" { gLabel = groupKey } groupNodes = append(groupNodes, plantRes.BadgeGroupNode{ GroupId: groupKey, GroupLabel: gLabel, Badges: badges, }) } tree = append(tree, plantRes.BadgeDimensionNode{ Dimension: dimKey, Label: dimKey, Groups: groupNodes, }) } return tree, nil } // AddBadgeConfig 添加徽章配置 func (s *BadgeConfigService) AddBadgeConfig(req plantReq.CreateBadge) error { // 判断是否已存在相同配置(可选逻辑,例如同一组同一等级只能有一个) if !errors.Is(global.DB.Where("group_id = ? AND tier = ?", req.GroupId, req.Tier).First(&plant.BadgeConfig{}).Error, gorm.ErrRecordNotFound) { return errors.New("该组下该等级徽章已存在") } badge := plant.BadgeConfig{ Dimension: req.Dimension, GroupId: req.GroupId, Name: req.Name, Description: req.Description, IconId: req.IconId, Tier: req.Tier, TargetAction: req.TargetAction, Threshold: req.Threshold, Comparator: req.Comparator, RewardSunlight: req.RewardSunlight, Sort: req.Sort, } return global.DB.Create(&badge).Error } // UpdateBadgeConfig 修改徽章配置 func (s *BadgeConfigService) UpdateBadgeConfig(req plantReq.UpdateBadge) error { // 使用 Map 更新可以避免 0 值问题,或者直接更新结构体 // 这里简单起见,先查再更,或者直接 Model update var badge plant.BadgeConfig if err := global.DB.Where("id = ?", req.Id).First(&badge).Error; err != nil { return errors.New("记录不存在") } // 手动映射需要更新的字段 (更安全) updateMap := map[string]interface{}{ "name": req.Name, "description": req.Description, "icon_id": req.IconId, "dimension": req.Dimension, "group_id": req.GroupId, "tier": req.Tier, "target_action": req.TargetAction, "threshold": req.Threshold, "reward_sunlight": req.RewardSunlight, "sort": req.Sort, } return global.DB.Model(&badge).Updates(updateMap).Error } // GetBadgeConfig 根据ID获取单条 func (s *BadgeConfigService) GetBadgeConfig(id string) (plant.BadgeConfig, error) { var badge plant.BadgeConfig err := global.DB.Where("id = ?", id).Preload("Icon").First(&badge).Error return badge, err } // DeleteBadgeConfig 删除徽章配置 func (s *BadgeConfigService) DeleteBadgeConfig(id string) error { return global.DB.Where("id = ?", id).Delete(&plant.BadgeConfig{}).Error }