372 lines
10 KiB
Go
372 lines
10 KiB
Go
package userProfile
|
|
|
|
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"
|
|
|
|
"github.com/zeromicro/go-zero/core/logx"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type GetMyStarsLogic struct {
|
|
logx.Logger
|
|
ctx context.Context
|
|
svcCtx *svc.ServiceContext
|
|
}
|
|
|
|
func NewGetMyStarsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetMyStarsLogic {
|
|
return &GetMyStarsLogic{Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx}
|
|
}
|
|
|
|
func (l *GetMyStarsLogic) GetMyStars(req *types.PageReq) (interface{}, error) {
|
|
userId := fmt.Sprintf("%v", l.ctx.Value("userId"))
|
|
|
|
db := l.svcCtx.DB.Model(&plantModel.UserStar{}).Where("user_id = ?", userId)
|
|
if req.Class == 1 {
|
|
db = db.Where("type = ?", "wiki")
|
|
} else if req.Class == 2 {
|
|
db = db.Where("type = ?", "post")
|
|
}
|
|
|
|
var total int64
|
|
if err := db.Count(&total).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
pageSize := req.PageSize
|
|
if pageSize <= 0 {
|
|
pageSize = 10
|
|
}
|
|
page := req.Current
|
|
if page <= 0 {
|
|
page = 1
|
|
}
|
|
offset := (page - 1) * pageSize
|
|
|
|
var stars []*plantModel.UserStar
|
|
if err := db.Limit(pageSize).Offset(offset).Order("created_at desc").Find(&stars).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 提取 TargetID
|
|
var wikiIds []string
|
|
var postIds []string
|
|
for _, s := range stars {
|
|
if s.Type == "wiki" {
|
|
wikiIds = append(wikiIds, s.TargetID)
|
|
} else if s.Type == "post" {
|
|
postIds = append(postIds, s.TargetID)
|
|
}
|
|
}
|
|
|
|
// 1. 查询 Wiki 详情
|
|
wikiMap := make(map[string]map[string]interface{})
|
|
if len(wikiIds) > 0 {
|
|
var wikis []*plantModel.Wiki
|
|
if err := l.svcCtx.DB.Where("id IN ?", wikiIds).Find(&wikis).Error; err == nil {
|
|
// 查本地 WikiOss
|
|
type rel struct {
|
|
WikiID string `gorm:"column:wiki_id"`
|
|
OssID string `gorm:"column:oss_id"`
|
|
}
|
|
var rels []rel
|
|
l.svcCtx.DB.Table("sundynix_plant_wiki_oss").Where("wiki_id IN ?", wikiIds).Find(&rels)
|
|
wikiOssMap := make(map[string][]string)
|
|
var allOssIds []string
|
|
for _, r := range rels {
|
|
wikiOssMap[r.WikiID] = append(wikiOssMap[r.WikiID], r.OssID)
|
|
allOssIds = append(allOssIds, r.OssID)
|
|
}
|
|
|
|
// 通过 FileRpc 获取图片信息
|
|
fileMap := l.fetchFileMap(allOssIds)
|
|
|
|
for _, w := range wikis {
|
|
ossIds := wikiOssMap[w.ID]
|
|
imgList := l.imgListToList(fileMap, ossIds)
|
|
wikiMap[w.ID] = map[string]interface{}{
|
|
"id": w.ID, "name": w.Name, "latinName": w.LatinName,
|
|
"aliases": w.Aliases, "genus": w.Genus, "difficulty": w.Difficulty,
|
|
"isHot": w.IsHot, "growthHabit": w.GrowthHabit,
|
|
"lightIntensity": w.LightIntensity, "classId": w.ClassID,
|
|
"createdAt": w.CreatedAt.Format("2006-01-02 15:04:05"),
|
|
"hasStar": 1, // 既然在这个列表中,说明一定是被收藏的
|
|
"imgList": imgList,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 2. 查询 Post 详情
|
|
postMap := make(map[string]map[string]interface{})
|
|
if len(postIds) > 0 {
|
|
var posts []*plantModel.Post
|
|
if err := l.svcCtx.DB.
|
|
Preload("CommentList", func(db *gorm.DB) *gorm.DB {
|
|
return db.Order("created_at asc")
|
|
}).
|
|
Preload("LikeList").
|
|
Where("id IN ?", postIds).Find(&posts).Error; err == nil {
|
|
|
|
// 查帖子图片
|
|
postImgMap := l.queryPostImages(postIds)
|
|
// 查用户信息
|
|
allUserIds := l.collectPostUserIds(posts)
|
|
userMap := l.queryUserMap(allUserIds)
|
|
// 点赞收藏状态
|
|
likedSet, starredSet := l.queryLikeStarStatus(userId, postIds)
|
|
|
|
for _, p := range posts {
|
|
item := map[string]interface{}{
|
|
"id": p.ID, "title": p.Title, "content": p.Content,
|
|
"userId": p.UserID, "location": p.Location,
|
|
"viewCount": p.ViewCount, "commentCount": p.CommentCount,
|
|
"likeCount": p.LikeCount, "starCount": p.StarCount,
|
|
"hasReviewed": p.HasReviewed,
|
|
"createdAt": p.CreatedAt.Format(time.RFC3339),
|
|
"updatedAt": p.UpdatedAt.Format(time.RFC3339),
|
|
"createdAtStr": p.CreatedAt.Format("2006-01-02 15:04:05"),
|
|
"hasLiked": 0, "hasStar": 0,
|
|
"imgList": postImgMap[p.ID],
|
|
"publisher": l.buildPublisherInfo(userMap, p.UserID),
|
|
"commentList": l.buildCommentList(userMap, p.CommentList),
|
|
"likeList": l.buildLikeList(userMap, p.LikeList),
|
|
"starList": []map[string]interface{}{},
|
|
}
|
|
if likedSet[p.ID] {
|
|
item["hasLiked"] = 1
|
|
}
|
|
if starredSet[p.ID] {
|
|
item["hasStar"] = 1
|
|
}
|
|
postMap[p.ID] = item
|
|
}
|
|
}
|
|
}
|
|
|
|
// 3. 按照 Stars 排序组装最终 List
|
|
var list []map[string]interface{}
|
|
for _, s := range stars {
|
|
item := map[string]interface{}{
|
|
"id": s.ID, "userId": s.UserID, "targetId": s.TargetID, "type": s.Type,
|
|
"createdAt": s.CreatedAt.Format("2006-01-02 15:04:05"),
|
|
}
|
|
if s.Type == "wiki" {
|
|
if w, ok := wikiMap[s.TargetID]; ok {
|
|
item["wiki"] = w
|
|
list = append(list, item)
|
|
}
|
|
} else if s.Type == "post" {
|
|
if p, ok := postMap[s.TargetID]; ok {
|
|
item["post"] = p
|
|
list = append(list, item)
|
|
}
|
|
}
|
|
}
|
|
|
|
if list == nil {
|
|
list = []map[string]interface{}{}
|
|
}
|
|
|
|
return map[string]interface{}{
|
|
"list": list,
|
|
"total": total,
|
|
"page": page,
|
|
"pageSize": pageSize,
|
|
}, nil
|
|
}
|
|
|
|
func (l *GetMyStarsLogic) fetchFileMap(ids []string) map[string]map[string]interface{} {
|
|
result := make(map[string]map[string]interface{})
|
|
if len(ids) == 0 {
|
|
return result
|
|
}
|
|
resp, err := l.svcCtx.FileRpc.GetFilesByIds(l.ctx, &filePb.GetFilesByIdsReq{Ids: ids})
|
|
if err != nil || resp == nil {
|
|
return result
|
|
}
|
|
for _, f := range resp.Files {
|
|
result[f.Id] = 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),
|
|
"updatedAt": time.Unix(f.CreatedAt, 0).Format(time.RFC3339),
|
|
"createdAtStr": time.Unix(f.CreatedAt, 0).Format("2006-01-02 15:04:05"),
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func (l *GetMyStarsLogic) imgListToList(fileMap map[string]map[string]interface{}, ossIds []string) []map[string]interface{} {
|
|
var list []map[string]interface{}
|
|
for _, id := range ossIds {
|
|
if img, ok := fileMap[id]; ok {
|
|
list = append(list, img)
|
|
}
|
|
}
|
|
if list == nil {
|
|
list = []map[string]interface{}{}
|
|
}
|
|
return list
|
|
}
|
|
|
|
func (l *GetMyStarsLogic) queryPostImages(postIds []string) map[string][]map[string]interface{} {
|
|
type rel struct {
|
|
PostID string `gorm:"column:post_id"`
|
|
OssID string `gorm:"column:oss_id"`
|
|
}
|
|
var rels []rel
|
|
l.svcCtx.DB.Table("sundynix_plant_post_oss").Where("post_id IN ?", postIds).Find(&rels)
|
|
|
|
var allOssIds []string
|
|
pidMap := make(map[string][]string)
|
|
for _, r := range rels {
|
|
pidMap[r.PostID] = append(pidMap[r.PostID], r.OssID)
|
|
allOssIds = append(allOssIds, r.OssID)
|
|
}
|
|
|
|
fileInfos := l.fetchFileMap(allOssIds)
|
|
|
|
result := make(map[string][]map[string]interface{})
|
|
for pid, ids := range pidMap {
|
|
var imgs []map[string]interface{}
|
|
for _, oid := range ids {
|
|
if info, ok := fileInfos[oid]; ok {
|
|
imgs = append(imgs, info)
|
|
}
|
|
}
|
|
if imgs == nil {
|
|
imgs = []map[string]interface{}{}
|
|
}
|
|
result[pid] = imgs
|
|
}
|
|
for _, pid := range postIds {
|
|
if _, ok := result[pid]; !ok {
|
|
result[pid] = []map[string]interface{}{}
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func (l *GetMyStarsLogic) collectPostUserIds(posts []*plantModel.Post) []string {
|
|
set := make(map[string]bool)
|
|
for _, p := range posts {
|
|
set[p.UserID] = true
|
|
for _, c := range p.CommentList {
|
|
set[c.UserID] = true
|
|
}
|
|
for _, l := range p.LikeList {
|
|
set[l.UserID] = true
|
|
}
|
|
}
|
|
var ids []string
|
|
for id := range set {
|
|
ids = append(ids, id)
|
|
}
|
|
return ids
|
|
}
|
|
|
|
func (l *GetMyStarsLogic) queryUserMap(ids []string) map[string]map[string]interface{} {
|
|
result := make(map[string]map[string]interface{})
|
|
if len(ids) == 0 {
|
|
return result
|
|
}
|
|
type userRow struct {
|
|
ID string `gorm:"column:id"`
|
|
NickName string `gorm:"column:nick_name"`
|
|
Name string `gorm:"column:name"`
|
|
AvatarID string `gorm:"column:avatar_id"`
|
|
}
|
|
var rows []userRow
|
|
l.svcCtx.DB.Table("sundynix_user").Where("id IN ?", ids).Find(&rows)
|
|
|
|
var avatarIds []string
|
|
for _, row := range rows {
|
|
if row.AvatarID != "" {
|
|
avatarIds = append(avatarIds, row.AvatarID)
|
|
}
|
|
}
|
|
avatarMap := l.fetchFileMap(avatarIds)
|
|
|
|
for _, row := range rows {
|
|
avatarData := map[string]interface{}{}
|
|
if av, ok := avatarMap[row.AvatarID]; ok {
|
|
avatarData = av
|
|
}
|
|
result[row.ID] = map[string]interface{}{
|
|
"id": row.ID, "nickName": row.NickName, "name": row.Name,
|
|
"avatarId": row.AvatarID, "avatar": avatarData,
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func (l *GetMyStarsLogic) queryLikeStarStatus(userId string, postIds []string) (likedSet, starredSet map[string]bool) {
|
|
likedSet = make(map[string]bool)
|
|
starredSet = make(map[string]bool)
|
|
if len(postIds) == 0 {
|
|
return
|
|
}
|
|
type rel struct {
|
|
PostID string `gorm:"column:post_id"`
|
|
}
|
|
var likes []rel
|
|
l.svcCtx.DB.Table("sundynix_plant_post_like").Where("post_id IN ? AND user_id = ?", postIds, userId).Find(&likes)
|
|
for _, l := range likes {
|
|
likedSet[l.PostID] = true
|
|
}
|
|
var stars []rel
|
|
l.svcCtx.DB.Table("sundynix_plant_user_star").Where("target_id IN ? AND user_id = ? AND type = 'post'", postIds, userId).Find(&stars)
|
|
for _, s := range stars {
|
|
starredSet[s.PostID] = true
|
|
}
|
|
return
|
|
}
|
|
|
|
func (l *GetMyStarsLogic) buildPublisherInfo(userMap map[string]map[string]interface{}, userId string) map[string]interface{} {
|
|
if u, ok := userMap[userId]; ok {
|
|
return u
|
|
}
|
|
return map[string]interface{}{
|
|
"id": userId, "nickName": "", "name": "", "avatarId": "", "avatar": map[string]interface{}{},
|
|
}
|
|
}
|
|
|
|
func (l *GetMyStarsLogic) buildCommentList(userMap map[string]map[string]interface{}, comments []*plantModel.PostComment) []map[string]interface{} {
|
|
var list []map[string]interface{}
|
|
for _, c := range comments {
|
|
list = append(list, map[string]interface{}{
|
|
"id": c.ID, "postId": c.PostID, "userId": c.UserID,
|
|
"content": c.Content, "parentId": c.ParentID,
|
|
"createdAt": c.CreatedAt.Format(time.RFC3339),
|
|
"updatedAt": c.UpdatedAt.Format(time.RFC3339),
|
|
"createdAtStr": c.CreatedAt.Format("2006-01-02 15:04:05"),
|
|
"commentator": l.buildPublisherInfo(userMap, c.UserID),
|
|
})
|
|
}
|
|
if list == nil {
|
|
list = []map[string]interface{}{}
|
|
}
|
|
return list
|
|
}
|
|
|
|
func (l *GetMyStarsLogic) buildLikeList(userMap map[string]map[string]interface{}, likes []*plantModel.PostLike) []map[string]interface{} {
|
|
var list []map[string]interface{}
|
|
for _, like := range likes {
|
|
list = append(list, map[string]interface{}{
|
|
"id": like.ID, "postId": like.PostID, "userId": like.UserID,
|
|
"liker": l.buildPublisherInfo(userMap, like.UserID),
|
|
})
|
|
}
|
|
if list == nil {
|
|
list = []map[string]interface{}{}
|
|
}
|
|
return list
|
|
}
|