Files
nl-im-service/internal/api/contact_handler.go

387 lines
9.3 KiB
Go
Raw Permalink Normal View History

2025-12-03 11:00:47 +08:00
/**
* package api
* 作用联系人管理相关API处理器
*/
package api
import (
"strconv"
"xk-websocket-v2/internal/model"
"xk-websocket-v2/internal/service"
"xk-websocket-v2/internal/utils"
"github.com/gin-gonic/gin"
)
/**
* ContactListHandler
* 功能获取联系人列表已存在需改为从数据库查询
* 路径GET /api/contacts
*/
func ContactListHandler(c *gin.Context) {
// 从Context获取用户ID由JWT中间件注入
userID, exists := c.Get("user_id")
if !exists {
// 如果没有认证,返回空列表(兼容旧代码)
utils.SuccessWithData(c, []interface{}{}, "获取成功")
return
}
contacts, err := service.ContactSvc.GetContactsWithUserInfo(userID.(string))
if err != nil {
utils.InternalError(c, "查询失败")
return
}
// 确保返回空数组而不是null
if contacts == nil {
contacts = []map[string]interface{}{}
}
utils.SuccessWithData(c, contacts, "获取成功")
}
/**
* SearchUsersHandler
2025-12-10 15:19:26 +08:00
* 功能搜索用户返回带有 is_friend 标识的结果
2025-12-03 11:00:47 +08:00
* 路径GET /api/contacts/search
*/
func SearchUsersHandler(c *gin.Context) {
keyword := c.Query("keyword")
if keyword == "" {
utils.BadRequest(c, "搜索关键词不能为空")
return
}
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "20"))
if limit < 1 || limit > 100 {
limit = 20
}
2025-12-10 15:19:26 +08:00
// 获取当前用户ID用于判断好友关系
var currentUserID string
if userID, exists := c.Get("user_id"); exists {
currentUserID = userID.(string)
}
// 调用服务层搜索用户
result, err := service.ContactSvc.SearchUsersWithFriendStatus(currentUserID, keyword, limit)
2025-12-03 11:00:47 +08:00
if err != nil {
utils.InternalError(c, "搜索失败")
return
}
// 确保返回空数组而不是null
2025-12-10 15:19:26 +08:00
if result == nil {
result = []map[string]interface{}{}
2025-12-03 11:00:47 +08:00
}
2025-12-10 15:19:26 +08:00
utils.SuccessWithData(c, result, "搜索成功")
2025-12-03 11:00:47 +08:00
}
/**
* AddFriendHandler
* 功能添加好友发送申请
* 路径POST /api/contacts/add-friend
*/
func AddFriendHandler(c *gin.Context) {
userID, _ := c.Get("user_id")
2025-12-10 15:19:26 +08:00
2025-12-03 11:00:47 +08:00
var req struct {
ToUserID string `json:"to_user_id" binding:"required"`
Message string `json:"message"`
}
if err := c.ShouldBindJSON(&req); err != nil {
utils.BadRequest(c, "参数错误: "+err.Error())
return
}
if err := service.ContactSvc.AddFriend(userID.(string), req.ToUserID, req.Message); err != nil {
utils.BadRequest(c, err.Error())
return
}
utils.Success(c, "好友申请已发送")
}
/**
* GetFriendRequestsHandler
* 功能获取好友申请列表
* 路径GET /api/contacts/friend-requests
*/
func GetFriendRequestsHandler(c *gin.Context) {
userID, _ := c.Get("user_id")
requests, err := service.ContactSvc.GetFriendRequests(userID.(string))
if err != nil {
utils.InternalError(c, "查询失败")
return
}
// 确保返回空数组而不是null
if requests == nil {
requests = []model.FriendRequest{}
}
utils.SuccessWithData(c, requests, "获取成功")
}
/**
* AcceptFriendRequestHandler
* 功能接受好友申请
* 路径POST /api/contacts/accept-request
*/
func AcceptFriendRequestHandler(c *gin.Context) {
userID, _ := c.Get("user_id")
var req struct {
RequestID uint `json:"request_id" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
utils.BadRequest(c, "参数错误")
return
}
if err := service.ContactSvc.AcceptFriendRequest(req.RequestID, userID.(string)); err != nil {
utils.BadRequest(c, err.Error())
return
}
utils.Success(c, "已接受好友申请")
}
/**
* RejectFriendRequestHandler
* 功能拒绝好友申请
* 路径POST /api/contacts/reject-request
*/
func RejectFriendRequestHandler(c *gin.Context) {
userID, _ := c.Get("user_id")
var req struct {
RequestID uint `json:"request_id" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
utils.BadRequest(c, "参数错误")
return
}
if err := service.ContactSvc.RejectFriendRequest(req.RequestID, userID.(string)); err != nil {
utils.BadRequest(c, err.Error())
return
}
utils.Success(c, "已拒绝好友申请")
}
/**
* GetGroupsHandler
* 功能获取分组列表
* 路径GET /api/contacts/groups
*/
func GetGroupsHandler(c *gin.Context) {
userID, _ := c.Get("user_id")
groups, err := service.ContactSvc.GetGroups(userID.(string))
if err != nil {
utils.InternalError(c, "查询失败")
return
}
// 确保返回空数组而不是null
if groups == nil {
groups = []model.ContactGroup{}
}
utils.SuccessWithData(c, groups, "获取成功")
}
/**
* CreateGroupHandler
* 功能创建分组
* 路径POST /api/contacts/groups
*/
func CreateGroupHandler(c *gin.Context) {
userID, _ := c.Get("user_id")
var req struct {
GroupName string `json:"group_name" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
utils.BadRequest(c, "参数错误: "+err.Error())
return
}
group, err := service.ContactSvc.CreateGroup(userID.(string), req.GroupName)
if err != nil {
utils.BadRequest(c, "创建失败: "+err.Error())
return
}
utils.SuccessWithData(c, group, "创建成功")
}
/**
* UpdateGroupHandler
* 功能更新分组
* 路径PUT /api/contacts/groups/:id
*/
func UpdateGroupHandler(c *gin.Context) {
userID, _ := c.Get("user_id")
2026-08-24 15:29:53 +08:00
// 校验 :id 解析错误:原实现忽略 error非法ID会静默变成 0 去更新不存在的分组
groupID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
utils.BadRequest(c, "分组ID不合法")
return
}
2025-12-03 11:00:47 +08:00
2026-08-24 15:29:53 +08:00
// 使用指针字段表达"字段是否出现"语义:
// 原实现用 !="" / >0 判断,导致无法把排序值置 0
// 指针为 nil 表示前端没传该字段(跳过),非 nil 表示要更新(含零值)
2025-12-03 11:00:47 +08:00
var req struct {
2026-08-24 15:29:53 +08:00
GroupName *string `json:"group_name"`
SortOrder *int `json:"sort_order"`
2025-12-03 11:00:47 +08:00
}
if err := c.ShouldBindJSON(&req); err != nil {
utils.BadRequest(c, "参数错误")
return
}
updates := make(map[string]interface{})
2026-08-24 15:29:53 +08:00
if req.GroupName != nil {
// 分组名不允许被清空(业务约束),显式传空串视为非法
if *req.GroupName == "" {
utils.BadRequest(c, "分组名不能为空")
return
}
updates["group_name"] = *req.GroupName
2025-12-03 11:00:47 +08:00
}
2026-08-24 15:29:53 +08:00
if req.SortOrder != nil {
updates["sort_order"] = *req.SortOrder
2025-12-03 11:00:47 +08:00
}
if err := service.ContactSvc.UpdateGroup(uint(groupID), userID.(string), updates); err != nil {
utils.BadRequest(c, "更新失败: "+err.Error())
return
}
utils.Success(c, "更新成功")
}
/**
* DeleteGroupHandler
* 功能删除分组
* 路径DELETE /api/contacts/groups/:id
*/
func DeleteGroupHandler(c *gin.Context) {
userID, _ := c.Get("user_id")
2026-08-24 15:29:53 +08:00
// 校验 :id 解析错误非法ID静默变 0 会误删/误匹配
groupID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
utils.BadRequest(c, "分组ID不合法")
return
}
2025-12-03 11:00:47 +08:00
if err := service.ContactSvc.DeleteGroup(uint(groupID), userID.(string)); err != nil {
utils.BadRequest(c, "删除失败: "+err.Error())
return
}
utils.Success(c, "删除成功")
}
/**
* GetContactDetailHandler
2025-12-10 15:19:26 +08:00
* 功能获取用户详情包含好友关系
2025-12-03 11:00:47 +08:00
* 路径GET /api/contacts/:id
*/
func GetContactDetailHandler(c *gin.Context) {
userID, _ := c.Get("user_id")
contactID := c.Param("id")
2025-12-10 15:19:26 +08:00
// 调用服务层获取用户详情(包含好友关系)
result, err := service.ContactSvc.GetUserDetailWithFriendStatus(userID.(string), contactID)
2025-12-03 11:00:47 +08:00
if err != nil {
utils.NotFound(c, "用户不存在")
return
}
utils.SuccessWithData(c, result, "获取成功")
}
/**
* UpdateContactHandler
* 功能更新好友信息
* 路径PUT /api/contacts/:id
*/
func UpdateContactHandler(c *gin.Context) {
userID, _ := c.Get("user_id")
contactID := c.Param("id")
2026-08-24 15:29:53 +08:00
// 全部使用指针字段表达"字段是否出现"语义:
// 原实现 remark_name!="" / group_id>0 才写入,导致无法清空备注、
// 无法把联系人移回默认分组(0);指针为 nil 表示未传(跳过),非 nil 表示更新(含零值)
2025-12-03 11:00:47 +08:00
var req struct {
2026-08-24 15:29:53 +08:00
RemarkName *string `json:"remark_name"`
GroupID *uint `json:"group_id"`
IsTop *bool `json:"is_top"`
IsMuted *bool `json:"is_muted"`
IsBlocked *bool `json:"is_blocked"`
IsSpecialCare *bool `json:"is_special_care"` // 特别关心此前漏了该字段PC端开关一直不生效
2025-12-03 11:00:47 +08:00
}
if err := c.ShouldBindJSON(&req); err != nil {
utils.BadRequest(c, "参数错误")
return
}
updates := make(map[string]interface{})
2026-08-24 15:29:53 +08:00
if req.RemarkName != nil {
updates["remark_name"] = *req.RemarkName
2025-12-03 11:00:47 +08:00
}
2026-08-24 15:29:53 +08:00
if req.GroupID != nil {
updates["group_id"] = *req.GroupID
2025-12-03 11:00:47 +08:00
}
if req.IsTop != nil {
updates["is_top"] = *req.IsTop
}
if req.IsMuted != nil {
updates["is_muted"] = *req.IsMuted
}
2026-07-08 08:18:58 +08:00
if req.IsBlocked != nil {
updates["is_blocked"] = *req.IsBlocked
}
2026-08-24 15:29:53 +08:00
if req.IsSpecialCare != nil {
updates["is_special_care"] = *req.IsSpecialCare
}
2025-12-03 11:00:47 +08:00
if err := service.ContactSvc.UpdateContact(userID.(string), contactID, updates); err != nil {
utils.BadRequest(c, "更新失败: "+err.Error())
return
}
utils.Success(c, "更新成功")
}
/**
* DeleteContactHandler
* 功能删除好友
* 路径DELETE /api/contacts/:id
*/
func DeleteContactHandler(c *gin.Context) {
userID, _ := c.Get("user_id")
contactID := c.Param("id")
if err := service.ContactSvc.DeleteContact(userID.(string), contactID); err != nil {
utils.BadRequest(c, "删除失败: "+err.Error())
return
}
utils.Success(c, "已删除好友")
}