Files
sundynix-micro-be/app/plant/api/internal/logic/complete/completetasklogic.go
T
2026-05-24 23:04:09 +08:00

117 lines
3.7 KiB
Go

package complete
import (
"context"
"fmt"
"time"
filePb "sundynix-micro-go/app/file/rpc/file"
"sundynix-micro-go/app/plant/api/internal/svc"
"sundynix-micro-go/app/plant/api/internal/types"
plantModel "sundynix-micro-go/app/plant/model"
plantPb "sundynix-micro-go/app/plant/rpc/plant"
"github.com/zeromicro/go-zero/core/logx"
)
type CompleteTaskLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewCompleteTaskLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CompleteTaskLogic {
return &CompleteTaskLogic{Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx}
}
func (l *CompleteTaskLogic) CompleteTask(req *types.CompleteTaskApiReq) (interface{}, error) {
userId := fmt.Sprintf("%v", l.ctx.Value("userId"))
resp, err := l.svcCtx.PlantRpc.CompleteTask(l.ctx, &plantPb.CompleteTaskReq{
UserId: userId, TaskId: req.TaskId, Remark: req.Remark,
})
if err != nil {
return nil, err
}
// 1. 拼装当前等级详情(在升级时包含 perks 等完整字段,完美渲染等级弹窗)
var currentLevelData map[string]interface{}
if resp.CurrentLevel != nil {
currentLevelData = map[string]interface{}{
"id": resp.CurrentLevel.Id,
"level": resp.CurrentLevel.Level,
"title": resp.CurrentLevel.Title,
"minSunlight": resp.CurrentLevel.MinSunlight,
"perks": "",
}
// 若发生升级,自动利用 GORM 提取等级的 Perks 描述
if resp.IsLevelUp {
var lvl plantModel.LevelConfig
if errLvl := l.svcCtx.DB.Where("id = ?", resp.CurrentLevel.Id).First(&lvl).Error; errLvl == nil {
currentLevelData["perks"] = lvl.Perks
}
}
}
// 2. 拼装新获得徽章详情(包含 description 和 icon.url,完美渲染新徽章弹窗)
var newBadgeData map[string]interface{}
if resp.IsGetBadge && resp.NewBadge != nil {
var bc plantModel.BadgeConfig
if errBc := l.svcCtx.DB.Where("id = ?", resp.NewBadge.Id).First(&bc).Error; errBc == nil {
newBadgeData = map[string]interface{}{
"id": bc.ID,
"name": bc.Name,
"description": bc.Description,
"iconId": bc.IconID,
"dimension": bc.Dimension,
"groupId": bc.GroupID,
"tier": bc.Tier,
"targetAction": bc.TargetAction,
"threshold": bc.Threshold,
"comparator": bc.Comparator,
"rewardSunlight": bc.RewardSunlight,
"sort": bc.Sort,
"icon": nil,
}
// 跨微服务请求获取 Icon 图片 URL 等元数据
if bc.IconID != "" {
fileResp, errFile := l.svcCtx.FileRpc.GetFilesByIds(l.ctx, &filePb.GetFilesByIdsReq{Ids: []string{bc.IconID}})
if errFile == nil && fileResp != nil && len(fileResp.Files) > 0 {
f := fileResp.Files[0]
newBadgeData["icon"] = map[string]interface{}{
"id": f.Id,
"name": f.Name,
"url": f.Url,
"tag": f.Tag,
"key": f.Key,
"suffix": f.Suffix,
"md5": f.Md5,
"createdAt": time.Unix(f.CreatedAt, 0).Format(time.RFC3339),
}
}
}
} else {
// 兜底映射
newBadgeData = map[string]interface{}{
"id": resp.NewBadge.Id,
"name": resp.NewBadge.Name,
"dimension": resp.NewBadge.Dimension,
"tier": resp.NewBadge.Tier,
"rewardSunlight": resp.NewBadge.RewardSunlight,
"icon": nil,
}
}
}
// 3. 构建高度兼容的 JSON 响应,同时适配大小写驼峰字段
res := map[string]interface{}{
"isLevelUp": resp.IsLevelUp,
"currentLevel": currentLevelData,
"isGetBadge": resp.IsGetBadge,
"IsGetBadge": resp.IsGetBadge, // 兼容前端多处命名差异
"newBadge": newBadgeData,
"rewardSunlight": resp.RewardSunlight,
}
return res, nil
}