bug修改&朋友圈功能完善
This commit is contained in:
@@ -3,8 +3,10 @@ package mysql
|
||||
import (
|
||||
"acquaintances/biz/model"
|
||||
"acquaintances/biz/model/user"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/cloudwego/hertz/pkg/common/hlog"
|
||||
"gorm.io/gorm"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SaveMomentWithImages 新建动态
|
||||
@@ -20,11 +22,10 @@ func SaveMomentWithImages(moment *model.Moment, imageURLs []string) error {
|
||||
// 保存图片(如果有)
|
||||
if len(imageURLs) > 0 {
|
||||
images := make([]model.MomentImage, 0, len(imageURLs))
|
||||
for i, url := range imageURLs {
|
||||
for _, url := range imageURLs {
|
||||
images = append(images, model.MomentImage{
|
||||
MomentID: moment.ID,
|
||||
ImageURL: url,
|
||||
SortOrder: uint8(i), // 按URL顺序排序
|
||||
MomentID: moment.ID,
|
||||
ImageURL: url,
|
||||
})
|
||||
}
|
||||
if err := tx.Create(&images).Error; err != nil {
|
||||
@@ -48,100 +49,36 @@ func CheckUserExists(userID string) (bool, error) {
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
// 构建可见性查询条件
|
||||
func buildVisibilityCondition(currentUserID string) func(db *gorm.DB) *gorm.DB {
|
||||
return func(db *gorm.DB) *gorm.DB {
|
||||
// 可见性条件:公开 或者 仅自己可见(且是当前用户) 或者 仅好友可见(需要查询好友关系)
|
||||
return db.Where("(visibility = ?) OR (visibility = ? AND user_id = ?) OR (visibility = ? AND user_id IN (?))",
|
||||
model.VisibilityPublic,
|
||||
model.VisibilitySelfOnly,
|
||||
currentUserID,
|
||||
model.VisibilityFriendsOnly,
|
||||
getFriendUserIDs(currentUserID), // 需要实现好友关系查询
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取当前用户的好友ID列表
|
||||
func getFriendUserIDs(userID string) []string {
|
||||
// 实际项目中需要查询好友关系表
|
||||
// 这里简化处理,返回空列表
|
||||
return []string{}
|
||||
}
|
||||
|
||||
// ConvertMomentsToDTOs 将数据库模型转换为API响应DTO
|
||||
func ConvertMomentsToDTOs(moments []model.Moment, currentUserID string) ([]user.Moment, error) {
|
||||
db := DB
|
||||
var result []user.Moment
|
||||
|
||||
// 提取所有用户ID用于批量查询
|
||||
userIDs := make([]string, 0, len(moments))
|
||||
for _, m := range moments {
|
||||
userIDs = append(userIDs, m.UserID)
|
||||
}
|
||||
|
||||
// 批量查询用户信息
|
||||
userMap, err := batchGetUserInfo(userIDs)
|
||||
// 获取当前用户的好友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, err
|
||||
return nil, fmt.Errorf("查询好友列表失败: %w", err)
|
||||
}
|
||||
|
||||
// 处理每条动态
|
||||
for _, m := range moments {
|
||||
// 获取用户信息
|
||||
userInfo := convertUserModelToDTO(userMap[m.UserID])
|
||||
|
||||
// 查询动态图片
|
||||
var images []model.MomentImage
|
||||
if err := db.Where("moment_id = ?", m.ID).
|
||||
Order("sort_order ASC").
|
||||
Find(&images).Error; err != nil {
|
||||
return nil, 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{}{}
|
||||
}
|
||||
|
||||
// 转换图片列表
|
||||
momentImages := make([]*user.MomentImage, 0, len(images))
|
||||
for _, img := range images {
|
||||
momentImages = append(momentImages, &user.MomentImage{
|
||||
ID: int64(img.ID),
|
||||
MomentID: int64(img.MomentID),
|
||||
ImageURL: img.ImageURL,
|
||||
})
|
||||
}
|
||||
|
||||
// 构建动态DTO
|
||||
result = append(result, user.Moment{
|
||||
ID: int64(m.ID),
|
||||
UserID: m.UserID,
|
||||
User: &userInfo,
|
||||
Content: m.Content,
|
||||
Visibility: user.MomentVisibility(m.Visibility),
|
||||
Location: m.Location,
|
||||
Status: user.ContentStatus(m.Status),
|
||||
LikeCount: int32(m.LikeCount),
|
||||
CommentCount: int32(m.CommentCount),
|
||||
Images: momentImages,
|
||||
CreatedAt: m.CreatedAt.Format(time.RFC3339),
|
||||
UpdatedAt: m.UpdatedAt.Format(time.RFC3339),
|
||||
})
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// 批量获取用户信息
|
||||
func batchGetUserInfo(userIDs []string) (map[string]model.User, error) {
|
||||
db := DB
|
||||
var users []model.User
|
||||
if err := db.Where("user_id IN (?)", userIDs).Find(&users).Error; err != nil {
|
||||
return nil, err
|
||||
// 转换map为切片
|
||||
friendUserIDs := make([]string, 0, len(friendMap))
|
||||
for id := range friendMap {
|
||||
friendUserIDs = append(friendUserIDs, id)
|
||||
}
|
||||
|
||||
userMap := make(map[string]model.User)
|
||||
for _, u := range users {
|
||||
userMap[u.UserID] = u
|
||||
}
|
||||
return userMap, nil
|
||||
return friendUserIDs, nil
|
||||
}
|
||||
|
||||
// 将用户模型转换为DTO
|
||||
@@ -162,3 +99,280 @@ func convertUserModelToDTO(u model.User) user.UserInfoReq {
|
||||
|
||||
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
|
||||
})
|
||||
}
|
||||
|
@@ -33,7 +33,7 @@ func Init() {
|
||||
panic(err)
|
||||
}
|
||||
// 自动迁移
|
||||
err = DB.AutoMigrate(model.User{}, model.Country{}, model.UserRelations{}, model.FriendRelationship{}, model.ChatGroupInfo{}, model.GroupUserRelation{})
|
||||
err = DB.AutoMigrate(model.User{}, model.Country{}, model.UserRelations{}, model.FriendRelationship{}, model.ChatGroupInfo{}, model.GroupUserRelation{}, model.Moment{}, model.MomentImage{}, model.MomentLike{}, model.MomentComment{})
|
||||
if err != nil {
|
||||
hlog.Error("AutoMigrate failed: " + err.Error())
|
||||
return
|
||||
|
@@ -45,9 +45,6 @@ func DeleteUser(userId string) error {
|
||||
return errTransaction
|
||||
}
|
||||
|
||||
func UpdateUser(user *user.User) error {
|
||||
return DB.Updates(user).Error
|
||||
}
|
||||
func UpdatesUser(user *user.UpdateUserRequest) error {
|
||||
db := DB.Model(&model.User{})
|
||||
maps := make(map[string]interface{})
|
||||
|
@@ -6,6 +6,7 @@ import (
|
||||
"acquaintances/biz/dal/mysql"
|
||||
"acquaintances/biz/model"
|
||||
"context"
|
||||
"github.com/cloudwego/hertz/pkg/common/hlog"
|
||||
|
||||
user "acquaintances/biz/model/user"
|
||||
"github.com/cloudwego/hertz/pkg/app"
|
||||
@@ -20,18 +21,18 @@ func CreateMoment(ctx context.Context, c *app.RequestContext) {
|
||||
|
||||
// 绑定并验证请求参数
|
||||
if err = c.BindAndValidate(&req); err != nil {
|
||||
c.String(consts.StatusBadRequest, "请求参数错误: %v", err)
|
||||
c.JSON(consts.StatusBadRequest, "请求参数错误")
|
||||
return
|
||||
}
|
||||
|
||||
hlog.Errorf("+++++++")
|
||||
// 验证用户是否存在(实际项目中应通过token获取用户ID并验证)
|
||||
exists, err := mysql.CheckUserExists(req.UserID)
|
||||
if err != nil {
|
||||
c.String(consts.StatusInternalServerError, "查询用户信息失败: %v", err)
|
||||
c.JSON(consts.StatusInternalServerError, "查询用户信息失败")
|
||||
return
|
||||
}
|
||||
if !exists {
|
||||
c.String(consts.StatusForbidden, "用户不存在")
|
||||
c.JSON(consts.StatusForbidden, "用户不存在")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -45,7 +46,7 @@ func CreateMoment(ctx context.Context, c *app.RequestContext) {
|
||||
}
|
||||
|
||||
// 保存动态到数据库
|
||||
if err = mysql.SaveMomentWithImages(&moment, req.ImageURLs); err != nil {
|
||||
if err = mysql.SaveMomentWithImages(&moment, req.ImageUrls); err != nil {
|
||||
c.JSON(consts.StatusInternalServerError, &user.CreateMomentResponse{Code: user.Code_DBErr, Msg: err.Error()})
|
||||
return
|
||||
}
|
||||
@@ -56,50 +57,46 @@ func CreateMoment(ctx context.Context, c *app.RequestContext) {
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
||||
|
||||
// ListMoments .
|
||||
// ListMoments 获取朋友圈动态
|
||||
// @router /v1/Moments/list/ [GET]
|
||||
func ListMoments(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req user.ListMomentsRequest
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
c.JSON(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
data, total, err := mysql.GetFriendsMoments(req)
|
||||
if err != nil {
|
||||
c.JSON(consts.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
resp := new(user.ListMomentsResponse)
|
||||
resp.Moments = data
|
||||
resp.Total = total
|
||||
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
||||
|
||||
// ListMomentsAppoint .
|
||||
// ListMomentsAppoint 获取指定用户朋友圈动态
|
||||
// @router /v1/Moments/user/list/ [GET]
|
||||
func ListMomentsAppoint(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req user.ListMomentsAppointRequest
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
c.JSON(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
resp := new(user.ListMomentsAppointResponse)
|
||||
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
||||
|
||||
// GetMoment .
|
||||
// @router /v1/Moments/info/ [GET]
|
||||
func GetMoment(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req user.GetMomentRequest
|
||||
err = c.BindAndValidate(&req)
|
||||
data, total, err := mysql.GetMomentsAppoint(req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
c.JSON(consts.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
resp := new(user.GetMomentResponse)
|
||||
resp := new(user.ListMomentsAppointResponse)
|
||||
resp.Moments = data
|
||||
resp.Total = total
|
||||
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
||||
@@ -111,10 +108,14 @@ func DeleteMoment(ctx context.Context, c *app.RequestContext) {
|
||||
var req user.DeleteMomentRequest
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
c.JSON(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
err = mysql.DeleteMoment(req)
|
||||
if err != nil {
|
||||
c.JSON(consts.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
resp := new(user.DeleteMomentResponse)
|
||||
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
@@ -127,10 +128,14 @@ func LikeMoment(ctx context.Context, c *app.RequestContext) {
|
||||
var req user.LikeMomentRequest
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
c.JSON(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
err = mysql.LikeMoment(req)
|
||||
if err != nil {
|
||||
c.JSON(consts.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
resp := new(user.LikeMomentResponse)
|
||||
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
@@ -143,10 +148,14 @@ func UnlikeMoment(ctx context.Context, c *app.RequestContext) {
|
||||
var req user.UnlikeMomentRequest
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
c.JSON(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
err = mysql.UnlikeMoment(req)
|
||||
if err != nil {
|
||||
c.JSON(consts.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
resp := new(user.UnlikeMomentResponse)
|
||||
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
@@ -159,7 +168,7 @@ func ListMomentLikes(ctx context.Context, c *app.RequestContext) {
|
||||
var req user.ListMomentLikesRequest
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
c.JSON(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -175,7 +184,7 @@ func CommentMoment(ctx context.Context, c *app.RequestContext) {
|
||||
var req user.CommentMomentRequest
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
c.JSON(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -191,7 +200,7 @@ func ListMomentComments(ctx context.Context, c *app.RequestContext) {
|
||||
var req user.ListMomentCommentsRequest
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
c.JSON(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -207,7 +216,7 @@ func DeleteComment(ctx context.Context, c *app.RequestContext) {
|
||||
var req user.DeleteCommentRequest
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
c.JSON(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@@ -20,35 +20,28 @@ type Moment struct {
|
||||
Status uint8 `gorm:"column:status;type:tinyint unsigned;default:1;comment:'状态;0:删除,1:正常'"`
|
||||
LikeCount uint32 `gorm:"column:like_count;type:int unsigned;default:0;comment:'点赞数'"`
|
||||
CommentCount uint32 `gorm:"column:comment_count;type:int unsigned;default:0;comment:'评论数'"`
|
||||
// 关联
|
||||
Images []MomentImage `gorm:"foreignKey:MomentID"`
|
||||
Likes []MomentLike `gorm:"foreignKey:MomentID"`
|
||||
Comments []MomentComment `gorm:"foreignKey:MomentID"`
|
||||
}
|
||||
|
||||
// 朋友圈图片表
|
||||
type MomentImage struct {
|
||||
gorm.Model
|
||||
MomentID uint `gorm:"column:moment_id;type:int unsigned;not null;index:idx_moment_id;comment:'朋友圈动态ID'"`
|
||||
ImageURL string `gorm:"column:image_url;type:varchar(255);not null;comment:'图片URL'"`
|
||||
SortOrder uint8 `gorm:"column:sort_order;type:tinyint unsigned;default:0;comment:'排序序号'"`
|
||||
MomentID uint `gorm:"column:moment_id;type:int unsigned;not null;comment:'朋友圈动态ID'"`
|
||||
ImageURL string `gorm:"column:image_url;type:varchar(255);not null;comment:'图片URL'"`
|
||||
}
|
||||
|
||||
// 朋友圈点赞表
|
||||
type MomentLike struct {
|
||||
gorm.Model
|
||||
MomentID uint `gorm:"column:moment_id;type:int unsigned;not null;index:idx_moment_id;comment:'朋友圈动态ID'"`
|
||||
MomentID uint `gorm:"column:moment_id;type:int unsigned;not null;comment:'朋友圈动态ID'"`
|
||||
UserID string `gorm:"column:user_id;type:varchar(32);not null;comment:'点赞用户ID'"`
|
||||
// 联合唯一索引,确保一个用户只能给一条动态点一次赞
|
||||
gorm.Index `gorm:"uniqueIndex:idx_moment_user,comment:'动态ID和用户ID的联合索引'"`
|
||||
}
|
||||
|
||||
// 朋友圈评论表
|
||||
type MomentComment struct {
|
||||
gorm.Model
|
||||
MomentID uint `gorm:"column:moment_id;type:int unsigned;not null;index:idx_moment_id;comment:'朋友圈动态ID'"`
|
||||
MomentID uint `gorm:"column:moment_id;type:int unsigned;not null;comment:'朋友圈动态ID'"`
|
||||
UserID string `gorm:"column:user_id;type:varchar(32);not null;comment:'评论用户ID'"`
|
||||
Content string `gorm:"column:content;type:text;not null;comment:'评论内容'"`
|
||||
ParentID *uint `gorm:"column:parent_id;type:int unsigned;index:idx_parent_id;comment:'父评论ID,用于回复功能'"`
|
||||
ParentID uint `gorm:"column:parent_id;type:int unsigned;index:idx_parent_id;comment:'父评论ID,用于回复功能'"`
|
||||
Status uint8 `gorm:"column:status;type:tinyint unsigned;default:1;comment:'状态;0:删除,1:正常'"`
|
||||
}
|
||||
|
@@ -5,9 +5,12 @@ import (
|
||||
"acquaintances/biz/utils"
|
||||
"encoding/json"
|
||||
"gorm.io/gorm"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var UserSync *sync.Mutex
|
||||
|
||||
type User struct {
|
||||
gorm.Model
|
||||
UserID string `gorm:"column:user_id;type:varchar(32);uniqueIndex:idx_user_id;not null;comment:'用户唯一标识'"`
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,6 @@ package user
|
||||
import (
|
||||
user "acquaintances/biz/handler/user"
|
||||
"github.com/cloudwego/hertz/pkg/app/server"
|
||||
"github.com/hertz-contrib/cors"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -20,20 +19,6 @@ func Register(r *server.Hertz) {
|
||||
root := r.Group("/", rootMw()...)
|
||||
{
|
||||
_v1 := root.Group("/v1", _v1Mw()...)
|
||||
_v1.Use(cors.New(cors.Config{
|
||||
// 允许的源( origins ),* 表示允许所有源(生产环境建议指定具体域名)
|
||||
AllowOrigins: []string{"*"},
|
||||
// 允许的请求方法
|
||||
AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"},
|
||||
// 允许的请求头
|
||||
AllowHeaders: []string{"Origin", "Content-Type", "Accept", "Authorization"},
|
||||
// 是否允许发送 Cookie
|
||||
AllowCredentials: true,
|
||||
// 预检请求的有效期(秒),在此期间不需要重复发送预检请求
|
||||
MaxAge: 12 * 3600,
|
||||
// 允许暴露的响应头(前端通过 XMLHttpRequest 可以访问的头信息)
|
||||
ExposeHeaders: []string{"Content-Length"},
|
||||
}))
|
||||
{
|
||||
_moments := _v1.Group("/Moments", _momentsMw()...)
|
||||
_moments.DELETE("/", append(_deletemomentMw(), user.DeleteMoment)...)
|
||||
@@ -51,10 +36,6 @@ func Register(r *server.Hertz) {
|
||||
_dislike := _moments.Group("/dislike", _dislikeMw()...)
|
||||
_dislike.POST("/", append(_unlikemomentMw(), user.UnlikeMoment)...)
|
||||
}
|
||||
{
|
||||
_info := _moments.Group("/info", _infoMw()...)
|
||||
_info.GET("/", append(_getmomentMw(), user.GetMoment)...)
|
||||
}
|
||||
{
|
||||
_like := _moments.Group("/like", _likeMw()...)
|
||||
_like.POST("/", append(_likemomentMw(), user.LikeMoment)...)
|
||||
|
@@ -11,8 +11,8 @@ WorkerIDBits = 3
|
||||
Db = mysql
|
||||
DbHost = 127.0.0.1
|
||||
DbPort = 3306
|
||||
DbUser = iuqtRoot
|
||||
DbPassWord = mN3x4diYX6NzmC5a
|
||||
DbUser = root
|
||||
DbPassWord = 123456
|
||||
DbName = iuqt_acquaintances
|
||||
|
||||
#ETCD参数
|
||||
|
@@ -378,56 +378,56 @@ enum ContentStatus {
|
||||
|
||||
// 朋友圈图片结构体
|
||||
struct MomentImage {
|
||||
1: i64 ID // ID
|
||||
2: i64 MomentID // 所属动态ID
|
||||
3: string ImageURL // 图片URL
|
||||
1: i64 id // ID
|
||||
2: i64 moment_id // 所属动态ID
|
||||
3: string image_url // 图片URL
|
||||
}
|
||||
|
||||
// 朋友圈点赞结构体
|
||||
struct MomentLike {
|
||||
1: i64 ID // 点赞ID
|
||||
2: i64 MomentID // 动态ID
|
||||
3: string UserID // 点赞用户ID
|
||||
4: string CreatedAt // 点赞时间
|
||||
1: i64 id // 点赞ID
|
||||
2: i64 moment_id // 动态ID
|
||||
3: string user_id // 点赞用户ID
|
||||
4: string created_at // 点赞时间
|
||||
}
|
||||
|
||||
// 朋友圈评论结构体
|
||||
struct MomentComment {
|
||||
1: i64 ID // 评论ID
|
||||
2: i64 MomentID // 动态ID
|
||||
3: string UserID // 评论用户ID
|
||||
4: UserInfoReq User // 评论用户信息
|
||||
5: string Content // 评论内容
|
||||
6: i64 ParentID // 父评论ID,用于回复
|
||||
7: MomentComment ParentComment // 父评论信息
|
||||
8: ContentStatus Status // 状态
|
||||
9: string CreatedAt // 创建时间
|
||||
10: string UpdatedAt // 更新时间
|
||||
1: i64 id // 评论ID
|
||||
2: i64 moment_id // 动态ID
|
||||
3: string user_id // 评论用户ID
|
||||
4: UserInfoReq user // 评论用户信息
|
||||
5: string content // 评论内容
|
||||
6: i64 parent_id // 父评论ID,用于回复
|
||||
7: MomentComment parent_comment // 父评论信息
|
||||
8: ContentStatus status // 状态
|
||||
9: string created_at // 创建时间
|
||||
10: string updated_at // 更新时间
|
||||
}
|
||||
|
||||
// 朋友圈动态结构体
|
||||
struct Moment {
|
||||
1: i64 ID // 动态ID
|
||||
2: string UserID // 发布者用户ID
|
||||
3: UserInfoReq User // 发布者信息
|
||||
4: string Content // 动态内容
|
||||
5: MomentVisibility Visibility // 可见性
|
||||
6: string Location // 发布地点
|
||||
7: ContentStatus Status // 状态
|
||||
8: i32 LikeCount // 点赞数
|
||||
9: i32 CommentCount // 评论数
|
||||
10: list<MomentImage> Images // 动态图片列表
|
||||
11: string CreatedAt // 创建时间
|
||||
12: string UpdatedAt // 更新时间
|
||||
1: i64 id // 动态ID
|
||||
2: string user_id // 发布者用户ID
|
||||
3: UserInfoReq user // 发布者信息
|
||||
4: string content // 动态内容
|
||||
5: MomentVisibility visibility // 可见性
|
||||
6: string location // 发布地点
|
||||
7: ContentStatus status // 状态
|
||||
8: i32 like_count // 点赞数
|
||||
9: i32 comment_count // 评论数
|
||||
10: list<MomentImage> images // 动态图片列表
|
||||
11: string created_at // 创建时间
|
||||
12: string updated_at // 更新时间
|
||||
}
|
||||
|
||||
// 发布动态请求
|
||||
struct CreateMomentRequest {
|
||||
1: string UserID // 发布者用户ID
|
||||
2: string Content // 动态内容
|
||||
3: MomentVisibility Visibility // 可见性,默认公开
|
||||
4: string Location // 发布地点
|
||||
5: list<string> ImageURLs // 图片URL列表
|
||||
1: string user_id // 发布者用户ID
|
||||
2: string content // 动态内容
|
||||
3: MomentVisibility visibility // 可见性,默认公开
|
||||
4: string location // 发布地点
|
||||
5: list<string> image_urls // 图片URL列表
|
||||
}
|
||||
|
||||
// 发布动态响应
|
||||
@@ -438,38 +438,22 @@ struct CreateMomentResponse {
|
||||
|
||||
// 获取动态列表请求
|
||||
struct ListMomentsRequest {
|
||||
1: string UserID // 当前用户ID
|
||||
2: i32 Page // 页码,默认1
|
||||
3: i32 PageSize // 每页数量,默认10
|
||||
1: string user_id // 当前用户ID
|
||||
2: i32 page // 页码,默认1
|
||||
3: i32 pageSize // 每页数量,默认10
|
||||
}
|
||||
|
||||
// 获取动态列表响应
|
||||
struct ListMomentsResponse {
|
||||
1: Code code
|
||||
2: list<Moment> Moments // 动态列表
|
||||
3: i32 Total // 总数量
|
||||
4: i32 Page // 当前页码
|
||||
5: i32 PageSize // 每页数量
|
||||
6: string Message // 提示信息
|
||||
}
|
||||
|
||||
// 获取单条动态请求
|
||||
struct GetMomentRequest {
|
||||
1: string UserID // 当前用户ID
|
||||
2: i64 MomentID // 动态ID
|
||||
}
|
||||
|
||||
// 获取单条动态响应
|
||||
struct GetMomentResponse {
|
||||
1: Code code // 是否成功
|
||||
2: Moment Moment // 动态详情
|
||||
3: string msg // 提示信息
|
||||
2: list<Moment> moments // 动态列表
|
||||
3: i32 total // 总数量
|
||||
}
|
||||
|
||||
// 删除动态请求
|
||||
struct DeleteMomentRequest {
|
||||
1: string UserID // 当前用户ID
|
||||
2: i64 MomentID // 动态ID
|
||||
1: string user_id // 当前用户ID
|
||||
2: i64 moment_id // 动态ID
|
||||
}
|
||||
|
||||
// 删除动态响应
|
||||
@@ -480,8 +464,8 @@ struct DeleteMomentResponse {
|
||||
|
||||
// 点赞动态请求
|
||||
struct LikeMomentRequest {
|
||||
1: string UserID // 当前用户ID
|
||||
2: i64 MomentID // 动态ID
|
||||
1: string user_id // 当前用户ID
|
||||
2: i64 moment_id // 动态ID
|
||||
}
|
||||
|
||||
// 点赞动态响应
|
||||
@@ -492,8 +476,8 @@ struct LikeMomentResponse {
|
||||
|
||||
// 取消点赞请求
|
||||
struct UnlikeMomentRequest {
|
||||
1: string UserID // 当前用户ID
|
||||
2: i64 MomentID // 动态ID
|
||||
1: string user_id // 当前用户ID
|
||||
2: i64 moment_id // 动态ID
|
||||
}
|
||||
|
||||
// 取消点赞响应
|
||||
@@ -504,25 +488,25 @@ struct UnlikeMomentResponse {
|
||||
|
||||
// 获取动态点赞列表请求
|
||||
struct ListMomentLikesRequest {
|
||||
1: i64 MomentID // 动态ID
|
||||
2: i32 Page // 页码,默认1
|
||||
3: i32 PageSize // 每页数量,默认20
|
||||
1: i64 moment_id // 动态ID
|
||||
2: i32 page // 页码,默认1
|
||||
3: i32 page_size // 每页数量,默认20
|
||||
}
|
||||
|
||||
// 获取动态点赞列表响应
|
||||
struct ListMomentLikesResponse {
|
||||
1: Code code
|
||||
2: list<MomentLike> Likes // 点赞列表
|
||||
3: i32 Total // 总数量
|
||||
4: string Message // 提示信息
|
||||
2: list<MomentLike> likes // 点赞列表
|
||||
3: i32 total // 总数量
|
||||
4: string message // 提示信息
|
||||
}
|
||||
|
||||
// 评论动态请求
|
||||
struct CommentMomentRequest {
|
||||
1: string UserID // 当前用户ID
|
||||
2: i64 MomentID // 动态ID
|
||||
3: string Content // 评论内容
|
||||
4: i64 ParentID // 父评论ID,用于回复
|
||||
1: string user_id // 当前用户ID
|
||||
2: i64 moment_id // 动态ID
|
||||
3: string content // 评论内容
|
||||
4: i64 parent_id // 父评论ID,用于回复
|
||||
}
|
||||
|
||||
// 评论动态响应
|
||||
@@ -533,24 +517,24 @@ struct CommentMomentResponse {
|
||||
|
||||
// 获取动态评论列表请求
|
||||
struct ListMomentCommentsRequest {
|
||||
1: i64 MomentID // 动态ID
|
||||
2: i64 ParentID // 父评论ID,用于获取回复
|
||||
3: i32 Page // 页码,默认1
|
||||
4: i32 PageSize // 每页数量,默认20
|
||||
1: i64 moment_id // 动态ID
|
||||
2: i64 parent_id // 父评论ID,用于获取回复
|
||||
3: i32 page // 页码,默认1
|
||||
4: i32 page_size // 每页数量,默认20
|
||||
}
|
||||
|
||||
// 获取动态评论列表响应
|
||||
struct ListMomentCommentsResponse {
|
||||
1: Code code
|
||||
2: list<MomentComment> Comments // 评论列表
|
||||
3: i32 Total // 总数量
|
||||
2: list<MomentComment> comments // 评论列表
|
||||
3: i32 total // 总数量
|
||||
4: string msg // 提示信息
|
||||
}
|
||||
|
||||
// 删除评论请求
|
||||
struct DeleteCommentRequest {
|
||||
1: string UserID // 当前用户ID
|
||||
2: i64 CommentID // 评论ID
|
||||
1: string user_id // 当前用户ID
|
||||
2: i64 comment_id // 评论ID
|
||||
}
|
||||
|
||||
// 删除评论响应
|
||||
@@ -560,19 +544,16 @@ struct DeleteCommentResponse {
|
||||
}
|
||||
|
||||
struct ListMomentsAppointRequest {
|
||||
1: string UserID // 当前用户ID
|
||||
2: i32 Page // 页码,默认1
|
||||
3: i32 PageSize // 每页数量,默认10
|
||||
1: string user_id // 当前用户ID
|
||||
2: i32 page // 页码,默认1
|
||||
3: i32 page_size // 每页数量,默认10
|
||||
}
|
||||
|
||||
// 获取动态列表响应
|
||||
struct ListMomentsAppointResponse {
|
||||
1: Code code
|
||||
2: list<Moment> Moments // 动态列表
|
||||
3: i32 Total // 总数量
|
||||
4: i32 Page // 当前页码
|
||||
5: i32 PageSize // 每页数量
|
||||
6: string Message // 提示信息
|
||||
2: list<Moment> moments // 动态列表
|
||||
3: i32 total // 总数量
|
||||
}
|
||||
|
||||
// 朋友圈服务接口
|
||||
@@ -586,9 +567,6 @@ service MomentsService {
|
||||
//获取指定用户动态列表
|
||||
ListMomentsAppointResponse ListMomentsAppoint(1: ListMomentsAppointRequest req)(api.get="/v1/Moments/user/list/")
|
||||
|
||||
// 获取单条动态详情
|
||||
GetMomentResponse GetMoment(1: GetMomentRequest req)(api.get="/v1/Moments/info/")
|
||||
|
||||
// 删除动态
|
||||
DeleteMomentResponse DeleteMoment(1: DeleteMomentRequest req)(api.delete="/v1/Moments/")
|
||||
|
||||
|
Reference in New Issue
Block a user