Files
work_flow_ishare/SYSTEM_DESIGN.md
Admin 2e34dd172b init: iShare Phase D 设计文档完整归档
文档清单:
- README.md                     仓库导航
- iShare-dev-plan.md            开发规划
- SYSTEM_DESIGN.md              系统设计(角色/流程/接口)
- DATABASE_DESIGN_V2.md         数据库完整字段设计
- DATABASE_DESIGN_OVERVIEW.md   设计概要 v4(28张表)
- DECISIONS.md                  6个关键决策记录
- db/ishare_schema_v2.sql       基础建表 SQL
- db/ishare_schema_v3_delta.sql v2→v3 增量(评审修复)
- db/ishare_schema_v4_delta.sql v3→v4 增量(决策确认)
- memory_2026-02-17.md          工作日志

Phase D 完成:28张表定稿,所有决策已确认
2026-02-17 13:27:34 +01:00

372 lines
14 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.
# iShare 系统设计文档
> 优先级:最高(先于所有开发任务)
> 版本v1.0
> 日期2026-02-17
---
## 一、系统角色
| 角色 | 说明 |
|------|------|
| **普通用户** | 注册登录,购买合租商品,获取账号凭据 |
| **车主(发布者)** | 发布自己的合租位(个人拼车广场) |
| **平台运营(管理员)** | 管理平台数据、自营商品、用户、订单 |
| **超级管理员** | 全局配置,含财务、权限管理 |
---
## 二、功能模块清单
### 2.1 用户端 H5 功能
| 模块 | 功能点 |
|------|--------|
| **账号** | 手机号注册/登录、邮箱注册/登录、找回密码(验证码)、微信/社交登录(二期) |
| **首页** | 平台分类Tab、推荐商品卡片、Banner 广告位、热门合租榜 |
| **商品列表** | 按平台类型筛选、按价格/评分排序、关键词搜索 |
| **商品详情** | 平台介绍、套餐选择(月/季/年)、评价列表、剩余席位数、立即购买 |
| **购买流程** | 选套餐 → 确认订单 → 支付(余额/在线支付)→ 获取账号凭据 |
| **我的订阅** | 当前有效订阅列表、账号凭据查看、续费、退订 |
| **广场/拼车** | 浏览他人发起的合租位、申请加入、发起自己的合租 |
| **推广中心** | 邀请码、邀请记录、返现奖励记录 |
| **钱包** | 余额查看、充值、提现(二期)、流水记录 |
| **通知** | 续费提醒、订单状态变更、系统公告 |
| **个人中心** | 基本信息编辑、头像、安全设置(改密)、退出登录 |
### 2.2 管理后台功能
| 模块 | 功能点 |
|------|--------|
| **平台管理** | 平台CRUD、平台分类CRUD、图标上传 |
| **订阅计划管理** | 计划CRUD、付费方案CRUD多地区/多货币) |
| **自营商品管理** | 商品CRUD、上下架、库存账号管理、绑定账号凭据 |
| **订单管理** | 订单列表、状态查看、人工审核、退款处理 |
| **用户管理** | 用户列表、封禁/解封、余额调整、查看订阅记录 |
| **评价管理** | 评价列表、违规删除 |
| **财务管理** | 收入统计、提现申请审核(二期)、优惠券管理(二期) |
| **通知配置** | 系统通知模板、续费提醒开关 |
| **系统配置** | 站点信息、支付配置、短信/邮件配置 |
---
## 三、核心业务流程
### 3.1 用户注册/登录
```
[用户] → 输入手机/邮箱
→ 获取验证码(短信/邮件)
→ 验证 → 首次登录自动注册 app_user
→ 生成 JWT Token复用 pigx-auth
→ 进入首页
```
### 3.2 购买合租商品(核心流程)
```
[用户] → 浏览商品列表as_sub_product, status=上架)
→ 商品详情页
├── 查看剩余席位 = capacity - capacity_loaded来自 as_user_sub 聚合)
└── 选择付费方案as_sub_payroll
→ 点击"立即购买"
→ 创建订单as_order, status=待支付)
→ 支付
├── 余额支付 → 扣减 as_wallet.balance
└── 在线支付 → 支付宝/微信回调 → 更新订单状态
→ 支付成功
├── 订单状态 → 已支付 → 使用中
├── 创建 as_user_sub 记录capacity_loaded +1
├── 返回账号凭据as_sub_account 解密后展示)
└── 推送通知(订阅成功)
```
### 3.3 账号凭据查看
```
[用户] → "我的订阅" → 选择订阅
→ 验证身份(二次密码/生物识别,可选)
→ 从 as_sub_account 查询 account_name + account_passwd
→ AES 解密 account_passwd服务端解密不返回明文密钥
→ 展示账号密码(可设置自动隐藏倒计时)
```
### 3.4 订阅到期/续费
```
[定时任务(每日凌晨)]
→ 扫描 as_user_sub.expire_time < now() + 7天
→ 发送续费提醒通知as_notification
→ 到期当日as_user_sub.status = expired
→ capacity_loaded -1释放席位
[用户续费]
→ 进入"我的订阅" → 点击续费
→ 选择续费套餐 → 走购买流程(复用)
→ 续费成功as_user_sub.expire_time 延长
```
### 3.5 广场拼车(个人发布)
```
[车主]
→ 填写合租信息(平台、计划、价格、总席位数、说明)
→ 创建 as_sub_productproduct_type=2 个人)
→ 提交审核 → 管理员审核通过 → 上架status=active
[拼车者]
→ 广场浏览 → 找到心仪的拼车
→ 申请加入 → 走购买流程
→ 成功后 → 车主将账号凭据录入 as_sub_account
→ 拼车者可查看凭据
```
### 3.6 推广/邀请
```
[用户A] → 分享邀请码/链接
[用户B] → 点击链接注册
→ as_invite 记录inviter=A, invitee=B
[用户B首次购买成功]
→ 触发返现奖励
→ as_wallet_log 记录用户A 获得返现)
→ as_wallet.balance 增加
```
---
## 四、数据库设计(完整版)
### 4.1 现有表评审与修订
#### ⚠️ 现有设计问题
| 表 | 问题 | 修订方案 |
|----|------|----------|
| `as_sub_account` | `passwd_salt` 是 int不够安全缺加密字段标记 | 改为 varchar salt`encrypt_type` 字段 |
| `as_sub_account` | 缺 `status` 字段(账号可能失效/被封) | 加 `status`: 0=正常,1=失效,2=异常 |
| `as_user_sub` | 缺 `status``start_time``expire_time` | 补充状态和时间字段 |
| `as_user_sub` | `remark` 字段类型是 int应为 varchar | 改为 varchar |
| `as_sub_product` | 缺 `status`(上架/下架/售完)、`available_seats` | 补充状态和实时剩余席位 |
| `as_sub_product` | `sub_plan_ids` 用逗号分隔(反范式) | 评估是否改为关联表(影响查询) |
| `as_sub_payroll` | 缺促销价/折扣字段 | 加 `original_price``discount_rate` |
| `as_platform_type` | `platform_type` 是 int0=全部 含义混乱 | 改用独立 sort_order + is_all 标志位 |
### 4.2 核心业务表(完整版)
#### 保留现有(修订后)
- `as_platform`
- `as_platform_type`
- `as_sub_plan`
- `as_sub_payroll`(加 original_price, discount_rate
- `as_sub_account`(加 status, encrypt_type, 改 passwd_salt 为 varchar
- `as_sub_product`(加 status, available_seats
- `as_sub_product_comment`
- `as_user_sub`(加 status, start_time, expire_time, 改 remark 为 varchar
#### 新增表
---
### `as_order` — 订单表
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | bigint PK | 订单ID |
| `order_no` | varchar(32) | 订单号(唯一,业务用) |
| `user_id` | bigint | 购买用户 |
| `product_id` | bigint | 商品ID (as_sub_product) |
| `payroll_id` | bigint | 付费方案ID (as_sub_payroll) |
| `amount` | decimal(10,2) | 实付金额 |
| `original_amount` | decimal(10,2) | 原价 |
| `discount_amount` | decimal(10,2) | 优惠金额 |
| `pay_type` | tinyint | 支付方式: 1=余额, 2=支付宝, 3=微信 |
| `pay_no` | varchar(64) | 第三方支付单号 |
| `status` | tinyint | 0=待支付, 1=已支付, 2=已完成, 3=已退款, 4=已取消 |
| `user_sub_id` | bigint | 关联的用户订阅ID (创建后填充) |
| `remark` | varchar | 备注 |
| `expire_time` | datetime | 订单过期时间(未支付自动取消) |
| `pay_time` | datetime | 支付时间 |
| `create_time` | datetime | |
| `update_time` | datetime | |
---
### `as_wallet` — 用户钱包
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | bigint PK | |
| `user_id` | bigint UNIQUE | 用户ID一人一钱包 |
| `balance` | decimal(10,2) | 可用余额 |
| `frozen_amount` | decimal(10,2) | 冻结金额(待退款/提现) |
| `total_income` | decimal(10,2) | 累计收入 |
| `total_expense` | decimal(10,2) | 累计支出 |
| `create_time` | datetime | |
| `update_time` | datetime | |
---
### `as_wallet_log` — 钱包流水
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | bigint PK | |
| `user_id` | bigint | 用户ID |
| `amount` | decimal(10,2) | 金额(正=收入,负=支出) |
| `type` | tinyint | 1=充值, 2=消费, 3=退款, 4=邀请返现, 5=提现 |
| `order_id` | bigint | 关联订单ID可空 |
| `balance_after` | decimal(10,2) | 操作后余额(快照) |
| `remark` | varchar | 说明(如"订阅 Netflix 高级版" |
| `create_time` | datetime | |
---
### `as_invite` — 邀请关系
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | bigint PK | |
| `inviter_id` | bigint | 邀请人用户ID |
| `invitee_id` | bigint | 被邀请人用户ID |
| `invite_code` | varchar(16) | 使用的邀请码 |
| `reward_amount` | decimal(10,2) | 返现金额 |
| `reward_status` | tinyint | 0=待发放, 1=已发放(首次购买后触发) |
| `create_time` | datetime | |
| `reward_time` | datetime | 返现时间 |
---
### `as_notification` — 通知消息
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | bigint PK | |
| `user_id` | bigint | 目标用户ID0=全部用户) |
| `title` | varchar | 通知标题 |
| `content` | varchar | 通知内容 |
| `type` | tinyint | 1=续费提醒, 2=订单通知, 3=系统公告, 4=邀请奖励 |
| `ref_id` | bigint | 关联业务ID如订单ID、订阅ID |
| `is_read` | tinyint | 0=未读, 1=已读 |
| `create_time` | datetime | |
---
### `app_user` 字段补充
在现有 PigX 的 `app_user` 表上补充以下字段via ALTER
| 字段 | 类型 | 说明 |
|------|------|------|
| `invite_code` | varchar(16) UNIQUE | 用户的专属邀请码(注册时生成) |
| `inviter_id` | bigint | 邀请人用户ID注册时记录 |
---
### 4.3 完整 ER 关系图
```
as_platform_type (1) ──< (N) as_platform [platform_type]
as_platform (1) ──< (N) as_sub_plan [platform_id]
as_sub_plan (1) ──< (N) as_sub_payroll [sub_plans]
as_sub_plan (N) >──< (N) as_sub_product [sub_plan_ids]
as_sub_product (1) ──< (N) as_sub_product_comment [product_id]
as_sub_product (1) ──< (N) as_sub_account [product_id]
as_sub_plan (1) ──< (N) as_sub_account [sub_plan_id]
as_sub_payroll (1) ──< (N) as_sub_account [sub_payroll_id]
as_sub_product (1) ──< (N) as_order [product_id]
as_sub_payroll (1) ──< (N) as_order [payroll_id]
as_order (1) ──< (1) as_user_sub [user_sub_id]
as_sub_plan (1) ──< (N) as_user_sub [plan_id]
as_sub_account (1) ──< (N) as_user_sub [main_account]
app_user (1) ──< (1) as_wallet [user_id]
as_wallet (1) ──< (N) as_wallet_log [user_id]
as_order (1) ──< (N) as_wallet_log [order_id]
app_user (1) ──< (N) as_order [user_id]
app_user (1) ──< (N) as_user_sub [user_id]
app_user (1) ──< (N) as_sub_product [user_id — 发布者]
app_user (1) ──< (N) as_sub_account [user_id — 账号持有者]
app_user (1) ──< (N) as_sub_product_comment [user_id]
app_user (1) ──< (N) as_notification [user_id]
app_user (1) ──< (N) as_invite [as inviter] [inviter_id]
app_user (1) ──< (1) as_invite [as invitee] [invitee_id]
```
### 4.4 `as_user_sub` 状态机
```
购买成功
[pending] ──────→ [active] ──→ 到期 ──→ [expired]
│ │
│ 退款/申请退订 │ 续费
↓ ↓
[cancelled] [active]
```
状态值0=待激活, 1=使用中, 2=已到期, 3=已退订
### 4.5 `as_order` 状态机
```
[pending] → 15分钟未支付 → [cancelled]
[pending] → 支付成功 → [paid] → 激活订阅成功 → [completed]
[paid/completed] → 退款申请 → 审核通过 → [refunded]
```
---
## 五、接口设计要点
### 5.1 账号凭据安全
- `account_passwd` 使用 **AES-256-GCM** 加密存储
- 密钥由服务端持有(存配置中心/环境变量),不入库
- `passwd_salt` 用于 AES 的 IV改为 varchar(32)16字节随机
- 凭据查看接口:仅限订阅状态为 `active` 的用户,且需校验 `as_user_sub.user_id == currentUser`
- 返回解密后的明文,但 **不记录日志**(防止泄露)
### 5.2 席位并发控制
- 购买时使用 **数据库乐观锁****Redis 分布式锁** 防止超卖
- `as_sub_product.available_seats` 在下单时 -1乐观锁 version 字段)
- 订单取消/超时后 +1 回补
### 5.3 价格一致性
- 订单金额在创建时 **快照**`as_order.amount`
- 不依赖付费方案的实时价格(防止价格变动导致差异)
---
## 六、设计待决策项(需 Ami 确认)
| # | 问题 | 选项 |
|---|------|------|
| 1 | 付费方式一期支持哪些? | A) 仅余额人工充值B) 余额+支付宝 C) 三种都支持 |
| 2 | 拼车广场是否需要审核流程? | A) 管理员审核 B) 自动上架 C) 仅自营,无拼车广场 |
| 3 | 账号凭据展示方式? | A) 直接明文 B) 需二次验证(短信/密码C) 限时展示30s后隐藏|
| 4 | 邀请返现比例和条件? | 需定义:返现金额/比例,是否有上限 |
| 5 | `as_sub_product` 的多计划关联是否改为关联表? | A) 保持逗号分隔简单B) 改关联表(规范,便于查询)|
| 6 | 提现功能是否一期上线? | A) 一期上 B) 二期(一期只充值不提现)|
---
## 七、调整后的项目阶段
| 阶段 | 内容 | 时间 |
|------|------|------|
| **Phase D当前·最高优先** | 系统设计:功能清单 + 业务流程 + 数据库设计 | 进行中 |
| **Phase 0** | 环境搭建:仓库 + Fork PigX + CI/CD + 建库 SQL | D 完成后 |
| **Phase 1** | 后端核心 CRUD API | 1-2周 |
| **Phase 2** | 管理后台前端 | 1周 |
| **Phase 3** | 用户端 H5 | 2-3周 |
| **Phase 4** | 支付集成 | 按需 |
| **Phase 5** | 测试 + 上线 | — |