liuchengsen пре 1 месец
родитељ
комит
5cd1c9c981

+ 252 - 61
docs/01-产品文档.md

@@ -6,7 +6,7 @@
 > **产品形态**:**多端交付策略** - MVP首选Windows独立桌面应用(.exe),后续扩展微信小程序、APP、公众号等多渠道。  
 > **目标用户**:药店采购人员、药师,目标日活20万+。
 >
-> 📅 版本:v1.1-MVP | 📆 更新日期:2026-07-01 | ✅ 状态:开发中
+> 📅 版本:v1.2-MVP | 📆 更新日期:2026-07-11 | ✅ 状态:开发中
 
 ---
 
@@ -148,9 +148,8 @@
 |------|------|
 | GET /api/membership/my | 查询我的会员信息(等级、到期时间、来源等) |
 | GET /api/membership/benefits?level=PLUS | 查询指定等级的权益配置详情 |
-| GET /api/level/list | 获取所有会员等级列表(公开,含定价方案) |
-| GET /api/level/{id} | 获取等级详情(公开) |
-| GET /api/level/my | 获取当前用户等级信息(含配额、到期时间、套餐) |
+| GET /api/membership/levels | 获取所有会员等级列表(公开,含定价方案) |
+| GET /api/membership/levels/{id} | 获取等级详情(公开) |
 
 ### 2.3 爬虫配额体系
 
@@ -412,9 +411,9 @@
 
 | 接口 | 说明 |
 |------|------|
-| GET /api/search-record/history | 获取用户搜索历史 |
-| DELETE /api/search-record/history/{id} | 删除指定搜索记录 |
-| DELETE /api/search-record/history | 清空搜索历史 |
+| POST /api/search-record/history | 保存一次比价搜索记录(桌面端调用) |
+| GET /api/search-record/history | 分页获取用户搜索历史 |
+| GET /api/search-record/history/{id} | 获取指定搜索记录详情 |
 
 #### 关注/收藏列表
 
@@ -427,35 +426,209 @@
 
 **关注信息**:药品名称、规格、厂家、关注时最低价、最低价平台、上次查询价格、价格变动、最后检查时间。
 
-### 2.12 运营管理后台
-
-| 功能 | 接口 |
-|------|------|
-| 邀请配置管理 | GET/PUT /api/admin/invite/config |
-| 邀请配置列表 | GET /api/admin/invite/configs |
-| 手动发放爬虫次数 | POST /api/admin/crawler/grant |
-| 查看发放记录 | GET /api/admin/crawler/grants |
-| 查看邀请记录 | GET /api/admin/invite/rewards |
-| 用户等级调整 | PUT /api/level/user/{userId} |
-| 会员发放/调整 | POST /api/admin/membership/grant |
-| 会员记录查询 | GET /api/admin/memberships |
-| 优惠券发放 | POST /api/coupon/issue |
-| 支付方案管理 | POST/PUT /api/admin/payment/plans |
-| 平台分布统计 | GET /api/admin/crawler/user-detail |
-| 入驻信息审核 | GET/POST /api/admin/license/review |
-| 用户列表管理 | GET /api/admin/users |
-| 用户角色修改 | PUT /api/admin/users/{userId}/role(仅SUPER_ADMIN) |
-| 体验配额配置 | GET/POST/PUT/DELETE /api/admin/trial-quota/*(详见下方) |
-| 操作审计日志 | GET /api/admin/audit-log/*(详见下方) |
-| 邀请转化统计 | GET /api/admin/invite/conversion-stats?userId=1 |
-
-### 2.13 操作审计日志系统
+### 2.12 活动中心
+
+活动中心统一管理三类运营活动:**邀请有礼**、**签到有礼**、**比价抽奖**。
+
+#### 2.12.1 邀请有礼活动
+
+基于邀请裂变系统(见 2.5)的增强版,由活动配置驱动:
+
+- 活动时间窗口内,邀请人成功邀请新用户并通过入驻审核后,双方各获得会员天数奖励
+- 支持运营端配置奖励天数、邀请上限、活动开关
+- 支持撤销邀请奖励(反作弊)和活动窗口内补发
+
+**用户侧接口**:
+
+| 接口 | 说明 |
+|------|------|
+| GET /api/activity/invite/status | 查询邀请有礼活动状态(已获奖励次数、剩余次数等) |
+
+#### 2.12.2 签到有礼活动
+
+每日签到 + 周期达标奖励机制:
+
+- 用户每天可签到一次
+- 每个活动周期内累计签到达到要求天数,自动获得会员天数奖励
+- 支持签到日历查看、签到记录分页
+
+**用户侧接口**:
+
+| 接口 | 说明 |
+|------|------|
+| GET /api/checkin/status | 查询今日签到状态 |
+| POST /api/checkin | 执行签到 |
+| GET /api/checkin/calendar?year=2026&month=7 | 查询当月签到日历 |
+| GET /api/checkin/records | 分页查询签到记录 |
+
+#### 2.12.3 比价抽奖活动
+
+面向高级会员的抽奖运营活动,用户每日首次比价后获得一次抽奖机会。
+
+**参与条件**:高级会员(PRO)及以上 + 入驻信息审核通过,活动时间可配置。
+
+**奖品池示例**:
+
+| 奖项 | 奖品 | 份数 | 权重 | 中奖概率 |
+|------|------|------|------|----------|
+| 特等奖 | iPhone 17 | 0 | 0 | 0%(仅展示) |
+| 一等奖 | 30天高级会员 | 20 | 20 | 0.25% |
+| 二等奖 | 15天高级会员 | 100 | 100 | 1.25% |
+| 三等奖 | 7天高级会员 | 150 | 150 | 1.875% |
+| 四等奖 | 3天高级会员 | 250 | 250 | 3.125% |
+| 五等奖 | 1天高级会员 | 1080 | 1080 | 13.5% |
+| 谢谢惠顾 | 无 | 6400 | 6400 | 80% |
+
+**抽奖限制**:每日仅限抽奖1次,重复抽奖记录违规审计日志。
+
+**用户侧接口**:
+
+| 接口 | 说明 |
+|------|------|
+| GET /api/activity/lottery/status | 查询抽奖活动状态(今日可用机会、资格) |
+| GET /api/activity/lottery/prizes | 获取可抽奖品列表(不含概率权重等敏感信息) |
+| POST /api/activity/lottery/draw | 执行抽奖 |
+| GET /api/activity/lottery/records?limit=20 | 我的抽奖记录 |
+
+#### 2.12.4 统一活动接口
+
+| 接口 | 说明 |
+|------|------|
+| GET /api/activity/available | 获取当前用户可参加的所有活动摘要(三类活动一次返回) |
+| GET /api/activity/rewards?type=INVITE\|CHECKIN\|LOTTERY | 按活动类型分页查询奖励记录 |
+| GET /api/activity/checkin-cycle/status | 签到送会员周期状态 |
+| GET /api/activity/checkin-cycle/rewards | 签到周期奖励记录 |
+
+#### 运营端活动管理接口
+
+| 接口 | 说明 |
+|------|------|
+| GET /api/admin/activity/invite/config | 查询邀请有礼活动配置 |
+| PUT /api/admin/activity/invite/config | 更新邀请有礼活动配置 |
+| POST /api/admin/activity/invite/revoke | 撤销邀请奖励(反作弊) |
+| POST /api/admin/activity/invite/retroactive-grant | 活动窗口内补发邀请奖励 |
+| GET /api/admin/activity/checkin-cycle/config | 查询签到送会员配置 |
+| PUT /api/admin/activity/checkin-cycle/config | 更新签到送会员配置 |
+| GET /api/admin/activity/lottery/config | 查询比价抽奖活动配置 |
+| PUT /api/admin/activity/lottery/config | 更新比价抽奖活动配置 |
+| GET /api/admin/activity/lottery/prizes | 奖品池列表 |
+| POST /api/admin/activity/lottery/prizes | 新增奖品 |
+| PUT /api/admin/activity/lottery/prizes/{id} | 更新奖品 |
+| DELETE /api/admin/activity/lottery/prizes/{id} | 删除奖品 |
+| GET /api/admin/activity/lottery/records | 分页查询所有用户抽奖记录 |
+| GET /api/admin/activity/rewards?type=INVITE\|CHECKIN\|LOTTERY | 按活动类型分页查询奖励记录 |
+
+### 2.13 运营管理后台
+
+#### 用户管理
+
+| 接口 | 说明 |
+|------|------|
+| GET /api/admin/users | 分页查询用户列表(支持按手机号/昵称筛选) |
+| POST /api/admin/users/{userId}/kick | 强制踢出用户(使所有 Token 失效) |
+
+#### 管理员账号管理
+
+| 接口 | 说明 |
+|------|------|
+| GET /api/admin/admins | 管理员列表(分页) |
+| GET /api/admin/admins/{id} | 查询单个管理员 |
+| POST /api/admin/admins | 创建管理员 |
+| PUT /api/admin/admins/{id} | 更新管理员信息 |
+| DELETE /api/admin/admins/{id} | 禁用管理员 |
+| PUT /api/admin/admins/{id}/password | 重置管理员密码 |
+| PUT /api/admin/admins/password | 当前管理员修改自己的密码 |
+| POST /api/admin/admins/{adminId}/kick | 强制退出管理员 |
+
+#### 系统配置管理
+
+| 接口 | 说明 |
+|------|------|
+| GET /api/admin/system-config/list | 分页查询系统配置列表(按类型筛选) |
+| GET /api/admin/system-config/enabled | 查询启用的配置列表 |
+| GET /api/admin/system-config/{id} | 查询单个配置 |
+| GET /api/admin/system-config/by-key | 按配置键精确查询 |
+| POST /api/admin/system-config | 新增配置 |
+| PUT /api/admin/system-config/{id} | 更新配置 |
+| DELETE /api/admin/system-config/{id} | 删除配置 |
+
+> 系统配置支持管理外部 API Key、业务开关等全局参数,按 configType 分组(如 EXTERNAL_API、GENERAL),修改后立即生效。
+
+#### 邀请管理
+
+| 接口 | 说明 |
+|------|------|
+| GET /api/admin/invite/config | 获取当前生效的邀请配置 |
+| PUT /api/admin/invite/config | 更新邀请配置 |
+| GET /api/admin/invite/configs | 分页获取邀请配置列表 |
+| GET /api/admin/invite/config/{id} | 根据ID获取邀请配置 |
+| POST /api/admin/invite/config | 创建新的邀请配置 |
+| PUT /api/admin/invite/config/{id} | 更新指定ID的邀请配置 |
+| DELETE /api/admin/invite/config/{id} | 删除邀请配置 |
+| GET /api/admin/invite/rewards | 查看邀请记录(分页) |
+| GET /api/admin/invite/conversion-stats | 查看邀请转化统计 |
+
+#### 爬虫配额管理
+
+| 接口 | 说明 |
+|------|------|
+| POST /api/admin/crawler/grant | 运营手动发放爬虫次数 |
+| GET /api/admin/crawler/grants | 查看发放记录(分页) |
+| GET /api/admin/crawler/user-detail | 查看用户爬虫使用详情(含平台分布) |
+
+#### 会员管理
+
+| 接口 | 说明 |
+|------|------|
+| POST /api/admin/membership/grant | 发放/调整用户会员等级 |
+| GET /api/admin/membership/memberships | 分页查询会员记录(支持多条件筛选) |
+| GET /api/admin/membership/users | 会员用户快照列表(用户维度) |
+
+#### 入驻信息审核
+
+| 接口 | 说明 |
+|------|------|
+| GET /api/admin/license/review | 审核列表查询(支持按状态/关键词筛选) |
+| POST /api/admin/license | 管理员代填入驻信息 |
+| PUT /api/admin/license/{licenseId} | 管理员编辑入驻信息 |
+| POST /api/admin/license/review | 审核入驻信息(通过/驳回) |
+
+#### 支付方案管理
+
+| 接口 | 说明 |
+|------|------|
+| GET /api/admin/payment/plans | 查询所有支付方案(含已下架) |
+| POST /api/admin/payment/plans | 创建支付方案 |
+| PUT /api/admin/payment/plans/{id} | 更新支付方案 |
+| PUT /api/admin/payment/plans/{id}/status | 上架/下架方案 |
+
+#### 优惠券发放
+
+| 接口 | 说明 |
+|------|------|
+| POST /api/coupon/issue | 发放优惠券(指定已有券批量发放给用户) |
+
+#### 签到管理
+
+| 接口 | 说明 |
+|------|------|
+| GET /api/admin/checkin/config | 获取签到全局配置 |
+| PUT /api/admin/checkin/config | 更新签到全局配置 |
+| GET /api/admin/checkin/stats | 签到统计概览 |
+| GET /api/admin/checkin/records | 分页查询签到记录 |
+| GET /api/admin/checkin/user/{userId}/records | 查询指定用户签到记录 |
+| GET /api/admin/checkin/periods | 签到周期列表 |
+| POST /api/admin/checkin/periods | 创建签到周期 |
+| PUT /api/admin/checkin/periods/{id} | 更新签到周期 |
+| DELETE /api/admin/checkin/periods/{id} | 删除签到周期 |
+
+### 2.14 操作审计日志系统
 
 系统对所有关键操作进行审计记录,支持追溯:
 
 - **记录维度**:操作人、操作时间、IP地址、设备信息、操作模块、操作类型、目标对象、操作前后数据快照、耗时
 - **敏感操作标记**:禁用用户、审核操作、配置变更等标记为敏感操作
-- **操作模块覆盖**:用户管理、平台配置、账号绑定、入驻信息、邀请系统、优惠券、体验配额、爬虫配额、系统管理
+- **操作模块覆盖**:用户管理、平台配置、账号绑定、入驻信息、邀请系统、优惠券、爬虫配额、系统管理
 
 **运营侧接口**:
 
@@ -467,15 +640,43 @@
 | GET /api/admin/audit-log/target/{type}/{id} | 查询指定目标对象的操作历史 |
 | GET /api/admin/audit-log/stats | 按模块统计操作次数 |
 
-**体验配额配置接口**:
+### 2.15 采购台账
+
+手动记录采购信息,便于药店管理采购流水:
+
+| 接口 | 说明 |
+|------|------|
+| GET /api/procurement-ledgers | 分页查询我的采购台账列表 |
+| POST /api/procurement-ledgers | 新增一条采购记录(关联比价查询ID、药品名称、数量、价格、平台等) |
+| PATCH /api/procurement-ledgers/{id} | 更新采购记录(状态、数量、价格、备注) |
+| DELETE /api/procurement-ledgers/{id} | 删除采购记录 |
+
+### 2.16 跳转购买记录
+
+记录用户从比价结果页点击"去购买"跳转到第三方平台的行为:
+
+| 接口 | 说明 |
+|------|------|
+| GET /api/purchase-intents | 分页查询跳转购买记录列表 |
+| GET /api/purchase-intents/{id} | 查询跳转购买详情 |
+| POST /api/purchase-intents | 写入跳转购买记录(桌面端/Android 调用) |
+
+**记录信息**:药品名称、规格、厂家、平台、参考价格、跳转链接、来源客户端。
+
+### 2.17 帮助与内容
+
+提供面向用户的静态内容服务:
+
+| 接口 | 说明 |
+|------|------|
+| GET /api/content/help | 帮助与常见问题(FAQ),返回帮助标题和问答列表 |
+| GET /api/content/download | 获取桌面客户端下载链接、版本号、更新日志 |
+
+### 2.18 管理员认证
 
 | 接口 | 说明 |
 |------|------|
-| GET /api/admin/trial-quota/configs | 查询所有体验配额配置 |
-| POST /api/admin/trial-quota/config | 创建体验配额配置 |
-| PUT /api/admin/trial-quota/config/{id} | 更新体验配额配置 |
-| DELETE /api/admin/trial-quota/config/{id} | 删除体验配额配置 |
-| GET /api/trial-quota/active | 用户端查询当前生效的体验配额配置 |
+| POST /api/admin/auth/login | 管理员密码登录(操作 t_admin 表,支持用户名/手机号+密码) |
 
 ---
 
@@ -629,9 +830,9 @@
 
 1. **平台扩展性**:代码支持34个平台,MVP首期启用3个,后续通过运营配置逐步开放
 2. **入驻信息可选**:用户可以自愿提交,非强制要求,审核后显示认证标识
-3. **体验配额可配**:运营可以动态调整体验天数、查询次数等参数
-4. **会员体系灵活**:会员权益配置表支持运营动态调整各等级配额加成
-5. **支付方案可配**:运营可创建/上架/下架会员套餐方案
+3. **会员体系灵活**:会员权益配置表支持运营动态调整各等级配额加成
+4. **支付方案可配**:运营可创建/上架/下架会员套餐方案
+5. **系统配置灵活**:运营可通过系统配置管理界面调整全局参数(API Key、业务开关等),修改后立即生效
 
 ### 5.2 平台配置策略
 
@@ -651,20 +852,7 @@
 - **Phase 5**:7个综合电商医药频道(京东健康、天猫医药等)
 - **Phase 6**:4个垂直医药平台(微医、平安好医生等)
 
-### 5.3 体验配额配置策略
-
-运营可以动态调整以下参数:
-
-| 参数 | 默认值 | 说明 |
-|------|--------|------|
-| 体验天数 | 15天 | 新用户免费体验时长 |
-| 每日查询次数 | 20次 | 体验期每日可查询次数 |
-| 每月关注品种数 | 199种 | 体验期每月可关注品种数 |
-
-**配置类型**:
-- **默认配置**:适用于所有新注册用户(通过运营后台 CRUD 管理)
-
-### 5.4 会员权益配置
+### 5.3 会员权益配置
 
 **会员权益配置表**支持运营动态调整各等级权益加成:
 
@@ -699,25 +887,28 @@
 
 **核心功能**:
 - [x] **Windows独立桌面应用**(.exe格式,内置WebView2浏览器引擎)
-- [x] 用户认证(短信验证码登录、密码登录、微信扫码登录)
+- [x] 用户认证(短信验证码登录、密码登录、微信扫码登录、小程序登录、Token刷新、心跳保活
 - [x] 密码管理(设置/修改密码、修改手机号)
 - [x] 入驻信息提交(可选,审核后显示认证标识)
 - [x] B2B平台账号绑定(药师帮/药帮忙/1药城,密码AES-256加密存储)
 - [x] 药品搜索比价功能(消耗配额查询,返回各平台报价)
 - [x] 跳转原平台购买(WebView内嵌跳转,不依赖系统浏览器)
-- [x] 搜索历史记录管理
+- [x] 搜索历史记录管理(保存、分页查询、详情查看)
 - [x] 药品关注/收藏列表(价格变动追踪)
 - [x] 会员体系(PLUS/PRO/ULTRA三档,权益驱动配额)
 - [x] 爬虫配额管理(日/月/年三周期 + 额外配额 + 优惠券)
 - [x] 邀请裂变系统(多渠道落地页、URL Scheme自动填入邀请码、会员时长奖励)
-- [x] 支付系统(模拟支付、支付方案管理、渠道切换、重复支付自动退款、签约协议、安心付;微信/支付宝回调为占位实现,待接入SDK)
-- [x] 体验配额管理(运营可配置天数、查询次数、关注品种数)
+- [x] 支付系统(模拟支付、支付方案管理、渠道切换、重复支付自动退款、签约协议;微信/支付宝回调为占位实现,待接入SDK)
 - [x] 优惠券系统(批量发放、配额消耗优先使用)
-- [x] 运营管理后台(配置管理、入驻审核、数据统计、会员管理、支付方案管理)
-- [x] 用户管理(三级RBAC角色模型、用户列表、角色赋权)
+- [x] 活动中心(邀请有礼、签到送会员、比价抽奖三类活动,含统一摘要接口)
+- [x] 每日签到(签到日历、周期管理、签到统计)
+- [x] 采购台账(手动记录采购流水,增删改查)
+- [x] 跳转购买记录(追踪用户跳转第三方平台行为)
+- [x] 运营管理后台(用户管理、管理员管理、系统配置、配置管理、入驻审核、会员管理、支付方案管理、签到管理)
 - [x] 平台配置管理(34个平台预留,MVP启用3个,运营动态配置)
 - [x] 操作审计日志系统(记录所有关键操作,支持追溯)
 - [x] 网关层请求日志与限流(基于Redis的IP+路径限流)
+- [x] 帮助内容服务(FAQ、下载链接)
 
 **多端扩展准备**:
 - [x] 统一账号体系设计(支持多端登录)
@@ -815,4 +1006,4 @@
 
 ---
 
-**📝 说明**:本文档会随着项目迭代持续更新,请以最新版本为准。
+**📝 说明**:本文档会随着项目迭代持续更新,请以最新版本为准。

+ 69 - 1
docs/02-架构文档.md

@@ -36,6 +36,7 @@ zhijiayun-pharmacy (父工程)
 ├── zhijiayun-user      # 用户模块:认证、会员、优惠券、爬虫配额、搜索、关注、入驻信息、审计日志
 ├── zhijiayun-invite    # 邀请模块:邀请码、裂变、会员奖励、运营配置
 ├── zhijiayun-payment   # 支付模块:微信/支付宝支付、订单管理、套餐方案、二维码生成、重复支付自动退款
+├── zhijiayun-activity  # 活动模块:比价抽奖、签到送会员、邀请有礼、签到打卡
 ├── zhijiayun-gateway   # 网关模块:聚合启动、请求日志、Redis限流、全局异常处理
 └── zhijiayun-test      # 测试模块:集成测试页面、端到端测试
 ```
@@ -143,6 +144,62 @@ com.xuekairui
 │       ├── AutoDeductScheduler.java    # 自动续费定时扣款任务(每10分钟)
 │       └── QRCodeService.java          # 二维码生成
+├── activity/                  # zhijiayun-activity
+│   ├── controller/            # 控制器(4个)
+│   │   ├── ActivityController.java       # 用户端:抽奖状态、奖品列表、执行抽奖、抽奖记录
+│   │   ├── AdminActivityController.java  # 运营端:奖品CRUD、活动配置、抽奖记录查询
+│   │   ├── CheckInController.java        # 用户端:每日签到、签到状态、日历、统计
+│   │   └── AdminCheckInController.java   # 运营端:签到配置、签到记录查询
+│   ├── dto/                   # 数据传输对象(16个)
+│   │   ├── ActivityLotteryStatusResponse.java   # 抽奖活动状态
+│   │   ├── ActivityLotteryResultResponse.java   # 抽奖结果
+│   │   ├── ActivityLotteryPrizeRequest.java     # 奖品创建/更新请求
+│   │   ├── ActivityLotteryConfigRequest.java    # 抽奖活动配置请求
+│   │   ├── ActivityInviteStatusResponse.java    # 邀请有礼活动状态
+│   │   ├── ActivityInviteConfigRequest.java     # 邀请有礼配置请求
+│   │   ├── ActivityCheckinCycleStatusResponse.java # 签到周期活动状态
+│   │   ├── ActivityCheckinCycleConfigRequest.java  # 签到周期配置请求
+│   │   ├── ActivityRewardRecordResponse.java    # 奖励记录
+│   │   ├── ActivityAvailableResponse.java       # 可用活动列表
+│   │   ├── CheckInStatusResponse.java           # 签到状态
+│   │   ├── CheckInResultResponse.java           # 签到结果
+│   │   ├── CheckInCalendarResponse.java         # 签到日历
+│   │   ├── CheckInStatsResponse.java            # 签到统计
+│   │   ├── CheckInConfigRequest.java            # 签到配置请求
+│   │   └── AdminCheckInRecordResponse.java      # 管理端签到记录
+│   ├── entity/                # 数据库实体(10个)
+│   │   ├── ActivityLotteryPrize.java    # 抽奖奖品(含库存管理)
+│   │   ├── ActivityLotteryRecord.java   # 抽奖记录
+│   │   ├── ActivityLotteryChance.java   # 抽奖机会
+│   │   ├── ActivityLotteryConfig.java   # 抽奖活动配置
+│   │   ├── ActivityInviteConfig.java    # 邀请有礼配置
+│   │   ├── ActivityInviteRewardRecord.java # 邀请奖励记录
+│   │   ├── ActivityCheckinCycleConfig.java # 签到周期配置
+│   │   ├── ActivityCheckinCycleRecord.java # 签到周期记录
+│   │   ├── CheckInConfig.java           # 签到配置
+│   │   ├── CheckInPeriod.java           # 签到周期
+│   │   └── CheckInRecord.java           # 签到记录
+│   ├── mapper/                # MyBatis-Plus Mapper(10个)
+│   │   ├── ActivityLotteryPrizeMapper.java   # 奖品查询、库存原子扣减
+│   │   ├── ActivityLotteryRecordMapper.java
+│   │   ├── ActivityLotteryChanceMapper.java
+│   │   ├── ActivityLotteryConfigMapper.java
+│   │   ├── ActivityInviteConfigMapper.java
+│   │   ├── ActivityInviteRewardRecordMapper.java
+│   │   ├── ActivityCheckinCycleConfigMapper.java
+│   │   ├── ActivityCheckinCycleRecordMapper.java
+│   │   ├── CheckInConfigMapper.java
+│   │   ├── CheckInPeriodMapper.java
+│   │   └── CheckInRecordMapper.java
+│   ├── service/               # 业务逻辑(5个服务)
+│   │   ├── ActivityLotteryService.java      # 抽奖核心逻辑(加权随机、库存扣减、违规记录)
+│   │   ├── ActivityInviteService.java       # 邀请有礼(实现ActivityInviteGate门面)
+│   │   ├── ActivityCheckinCycleService.java # 签到送会员(周期制)
+│   │   ├── CheckInService.java              # 每日签到
+│   │   └── CheckInConfigService.java        # 签到配置管理
+│   └── scheduler/
+│       └── ActivityEventScheduler.java      # 活动事件定时任务
+│
 └── gateway/                   # zhijiayun-gateway
     ├── Application.java       # 启动类
     ├── config/
@@ -189,6 +246,17 @@ com.xuekairui
 | t_operation_audit_log | 操作审计日志表 | operator_id, operator_role, module, operation_type, target_type, target_id, before_data, after_data, result, is_sensitive |
 | t_search_history | 搜索历史表(轻量关键词日志,无Java实体) | user_id, keyword, platform, result_count, search_time |
 | t_watchlist | 关注/收藏表 | user_id, drug_name, spec, manufacturer, min_price, min_price_platform, last_price, price_change |
+| t_activity_lottery_config | 抽奖活动配置表 | enabled, start_time, end_time, daily_chance_limit, require_membership_level, require_license_approved |
+| t_activity_lottery_prize | 抽奖奖品表 | name, reward_type(MEMBERSHIP/CRAWLER/EMPTY/PHYSICAL), reward_amount, reward_days, reward_level, stock, remaining_stock, probability_weight, enabled, sort |
+| t_activity_lottery_chance | 抽奖机会表 | user_id, chance_date, source(FIRST_SEARCH/ADMIN), status(0未使用/1已使用), used_time, record_id |
+| t_activity_lottery_record | 抽奖记录表 | user_id, prize_id, prize_name, reward_type, reward_amount, reward_days, reward_level, chance_id, client_ip |
+| t_activity_invite_config | 邀请有礼活动配置表 | enabled, start_time, end_time, reward_trigger(REGISTRATION/LICENSE_APPROVED), reward_type, reward_months, reward_days, max_reward_count |
+| t_activity_invite_reward_record | 邀请奖励记录表 | inviter_id, invitee_id, reward_type, reward_months, reward_days, trigger_type, granted_time |
+| t_activity_checkin_cycle_config | 签到周期活动配置表 | enabled, start_time, end_time, cycle_mode(FRI_THU), required_days, reward_days, max_reward_count |
+| t_activity_checkin_cycle_record | 签到周期记录表 | user_id, cycle_start_date, cycle_end_date, signed_days, reward_granted, reward_time |
+| t_checkin_config | 签到配置表 | enabled, reward_type, reward_value, consecutive_bonusus |
+| t_checkin_period | 签到周期表 | user_id, period_start, period_end, signed_count, last_sign_date |
+| t_checkin_record | 签到记录表 | user_id, sign_date, reward_type, reward_value |
 
 ### 3.2 ER关系
 
@@ -468,4 +536,4 @@ t_payment_plan ──1:N──> t_alipay_anxin_card (方案-安心付卡模板)
 
 ---
 
-**📝 说明**:本文档会随着项目迭代持续更新,请以最新版本为准。
+**📝 说明**:本文档会随着项目迭代持续更新,请以最新版本为准。

+ 318 - 0
docs/03-接口文档.md

@@ -3038,4 +3038,322 @@ GET /api/admin/audit-log/stats?module=PAYMENT&startTime=2026-07-01T00:00:00
 
 ---
 
+## 21. 活动模块 /api/activity
+
+### 21.1 比价抽奖活动
+
+#### 21.1.1 查询抽奖活动状态
+
+```
+GET /api/activity/lottery/status
+```
+
+**需要认证**
+
+**响应:**
+```json
+{
+  "code": 200,
+  "data": {
+    "enabled": true,
+    "inWindow": true,
+    "eligible": true,
+    "membershipLevel": "PRO",
+    "requireMembershipLevel": "PRO",
+    "availableChances": 1,
+    "usedChances": 0,
+    "reason": null
+  }
+}
+```
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| enabled | Boolean | 活动是否开启 |
+| inWindow | Boolean | 当前时间是否在活动窗口内 |
+| eligible | Boolean | 用户是否具备参与资格(会员等级+入驻审核) |
+| membershipLevel | String | 当前会员等级 |
+| requireMembershipLevel | String | 所需最低会员等级 |
+| availableChances | Integer | 今日可用抽奖机会数 |
+| usedChances | Integer | 今日已使用抽奖机会数 |
+| reason | String | 状态原因说明(机会为0时告知原因) |
+
+#### 21.1.2 获取可抽奖品列表
+
+```
+GET /api/activity/lottery/prizes
+```
+
+**需要认证**
+
+**响应:**
+```json
+{
+  "code": 200,
+  "data": [
+    {
+      "id": 1,
+      "name": "特等奖 iPhone 17",
+      "rewardType": "PHYSICAL",
+      "rewardAmount": 0,
+      "rewardDays": null,
+      "rewardLevel": null,
+      "sort": 1
+    },
+    {
+      "id": 2,
+      "name": "一等奖 30天高级会员",
+      "rewardType": "MEMBERSHIP",
+      "rewardAmount": 0,
+      "rewardDays": 30,
+      "rewardLevel": "PRO",
+      "sort": 2
+    }
+  ]
+}
+```
+
+> **注意**:不返回 `probabilityWeight`、`stock`、`remainingStock` 等敏感信息
+
+#### 21.1.3 执行抽奖
+
+```
+POST /api/activity/lottery/draw
+```
+
+**需要认证**
+
+**业务规则:**
+- 每日仅限抽奖1次
+- 重复抽奖返回"今日抽奖次数已用完"并记录违规审计日志
+- 抽奖机会来源于每日首次成功比价
+
+**响应(中奖):**
+```json
+{
+  "code": 200,
+  "data": {
+    "recordId": "1234567890",
+    "prizeName": "一等奖 30天高级会员",
+    "rewardType": "MEMBERSHIP",
+    "rewardAmount": 0,
+    "rewardDays": 30,
+    "rewardLevel": "PRO",
+    "prizeTier": "一等奖",
+    "win": true,
+    "createTime": "2026-07-13T10:30:00"
+  }
+}
+```
+
+**响应(未中奖):**
+```json
+{
+  "code": 200,
+  "data": {
+    "recordId": "1234567891",
+    "prizeName": "谢谢惠顾",
+    "rewardType": "EMPTY",
+    "rewardAmount": 0,
+    "rewardDays": null,
+    "rewardLevel": null,
+    "prizeTier": "谢谢惠顾",
+    "win": false,
+    "createTime": "2026-07-13T10:30:00"
+  }
+}
+```
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| recordId | String | 抽奖记录ID |
+| prizeName | String | 奖品名称 |
+| rewardType | String | 奖励类型:MEMBERSHIP/CRAWLER/EMPTY/PHYSICAL |
+| rewardAmount | Integer | 奖励数量 |
+| rewardDays | Integer | 奖励天数(会员时长) |
+| rewardLevel | String | 奖励等级(PRO/ULTRA) |
+| prizeTier | String | 奖品等级名称(特等奖/一等奖/.../谢谢惠顾) |
+| win | Boolean | 是否中奖(EMPTY为未中奖) |
+| createTime | DateTime | 抽奖时间 |
+
+#### 21.1.4 我的抽奖记录
+
+```
+GET /api/activity/lottery/records?limit=20
+```
+
+**需要认证**
+
+| 参数 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| limit | Integer | 否 | 返回条数限制(默认20) |
+
+**响应:**
+```json
+{
+  "code": 200,
+  "data": [
+    {
+      "recordId": "1234567890",
+      "prizeName": "一等奖 30天高级会员",
+      "rewardType": "MEMBERSHIP",
+      "rewardAmount": 0,
+      "rewardDays": 30,
+      "rewardLevel": "PRO",
+      "prizeTier": "一等奖",
+      "win": true,
+      "createTime": "2026-07-13T10:30:00"
+    }
+  ]
+}
+```
+
+### 21.2 运营管理-抽奖活动配置
+
+#### 21.2.1 查询抽奖活动配置
+
+```
+GET /api/admin/activity/lottery/config
+```
+
+**需要管理员权限**
+
+**响应:**
+```json
+{
+  "code": 200,
+  "data": {
+    "id": 1,
+    "enabled": 1,
+    "startTime": "2026-07-13T00:00:00",
+    "endTime": "2026-07-31T23:59:59",
+    "dailyChanceLimit": 1,
+    "requireMembershipLevel": "PRO",
+    "requireLicenseApproved": 1
+  }
+}
+```
+
+#### 21.2.2 更新抽奖活动配置
+
+```
+PUT /api/admin/activity/lottery/config
+```
+
+**需要管理员权限**
+
+**请求体:**
+```json
+{
+  "enabled": 1,
+  "startTime": "2026-07-13T00:00:00",
+  "endTime": "2026-07-31T23:59:59",
+  "dailyChanceLimit": 1,
+  "requireMembershipLevel": "PRO",
+  "requireLicenseApproved": 1
+}
+```
+
+#### 21.2.3 奖品池列表
+
+```
+GET /api/admin/activity/lottery/prizes
+```
+
+**需要管理员权限**
+
+**响应:**
+```json
+{
+  "code": 200,
+  "data": [
+    {
+      "id": 1,
+      "name": "特等奖 iPhone 17",
+      "rewardType": "PHYSICAL",
+      "rewardAmount": 0,
+      "rewardDays": null,
+      "rewardLevel": null,
+      "stock": 0,
+      "remainingStock": 0,
+      "probabilityWeight": 0,
+      "enabled": 1,
+      "sort": 1
+    }
+  ]
+}
+```
+
+#### 21.2.4 新增奖品
+
+```
+POST /api/admin/activity/lottery/prizes
+```
+
+**需要管理员权限**
+
+**请求体:**
+```json
+{
+  "name": "六等奖 2天高级会员",
+  "rewardType": "MEMBERSHIP",
+  "rewardAmount": 0,
+  "rewardDays": 2,
+  "rewardLevel": "PRO",
+  "stock": 500,
+  "probabilityWeight": 500,
+  "enabled": 1,
+  "sort": 8
+}
+```
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| name | String | 是 | 奖品名称 |
+| rewardType | String | 是 | 奖励类型:MEMBERSHIP/CRAWLER/EMPTY/PHYSICAL |
+| rewardAmount | Integer | 否 | 奖励数量 |
+| rewardDays | Integer | 否 | 奖励天数(会员时长) |
+| rewardLevel | String | 否 | 奖励等级(PRO/ULTRA) |
+| stock | Integer | 是 | 奖品总份数(0表示不限或仅展示) |
+| probabilityWeight | Integer | 是 | 概率权重(权重=份数,确保库存均匀消耗) |
+| enabled | Integer | 否 | 是否启用(默认1) |
+| sort | Integer | 否 | 排序(默认按ID) |
+
+#### 21.2.5 更新奖品
+
+```
+PUT /api/admin/activity/lottery/prizes/{id}
+```
+
+**需要管理员权限**
+
+**请求体:** 同 21.2.4
+
+#### 21.2.6 删除奖品
+
+```
+DELETE /api/admin/activity/lottery/prizes/{id}
+```
+
+**需要管理员权限**
+
+#### 21.2.7 分页查询所有用户抽奖记录
+
+```
+GET /api/admin/activity/lottery/records?page=1&size=20&userId=1&prizeType=MEMBERSHIP
+```
+
+**需要管理员权限**
+
+| 参数 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| page | Integer | 否 | 页码(默认1) |
+| size | Integer | 否 | 每页数量(默认20) |
+| userId | Long | 否 | 用户ID筛选 |
+| prizeType | String | 否 | 奖品类型筛选(MEMBERSHIP/CRAWLER/EMPTY/PHYSICAL) |
+
+**响应:** 分页格式(参见"通用说明 - 分页响应格式")
+
+---
+
 **📝 说明**:本文档会随着项目迭代持续更新,请以最新版本为准。

+ 28 - 2
docs/05-测试文档.md

@@ -197,7 +197,32 @@
 | DUP-07 | 自动退款 - 支付宝渠道重复支付触发退款(mock模式) | P0 |
 | DUP-08 | 退款状态 - 退款成功后refund_status=SUCCESS | P0 |
 | DUP-09 | 退款失败 - 记录refund_fail_reason,refund_status=FAILED | P1 |
-| DUP-10 | 退款幂等 - 同一重复支付记录不重复退款 | P1 |
+| DUP-10 | 退款幂等 - 同一重复支付记录不重复退款 | P1 |### 3.7 活动模块测试
+
+#### 3.7.1 比价抽奖活动测试
+
+| 编号 | 用例 | 优先级 |
+|------|------|--------|
+| ACT-01 | GET /api/activity/lottery/status - 查询抽奖状态(活动开启) | P0 |
+| ACT-02 | GET /api/activity/lottery/status - 查询抽奖状态(活动关闭) | P0 |
+| ACT-03 | GET /api/activity/lottery/status - 普通会员无资格 | P0 |
+| ACT-04 | GET /api/activity/lottery/status - 入驻未审核无资格 | P0 |
+| ACT-05 | GET /api/activity/lottery/prizes - 获取奖品列表(不含敏感信息) | P0 |
+| ACT-06 | POST /api/activity/lottery/draw - 有资格用户抽奖成功 | P0 |
+| ACT-07 | POST /api/activity/lottery/draw - 无资格用户抽奖拒绝 | P0 |
+| ACT-08 | POST /api/activity/lottery/draw - 无机会用户抽奖拒绝 | P0 |
+| ACT-09 | POST /api/activity/lottery/draw - 重复抽奖记录违规日志 | P0 |
+| ACT-10 | POST /api/activity/lottery/draw - 库存扣减正确 | P0 |
+| ACT-11 | POST /api/activity/lottery/draw - 库存为0奖品不参与抽奖 | P0 |
+| ACT-12 | POST /api/activity/lottery/draw - 权重计算正确(权重=份数) | P0 |
+| ACT-13 | GET /api/activity/lottery/records - 查询抽奖记录 | P1 |
+| ACT-14 | GET /api/admin/activity/lottery/config - 查询活动配置 | P1 |
+| ACT-15 | PUT /api/admin/activity/lottery/config - 更新活动配置 | P1 |
+| ACT-16 | GET /api/admin/activity/lottery/prizes - 查询奖品池(含敏感信息) | P1 |
+| ACT-17 | POST /api/admin/activity/lottery/prizes - 新增奖品 | P1 |
+| ACT-18 | PUT /api/admin/activity/lottery/prizes/{id} - 更新奖品 | P1 |
+| ACT-19 | DELETE /api/admin/activity/lottery/prizes/{id} - 删除奖品 | P1 |
+| ACT-20 | GET /api/admin/activity/lottery/records - 分页查询抽奖记录 | P1 |
 
 ---
 
@@ -255,5 +280,6 @@ mvn test -pl zhijiayun-gateway -Dtest="AuthControllerTest#sendCode_invalidPhone_
 | zhijiayun-user | 70% | 60% |
 | zhijiayun-invite | 70% | 60% |
 | zhijiayun-payment | 70% | 60% |
+| zhijiayun-activity | 70% | 60% |
 | zhijiayun-gateway | 80% | 70% |
-| 整体 | 70% | 60% |
+| 整体 | 70% | 60% |

+ 19 - 1
docs/06-验收流程与标准.md

@@ -205,6 +205,23 @@
 | FA-114 | SUPER_ADMIN全权限 | 超管可访问所有接口 | P0 |
 | FA-115 | 未认证访问保护接口 | 未认证访问保护接口返回401 | P0 |
 
+  ### 2.13 活动模块
+
+| 编号 | 验收项 | 通过标准 | 优先级 |
+|------|--------|----------|--------|
+| FA-120 | 抽奖活动状态查询 | 返回活动状态、用户资格、可用机会 | P0 |
+| FA-121 | 奖品列表查询 | 返回奖品列表(不含敏感信息) | P0 |
+| FA-122 | 执行抽奖 | 有资格用户可正常抽奖,返回中奖结果 | P0 |
+| FA-123 | 抽奖资格校验 | 普通会员/入驻未审核用户无法抽奖 | P0 |
+| FA-124 | 抽奖次数限制 | 每日仅限抽奖1次,重复抽奖拒绝 | P0 |
+| FA-125 | 违规记录 | 重复抽奖行为记录到审计日志 | P0 |
+| FA-126 | 库存扣减 | 中奖后奖品库存正确扣减 | P0 |
+| FA-127 | 权重计算 | 权重=份数,确保库存均匀消耗 | P0 |
+| FA-128 | 抽奖记录查询 | 用户可查询自己的抽奖记录 | P1 |
+| FA-129 | 活动配置管理 | 运营可配置活动时间、参与条件 | P1 |
+| FA-130 | 奖品池管理 | 运营可增删改查奖品 | P1 |
+| FA-131 | 抽奖记录管理 | 运营可查询所有用户抽奖记录 | P1 |
+
 ---
 
 ## 3. 性能验收标准
@@ -291,6 +308,7 @@
 - [ ] 邀请裂变系统(多渠道 + 会员时长奖励 + 智能解析)
 - [ ] 支付系统(微信/支付宝 + 套餐管理 + 模拟支付 + 渠道切换 + 重复支付自动退款 + 签约协议 + 安心付)
 - [ ] 优惠券系统
+- [ ] 活动模块(比价抽奖 + 签到送会员 + 邀请有礼)
 - [ ] 运营管理后台(用户管理 + 配置管理 + 审核管理)
 - [ ] 操作审计日志系统
 - [ ] 平台会话管理(会话更新/查询/删除)
@@ -321,4 +339,4 @@
 
 **验收结论**:☐ 通过  ☐ 有条件通过(附整改清单)  ☐ 不通过
 
-**备注**:
+**备注**:

+ 10 - 7
zhijiayun-gateway/src/main/resources/db/migration-v16.sql

@@ -44,17 +44,20 @@ SET @sql = IF(@col_exists > 0,
 PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
 
 -- ========== 三、清空旧奖品池,写入新7档奖品 ==========
+-- 权重 = 份数(权重与份数严格成正比,确保库存均匀消耗,不会出现某奖品早早发完而其他大量剩余)
+-- 特等奖 iPhone 17:份数=0、权重=0,仅展示不中奖,后续运营端可配置
+-- 总权重 = 总份数 = 8000,每个奖品的实际中奖概率 = 份数/8000
 DELETE FROM `t_activity_lottery_prize`;
 
 INSERT INTO `t_activity_lottery_prize` (`name`, `reward_type`, `reward_amount`, `reward_days`, `reward_level`, `stock`, `remaining_stock`, `probability_weight`, `enabled`, `sort`)
 VALUES
-('特等奖 iPhone 17', 'PHYSICAL',  0, NULL, NULL,   0,    0,   0, 1, 1),
-('一等奖 30天高级会员', 'MEMBERSHIP', 0, 30, 'PRO',  20,   20,   2, 1, 2),
-('二等奖 15天高级会员', 'MEMBERSHIP', 0, 15, 'PRO', 100,  100,  10, 1, 3),
-('三等奖 7天高级会员',  'MEMBERSHIP', 0,  7, 'PRO', 150,  150,  15, 1, 4),
-('四等奖 3天高级会员',  'MEMBERSHIP', 0,  3, 'PRO', 250,  250,  25, 1, 5),
-('五等奖 1天高级会员',  'MEMBERSHIP', 0,  1, 'PRO', 1080, 1080, 108, 1, 6),
-('谢谢惠顾',           'EMPTY',     0, NULL, NULL, 6400, 6400, 640, 1, 7);
+('特等奖 iPhone 17',   'PHYSICAL',   0, NULL, NULL,    0,    0,     0, 1, 1),
+('一等奖 30天高级会员', 'MEMBERSHIP', 0, 30,   'PRO',   20,   20,    20, 1, 2),
+('二等奖 15天高级会员', 'MEMBERSHIP', 0, 15,   'PRO',  100,  100,   100, 1, 3),
+('三等奖 7天高级会员',  'MEMBERSHIP', 0,  7,   'PRO',  150,  150,   150, 1, 4),
+('四等奖 3天高级会员',  'MEMBERSHIP', 0,  3,   'PRO',  250,  250,   250, 1, 5),
+('五等奖 1天高级会员',  'MEMBERSHIP', 0,  1,   'PRO', 1080, 1080, 1080, 1, 6),
+('谢谢惠顾',           'EMPTY',      0, NULL, NULL,  6400, 6400, 6400, 1, 7);
 
 -- ========== 四、抽奖记录表新增 client_ip 字段 ==========
 SET @col_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS