48 lines
1.8 KiB
Markdown
48 lines
1.8 KiB
Markdown
# Phase 16 Completion Report
|
||||
|
|
|
|||
|
|
## Status
|
|||
|
|
✅ Completed
|
|||
|
|
|
|||
|
|
## Implemented
|
|||
|
|
|
|||
|
|
### P16-T01 ~ P16-T08: 活动互选核心
|
|||
|
|
- [x] V011 迁移:`activity_interests` 表(unique(activity_id, source_user_id, target_user_id))
|
|||
|
|
- [x] `ActivityInterest` 实体 + `ActivityInterestMapper`(4个查询方法)
|
|||
|
|
- [x] `ActivityInterestService` — submitFeedback / activateMutual / getMutualMatches
|
|||
|
|
- [x] `ActivityInterestController` — 3个API端点(含JwtTokenService认证)
|
|||
|
|
- [x] Constants 新增:ACTIVITY_INTEREST_STATUS_EXPRESSED / ACTIVITY_INTEREST_STATUS_MUTUAL
|
|||
|
|
|
|||
|
|
### Miniapp 页面
|
|||
|
|
- [x] U32 活动反馈页 — 满意度+意愿+意向选择
|
|||
|
|
- [x] U36 活动缘分页 — 双向互选结果展示 + 快速聊天
|
|||
|
|
|
|||
|
|
### Admin Web
|
|||
|
|
- [x] A15 活动互选管理页 — 列表 + 互选详情抽屉
|
|||
|
|
- [x] 路由注册:/activities/interests
|
|||
|
|
|
|||
|
|
## Core Invariants 已保护
|
|||
|
|
- ✅ **单向意向保密** — expressed 状态仅表达者可见,目标用户不可查询
|
|||
|
|
- ✅ **仅双向确认后通知** — activateMutual 仅在双方均表达后触发
|
|||
|
|
- ✅ **重复表达幂等** — findByActivityPair 检查,已存在则跳过
|
|||
|
|
- ✅ **仅approved参与者可互选** — getApprovedParticipants 过滤
|
|||
|
|
- ✅ **活动结束后才能反馈** — activity.status == 'ended' 校验
|
|||
|
|
|
|||
|
|
## API 端点(3个)
|
|||
|
|
POST /activities/{id}/feedback(提交反馈+表达意向)
|
|||
|
|
GET /activities/{id}/interests/mutual(获取互选结果)
|
|||
|
|
GET /activities/operator/{id}/interest-stats(统计,管理端)
|
|||
|
|
|
|||
|
|
## Migration
|
|||
|
|
V011__add_activity_interests.sql
|
|||
|
|
|
|||
|
|
## Tests
|
|||
|
|
- `ActivityInterestServiceTest`: 6 个不变量用例
|
|||
|
|
|
|||
|
|
## Project Stats
|
|||
|
|
- Java files: 164 (+6 from Phase 15)
|
|||
|
|
- Test classes: 28 (+1)
|
|||
|
|
- Migration SQL: 11
|
|||
|
|
|
|||
|
|
## Next Phase
|
|||
|
|
Phase 17: 举报与风控(report submission + risk event scoring + risk action: warning/limit/suspend/ban + 实时联动)
|