145 lines
4.4 KiB
Go
145 lines
4.4 KiB
Go
package mysql
|
||
|
||
import (
|
||
"acquaintances/biz/model"
|
||
"acquaintances/biz/model/user"
|
||
"errors"
|
||
"fmt"
|
||
"github.com/cloudwego/hertz/pkg/common/hlog"
|
||
"gorm.io/gorm"
|
||
"gorm.io/gorm/clause"
|
||
)
|
||
|
||
func CreateFriendApplication(applicantID, targetUserID, message string) error {
|
||
// 检查是否为同一用户
|
||
if applicantID == targetUserID {
|
||
return errors.New("不能添加自己为好友")
|
||
}
|
||
|
||
// 检查目标用户是否存在(假设存在用户表查询函数)
|
||
exists, err := CheckUserExists(targetUserID)
|
||
if err != nil {
|
||
return fmt.Errorf("检查目标用户失败: %w", err)
|
||
}
|
||
if !exists {
|
||
return errors.New("目标用户不存在")
|
||
}
|
||
|
||
// 使用事务保证原子性
|
||
return DB.Transaction(func(tx *gorm.DB) error {
|
||
// 悲观锁查询,防止并发问题
|
||
var existing model.FriendRelationship
|
||
err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).
|
||
Where("applicant_id = ? AND target_user_id = ? AND status = ?",
|
||
applicantID, targetUserID, model.ApplicationPending).
|
||
First(&existing).Error
|
||
|
||
// 存在未处理申请
|
||
if err == nil {
|
||
return errors.New("已向该用户发起好友申请,待对方处理")
|
||
}
|
||
// 非"记录不存在"的其他错误
|
||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||
return fmt.Errorf("查询申请记录失败: %w", err)
|
||
}
|
||
|
||
// 检查是否有反向的待处理申请(B向A申请时,A已向B申请)
|
||
var reverseExisting model.FriendRelationship
|
||
err = tx.Where("applicant_id = ? AND target_user_id = ? AND status = ?",
|
||
targetUserID, applicantID, model.ApplicationPending).
|
||
First(&reverseExisting).Error
|
||
if err == nil {
|
||
return errors.New("对方已向你发起好友申请,请先处理")
|
||
}
|
||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||
return fmt.Errorf("查询反向申请记录失败: %w", err)
|
||
}
|
||
|
||
// 创建新申请
|
||
application := &model.FriendRelationship{
|
||
ApplicantID: applicantID,
|
||
TargetUserID: targetUserID,
|
||
ApplicationMessage: message,
|
||
Status: model.ApplicationPending,
|
||
}
|
||
if err := tx.Create(application).Error; err != nil {
|
||
return fmt.Errorf("创建申请失败: %w", err)
|
||
}
|
||
return nil
|
||
})
|
||
}
|
||
|
||
// HandleFriendApplication 处理好友申请(接受/拒绝)
|
||
func HandleFriendApplication(applicationID int64, status model.FriendApplicationStatus) error {
|
||
tx := DB
|
||
if !status.IsValid() {
|
||
return gorm.ErrInvalidData
|
||
}
|
||
|
||
var application model.FriendRelationship
|
||
if err := tx.Where("id = ? AND status = ?", applicationID, model.ApplicationPending).
|
||
First(&application).Error; err != nil {
|
||
return err
|
||
}
|
||
|
||
application.Status = status
|
||
|
||
if err := tx.Save(&application).Error; err != nil {
|
||
return err
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// GetApplications 获取收到的好友申请/获取发出的好友申请
|
||
func GetApplications(req user.ListFriendRelationshipReq, status ...model.FriendApplicationStatus) ([]*user.FriendRelationshipListInfo, error) {
|
||
tx := DB
|
||
|
||
var applications []*model.FriendRelationship
|
||
query := tx.Where("target_user_id = ? or applicant_id = ?", req.UserID, req.UserID)
|
||
|
||
if len(status) > 0 {
|
||
query = query.Where("status IN (?)", status)
|
||
}
|
||
|
||
if err := query.Order("created_at DESC").Find(&applications).Error; err != nil {
|
||
return nil, err
|
||
}
|
||
var result []*user.FriendRelationshipListInfo
|
||
for _, v := range applications {
|
||
info := &user.FriendRelationshipListInfo{
|
||
ID: int64(v.ID),
|
||
ApplicationMessage: v.ApplicationMessage,
|
||
Status: int8(v.Status),
|
||
}
|
||
|
||
// 发出的申请:获取目标用户信息(TargetUserID)
|
||
if v.ApplicantID == req.UserID {
|
||
info.UserID = v.TargetUserID
|
||
userInfo, err := InfoUser(v.TargetUserID) // 假设改为获取单个用户的函数
|
||
if err != nil {
|
||
hlog.Errorf("获取目标用户 %s 信息失败: %v", v.TargetUserID, err)
|
||
// 可设置默认值(如"未知用户"),避免漏显示
|
||
info.UserName = "未知用户"
|
||
} else {
|
||
info.UserName = userInfo.UserName
|
||
info.AvatarImageURL = userInfo.AvatarImageURL
|
||
}
|
||
} else if v.TargetUserID == req.UserID { // 收到的申请:获取申请人信息(ApplicantID)
|
||
info.UserID = v.ApplicantID
|
||
userInfo, err := InfoUser(v.ApplicantID)
|
||
if err != nil {
|
||
hlog.Errorf("获取申请人 %s 信息失败: %v", v.ApplicantID, err)
|
||
info.UserName = "未知用户"
|
||
} else {
|
||
info.UserName = userInfo.UserName
|
||
info.AvatarImageURL = userInfo.AvatarImageURL
|
||
}
|
||
}
|
||
|
||
result = append(result, info)
|
||
}
|
||
|
||
return result, nil
|
||
}
|