聊天模块修改&聊天群组模块&用户好友关模块系完善
This commit is contained in:
415
acquaintances/biz/dal/mysql/chat_group.go
Normal file
415
acquaintances/biz/dal/mysql/chat_group.go
Normal file
@@ -0,0 +1,415 @@
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"acquaintances/biz/model"
|
||||
"acquaintances/biz/model/user"
|
||||
"errors"
|
||||
"github.com/cloudwego/hertz/pkg/common/hlog"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 创建群
|
||||
func CreateChatGroupInfo(userId string, data *user.ChatGroupInfo) error {
|
||||
// 参数校验
|
||||
if userId == "" {
|
||||
return errors.New("用户ID不能为空")
|
||||
}
|
||||
if data == nil {
|
||||
return errors.New("群组信息不能为空")
|
||||
}
|
||||
if data.ChatGroupID == "" {
|
||||
return errors.New("群组ID不能为空")
|
||||
}
|
||||
if data.ChatGroupName == "" {
|
||||
return errors.New("群组名称不能为空")
|
||||
}
|
||||
|
||||
// 执行事务操作
|
||||
errTransaction := DB.Transaction(func(tx *gorm.DB) error {
|
||||
// 创建群基本信息
|
||||
if err := tx.Model(&model.ChatGroupInfo{}).Create(data).Error; err != nil {
|
||||
hlog.Error("创建群基本信息失败", err, "group_id", data.ChatGroupID, "user_id", userId)
|
||||
return errors.New("创建群信息失败")
|
||||
}
|
||||
hlog.Info("群基本信息创建成功", "group_id", data.ChatGroupID)
|
||||
|
||||
// 添加创始人到群,设置为群主
|
||||
creater := model.GroupUserRelation{
|
||||
ChatGroupID: data.ChatGroupID,
|
||||
UserID: userId,
|
||||
Role: model.GroupLeader,
|
||||
}
|
||||
|
||||
if err := tx.Model(&model.GroupUserRelation{}).Create(&creater).Error; err != nil {
|
||||
hlog.Error("添加群主到群失败", err, "group_id", data.ChatGroupID, "user_id", userId)
|
||||
return errors.New("添加群主失败")
|
||||
}
|
||||
hlog.Info("群主添加到群成功", "group_id", data.ChatGroupID, "user_id", userId)
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if errTransaction != nil {
|
||||
hlog.Error("创建群事务执行失败", errTransaction, "group_id", data.ChatGroupID, "user_id", userId)
|
||||
return errTransaction
|
||||
}
|
||||
|
||||
hlog.Info("群创建成功", "group_id", data.ChatGroupID, "creator", userId)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 解散群
|
||||
func DeleteChatGroupInfo(chatGroupId, userId string) error {
|
||||
// 参数校验
|
||||
if chatGroupId == "" || userId == "" {
|
||||
return errors.New("群组ID和用户ID不能为空")
|
||||
}
|
||||
|
||||
// 检查用户是否为群主(只有群主可以解散群)
|
||||
var role model.ChatGroupRole
|
||||
err := DB.Model(&model.GroupUserRelation{}).
|
||||
Where("chat_group_id = ? AND user_id = ?", chatGroupId, userId).
|
||||
Pluck("role", &role).Error
|
||||
|
||||
if err != nil {
|
||||
hlog.Error("查询用户群角色失败", err, "user_id", userId, "group_id", chatGroupId)
|
||||
return errors.New("查询用户权限失败")
|
||||
}
|
||||
|
||||
if role != model.GroupLeader {
|
||||
hlog.Warn("非群主尝试解散群", "user_id", userId, "group_id", chatGroupId, "role", role)
|
||||
return errors.New("只有群主可以解散群")
|
||||
}
|
||||
|
||||
// 执行事务操作
|
||||
errTransaction := DB.Transaction(func(tx *gorm.DB) error {
|
||||
// 解除群与用户关系
|
||||
relationResult := tx.Where("chat_group_id = ?", chatGroupId).Delete(&model.GroupUserRelation{})
|
||||
if relationResult.Error != nil {
|
||||
hlog.Error("解除群与用户关系失败", relationResult.Error, "group_id", chatGroupId)
|
||||
return errors.New("解除群成员关系失败")
|
||||
}
|
||||
hlog.Info("解除群与用户关系成功", "group_id", chatGroupId, "affected_users", relationResult.RowsAffected)
|
||||
|
||||
// 删除群基本信息
|
||||
groupResult := tx.Where("chat_group_id = ?", chatGroupId).Delete(&model.ChatGroupInfo{})
|
||||
if groupResult.Error != nil {
|
||||
hlog.Error("删除群基本信息失败", groupResult.Error, "group_id", chatGroupId)
|
||||
return errors.New("删除群信息失败")
|
||||
}
|
||||
|
||||
if groupResult.RowsAffected == 0 {
|
||||
hlog.Warn("未找到要删除的群信息", "group_id", chatGroupId)
|
||||
return errors.New("未找到对应的群")
|
||||
}
|
||||
|
||||
hlog.Info("群信息删除成功", "group_id", chatGroupId)
|
||||
return nil
|
||||
})
|
||||
|
||||
if errTransaction != nil {
|
||||
hlog.Error("解散群事务执行失败", errTransaction, "group_id", chatGroupId, "user_id", userId)
|
||||
return errTransaction
|
||||
}
|
||||
|
||||
hlog.Info("群解散成功", "group_id", chatGroupId, "operator", userId)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 修改群信息
|
||||
func UpdatesChatGroupInfo(cg *user.UpdateChatGroupReq) error {
|
||||
// 参数基本校验
|
||||
if cg == nil {
|
||||
return errors.New("请求参数不能为空")
|
||||
}
|
||||
if cg.UserID == "" || cg.ChatGroupID == "" {
|
||||
return errors.New("用户ID和群组ID不能为空")
|
||||
}
|
||||
|
||||
// 检查用户是否有修改权限(群主或管理员)
|
||||
var hasPermission bool
|
||||
err := DB.Model(&model.GroupUserRelation{}).
|
||||
Where("user_id = ? AND chat_group_id = ? AND role IN (?, ?)",
|
||||
cg.UserID, cg.ChatGroupID, model.GroupLeader, model.Administrators).
|
||||
Select("COUNT(*) > 0").
|
||||
Scan(&hasPermission).Error
|
||||
|
||||
if err != nil {
|
||||
hlog.Error("查询用户群权限失败", err, "user_id", cg.UserID, "group_id", cg.ChatGroupID)
|
||||
return errors.New("查询权限失败")
|
||||
}
|
||||
if !hasPermission {
|
||||
return errors.New("没有权限修改群信息")
|
||||
}
|
||||
|
||||
// 构建更新字段映射
|
||||
updateFields := make(map[string]interface{})
|
||||
if cg.NewChatGroupName != "" {
|
||||
updateFields["chat_group_name"] = cg.NewChatGroupName
|
||||
}
|
||||
if cg.ChatGroupNameImageURL != "" {
|
||||
updateFields["chat_group_image_url"] = cg.ChatGroupNameImageURL
|
||||
}
|
||||
if cg.ChatGroupNotice != "" {
|
||||
updateFields["chat_group_notice"] = cg.ChatGroupNotice
|
||||
}
|
||||
|
||||
// 没有需要更新的字段
|
||||
if len(updateFields) == 0 {
|
||||
return errors.New("没有需要更新的群信息")
|
||||
}
|
||||
|
||||
hlog.Info("准备更新群信息", "group_id", cg.ChatGroupID, "fields", updateFields)
|
||||
|
||||
// 执行更新操作
|
||||
result := DB.Model(&model.ChatGroupInfo{}).
|
||||
Where("chat_group_id = ?", cg.ChatGroupID).
|
||||
Updates(updateFields)
|
||||
|
||||
if result.Error != nil {
|
||||
hlog.Error("更新群信息失败", result.Error, "group_id", cg.ChatGroupID)
|
||||
return errors.New("更新群信息失败")
|
||||
}
|
||||
|
||||
if result.RowsAffected == 0 {
|
||||
hlog.Warn("未找到对应群组或没有修改任何信息", "group_id", cg.ChatGroupID)
|
||||
return errors.New("未找到对应群组")
|
||||
}
|
||||
|
||||
hlog.Info("群信息更新成功", "group_id", cg.ChatGroupID, "rows_affected", result.RowsAffected)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 加入群
|
||||
func JoinChatGroup(joinData *user.JoinChatGroupReq) error {
|
||||
// 参数校验
|
||||
if joinData == nil {
|
||||
return errors.New("请求参数不能为空")
|
||||
}
|
||||
if joinData.UserID == "" || joinData.ChatGroupID == "" {
|
||||
return errors.New("用户ID和群组ID不能为空")
|
||||
}
|
||||
|
||||
// 检查群组是否存在
|
||||
var groupExists bool
|
||||
err := DB.Model(&model.ChatGroupInfo{}).
|
||||
Where("chat_group_id = ?", joinData.ChatGroupID).
|
||||
Select("COUNT(*) > 0").
|
||||
Scan(&groupExists).Error
|
||||
|
||||
if err != nil {
|
||||
hlog.Error("查询群组存在性失败", err, "group_id", joinData.ChatGroupID)
|
||||
return errors.New("查询群组信息失败")
|
||||
}
|
||||
if !groupExists {
|
||||
return errors.New("群组不存在")
|
||||
}
|
||||
|
||||
// 检查用户是否已在群中
|
||||
var userInGroup bool
|
||||
err = DB.Model(&model.GroupUserRelation{}).
|
||||
Where("chat_group_id = ? AND user_id = ?", joinData.ChatGroupID, joinData.UserID).
|
||||
Select("COUNT(*) > 0").
|
||||
Scan(&userInGroup).Error
|
||||
|
||||
if err != nil {
|
||||
hlog.Error("查询用户是否在群中失败", err, "group_id", joinData.ChatGroupID, "user_id", joinData.UserID)
|
||||
return errors.New("查询用户群成员关系失败")
|
||||
}
|
||||
if userInGroup {
|
||||
return errors.New("用户已在群中")
|
||||
}
|
||||
|
||||
// 准备加入群的数据
|
||||
joinUser := &model.GroupUserRelation{
|
||||
UserID: joinData.UserID,
|
||||
ChatGroupID: joinData.ChatGroupID,
|
||||
Role: model.General,
|
||||
}
|
||||
|
||||
hlog.Info("准备添加群成员", "group_id", joinData.ChatGroupID, "user_id", joinData.UserID)
|
||||
|
||||
// 执行添加操作
|
||||
err = DB.Model(&model.GroupUserRelation{}).Create(joinUser).Error
|
||||
if err != nil {
|
||||
hlog.Error("添加群成员失败", err, "group_id", joinData.ChatGroupID, "user_id", joinData.UserID)
|
||||
return errors.New("加入群失败")
|
||||
}
|
||||
|
||||
hlog.Info("用户成功加入群", "group_id", joinData.ChatGroupID, "user_id", joinData.UserID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 退出群
|
||||
func ExitChatGroup(leaveData *user.ExitChatGroupReq) error {
|
||||
// 参数校验
|
||||
if leaveData == nil {
|
||||
return errors.New("请求参数不能为空")
|
||||
}
|
||||
if leaveData.UserID == "" || leaveData.ChatGroupID == "" {
|
||||
return errors.New("用户ID和群组ID不能为空")
|
||||
}
|
||||
|
||||
// 检查用户是否在群中
|
||||
var userRelation model.GroupUserRelation
|
||||
err := DB.Model(&model.GroupUserRelation{}).
|
||||
Where("chat_group_id = ? AND user_id = ?", leaveData.ChatGroupID, leaveData.UserID).
|
||||
First(&userRelation).Error
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return errors.New("用户不在该群中")
|
||||
}
|
||||
hlog.Error("查询用户群关系失败", err, "group_id", leaveData.ChatGroupID, "user_id", leaveData.UserID)
|
||||
return errors.New("查询用户群成员关系失败")
|
||||
}
|
||||
|
||||
// 检查是否为群主
|
||||
if userRelation.Role == model.GroupLeader {
|
||||
// 统计群成员数量
|
||||
var memberCount int64
|
||||
if err := DB.Model(&model.GroupUserRelation{}).
|
||||
Where("chat_group_id = ?", leaveData.ChatGroupID).
|
||||
Count(&memberCount).Error; err != nil {
|
||||
hlog.Error("查询群成员数量失败", err, "group_id", leaveData.ChatGroupID)
|
||||
return errors.New("查询群成员数量失败")
|
||||
}
|
||||
|
||||
// 群主不能退出群,只能解散群(如果是最后一个成员则允许退出并解散)
|
||||
if memberCount > 1 {
|
||||
return errors.New("群主不能退出群,请先解散群或转让群主身份")
|
||||
}
|
||||
}
|
||||
|
||||
// 执行退出操作
|
||||
result := DB.Model(&model.GroupUserRelation{}).
|
||||
Where("chat_group_id = ? AND user_id = ?", leaveData.ChatGroupID, leaveData.UserID).
|
||||
Delete(&model.GroupUserRelation{})
|
||||
|
||||
if result.Error != nil {
|
||||
hlog.Error("退出群失败", result.Error, "group_id", leaveData.ChatGroupID, "user_id", leaveData.UserID)
|
||||
return errors.New("退出群失败")
|
||||
}
|
||||
|
||||
// 如果是群主且是最后一个成员,同时删除群
|
||||
if userRelation.Role == model.GroupLeader {
|
||||
var remainingCount int64
|
||||
if err := DB.Model(&model.GroupUserRelation{}).
|
||||
Where("chat_group_id = ?", leaveData.ChatGroupID).
|
||||
Count(&remainingCount).Error; err != nil {
|
||||
hlog.Error("查询剩余群成员失败", err, "group_id", leaveData.ChatGroupID)
|
||||
return errors.New("查询剩余群成员失败")
|
||||
}
|
||||
|
||||
if remainingCount == 0 {
|
||||
// 最后一个成员(群主)退出,删除群
|
||||
if err := DB.Where("chat_group_id = ?", leaveData.ChatGroupID).
|
||||
Delete(&model.ChatGroupInfo{}).Error; err != nil {
|
||||
hlog.Error("删除空群失败", err, "group_id", leaveData.ChatGroupID)
|
||||
// 这里不返回错误,因为用户已经成功退出
|
||||
hlog.Warn("用户已退出,但删除空群失败", "group_id", leaveData.ChatGroupID)
|
||||
} else {
|
||||
hlog.Info("群已解散(最后一个成员退出)", "group_id", leaveData.ChatGroupID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hlog.Info("用户成功退出群", "group_id", leaveData.ChatGroupID, "user_id", leaveData.UserID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 获取群成员列表
|
||||
func GetUserListByChatGroup(req *user.ListUserChatGroupReq) ([]*user.UserInfoReq, error) {
|
||||
// 参数校验
|
||||
if req == nil {
|
||||
return nil, errors.New("请求参数不能为空")
|
||||
}
|
||||
if req.ChatGroupID == "" {
|
||||
return nil, errors.New("群组ID不能为空")
|
||||
}
|
||||
|
||||
// 检查群组是否存在
|
||||
var groupCount int64
|
||||
if err := DB.Model(&model.ChatGroupInfo{}).
|
||||
Where("chat_group_id = ?", req.ChatGroupID).
|
||||
Count(&groupCount).Error; err != nil {
|
||||
hlog.Error("查询群组存在性失败", err, "chat_group_id", req.ChatGroupID)
|
||||
return nil, errors.New("查询群组信息失败")
|
||||
}
|
||||
if groupCount == 0 {
|
||||
return nil, errors.New("指定的群组不存在")
|
||||
}
|
||||
|
||||
// 查询群内所有成员关系
|
||||
var relations []model.GroupUserRelation
|
||||
if err := DB.Model(&model.GroupUserRelation{}).
|
||||
Where("chat_group_id = ?", req.ChatGroupID).
|
||||
Find(&relations).Error; err != nil {
|
||||
hlog.Error("查询群成员关系失败", err, "chat_group_id", req.ChatGroupID)
|
||||
return nil, errors.New("获取群成员关系失败")
|
||||
}
|
||||
|
||||
// 处理没有成员的情况
|
||||
if len(relations) == 0 {
|
||||
return []*user.UserInfoReq{}, nil // 返回空列表而非错误
|
||||
}
|
||||
|
||||
// 提取成员ID列表
|
||||
var userIDs []string
|
||||
for _, relation := range relations {
|
||||
userIDs = append(userIDs, relation.UserID)
|
||||
}
|
||||
|
||||
// 批量获取用户信息
|
||||
users, err := GetUsersById(userIDs)
|
||||
if err != nil {
|
||||
hlog.Error("批量获取用户信息失败", err, "user_ids_count", len(userIDs))
|
||||
return nil, errors.New("获取用户信息失败")
|
||||
}
|
||||
|
||||
hlog.Info("成功获取群成员列表", "chat_group_id", req.ChatGroupID, "member_count", len(users))
|
||||
return users, nil
|
||||
}
|
||||
|
||||
// 获取用户群列表
|
||||
func GetChatGroupListByUser(req *user.ListChatGroupByUserReq) ([]*user.ChatGroupInfo, error) {
|
||||
// 参数校验
|
||||
if req == nil {
|
||||
return nil, errors.New("请求参数不能为空")
|
||||
}
|
||||
if req.UserID == "" {
|
||||
return nil, errors.New("用户ID不能为空")
|
||||
}
|
||||
|
||||
// 查询用户加入的所有群的关系记录
|
||||
var relations []model.GroupUserRelation
|
||||
if err := DB.Model(&model.GroupUserRelation{}).
|
||||
Where("user_id = ?", req.UserID).
|
||||
Find(&relations).Error; err != nil {
|
||||
hlog.Error("查询用户群关系失败", err, "user_id", req.UserID)
|
||||
return nil, errors.New("获取用户群关系失败")
|
||||
}
|
||||
|
||||
// 处理用户未加入任何群的情况
|
||||
if len(relations) == 0 {
|
||||
return []*user.ChatGroupInfo{}, nil // 返回空列表而非错误
|
||||
}
|
||||
|
||||
// 提取所有群组ID
|
||||
var groupIDs []string
|
||||
for _, relation := range relations {
|
||||
groupIDs = append(groupIDs, relation.ChatGroupID)
|
||||
}
|
||||
|
||||
// 查询这些群组的详细信息
|
||||
var groupInfos []*user.ChatGroupInfo
|
||||
if err := DB.Model(&model.ChatGroupInfo{}).
|
||||
Where("chat_group_id IN (?)", groupIDs).
|
||||
Find(&groupInfos).Error; err != nil {
|
||||
hlog.Error("查询群组信息失败", err, "group_ids_count", len(groupIDs))
|
||||
return nil, errors.New("获取群组信息失败")
|
||||
}
|
||||
|
||||
hlog.Info("成功获取用户群列表", "user_id", req.UserID, "group_count", len(groupInfos))
|
||||
return groupInfos, nil
|
||||
}
|
77
acquaintances/biz/dal/mysql/friend_relationship.go
Normal file
77
acquaintances/biz/dal/mysql/friend_relationship.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"acquaintances/biz/model"
|
||||
"acquaintances/biz/model/user"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// CreateFriendApplication 发起好友申请
|
||||
func CreateFriendApplication(applicantID, targetUserID, message string) error {
|
||||
tx := DB
|
||||
// 检查是否已存在未处理的申请
|
||||
var existing int64
|
||||
if err := tx.Model(&model.FriendRelationship{}).
|
||||
Where("applicant_id = ? AND target_user_id = ? AND status = ?",
|
||||
applicantID, targetUserID, model.ApplicationPending).
|
||||
Count(&existing).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if existing > 0 {
|
||||
return gorm.ErrDuplicatedKey // 已存在未处理的申请
|
||||
}
|
||||
|
||||
application := &model.FriendRelationship{
|
||||
ApplicantID: applicantID,
|
||||
TargetUserID: targetUserID,
|
||||
ApplicationMessage: message,
|
||||
Status: model.ApplicationPending,
|
||||
}
|
||||
|
||||
if err := tx.Create(application).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// HandleFriendApplication 处理好友申请(接受/拒绝)
|
||||
func HandleFriendApplication(applicationID uint64, 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.FriendRelationshipInfo, error) {
|
||||
tx := DB
|
||||
|
||||
var applications []*user.FriendRelationshipInfo
|
||||
query := tx.Where("target_user_id = ? and 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
|
||||
}
|
||||
|
||||
return applications, nil
|
||||
}
|
@@ -4,17 +4,26 @@ import (
|
||||
"acquaintances/biz/model"
|
||||
"acquaintances/biz/model/user"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/cloudwego/hertz/pkg/common/hlog"
|
||||
)
|
||||
|
||||
// 发起好申请
|
||||
func CreateUserRelations(relations user.CreateUserRelationsReq) error {
|
||||
// 参数校验
|
||||
if relations.UserID == "" || relations.FriendID == "" {
|
||||
return errors.New("用户ID和好友ID不能为空")
|
||||
}
|
||||
if relations.UserID == relations.FriendID {
|
||||
return errors.New("不能添加自己为好友")
|
||||
}
|
||||
db := DB.Model(&model.UserRelations{})
|
||||
var data model.UserRelations
|
||||
friends, err := getFriend(relations.UserID)
|
||||
if err != nil {
|
||||
hlog.Error("DeleteUserRelations:", err)
|
||||
hlog.Error("CreateUserRelations:", err)
|
||||
return err
|
||||
}
|
||||
// 检查是否已存在
|
||||
@@ -32,14 +41,19 @@ func CreateUserRelations(relations user.CreateUserRelationsReq) error {
|
||||
friends = append(friends, newFriend)
|
||||
data.FriendList, err = json.Marshal(friends)
|
||||
if err != nil {
|
||||
hlog.Error("DeleteUserRelations:", err)
|
||||
hlog.Error("CreateUserRelations:", err)
|
||||
return err
|
||||
}
|
||||
data.FriendCount = int64(len(friends))
|
||||
return db.Create(data).Error
|
||||
}
|
||||
|
||||
// 删除好友
|
||||
func DeleteUserRelations(relations user.DeleteUserRelationsReq) error {
|
||||
// 参数校验
|
||||
if relations.UserID == "" || relations.FriendID == "" {
|
||||
return errors.New("用户ID和好友ID不能为空")
|
||||
}
|
||||
db := DB.Model(&model.UserRelations{})
|
||||
friends, err := getFriend(relations.UserID)
|
||||
if err != nil {
|
||||
@@ -63,7 +77,15 @@ func DeleteUserRelations(relations user.DeleteUserRelationsReq) error {
|
||||
return db.Where("user_id = ?", relations.UserID).Updates(maps).Error
|
||||
}
|
||||
|
||||
// 更新好友备注
|
||||
func UpdateUserRelations(relations user.UpdateUserRelationsReq) error {
|
||||
// 参数校验
|
||||
if relations.UserID == "" || relations.FriendID == "" {
|
||||
return errors.New("用户ID和好友ID不能为空")
|
||||
}
|
||||
if relations.Remark == "" {
|
||||
return errors.New("备注信息不能为空")
|
||||
}
|
||||
db := DB.Model(&model.UserRelations{})
|
||||
friends, err := getFriend(relations.UserID)
|
||||
if err != nil {
|
||||
@@ -84,22 +106,22 @@ func UpdateUserRelations(relations user.UpdateUserRelationsReq) error {
|
||||
return db.Where("user_id = ?", relations.UserID).Updates(maps).Error
|
||||
}
|
||||
|
||||
|
||||
// 获取好友列表
|
||||
func GetUserListRelations(relations user.ListUserRelationsReq) (*user.ListUserRelationsRes, error) {
|
||||
var res *user.ListUserRelationsRes
|
||||
friends, err := getFriend(relations.UserID)
|
||||
if err != nil {
|
||||
hlog.Error("GetUserListRelations:", err)
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
var ids []string
|
||||
for _,v :=range friends{
|
||||
for _, v := range friends {
|
||||
ids = append(ids, v.FriendID)
|
||||
}
|
||||
res.Users,err = GetUsersById(ids)
|
||||
if err != nil{
|
||||
res.Users, err = GetUsersById(ids)
|
||||
if err != nil {
|
||||
hlog.Error("GetUserListRelations:", err)
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
res.Total = int64(len(friends))
|
||||
return res, nil
|
||||
|
156
acquaintances/biz/handler/user/chat_group_service.go
Normal file
156
acquaintances/biz/handler/user/chat_group_service.go
Normal file
@@ -0,0 +1,156 @@
|
||||
// Code generated by hertz generator.
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"acquaintances/biz/dal/mysql"
|
||||
"acquaintances/biz/utils"
|
||||
"context"
|
||||
|
||||
user "acquaintances/biz/model/user"
|
||||
"github.com/cloudwego/hertz/pkg/app"
|
||||
"github.com/cloudwego/hertz/pkg/protocol/consts"
|
||||
)
|
||||
|
||||
// CreateChatGroup .
|
||||
// @router /v1/cg/ [POST]
|
||||
func CreateChatGroup(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req user.CreateChatGroupReq
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.JSON(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
data := &user.ChatGroupInfo{ChatGroupID: utils.GenerateChatGroupID(), ChatGroupName: req.ChatGroupName}
|
||||
err = mysql.CreateChatGroupInfo(req.UserID, data)
|
||||
if err != nil {
|
||||
c.JSON(consts.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
resp := new(user.CreateChatGroupRes)
|
||||
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
||||
|
||||
// DeleteChatGroup .
|
||||
// @router /v1/cg/ [DELETE]
|
||||
func DeleteChatGroup(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req user.DeleteChatGroupReq
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.JSON(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
err = mysql.DeleteChatGroupInfo(req.ChatGroupID, req.UserID)
|
||||
if err != nil {
|
||||
c.JSON(consts.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
resp := new(user.DeleteChatGroupRes)
|
||||
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
||||
|
||||
// UpdateChatGroup .
|
||||
// @router /v1/cg/ [PUT]
|
||||
func UpdateChatGroup(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req user.UpdateChatGroupReq
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.JSON(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
err = mysql.UpdatesChatGroupInfo(&req)
|
||||
if err != nil {
|
||||
c.JSON(consts.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
resp := new(user.UpdateChatGroupRes)
|
||||
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
||||
|
||||
// ListChatGroupByUser .
|
||||
// @router /v1/cg/ [GET]
|
||||
func ListChatGroupByUser(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req user.ListChatGroupByUserReq
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.JSON(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
data, err := mysql.GetChatGroupListByUser(&req)
|
||||
if err != nil {
|
||||
c.JSON(consts.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
resp := new(user.ListChatGroupByUserRes)
|
||||
resp.ChatGroups = data
|
||||
resp.Total = int64(len(data))
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
||||
|
||||
// ListUserChatGroup .
|
||||
// @router /v1/cg/users/ [GET]
|
||||
func ListUserChatGroup(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req user.ListUserChatGroupReq
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.JSON(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
data, err := mysql.GetUserListByChatGroup(&req)
|
||||
if err != nil {
|
||||
c.JSON(consts.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
resp := new(user.ListUserChatGroupRes)
|
||||
resp.Users = data
|
||||
resp.Total = int64(len(data))
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
||||
|
||||
// JoinChatGroup .
|
||||
// @router /v1/cg/join/ [POST]
|
||||
func JoinChatGroup(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req user.JoinChatGroupReq
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.JSON(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
err = mysql.JoinChatGroup(&req)
|
||||
if err != nil {
|
||||
c.JSON(consts.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
resp := new(user.JoinChatGroupRes)
|
||||
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
||||
|
||||
// ExitChatGroup .
|
||||
// @router /v1/cg/exit/ [POST]
|
||||
func ExitChatGroup(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req user.ExitChatGroupReq
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.JSON(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
err = mysql.ExitChatGroup(&req)
|
||||
if err != nil {
|
||||
c.JSON(consts.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
resp := new(user.ExitChatGroupRes)
|
||||
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
// Code generated by hertz generator.
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"acquaintances/biz/dal/mysql"
|
||||
"acquaintances/biz/model"
|
||||
"context"
|
||||
|
||||
user "acquaintances/biz/model/user"
|
||||
"github.com/cloudwego/hertz/pkg/app"
|
||||
"github.com/cloudwego/hertz/pkg/protocol/consts"
|
||||
)
|
||||
|
||||
// CreateFriendRelationship .
|
||||
// @router /v1/user/friendRelationship/ [POST]
|
||||
func CreateFriendRelationship(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req user.CreateFriendRelationshipReq
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
err = mysql.CreateFriendApplication(req.ApplicantID, req.TargetUserID, req.ApplicationMessage)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
resp := new(user.CreateFriendRelationshipRes)
|
||||
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
||||
|
||||
// UpdateFriendRelationship .
|
||||
// @router /v1/user/friendRelationship/ [PUT]
|
||||
func UpdateFriendRelationship(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req user.UpdateFriendRelationshipReq
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
resp := new(user.UpdateFriendRelationshipRes)
|
||||
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
||||
|
||||
// ListFriendRelationship .
|
||||
// @router /v1/user/friendRelationship/ [GET]
|
||||
func ListFriendRelationship(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req user.ListFriendRelationshipReq
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
data, err := mysql.GetApplications(req, model.ApplicationPending, model.ApplicationAccepted, model.ApplicationRejected)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
resp := new(user.ListFriendRelationshipRes)
|
||||
resp.FriendRelationshipInfos = data
|
||||
resp.Total = int64(len(data))
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
69
acquaintances/biz/model/chat_group.go
Normal file
69
acquaintances/biz/model/chat_group.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package model
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
// ChatGroupInfo 聊天群组信息结构体
|
||||
// 存储群组的基本信息,如名称、头像、公告等
|
||||
type ChatGroupInfo struct {
|
||||
gorm.Model
|
||||
ChatGroupID string `gorm:"column:chat_group_id;type:varchar(64);primary_key;comment:群唯一标识ID"` // 群组唯一ID
|
||||
ChatGroupName string `gorm:"column:chat_group_name;type:varchar(128);not null;comment:群组名称"` // 群组名称
|
||||
ChatGroupImageURL string `gorm:"column:chat_group_image_url;type:varchar(255);comment:群组头像图片URL地址"` // 群组头像URL
|
||||
ChatGroupNotice string `gorm:"column:chat_group_notice;type:text;comment:群组公告内容"` // 群组公告
|
||||
}
|
||||
|
||||
// TableName 指定数据库表名
|
||||
func (c *ChatGroupInfo) TableName() string {
|
||||
return "chat_group_info"
|
||||
}
|
||||
|
||||
type ChatGroupRole int
|
||||
|
||||
const (
|
||||
General ChatGroupRole = iota
|
||||
Administrators
|
||||
GroupLeader
|
||||
)
|
||||
|
||||
// GroupUserRelation 群与用户关系结构体
|
||||
// 记录用户与群组的关联关系及用户在群内的相关属性
|
||||
type GroupUserRelation struct {
|
||||
gorm.Model
|
||||
ChatGroupID string `gorm:"column:chat_group_id;type:varchar(64);not null;index;comment:关联的群ID"` // 群组ID,关联ChatGroupInfo表
|
||||
UserID string `gorm:"column:user_id;type:varchar(64);not null;index;comment:关联的用户ID"` // 用户ID,关联用户表
|
||||
Role ChatGroupRole `gorm:"column:role;type:int;not null;default:0;comment:用户群内角色(0-普通成员,1-管理员,2-群主)"` // 用户在群内的角色
|
||||
LastReadTime int64 `gorm:"column:last_read_time;type:bigint;default:0;comment:最后阅读消息时间(Unix时间戳)"` // 最后阅读时间(时间戳)
|
||||
IsMuted bool `gorm:"column:is_muted;type:tinyint(1);default:false;comment:是否被禁言(true-是,false-否)"` // 是否被禁言
|
||||
MuteExpireTime int64 `gorm:"column:mute_expire_time;type:bigint;default:0;comment:禁言过期时间(Unix时间戳,0表示永久)"` // 禁言过期时间
|
||||
}
|
||||
|
||||
// TableName 指定数据库表名
|
||||
func (g *GroupUserRelation) TableName() string {
|
||||
return "group_user_relation"
|
||||
}
|
||||
|
||||
// BeforeCreate 创建前钩子方法
|
||||
// 用于创建联合索引,确保数据完整性
|
||||
func (g *GroupUserRelation) BeforeCreate(tx *gorm.DB) error {
|
||||
// 检查索引是否已存在,避免重复创建
|
||||
var count int64
|
||||
err := tx.Raw(`
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.statistics
|
||||
WHERE table_name = 'group_user_relation'
|
||||
AND index_name = 'idx_group_user'
|
||||
`).Scan(&count).Error
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
// 创建唯一联合索引,确保一个用户在一个群中只有一条记录
|
||||
if err := tx.Exec("CREATE UNIQUE INDEX idx_group_user ON group_user_relation(chat_group_id, user_id)").Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -2,24 +2,52 @@ package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// UserRelations 好友关系表
|
||||
type UserRelations struct {
|
||||
gorm.Model
|
||||
UserID string `gorm:"column:user_id;type:varchar(32);not null;index:idx_user_friend,unique;comment:用户id"`
|
||||
FriendList json.RawMessage `gorm:"column:friend_list;type:json;comment:'好友列表'"`
|
||||
FriendCount int64 `gorm:"column:friend_count;type:int;default:0;comment:好友数量"`
|
||||
UserID string `gorm:"column:user_id;type:varchar(32);not null;index:idx_user_friend,unique;comment:用户id"`
|
||||
FriendList json.RawMessage `gorm:"column:friend_list;type:json;comment:'好友列表'"`
|
||||
FriendCount int64 `gorm:"column:friend_count;type:int;default:0;comment:好友数量"`
|
||||
}
|
||||
|
||||
type Friend struct{
|
||||
type Friend struct {
|
||||
FriendID string `json:"friend_id"`
|
||||
Remark string `json:"remark"` // 好友备注
|
||||
Remark string `json:"remark"` // 好友备注
|
||||
CreateTime int64 `json:"create_time"` // 创建时间
|
||||
}
|
||||
|
||||
func (u *UserRelations) TableName() string {
|
||||
return "user_relations"
|
||||
}
|
||||
|
||||
// FriendApplicationStatus 好友申请状态
|
||||
type FriendApplicationStatus int
|
||||
|
||||
const (
|
||||
ApplicationPending FriendApplicationStatus = iota // 0-待处理
|
||||
ApplicationAccepted // 1-已接受
|
||||
ApplicationRejected //已拒绝
|
||||
RelationshipBreakdown //删除
|
||||
)
|
||||
|
||||
// FriendApplication 好友申请表
|
||||
type FriendRelationship struct {
|
||||
gorm.Model
|
||||
ApplicantID string `gorm:"column:applicant_id;type:varchar(32);not null;index:idx_applicant_target,unique;comment:申请人ID"` // 发起申请者ID
|
||||
TargetUserID string `gorm:"column:target_user_id;type:varchar(32);not null;index:idx_applicant_target,unique;comment:目标用户ID"` // 被申请用户ID
|
||||
ApplicationMessage string `gorm:"column:application_message;type:varchar(255);comment:申请留言"` // 申请留言
|
||||
Status FriendApplicationStatus `gorm:"column:status;type:int;not null;default:0;comment:申请状态(0-待处理,1-已接受,2-已拒绝.3-关系破裂)"` // 申请状态
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (f *FriendRelationship) TableName() string {
|
||||
return "friend_relationship"
|
||||
}
|
||||
|
||||
// IsValid 检查状态是否有效
|
||||
func (s FriendApplicationStatus) IsValid() bool {
|
||||
return s >= ApplicationPending && s <= RelationshipBreakdown
|
||||
}
|
||||
|
@@ -120,3 +120,78 @@ func _updateuserrelationsMw() []app.HandlerFunc {
|
||||
// your code...
|
||||
return nil
|
||||
}
|
||||
|
||||
func _cgMw() []app.HandlerFunc {
|
||||
// your code...
|
||||
return nil
|
||||
}
|
||||
|
||||
func _deletechatgroupMw() []app.HandlerFunc {
|
||||
// your code...
|
||||
return nil
|
||||
}
|
||||
|
||||
func _listchatgroupbyuserMw() []app.HandlerFunc {
|
||||
// your code...
|
||||
return nil
|
||||
}
|
||||
|
||||
func _createchatgroupMw() []app.HandlerFunc {
|
||||
// your code...
|
||||
return nil
|
||||
}
|
||||
|
||||
func _updatechatgroupMw() []app.HandlerFunc {
|
||||
// your code...
|
||||
return nil
|
||||
}
|
||||
|
||||
func _exitMw() []app.HandlerFunc {
|
||||
// your code...
|
||||
return nil
|
||||
}
|
||||
|
||||
func _exitchatgroupMw() []app.HandlerFunc {
|
||||
// your code...
|
||||
return nil
|
||||
}
|
||||
|
||||
func _joinMw() []app.HandlerFunc {
|
||||
// your code...
|
||||
return nil
|
||||
}
|
||||
|
||||
func _joinchatgroupMw() []app.HandlerFunc {
|
||||
// your code...
|
||||
return nil
|
||||
}
|
||||
|
||||
func _usersMw() []app.HandlerFunc {
|
||||
// your code...
|
||||
return nil
|
||||
}
|
||||
|
||||
func _listuserchatgroupMw() []app.HandlerFunc {
|
||||
// your code...
|
||||
return nil
|
||||
}
|
||||
|
||||
func _friendrelationshipMw() []app.HandlerFunc {
|
||||
// your code...
|
||||
return nil
|
||||
}
|
||||
|
||||
func _createfriendrelationshipMw() []app.HandlerFunc {
|
||||
// your code...
|
||||
return nil
|
||||
}
|
||||
|
||||
func _updatefriendrelationshipMw() []app.HandlerFunc {
|
||||
// your code...
|
||||
return nil
|
||||
}
|
||||
|
||||
func _listfriendrelationshipMw() []app.HandlerFunc {
|
||||
// your code...
|
||||
return nil
|
||||
}
|
||||
|
@@ -19,12 +19,37 @@ func Register(r *server.Hertz) {
|
||||
root := r.Group("/", rootMw()...)
|
||||
{
|
||||
_v1 := root.Group("/v1", _v1Mw()...)
|
||||
{
|
||||
_cg := _v1.Group("/cg", _cgMw()...)
|
||||
_cg.DELETE("/", append(_deletechatgroupMw(), user.DeleteChatGroup)...)
|
||||
_cg.GET("/", append(_listchatgroupbyuserMw(), user.ListChatGroupByUser)...)
|
||||
_cg.POST("/", append(_createchatgroupMw(), user.CreateChatGroup)...)
|
||||
_cg.PUT("/", append(_updatechatgroupMw(), user.UpdateChatGroup)...)
|
||||
{
|
||||
_exit := _cg.Group("/exit", _exitMw()...)
|
||||
_exit.POST("/", append(_exitchatgroupMw(), user.ExitChatGroup)...)
|
||||
}
|
||||
{
|
||||
_join := _cg.Group("/join", _joinMw()...)
|
||||
_join.POST("/", append(_joinchatgroupMw(), user.JoinChatGroup)...)
|
||||
}
|
||||
{
|
||||
_users := _cg.Group("/users", _usersMw()...)
|
||||
_users.GET("/", append(_listuserchatgroupMw(), user.ListUserChatGroup)...)
|
||||
}
|
||||
}
|
||||
{
|
||||
_user := _v1.Group("/user", _userMw()...)
|
||||
_user.DELETE("/", append(_deleteuserMw(), user.DeleteUser)...)
|
||||
_user.GET("/", append(_infouserMw(), user.InfoUser)...)
|
||||
_user.POST("/", append(_createuserMw(), user.CreateUser)...)
|
||||
_user.PUT("/", append(_updateuserMw(), user.UpdateUser)...)
|
||||
{
|
||||
_friendrelationship := _user.Group("/friendRelationship", _friendrelationshipMw()...)
|
||||
_friendrelationship.GET("/", append(_listfriendrelationshipMw(), user.ListFriendRelationship)...)
|
||||
_friendrelationship.POST("/", append(_createfriendrelationshipMw(), user.CreateFriendRelationship)...)
|
||||
_friendrelationship.PUT("/", append(_updatefriendrelationshipMw(), user.UpdateFriendRelationship)...)
|
||||
}
|
||||
{
|
||||
_relation := _user.Group("/relation", _relationMw()...)
|
||||
_relation.DELETE("/", append(_deleteuserrelationsMw(), user.DeleteUserRelations)...)
|
||||
|
@@ -137,3 +137,37 @@ func GetID() (int64, error) {
|
||||
})
|
||||
return generator.Generate()
|
||||
}
|
||||
|
||||
// GenerateChatGroupID 生成唯一的群组ID
|
||||
// 格式: group-{时间戳}-{随机字符串}
|
||||
// 时间戳使用秒级,确保一定的时间顺序性
|
||||
// 随机字符串确保在同一秒内生成的ID也能保持唯一
|
||||
func GenerateChatGroupID() string {
|
||||
// 获取当前时间戳(秒级)
|
||||
timestamp := time.Now().Unix()
|
||||
|
||||
// 生成随机字节
|
||||
randomBytes := make([]byte, 8) // 8字节=64位,足够产生足够随机的字符串
|
||||
_, err := rand.Read(randomBytes)
|
||||
if err != nil {
|
||||
// 极端情况下随机数生成失败,使用伪随机数作为 fallback
|
||||
// 这种情况发生概率极低,但仍需处理以保证函数可用性
|
||||
randStr := fmt.Sprintf("%016x", time.Now().UnixNano())
|
||||
return fmt.Sprintf("group-%d-%s", timestamp, randStr[:12])
|
||||
}
|
||||
|
||||
// 将随机字节转换为URL安全的Base64字符串,去掉末尾可能的=号
|
||||
randStr := base64.URLEncoding.EncodeToString(randomBytes)
|
||||
randStr = trimBase64Padding(randStr)
|
||||
|
||||
// 组合成最终的群组ID
|
||||
return fmt.Sprintf("group-%d-%s", timestamp, randStr)
|
||||
}
|
||||
|
||||
// trimBase64Padding 移除Base64字符串末尾的填充字符=
|
||||
func trimBase64Padding(s string) string {
|
||||
for len(s) > 0 && s[len(s)-1] == '=' {
|
||||
s = s[:len(s)-1]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
@@ -172,3 +172,154 @@ service UserRelationsService {
|
||||
UpdateUserRelationsRes UpdateUserRelations(1:UpdateUserRelationsReq req)(api.put="/v1/user/relation/") //修改好友备注
|
||||
}
|
||||
|
||||
//好友申请
|
||||
//发起好友申请
|
||||
struct FriendRelationshipInfo {
|
||||
1: string applicant_id
|
||||
2: string target_user_id
|
||||
3: string application_message
|
||||
4: string status
|
||||
}
|
||||
|
||||
struct CreateFriendRelationshipReq {
|
||||
1: string applicant_id //id
|
||||
2: string target_user_id //好友id
|
||||
3: string application_message //好友id
|
||||
}
|
||||
|
||||
struct CreateFriendRelationshipRes{
|
||||
1: Code code
|
||||
2: string msg
|
||||
}
|
||||
|
||||
//同意/拒绝好友申请
|
||||
struct UpdateFriendRelationshipReq {
|
||||
1: string applicant_id //id
|
||||
2: string target_user_id //好友id
|
||||
3: string Status //好友id
|
||||
}
|
||||
|
||||
struct UpdateFriendRelationshipRes{
|
||||
1: Code code
|
||||
2: string msg
|
||||
}
|
||||
|
||||
//请求添加好友或被添加好友列表
|
||||
struct ListFriendRelationshipReq{
|
||||
1: string user_id //id
|
||||
}
|
||||
|
||||
|
||||
struct ListFriendRelationshipRes{
|
||||
1: Code code
|
||||
2: string msg
|
||||
3: list<FriendRelationshipInfo> FriendRelationshipInfos
|
||||
4: i64 total
|
||||
}
|
||||
|
||||
service FriendRelationshipService {
|
||||
CreateFriendRelationshipRes CreateFriendRelationship(1:CreateFriendRelationshipReq req)(api.post="/v1/user/friendRelationship/") //发起好友申请
|
||||
UpdateFriendRelationshipRes UpdateFriendRelationship(1:UpdateFriendRelationshipReq req)(api.put="/v1/user/friendRelationship/") //同意或拒绝好友申请
|
||||
ListFriendRelationshipRes ListFriendRelationship(1:ListFriendRelationshipReq req)(api.get="/v1/user/friendRelationship/") //获取添加或申请记录列表
|
||||
}
|
||||
|
||||
|
||||
//聊天群组
|
||||
//创建群聊
|
||||
struct ChatGroupInfo{
|
||||
1: string chat_group_id
|
||||
2: string chat_group_name
|
||||
3: string chat_group_image_url
|
||||
4: string chat_group_Notice
|
||||
}
|
||||
|
||||
struct CreateChatGroupReq {
|
||||
1: string user_id //创建者id
|
||||
2: string chat_group_name //群名
|
||||
}
|
||||
|
||||
struct CreateChatGroupRes{
|
||||
1: Code code
|
||||
2: string msg
|
||||
}
|
||||
|
||||
//解散群聊
|
||||
struct DeleteChatGroupReq {
|
||||
1: string user_id //创建者id
|
||||
2: string chat_group_id //群号
|
||||
}
|
||||
|
||||
struct DeleteChatGroupRes{
|
||||
1: Code code
|
||||
2: string msg
|
||||
}
|
||||
|
||||
//修改群信息
|
||||
struct UpdateChatGroupReq {
|
||||
1: string user_id //创建者id
|
||||
2: string chat_group_id //群号
|
||||
3: string new_chat_group_name //新群名
|
||||
4: string chat_group_name_image_url //群头像
|
||||
5: string chat_group_Notice //群公告
|
||||
}
|
||||
|
||||
struct UpdateChatGroupRes{
|
||||
1: Code code
|
||||
2: string msg
|
||||
}
|
||||
|
||||
//加入群聊
|
||||
struct JoinChatGroupReq {
|
||||
1: string user_id //申请者id
|
||||
2: string chat_group_id //群号
|
||||
}
|
||||
|
||||
struct JoinChatGroupRes{
|
||||
1: Code code
|
||||
2: string msg
|
||||
}
|
||||
|
||||
//退出群聊
|
||||
struct ExitChatGroupReq {
|
||||
1: string user_id //申请者id
|
||||
2: string chat_group_id //群号
|
||||
}
|
||||
|
||||
struct ExitChatGroupRes{
|
||||
1: Code code
|
||||
2: string msg
|
||||
}
|
||||
|
||||
//获取自己加入的群列表
|
||||
struct ListChatGroupByUserReq {
|
||||
1: string user_id //id
|
||||
}
|
||||
|
||||
struct ListChatGroupByUserRes{
|
||||
1: Code code
|
||||
2: string msg
|
||||
3: list<ChatGroupInfo> chat_groups
|
||||
4: i64 total
|
||||
}
|
||||
|
||||
//获取群成员列表
|
||||
struct ListUserChatGroupReq {
|
||||
1: string chat_group_id
|
||||
}
|
||||
|
||||
struct ListUserChatGroupRes{
|
||||
1: Code code
|
||||
2: string msg
|
||||
3: list<UserInfoReq> users
|
||||
4: i64 total
|
||||
}
|
||||
|
||||
service ChatGroupService {
|
||||
CreateChatGroupRes CreateChatGroup(1:CreateChatGroupReq req)(api.post="/v1/cg/") //创建群聊
|
||||
DeleteChatGroupRes DeleteChatGroup(1:DeleteChatGroupReq req)(api.delete="/v1/cg/") //删除群
|
||||
UpdateChatGroupRes UpdateChatGroup(1:UpdateChatGroupReq req)(api.put="/v1/cg/") //修改群信息
|
||||
ListChatGroupByUserRes ListChatGroupByUser(1: ListChatGroupByUserReq req)(api.get="/v1/cg/") //获取指定用户群列表
|
||||
ListUserChatGroupRes ListUserChatGroup(1: ListUserChatGroupReq req)(api.get="/v1/cg/users/") //获取指定群用户列表
|
||||
JoinChatGroupRes JoinChatGroup(1:JoinChatGroupReq req)(api.post="/v1/cg/join/") //入群
|
||||
ExitChatGroupRes ExitChatGroup(1:ExitChatGroupReq req)(api.post="/v1/cg/exit/") //退出群
|
||||
}
|
Reference in New Issue
Block a user