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

3140 lines
40 KiB
Markdown
Raw Permalink Normal View History

> **⚠️ 部分取代(2026-09-18 头注)**:本文件为 V1.0 REST API 全量规范。V1.1 增量(Banner、
> 服务站、预约、咨询、本地资格、首页聚合等)以 `docs/善缘丹阳 V1.1 数据库与API增量设计.md` 为准,
> 路径收敛以 `docs/api/API_INVENTORY.md` 为准。本文件仍是后端代码注释与契约测试援引的协议出处
> (如 WebSocket 事件信封第 125 章),该部分继续有效。
2026-09-09 22:05:00 +08:00
# 丹阳公益婚恋服务平台
# 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最终要求达到:
> 微信小程序、公益红娘工作台和运营管理后台都可以基于同一套稳定、清晰、安全的服务端接口完成完整业务闭环,同时为后续升级保留足够扩展空间。