Files
IUQT/acquaintances/biz/dal/mysql/friend_moments.go

379 lines
10 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package mysql
import (
"acquaintances/biz/model"
"acquaintances/biz/model/user"
"errors"
"fmt"
"github.com/cloudwego/hertz/pkg/common/hlog"
"gorm.io/gorm"
)
// SaveMomentWithImages 新建动态
func SaveMomentWithImages(moment *model.Moment, imageURLs []string) error {
db := DB
// 使用事务确保数据一致性
return db.Transaction(func(tx *gorm.DB) error {
// 保存动态
if err := tx.Create(moment).Error; err != nil {
return err
}
// 保存图片(如果有)
if len(imageURLs) > 0 {
images := make([]model.MomentImage, 0, len(imageURLs))
for _, url := range imageURLs {
images = append(images, model.MomentImage{
MomentID: moment.ID,
ImageURL: url,
})
}
if err := tx.Create(&images).Error; err != nil {
return err
}
}
return nil
})
}
// CheckUserExists 检查用户是否存在
func CheckUserExists(userID string) (bool, error) {
db := DB
// 实际实现中应查询数据库验证用户是否存在
// 这里仅为示例
var count int64
if err := db.Model(&model.User{}).Where("user_id = ?", userID).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}
// 获取当前用户的好友ID列表
// 获取当前用户的好友ID列表
func getFriendUserIDs(userID string) ([]string, error) {
var friends []model.FriendRelationship
// 一次查询所有与当前用户相关的已通过好友关系
err := DB.Model(model.FriendRelationship{}).
Where("(applicant_id = ? OR target_user_id = ?) AND status = 1", userID, userID).
Find(&friends).Error
if err != nil {
return nil, fmt.Errorf("查询好友列表失败: %w", err)
}
// 使用map去重
friendMap := make(map[string]struct{})
for _, rel := range friends {
// 根据关系方向添加对应的好友ID
if rel.ApplicantID == userID {
friendMap[rel.TargetUserID] = struct{}{}
} else {
friendMap[rel.ApplicantID] = struct{}{}
}
}
// 转换map为切片
friendUserIDs := make([]string, 0, len(friendMap))
for id := range friendMap {
friendUserIDs = append(friendUserIDs, id)
}
return friendUserIDs, nil
}
// 将用户模型转换为DTO
func convertUserModelToDTO(u model.User) user.UserInfoReq {
userInfo := user.UserInfoReq{
UserID: u.UserID,
UserName: u.UserName,
Gender: u.Gender,
Age: int64(u.Age),
Introduce: u.Introduce,
AvatarImageURL: u.AvatarImageURL,
}
// 可选字段处理
if u.Birthday != nil {
userInfo.Birthday = u.Birthday.Format("2006-01-02")
}
return userInfo
}
// GetMomentsImage 获取指定动态的图像列表
func GetMomentsImage(ids uint) ([]*user.MomentImage, error) {
db := DB
var images []model.MomentImage
var data []*user.MomentImage
err := db.Model(&model.MomentImage{}).Where("moment_id = ?", ids).Find(&images).Error
if err != nil {
return nil, err
}
for _, v := range images {
data = append(data, &user.MomentImage{
ID: int64(v.ID),
MomentID: int64(v.MomentID),
ImageURL: v.ImageURL,
})
}
return data, nil
}
// GetFriendsMoments 获取好友动态
func GetFriendsMoments(req user.ListMomentsRequest) ([]*user.Moment, int32, error) {
db := DB
//获取好友id列表
friends, err := getFriendUserIDs(req.UserID)
if err != nil {
return nil, 0, err
}
// 校验分页参数
if req.Page < 1 {
req.Page = 1
}
if req.PageSize < 1 {
req.PageSize = 10
}
// 查询总数
var total int64
query := db.Model(&model.Moment{}).Where("user_id = ?", req.UserID)
if len(friends) > 0 {
query = query.Or("user_id IN (?) AND visibility != ?", friends, model.VisibilitySelfOnly)
}
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
//获取朋友圈内容信息
var moments []model.Moment
query = db.Model(&model.Moment{}).Where("user_id = ?", req.UserID)
if len(friends) > 0 {
query = query.Or("user_id IN (?) AND visibility != ?", friends, model.VisibilitySelfOnly)
}
err = query.Limit(int(req.PageSize)).Offset(int(req.PageSize * (req.Page - 1))).Find(&moments).Error
if err != nil {
return nil, 0, err
}
//批量查询用户信息
var userIDs []string
for _, v := range moments {
userIDs = append(userIDs, v.UserID)
}
userInfo, err := GetUsersById(userIDs...) // 自定义批量查询函数
if err != nil {
hlog.Errorf("批量查询用户失败: %v", err)
return nil, 0, err
}
var data []*user.Moment
query = db.Model(&model.Moment{}).Where("user_id = ?", req.UserID)
if len(friends) > 0 {
query = query.Or("user_id IN (?) AND visibility != ?", friends, model.VisibilitySelfOnly)
}
err = query.Limit(int(req.PageSize)).Offset(int(req.PageSize * (req.Page - 1))).Find(&moments).Error
if err != nil {
return nil, 0, err
}
for k, v := range moments {
images, err := GetMomentsImage(v.ID)
if err != nil {
continue
}
data = append(data, &user.Moment{
ID: int64(v.ID),
UserID: v.UserID,
User: userInfo[k],
Content: v.Content,
Location: v.Location,
Status: user.ContentStatus(int64(v.Status)),
LikeCount: int32(v.LikeCount),
CommentCount: int32(v.CommentCount),
Images: images,
CreatedAt: v.CreatedAt.Format("2006-01-02 15:04"),
})
}
return data, int32(total), nil
}
// GetMomentsAppoint 获取指定好友动态
func GetMomentsAppoint(req user.ListMomentsAppointRequest) ([]*user.Moment, int32, error) {
db := DB
// 校验分页参数
if req.Page < 1 {
req.Page = 1
}
if req.PageSize < 1 {
req.PageSize = 10
}
// 查询总数
var total int64
query := db.Model(&model.Moment{}).Where("user_id = ?", req.UserID)
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
//获取朋友圈内容信息
var moments []model.Moment
query = db.Model(&model.Moment{}).Where("user_id = ?", req.UserID)
err := query.Limit(int(req.PageSize)).Offset(int(req.PageSize * (req.Page - 1))).Find(&moments).Error
if err != nil {
return nil, 0, err
}
//查询用户信息
userInfo, err := GetUsersById(req.UserID) // 自定义批量查询函数
if err != nil || len(userInfo) != 1 {
hlog.Errorf("批量查询用户失败: %v", err)
return nil, 0, err
}
var data []*user.Moment
query = db.Model(&model.Moment{}).Where("user_id = ?", req.UserID).Limit(int(req.PageSize)).Offset(int(req.PageSize * (req.Page - 1))).Find(&moments)
if db.Error != nil {
return nil, 0, err
}
for _, v := range moments {
images, err := GetMomentsImage(v.ID)
if err != nil {
continue
}
data = append(data, &user.Moment{
ID: int64(v.ID),
UserID: v.UserID,
User: userInfo[0],
Content: v.Content,
Location: v.Location,
Status: user.ContentStatus(int64(v.Status)),
LikeCount: int32(v.LikeCount),
CommentCount: int32(v.CommentCount),
Images: images,
CreatedAt: v.CreatedAt.Format("2006-01-02 15:04"),
})
}
return data, int32(total), nil
}
// DeleteMoment 删除朋友圈动态
func DeleteMoment(req user.DeleteMomentRequest) error {
db := DB
// 使用事务确保数据一致性
return db.Transaction(func(tx *gorm.DB) error {
// 保存动态
if err := tx.Model(&model.Moment{}).Where("id = ?", req.MomentID).Delete(&model.Moment{}).Error; err != nil {
return err
}
// 删除图片
if err := tx.Model(model.MomentImage{}).Where("moment_id = ?", req.MomentID).Delete(&model.MomentImage{}).Error; err != nil {
return err
}
//删除评论
//TODO
//删除点赞
//TODO
return nil
})
}
// LikeMoment 点赞朋友圈动态
func LikeMoment(req user.LikeMomentRequest) error {
db := DB
// 使用事务确保数据一致性
return db.Transaction(func(tx *gorm.DB) error {
// 检查是否已经点赞
var existingLike model.MomentLike
err := tx.Model(&model.MomentLike{}).
Where("user_id = ? AND moment_id = ?", req.UserID, req.MomentID).
First(&existingLike).Error
// 如果不是"未找到"错误,说明查询异常
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return fmt.Errorf("检查点赞记录失败: %w", err)
}
// 如果已经点赞,返回错误
if err == nil {
return errors.New("已经点赞过该动态")
}
// 新增点赞记录
if err := tx.Model(&model.MomentLike{}).Create(&model.MomentLike{
UserID: req.UserID,
MomentID: uint(req.MomentID),
}).Error; err != nil {
return fmt.Errorf("创建点赞记录失败: %w", err)
}
// 点赞数原子增加1避免并发问题
result := tx.Model(model.Moment{}).
Where("moment_id = ?", req.MomentID).
Update("like_count", gorm.Expr("like_count + 1"))
if result.Error != nil {
return fmt.Errorf("更新点赞数失败: %w", result.Error)
}
// 检查动态是否存在
if result.RowsAffected == 0 {
return errors.New("动态不存在")
}
return nil
})
}
// UnlikeMoment 取消点赞朋友圈动态
func UnlikeMoment(req user.UnlikeMomentRequest) error {
db := DB
// 使用事务确保数据一致性
return db.Transaction(func(tx *gorm.DB) error {
// 检查是否存在点赞记录
var like model.MomentLike
err := tx.Model(&model.MomentLike{}).
Where("user_id = ? AND moment_id = ?", req.UserID, req.MomentID).
First(&like).Error
// 如果不是"未找到"错误,说明查询异常
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return fmt.Errorf("检查点赞记录失败: %w", err)
}
// 如果没有点赞记录,返回错误
if errors.Is(err, gorm.ErrRecordNotFound) {
return errors.New("未点赞该动态,无法取消")
}
// 删除点赞记录
if err := tx.Model(&model.MomentLike{}).
Where("user_id = ? AND moment_id = ?", req.UserID, req.MomentID).
Delete(&model.MomentLike{}).Error; err != nil {
return fmt.Errorf("删除点赞记录失败: %w", err)
}
// 点赞数原子减少1
result := tx.Model(model.Moment{}).
Where("moment_id = ? AND like_count > 0", req.MomentID). // 确保点赞数不会小于0
Update("like_count", gorm.Expr("like_count - 1"))
if result.Error != nil {
return fmt.Errorf("更新点赞数失败: %w", result.Error)
}
// 检查动态是否存在
if result.RowsAffected == 0 {
return errors.New("动态不存在或点赞数已为0")
}
return nil
})
}