feat: 徽章api
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
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
|
||||
}
|
||||
@@ -8,5 +8,6 @@ type ServiceGroup struct {
|
||||
WikiService
|
||||
OcrService
|
||||
LevelConfigService
|
||||
BadgeConfigService
|
||||
UserProfileService
|
||||
}
|
||||
|
||||
@@ -100,11 +100,13 @@ func (s *MyPlantService) PlantDetail(id string) (p plant.MyPlant, err error) {
|
||||
return db.Order("created_at desc")
|
||||
}).
|
||||
Preload("CarePlans").
|
||||
Preload("CareRecords").
|
||||
Preload("CareRecords", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Order("created_at desc")
|
||||
}).
|
||||
Preload("GrowthRecords", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Preload("ImgList", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Order("created_at desc")
|
||||
})
|
||||
}).Order("created_at desc")
|
||||
}).
|
||||
First(&res).Error
|
||||
|
||||
|
||||
@@ -79,11 +79,11 @@ func (s *TopicService) Detail(id string) (t plant.Topic, err error) {
|
||||
// DeleteTopics 删除话题
|
||||
func (s *TopicService) DeleteTopics(req common.IdsReq) error {
|
||||
var topics []plant.Topic
|
||||
err := global.DB.Where("id in (?)", req.Ids).Find(&topics).Error
|
||||
err := global.DB.Where("id in ?", req.Ids).Find(&topics).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = global.DB.Unscoped().Delete(&plant.Topic{}).Error
|
||||
err = global.DB.Unscoped().Delete(&topics).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -4,18 +4,36 @@ import (
|
||||
"sundynix-go/global"
|
||||
"sundynix-go/model/plant"
|
||||
plantReq "sundynix-go/model/plant/request"
|
||||
"sundynix-go/model/system"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type UserProfileService struct{}
|
||||
|
||||
// UpdateProfile 修改用户信息
|
||||
func (s *UserProfileService) UpdateProfile(req plantReq.UpdateProfile, userId string) error {
|
||||
updateMap := map[string]interface{}{
|
||||
"nick_name": req.Nickname,
|
||||
"avatar_id": req.AvatarId,
|
||||
}
|
||||
return global.DB.Model(&plant.UserProfile{}).Where("user_id = ?", userId).Updates(updateMap).Error
|
||||
|
||||
return global.DB.Transaction(func(tx *gorm.DB) error {
|
||||
//1.更新profile
|
||||
updateMap := map[string]interface{}{
|
||||
"nick_name": req.Nickname,
|
||||
"avatar_id": req.AvatarId,
|
||||
}
|
||||
err := tx.Model(&plant.UserProfile{}).Where("user_id = ?", userId).Updates(updateMap).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//2.更新user表
|
||||
updateMap = map[string]interface{}{
|
||||
"name": req.Nickname,
|
||||
"avatar_id": req.AvatarId,
|
||||
}
|
||||
err = tx.Model(&system.User{}).Where("id = ?", userId).Updates(updateMap).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// ProfileDetail 获取用户详情
|
||||
|
||||
Reference in New Issue
Block a user