feat: 个人中心发布
This commit is contained in:
+201
-62
@@ -1,6 +1,8 @@
|
||||
package plant
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"sundynix-go/global"
|
||||
common "sundynix-go/model/commom/request"
|
||||
"sundynix-go/model/plant"
|
||||
@@ -32,13 +34,14 @@ func (s *MyPlantService) AddPlant(req plantReq.CreateMyPlant, userId string) err
|
||||
var carePlans []*plant.CarePlan
|
||||
for _, v := range req.CarePlans {
|
||||
carePlans = append(carePlans, &plant.CarePlan{
|
||||
UserId: userId,
|
||||
Name: v.Name,
|
||||
Icon: v.Icon,
|
||||
Period: v.Period,
|
||||
UserId: userId,
|
||||
Name: v.Name,
|
||||
Icon: v.Icon,
|
||||
Period: v.Period,
|
||||
TargetAction: v.TargetAction,
|
||||
})
|
||||
}
|
||||
//3.保存数据
|
||||
//3.保存数据 myPlant钩子函数自动处理创建careTask
|
||||
myPlant := plant.MyPlant{
|
||||
UserId: userId,
|
||||
Name: req.Name,
|
||||
@@ -150,9 +153,10 @@ func (s *MyPlantService) UpdatePlant(req plantReq.UpdateMyPlant) error {
|
||||
today := timer.GetZeroTime()
|
||||
for _, plan := range req.CarePlans {
|
||||
err = tx.Model(&plant.CarePlan{}).Where("id = ?", plan.Id).Updates(map[string]interface{}{
|
||||
"icon": plan.Icon,
|
||||
"name": plan.Name,
|
||||
"period": plan.Period,
|
||||
"icon": plan.Icon,
|
||||
"name": plan.Name,
|
||||
"period": plan.Period,
|
||||
"target_action": plan.TargetAction,
|
||||
}).Error
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -234,7 +238,8 @@ func (s *MyPlantService) TodayTask(userId string) ([]plantRes.PlantTaskVO, error
|
||||
}
|
||||
|
||||
// CompleteTask 完成任务
|
||||
func (s *MyPlantService) CompleteTask(req plantReq.CompleteTask, userId string) error {
|
||||
func (s *MyPlantService) CompleteTask(req plantReq.CompleteTask, userId string) (*plantRes.TaskCompletionResult, error) {
|
||||
var result plantRes.TaskCompletionResult
|
||||
err := global.DB.Transaction(func(tx *gorm.DB) error {
|
||||
var task plant.CareTask
|
||||
if err := tx.Where("id = ?", req.TaskId).First(&task).Error; err != nil {
|
||||
@@ -257,13 +262,14 @@ func (s *MyPlantService) CompleteTask(req plantReq.CompleteTask, userId string)
|
||||
today := timer.GetZeroTime()
|
||||
nextDueDate := today.AddDate(0, 0, plan.Period)
|
||||
newTask := plant.CareTask{
|
||||
UserId: plan.UserId,
|
||||
PlantId: plan.PlantId,
|
||||
PlanId: plan.Id,
|
||||
Name: plan.Name,
|
||||
Icon: plan.Icon,
|
||||
DueDate: nextDueDate,
|
||||
Status: 1,
|
||||
UserId: plan.UserId,
|
||||
PlantId: plan.PlantId,
|
||||
PlanId: plan.Id,
|
||||
Name: plan.Name,
|
||||
Icon: plan.Icon,
|
||||
TargetAction: plan.TargetAction,
|
||||
DueDate: nextDueDate,
|
||||
Status: 1,
|
||||
}
|
||||
if err := tx.Create(&newTask).Error; err != nil {
|
||||
return err
|
||||
@@ -280,51 +286,134 @@ func (s *MyPlantService) CompleteTask(req plantReq.CompleteTask, userId string)
|
||||
if err := tx.Create(&record).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
//4.等级与阳光计算
|
||||
var profile plant.UserProfile
|
||||
if err := tx.Set("gorm:query_option", "FOR UPDATE").Where("user_id = ?", userId).First(&profile).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
fieldMap := map[string]string{
|
||||
"ACT_WATER": "water_count",
|
||||
"ACT_FERTILIZE": "fertilize_count",
|
||||
"ACT_REPOT": "repot_count",
|
||||
"ACT_PRUNE": "prune_count",
|
||||
}
|
||||
column, ok := fieldMap[task.TargetAction]
|
||||
if !ok {
|
||||
column = "care_count" // 默认备用
|
||||
}
|
||||
const TaskReward = 50
|
||||
newTotalSunlight := profile.TotalSunlight + TaskReward
|
||||
newCurrentSunlight := profile.CurrentSunlight + TaskReward
|
||||
// 5. 等级判定 (根据累计阳光查出当前应有的等级)
|
||||
var latestLevel plant.LevelConfig
|
||||
if err := tx.Where("min_sunlight <= ?", newTotalSunlight).
|
||||
Order("min_sunlight DESC").First(&latestLevel).Error; err != nil {
|
||||
return errors.New("等级配置异常")
|
||||
}
|
||||
result.CurrentLevel = &latestLevel
|
||||
result.IsLevelUp = latestLevel.Id != profile.LevelId
|
||||
// 6. 执行 Profile 更新 (任务阳光 + 计数自增 + 等级同步)
|
||||
profileData := map[string]interface{}{
|
||||
column: gorm.Expr(column + " + 1"),
|
||||
"current_sunlight": newCurrentSunlight,
|
||||
"total_sunlight": newTotalSunlight,
|
||||
"level_id": latestLevel.Id,
|
||||
}
|
||||
if err := tx.Model(&plant.UserProfile{}).Where("user_id = ?", userId).Updates(profileData).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
// 7. 徽章判定逻辑
|
||||
// 7.1 计算当前动作的最新逻辑数值
|
||||
var currentActionVal int64
|
||||
switch task.TargetAction {
|
||||
case "ACT_WATER":
|
||||
currentActionVal = profile.WaterCount + 1
|
||||
case "ACT_FERTILIZE":
|
||||
currentActionVal = profile.FertilizeCount + 1
|
||||
case "ACT_REPOT":
|
||||
currentActionVal = profile.RepotCount + 1
|
||||
case "ACT_PRUNE":
|
||||
currentActionVal = profile.PruneCount + 1
|
||||
default:
|
||||
currentActionVal = 0
|
||||
}
|
||||
// 7.2 查询已拥有的徽章 ID (用于去重)
|
||||
var ownedBadgeIds []string
|
||||
tx.Model(&plant.UserBadge{}).Where("user_id = ?", userId).Pluck("badge_id", &ownedBadgeIds)
|
||||
ownedMap := make(map[string]bool)
|
||||
for _, id := range ownedBadgeIds {
|
||||
ownedMap[id] = true
|
||||
}
|
||||
// 7.3 筛选当前 Action 下满足条件的最高级徽章
|
||||
var badgeConfigs []plant.BadgeConfig
|
||||
tx.Where("target_action = ?", task.TargetAction).Preload("Icon").Find(&badgeConfigs)
|
||||
|
||||
for i := range badgeConfigs {
|
||||
conf := &badgeConfigs[i]
|
||||
// 如果没拿过且数值达标
|
||||
if !ownedMap[conf.Id] && currentActionVal >= conf.Threshold {
|
||||
// 寻找 Tier 最大的那个
|
||||
if result.NewBadge == nil || conf.Tier > result.NewBadge.Tier {
|
||||
result.NewBadge = conf
|
||||
result.IsGetBadge = true
|
||||
}
|
||||
}
|
||||
}
|
||||
// 8. 奖励入库:如果产生了新徽章
|
||||
if result.NewBadge != nil {
|
||||
// 写入获得记录
|
||||
ub := plant.UserBadge{
|
||||
UserId: userId,
|
||||
BadgeId: result.NewBadge.Id, // 注意这里 Id 是 string
|
||||
}
|
||||
if err := tx.Create(&ub).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
// 发放徽章额外奖励阳光
|
||||
if err := tx.Model(&plant.UserProfile{}).Where("user_id = ?", userId).
|
||||
Update("current_sunlight", gorm.Expr("current_sunlight + ?", result.NewBadge.RewardSunlight)).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err == nil {
|
||||
go func() {
|
||||
//5.更新用户profile
|
||||
var profile plant.UserProfile
|
||||
if asyncErr := global.DB.Where("user_id = ?", userId).First(&profile).Error; err != nil {
|
||||
global.Logger.Error("完成任务异步操作-----查询用户profile失败", zap.Error(asyncErr))
|
||||
}
|
||||
totalSunlight := profile.TotalSunlight + 50
|
||||
updateData := map[string]interface{}{
|
||||
"care_count": profile.CareCount + 1,
|
||||
"current_sunlight": profile.CurrentSunlight + 50,
|
||||
"total_sunlight": totalSunlight,
|
||||
}
|
||||
//5.1 判断是否到达下个等级
|
||||
var currentLevel plant.LevelConfig
|
||||
levelErr := global.DB.Where("min_sunlight <= ?", totalSunlight).Order("min_sunlight DESC").First(¤tLevel).Error
|
||||
if levelErr != nil {
|
||||
global.Logger.Error("完成任务异步操作-----查询用户等级失败", zap.Error(levelErr))
|
||||
}
|
||||
updateData["level_id"] = currentLevel.Id
|
||||
//5.2 更新用户profile
|
||||
updateProfileErr := global.DB.Model(&plant.UserProfile{}).Where("user_id = ?", userId).Updates(updateData).Error
|
||||
if updateProfileErr != nil {
|
||||
global.Logger.Error("完成任务异步操作-----更新用户profile失败", zap.Error(updateProfileErr))
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
return err
|
||||
return &result, err
|
||||
}
|
||||
|
||||
// DeletePlants 删除植物
|
||||
func (s *MyPlantService) DeletePlants(req common.IdsReq) error {
|
||||
return global.DB.Transaction(func(tx *gorm.DB) error {
|
||||
var plants []plant.MyPlant
|
||||
if err := tx.Where("id in ?", req.Ids).Find(&plants).Error; err != nil {
|
||||
var imgIds []string
|
||||
tx.Table("sundynix_my_plant_oss").Where("my_plant_id IN ?", req.Ids).Pluck("oss_id", &imgIds)
|
||||
// 2. 清理中间表记录 (解开多对多关系)
|
||||
// 使用 Exec 直接操作中间表比循环 Clear 快得多
|
||||
if err := tx.Exec("DELETE FROM sundynix_my_plant_oss WHERE my_plant_id IN ?", req.Ids).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
// 删除图片 养护计划 养护任务 养护记录 成长记录
|
||||
err := tx.Select("ImgList", "CarePlans", "CareTasks", "CareRecords").Unscoped().Delete(&plants).Error
|
||||
if err != nil {
|
||||
// 3. 物理删除图片记录本身
|
||||
if len(imgIds) > 0 {
|
||||
if err := tx.Unscoped().Where("id IN ?", imgIds).Delete(&system.Oss{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
//4.批量删除养护计划 养护任务 养护记录 成长记录
|
||||
if err := tx.Unscoped().Where("plant_id in ?", req.Ids).Delete(&plant.CarePlan{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Unscoped().Where("plant_id in ?", req.Ids).Delete(&plant.CareTask{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Unscoped().Where("plant_id in ?", req.Ids).Delete(&plant.CareRecord{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Unscoped().Where("plant_id in ?", req.Ids).Delete(&plant.GrowthRecord{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
//5.删除植物本身
|
||||
if err := tx.Unscoped().Where("id in ?", req.Ids).Delete(&plant.MyPlant{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -365,11 +454,12 @@ func (s *MyPlantService) AddCarePlan(req plantReq.AddPlans) error {
|
||||
}
|
||||
//1.新增计划
|
||||
newPlan := plant.CarePlan{
|
||||
UserId: myPlant.UserId,
|
||||
PlantId: myPlant.Id,
|
||||
Name: plan.Name,
|
||||
Icon: plan.Icon,
|
||||
Period: plan.Period,
|
||||
UserId: myPlant.UserId,
|
||||
PlantId: myPlant.Id,
|
||||
Name: plan.Name,
|
||||
Icon: plan.Icon,
|
||||
Period: plan.Period,
|
||||
TargetAction: plan.TargetAction,
|
||||
}
|
||||
err = tx.Create(&newPlan).Error
|
||||
if err != nil {
|
||||
@@ -379,13 +469,14 @@ func (s *MyPlantService) AddCarePlan(req plantReq.AddPlans) error {
|
||||
today := timer.GetZeroTime()
|
||||
dueDate := today.AddDate(0, 0, plan.Period)
|
||||
task := plant.CareTask{
|
||||
UserId: myPlant.UserId,
|
||||
PlantId: myPlant.Id,
|
||||
PlanId: newPlan.Id,
|
||||
Name: plan.Name,
|
||||
Icon: plan.Icon,
|
||||
DueDate: dueDate,
|
||||
Status: 1,
|
||||
UserId: myPlant.UserId,
|
||||
PlantId: myPlant.Id,
|
||||
PlanId: newPlan.Id,
|
||||
Name: plan.Name,
|
||||
Icon: plan.Icon,
|
||||
TargetAction: plan.TargetAction,
|
||||
DueDate: dueDate,
|
||||
Status: 1,
|
||||
}
|
||||
err = tx.Create(&task).Error
|
||||
if err != nil {
|
||||
@@ -459,3 +550,51 @@ func (s *MyPlantService) AddGrowthRecord(req plantReq.CreateGrowthRecord, userId
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// 完成任务后异步执行 更新用户等级 sunlight
|
||||
func (s *MyPlantService) handleCompleteTaskThenUpdateProfile(ctx context.Context, userId string) {
|
||||
//5.更新用户profile
|
||||
var profile plant.UserProfile
|
||||
if asyncErr := global.DB.Where("user_id = ?", userId).First(&profile).Error; asyncErr != nil {
|
||||
global.Logger.Error("完成任务异步操作-----查询用户profile失败", zap.Error(asyncErr))
|
||||
}
|
||||
totalSunlight := profile.TotalSunlight + 50
|
||||
updateData := map[string]interface{}{
|
||||
"care_count": profile.CareCount + 1,
|
||||
"current_sunlight": profile.CurrentSunlight + 50,
|
||||
"total_sunlight": totalSunlight,
|
||||
}
|
||||
//5.1 判断是否到达下个等级
|
||||
var currentLevel plant.LevelConfig
|
||||
levelErr := global.DB.Where("min_sunlight <= ?", totalSunlight).Order("min_sunlight DESC").First(¤tLevel).Error
|
||||
if levelErr != nil {
|
||||
global.Logger.Error("完成任务异步操作-----查询用户等级失败", zap.Error(levelErr))
|
||||
}
|
||||
updateData["level_id"] = currentLevel.Id
|
||||
//5.2 更新用户profile
|
||||
updateProfileErr := global.DB.Model(&plant.UserProfile{}).Where("user_id = ?", userId).Updates(updateData).Error
|
||||
if updateProfileErr != nil {
|
||||
global.Logger.Error("完成任务异步操作-----更新用户profile失败", zap.Error(updateProfileErr))
|
||||
}
|
||||
}
|
||||
|
||||
// todo 完成任务后异步执行 处理徽章
|
||||
func (s *MyPlantService) handleCompleteTaskThenHandleBadge(ctx context.Context, taskId, userId string) {
|
||||
//1.查询任务
|
||||
var task plant.CareTask
|
||||
if asyncErr := global.DB.Where("id = ?", taskId).First(&task).Error; asyncErr != nil {
|
||||
global.Logger.Error("完成任务异步操作-----查询任务失败", zap.Error(asyncErr))
|
||||
}
|
||||
//2.查询徽章
|
||||
var badges []plant.BadgeConfig
|
||||
if asyncErr := global.DB.Where("target_action = ?", task.TargetAction).Order("tier ASC").Find(&badges).Error; asyncErr != nil {
|
||||
global.Logger.Error("完成任务异步操作-----查询徽章失败", zap.Error(asyncErr))
|
||||
}
|
||||
//3.用户的徽章
|
||||
var userBadges []plant.UserBadge
|
||||
if asyncErr := global.DB.Where("user_id = ?", userId).Find(&userBadges).Error; asyncErr != nil {
|
||||
global.Logger.Error("完成任务异步操作-----查询用户徽章失败", zap.Error(asyncErr))
|
||||
}
|
||||
//4.用户个人资料
|
||||
|
||||
}
|
||||
|
||||
@@ -114,6 +114,11 @@ func (s *OcrService) MyClassifyLog(req request.PageInfo, id string) (list interf
|
||||
|
||||
}
|
||||
|
||||
// DeleteClassifyLog 删除植物识别记录
|
||||
func (s *OcrService) DeleteClassifyLog(req request.IdsReq, userId string) error {
|
||||
return global.DB.Where("id in ? and user_id = ?", req.Ids, userId).Unscoped().Delete(&plant.ClassifyRecord{}).Error
|
||||
}
|
||||
|
||||
func getAccessToken() string {
|
||||
rpcUrl := "https://aip.baidubce.com/oauth/2.0/token"
|
||||
postData := fmt.Sprintf("grant_type=client_credentials&client_id=%s&client_secret=%s", global.Config.BaiduImgClassify.ApiKey, global.Config.BaiduImgClassify.SecretKey)
|
||||
|
||||
+104
-7
@@ -62,11 +62,6 @@ func (s *PostService) PostPage(req plantReq.PostPage, userId string) (list inter
|
||||
Preload("Publisher", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Preload("Avatar")
|
||||
}).
|
||||
Preload("LikeList", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Preload("Liker", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Preload("Avatar")
|
||||
})
|
||||
}).
|
||||
Preload("CommentList", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Preload("Commentator", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Preload("Avatar")
|
||||
@@ -96,11 +91,21 @@ func (s *PostService) PostPage(req plantReq.PostPage, userId string) (list inter
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
//批量查询当前用户的收藏
|
||||
var stars []*plant.UserStar
|
||||
err = global.DB.Where("user_id = ? and post_id in ?", userId, postIds).Find(&stars).Error
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// 构建id映射
|
||||
likesMap := make(map[string]bool)
|
||||
for _, v := range postLikeList {
|
||||
likesMap[v.PostId] = true
|
||||
}
|
||||
starsMap := make(map[string]bool)
|
||||
for _, v := range stars {
|
||||
starsMap[v.PostId] = true
|
||||
}
|
||||
// 是否点赞
|
||||
for i := range posts {
|
||||
if likesMap[posts[i].Id] {
|
||||
@@ -109,6 +114,11 @@ func (s *PostService) PostPage(req plantReq.PostPage, userId string) (list inter
|
||||
posts[i].HasLiked = 0
|
||||
}
|
||||
|
||||
if starsMap[posts[i].Id] {
|
||||
posts[i].HasStar = 1
|
||||
} else {
|
||||
posts[i].HasStar = 0
|
||||
}
|
||||
}
|
||||
|
||||
return posts, total, err
|
||||
@@ -169,7 +179,6 @@ func (s *PostService) MyPost(req plantReq.PostPage, userId string) (list interfa
|
||||
} else {
|
||||
posts[i].HasLiked = 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return posts, total, err
|
||||
@@ -210,7 +219,9 @@ func (s *PostService) LikePost(userId, postId, class string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = tx.Model(&post).Update("like_count", post.LikeCount-1).Error
|
||||
err = tx.Model(&post).
|
||||
Where("like_count > 0"). // 只有大于 0 才会执行减法
|
||||
Update("like_count", post.LikeCount-1).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -244,3 +255,89 @@ func (s *PostService) CommentPost(req plantReq.CreateComment, userId string) err
|
||||
return tx.Create(&comment).Error
|
||||
})
|
||||
}
|
||||
|
||||
// DeletePost 删除帖子
|
||||
func (s *PostService) DeletePost(ids []string) error {
|
||||
return global.DB.Transaction(func(tx *gorm.DB) error {
|
||||
var imgIds []string
|
||||
tx.Table("sundynix_post_oss").Where("post_id IN ?", ids).Pluck("oss_id", &imgIds)
|
||||
|
||||
// 2. 清理中间表记录 (解开多对多关系)
|
||||
// 使用 Exec 直接操作中间表比循环 Clear 快得多
|
||||
if err := tx.Exec("DELETE FROM sundynix_post_oss WHERE post_id IN ?", ids).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 3. 物理删除图片记录本身
|
||||
if len(imgIds) > 0 {
|
||||
if err := tx.Unscoped().Where("id IN ?", imgIds).Delete(&system.Oss{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// 4. 批量删除点赞 (PostLike)
|
||||
if err := tx.Unscoped().Where("post_id IN ?", ids).Delete(&plant.PostLike{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
// 5. 批量删除评论 (PostComment)
|
||||
if err := tx.Unscoped().Where("post_id IN ?", ids).Delete(&plant.PostComment{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 6. 最后删除主表 Post
|
||||
if err := tx.Unscoped().Where("id IN ?", ids).Delete(&plant.Post{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// StarPost 收藏帖子
|
||||
func (s *PostService) StarPost(userId string, postId string, class string) error {
|
||||
if class == "1" {
|
||||
return global.DB.Transaction(func(tx *gorm.DB) error {
|
||||
var post plant.Post
|
||||
err := tx.Where("id = ?", postId).First(&post).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//1.更新点赞数
|
||||
err = tx.Model(&post).Update("star_count", post.LikeCount+1).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//2.添加到我的收藏
|
||||
star := plant.UserStar{
|
||||
UserId: userId,
|
||||
Type: 2,
|
||||
PostId: postId,
|
||||
}
|
||||
return tx.Create(&star).Error
|
||||
})
|
||||
} else if class == "2" {
|
||||
return global.DB.Transaction(func(tx *gorm.DB) error {
|
||||
var star plant.UserStar
|
||||
err := tx.Where("post_id = ? and user_id = ?", postId, userId).First(&star).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//1.更新收藏数
|
||||
var post plant.Post
|
||||
err = tx.Where("id = ?", postId).First(&post).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = tx.Model(&post).
|
||||
Where("star_count > ?", 0). // 只有大于 0 才会执行减法
|
||||
Update("star_count", gorm.Expr("star_count - 1")).
|
||||
Error
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//2.删除收藏
|
||||
return tx.Unscoped().Delete(&star).Error
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -45,3 +45,29 @@ func (s *UserProfileService) ProfileDetail(userId string) (plant.UserProfile, er
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// MyStars 我的收藏
|
||||
func (s *UserProfileService) MyStars(req plantReq.StarsPageReq, userId string) (list interface{}, total int64, err error) {
|
||||
limit := req.PageSize
|
||||
offset := req.PageSize * (req.Current - 1)
|
||||
db := global.DB.Model(&plant.UserStar{}).Preload("Wiki", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Preload("ImgList", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Order("created_at desc")
|
||||
})
|
||||
}).Preload("Post", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Preload("ImgList", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Order("created_at desc")
|
||||
})
|
||||
})
|
||||
var stars []*plant.UserStar
|
||||
db = db.Where("user_id = ?", userId)
|
||||
if req.Class != 0 {
|
||||
db = db.Where("type = ?", req.Class) //1.百科 //2.社交动态
|
||||
}
|
||||
err = db.Count(&total).Error
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = db.Limit(limit).Offset(offset).Order("created_at desc").Find(&stars).Error
|
||||
return stars, total, err
|
||||
}
|
||||
|
||||
+65
-2
@@ -149,7 +149,7 @@ func (s *WikiService) UpdateWiki(req plantReq.UpdateWiki) error {
|
||||
}
|
||||
|
||||
// WikiPage 分页
|
||||
func (s *WikiService) WikiPage(req plantReq.WikiPage) (list interface{}, total int64, err error) {
|
||||
func (s *WikiService) WikiPage(req plantReq.WikiPage, userId string) (list interface{}, total int64, err error) {
|
||||
limit := req.PageSize
|
||||
offset := req.PageSize * (req.Current - 1)
|
||||
db := global.DB.Model(&plant.Wiki{}).Preload("ImgList", func(db *gorm.DB) *gorm.DB {
|
||||
@@ -173,11 +173,35 @@ func (s *WikiService) WikiPage(req plantReq.WikiPage) (list interface{}, total i
|
||||
return
|
||||
}
|
||||
err = db.Limit(limit).Offset(offset).Order("created_at desc").Find(&wikis).Error
|
||||
|
||||
// 优化 N+1 查询
|
||||
var wikiIds []string
|
||||
for _, v := range wikis {
|
||||
wikiIds = append(wikiIds, v.Id)
|
||||
}
|
||||
//批量查询当前用户的收藏
|
||||
var stars []*plant.UserStar
|
||||
err = global.DB.Where("user_id = ? and wiki_id in ?", userId, wikiIds).Find(&stars).Error
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
starsMap := make(map[string]bool)
|
||||
for _, v := range stars {
|
||||
starsMap[v.WikiId] = true
|
||||
}
|
||||
// 是否收藏
|
||||
for i := range wikis {
|
||||
if starsMap[wikis[i].Id] {
|
||||
wikis[i].HasStar = 1
|
||||
} else {
|
||||
wikis[i].HasStar = 0
|
||||
}
|
||||
}
|
||||
return wikis, total, err
|
||||
}
|
||||
|
||||
// Detail 详情
|
||||
func (s *WikiService) Detail(id string) (w plant.Wiki, err error) {
|
||||
func (s *WikiService) Detail(id, userId string) (w plant.Wiki, err error) {
|
||||
var wiki plant.Wiki
|
||||
err = global.DB.Where("id = ?", id).
|
||||
Preload("Classes", func(db *gorm.DB) *gorm.DB {
|
||||
@@ -193,5 +217,44 @@ func (s *WikiService) Detail(id string) (w plant.Wiki, err error) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var stars []plant.UserStar
|
||||
err = global.DB.Where("user_id = ? and wiki_id = ?", userId, id).Find(&stars).Error
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(stars) > 0 {
|
||||
wiki.HasStar = 1
|
||||
}
|
||||
return wiki, nil
|
||||
}
|
||||
|
||||
// StarWiki 收藏
|
||||
func (s *WikiService) StarWiki(userId, wikiId, class string) error {
|
||||
if class == "1" {
|
||||
return global.DB.Transaction(func(tx *gorm.DB) error {
|
||||
var wiki plant.Wiki
|
||||
err := tx.Where("id = ?", wikiId).First(&wiki).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//2.添加到我的收藏
|
||||
star := plant.UserStar{
|
||||
UserId: userId,
|
||||
Type: 1,
|
||||
WikiId: wikiId,
|
||||
}
|
||||
return tx.Create(&star).Error
|
||||
})
|
||||
} else if class == "2" {
|
||||
return global.DB.Transaction(func(tx *gorm.DB) error {
|
||||
var star plant.UserStar
|
||||
err := tx.Where("wiki_id = ? and user_id = ?", wikiId, userId).First(&star).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//2.删除收藏
|
||||
return tx.Unscoped().Delete(&star).Error
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package system
|
||||
import (
|
||||
"context"
|
||||
"sundynix-go/global"
|
||||
"sundynix-go/utils"
|
||||
"sundynix-go/utils/timer"
|
||||
)
|
||||
|
||||
type JwtService struct{}
|
||||
@@ -12,7 +12,7 @@ var JwtServiceApp = new(JwtService)
|
||||
|
||||
// 登出,禁用jwt
|
||||
func (s *JwtService) PutBlacklist(userId string, token string) (err error) {
|
||||
expire, err := utils.ParseDuration(global.Config.JWT.ExpiresTime)
|
||||
expire, err := timer.ParseDuration(global.Config.JWT.ExpiresTime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user