Files
IUQT/acquaintances/biz/dal/mysql/friend_relationship.go
2025-07-28 18:46:14 +08:00

145 lines
4.4 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"
"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
}