Files
danyang-match/REST API 接口详细设计规范.md
WorkBuddy 16538d7af5 chore(docs): V1.0 前端设计文档归档至 docs/archive/design-v1.0;为仍被援引的 V1.0 总纲文档加取代头注
- git mv 4 份 UI 类文档(UIUX 视觉规范/组件库与 Design Token/高保真原型/页面级功能清单)入档,
  附 README 说明取代关系:UI 域唯一基线为 docs/superpowers/specs/2026-09-13-* 规格
- 根目录两份 V1.0 WorkBuddy 提示词/总指令:加「已被 V1.1 整合版取代」头注,保留原位
  (AGENTS_SUMMARY 与 Recovery 报告仍援引其行号)
- REST API 规范:加「部分取代」头注(V1.1 增量以数据库与API增量设计为准;WebSocket 章节仍为协议出处)
- 根 CHANGELOG.md:加指针指向 docs/V1_1_CHANGELOG.md
- V1.0 业务设计 12 份与部署运维方案按用户决定保留原位不动
2026-09-18 20:25:58 +08:00

3140 lines
40 KiB
Markdown
Raw Permalink 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.
> **⚠️ 部分取代(2026-09-18 头注)**:本文件为 V1.0 REST API 全量规范。V1.1 增量(Banner、
> 服务站、预约、咨询、本地资格、首页聚合等)以 `docs/善缘丹阳 V1.1 数据库与API增量设计.md` 为准,
> 路径收敛以 `docs/api/API_INVENTORY.md` 为准。本文件仍是后端代码注释与契约测试援引的协议出处
> (如 WebSocket 事件信封第 125 章),该部分继续有效。
# 丹阳公益婚恋服务平台
# V1.0 REST API 接口详细设计规范
版本:V1.0
协议:HTTPS + REST
实时通信:WebSocket
基础路径:`/api/v1`
适用范围:微信小程序用户端、公益红娘工作台、运营管理后台
---
# 第一章 API设计目标
本规范用于统一:
- REST路径
- HTTP方法
- 请求参数
- 响应结构
- 分页规范
- 错误码
- 权限校验
- 幂等机制
- 用户状态限制
- 数据脱敏
- 后台操作审计
目标是做到:
> 前端知道怎么调用。
> 后端知道怎么实现。
> 测试知道怎么验收。
> 后续升级不会因为接口随意变化造成大量返工。
---
# 第二章 基础URL
生产环境示例:
```text
https://api.example.com/api/v1
```
实际正式域名在部署阶段确定。
用户API:
```text
/api/v1/*
```
红娘工作台:
```text
/api/v1/operator/*
```
管理后台:
```text
/api/v1/admin/*
```
---
# 第三章 HTTPS要求
所有生产API:
> 必须HTTPS。
禁止:
- HTTP明文登录
- HTTP上传敏感信息
- 在URL Query中传Token
- 在URL中传身份证、手机号等敏感数据
---
# 第四章 HTTP方法规范
统一:
```text
GET 查询
POST 创建/业务动作
PUT 整体修改
PATCH 局部修改
DELETE 删除/撤销
```
V1实际业务中优先:
```text
GET
POST
PATCH
DELETE
```
---
# 第五章 API统一响应结构
成功:
```json
{
"success": true,
"code": "OK",
"message": "success",
"data": {}
}
```
错误:
```json
{
"success": false,
"code": "PROFILE_NOT_APPROVED",
"message": "当前资料尚未通过审核",
"data": null
}
```
---
# 第六章 Trace ID
每个响应建议返回:
```text
X-Request-Id
```
错误响应也可包含:
```json
{
"requestId": "req_xxx"
}
```
方便排查问题。
---
# 第七章 Authentication Header
用户:
```text
Authorization: Bearer <access_token>
```
工作人员同样:
```text
Authorization: Bearer <operator_token>
```
两类Token不可混用。
---
# 第八章 Idempotency Key
以下接口必须支持:
```text
Idempotency-Key
```
例如:
```text
Idempotency-Key: 8f52...
```
适用:
- 提交审核
- 喜欢
- 活动报名
- 红娘申请
- 举报
- 签到
- 成功牵手请求
---
# 第九章 分页规范
后台列表:
```text
?page=1&pageSize=20
```
响应:
```json
{
"items": [],
"page": 1,
"pageSize": 20,
"total": 128
}
```
聊天、推荐等动态列表:
> Cursor分页。
例如:
```text
?cursor=xxx&limit=20
```
返回:
```json
{
"items": [],
"nextCursor": "xxx",
"hasMore": true
}
```
---
# 第十章 用户认证接口总览
```text
POST /auth/wechat/login
POST /auth/phone/bind
POST /auth/refresh
POST /auth/logout
GET /me/status
```
---
# 第十一章 POST /auth/wechat/login
用途:
> 微信小程序登录。
请求:
```json
{
"code": "wx_login_code"
}
```
响应:
```json
{
"accessToken": "xxx",
"refreshToken": "xxx",
"expiresIn": 7200,
"user": {
"id": "usr_xxx",
"phoneBound": false,
"verified": false,
"profileCompletionStatus": "not_started",
"reviewStatus": "not_submitted",
"accountStatus": "normal",
"relationshipStatus": "searching"
}
}
```
---
# 第十二章 登录错误码
```text
WECHAT_LOGIN_FAILED
ACCOUNT_BANNED
ACCOUNT_CLOSED
AUTH_PROVIDER_ERROR
```
---
# 第十三章 POST /auth/phone/bind
请求:
优先微信手机号授权:
```json
{
"phoneCode": "wx_phone_code"
}
```
备用验证码模式:
```json
{
"phone": "13800000000",
"smsCode": "123456"
}
```
响应:
```json
{
"phoneBound": true,
"phoneMasked": "138****0000"
}
```
错误:
```text
PHONE_ALREADY_BOUND
PHONE_INVALID
SMS_CODE_INVALID
```
---
# 第十四章 POST /auth/refresh
请求:
```json
{
"refreshToken": "xxx"
}
```
响应:
```json
{
"accessToken": "new_token",
"refreshToken": "new_refresh_token",
"expiresIn": 7200
}
```
---
# 第十五章 POST /auth/logout
登录用户。
请求体:
```json
{}
```
响应:
```json
{
"loggedOut": true
}
```
服务端同时撤销当前会话。
---
# 第十六章 GET /me/status
这是前端路由守卫核心接口。
响应:
```json
{
"id": "usr_xxx",
"phoneBound": true,
"realNameVerified": true,
"profileCompletionStatus": "completed",
"reviewStatus": "approved",
"accountStatus": "normal",
"relationshipStatus": "searching",
"recommendationEnabled": true,
"visibleInSearch": true
}
```
---
# 第十七章 实名认证接口总览
```text
GET /verification/status
POST /verification/real-name
```
---
# 第十八章 GET /verification/status
响应:
```json
{
"status": "verified",
"verifiedAt": "2026-08-28T10:00:00+08:00"
}
```
不能返回:
- 完整姓名
- 身份证号码
---
# 第十九章 POST /verification/real-name
请求:
```json
{
"realName": "张三",
"idNumber": "320xxxxxxxxxxxxx"
}
```
响应成功:
```json
{
"status": "verified",
"adult": true,
"gender": "male",
"birthDate": "1990-05-12"
}
```
---
# 第二十章 实名错误码
```text
REAL_NAME_MISMATCH
ID_NUMBER_INVALID
UNDER_18
VERIFICATION_FAILED
VERIFICATION_RATE_LIMITED
ALREADY_VERIFIED
```
---
# 第二十一章 用户资料接口总览
```text
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
响应:
```json
{
"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
请求:
```json
{
"heightCm": 175,
"regionCode": "321181",
"maritalStatus": "never_married",
"childrenStatus": "none",
"educationCode": "bachelor",
"occupationCode": "enterprise_employee"
}
```
规则:
- gender不可直接改
- birthDate不可直接改
- maritalStatus重要变更可能触发重新审核
---
# 第二十四章 PATCH /me/profile/lifestyle
请求:
```json
{
"workRegionCode": "321181",
"smokingStatus": "no",
"drinkingStatus": "occasional",
"longTermDanyang": "yes",
"futureDanyang": "yes"
}
```
---
# 第二十五章 PATCH /me/profile/relationship-intent
请求:
```json
{
"relationshipGoal": "marriage",
"marriagePlan": "within_1_2_years",
"acceptMatchmakerRecommendation": true,
"acceptActivityRecommendation": true
}
```
---
# 第二十六章 PATCH /me/profile/self-intro
请求:
```json
{
"selfIntro": "性格开朗,平时喜欢运动和旅行……"
}
```
限制:
- 长度50~500
- 禁止联系方式
- 禁止二维码文本
- 禁止广告
- 禁止明显违规内容
修改后:
> 进入重新审核。
响应:
```json
{
"saved": true,
"reviewRequired": true
}
```
---
# 第二十七章 GET /me/interests
响应:
```json
{
"selected": [
"travel",
"sports",
"reading"
],
"available": [
{
"code": "travel",
"name": "旅行"
}
]
}
```
---
# 第二十八章 PUT /me/interests
请求:
```json
{
"interestCodes": [
"travel",
"sports",
"reading"
]
}
```
限制:
> 最多8项。
---
# 第二十九章 POST /me/photos/upload-token
请求:
```json
{
"fileType": "image/jpeg",
"purpose": "profile_photo"
}
```
响应:
```json
{
"uploadUrl": "...",
"fileKey": "users/usr_xxx/xxx.jpg",
"expiresIn": 600
}
```
---
# 第三十章 POST /me/photos
图片上传对象存储后登记。
请求:
```json
{
"fileKey": "users/usr_xxx/xxx.jpg",
"photoType": "avatar"
}
```
响应:
```json
{
"photoId": "pho_xxx",
"reviewStatus": "pending"
}
```
---
# 第三十一章 PATCH /me/photos/{photoId}
用于:
- 排序
- 设主头像
示例:
```json
{
"sortOrder": 1
}
```
---
# 第三十二章 DELETE /me/photos/{photoId}
限制:
如果删除当前唯一主头像:
> 拒绝或要求先上传新头像。
错误:
```text
PRIMARY_AVATAR_REQUIRED
```
---
# 第三十三章 择偶条件接口
```text
GET /me/preferences
PUT /me/preferences
```
---
# 第三十四章 GET /me/preferences
响应:
```json
{
"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
- 字典值有效
---
# 第三十六章 资料提交审核接口
```text
POST /me/profile/submit-review
GET /me/profile/review-status
```
---
# 第三十七章 POST /me/profile/submit-review
Header:
```text
Idempotency-Key
```
请求:
```json
{}
```
服务端校验:
- 已实名
- 基础资料完整
- 有主头像
- 择偶条件完成
- 个人介绍合法
响应:
```json
{
"reviewTaskId": "rev_xxx",
"status": "pending"
}
```
---
# 第三十八章 提交审核错误码
```text
PROFILE_INCOMPLETE
REAL_NAME_REQUIRED
AVATAR_REQUIRED
PREFERENCE_INCOMPLETE
REVIEW_ALREADY_PENDING
ACCOUNT_LIMITED
```
---
# 第三十九章 GET /me/profile/review-status
响应:
```json
{
"status": "need_edit",
"items": [
{
"itemType": "avatar",
"status": "need_edit",
"reasonCode": "AVATAR_NOT_CLEAR",
"reasonText": "当前照片无法清楚确认本人"
},
{
"itemType": "self_intro",
"status": "approved"
}
]
}
```
---
# 第四十章 首页推荐接口
```text
GET /recommendations/today
POST /recommendations/{targetUserId}/pass
```
喜欢不放推荐模块,统一走relation模块。
---
# 第四十一章 GET /recommendations/today
请求:
```text
?cursor=xxx&limit=6
```
响应:
```json
{
"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
}
```
---
# 第四十二章 推荐访问限制
如果:
```text
PROFILE_NOT_APPROVED
ACCOUNT_LIMITED
RELATIONSHIP_PAUSED
```
返回对应错误。
---
# 第四十三章 找对象接口
```text
GET /discover/users
```
Query:
```text
minAge
maxAge
minHeight
maxHeight
regionCode
maritalStatus
educationCode
childrenAcceptance
cursor
limit
```
---
# 第四十四章 GET /discover/users
响应:
```json
{
"items": [
{
"id": "usr_xxx",
"displayName": "王女士",
"age": 32,
"heightCm": 165,
"regionName": "丹阳",
"educationName": "本科",
"occupationName": "教师",
"maritalStatusName": "未婚",
"avatarUrl": "...",
"verified": true
}
],
"nextCursor": "xxx",
"hasMore": true
}
```
---
# 第四十五章 用户公开详情接口
```text
GET /users/{userId}/profile
```
仅返回:
> PublicUserProfileDTO
不能返回:
- 手机号
- 身份证
- 完整姓名
- 精确住址
- 完整单位
---
# 第四十六章 用户详情响应
```json
{
"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接口总览
```text
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:
```text
Idempotency-Key
```
响应非双向:
```json
{
"relationStatus": "liked",
"mutualMatch": false
}
```
响应双向:
```json
{
"relationStatus": "mutual_match",
"mutualMatch": true,
"matchId": "mat_xxx",
"conversationId": "con_xxx"
}
```
---
# 第四十九章 Like错误码
```text
CANNOT_LIKE_SELF
TARGET_UNAVAILABLE
ALREADY_BLOCKED
BLOCKED_BY_TARGET
PROFILE_NOT_APPROVED
RELATIONSHIP_NOT_SEARCHABLE
ACCOUNT_LIMITED
```
---
# 第五十章 DELETE /relationships/{targetUserId}/like
用途:
> 取消单向喜欢。
如果已经双向匹配:
> 不允许通过此接口直接解除。
错误:
```text
MUTUAL_MATCH_EXISTS
```
应使用:
> 解除匹配接口。
---
# 第五十一章 POST /relationships/{targetUserId}/pass
响应:
```json
{
"passed": true
}
```
---
# 第五十二章 POST /relationships/{targetUserId}/block
响应:
```json
{
"blocked": true,
"conversationClosed": true
}
```
---
# 第五十三章 DELETE /relationships/{targetUserId}/block
响应:
```json
{
"blocked": false
}
```
不会自动恢复原match。
---
# 第五十四章 GET /relationships/mutual
Cursor分页。
响应:
```json
{
"items": [
{
"matchId": "mat_xxx",
"user": {},
"matchedAt": "2026-08-28T10:00:00+08:00",
"conversationId": "con_xxx"
}
]
}
```
---
# 第五十五章 Match管理接口
用户侧:
```text
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
请求:
```json
{
"reasonCode": "not_suitable"
}
```
响应:
```json
{
"matchStatus": "unmatched"
}
```
---
# 第五十七章 POST /matches/{matchId}/getting-to-know
请求:
```json
{
"pauseOtherRecommendations": true
}
```
响应:
```json
{
"matchStatus": "getting_to_know",
"relationshipStatus": "getting_to_know",
"recommendationEnabled": false
}
```
---
# 第五十八章 POST /matches/{matchId}/success-request
请求:
```json
{}
```
响应:
```json
{
"requestId": "succ_xxx",
"status": "pending"
}
```
---
# 第五十九章 POST /matches/{matchId}/success-confirm
只有对方可确认。
响应:
```json
{
"matchStatus": "successful",
"relationshipStatus": "matched_successfully"
}
```
---
# 第六十章 聊天接口总览
REST:
```text
GET /conversations
GET /conversations/{conversationId}
GET /conversations/{conversationId}/messages
POST /conversations/{conversationId}/messages
POST /conversations/{conversationId}/read
```
实时:
> WebSocket
---
# 第六十一章 GET /conversations
响应:
```json
{
"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:
```text
?cursor=xxx&limit=30
```
响应:
```json
{
"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
请求文字:
```json
{
"clientMessageId": "client_xxx",
"type": "text",
"content": "你好,很高兴认识你"
}
```
图片:
```json
{
"clientMessageId": "client_xxx",
"type": "image",
"fileId": "file_xxx"
}
```
---
# 第六十四章 聊天发送错误码
```text
MATCH_REQUIRED
CONVERSATION_CLOSED
BLOCKED_RELATION
ACCOUNT_LIMITED
TARGET_UNAVAILABLE
MESSAGE_TOO_FREQUENT
MESSAGE_CONTENT_INVALID
```
---
# 第六十五章 POST /conversations/{id}/read
请求:
```json
{
"lastReadMessageId": "msg_xxx"
}
```
响应:
```json
{
"unreadCount": 0
}
```
---
# 第六十六章 未读数量接口
```text
GET /messages/unread-summary
```
响应:
```json
{
"chatUnread": 3,
"systemUnread": 2,
"totalUnread": 5
}
```
---
# 第六十七章 系统通知接口
```text
GET /notifications
POST /notifications/{id}/read
POST /notifications/read-all
```
---
# 第六十八章 活动用户接口
```text
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:
```text
status=upcoming
cursor
limit
```
响应:
```json
{
"items": [
{
"id": "act_xxx",
"title": "丹阳青年公益相亲会",
"coverUrl": "...",
"startAt": "2026-09-20T14:00:00+08:00",
"locationName": "丹阳××活动中心",
"feeType": "free",
"registrationStatus": "not_applied"
}
]
}
```
---
# 第七十章 GET /activities/{id}
响应:
```json
{
"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:
```text
Idempotency-Key
```
请求:
```json
{
"agreeRules": true,
"emergencyContact": {
"name": "张某",
"phone": "13800000000"
}
}
```
紧急联系人是否必填:
> 由活动配置决定。
响应:
```json
{
"registrationId": "reg_xxx",
"status": "pending"
}
```
---
# 第七十二章 报名错误码
```text
ACTIVITY_NOT_OPEN
ACTIVITY_FULL
GENDER_QUOTA_FULL
AGE_NOT_ELIGIBLE
ALREADY_APPLIED
PROFILE_NOT_APPROVED
ACCOUNT_LIMITED
```
---
# 第七十三章 GET /me/activity-registrations
响应:
```json
{
"items": [
{
"registrationId": "reg_xxx",
"activity": {},
"status": "approved",
"checkinStatus": "not_checked_in"
}
]
}
```
---
# 第七十四章 GET /activities/{id}/checkin-token
仅:
> 报名已通过用户。
响应:
```json
{
"token": "signed_token",
"expiresAt": "2026-09-20T15:00:00+08:00"
}
```
---
# 第七十五章 POST /activities/{id}/feedback
请求:
```json
{
"satisfaction": 5,
"joinAgain": "yes",
"interestedUserId": "usr_xxx",
"comment": "活动组织很好"
}
```
interestedUserId:
> 可为空。
---
# 第七十六章 公益红娘用户接口
```text
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
请求:
```json
{
"serviceType": "recommend_partner",
"description": "希望帮我推荐一些年龄30~35岁的丹阳本地对象"
}
```
响应:
```json
{
"serviceId": "mms_xxx",
"status": "submitted"
}
```
---
# 第七十八章 GET /matchmaker/services/{id}
响应:
```json
{
"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
响应:
```json
{
"items": [
{
"id": "mmr_xxx",
"targetUser": {},
"reason": "年龄、地区和婚恋计划比较符合",
"status": "pending_view",
"createdAt": "..."
}
]
}
```
---
# 第八十章 举报接口
```text
POST /reports
GET /me/reports
POST /appeals
```
---
# 第八十一章 POST /reports
请求:
```json
{
"targetUserId": "usr_xxx",
"reportType": "fraud",
"description": "对方引导我投资",
"evidenceFileIds": [
"file_xxx"
]
}
```
响应:
```json
{
"reportId": "rep_xxx",
"status": "pending"
}
```
---
# 第八十二章 举报错误码
```text
CANNOT_REPORT_SELF
REPORT_DUPLICATE
TARGET_NOT_FOUND
REPORT_TYPE_INVALID
EVIDENCE_INVALID
```
---
# 第八十三章 婚恋状态接口
```text
GET /me/relationship-status
PATCH /me/relationship-status
```
---
# 第八十四章 PATCH /me/relationship-status
请求暂停:
```json
{
"status": "paused"
}
```
响应:
```json
{
"status": "paused",
"recommendationEnabled": false
}
```
成功牵手不能通过此接口直接设置。
错误:
```text
SUCCESS_CONFIRMATION_REQUIRED
```
---
# 第八十五章 隐私设置接口
```text
GET /me/privacy
PATCH /me/privacy
```
请求:
```json
{
"visibleInRecommendations": true,
"visibleInSearch": false,
"showOccupation": true,
"showLifestylePhotos": true,
"receiveActivityRecommendations": true,
"acceptMatchmakerRecommendations": true
}
```
---
# 第八十六章 黑名单接口
```text
GET /me/blacklist
```
拉黑/解除拉黑统一走Relationship接口。
---
# 第八十七章 意见反馈
```text
POST /feedback
```
请求:
```json
{
"type": "feature",
"description": "希望优化筛选功能",
"fileIds": [],
"contactPhone": "13800000000"
}
```
---
# 第八十八章 红娘工作人员认证接口
```text
POST /operator/auth/login
POST /operator/auth/logout
GET /operator/me
```
---
# 第八十九章 POST /operator/auth/login
请求:
```json
{
"username": "zhang",
"password": "******"
}
```
响应:
```json
{
"accessToken": "...",
"operator": {
"id": "opr_xxx",
"name": "张老师",
"organization": {
"id": "org_xxx",
"name": "××公益服务中心"
},
"roles": [
"matchmaker"
],
"permissions": [
"matchmaker.service",
"matchmaker.user.view"
]
}
}
```
---
# 第九十章 红娘端服务接口
```text
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:
```text
status
page
pageSize
```
响应:
```json
{
"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
权限:
```text
matchmaker.service
```
响应:
```json
{
"claimed": true,
"status": "assigned"
}
```
并发失败:
```text
SERVICE_ALREADY_CLAIMED
```
---
# 第九十三章 GET /operator/matchmaker/services/{id}/candidates
响应:
```json
{
"items": [
{
"user": {},
"matchLevel": "high",
"reasons": [
"年龄符合双方要求",
"地区符合"
]
}
]
}
```
---
# 第九十四章 POST /operator/matchmaker/services/{id}/recommendations
请求:
```json
{
"targetUserId": "usr_xxx",
"reason": "年龄、地区和婚恋计划比较符合"
}
```
服务端必须验证:
- target仍可推荐
- 未拉黑
- 审核正常
- 不违反双方required条件
---
# 第九十五章 管理后台认证
可复用:
```text
/operator/auth/*
```
通过权限区分红娘与管理员。
也可以保持:
```text
/admin/auth/login
```
但不建议维护两套完全不同的账号体系。
推荐:
> 一个Operator账号系统,多角色、多权限。
---
# 第九十六章 管理后台工作台
```text
GET /admin/dashboard
```
响应:
```json
{
"pendingReviews": 12,
"pendingReports": 2,
"pendingMatchmakerAssignments": 5,
"pendingActivityRegistrations": 16,
"newUsersToday": 18,
"mutualMatchesToday": 7
}
```
---
# 第九十七章 后台用户管理
```text
GET /admin/users
GET /admin/users/{userId}
PATCH /admin/users/{userId}/status
GET /admin/users/{userId}/sensitive-identity
```
---
# 第九十八章 GET /admin/users
Query:
```text
keyword
gender
regionCode
verificationStatus
reviewStatus
relationshipStatus
accountStatus
riskLevel
page
pageSize
```
---
# 第九十九章 GET /admin/users/{id}
根据权限返回:
> AdminUserDTO
不自动包含敏感实名。
---
# 第一百章 GET /admin/users/{id}/sensitive-identity
权限:
```text
user.sensitive.view
```
请求Header可要求:
```text
X-Access-Reason: 审核身份异常
```
响应:
```json
{
"realName": "张三",
"idNumberMasked": "320***********1234"
}
```
如果业务确实需要完整身份证:
> 建议单独更高权限接口。
每次访问写:
> sensitive_access_logs。
---
# 第一百零一章 审核后台接口
```text
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
权限:
```text
review.process
```
响应:
```json
{
"status": "processing",
"assignedOperatorId": "opr_xxx"
}
```
---
# 第一百零三章 POST /admin/reviews/{id}/approve
请求:
```json
{
"items": [
{
"itemType": "avatar",
"status": "approved"
}
],
"comment": "资料正常"
}
```
服务端:
- 完成审核
- 更新Profile审核状态
- 触发ProfileApproved事件
- 发送通知
---
# 第一百零四章 POST /admin/reviews/{id}/need-edit
请求:
```json
{
"items": [
{
"itemType": "avatar",
"status": "need_edit",
"reasonCode": "AVATAR_NOT_CLEAR",
"comment": "请上传清晰正面照片"
}
]
}
```
---
# 第一百零五章 匹配管理后台
```text
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
响应:
```json
{
"activeVersion": 3,
"rules": [
{
"version": 3,
"status": "active",
"weights": {
"age": 15,
"region": 15,
"marital": 10
},
"minimumScore": 60
}
]
}
```
---
# 第一百零七章 POST /admin/match-rules
权限:
```text
match.rule.manage
```
请求:
```json
{
"weights": {
"age": 15,
"region": 15,
"marital": 10,
"children": 10,
"education": 5,
"height": 5,
"marriagePlan": 15,
"settlement": 10,
"lifestyle": 10,
"interest": 5
},
"minimumScore": 60
}
```
必须校验总分:
> 100。
---
# 第一百零八章 活动后台接口
```text
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
请求:
```json
{
"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
}
```
---
# 第一百一十章 报名审核接口
批准:
```text
POST /admin/activity-registrations/{id}/approve
```
响应:
```json
{
"status": "approved"
}
```
如果名额已满:
```text
ACTIVITY_FULL
```
必须事务控制。
---
# 第一百一十一章 活动签到后台
```text
POST /admin/activities/{id}/checkin
```
请求:
```json
{
"checkinToken": "signed-token"
}
```
响应:
```json
{
"user": {
"displayName": "张先生",
"phoneMasked": "138****1234"
},
"status": "checked_in",
"checkinAt": "..."
}
```
重复签到:
```text
ALREADY_CHECKED_IN
```
---
# 第一百一十二章 红娘后台管理
```text
GET /admin/matchmaker/services
POST /admin/matchmaker/services/{id}/assign
GET /admin/matchmakers
PATCH /admin/matchmakers/{id}/status
```
---
# 第一百一十三章 POST /admin/matchmaker/services/{id}/assign
请求:
```json
{
"operatorId": "opr_xxx"
}
```
权限:
```text
matchmaker.assign
```
---
# 第一百一十四章 举报风控后台接口
```text
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
请求:
```json
{
"resultCode": "confirmed_fraud",
"action": "temporary_suspend",
"comment": "经核实存在诱导投资行为"
}
```
服务端:
- 更新Report
- 创建RiskEvent
- 创建RiskAction
- 更新User状态
- 写AuditLog
- 必要时关闭聊天与推荐
---
# 第一百一十六章 风控处理权限
```text
risk.report.process
risk.user.limit
risk.user.suspend
risk.user.ban
```
不同操作应可拆权限。
---
# 第一百一十七章 组织管理接口
```text
GET /admin/organizations
POST /admin/organizations
GET /admin/organizations/{id}
PATCH /admin/organizations/{id}
```
---
# 第一百一十八章 工作人员管理接口
```text
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
```
---
# 第一百一十九章 权限管理接口
```text
GET /admin/roles
POST /admin/roles
GET /admin/permissions
PUT /admin/roles/{roleId}/permissions
```
---
# 第一百二十章 数据统计接口
```text
GET /admin/analytics/overview
GET /admin/analytics/users
GET /admin/analytics/matches
GET /admin/analytics/activities
GET /admin/analytics/matchmaker
GET /admin/analytics/risk
```
---
# 第一百二十一章 数据统计时间参数
统一:
```text
startDate
endDate
```
例如:
```text
?startDate=2026-08-01&endDate=2026-08-31
```
---
# 第一百二十二章 配置接口
```text
GET /admin/configs
PATCH /admin/configs/{key}
```
普通前端可读取公开配置:
```text
GET /app/config
```
响应:
```json
{
"dailyRecommendationLimit": 6,
"maxProfilePhotos": 6,
"maxInterestTags": 8,
"activityEnabled": true,
"matchmakerEnabled": true,
"chatImageEnabled": true
}
```
---
# 第一百二十三章 文件通用接口
建议:
```text
POST /files/upload-token
GET /files/{fileId}/access-url
```
不能让用户通过fileId任意获取别人隐私文件。
必须验证业务权限。
---
# 第一百二十四章 WebSocket连接
建议路径:
```text
/wss/chat
```
或:
```text
/ws
```
建立连接后认证。
消息事件:
```text
message.new
message.read
conversation.closed
match.created
notification.new
account.status_changed
```
---
# 第一百二十五章 WebSocket message.new示例
```json
{
"event": "message.new",
"data": {
"conversationId": "con_xxx",
"message": {
"id": "msg_xxx",
"senderId": "usr_xxx",
"type": "text",
"content": "你好",
"createdAt": "..."
}
}
}
```
---
# 第一百二十六章 WebSocket安全原则
必须:
- Token认证
- 连接绑定userId
- 服务端决定订阅权限
- 不允许客户端自行订阅任意conversationId
- account limited后主动断开或限制
---
# 第一百二十七章 统一错误码分类
建议前缀:
```text
AUTH_
USER_
VERIFY_
PROFILE_
REVIEW_
MATCH_
RELATION_
MESSAGE_
ACTIVITY_
MATCHMAKER_
RISK_
PERMISSION_
SYSTEM_
```
---
# 第一百二十八章 通用错误码
```text
OK
INVALID_ARGUMENT
UNAUTHORIZED
FORBIDDEN
RESOURCE_NOT_FOUND
RATE_LIMITED
DUPLICATE_ACTION
CONFLICT
INTERNAL_ERROR
SERVICE_UNAVAILABLE
MAINTENANCE
```
---
# 第一百二十九章 用户状态错误
```text
ACCOUNT_LIMITED
ACCOUNT_SUSPENDED
ACCOUNT_BANNED
ACCOUNT_CLOSED
```
---
# 第一百三十章 资料错误
```text
REAL_NAME_REQUIRED
PROFILE_INCOMPLETE
PROFILE_NOT_APPROVED
PROFILE_REVIEW_PENDING
AVATAR_REQUIRED
PREFERENCE_INCOMPLETE
```
---
# 第一百三十一章 匹配错误
```text
TARGET_UNAVAILABLE
CANNOT_LIKE_SELF
ALREADY_LIKED
MUTUAL_MATCH_EXISTS
MATCH_NOT_FOUND
MATCH_NOT_ACTIVE
```
---
# 第一百三十二章 消息错误
```text
MATCH_REQUIRED
CONVERSATION_NOT_FOUND
CONVERSATION_CLOSED
MESSAGE_TOO_FREQUENT
MESSAGE_CONTENT_INVALID
```
---
# 第一百三十三章 活动错误
```text
ACTIVITY_NOT_FOUND
ACTIVITY_NOT_OPEN
ACTIVITY_FULL
GENDER_QUOTA_FULL
AGE_NOT_ELIGIBLE
ALREADY_APPLIED
REGISTRATION_NOT_APPROVED
ALREADY_CHECKED_IN
```
---
# 第一百三十四章 权限错误
```text
PERMISSION_DENIED
ORGANIZATION_SCOPE_DENIED
SENSITIVE_ACCESS_DENIED
```
---
# 第一百三十五章 运营后台组织范围
机构管理员只能查看:
> 本机构授权范围。
API层不能只靠前端传:
```text
organizationId
```
服务端从operator上下文判断。
---
# 第一百三十六章 请求参数校验
统一校验:
- 字符长度
- Enum
- ID格式
- 日期范围
- 上传文件类型
- 分页上限
- 文本内容
- 用户状态
不能依赖数据库报错给用户。
---
# 第一百三十七章 pageSize上限
后台:
```text
max pageSize = 100
```
用户动态列表:
```text
max limit = 50
```
避免恶意一次请求全库。
---
# 第一百三十八章 API日志
记录:
- method
- path
- status
- requestId
- operator/user匿名ID
- duration
不能记录:
- 密码
- Token
- 身份证
- 聊天正文
- 举报完整内容
---
# 第一百三十九章 敏感接口审计
这些接口必须额外审计:
```text
/admin/users/{id}/sensitive-identity
/admin/reports/{id}
/admin/risk/users/{id}/actions
/admin/roles/{id}/permissions
/admin/operators/*
```
---
# 第一百四十章 API版本策略
V1统一:
```text
/api/v1
```
未来重大破坏性变更:
```text
/api/v2
```
不要:
> 一个接口字段今天叫status,明天直接改成state。
优先保持向后兼容。
---
# 第一百四十一章 删除接口原则
婚恋核心数据不提供普通物理删除API。
例如:
不设计:
```text
DELETE /admin/users/{id}
```
而是:
```text
PATCH /admin/users/{id}/status
```
改为:
> closed / banned。
---
# 第一百四十二章 API DTO原则
严禁Controller直接返回数据库Entity。
必须使用:
```text
Request DTO
Response DTO
```
例如:
```text
PublicUserProfileResponse
SelfProfileResponse
AdminUserResponse
MatchmakerUserResponse
```
---
# 第一百四十三章 前后台DTO绝不能复用敏感全集
错误:
```text
UserDTO
```
所有地方都返回。
正确:
```text
UserSummaryResponse
PublicProfileResponse
SelfProfileResponse
AdminProfileResponse
SensitiveIdentityResponse
```
---
# 第一百四十四章 推荐理由归属
推荐理由由:
> Match Service生成。
接口返回结构化信息。
前端不自己算。
红娘推荐也应尽量复用同一匹配服务理由。
---
# 第一百四十五章 REST动作接口命名
纯CRUD优先资源式。
业务动作可以使用:
```text
/approve
/reject
/claim
/publish
/checkin
```
不要为了“REST纯洁性”把业务动作设计得难懂。
清晰优先。
---
# 第一百四十六章 接口幂等验收
必须测试:
1. 连续点击两次喜欢
2. 连续两次提交报名
3. 同一举报重复提交
4. 双击资料提交审核
5. 签到码扫码两次
6. 弱网消息重发
最终不能生成重复核心数据。
---
# 第一百四十七章 权限验收
必须测试:
- 普通用户访问admin接口
- 红娘查看完整身份证
- 活动管理员封禁用户
- 审核员修改角色权限
- 不属于该机构的数据访问
- 手工构造他人conversationId
必须返回:
> 401 / 403 / 业务权限错误。
---
# 第一百四十八章 状态验收
必须测试:
### 审核中用户
访问:
```text
/recommendations/today
```
返回:
```text
PROFILE_NOT_APPROVED
```
### 被封禁用户
发送聊天:
```text
ACCOUNT_BANNED
```
### 已拉黑
发送聊天:
```text
BLOCKED_RELATION
```
---
# 第一百四十九章 推荐API性能目标
建议:
```text
GET /recommendations/today
P95 < 1.5s
```
普通GET:
```text
P95 < 500ms
```
后台复杂统计:
```text
P95 < 2s
```
初期足够。
---
# 第一百五十章 API开发顺序
第一阶段:
```text
Auth
Verification
Profile
Preferences
Review
```
第二阶段:
```text
Recommendations
Relationships
Matches
Messaging
```
第三阶段:
```text
Activities
Matchmaker
Risk
Notifications
```
第四阶段:
```text
Admin
Analytics
Config
```
---
# 第一百五十一章 最核心的端到端接口链
用户第一次使用:
```text
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
```
审核员:
```text
GET /admin/reviews
↓
POST /admin/reviews/{id}/claim
↓
POST /admin/reviews/{id}/approve
```
用户:
```text
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最终要求达到:
> 微信小程序、公益红娘工作台和运营管理后台都可以基于同一套稳定、清晰、安全的服务端接口完成完整业务闭环,同时为后续升级保留足够扩展空间。