/** * 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 * 功能:搜索用户(返回带有 is_friend 标识的结果) * 路径: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 } // 获取当前用户ID(用于判断好友关系) var currentUserID string if userID, exists := c.Get("user_id"); exists { currentUserID = userID.(string) } // 调用服务层搜索用户 result, err := service.ContactSvc.SearchUsersWithFriendStatus(currentUserID, keyword, limit) if err != nil { utils.InternalError(c, "搜索失败") return } // 确保返回空数组而不是null if result == nil { result = []map[string]interface{}{} } utils.SuccessWithData(c, result, "搜索成功") } /** * AddFriendHandler * 功能:添加好友(发送申请) * 路径:POST /api/contacts/add-friend */ func AddFriendHandler(c *gin.Context) { userID, _ := c.Get("user_id") 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") // 校验 :id 解析错误:原实现忽略 error,非法ID会静默变成 0 去更新不存在的分组 groupID, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { utils.BadRequest(c, "分组ID不合法") return } // 使用指针字段表达"字段是否出现"语义: // 原实现用 !="" / >0 判断,导致无法把排序值置 0; // 指针为 nil 表示前端没传该字段(跳过),非 nil 表示要更新(含零值) var req struct { GroupName *string `json:"group_name"` SortOrder *int `json:"sort_order"` } if err := c.ShouldBindJSON(&req); err != nil { utils.BadRequest(c, "参数错误") return } updates := make(map[string]interface{}) if req.GroupName != nil { // 分组名不允许被清空(业务约束),显式传空串视为非法 if *req.GroupName == "" { utils.BadRequest(c, "分组名不能为空") return } updates["group_name"] = *req.GroupName } if req.SortOrder != nil { updates["sort_order"] = *req.SortOrder } 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") // 校验 :id 解析错误:非法ID静默变 0 会误删/误匹配 groupID, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { utils.BadRequest(c, "分组ID不合法") return } if err := service.ContactSvc.DeleteGroup(uint(groupID), userID.(string)); err != nil { utils.BadRequest(c, "删除失败: "+err.Error()) return } utils.Success(c, "删除成功") } /** * GetContactDetailHandler * 功能:获取用户详情(包含好友关系) * 路径:GET /api/contacts/:id */ func GetContactDetailHandler(c *gin.Context) { userID, _ := c.Get("user_id") contactID := c.Param("id") // 调用服务层获取用户详情(包含好友关系) result, err := service.ContactSvc.GetUserDetailWithFriendStatus(userID.(string), contactID) 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") // 全部使用指针字段表达"字段是否出现"语义: // 原实现 remark_name!="" / group_id>0 才写入,导致无法清空备注、 // 无法把联系人移回默认分组(0);指针为 nil 表示未传(跳过),非 nil 表示更新(含零值) var req struct { 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端开关一直不生效) } if err := c.ShouldBindJSON(&req); err != nil { utils.BadRequest(c, "参数错误") return } updates := make(map[string]interface{}) if req.RemarkName != nil { updates["remark_name"] = *req.RemarkName } if req.GroupID != nil { updates["group_id"] = *req.GroupID } if req.IsTop != nil { updates["is_top"] = *req.IsTop } if req.IsMuted != nil { updates["is_muted"] = *req.IsMuted } if req.IsBlocked != nil { updates["is_blocked"] = *req.IsBlocked } if req.IsSpecialCare != nil { updates["is_special_care"] = *req.IsSpecialCare } 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, "已删除好友") }