Files
danyang-match/REST API 接口详细设计规范.md
T

40 KiB
Raw Blame History

丹阳公益婚恋服务平台

V1.0 REST API 接口详细设计规范

版本:V1.0
协议:HTTPS + REST
实时通信:WebSocket
基础路径:/api/v1
适用范围:微信小程序用户端、公益红娘工作台、运营管理后台


第一章 API设计目标

本规范用于统一:

  • REST路径
  • HTTP方法
  • 请求参数
  • 响应结构
  • 分页规范
  • 错误码
  • 权限校验
  • 幂等机制
  • 用户状态限制
  • 数据脱敏
  • 后台操作审计

目标是做到:

前端知道怎么调用。

后端知道怎么实现。

测试知道怎么验收。

后续升级不会因为接口随意变化造成大量返工。


第二章 基础URL

生产环境示例:

https://api.example.com/api/v1

实际正式域名在部署阶段确定。

用户API:

/api/v1/*

红娘工作台:

/api/v1/operator/*

管理后台:

/api/v1/admin/*

第三章 HTTPS要求

所有生产API:

必须HTTPS。

禁止:

  • HTTP明文登录
  • HTTP上传敏感信息
  • 在URL Query中传Token
  • 在URL中传身份证、手机号等敏感数据

第四章 HTTP方法规范

统一:

GET     查询
POST    创建/业务动作
PUT     整体修改
PATCH   局部修改
DELETE  删除/撤销

V1实际业务中优先:

GET
POST
PATCH
DELETE

第五章 API统一响应结构

成功:

{
  "success": true,
  "code": "OK",
  "message": "success",
  "data": {}
}

错误:

{
  "success": false,
  "code": "PROFILE_NOT_APPROVED",
  "message": "当前资料尚未通过审核",
  "data": null
}

第六章 Trace ID

每个响应建议返回:

X-Request-Id

错误响应也可包含:

{
  "requestId": "req_xxx"
}

方便排查问题。


第七章 Authentication Header

用户:

Authorization: Bearer <access_token>

工作人员同样:

Authorization: Bearer <operator_token>

两类Token不可混用。


第八章 Idempotency Key

以下接口必须支持:

Idempotency-Key

例如:

Idempotency-Key: 8f52...

适用:

  • 提交审核
  • 喜欢
  • 活动报名
  • 红娘申请
  • 举报
  • 签到
  • 成功牵手请求

第九章 分页规范

后台列表:

?page=1&pageSize=20

响应:

{
  "items": [],
  "page": 1,
  "pageSize": 20,
  "total": 128
}

聊天、推荐等动态列表:

Cursor分页。

例如:

?cursor=xxx&limit=20

返回:

{
  "items": [],
  "nextCursor": "xxx",
  "hasMore": true
}

第十章 用户认证接口总览

POST /auth/wechat/login
POST /auth/phone/bind
POST /auth/refresh
POST /auth/logout

GET  /me/status

第十一章 POST /auth/wechat/login

用途:

微信小程序登录。

请求:

{
  "code": "wx_login_code"
}

响应:

{
  "accessToken": "xxx",
  "refreshToken": "xxx",
  "expiresIn": 7200,
  "user": {
    "id": "usr_xxx",
    "phoneBound": false,
    "verified": false,
    "profileCompletionStatus": "not_started",
    "reviewStatus": "not_submitted",
    "accountStatus": "normal",
    "relationshipStatus": "searching"
  }
}

第十二章 登录错误码

WECHAT_LOGIN_FAILED
ACCOUNT_BANNED
ACCOUNT_CLOSED
AUTH_PROVIDER_ERROR

第十三章 POST /auth/phone/bind

请求:

优先微信手机号授权:

{
  "phoneCode": "wx_phone_code"
}

备用验证码模式:

{
  "phone": "13800000000",
  "smsCode": "123456"
}

响应:

{
  "phoneBound": true,
  "phoneMasked": "138****0000"
}

错误:

PHONE_ALREADY_BOUND
PHONE_INVALID
SMS_CODE_INVALID

第十四章 POST /auth/refresh

请求:

{
  "refreshToken": "xxx"
}

响应:

{
  "accessToken": "new_token",
  "refreshToken": "new_refresh_token",
  "expiresIn": 7200
}

第十五章 POST /auth/logout

登录用户。

请求体:

{}

响应:

{
  "loggedOut": true
}

服务端同时撤销当前会话。


第十六章 GET /me/status

这是前端路由守卫核心接口。

响应:

{
  "id": "usr_xxx",
  "phoneBound": true,
  "realNameVerified": true,
  "profileCompletionStatus": "completed",
  "reviewStatus": "approved",
  "accountStatus": "normal",
  "relationshipStatus": "searching",
  "recommendationEnabled": true,
  "visibleInSearch": true
}

第十七章 实名认证接口总览

GET  /verification/status
POST /verification/real-name

第十八章 GET /verification/status

响应:

{
  "status": "verified",
  "verifiedAt": "2026-08-28T10:00:00+08:00"
}

不能返回:

  • 完整姓名
  • 身份证号码

第十九章 POST /verification/real-name

请求:

{
  "realName": "张三",
  "idNumber": "320xxxxxxxxxxxxx"
}

响应成功:

{
  "status": "verified",
  "adult": true,
  "gender": "male",
  "birthDate": "1990-05-12"
}

第二十章 实名错误码

REAL_NAME_MISMATCH
ID_NUMBER_INVALID
UNDER_18
VERIFICATION_FAILED
VERIFICATION_RATE_LIMITED
ALREADY_VERIFIED

第二十一章 用户资料接口总览

GET   /me/profile
PATCH /me/profile/basic
PATCH /me/profile/lifestyle
PATCH /me/profile/relationship-intent
PATCH /me/profile/self-intro

GET   /me/interests
PUT   /me/interests

GET   /me/photos
POST  /me/photos/upload-token
POST  /me/photos
PATCH /me/photos/{photoId}
DELETE /me/photos/{photoId}

GET   /me/profile/completion

第二十二章 GET /me/profile

响应:

{
  "displayName": "张先生",
  "gender": "male",
  "age": 36,
  "birthDate": "1990-05-12",
  "heightCm": 175,
  "region": {
    "code": "321181",
    "name": "丹阳"
  },
  "maritalStatus": "never_married",
  "childrenStatus": "none",
  "educationCode": "bachelor",
  "occupationCode": "enterprise_employee",
  "workRegionCode": "321181",
  "smokingStatus": "no",
  "drinkingStatus": "occasional",
  "longTermDanyang": "yes",
  "futureDanyang": "yes",
  "relationshipGoal": "marriage",
  "marriagePlan": "within_1_2_years",
  "selfIntro": "……",
  "profileCompletion": 85,
  "reviewStatus": "approved"
}

第二十三章 PATCH /me/profile/basic

请求:

{
  "heightCm": 175,
  "regionCode": "321181",
  "maritalStatus": "never_married",
  "childrenStatus": "none",
  "educationCode": "bachelor",
  "occupationCode": "enterprise_employee"
}

规则:

  • gender不可直接改
  • birthDate不可直接改
  • maritalStatus重要变更可能触发重新审核

第二十四章 PATCH /me/profile/lifestyle

请求:

{
  "workRegionCode": "321181",
  "smokingStatus": "no",
  "drinkingStatus": "occasional",
  "longTermDanyang": "yes",
  "futureDanyang": "yes"
}

第二十五章 PATCH /me/profile/relationship-intent

请求:

{
  "relationshipGoal": "marriage",
  "marriagePlan": "within_1_2_years",
  "acceptMatchmakerRecommendation": true,
  "acceptActivityRecommendation": true
}

第二十六章 PATCH /me/profile/self-intro

请求:

{
  "selfIntro": "性格开朗,平时喜欢运动和旅行……"
}

限制:

  • 长度50~500
  • 禁止联系方式
  • 禁止二维码文本
  • 禁止广告
  • 禁止明显违规内容

修改后:

进入重新审核。

响应:

{
  "saved": true,
  "reviewRequired": true
}

第二十七章 GET /me/interests

响应:

{
  "selected": [
    "travel",
    "sports",
    "reading"
  ],
  "available": [
    {
      "code": "travel",
      "name": "旅行"
    }
  ]
}

第二十八章 PUT /me/interests

请求:

{
  "interestCodes": [
    "travel",
    "sports",
    "reading"
  ]
}

限制:

最多8项。


第二十九章 POST /me/photos/upload-token

请求:

{
  "fileType": "image/jpeg",
  "purpose": "profile_photo"
}

响应:

{
  "uploadUrl": "...",
  "fileKey": "users/usr_xxx/xxx.jpg",
  "expiresIn": 600
}

第三十章 POST /me/photos

图片上传对象存储后登记。

请求:

{
  "fileKey": "users/usr_xxx/xxx.jpg",
  "photoType": "avatar"
}

响应:

{
  "photoId": "pho_xxx",
  "reviewStatus": "pending"
}

第三十一章 PATCH /me/photos/{photoId}

用于:

  • 排序
  • 设主头像

示例:

{
  "sortOrder": 1
}

第三十二章 DELETE /me/photos/{photoId}

限制:

如果删除当前唯一主头像:

拒绝或要求先上传新头像。

错误:

PRIMARY_AVATAR_REQUIRED

第三十三章 择偶条件接口

GET /me/preferences
PUT /me/preferences

第三十四章 GET /me/preferences

响应:

{
  "age": {
    "min": 28,
    "max": 35,
    "priority": "required"
  },
  "height": {
    "min": 160,
    "max": 175,
    "priority": "preferred"
  },
  "regions": [
    "321181"
  ],
  "regionPriority": "required",
  "maritalStatuses": [
    "never_married",
    "divorced"
  ],
  "maritalPriority": "preferred",
  "minEducationCode": "college",
  "educationPriority": "preferred",
  "childrenAcceptance": "case_by_case",
  "childrenPriority": "preferred"
}

第三十五章 PUT /me/preferences

请求结构与GET基本一致。

服务端校验:

  • 年龄区间合法
  • 身高区间合法
  • priority只能required/preferred
  • 字典值有效

第三十六章 资料提交审核接口

POST /me/profile/submit-review
GET  /me/profile/review-status

第三十七章 POST /me/profile/submit-review

Header:

Idempotency-Key

请求:

{}

服务端校验:

  • 已实名
  • 基础资料完整
  • 有主头像
  • 择偶条件完成
  • 个人介绍合法

响应:

{
  "reviewTaskId": "rev_xxx",
  "status": "pending"
}

第三十八章 提交审核错误码

PROFILE_INCOMPLETE
REAL_NAME_REQUIRED
AVATAR_REQUIRED
PREFERENCE_INCOMPLETE
REVIEW_ALREADY_PENDING
ACCOUNT_LIMITED

第三十九章 GET /me/profile/review-status

响应:

{
  "status": "need_edit",
  "items": [
    {
      "itemType": "avatar",
      "status": "need_edit",
      "reasonCode": "AVATAR_NOT_CLEAR",
      "reasonText": "当前照片无法清楚确认本人"
    },
    {
      "itemType": "self_intro",
      "status": "approved"
    }
  ]
}

第四十章 首页推荐接口

GET /recommendations/today
POST /recommendations/{targetUserId}/pass

喜欢不放推荐模块,统一走relation模块。


第四十一章 GET /recommendations/today

请求:

?cursor=xxx&limit=6

响应:

{
  "items": [
    {
      "user": {
        "id": "usr_2",
        "displayName": "王女士",
        "age": 32,
        "heightCm": 165,
        "regionName": "丹阳",
        "educationName": "本科",
        "occupationName": "教师",
        "maritalStatusName": "未婚",
        "avatarUrl": "signed-url",
        "verified": true,
        "reviewed": true
      },
      "level": "high",
      "reasons": [
        "年龄符合双方要求",
        "都希望长期在丹阳生活",
        "婚恋计划比较一致"
      ],
      "relationStatus": "neutral"
    }
  ],
  "dailyLimit": 6,
  "todayViewed": 2,
  "nextCursor": "xxx",
  "hasMore": true
}

第四十二章 推荐访问限制

如果:

PROFILE_NOT_APPROVED
ACCOUNT_LIMITED
RELATIONSHIP_PAUSED

返回对应错误。


第四十三章 找对象接口

GET /discover/users

Query:

minAge
maxAge
minHeight
maxHeight
regionCode
maritalStatus
educationCode
childrenAcceptance
cursor
limit

第四十四章 GET /discover/users

响应:

{
  "items": [
    {
      "id": "usr_xxx",
      "displayName": "王女士",
      "age": 32,
      "heightCm": 165,
      "regionName": "丹阳",
      "educationName": "本科",
      "occupationName": "教师",
      "maritalStatusName": "未婚",
      "avatarUrl": "...",
      "verified": true
    }
  ],
  "nextCursor": "xxx",
  "hasMore": true
}

第四十五章 用户公开详情接口

GET /users/{userId}/profile

仅返回:

PublicUserProfileDTO

不能返回:

  • 手机号
  • 身份证
  • 完整姓名
  • 精确住址
  • 完整单位

第四十六章 用户详情响应

{
  "id": "usr_xxx",
  "displayName": "王女士",
  "age": 32,
  "heightCm": 165,
  "regionName": "丹阳",
  "educationName": "本科",
  "occupationName": "教师",
  "maritalStatusName": "未婚",
  "childrenStatusName": "无",
  "smokingStatusName": "不吸烟",
  "drinkingStatusName": "偶尔",
  "selfIntro": "……",
  "interests": [
    "旅行",
    "阅读",
    "运动"
  ],
  "photos": [],
  "relationshipGoalName": "以结婚为目的的稳定关系",
  "marriagePlanName": "1~2年内",
  "verified": true,
  "reviewed": true,
  "recommendReasons": [],
  "relationStatus": "neutral",
  "canChat": false
}

第四十七章 Relationship接口总览

POST   /relationships/{targetUserId}/like
DELETE /relationships/{targetUserId}/like

POST   /relationships/{targetUserId}/pass
POST   /relationships/{targetUserId}/block
DELETE /relationships/{targetUserId}/block

GET /relationships/mutual
GET /relationships/liked-by-me
GET /relationships/liked-me

第四十八章 POST /relationships/{targetUserId}/like

Header:

Idempotency-Key

响应非双向:

{
  "relationStatus": "liked",
  "mutualMatch": false
}

响应双向:

{
  "relationStatus": "mutual_match",
  "mutualMatch": true,
  "matchId": "mat_xxx",
  "conversationId": "con_xxx"
}

第四十九章 Like错误码

CANNOT_LIKE_SELF
TARGET_UNAVAILABLE
ALREADY_BLOCKED
BLOCKED_BY_TARGET
PROFILE_NOT_APPROVED
RELATIONSHIP_NOT_SEARCHABLE
ACCOUNT_LIMITED

第五十章 DELETE /relationships/{targetUserId}/like

用途:

取消单向喜欢。

如果已经双向匹配:

不允许通过此接口直接解除。

错误:

MUTUAL_MATCH_EXISTS

应使用:

解除匹配接口。


第五十一章 POST /relationships/{targetUserId}/pass

响应:

{
  "passed": true
}

第五十二章 POST /relationships/{targetUserId}/block

响应:

{
  "blocked": true,
  "conversationClosed": true
}

第五十三章 DELETE /relationships/{targetUserId}/block

响应:

{
  "blocked": false
}

不会自动恢复原match。


第五十四章 GET /relationships/mutual

Cursor分页。

响应:

{
  "items": [
    {
      "matchId": "mat_xxx",
      "user": {},
      "matchedAt": "2026-08-28T10:00:00+08:00",
      "conversationId": "con_xxx"
    }
  ]
}

第五十五章 Match管理接口

用户侧:

GET  /matches/{matchId}
POST /matches/{matchId}/unmatch
POST /matches/{matchId}/getting-to-know
POST /matches/{matchId}/success-request
POST /matches/{matchId}/success-confirm
POST /matches/{matchId}/success-decline

第五十六章 POST /matches/{matchId}/unmatch

请求:

{
  "reasonCode": "not_suitable"
}

响应:

{
  "matchStatus": "unmatched"
}

第五十七章 POST /matches/{matchId}/getting-to-know

请求:

{
  "pauseOtherRecommendations": true
}

响应:

{
  "matchStatus": "getting_to_know",
  "relationshipStatus": "getting_to_know",
  "recommendationEnabled": false
}

第五十八章 POST /matches/{matchId}/success-request

请求:

{}

响应:

{
  "requestId": "succ_xxx",
  "status": "pending"
}

第五十九章 POST /matches/{matchId}/success-confirm

只有对方可确认。

响应:

{
  "matchStatus": "successful",
  "relationshipStatus": "matched_successfully"
}

第六十章 聊天接口总览

REST:

GET /conversations
GET /conversations/{conversationId}
GET /conversations/{conversationId}/messages
POST /conversations/{conversationId}/messages
POST /conversations/{conversationId}/read

实时:

WebSocket


第六十一章 GET /conversations

响应:

{
  "items": [
    {
      "conversationId": "con_xxx",
      "targetUser": {
        "id": "usr_xxx",
        "displayName": "王女士",
        "avatarUrl": "..."
      },
      "lastMessage": "周末有时间吗?",
      "lastMessageAt": "2026-08-28T10:32:00+08:00",
      "unreadCount": 2,
      "canSend": true
    }
  ]
}

第六十二章 GET /conversations/{id}/messages

Query:

?cursor=xxx&limit=30

响应:

{
  "items": [
    {
      "id": "msg_xxx",
      "senderId": "usr_xxx",
      "type": "text",
      "content": "你好",
      "createdAt": "2026-08-28T10:31:00+08:00",
      "status": "sent"
    }
  ],
  "nextCursor": "xxx",
  "hasMore": true
}

第六十三章 POST /conversations/{id}/messages

请求文字:

{
  "clientMessageId": "client_xxx",
  "type": "text",
  "content": "你好,很高兴认识你"
}

图片:

{
  "clientMessageId": "client_xxx",
  "type": "image",
  "fileId": "file_xxx"
}

第六十四章 聊天发送错误码

MATCH_REQUIRED
CONVERSATION_CLOSED
BLOCKED_RELATION
ACCOUNT_LIMITED
TARGET_UNAVAILABLE
MESSAGE_TOO_FREQUENT
MESSAGE_CONTENT_INVALID

第六十五章 POST /conversations/{id}/read

请求:

{
  "lastReadMessageId": "msg_xxx"
}

响应:

{
  "unreadCount": 0
}

第六十六章 未读数量接口

GET /messages/unread-summary

响应:

{
  "chatUnread": 3,
  "systemUnread": 2,
  "totalUnread": 5
}

第六十七章 系统通知接口

GET  /notifications
POST /notifications/{id}/read
POST /notifications/read-all

第六十八章 活动用户接口

GET  /activities
GET  /activities/{activityId}
POST /activities/{activityId}/registrations
GET  /me/activity-registrations
GET  /activities/{activityId}/checkin-token
POST /activities/{activityId}/feedback

第六十九章 GET /activities

Query:

status=upcoming
cursor
limit

响应:

{
  "items": [
    {
      "id": "act_xxx",
      "title": "丹阳青年公益相亲会",
      "coverUrl": "...",
      "startAt": "2026-09-20T14:00:00+08:00",
      "locationName": "丹阳××活动中心",
      "feeType": "free",
      "registrationStatus": "not_applied"
    }
  ]
}

第七十章 GET /activities/{id}

响应:

{
  "id": "act_xxx",
  "title": "丹阳青年公益相亲会",
  "description": "……",
  "organizerName": "××单位",
  "startAt": "2026-09-20T14:00:00+08:00",
  "endAt": "2026-09-20T17:00:00+08:00",
  "locationName": "丹阳××活动中心",
  "locationAddress": "……",
  "minAge": 25,
  "maxAge": 40,
  "needReview": true,
  "status": "registration_open",
  "registrationStatus": "not_applied"
}

第七十一章 POST /activities/{id}/registrations

Header:

Idempotency-Key

请求:

{
  "agreeRules": true,
  "emergencyContact": {
    "name": "张某",
    "phone": "13800000000"
  }
}

紧急联系人是否必填:

由活动配置决定。

响应:

{
  "registrationId": "reg_xxx",
  "status": "pending"
}

第七十二章 报名错误码

ACTIVITY_NOT_OPEN
ACTIVITY_FULL
GENDER_QUOTA_FULL
AGE_NOT_ELIGIBLE
ALREADY_APPLIED
PROFILE_NOT_APPROVED
ACCOUNT_LIMITED

第七十三章 GET /me/activity-registrations

响应:

{
  "items": [
    {
      "registrationId": "reg_xxx",
      "activity": {},
      "status": "approved",
      "checkinStatus": "not_checked_in"
    }
  ]
}

第七十四章 GET /activities/{id}/checkin-token

仅:

报名已通过用户。

响应:

{
  "token": "signed_token",
  "expiresAt": "2026-09-20T15:00:00+08:00"
}

第七十五章 POST /activities/{id}/feedback

请求:

{
  "satisfaction": 5,
  "joinAgain": "yes",
  "interestedUserId": "usr_xxx",
  "comment": "活动组织很好"
}

interestedUserId:

可为空。


第七十六章 公益红娘用户接口

POST /matchmaker/services
GET  /matchmaker/services
GET  /matchmaker/services/{serviceId}
GET  /matchmaker/recommendations
GET  /matchmaker/recommendations/{recommendationId}
POST /matchmaker/services/{serviceId}/supplement

第七十七章 POST /matchmaker/services

请求:

{
  "serviceType": "recommend_partner",
  "description": "希望帮我推荐一些年龄30~35岁的丹阳本地对象"
}

响应:

{
  "serviceId": "mms_xxx",
  "status": "submitted"
}

第七十八章 GET /matchmaker/services/{id}

响应:

{
  "id": "mms_xxx",
  "serviceType": "recommend_partner",
  "status": "in_service",
  "assignedMatchmaker": {
    "displayName": "张老师",
    "organizationName": "××公益服务中心"
  },
  "followups": [
    {
      "time": "2026-08-28T10:00:00+08:00",
      "summary": "正在帮助筛选合适对象"
    }
  ]
}

第七十九章 GET /matchmaker/recommendations

响应:

{
  "items": [
    {
      "id": "mmr_xxx",
      "targetUser": {},
      "reason": "年龄、地区和婚恋计划比较符合",
      "status": "pending_view",
      "createdAt": "..."
    }
  ]
}

第八十章 举报接口

POST /reports
GET  /me/reports
POST /appeals

第八十一章 POST /reports

请求:

{
  "targetUserId": "usr_xxx",
  "reportType": "fraud",
  "description": "对方引导我投资",
  "evidenceFileIds": [
    "file_xxx"
  ]
}

响应:

{
  "reportId": "rep_xxx",
  "status": "pending"
}

第八十二章 举报错误码

CANNOT_REPORT_SELF
REPORT_DUPLICATE
TARGET_NOT_FOUND
REPORT_TYPE_INVALID
EVIDENCE_INVALID

第八十三章 婚恋状态接口

GET   /me/relationship-status
PATCH /me/relationship-status

第八十四章 PATCH /me/relationship-status

请求暂停:

{
  "status": "paused"
}

响应:

{
  "status": "paused",
  "recommendationEnabled": false
}

成功牵手不能通过此接口直接设置。

错误:

SUCCESS_CONFIRMATION_REQUIRED

第八十五章 隐私设置接口

GET   /me/privacy
PATCH /me/privacy

请求:

{
  "visibleInRecommendations": true,
  "visibleInSearch": false,
  "showOccupation": true,
  "showLifestylePhotos": true,
  "receiveActivityRecommendations": true,
  "acceptMatchmakerRecommendations": true
}

第八十六章 黑名单接口

GET /me/blacklist

拉黑/解除拉黑统一走Relationship接口。


第八十七章 意见反馈

POST /feedback

请求:

{
  "type": "feature",
  "description": "希望优化筛选功能",
  "fileIds": [],
  "contactPhone": "13800000000"
}

第八十八章 红娘工作人员认证接口

POST /operator/auth/login
POST /operator/auth/logout
GET  /operator/me

第八十九章 POST /operator/auth/login

请求:

{
  "username": "zhang",
  "password": "******"
}

响应:

{
  "accessToken": "...",
  "operator": {
    "id": "opr_xxx",
    "name": "张老师",
    "organization": {
      "id": "org_xxx",
      "name": "××公益服务中心"
    },
    "roles": [
      "matchmaker"
    ],
    "permissions": [
      "matchmaker.service",
      "matchmaker.user.view"
    ]
  }
}

第九十章 红娘端服务接口

GET  /operator/matchmaker/services
GET  /operator/matchmaker/services/{id}
POST /operator/matchmaker/services/{id}/claim
POST /operator/matchmaker/services/{id}/followups
GET  /operator/matchmaker/services/{id}/candidates
POST /operator/matchmaker/services/{id}/recommendations
POST /operator/matchmaker/services/{id}/complete

第九十一章 GET /operator/matchmaker/services

Query:

status
page
pageSize

响应:

{
  "items": [
    {
      "id": "mms_xxx",
      "user": {
        "id": "usr_xxx",
        "displayName": "张先生",
        "age": 36,
        "regionName": "丹阳"
      },
      "serviceType": "recommend_partner",
      "status": "submitted",
      "createdAt": "..."
    }
  ],
  "total": 28
}

第九十二章 POST /operator/matchmaker/services/{id}/claim

权限:

matchmaker.service

响应:

{
  "claimed": true,
  "status": "assigned"
}

并发失败:

SERVICE_ALREADY_CLAIMED

第九十三章 GET /operator/matchmaker/services/{id}/candidates

响应:

{
  "items": [
    {
      "user": {},
      "matchLevel": "high",
      "reasons": [
        "年龄符合双方要求",
        "地区符合"
      ]
    }
  ]
}

第九十四章 POST /operator/matchmaker/services/{id}/recommendations

请求:

{
  "targetUserId": "usr_xxx",
  "reason": "年龄、地区和婚恋计划比较符合"
}

服务端必须验证:

  • target仍可推荐
  • 未拉黑
  • 审核正常
  • 不违反双方required条件

第九十五章 管理后台认证

可复用:

/operator/auth/*

通过权限区分红娘与管理员。

也可以保持:

/admin/auth/login

但不建议维护两套完全不同的账号体系。

推荐:

一个Operator账号系统,多角色、多权限。


第九十六章 管理后台工作台

GET /admin/dashboard

响应:

{
  "pendingReviews": 12,
  "pendingReports": 2,
  "pendingMatchmakerAssignments": 5,
  "pendingActivityRegistrations": 16,
  "newUsersToday": 18,
  "mutualMatchesToday": 7
}

第九十七章 后台用户管理

GET   /admin/users
GET   /admin/users/{userId}
PATCH /admin/users/{userId}/status
GET   /admin/users/{userId}/sensitive-identity

第九十八章 GET /admin/users

Query:

keyword
gender
regionCode
verificationStatus
reviewStatus
relationshipStatus
accountStatus
riskLevel
page
pageSize

第九十九章 GET /admin/users/{id}

根据权限返回:

AdminUserDTO

不自动包含敏感实名。


第一百章 GET /admin/users/{id}/sensitive-identity

权限:

user.sensitive.view

请求Header可要求:

X-Access-Reason: 审核身份异常

响应:

{
  "realName": "张三",
  "idNumberMasked": "320***********1234"
}

如果业务确实需要完整身份证:

建议单独更高权限接口。

每次访问写:

sensitive_access_logs。


第一百零一章 审核后台接口

GET  /admin/reviews
GET  /admin/reviews/{reviewId}
POST /admin/reviews/{reviewId}/claim
POST /admin/reviews/{reviewId}/approve
POST /admin/reviews/{reviewId}/need-edit
POST /admin/reviews/{reviewId}/reject

第一百零二章 POST /admin/reviews/{id}/claim

权限:

review.process

响应:

{
  "status": "processing",
  "assignedOperatorId": "opr_xxx"
}

第一百零三章 POST /admin/reviews/{id}/approve

请求:

{
  "items": [
    {
      "itemType": "avatar",
      "status": "approved"
    }
  ],
  "comment": "资料正常"
}

服务端:

  • 完成审核
  • 更新Profile审核状态
  • 触发ProfileApproved事件
  • 发送通知

第一百零四章 POST /admin/reviews/{id}/need-edit

请求:

{
  "items": [
    {
      "itemType": "avatar",
      "status": "need_edit",
      "reasonCode": "AVATAR_NOT_CLEAR",
      "comment": "请上传清晰正面照片"
    }
  ]
}

第一百零五章 匹配管理后台

GET /admin/matches/stats
GET /admin/matches
GET /admin/match-rules
POST /admin/match-rules
POST /admin/match-rules/{id}/activate

第一百零六章 GET /admin/match-rules

响应:

{
  "activeVersion": 3,
  "rules": [
    {
      "version": 3,
      "status": "active",
      "weights": {
        "age": 15,
        "region": 15,
        "marital": 10
      },
      "minimumScore": 60
    }
  ]
}

第一百零七章 POST /admin/match-rules

权限:

match.rule.manage

请求:

{
  "weights": {
    "age": 15,
    "region": 15,
    "marital": 10,
    "children": 10,
    "education": 5,
    "height": 5,
    "marriagePlan": 15,
    "settlement": 10,
    "lifestyle": 10,
    "interest": 5
  },
  "minimumScore": 60
}

必须校验总分:

100。


第一百零八章 活动后台接口

GET    /admin/activities
POST   /admin/activities
GET    /admin/activities/{id}
PATCH  /admin/activities/{id}
POST   /admin/activities/{id}/publish
POST   /admin/activities/{id}/cancel

GET    /admin/activities/{id}/registrations
POST   /admin/activity-registrations/{registrationId}/approve
POST   /admin/activity-registrations/{registrationId}/reject
POST   /admin/activities/{id}/checkin
GET    /admin/activities/{id}/feedback

第一百零九章 POST /admin/activities

请求:

{
  "title": "丹阳青年公益相亲会",
  "coverFileId": "file_xxx",
  "description": "……",
  "organizerOrgId": "org_xxx",
  "startAt": "2026-09-20T14:00:00+08:00",
  "endAt": "2026-09-20T17:00:00+08:00",
  "locationName": "丹阳××活动中心",
  "locationAddress": "……",
  "maleLimit": 50,
  "femaleLimit": 50,
  "totalLimit": 100,
  "minAge": 25,
  "maxAge": 40,
  "registrationStartAt": "...",
  "registrationEndAt": "...",
  "needReview": true
}

第一百一十章 报名审核接口

批准:

POST /admin/activity-registrations/{id}/approve

响应:

{
  "status": "approved"
}

如果名额已满:

ACTIVITY_FULL

必须事务控制。


第一百一十一章 活动签到后台

POST /admin/activities/{id}/checkin

请求:

{
  "checkinToken": "signed-token"
}

响应:

{
  "user": {
    "displayName": "张先生",
    "phoneMasked": "138****1234"
  },
  "status": "checked_in",
  "checkinAt": "..."
}

重复签到:

ALREADY_CHECKED_IN

第一百一十二章 红娘后台管理

GET  /admin/matchmaker/services
POST /admin/matchmaker/services/{id}/assign
GET  /admin/matchmakers
PATCH /admin/matchmakers/{id}/status

第一百一十三章 POST /admin/matchmaker/services/{id}/assign

请求:

{
  "operatorId": "opr_xxx"
}

权限:

matchmaker.assign

第一百一十四章 举报风控后台接口

GET  /admin/reports
GET  /admin/reports/{id}
POST /admin/reports/{id}/resolve
GET  /admin/risk/users/{userId}
POST /admin/risk/users/{userId}/actions
POST /admin/risk/actions/{actionId}/revoke
GET  /admin/appeals
POST /admin/appeals/{id}/resolve

第一百一十五章 POST /admin/reports/{id}/resolve

请求:

{
  "resultCode": "confirmed_fraud",
  "action": "temporary_suspend",
  "comment": "经核实存在诱导投资行为"
}

服务端:

  • 更新Report
  • 创建RiskEvent
  • 创建RiskAction
  • 更新User状态
  • 写AuditLog
  • 必要时关闭聊天与推荐

第一百一十六章 风控处理权限

risk.report.process
risk.user.limit
risk.user.suspend
risk.user.ban

不同操作应可拆权限。


第一百一十七章 组织管理接口

GET    /admin/organizations
POST   /admin/organizations
GET    /admin/organizations/{id}
PATCH  /admin/organizations/{id}

第一百一十八章 工作人员管理接口

GET    /admin/operators
POST   /admin/operators
GET    /admin/operators/{id}
PATCH  /admin/operators/{id}
POST   /admin/operators/{id}/reset-password
POST   /admin/operators/{id}/roles

第一百一十九章 权限管理接口

GET  /admin/roles
POST /admin/roles
GET  /admin/permissions
PUT  /admin/roles/{roleId}/permissions

第一百二十章 数据统计接口

GET /admin/analytics/overview
GET /admin/analytics/users
GET /admin/analytics/matches
GET /admin/analytics/activities
GET /admin/analytics/matchmaker
GET /admin/analytics/risk

第一百二十一章 数据统计时间参数

统一:

startDate
endDate

例如:

?startDate=2026-08-01&endDate=2026-08-31

第一百二十二章 配置接口

GET   /admin/configs
PATCH /admin/configs/{key}

普通前端可读取公开配置:

GET /app/config

响应:

{
  "dailyRecommendationLimit": 6,
  "maxProfilePhotos": 6,
  "maxInterestTags": 8,
  "activityEnabled": true,
  "matchmakerEnabled": true,
  "chatImageEnabled": true
}

第一百二十三章 文件通用接口

建议:

POST /files/upload-token
GET  /files/{fileId}/access-url

不能让用户通过fileId任意获取别人隐私文件。

必须验证业务权限。


第一百二十四章 WebSocket连接

建议路径:

/wss/chat

或:

/ws

建立连接后认证。

消息事件:

message.new
message.read
conversation.closed
match.created
notification.new
account.status_changed

第一百二十五章 WebSocket message.new示例

{
  "event": "message.new",
  "data": {
    "conversationId": "con_xxx",
    "message": {
      "id": "msg_xxx",
      "senderId": "usr_xxx",
      "type": "text",
      "content": "你好",
      "createdAt": "..."
    }
  }
}

第一百二十六章 WebSocket安全原则

必须:

  • Token认证
  • 连接绑定userId
  • 服务端决定订阅权限
  • 不允许客户端自行订阅任意conversationId
  • account limited后主动断开或限制

第一百二十七章 统一错误码分类

建议前缀:

AUTH_
USER_
VERIFY_
PROFILE_
REVIEW_
MATCH_
RELATION_
MESSAGE_
ACTIVITY_
MATCHMAKER_
RISK_
PERMISSION_
SYSTEM_

第一百二十八章 通用错误码

OK
INVALID_ARGUMENT
UNAUTHORIZED
FORBIDDEN
RESOURCE_NOT_FOUND
RATE_LIMITED
DUPLICATE_ACTION
CONFLICT
INTERNAL_ERROR
SERVICE_UNAVAILABLE
MAINTENANCE

第一百二十九章 用户状态错误

ACCOUNT_LIMITED
ACCOUNT_SUSPENDED
ACCOUNT_BANNED
ACCOUNT_CLOSED

第一百三十章 资料错误

REAL_NAME_REQUIRED
PROFILE_INCOMPLETE
PROFILE_NOT_APPROVED
PROFILE_REVIEW_PENDING
AVATAR_REQUIRED
PREFERENCE_INCOMPLETE

第一百三十一章 匹配错误

TARGET_UNAVAILABLE
CANNOT_LIKE_SELF
ALREADY_LIKED
MUTUAL_MATCH_EXISTS
MATCH_NOT_FOUND
MATCH_NOT_ACTIVE

第一百三十二章 消息错误

MATCH_REQUIRED
CONVERSATION_NOT_FOUND
CONVERSATION_CLOSED
MESSAGE_TOO_FREQUENT
MESSAGE_CONTENT_INVALID

第一百三十三章 活动错误

ACTIVITY_NOT_FOUND
ACTIVITY_NOT_OPEN
ACTIVITY_FULL
GENDER_QUOTA_FULL
AGE_NOT_ELIGIBLE
ALREADY_APPLIED
REGISTRATION_NOT_APPROVED
ALREADY_CHECKED_IN

第一百三十四章 权限错误

PERMISSION_DENIED
ORGANIZATION_SCOPE_DENIED
SENSITIVE_ACCESS_DENIED

第一百三十五章 运营后台组织范围

机构管理员只能查看:

本机构授权范围。

API层不能只靠前端传:

organizationId

服务端从operator上下文判断。


第一百三十六章 请求参数校验

统一校验:

  • 字符长度
  • Enum
  • ID格式
  • 日期范围
  • 上传文件类型
  • 分页上限
  • 文本内容
  • 用户状态

不能依赖数据库报错给用户。


第一百三十七章 pageSize上限

后台:

max pageSize = 100

用户动态列表:

max limit = 50

避免恶意一次请求全库。


第一百三十八章 API日志

记录:

  • method
  • path
  • status
  • requestId
  • operator/user匿名ID
  • duration

不能记录:

  • 密码
  • Token
  • 身份证
  • 聊天正文
  • 举报完整内容

第一百三十九章 敏感接口审计

这些接口必须额外审计:

/admin/users/{id}/sensitive-identity
/admin/reports/{id}
/admin/risk/users/{id}/actions
/admin/roles/{id}/permissions
/admin/operators/*

第一百四十章 API版本策略

V1统一:

/api/v1

未来重大破坏性变更:

/api/v2

不要:

一个接口字段今天叫status,明天直接改成state。

优先保持向后兼容。


第一百四十一章 删除接口原则

婚恋核心数据不提供普通物理删除API。

例如:

不设计:

DELETE /admin/users/{id}

而是:

PATCH /admin/users/{id}/status

改为:

closed / banned。


第一百四十二章 API DTO原则

严禁Controller直接返回数据库Entity。

必须使用:

Request DTO
Response DTO

例如:

PublicUserProfileResponse
SelfProfileResponse
AdminUserResponse
MatchmakerUserResponse

第一百四十三章 前后台DTO绝不能复用敏感全集

错误:

UserDTO

所有地方都返回。

正确:

UserSummaryResponse
PublicProfileResponse
SelfProfileResponse
AdminProfileResponse
SensitiveIdentityResponse

第一百四十四章 推荐理由归属

推荐理由由:

Match Service生成。

接口返回结构化信息。

前端不自己算。

红娘推荐也应尽量复用同一匹配服务理由。


第一百四十五章 REST动作接口命名

纯CRUD优先资源式。

业务动作可以使用:

/approve
/reject
/claim
/publish
/checkin

不要为了“REST纯洁性”把业务动作设计得难懂。

清晰优先。


第一百四十六章 接口幂等验收

必须测试:

  1. 连续点击两次喜欢
  2. 连续两次提交报名
  3. 同一举报重复提交
  4. 双击资料提交审核
  5. 签到码扫码两次
  6. 弱网消息重发

最终不能生成重复核心数据。


第一百四十七章 权限验收

必须测试:

  • 普通用户访问admin接口
  • 红娘查看完整身份证
  • 活动管理员封禁用户
  • 审核员修改角色权限
  • 不属于该机构的数据访问
  • 手工构造他人conversationId

必须返回:

401 / 403 / 业务权限错误。


第一百四十八章 状态验收

必须测试:

审核中用户

访问:

/recommendations/today

返回:

PROFILE_NOT_APPROVED

被封禁用户

发送聊天:

ACCOUNT_BANNED

已拉黑

发送聊天:

BLOCKED_RELATION

第一百四十九章 推荐API性能目标

建议:

GET /recommendations/today
P95 < 1.5s

普通GET:

P95 < 500ms

后台复杂统计:

P95 < 2s

初期足够。


第一百五十章 API开发顺序

第一阶段:

Auth
Verification
Profile
Preferences
Review

第二阶段:

Recommendations
Relationships
Matches
Messaging

第三阶段:

Activities
Matchmaker
Risk
Notifications

第四阶段:

Admin
Analytics
Config

第一百五十一章 最核心的端到端接口链

用户第一次使用:

POST /auth/wechat/login
↓
POST /auth/phone/bind
↓
POST /verification/real-name
↓
PATCH /me/profile/basic
↓
PATCH /me/profile/lifestyle
↓
POST /me/photos
↓
PATCH /me/profile/relationship-intent
↓
PUT /me/preferences
↓
POST /me/profile/submit-review

审核员:

GET /admin/reviews
↓
POST /admin/reviews/{id}/claim
↓
POST /admin/reviews/{id}/approve

用户:

GET /recommendations/today
↓
GET /users/{id}/profile
↓
POST /relationships/{id}/like
↓
Mutual Match
↓
GET /conversations
↓
POST /conversations/{id}/messages

这就是V1.0最核心的API闭环。


第一百五十二章 API最终设计原则

整个REST API必须坚持:

接口语义稳定。

用户状态由服务端判断。

敏感字段绝不进入普通DTO。

所有关键动作必须幂等。

所有后台敏感操作必须鉴权和审计。

前端不能靠猜测接口结果推进关键状态。

核心业务错误使用明确错误码。

API围绕用户任务设计,不围绕数据库表机械暴露。

V1.0最终要求达到:

微信小程序、公益红娘工作台和运营管理后台都可以基于同一套稳定、清晰、安全的服务端接口完成完整业务闭环,同时为后续升级保留足够扩展空间。