⚠️ MVP 阶段说明
本项目为全新项目,尚未上线,当前处于 MVP(最小可行产品)阶段。
本文档描述的是 MVP 版本的架构设计,后续将根据业务发展和技术演进持续优化。版本:v1.1-MVP | 更新日期:2026-07-01 | 状态:开发中
| 层次 | 技术 | 版本 | MVP状态 |
|---|---|---|---|
| 语言 | Java | 17 | ✅ |
| 框架 | Spring Boot | 3.5.14 | ✅ |
| ORM | MyBatis-Plus | 3.5.16 | ✅ |
| 数据库 | MySQL | 8.0+(驱动 9.3.0) | ✅ |
| 缓存 | Redis (Lettuce) | 6.0+ | ✅ 已接入真实Redis |
| 认证 | JWT (jjwt) | 0.12.6 | ✅ |
| 安全 | Spring Security + BouncyCastle | 1.84 | ✅ |
| 短信 | 阿里云 SMS | 4.5.1 | ✅ |
| 二维码 | Google ZXing | 3.5.3 | ✅ |
| 工具库 | Hutool | 5.8.44 | ✅ |
| 构建 | Maven | 3.8+ | ✅ |
zhijiayun-pharmacy (父工程)
├── zhijiayun-common # 公共模块:Result、ErrorCode、BusinessException、TraceIdGenerator、ValidateUtil
├── zhijiayun-user # 用户模块:认证、会员、优惠券、爬虫配额、搜索、关注、营业执照、审计日志
├── zhijiayun-invite # 邀请模块:邀请码、裂变、会员奖励、运营配置
├── zhijiayun-payment # 支付模块:微信/支付宝支付、订单管理、套餐方案、二维码生成、重复支付自动退款
├── zhijiayun-gateway # 网关模块:聚合启动、请求日志、Redis限流、全局异常处理
└── zhijiayun-test # 测试模块:集成测试页面、端到端测试
zhijiayun-gateway (聚合启动入口)
├── zhijiayun-user
│ └── zhijiayun-common
├── zhijiayun-invite
│ ├── zhijiayun-user (依赖 CrawlerQuotaGrantService、MembershipService)
│ └── zhijiayun-common
└── zhijiayun-payment
└── zhijiayun-common
com.xuekairui
├── common/ # zhijiayun-common
│ ├── Result.java # 统一响应封装
│ ├── ErrorCode.java # 错误码枚举(用户/验证码/微信/Token/支付/等级/优惠券/爬虫/邀请/搜索/关注)
│ ├── BusinessException.java # 业务异常
│ ├── TraceIdGenerator.java # 链路追踪ID生成器
│ └── ValidateUtil.java # 参数校验工具(IP提取等)
│
├── user/ # zhijiayun-user
│ ├── config/ # 配置类(6个)
│ │ ├── AliyunSmsProperties.java
│ │ ├── AsyncConfig.java # 异步任务线程池配置
│ │ ├── MyBatisPlusMetaHandler.java
│ │ ├── RedisConfig.java
│ │ ├── SecurityConfig.java # Spring Security + RBAC
│ │ └── SuperAdminInitializer.java # 超级管理员初始化
│ ├── controller/ # 控制器(19个)
│ │ ├── AuthController.java # 认证(短信/密码/微信登录、Token刷新、用户信息)
│ │ ├── CrawlerController.java # 爬虫配额状态、消耗、日志
│ │ ├── CouponController.java # 优惠券发放、查询
│ │ ├── UserLevelController.java # 等级列表、用户等级设置
│ │ ├── MembershipController.java # 会员信息查询、权益查询
│ │ ├── DrugSearchController.java # 药品搜索比价、搜索建议
│ │ ├── SearchRecordController.java # 搜索历史管理
│ │ ├── WatchlistController.java # 关注/收藏列表管理
│ │ ├── PlatformAccountController.java # B2B平台账号绑定
│ │ ├── PlatformSessionController.java # 平台会话管理
│ │ ├── CrawlerPlatformConfigController.java # 平台配置查询
│ │ ├── BusinessLicenseController.java # 营业执照上传
│ │ ├── FileUploadController.java # 文件上传
│ │ ├── TrialQuotaConfigController.java # 体验配额查询
│ │ ├── AdminUserController.java # 用户管理(SUPER_ADMIN)
│ │ ├── AdminMembershipController.java # 会员发放管理
│ │ ├── AdminLicenseController.java # 营业执照审核
│ │ ├── AdminTrialQuotaConfigController.java # 体验配额配置管理
│ │ └── OperationAuditLogController.java # 审计日志查询
│ ├── dto/ # 数据传输对象(34个)
│ ├── entity/ # 数据库实体(17个)
│ ├── enums/ # 枚举(MembershipLevel、UserRole、OperationType)
│ ├── event/ # 事件(UserRegisteredEvent)
│ ├── mapper/ # MyBatis-Plus Mapper(16个)
│ ├── security/ # JWT过滤器
│ ├── service/ # 业务逻辑(19个服务)
│ └── util/ # 工具类
│
├── invite/ # zhijiayun-invite
│ ├── controller/ # 控制器(2个)
│ │ ├── InviteController.java # 邀请码、统计、记录、落地页、解析、下载
│ │ └── AdminController.java # 邀请配置、爬虫发放、记录查看
│ ├── dto/ # 数据传输对象(9个)
│ ├── entity/ # 数据库实体(3个:InviteCode、InviteConfig、InviteRelation)
│ ├── listener/ # UserRegisteredListener(事件驱动)
│ ├── mapper/ # MyBatis-Plus Mapper(3个)
│ └── service/
│ ├── InviteService.java # 邀请核心服务
│ └── InviteConfigService.java # 邀请配置服务
│
├── payment/ # zhijiayun-payment
│ ├── config/ # PaymentConfig、PaymentProperties(2个)
│ ├── controller/ # 控制器(6个)
│ │ ├── PaymentController.java # 支付方案、创建订单、查询订单、切换渠道
│ │ ├── PaymentCallbackController.java # 微信/支付宝回调
│ │ ├── AdminPaymentController.java # 支付方案管理
│ │ ├── AgreementController.java # 签约协议管理
│ │ ├── AlipayAnxinPayController.java # 安心付管理
│ │ └── AlipayOpenController.java # 支付宝开放能力回调
│ ├── dto/ # 数据传输对象(11个)
│ ├── entity/ # 数据库实体(7个)
│ ├── enums/ # 枚举(5个:PaymentChannel、PaymentStatus、AgreementStatus、OrderType、PeriodType)
│ ├── mapper/ # MyBatis-Plus Mapper(8个)
│ │ ├── PaymentOrderMapper.java
│ │ ├── PaymentOrderExtraPaymentMapper.java # 重复支付记录
│ │ ├── PaymentAgreementMapper.java # 签约协议
│ │ ├── PaymentPlanMapper.java # 支付方案
│ │ ├── AlipayAnxinCardMapper.java # 安心付卡模板
│ │ ├── AlipayAnxinOrderRecordMapper.java # 安心付订单
│ │ └── AlipayCallbackRecordMapper.java # 支付宝回调记录
│ └── service/
│ ├── PaymentOrderService.java # 订单管理(含重复支付处理)
│ ├── PaymentPlanService.java # 方案管理
│ ├── PaymentRefundService.java # 退款服务(微信/支付宝原路退款)
│ ├── PaymentAgreementService.java # 签约协议服务
│ ├── AlipayAnxinPayService.java # 安心付服务
│ ├── AlipayCallbackRecordService.java # 支付宝回调记录服务
│ ├── AutoDeductScheduler.java # 自动续费定时扣款任务(每10分钟)
│ └── QRCodeService.java # 二维码生成
│
└── gateway/ # zhijiayun-gateway
├── Application.java # 启动类
├── config/
│ ├── GatewayConfig.java # 网关配置
│ └── GatewayProperties.java # 网关属性(日志、限流规则)
├── filter/
│ ├── RequestLoggingFilter.java # 请求日志+慢请求检测
│ └── RateLimitFilter.java # Redis限流过滤器
└── handler/
└── GlobalExceptionHandler.java # 全局异常处理
| 表名 | 说明 | 核心字段 |
|---|---|---|
| t_user | 用户表 | phone, nickname, password, wechat_open_id, role(USER/ADMIN/SUPER_ADMIN), membership_level(PLUS/PRO/ULTRA), pharmacy_name, login_source |
| t_user_membership | 用户会员记录表 | user_id, level(PLUS/PRO/ULTRA), source(ADMIN_GRANT/RECHARGE/SYSTEM), effective_from, effective_to, status |
| t_membership_benefit | 会员权益配置表 | level, benefit_type(DAILY/MONTHLY/YEARLY_QUOTA, MAX_CONCURRENT), benefit_value |
| t_coupon | 优惠券模板表 | name, type(CRAWLER), value, total_count, valid_type, min_level_code |
| t_user_coupon | 用户优惠券表 | user_id, coupon_id, status(0未使用/1已使用/2已过期), expire_time, source |
| t_crawler_usage_log | 爬虫使用记录表 | user_id, usage_date, usage_count, platform, source(QUOTA/COUPON) |
| t_crawler_quota_grant | 爬虫配额发放表 | user_id, grant_type(INVITE/PURCHASE/ADMIN), quota_count, used_count, expire_time, status(1有效/2用完/3过期) |
| t_invite_config | 邀请奖励配置表 | reward_type(MEMBERSHIP/CRAWLER), reward_months, max_daily_reward, 多渠道字段, landing_title |
| t_invite_code | 邀请码表 | user_id, code, max_uses, used_count, click_count, expire_time |
| t_invite_relation | 邀请关系表 | inviter_id, invitee_id, invite_code_id, registered, reward_granted |
| t_payment_plan | 支付方案表 | plan_code, plan_name, membership_level, price(DECIMAL), original_price(DECIMAL), duration_days, status |
| t_payment_order | 支付订单表 | order_no, user_id, plan_id, amount(DECIMAL), channel(WECHAT/ALIPAY), status(PENDING/PAID/EXPIRED/REFUNDED), qr_code_url, trade_no, paid_channel |
| t_payment_order_extra_payment | 重复支付记录表 | order_no, channel, trade_no, amount(DECIMAL), paid_time, refund_status(PENDING/SUCCESS/FAILED), refund_trade_no, refund_time, refund_fail_reason |
| t_payment_agreement | 签约协议表 | user_id, plan_id, channel, period_type(MONTH/YEAR), period_amount, status(PENDING/SIGNED/UNSIGNED/FAILED), agreement_no, next_deduct_time |
| t_alipay_anxin_card | 安心付卡模板表 | plan_id, card_id, card_name, card_type, period_amount, period_days, total_periods, status, appointment_url |
| t_alipay_anxin_order_record | 安心付订单记录表 | user_id, plan_id, card_id, order_id, sub_order_id, out_biz_no, deduct_amount, deduct_status, deduct_time, membership_activated, order_no |
| t_alipay_callback_record | 支付宝开放能力回调记录表 | type, app_id, msg_method, auth_code, source, state, params, status, error_msg |
| t_platform_session | 平台会话快照表 | user_id, platform_code, platform_name, login_url, account_label, cookies_encrypted, version, expires_at |
| t_platform_account | B2B平台账号绑定表 | user_id, platform_code, platform_name, account_encrypted, password_encrypted, enabled, verify_status |
| t_search_record | 搜索记录表(完整比价快照) | user_id, drug_name, searched_at, status_text, platform_results, search_log |
| t_platform_config | 平台配置表 | platform_code, platform_name, enabled, query_cost, priority, official_url, binding_instructions |
| t_business_license | 营业执照表 | user_id, license_image_url, credit_code, pharmacy_name, review_status(PENDING/APPROVED/REJECTED) |
| t_trial_quota_config | 体验配额配置表 | config_name, trial_days, daily_query_limit, monthly_watchlist_limit, config_type(DEFAULT/COUPON/ACTIVITY) |
| 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_user ──1:N──> t_invite_code (每个用户一个邀请码)
t_user ──1:N──> t_invite_relation (作为邀请人)
t_user ──1:N──> t_user_membership (会员记录)
t_user ──1:N──> t_crawler_quota_grant (配额发放)
t_user ──1:N──> t_crawler_usage_log (使用记录)
t_user ──1:N──> t_user_coupon (优惠券)
t_user ──1:N──> t_platform_account (平台账号绑定)
t_user ──1:1──> t_business_license (营业执照)
t_user ──1:N──> t_search_history (搜索历史/关键词日志)
t_user ──1:N──> t_search_record (搜索记录/比价快照)
t_user ──1:N──> t_watchlist (关注列表)
t_user ──1:N──> t_payment_order (支付订单)
t_coupon ──1:N──> t_user_coupon (模板-实例)
t_invite_code ──1:N──> t_invite_relation (邀请码-关系)
t_membership_benefit ──N:1──> MembershipLevel (等级-权益)
t_payment_plan ──1:N──> t_payment_order (方案-订单)
t_payment_order ──1:N──> t_payment_order_extra_payment (订单-重复支付记录)
t_payment_plan ──1:N──> t_payment_agreement (方案-签约协议)
t_user ──1:N──> t_payment_agreement (用户-签约协议)
t_user ──1:N──> t_platform_session (用户-平台会话)
t_payment_plan ──1:N──> t_alipay_anxin_card (方案-安心付卡模板)
客户端 → POST /api/auth/sms/login 或 /api/auth/password/login → 验证成功
→ 生成 JWT (Access Token 24h + Refresh Token 7d)
→ 后续请求携带 Authorization: Bearer <token>
→ JwtAuthenticationFilter 校验 → 放行/拒绝
| 角色 | 权限范围 | 说明 |
|---|---|---|
| USER | 用户侧接口 | 比价、搜索、关注、邀请、支付等 |
| ADMIN | 运营后台接口 | 用户管理、配置管理、审核、发放等 |
| SUPER_ADMIN | 全部权限 | 包括角色赋权(/api/admin/users/**) |
| 类型 | 路径 | 说明 |
|---|---|---|
| 公开 | /api/auth/sms/send, /api/auth/sms/login | 短信验证码 |
| 公开 | /api/auth/password/login | 密码登录 |
| 公开 | /api/auth/refresh | 刷新Token |
| 公开 | /api/auth/wechat/** | 微信登录相关 |
| 公开 | /api/invite/page/, /api/invite/click/, /api/invite/{code} | 邀请落地页 |
| 公开 | /api/invite/resolve-link, /api/invite/validate | 邀请码解析/验证 |
| 公开 | /invite/** | 浏览器直接访问邀请链接(公开) |
| 公开 | /api/platform-config/** | 平台配置查询 |
| 公开 | /api/trial-quota/** | 体验配额查询 |
| 公开 | /api/search/suggestions | 搜索建议 |
| 公开 | /api/payment/plans | 支付方案列表 |
| 公开 | /api/payment/callback/** | 支付回调 |
| 公开 | /api/payment/anxin/notify/** | 安心付通知 |
| 公开 | /api/payment/agreement/notify/** | 签约回调通知 |
| 公开 | /api/payment/alipay/** | 支付宝开放能力回调 |
| 公开 | /api/level/list, /api/level/{id} | 等级列表 |
| 认证 | /api/auth/user/**, /api/auth/password/set, /api/auth/phone/change | 用户信息 |
| 认证 | /api/crawler/**, /api/search/query | 爬虫/搜索 |
| 认证 | /api/platform-session/** | 平台会话管理 |
| 认证 | /api/search-record/** | 搜索历史 |
| 认证 | /api/invite/code, /api/invite/stats, /api/invite/rewards | 邀请操作 |
| 认证 | /api/invite/extra-quota, /api/invite/bind, /api/invite/my-inviter | 邀请操作 |
| 认证 | /api/coupon/, /api/membership/ | 优惠券/会员 |
| 认证 | /api/platform-account/, /api/watchlist/ | 账号绑定/关注 |
| 认证 | /api/payment/order/, /api/payment/agreement/ | 支付订单/签约 |
| 管理 | /api/admin/** (ADMIN + SUPER_ADMIN) | 运营管理 |
| 管理 | /api/admin/payment/anxin/** (ADMIN + SUPER_ADMIN) | 安心付管理 |
| 超管 | /api/admin/users/** (仅SUPER_ADMIN) | 用户角色管理 |
| 管理 | /api/coupon/issue, /api/level/user/** (ADMIN + SUPER_ADMIN) | 散落管理操作 |
基于 Redis 固定窗口计数器,按客户端IP + 路径前缀限流:
| 路径前缀 | 窗口 | 限制 | 说明 |
|---|---|---|---|
| /api/auth/sms | 60s | 10次 | 短信验证码发送 |
| /api/auth/login | 60s | 20次 | 登录接口 |
| /api/crawler | 60s | 60次 | 爬虫操作 |
| 其他 | 60s | 100次 | 默认限制 |
限流响应:HTTP 429 + X-RateLimit-Limit / X-RateLimit-Remaining 响应头
每日总配额 = 会员每日权益配额 + 额外配额之和
每月总配额 = 会员每月权益配额 + 额外配额之和
每年总配额 = 会员每年权益配额 + 额外配额之和
额外配额 = SUM(所有有效 grant 的 quota_count - used_count)
1. 优惠券 (COUPON) → 优先使用,避免浪费
2. 额外配额 (EXTRA) → 快过期优先消耗
3. 会员权益配额 (QUOTA) → 兜底
expire_time会员权益通过 t_membership_benefit 表配置,支持运营动态调整:
| 会员等级 | 每日配额 | 每月配额 | 每年配额 | 最大并发 |
|---|---|---|---|---|
| PLUS | 10 | 300 | 3650 | - |
| PRO | 999 | 29970 | 364635 | 5 |
| ULTRA | 999 | 29970 | 364635 | 10 |
用户选择套餐 → 创建订单(PENDING) → 生成支付二维码
→ 用户扫码支付 → 第三方异步回调 → 验签
→ 订单状态更新为PAID → 自动发放会员等级 → 配额生效
用户创建订单(渠道A)→ 切换为渠道B → 生成渠道B二维码
→ 渠道A先回调 → handlePaymentSuccess → 订单PAID,激活会员
→ 渠道B也回调 → processPaidCallback 检查到已PAID
→ handleDuplicatePayment(幂等:同交易号不重复处理)
→ 记录到 t_payment_order_extra_payment(refund_status=PENDING)
→ doRefund() → PaymentRefundService.refund()
├── 微信 → WxPayService.refundV3()
└── 支付宝 → AlipayClient.execute(AlipayTradeRefundRequest)
→ 退款成功:refund_status=SUCCESS, refund_trade_no=xxx
→ 退款失败:refund_status=FAILED, refund_fail_reason=xxx
退款服务:PaymentRefundService 封装微信/支付宝原路退款逻辑,mock模式下模拟退款成功。
| 渠道 | 编码 | 回调地址 | 说明 |
|---|---|---|---|
| 微信支付 | /api/payment/callback/wechat | Native扫码支付(API v3) | |
| 支付宝 | ALIPAY | /api/payment/callback/alipay | 当面付/扫码支付(RSA2验签) |
开发环境(payment.mock=true)支持模拟支付:
生产环境需配置:
CrawlerQuotaGrantService(配额发放)MembershipService(会员时长奖励发放)UserRegisteredEvent)→ UserRegisteredListener → 检查邀请码 → 建立邀请关系 → 发放会员奖励PaymentOrderService.processPaidCallback → 调用 MembershipService 发放对应会员等级handleDuplicatePayment → PaymentRefundService.refund() → 原路退款(微信/支付宝)当前采用单体架构,模块边界清晰:
优势:
| 扩展方向 | 预留设计 | MVP状态 |
|---|---|---|
| 支付渠道 | PaymentChannel 枚举可扩展新渠道 | ✅ 已实现微信/支付宝 |
| 新渠道 | t_invite_config 支持 dingtalk/feishu 等渠道字段 | ✅ 已支持 |
| 新配额来源 | t_crawler_quota_grant.grant_type 可扩展新类型 | ✅ 已支持 |
| 会员权益类型 | t_membership_benefit.benefit_type 可扩展 | ✅ 已支持 |
| 平台扩展 | t_platform_config 支持动态启用/禁用平台 | ✅ 已支持 |
| 操作审计 | OperationType 枚举覆盖9大模块 | ✅ 已实现 |
| 分布式 | 当前单体,模块边界清晰,可拆分为微服务 | ⏳ 后续演进 |
📝 说明:本文档会随着项目迭代持续更新,请以最新版本为准。