feat: 徽章处理

This commit is contained in:
Blizzard
2026-02-14 15:35:12 +08:00
parent 4ffc41ea84
commit 3f50901ac6
10 changed files with 157 additions and 8 deletions
+20
View File
@@ -82,3 +82,23 @@ func (a *UserProfileApi) MyStars(c *gin.Context) {
PageSize: req.PageSize, PageSize: req.PageSize,
}, c) }, c)
} }
// MyBadges 我的徽章
// @Tags 个人中心
// @Summary 我的徽章
// @Security BearerAuth
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /profile/badge [get]
func (a *UserProfileApi) MyBadges(c *gin.Context) {
userId := auth.GetUserId(c)
list, err := userProfileService.MyBadges(userId)
if err != nil {
global.Logger.Error("获取用户徽章失败", zap.Error(err))
response.FailWithMsg("获取用户徽章失败", c)
return
}
response.OkWithData(response.ListResult{
List: list,
}, c)
}
+51
View File
@@ -2,6 +2,7 @@ package plant
import ( import (
"sundynix-go/global" "sundynix-go/global"
common "sundynix-go/model/commom/request"
"sundynix-go/model/commom/response" "sundynix-go/model/commom/response"
plantReq "sundynix-go/model/plant/request" plantReq "sundynix-go/model/plant/request"
"sundynix-go/utils/auth" "sundynix-go/utils/auth"
@@ -113,6 +114,31 @@ func (a *WikiApi) WikiDetail(c *gin.Context) {
response.OkWithData(topic, c) response.OkWithData(topic, c)
} }
// DeleteWiki 删除百科
// @Tags 百科
// @Summary 删除百科
// @Security BearerAuth
// @accept application/json
// @Produce application/json
// @Param data body common.IdsReq true "删除百科"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /wiki/delete [post]
func (a *WikiApi) DeleteWiki(c *gin.Context) {
var req common.IdsReq
err := c.ShouldBindJSON(&req)
if err != nil {
response.FailWithMsg("请求参数错误", c)
return
}
err = wikiService.DeleteWiki(req)
if err != nil {
global.Logger.Error("删除失败", zap.Error(err))
response.FailWithMsg("删除失败", c)
return
}
response.OkWithMsg("删除成功", c)
}
// StarWiki 收藏百科 // StarWiki 收藏百科
// @Tags 百科 // @Tags 百科
// @Summary 收藏百科 // @Summary 收藏百科
@@ -134,3 +160,28 @@ func (a *WikiApi) StarWiki(c *gin.Context) {
} }
response.OkWithMsg("操作成功", c) response.OkWithMsg("操作成功", c)
} }
// UploadImg 上传图片
// @Tags 百科
// @Summary 上传图片
// @Security BearerAuth
// @accept application/json
// @Produce application/json
// @Param data body common.UploadOss true "上传图片"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"上传成功"}"
// @Router /wiki/uploadImg [post]
func (a *WikiApi) UploadImg(c *gin.Context) {
var req common.UploadOss
err := c.ShouldBind(&req)
if err != nil {
response.FailWithMsg("请求参数错误", c)
return
}
err = wikiService.UploadImg(req)
if err != nil {
global.Logger.Error("上传失败", zap.Error(err))
response.FailWithMsg("上传失败", c)
return
}
response.OkWithMsg("上传成功", c)
}
+1 -1
View File
@@ -15,7 +15,7 @@ func InitTimer() {
option = append(option, cron.WithSeconds()) option = append(option, cron.WithSeconds())
// 任务一:每天8点30执行 发送植物养护提醒 // 任务一:每天8点30执行 发送植物养护提醒
_, err := global.Timer.AddTaskByFuncWithSecond("SendCareRemind", "0 15 9 * * *", func() { _, err := global.Timer.AddTaskByFuncWithSecond("SendCareRemind", "0 30 8 * * *", func() {
err1 := task.SendCareMsg() err1 := task.SendCareMsg()
if err1 != nil { if err1 != nil {
global.Logger.Error("定时发送植物养护提醒失败", zap.Error(err1)) global.Logger.Error("定时发送植物养护提醒失败", zap.Error(err1))
+4 -3
View File
@@ -7,7 +7,8 @@ import (
type UserBadge struct { type UserBadge struct {
global.BaseModel global.BaseModel
UserId string `gorm:"type:varchar(50);index;not null;column:user_id;comment:用户id" json:"userId"` UserId string `gorm:"type:varchar(50);index;not null;column:user_id;comment:用户id" json:"userId"`
BadgeId string `gorm:"index:idx_user_badge,unique;not null;column:badge_id;comment:徽章配置ID" json:"badgeId"` BadgeId string `gorm:"index:idx_user_badge,unique;not null;column:badge_id;comment:徽章配置ID" json:"badgeId"`
AcquiredAt time.Time `gorm:"autoCreateTime;column:acquired_at;comment:获得时间" json:"acquiredAt"` AcquiredAt time.Time `gorm:"autoCreateTime;column:acquired_at;comment:获得时间" json:"acquiredAt"`
Badge *BadgeConfig `json:"badge" gorm:"foreignKey:BadgeId"`
} }
+2 -1
View File
@@ -10,7 +10,8 @@ func (c *UserProfileRouter) InitUserProfileRouter(Router *gin.RouterGroup) {
userProfileRouter.POST("update", userProfileApi.UpdateProfile) userProfileRouter.POST("update", userProfileApi.UpdateProfile)
userProfileRouter.GET("detail", userProfileApi.ProfileDetail) userProfileRouter.GET("detail", userProfileApi.ProfileDetail)
userProfileRouter.POST("star", userProfileApi.MyStars) //我的收藏 userProfileRouter.POST("star", userProfileApi.MyStars) //我的收藏
userProfileRouter.GET("badge", userProfileApi.MyBadges) //我的徽章
} }
} }
+2
View File
@@ -11,6 +11,8 @@ func (p *WikiRouter) InitWikiRouter(Router *gin.RouterGroup) {
wikiRouter.POST("/update", wikiApi.UpdateWiki) wikiRouter.POST("/update", wikiApi.UpdateWiki)
wikiRouter.POST("/page", wikiApi.WikiPage) wikiRouter.POST("/page", wikiApi.WikiPage)
wikiRouter.GET("/detail", wikiApi.WikiDetail) wikiRouter.GET("/detail", wikiApi.WikiDetail)
wikiRouter.POST("/delete", wikiApi.DeleteWiki)
wikiRouter.POST("/uploadImg", wikiApi.UploadImg)
//用户端 //用户端
wikiRouter.GET("/star", wikiApi.StarWiki) //收藏或者取消收藏 wikiRouter.GET("/star", wikiApi.StarWiki) //收藏或者取消收藏
+15 -1
View File
@@ -39,7 +39,10 @@ func (s *UserProfileService) UpdateProfile(req plantReq.UpdateProfile, userId st
// ProfileDetail 获取用户详情 // ProfileDetail 获取用户详情
func (s *UserProfileService) ProfileDetail(userId string) (plant.UserProfile, error) { func (s *UserProfileService) ProfileDetail(userId string) (plant.UserProfile, error) {
var res plant.UserProfile var res plant.UserProfile
err := global.DB.Where("user_id = ?", userId).Preload("Avatar").Preload("Level").First(&res).Error err := global.DB.Where("user_id = ?", userId).
Preload("Avatar").
Preload("Level").
First(&res).Error
if err != nil { if err != nil {
return res, err return res, err
} }
@@ -71,3 +74,14 @@ func (s *UserProfileService) MyStars(req plantReq.StarsPageReq, userId string) (
err = db.Limit(limit).Offset(offset).Order("created_at desc").Find(&stars).Error err = db.Limit(limit).Offset(offset).Order("created_at desc").Find(&stars).Error
return stars, total, err return stars, total, err
} }
// MyBadges 我的徽章
func (s *UserProfileService) MyBadges(userId string) ([]plant.UserBadge, error) {
var badges []plant.UserBadge
err := global.DB.Where("user_id = ?", userId).
Preload("Badge", func(db *gorm.DB) *gorm.DB {
return db.Preload("Icon")
}).
Find(&badges).Error
return badges, err
}
+54
View File
@@ -3,6 +3,7 @@ package plant
import ( import (
"errors" "errors"
"sundynix-go/global" "sundynix-go/global"
common "sundynix-go/model/commom/request"
"sundynix-go/model/plant" "sundynix-go/model/plant"
plantReq "sundynix-go/model/plant/request" plantReq "sundynix-go/model/plant/request"
"sundynix-go/model/system" "sundynix-go/model/system"
@@ -258,3 +259,56 @@ func (s *WikiService) StarWiki(userId, wikiId, class string) error {
} }
return nil return nil
} }
// UploadImg 上传图片
func (s *WikiService) UploadImg(req common.UploadOss) error {
return global.DB.Transaction(func(tx *gorm.DB) error {
var wiki plant.Wiki
err := tx.Where("id = ?", req.Id).First(&wiki).Error
if err != nil {
return err
}
var ossList []system.Oss
err = tx.Where("id in ?", req.OssIds).Find(&ossList).Error
if err != nil {
return err
}
var relations []map[string]interface{}
for _, oss := range ossList {
relations = append(relations, map[string]interface{}{
"wiki_id": wiki.Id,
"oss_id": oss.Id,
})
}
//3.添加关联关系(添加引用)
return global.DB.Table("sundynix_wiki_oss").Create(relations).Error
})
}
// DeleteWiki 删除百科
func (s *WikiService) DeleteWiki(req common.IdsReq) error {
return global.DB.Transaction(func(tx *gorm.DB) error {
var imgIds []string
tx.Table("sundynix_wiki_oss").Where("wiki_id IN ?", req.Ids).Pluck("oss_id", &imgIds)
// 3. 物理删除图片记录本身
if len(imgIds) > 0 {
if err := tx.Unscoped().Where("id IN ?", imgIds).Delete(&system.Oss{}).Error; err != nil {
return err
}
}
// 2. 清理中间表记录 (解开多对多关系)
// 使用 Exec 直接操作中间表比循环 Clear 快得多
if err := tx.Exec("DELETE FROM sundynix_wiki_oss WHERE wiki_id IN ?", req.Ids).Error; err != nil {
return err
}
if err := tx.Exec("DELETE FROM sundynix_wiki_class WHERE wiki_id IN ?", req.Ids).Error; err != nil {
return err
}
if err := tx.Exec("DELETE FROM sundynix_wiki_related WHERE wiki_id IN ? or related_wiki_id in ?", req.Ids, req.Ids).Error; err != nil {
return err
}
//删除百科本身
return tx.Unscoped().Where("id IN ?", req.Ids).Delete(&plant.Wiki{}).Error
})
}
+6
View File
@@ -162,11 +162,17 @@ func (userService *UserService) MiniLogin(code string) (result *system.User, err
UserId: newUser.Id, UserId: newUser.Id,
MiniOpenId: wxResp.Openid, MiniOpenId: wxResp.Openid,
Nickname: newUser.Name, Nickname: newUser.Name,
LevelId: "9bc0cd78-070f-11f1-8e90-1a43c43655d1",
CurrentSunlight: 0, CurrentSunlight: 0,
TotalSunlight: 0, TotalSunlight: 0,
PlantCount: 0, PlantCount: 0,
CareCount: 0, CareCount: 0,
PostCount: 0, PostCount: 0,
WaterCount: 0,
FertilizeCount: 0,
RepotCount: 0,
PruneCount: 0,
PhotoCount: 0,
} }
if err := tx.Create(&profile).Error; err != nil { if err := tx.Create(&profile).Error; err != nil {
return err return err
+2 -2
View File
@@ -66,11 +66,11 @@ func SendCareMsg() error {
} }
//3.构造请求参数 发送订阅消息 //3.构造请求参数 发送订阅消息
payload := SendMessagePayload{ payload := SendMessagePayload{
TemplateID: "R7fh3NDpuV8DYqI83HpEQvC8mLJy5xMWFl1qeGN9JIo", TemplateID: "iG5GYMPQAgKxIE9zZNOgKS6tCURhM9p9AC8iZ3Uj3uA",
Page: "pages/tasks/index", Page: "pages/tasks/index",
Touser: user.MiniOpenId, Touser: user.MiniOpenId,
Data: map[string]TemplateDataItem{ Data: map[string]TemplateDataItem{
"thing2": { "thing1": {
Value: myPlant.Name + "等", Value: myPlant.Name + "等",
}, },
"time3": { "time3": {