From 2e34dd172b13f35312d15345ca7528b478aecdcf Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 17 Feb 2026 13:27:34 +0100 Subject: [PATCH] =?UTF-8?q?init:=20iShare=20Phase=20D=20=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E5=AE=8C=E6=95=B4=E5=BD=92=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 文档清单: - 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张表定稿,所有决策已确认 --- DATABASE_DESIGN_OVERVIEW.md | 232 ++++++++++++++++++ DATABASE_DESIGN_V2.md | 427 ++++++++++++++++++++++++++++++++++ DECISIONS.md | 108 +++++++++ README.md | 66 +++++- SYSTEM_DESIGN.md | 371 +++++++++++++++++++++++++++++ db/ishare_schema_v2.sql | 370 +++++++++++++++++++++++++++++ db/ishare_schema_v3_delta.sql | 129 ++++++++++ db/ishare_schema_v4_delta.sql | 59 +++++ iShare-dev-plan.md | 277 ++++++++++++++++++++++ memory_2026-02-17.md | 201 ++++++++++++++++ 10 files changed, 2238 insertions(+), 2 deletions(-) create mode 100644 DATABASE_DESIGN_OVERVIEW.md create mode 100644 DATABASE_DESIGN_V2.md create mode 100644 DECISIONS.md create mode 100644 SYSTEM_DESIGN.md create mode 100644 db/ishare_schema_v2.sql create mode 100644 db/ishare_schema_v3_delta.sql create mode 100644 db/ishare_schema_v4_delta.sql create mode 100644 iShare-dev-plan.md create mode 100644 memory_2026-02-17.md diff --git a/DATABASE_DESIGN_OVERVIEW.md b/DATABASE_DESIGN_OVERVIEW.md new file mode 100644 index 0000000..cdd41c2 --- /dev/null +++ b/DATABASE_DESIGN_OVERVIEW.md @@ -0,0 +1,232 @@ +# iShare 数据库设计概要 + +> 版本:v4(决策确认后最终版) +> 修订时间:2026-02-17 +> 完整建表 SQL(v2 基础版):`db/ishare_schema_v2.sql` +> 增量 SQL:`db/ishare_schema_v3_delta.sql` → `db/ishare_schema_v4_delta.sql` +> 完整字段说明:`DATABASE_DESIGN_V2.md` +> 设计决策记录:`DECISIONS.md` + +--- + +## 一、表总览(28 张表) + +### 1.1 App 基础表(复用 PigX,共 9 张) + +| # | 表名 | 说明 | 变更 | +|---|------|------|------| +| 1 | `app_user` | 用户 | 追加 `invite_code`、`inviter_id` | +| 2-9 | `app_role` / `app_user_role` / `app_social_details` / `app_article*` / `app_page` / `app_tabbar` | 框架基础 | 沿用 | + +### 1.2 业务表(iShare 专属,共 19 张) + +#### 平台与产品 + +| # | 表名 | 说明 | Phase | +|---|------|------|-------| +| 10 | `as_platform_type` | 平台分类 | P1 | +| 11 | `as_platform` | 流媒体平台 | P1 | +| 12 | `as_sub_plan` | 订阅计划 | P1 | +| 13 | `as_sub_payroll` | 付费方案(月/季/年) | P1 | +| 14 | `as_sub_product` | 合租商品(P1仅 type=1 自营) | P1 | +| 15 | `as_product_plan_rel` | 产品-计划 M:N 关联 | P1 | +| 16 | `as_sub_account` | 平台账号凭据(AES 加密) | P1 | +| 17 | `as_sub_product_comment` | 商品评价 | P1 | +| 18 | `as_banner` | 首页 Banner 广告位 | P1 | + +#### 订阅与订单 + +| # | 表名 | 说明 | Phase | +|---|------|------|-------| +| 19 | `as_user_sub` | 合租槽/共享池 | P1 | +| 20 | `as_user_sub_member` | 个人订阅记录(status=4 P2用) | P1 | +| 21 | `as_order` | 订单(三种支付方式,复用 pigx-pay) | P1 | + +#### 钱包与推广 + +| # | 表名 | 说明 | Phase | +|---|------|------|-------| +| 22 | `as_recharge` | 充值单(人工/支付宝/微信) | P1 | +| 23 | `as_wallet` | 用户钱包(乐观锁防并发) | P1 | +| 24 | `as_wallet_log` | 钱包流水(type=5 提现 P2用) | P1 | +| 25 | `as_invite` | 邀请关系与返现记录 | P1 | +| 26 | `as_invite_config` | 邀请返现规则配置(可配置) | P1 | +| 27 | `as_notification` | 系统通知 | P1 | + +--- + +## 二、核心 ER 关系概览 + +``` +as_platform_type (1) ──< (N) as_platform +as_platform (1) ──< (N) as_sub_plan +as_sub_plan (1) ──< (N) as_sub_payroll +as_sub_plan (N) >──< (N) as_sub_product [via as_product_plan_rel] +as_platform (1) ──< (N) as_sub_product [platform_id 冗余] + +as_sub_product (1) ──< (N) as_sub_account +as_sub_product (1) ──< (N) as_user_sub +as_user_sub (1) ──< (N) as_user_sub_member + +as_sub_product (1) ──< (N) as_order +as_order (1) ──< (1) as_user_sub_member [order_id] + +app_user (1) ──< (1) as_wallet +as_wallet (1) ──< (N) as_wallet_log +as_wallet (1) ──< (N) as_recharge [user_id] +app_user (1) ──< (N) as_order +app_user (1) ──< (N) as_recharge +app_user (1) ──< (N) as_user_sub_member +app_user (1) ──< (N) as_invite [as inviter] +app_user (1) ──< (1) as_invite [as invitee] +app_user (1) ──< (N) as_notification + +as_invite_config (1:active) ──→ as_invite [规则快照到 reward_amount] +``` + +--- + +## 三、关键状态机 + +### 3.1 订单(as_order) + +``` +[待支付(0)] ─→ 15min 超时 ─→ [已取消(4)] +[待支付(0)] ─→ 支付成功 ─→ [已支付(1)] ─→ 激活订阅 ─→ [已完成(2)] +[已支付/完成] ─→ 退款 ─→ [已退款(3)] +``` + +**支付方式:** 1=余额 / 2=支付宝 / 3=微信(均通过 pigx-pay 模块处理) + +### 3.2 充值单(as_recharge) + +``` +人工充值(管理员): 直接创建 status=1 记录 +外部支付: + [待支付(0)] ─→ 支付成功 ─→ [已到账(1)] ─→ as_wallet.balance +amount + ─→ 15min 超时 ─→ [已取消(3)] + ─→ 支付失败 ─→ [失败(2)] +``` + +### 3.3 个人订阅(as_user_sub_member) + +``` +[待激活(0)] ─→ 订单完成 ─→ [使用中(1)] +[使用中(1)] ─→ 到期 ─→ [已到期(2)] ─→ 续费 → 新建记录回到[待激活(0)] + ─→ 主动退订 ─→ [已退订(3)] + +[Phase2] 拼车广场付款后 → [等待车主录入凭据(4)] → 车主录入 → [使用中(1)] +``` + +> 续费策略:新建 member 记录,旧记录置为2=已到期(保留历史,便于对账) + +### 3.4 合租槽(as_user_sub) + +``` +[可加入(0)] ─→ 席位满 ─→ [已满(1)] +[可加入/已满] ─→ 到期 ─→ [已到期(2)] + ─→ 车主关闭 ─→ [已关闭(3)] +``` + +--- + +## 四、关键设计机制 + +### 4.1 席位超卖防护(乐观锁) + +```sql +UPDATE as_user_sub +SET capacity_loaded = capacity_loaded + 1 +WHERE id = ? AND capacity_loaded < capacity; +-- affected rows = 0 → 席位已满,拒绝购买 +``` + +### 4.2 账号凭据安全 + +- 存储:AES-256-GCM 加密,密钥存环境变量不入库 +- 查看:**需二次验证(SMS OTP 或密码重输),OTP 存 Redis TTL 5min** +- 返回:服务端解密后返回明文,不记录日志,前端倒计时隐藏 + +### 4.3 支付集成 + +- **复用 pigx-pay 模块**(已集成支付宝 + 微信) +- 购买商品 → `as_order`(pay_type 2/3)→ pigx-pay 回调 → 更新订单状态 → 创建 member 记录 +- 余额充值 → `as_recharge`(pay_type 2/3)→ pigx-pay 回调 → 更新充值单 → 增加钱包余额 + +### 4.4 邀请返现(可配置规则) + +``` +1. 管理后台配置 as_invite_config(选择激活规则) +2. 被邀请人注册 → 写入 as_invite 记录 +3. 触发条件满足(首次购买 or 每次购买) + → 读取当前 is_active=1 的 as_invite_config + → 计算返现金额(快照到 as_invite.reward_amount) + → 延迟发放(reward_delay_days 天后) + → as_wallet_log(type=4)+ as_wallet.balance +reward_amount +``` + +### 4.5 钱包余额并发控制(乐观锁) + +```sql +UPDATE as_wallet +SET balance = balance - ?, version = version + 1 +WHERE user_id = ? AND version = ? AND balance >= ?; +-- affected rows = 0 → 并发冲突或余额不足 +``` + +### 4.6 订阅到期定时任务(每日 02:00) + +``` +1. expire_time < now()+7天 且 status=1 → 推送续费提醒 +2. expire_time < now() 且 status=1 → 置 status=2,capacity_loaded -1 +3. as_order.expire_time < now() 且 status=0 → 置 status=4(取消) +4. as_recharge.expire_time < now() 且 status=0 → 置 status=3(取消) +``` + +--- + +## 五、关键索引清单 + +| 表 | 索引字段 | 用途 | +|----|---------|------| +| `as_user_sub_member` | `(user_id, status)` | 我的订阅列表 | +| `as_user_sub_member` | `(expire_time, status)` | 定时任务扫描到期 | +| `as_order` | `(user_id, status)` | 用户订单列表 | +| `as_notification` | `(user_id, is_read)` | 未读通知数 | +| `as_user_sub` | `(product_id, status)` | 商品可用合租槽 | +| `as_sub_account` | `(product_id, status)` | 产品账号列表 | +| `as_sub_product` | `(product_type, status)` | 商品分类查询 | +| `as_banner` | `(status, sort_order)` | 首页 Banner | +| `as_recharge` | `(user_id, status)` | 充值记录查询 | +| `as_product_plan_rel` | `(product_id)` / `(plan_id)` | M:N 双向查询 | +| `as_invite_config` | `(is_active)` | 读取当前规则 | + +--- + +## 六、版本变更记录 + +| 版本 | 变更内容 | +|------|----------| +| v1 | 原版骨架(2023-08,有多项严重缺陷) | +| v2 | 全面修订:修复15项缺陷,新增6张表(23张) | +| v3 | 评审修订:修复7个问题,新增3张表(27张) | +| **v4** | **决策确认:新增 `as_invite_config`(28张),Phase 1/2 范围明确** | + +--- + +## 七、所有待决策项(已全部确认 ✅) + +| # | 问题 | 决策 | +|---|------|------| +| 1 | 付费方式一期 | ✅ C - 余额+支付宝+微信(复用 pigx-pay) | +| 2 | 拼车广场 | ✅ C - Phase 1 不做,Phase 2 追加 | +| 3 | 凭据展示 | ✅ B - 二次验证(SMS OTP 或密码重输) | +| 4 | 邀请返现 | ✅ 完全可配置(类型/金额/触发条件),无上限 | +| 5 | M:N 关联 | ✅ v3 已改为 `as_product_plan_rel` | +| 6 | 提现功能 | ✅ B - Phase 2,一期只充值+消费 | + +**Phase D(系统设计)✅ 全部完成** + +--- + +*最后更新:2026-02-17 · v4 定稿* diff --git a/DATABASE_DESIGN_V2.md b/DATABASE_DESIGN_V2.md new file mode 100644 index 0000000..9822c69 --- /dev/null +++ b/DATABASE_DESIGN_V2.md @@ -0,0 +1,427 @@ +# iShare 数据库设计 v2.0(修订版) + +> 基于原版 v1.0(2023-08 骨架)审查后全面修订 +> 修订时间: 2026-02-17 +> 建表脚本: `db/ishare_schema_v2.sql` + +--- + +## 一、修订说明 + +### 1.1 原版问题总结 + +| 类型 | 数量 | 说明 | +|------|------|------| +| 🔴 严重缺陷 | 4 项 | 直接导致核心功能不可用 | +| 🟠 重要问题 | 6 项 | 数据类型错误/查询困难 | +| 🟡 设计缺失 | 5 项 | 运营/安全功能不完整 | + +### 1.2 修订内容 + +| 表名 | 修订类型 | 主要变更 | +|------|----------|----------| +| `as_platform_type` | 补充 | 加 `status`、`del_flag`、时间戳;`sort_order` varchar→int | +| `as_platform` | 补充 | 加 `description`、`status`、`del_flag`、时间戳;`sort_order` varchar→int | +| `as_sub_plan` | 修复+补充 | `platform_id` varchar→**bigint**;`capacity` varchar→**int**;加状态/软删除/时间戳 | +| `as_sub_payroll` | 重构 | `sub_plans`→**`sub_plan_id`**(语义明确);加 `duration_months`、`original_price`、`is_active`;软删除/时间戳 | +| `as_sub_product` | 修复+补充 | **`Tags`→`tags`**(命名修复);加 `platform_id`、`cover_image`、`status`、`total_capacity`;`product_type`/`sub_type` Long→**tinyint** | +| `as_sub_account` | 修复+补充 | 4个字段 int→**bigint**;`passwd_salt` int→**varchar(64)**;加 `encrypt_type`、`status`、软删除/时间戳 | +| `as_user_sub` | 语义修订+修复 | 重定义为"合租槽(共享池)";`remark` int→**varchar**;字段 int→bigint;加 `product_id`、`status`、`expire_time`、软删除/时间戳;`user_id`→`host_user_id`(语义明确);`main_account`→`account_id` | +| `as_sub_product_comment` | 补充 | 加 `order_id`(购买验证)、`is_anonymous`、`reply_id`(追评)、`del_flag` | +| `as_user_sub_member` | **新增** | 个人订阅记录(原版最大缺失),含 `status`、`start_time`、`expire_time` | +| `as_order` | **新增** | 完整订单表(含状态机、价格快照、支付信息) | +| `as_wallet` | **新增** | 用户钱包(含乐观锁 `version` 防并发) | +| `as_wallet_log` | **新增** | 钱包流水(含 `balance_after` 快照便于对账) | +| `as_invite` | **新增** | 邀请关系与返现 | +| `as_notification` | **新增** | 系统通知(续费提醒/订单/公告/奖励) | +| `app_user` | 追加字段 | 加 `invite_code`(专属邀请码)、`inviter_id` | + +--- + +## 二、表结构(v2.0) + +### 2.1 `as_platform_type` — 平台类型 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `id` | bigint PK | 主键 | +| `name` | varchar(64) NOT NULL | 类型名称(视频/音乐/AI等) | +| `platform_type` | int DEFAULT 0 | 类型编号(0=全部,用于筛选) | +| `sort_order` | int DEFAULT 0 | 排序权重(升序,**原为 varchar**) | +| `status` | tinyint DEFAULT 1 | **新增** 0=禁用, 1=启用 | +| `del_flag` | char(1) DEFAULT '0' | **新增** 软删除 | +| `create_time` | datetime | **新增** | +| `update_time` | datetime | **新增** | + +### 2.2 `as_platform` — 流媒体平台 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `id` | bigint PK | 主键 | +| `platform_name` | varchar(128) NOT NULL | 平台名称 | +| `platform_type` | int DEFAULT 0 | 关联类型编号 | +| `icon` | varchar(512) | 图标 URL | +| `description` | varchar(512) | **新增** 平台简介 | +| `company` | varchar(128) | 所属公司 | +| `website` | varchar(256) | 官网 | +| `sort_order` | int DEFAULT 0 | 排序(**原为 varchar**) | +| `status` | tinyint DEFAULT 1 | **新增** 0=禁用, 1=启用 | +| `del_flag` | char(1) DEFAULT '0' | **新增** 软删除 | +| `create_time` | datetime | **新增** | +| `update_time` | datetime | **新增** | + +### 2.3 `as_sub_plan` — 订阅计划 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `id` | bigint PK | 主键 | +| `name` | varchar(128) NOT NULL | 计划名称 | +| `platform_id` | bigint NOT NULL | 所属平台(**原为 varchar,已修复**) | +| `capacity` | int NOT NULL DEFAULT 1 | 席位容量(**原为 varchar,已修复**) | +| `remark` | varchar(256) | 备注 | +| `sort_order` | int DEFAULT 0 | 排序 | +| `status` | tinyint DEFAULT 1 | **新增** 0=禁用, 1=启用 | +| `del_flag` | char(1) DEFAULT '0' | **新增** 软删除 | +| `create_time` | datetime | **新增** | +| `update_time` | datetime | **新增** | + +### 2.4 `as_sub_payroll` — 付费方案 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `id` | bigint PK | 主键 | +| `sub_plan_id` | bigint NOT NULL | 所属订阅计划(**原 `sub_plans` 注释混乱,已重命名+澄清**) | +| `platform_id` | bigint NOT NULL | 平台ID(冗余) | +| `payroll` | tinyint NOT NULL | 周期: 1=月付, 2=季付, 3=年付 | +| `duration_months` | int NOT NULL | **新增** 实际月数: 1/3/12 | +| `price` | decimal(10,2) | 售价 | +| `original_price` | decimal(10,2) | **新增** 划线价(显示折扣用) | +| `currency` | varchar(8) DEFAULT 'CNY' | 货币单位 | +| `region` | varchar(64) | 适用地区 | +| `is_active` | tinyint DEFAULT 1 | **新增** 0=下架, 1=上架 | +| `del_flag` | char(1) DEFAULT '0' | **新增** 软删除 | +| `create_time` | datetime | **新增** | +| `update_time` | datetime | **新增** | + +### 2.5 `as_sub_product` — 订阅产品(合租商品) + +| 字段 | 类型 | 说明 | +|------|------|------| +| `id` | bigint PK | 主键 | +| `title` | varchar(256) NOT NULL | 产品标题 | +| `description` | varchar(1024) | 描述 | +| `cover_image` | varchar(512) | **新增** 封面图 URL | +| `tags` | varchar(256) | 标签(逗号分隔,**原字段名 `Tags` 大写 Bug 已修复**) | +| `platform_id` | bigint NOT NULL | **新增** 所属平台(加速查询) | +| `sub_plan_ids` | varchar(256) | 关联计划ID列表(逗号分隔,保留现状) | +| `product_type` | tinyint NOT NULL DEFAULT 1 | 1=自营, 2=个人(**原为 Long,已修复**) | +| `sub_type` | tinyint NOT NULL DEFAULT 1 | 1=单品, 2=多品组合(**原为 Long,已修复**) | +| `total_capacity` | int NOT NULL DEFAULT 1 | **新增** 总席位数 | +| `amount` | decimal(10,2) | 基准月价 | +| `star` | decimal(3,1) DEFAULT 0.0 | 综合评分(由评价聚合更新) | +| `status` | tinyint NOT NULL DEFAULT 0 | **新增** 0=草稿, 1=上架, 2=下架, 3=售完 | +| `user_id` | bigint | 发布者用户ID | +| `del_flag` | char(1) DEFAULT '0' | **新增** 软删除 | +| `create_by` / `update_by` | varchar(64) | **新增** | +| `create_time` / `update_time` | datetime | | + +### 2.6 `as_sub_account` — 平台账号凭据 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `id` | bigint PK | 主键 | +| `product_id` | bigint | 关联产品ID | +| `sub_plan_id` | bigint | 订阅计划ID(**原 int,已修复**) | +| `sub_payroll_id` | bigint | 付费方案ID(**原 int,已修复**) | +| `platform_id` | bigint NOT NULL | 平台ID(**原 int,已修复**) | +| `user_id` | bigint NOT NULL | 账号持有者(**原 int,已修复**) | +| `account_name` | varchar(256) NOT NULL | 平台登录用户名/邮箱 | +| `account_passwd` | varchar(512) NOT NULL | 加密后的密码 | +| `passwd_salt` | varchar(64) NOT NULL | 加密盐值(**原 int 已修复为 varchar(64)**) | +| `encrypt_type` | tinyint NOT NULL DEFAULT 1 | **新增** 加密算法: 1=AES-256-GCM | +| `region` | varchar(64) | 账号地区 | +| `share_type` | tinyint | 分享类型 | +| `account_type` | tinyint | 账号类型 | +| `renew_date` | datetime | 账号下次续费日 | +| `status` | tinyint NOT NULL DEFAULT 0 | **新增** 0=正常, 1=已失效, 2=异常/被封 | +| `del_flag` | char(1) DEFAULT '0' | **新增** 软删除 | +| `create_time` / `update_time` | datetime | **新增** | + +### 2.7 `as_user_sub` — 合租槽(共享池) + +> 语义修订:代表"一个共享席位池",不代表个人订阅。个人订阅记录见 `as_user_sub_member`。 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `id` | bigint PK | 主键 | +| `product_id` | bigint NOT NULL | **新增** 关联产品 | +| `plan_id` | bigint NOT NULL | 订阅计划(**原 int,已修复**) | +| `platform_id` | bigint NOT NULL | 平台(冗余) | +| `host_user_id` | bigint NOT NULL | **重命名自 `user_id`**,车主用户ID(语义明确) | +| `account_id` | bigint | **重命名自 `main_account`**,关联凭据(语义明确) | +| `capacity` | int NOT NULL | 总席位数 | +| `capacity_loaded` | int NOT NULL DEFAULT 0 | 已占用席位数 | +| `region` | varchar(64) | 地区 | +| `status` | tinyint NOT NULL DEFAULT 0 | **新增** 0=可加入, 1=已满, 2=已到期, 3=已关闭 | +| `expire_time` | datetime | **新增** 合租槽到期时间 | +| `remark` | varchar(512) | 车主说明(**原 int,已修复为 varchar**) | +| `del_flag` | char(1) DEFAULT '0' | **新增** 软删除 | +| `create_time` / `update_time` | datetime | **新增** | + +### 2.8 `as_sub_product_comment` — 产品评价 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `id` | bigint PK | 主键 | +| `product_id` | bigint NOT NULL | 关联产品 | +| `user_id` | bigint NOT NULL | 评价用户 | +| `order_id` | bigint | **新增** 关联订单(验证是否购买过) | +| `star` | tinyint NOT NULL | 评分 1-5 | +| `comment` | varchar(1024) | 评价内容 | +| `is_anonymous` | tinyint DEFAULT 0 | **新增** 0=公开, 1=匿名 | +| `reply_id` | bigint | **新增** 回复的评价ID(追评/商家回复) | +| `del_flag` | char(1) DEFAULT '0' | **新增** 软删除 | +| `create_time` / `update_time` | datetime | | + +### 2.9 `as_user_sub_member` — 个人订阅记录 【新增,原版最大缺失】 + +> 原版无此表,导致"哪些用户加入了哪个合租位"完全无法追踪。 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `id` | bigint PK | 主键 | +| `sub_id` | bigint NOT NULL | 所在合租槽(→ `as_user_sub.id`) | +| `user_id` | bigint NOT NULL | 订阅用户 | +| `order_id` | bigint NOT NULL | 来源订单(→ `as_order.id`) | +| `payroll_id` | bigint NOT NULL | 购买的付费方案 | +| `status` | tinyint NOT NULL DEFAULT 0 | 0=待激活, 1=使用中, 2=已到期, 3=已退订 | +| `start_time` | datetime NOT NULL | 订阅开始时间 | +| `expire_time` | datetime NOT NULL | 订阅到期时间 | +| `del_flag` | char(1) DEFAULT '0' | 软删除 | +| `create_time` / `update_time` | datetime | | +| UK: `(sub_id, user_id)` | — | 同一合租槽同一用户只能有一条有效记录 | + +### 2.10 `as_order` — 订单表 【新增】 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `id` | bigint PK | 主键 | +| `order_no` | varchar(32) UNIQUE | 业务订单号(AS+时间戳+随机) | +| `user_id` | bigint NOT NULL | 购买用户 | +| `product_id` | bigint NOT NULL | 商品 | +| `payroll_id` | bigint NOT NULL | 付费方案 | +| `original_amount` | decimal(10,2) | 原价快照(防价格变动) | +| `discount_amount` | decimal(10,2) DEFAULT 0 | 优惠金额 | +| `amount` | decimal(10,2) | 实付金额 | +| `pay_type` | tinyint | 1=余额, 2=支付宝, 3=微信 | +| `pay_no` | varchar(64) | 第三方支付单号 | +| `status` | tinyint NOT NULL DEFAULT 0 | 0=待支付, 1=已支付, 2=已完成, 3=已退款, 4=已取消 | +| `member_id` | bigint | 关联个人订阅记录(支付后填充) | +| `expire_time` | datetime NOT NULL | 订单过期时间(默认 +15min)| +| `pay_time` | datetime | 实际支付时间 | +| `del_flag` | char(1) DEFAULT '0' | 软删除 | +| `create_time` / `update_time` | datetime | | + +**订单状态机:** +``` +[待支付] → 15分钟超时 → [已取消] +[待支付] → 支付成功 → [已支付] → 激活订阅 → [已完成] +[已支付/已完成] → 退款 → [已退款] +``` + +### 2.11 `as_wallet` — 用户钱包 【新增】 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `id` | bigint PK | 主键 | +| `user_id` | bigint UNIQUE | 用户(一人一钱包) | +| `balance` | decimal(10,2) | 可用余额 | +| `frozen_amount` | decimal(10,2) | 冻结金额 | +| `total_income` | decimal(10,2) | 累计收入 | +| `total_expense` | decimal(10,2) | 累计支出 | +| `version` | int DEFAULT 0 | 乐观锁版本号(防并发余额错误) | +| `create_time` / `update_time` | datetime | | + +### 2.12 `as_wallet_log` — 钱包流水 【新增】 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `id` | bigint PK | 主键 | +| `user_id` | bigint NOT NULL | 用户 | +| `amount` | decimal(10,2) | 金额(正=收入, 负=支出) | +| `type` | tinyint | 1=充值, 2=消费, 3=退款, 4=邀请返现, 5=提现 | +| `order_id` | bigint | 关联订单(可空) | +| `balance_after` | decimal(10,2) | 操作后余额快照(对账用) | +| `remark` | varchar(256) | 说明 | +| `create_time` | datetime | | + +### 2.13 `as_invite` — 邀请关系 【新增】 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `id` | bigint PK | 主键 | +| `inviter_id` | bigint NOT NULL | 邀请人 | +| `invitee_id` | bigint NOT NULL UNIQUE | 被邀请人(一个人只有一条邀请记录) | +| `invite_code` | varchar(16) | 使用的邀请码 | +| `reward_amount` | decimal(10,2) | 返现金额 | +| `reward_status` | tinyint DEFAULT 0 | 0=待发放, 1=已发放, 2=已失效 | +| `reward_time` | datetime | 返现时间 | +| `create_time` | datetime | 注册时间 | + +### 2.14 `as_notification` — 系统通知 【新增】 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `id` | bigint PK | 主键 | +| `user_id` | bigint NOT NULL | 目标用户(0=全体广播) | +| `title` | varchar(128) | 通知标题 | +| `content` | varchar(1024) | 通知内容 | +| `type` | tinyint | 1=续费提醒, 2=订单通知, 3=系统公告, 4=邀请奖励 | +| `ref_id` | bigint | 关联业务ID(按 type 解析) | +| `is_read` | tinyint DEFAULT 0 | 0=未读, 1=已读 | +| `create_time` | datetime | | + +--- + +## 三、完整 ER 关系图(v2.0) + +``` +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_plan_id] +as_sub_plan (N) >──< (N) as_sub_product [sub_plan_ids 逗号分隔] +as_platform (1) ──< (N) as_sub_product [platform_id 冗余] + +as_sub_product (1) ──< (N) as_sub_product_comment [product_id] +as_sub_product (1) ──< (N) as_sub_account [product_id] +as_sub_product (1) ──< (N) as_user_sub [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_user_sub (1) ──< (N) as_user_sub_member [sub_id] ← 新增关键表 +as_order (1) ──< (1) as_user_sub_member [order_id] +as_sub_payroll (1) ──< (N) as_user_sub_member [payroll_id] + +as_sub_product (1) ──< (N) as_order [product_id] +as_sub_payroll (1) ──< (N) as_order [payroll_id] +as_order (1) ──< (N) as_wallet_log [order_id] + +app_user (1) ──< (1) as_wallet [user_id] +as_wallet (1) ──< (N) as_wallet_log [user_id] + +app_user (1) ──< (N) as_order [user_id] +app_user (1) ──< (N) as_user_sub [as host] [host_user_id] +app_user (1) ──< (N) as_user_sub_member [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] +``` + +--- + +## 四、`as_user_sub_member` 状态机 + +``` + 购买成功(order paid) +[待激活] ──────────────→ [使用中] + │ + ┌───────────┤ + │ │ + 主动退订 到期 + │ │ + ↓ ↓ + [已退订] [已到期] + │ + 续费 + │ + ↓ + [使用中] +``` + +--- + +## 五、重要设计说明 + +### 5.1 容量管理与并发控制 + +**席位超卖防护:** +- `as_sub_product.total_capacity` — 总席位(固定值) +- `as_user_sub.capacity_loaded` — 已占用(购买时 +1,退订/到期时 -1) +- 购买时通过 **乐观锁** 控制: + ```sql + UPDATE as_user_sub + SET capacity_loaded = capacity_loaded + 1 + WHERE id = ? AND capacity_loaded < capacity + ``` + 更新行数 = 0 则说明已满,拒绝购买 + +### 5.2 账号凭据加密 + +- 算法:AES-256-GCM(`encrypt_type = 1`) +- `account_passwd`:密文(Base64 编码) +- `passwd_salt`:随机 IV(16字节,Base64 编码,**原 int 类型错误已修复**) +- 密钥:存于服务端配置/环境变量,不入库 + +### 5.3 钱包余额并发控制 + +- `as_wallet.version` 字段实现乐观锁: + ```sql + UPDATE as_wallet + SET balance = balance - ?, version = version + 1 + WHERE user_id = ? AND version = ? AND balance >= ? + ``` + 更新行数 = 0 则说明并发冲突或余额不足 + +### 5.4 订阅到期任务 + +定时任务(建议每日 02:00): +``` +1. 查询 expire_time < now() + 7d 且 status = 1 的 as_user_sub_member + → 生成 as_notification(type=1,续费提醒) + +2. 查询 expire_time < now() 且 status = 1 的 as_user_sub_member + → UPDATE status = 2(已到期) + → UPDATE as_user_sub SET capacity_loaded = capacity_loaded - 1 +``` + +### 5.5 评价限制 + +- 写评价前校验:`as_order` 存在且 `status IN (2,3)` 且 `user_id` 匹配 +- `star` 范围 1-5,服务端强制校验 +- `as_sub_product.star` 由定时任务或触发器聚合更新(AVG) + +--- + +## 六、数据库表总览(v2.0) + +| # | 表名 | 类型 | 状态 | +|---|------|------|------| +| 1 | `app_user` | App基础 | 追加2字段 | +| 2 | `app_role` | App基础 | 沿用 | +| 3 | `app_user_role` | App基础 | 沿用 | +| 4 | `app_social_details` | App基础 | 沿用 | +| 5 | `app_article_category` | App基础 | 沿用 | +| 6 | `app_article` | App基础 | 沿用 | +| 7 | `app_article_collect` | App基础 | 沿用 | +| 8 | `app_page` | App基础 | 沿用 | +| 9 | `app_tabbar` | App基础 | 沿用 | +| 10 | `as_platform_type` | 业务 | 修订 | +| 11 | `as_platform` | 业务 | 修订 | +| 12 | `as_sub_plan` | 业务 | 修订 | +| 13 | `as_sub_payroll` | 业务 | 修订 | +| 14 | `as_sub_product` | 业务 | 修订 | +| 15 | `as_sub_account` | 业务 | 修订 | +| 16 | `as_user_sub` | 业务 | 修订(语义重定义) | +| 17 | `as_sub_product_comment` | 业务 | 修订 | +| 18 | `as_user_sub_member` | 业务 | **新增** | +| 19 | `as_order` | 业务 | **新增** | +| 20 | `as_wallet` | 业务 | **新增** | +| 21 | `as_wallet_log` | 业务 | **新增** | +| 22 | `as_invite` | 业务 | **新增** | +| 23 | `as_notification` | 业务 | **新增** | + +合计:9 张 App 基础表 + 14 张业务表 = **23 张表** diff --git a/DECISIONS.md b/DECISIONS.md new file mode 100644 index 0000000..4b2c976 --- /dev/null +++ b/DECISIONS.md @@ -0,0 +1,108 @@ +# iShare 设计决策记录 + +> 决策时间:2026-02-17 +> 阶段:Phase D(系统设计) + +--- + +## 决策1:付费方式(一期) + +**结论:C — 余额 + 支付宝 + 微信全支持** + +**原因:** PigX 框架已集成支付功能,无需自行实现,接入成本低。 + +**影响:** +- `as_order.pay_type`:1=余额, 2=支付宝, 3=微信 ✅(已支持) +- `as_recharge.pay_type`:同上 ✅ +- 支付接入:复用 `pigx-pay` 模块,配置支付宝/微信商户信息即可 + +--- + +## 决策2:拼车广场 + +**结论:C — 一期不做广场,仅平台自营商品** + +**原因:** 简化一期功能,降低开发复杂度;拼车广场作为 Phase 2 功能后续追加。 + +**影响:** +- `as_sub_product.product_type=2`(个人发布)一期不启用 +- `as_user_sub_member.status=4`(等待车主录入凭据)一期不启用 +- `as_user_sub.host_user_id` 一期始终为平台管理员账号 +- 管理后台的"广场审核"模块 Phase 2 再开发 + +--- + +## 决策3:账号凭据展示方式 + +**结论:B — 需二次验证(短信/密码)才能查看** + +**原因:** 安全优先,防止他人借用设备盗取账号密码。 + +**影响:** +- 查看凭据接口前置二次验证步骤 +- 验证方式:短信验证码(发到注册手机号)or 账号密码重新输入 +- 实现:OTP 存 Redis(TTL 5min),无需额外数据库表 +- 凭据展示后建议前端自动隐藏倒计时(UX 优化,非强制) + +--- + +## 决策4:邀请返现规则 + +**结论:完全可配置,无上限** + +| 配置项 | 说明 | +|--------|------| +| 返现类型 | 可配置:固定金额 or 按比例(%) | +| 返现值 | 数字,根据类型解释为金额或百分比 | +| 触发条件 | 可配置:仅首次购买 or 每次购买 | +| 最低订单金额 | 可配置(NULL=不限) | +| 延迟发放天数 | 可配置(0=立即,N天后发放,防退款刷单) | +| 返现上限 | 无上限 | + +**影响:** +- 新增 `as_invite_config` 表(管理后台可配置规则,同时启用一套) +- `as_invite.reward_amount` 记录实际发放金额(创建时从当前有效规则快照) + +--- + +## 决策5:`sub_plan_ids` 关联方式 + +**结论:改为关联表** ✅(已在 v3 执行) + +--- + +## 决策6:提现功能 + +**结论:B — 二期再做,一期只充值+消费** + +**原因:** 提现涉及实名认证、合规审核等复杂流程,MVP 阶段不上线。 + +**影响:** +- `as_wallet_log.type=5`(提现)一期不启用 +- `as_wallet.frozen_amount` 字段保留,一期无写入场景 +- 管理后台"提现审核"模块 Phase 2 开发 + +--- + +## Phase 1 功能范围(最终确认) + +### ✅ Phase 1 包含 +- 用户注册/登录(手机/邮箱) +- 首页(Banner + 商品列表) +- 平台自营商品(product_type=1)购买 +- 余额 + 支付宝 + 微信支付(复用 pigx-pay) +- 我的订阅 + 账号凭据查看(二次验证) +- 余额充值(支付宝/微信/人工充值) +- 邀请推广 + 可配置返现 +- 系统通知(续费提醒/订单通知) +- 管理后台:平台/商品/账号/订单/用户管理 + +### ❌ Phase 2 延期 +- 拼车广场(个人发布 + 审核流程) +- 提现功能 +- 微信/社交登录 +- 小程序端 + +--- + +*决策人:Ami · 2026-02-17* diff --git a/README.md b/README.md index 63caa29..96688ed 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,65 @@ -# work_flow_ishare +# iShare 项目设计文档归档 -iShare 项目工作流程与设计文档归档 \ No newline at end of file +> 归档时间:2026-02-17 +> 项目:流媒体订阅合租分享平台(Netflix/Spotify 等) +> 技术栈:PigX 5.11.0(Java 17 + Spring Boot 3)二次开发 +> 源码仓库:https://git.puro.im/purovps/pigx_ishare + +--- + +## 文档目录 + +### 系统设计 + +| 文件 | 说明 | +|------|------| +| `iShare-dev-plan.md` | 项目开发规划(技术路线、仓库规划、开发周期) | +| `SYSTEM_DESIGN.md` | 系统设计文档(角色、功能模块、业务流程、接口要点) | +| `DECISIONS.md` | 设计决策记录(6个关键决策 + Phase 1/2 范围确认) | + +### 数据库设计 + +| 文件 | 说明 | +|------|------| +| `DATABASE_DESIGN_V2.md` | 完整数据库字段设计(28张表详细说明) | +| `DATABASE_DESIGN_OVERVIEW.md` | 数据库设计概要(表总览、ER关系、状态机、设计机制) | +| `db/ishare_schema_v2.sql` | 基础建表 SQL(修订版,23张表) | +| `db/ishare_schema_v3_delta.sql` | v2→v3 增量 SQL(评审修复:新增3张表,补索引) | +| `db/ishare_schema_v4_delta.sql` | v3→v4 增量 SQL(决策确认:新增 as_invite_config) | + +### 工作记录 + +| 文件 | 说明 | +|------|------| +| `memory_2026-02-17.md` | 2026-02-17 工作日志(Phase D 完整过程) | + +--- + +## 版本历史 + +| Tag | 说明 | +|-----|------| +| `v1-initial-design` | 初步设计(功能清单 + 流程 + 数据库 v2.0) | +| `v2-db-reviewed` | 数据库评审完成(7个问题全部修复,27张表) | +| `v3-phase-d-complete` | Phase D 完成(决策确认,28张表定稿) | + +--- + +## 数据库概览 + +- **总表数**:28 张(9张 PigX 基础表 + 19张 iShare 业务表) +- **核心新增**:`as_recharge`(充值单)/ `as_banner`(广告位)/ `as_product_plan_rel`(M:N关联)/ `as_invite_config`(返现配置) + +## Phase 1 范围(已确认) + +✅ 平台自营商品购买 | 三种支付(复用 pigx-pay)| 凭据二次验证 | 可配置邀请返现 +❌ 拼车广场(Phase 2)| 提现(Phase 2) + +--- + +## 下一步 + +**Phase 0:环境搭建** +- 创建 3 个开发仓库(ishare-backend / ishare-admin / ishare-web) +- Fork PigX 5.11.0 + 配置 Drone CI/CD +- 执行建表 SQL,初始化数据库 diff --git a/SYSTEM_DESIGN.md b/SYSTEM_DESIGN.md new file mode 100644 index 0000000..014a611 --- /dev/null +++ b/SYSTEM_DESIGN.md @@ -0,0 +1,371 @@ +# 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_product(product_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` 是 int,0=全部 含义混乱 | 改用独立 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 | 目标用户ID(0=全部用户) | +| `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** | 测试 + 上线 | — | diff --git a/db/ishare_schema_v2.sql b/db/ishare_schema_v2.sql new file mode 100644 index 0000000..54cfc74 --- /dev/null +++ b/db/ishare_schema_v2.sql @@ -0,0 +1,370 @@ +-- ============================================================ +-- iShare 数据库设计 v2.0(修订版) +-- 修订时间: 2026-02-17 +-- 修订说明: 修复原版缺陷,补充完整业务字段和新增表 +-- 数据库: pigxx_app +-- ============================================================ + +USE pigxx_app; +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ============================================================ +-- 一、App 基础表(沿用原版,仅 app_user 追加字段) +-- ============================================================ + +-- app_user 追加字段(ALTER,不重建表) +ALTER TABLE `app_user` + ADD COLUMN IF NOT EXISTS `invite_code` varchar(16) UNIQUE COMMENT '用户专属邀请码(注册时生成)' AFTER `email`, + ADD COLUMN IF NOT EXISTS `inviter_id` bigint DEFAULT NULL COMMENT '邀请人用户ID' AFTER `invite_code`; + + +-- ============================================================ +-- 二、iShare 核心业务表(修订版,8 张原表 + 新增 6 张) +-- ============================================================ + +-- ------------------------------------------------------------ +-- 2.1 as_platform_type — 平台类型 +-- 修订: 加 status、del_flag、create_time/update_time +-- ------------------------------------------------------------ +DROP TABLE IF EXISTS `as_platform_type`; +CREATE TABLE `as_platform_type` ( + `id` bigint NOT NULL COMMENT '主键', + `name` varchar(64) NOT NULL COMMENT '类型名称(视频/音乐/AI等)', + `platform_type` int NOT NULL DEFAULT 0 COMMENT '类型编号(用于分类筛选),0=全部', + `sort_order` int NOT NULL DEFAULT 0 COMMENT '排序权重(升序)', + `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态: 0=禁用, 1=启用', + `del_flag` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志: 0=正常, 1=已删除', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `idx_platform_type` (`platform_type`), + KEY `idx_sort` (`sort_order`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='平台类型表'; + +-- ------------------------------------------------------------ +-- 2.2 as_platform — 流媒体平台 +-- 修订: 加 description、status、del_flag、create_time/update_time +-- sort_order 从 varchar 改为 int +-- ------------------------------------------------------------ +DROP TABLE IF EXISTS `as_platform`; +CREATE TABLE `as_platform` ( + `id` bigint NOT NULL COMMENT '主键', + `platform_name` varchar(128) NOT NULL COMMENT '平台名称', + `platform_type` int NOT NULL DEFAULT 0 COMMENT '平台类型(关联 as_platform_type.platform_type)', + `icon` varchar(512) DEFAULT NULL COMMENT '应用图标 URL', + `description` varchar(512) DEFAULT NULL COMMENT '平台简介', + `company` varchar(128) DEFAULT NULL COMMENT '所属公司', + `website` varchar(256) DEFAULT NULL COMMENT '平台官网', + `sort_order` int NOT NULL DEFAULT 0 COMMENT '排序权重(升序)', + `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态: 0=禁用, 1=启用', + `del_flag` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志: 0=正常, 1=已删除', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `idx_platform_type` (`platform_type`), + KEY `idx_status` (`status`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='流媒体平台表'; + +-- ------------------------------------------------------------ +-- 2.3 as_sub_plan — 订阅计划 +-- 修订: platform_id varchar→bigint, capacity varchar→int +-- 加 status、del_flag、create_time/update_time +-- ------------------------------------------------------------ +DROP TABLE IF EXISTS `as_sub_plan`; +CREATE TABLE `as_sub_plan` ( + `id` bigint NOT NULL COMMENT '计划ID', + `name` varchar(128) NOT NULL COMMENT '计划名称(标准版/高级版等)', + `platform_id` bigint NOT NULL COMMENT '所属平台ID(→ as_platform.id)', + `capacity` int NOT NULL DEFAULT 1 COMMENT '席位容量(该计划最多可共享人数)', + `remark` varchar(256) DEFAULT NULL COMMENT '备注', + `sort_order` int NOT NULL DEFAULT 0 COMMENT '排序权重(升序)', + `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态: 0=禁用, 1=启用', + `del_flag` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志: 0=正常, 1=已删除', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `idx_platform_id` (`platform_id`), + KEY `idx_status` (`status`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订阅计划表'; + +-- ------------------------------------------------------------ +-- 2.4 as_sub_payroll — 付费方案 +-- 修订: sub_plans(Long,注释混乱) → sub_plan_id(bigint,明确1:1) +-- 加 duration_months、original_price、is_active +-- del_flag、create_time/update_time +-- ------------------------------------------------------------ +DROP TABLE IF EXISTS `as_sub_payroll`; +CREATE TABLE `as_sub_payroll` ( + `id` bigint NOT NULL COMMENT '主键', + `sub_plan_id` bigint NOT NULL COMMENT '所属订阅计划ID(→ as_sub_plan.id)', + `platform_id` bigint NOT NULL COMMENT '平台ID(冗余,便于查询)', + `payroll` tinyint NOT NULL COMMENT '付费周期: 1=月付, 2=季付, 3=年付', + `duration_months` int NOT NULL COMMENT '实际月数: 1/3/12(与 payroll 对应)', + `price` decimal(10,2) NOT NULL COMMENT '售价', + `original_price` decimal(10,2) DEFAULT NULL COMMENT '划线价(原价,用于展示折扣)', + `currency` varchar(8) NOT NULL DEFAULT 'CNY' COMMENT '货币单位(CNY/USD等)', + `region` varchar(64) DEFAULT NULL COMMENT '适用地区', + `is_active` tinyint NOT NULL DEFAULT 1 COMMENT '是否上架: 0=下架, 1=上架', + `del_flag` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志: 0=正常, 1=已删除', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `idx_sub_plan_id` (`sub_plan_id`), + KEY `idx_platform_id` (`platform_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='付费方案表'; + +-- ------------------------------------------------------------ +-- 2.5 as_sub_product — 订阅产品(合租商品) +-- 修订: Tags→tags(命名修复), 加 platform_id、status、cover_image +-- product_type/sub_type 从 Long 改为 tinyint +-- 加 total_capacity、del_flag、create_by/update_by +-- ------------------------------------------------------------ +DROP TABLE IF EXISTS `as_sub_product`; +CREATE TABLE `as_sub_product` ( + `id` bigint NOT NULL COMMENT '主键', + `title` varchar(256) NOT NULL COMMENT '产品标题', + `description` varchar(1024) DEFAULT NULL COMMENT '产品描述', + `cover_image` varchar(512) DEFAULT NULL COMMENT '封面图 URL', + `tags` varchar(256) DEFAULT NULL COMMENT '标签(逗号分隔)', + `platform_id` bigint NOT NULL COMMENT '所属平台ID(→ as_platform.id,冗余加速查询)', + `sub_plan_ids` varchar(256) DEFAULT NULL COMMENT '关联订阅计划ID列表(逗号分隔)', + `product_type` tinyint NOT NULL DEFAULT 1 COMMENT '产品类型: 1=自营, 2=个人', + `sub_type` tinyint NOT NULL DEFAULT 1 COMMENT '订阅类型: 1=单品, 2=多品组合', + `total_capacity` int NOT NULL DEFAULT 1 COMMENT '总席位数(该商品可供多少人购买)', + `amount` decimal(10,2) DEFAULT NULL COMMENT '基准价格(月)', + `star` decimal(3,1) DEFAULT 0.0 COMMENT '综合评分(0.0-5.0,由评价聚合更新)', + `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态: 0=草稿, 1=上架, 2=下架, 3=售完', + `user_id` bigint DEFAULT NULL COMMENT '发布者用户ID(→ app_user.user_id)', + `del_flag` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志: 0=正常, 1=已删除', + `create_by` varchar(64) DEFAULT NULL COMMENT '创建人', + `update_by` varchar(64) DEFAULT NULL COMMENT '修改人', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `idx_platform_id` (`platform_id`), + KEY `idx_status` (`status`), + KEY `idx_product_type` (`product_type`), + KEY `idx_user_id` (`user_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订阅产品表(合租商品)'; + +-- ------------------------------------------------------------ +-- 2.6 as_sub_account — 流媒体平台账号凭据 +-- 修订: user_id/sub_plan_id/sub_payroll_id/platform_id int→bigint +-- passwd_salt int→varchar(64,存hex/base64) +-- 加 encrypt_type、status、del_flag、create_time/update_time +-- ------------------------------------------------------------ +DROP TABLE IF EXISTS `as_sub_account`; +CREATE TABLE `as_sub_account` ( + `id` bigint NOT NULL COMMENT '主键', + `product_id` bigint DEFAULT NULL COMMENT '关联产品ID(→ as_sub_product.id)', + `sub_plan_id` bigint DEFAULT NULL COMMENT '订阅计划ID(→ as_sub_plan.id)', + `sub_payroll_id` bigint DEFAULT NULL COMMENT '付费方案ID(→ as_sub_payroll.id)', + `platform_id` bigint NOT NULL COMMENT '平台ID(→ as_platform.id)', + `user_id` bigint NOT NULL COMMENT '账号持有者用户ID(主用户,→ app_user.user_id)', + `account_name` varchar(256) NOT NULL COMMENT '平台登录用户名/邮箱', + `account_passwd` varchar(512) NOT NULL COMMENT '平台登录密码(加密存储)', + `passwd_salt` varchar(64) NOT NULL COMMENT '加密盐值(Base64/Hex,16字节随机)', + `encrypt_type` tinyint NOT NULL DEFAULT 1 COMMENT '加密算法: 1=AES-256-GCM', + `region` varchar(64) DEFAULT NULL COMMENT '账号所在地区', + `share_type` tinyint DEFAULT NULL COMMENT '分享类型', + `account_type` tinyint DEFAULT NULL COMMENT '账号类型(主账号/子账号等)', + `renew_date` datetime DEFAULT NULL COMMENT '账号在平台的下次续费日', + `status` tinyint NOT NULL DEFAULT 0 COMMENT '账号状态: 0=正常, 1=已失效, 2=异常/被封', + `del_flag` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志: 0=正常, 1=已删除', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `idx_product_id` (`product_id`), + KEY `idx_platform_id` (`platform_id`), + KEY `idx_user_id` (`user_id`), + KEY `idx_status` (`status`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='流媒体平台账号凭据表'; + +-- ------------------------------------------------------------ +-- 2.7 as_user_sub — 合租槽(共享池) +-- 语义修订: 代表"一个合租位池",不代表个人订阅 +-- 修订: remark int→varchar, plan_id/user_id/main_account int→bigint +-- 加 product_id、status、expire_time、del_flag、create_time/update_time +-- ------------------------------------------------------------ +DROP TABLE IF EXISTS `as_user_sub`; +CREATE TABLE `as_user_sub` ( + `id` bigint NOT NULL COMMENT '主键', + `product_id` bigint NOT NULL COMMENT '关联产品ID(→ as_sub_product.id)', + `plan_id` bigint NOT NULL COMMENT '订阅计划ID(→ as_sub_plan.id)', + `platform_id` bigint NOT NULL COMMENT '平台ID(冗余,加速查询)', + `host_user_id` bigint NOT NULL COMMENT '车主用户ID(提供账号的一方,→ app_user.user_id)', + `account_id` bigint DEFAULT NULL COMMENT '关联平台账号ID(→ as_sub_account.id)', + `capacity` int NOT NULL COMMENT '总席位数(来自 as_sub_plan.capacity)', + `capacity_loaded` int NOT NULL DEFAULT 0 COMMENT '已占用席位数', + `region` varchar(64) DEFAULT NULL COMMENT '地区', + `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态: 0=可加入, 1=已满, 2=已到期, 3=已关闭', + `expire_time` datetime DEFAULT NULL COMMENT '该合租槽到期时间(来自最晚成员到期时间)', + `remark` varchar(512) DEFAULT NULL COMMENT '备注(车主说明)', + `del_flag` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志: 0=正常, 1=已删除', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `idx_product_id` (`product_id`), + KEY `idx_plan_id` (`plan_id`), + KEY `idx_host_user_id` (`host_user_id`), + KEY `idx_status` (`status`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='合租槽表(共享席位池)'; + +-- ------------------------------------------------------------ +-- 2.8 as_sub_product_comment — 产品评价 +-- 修订: 加 del_flag、is_anonymous、reply_id(支持追评) +-- star 字段加注释明确 1-5 范围 +-- ------------------------------------------------------------ +DROP TABLE IF EXISTS `as_sub_product_comment`; +CREATE TABLE `as_sub_product_comment` ( + `id` bigint NOT NULL COMMENT '主键', + `product_id` bigint NOT NULL COMMENT '关联产品ID(→ as_sub_product.id)', + `user_id` bigint NOT NULL COMMENT '评价用户ID(→ app_user.user_id)', + `order_id` bigint DEFAULT NULL COMMENT '关联订单ID(校验是否已购买)', + `star` tinyint NOT NULL COMMENT '评分 1-5(服务端校验范围)', + `comment` varchar(1024) DEFAULT NULL COMMENT '评价内容', + `is_anonymous` tinyint NOT NULL DEFAULT 0 COMMENT '是否匿名: 0=公开, 1=匿名', + `reply_id` bigint DEFAULT NULL COMMENT '回复的评价ID(追评/商家回复,NULL=原始评价)', + `del_flag` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志: 0=正常, 1=已删除', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `idx_product_id` (`product_id`), + KEY `idx_user_id` (`user_id`), + KEY `idx_reply_id` (`reply_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='产品评价表'; + + +-- ============================================================ +-- 三、新增表(原版缺失的核心业务表) +-- ============================================================ + +-- ------------------------------------------------------------ +-- 3.1 as_user_sub_member — 个人订阅记录(原版最大缺失) +-- 语义: 某用户购买加入了某合租槽,追踪个人维度 +-- ------------------------------------------------------------ +CREATE TABLE IF NOT EXISTS `as_user_sub_member` ( + `id` bigint NOT NULL COMMENT '主键', + `sub_id` bigint NOT NULL COMMENT '关联合租槽ID(→ as_user_sub.id)', + `user_id` bigint NOT NULL COMMENT '订阅用户ID(→ app_user.user_id)', + `order_id` bigint NOT NULL COMMENT '关联订单ID(→ as_order.id)', + `payroll_id` bigint NOT NULL COMMENT '购买的付费方案ID(→ as_sub_payroll.id)', + `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态: 0=待激活, 1=使用中, 2=已到期, 3=已退订', + `start_time` datetime NOT NULL COMMENT '订阅开始时间', + `expire_time` datetime NOT NULL COMMENT '订阅到期时间', + `del_flag` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志: 0=正常, 1=已删除', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_sub_user` (`sub_id`, `user_id`), + KEY `idx_user_id` (`user_id`), + KEY `idx_order_id` (`order_id`), + KEY `idx_status` (`status`), + KEY `idx_expire` (`expire_time`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='个人订阅记录表'; + +-- ------------------------------------------------------------ +-- 3.2 as_order — 订单表 +-- ------------------------------------------------------------ +CREATE TABLE IF NOT EXISTS `as_order` ( + `id` bigint NOT NULL COMMENT '主键', + `order_no` varchar(32) NOT NULL COMMENT '订单号(业务唯一,格式: AS+时间戳+随机)', + `user_id` bigint NOT NULL COMMENT '购买用户ID(→ app_user.user_id)', + `product_id` bigint NOT NULL COMMENT '商品ID(→ as_sub_product.id)', + `payroll_id` bigint NOT NULL COMMENT '付费方案ID(→ as_sub_payroll.id)', + `original_amount` decimal(10,2) NOT NULL COMMENT '原价(快照,防止价格变动)', + `discount_amount` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '优惠金额', + `amount` decimal(10,2) NOT NULL COMMENT '实付金额', + `pay_type` tinyint DEFAULT NULL COMMENT '支付方式: 1=余额, 2=支付宝, 3=微信支付', + `pay_no` varchar(64) DEFAULT NULL COMMENT '第三方支付单号', + `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态: 0=待支付, 1=已支付, 2=已完成, 3=已退款, 4=已取消', + `member_id` bigint DEFAULT NULL COMMENT '关联个人订阅记录ID(→ as_user_sub_member.id,支付成功后填充)', + `remark` varchar(256) DEFAULT NULL COMMENT '备注', + `expire_time` datetime NOT NULL COMMENT '订单过期时间(未支付自动取消,默认 +15min)', + `pay_time` datetime DEFAULT NULL COMMENT '实际支付时间', + `del_flag` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志: 0=正常, 1=已删除', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_order_no` (`order_no`), + KEY `idx_user_id` (`user_id`), + KEY `idx_product_id` (`product_id`), + KEY `idx_status` (`status`), + KEY `idx_expire` (`expire_time`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订单表'; + +-- ------------------------------------------------------------ +-- 3.3 as_wallet — 用户钱包 +-- ------------------------------------------------------------ +CREATE TABLE IF NOT EXISTS `as_wallet` ( + `id` bigint NOT NULL COMMENT '主键', + `user_id` bigint NOT NULL COMMENT '用户ID(→ app_user.user_id,一人一钱包)', + `balance` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '可用余额', + `frozen_amount` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '冻结金额(退款/提现处理中)', + `total_income` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '累计收入', + `total_expense` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '累计支出', + `version` int NOT NULL DEFAULT 0 COMMENT '乐观锁版本号(防并发余额错误)', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_user_id` (`user_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户钱包表'; + +-- ------------------------------------------------------------ +-- 3.4 as_wallet_log — 钱包流水 +-- ------------------------------------------------------------ +CREATE TABLE IF NOT EXISTS `as_wallet_log` ( + `id` bigint NOT NULL COMMENT '主键', + `user_id` bigint NOT NULL COMMENT '用户ID(→ app_user.user_id)', + `amount` decimal(10,2) NOT NULL COMMENT '变动金额(正=收入, 负=支出)', + `type` tinyint NOT NULL COMMENT '类型: 1=充值, 2=消费, 3=退款, 4=邀请返现, 5=提现', + `order_id` bigint DEFAULT NULL COMMENT '关联订单ID(→ as_order.id,可空)', + `balance_after` decimal(10,2) NOT NULL COMMENT '操作后余额(快照,便于对账)', + `remark` varchar(256) DEFAULT NULL COMMENT '说明(如:订阅 Netflix 高级版 3 个月)', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`), + KEY `idx_user_id` (`user_id`), + KEY `idx_order_id` (`order_id`), + KEY `idx_type` (`type`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='钱包流水表'; + +-- ------------------------------------------------------------ +-- 3.5 as_invite — 邀请关系 +-- ------------------------------------------------------------ +CREATE TABLE IF NOT EXISTS `as_invite` ( + `id` bigint NOT NULL COMMENT '主键', + `inviter_id` bigint NOT NULL COMMENT '邀请人用户ID(→ app_user.user_id)', + `invitee_id` bigint NOT NULL COMMENT '被邀请人用户ID(→ app_user.user_id)', + `invite_code` varchar(16) NOT NULL COMMENT '使用的邀请码', + `reward_amount` decimal(10,2) DEFAULT NULL COMMENT '返现金额(首次购买后确定)', + `reward_status` tinyint NOT NULL DEFAULT 0 COMMENT '返现状态: 0=待发放, 1=已发放, 2=已失效', + `reward_time` datetime DEFAULT NULL COMMENT '返现发放时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间(注册时间)', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_invitee` (`invitee_id`), + KEY `idx_inviter_id` (`inviter_id`), + KEY `idx_invite_code` (`invite_code`), + KEY `idx_reward_status` (`reward_status`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='邀请关系表'; + +-- ------------------------------------------------------------ +-- 3.6 as_notification — 系统通知 +-- ------------------------------------------------------------ +CREATE TABLE IF NOT EXISTS `as_notification` ( + `id` bigint NOT NULL COMMENT '主键', + `user_id` bigint NOT NULL COMMENT '目标用户ID(→ app_user.user_id,0=全体广播)', + `title` varchar(128) NOT NULL COMMENT '通知标题', + `content` varchar(1024) NOT NULL COMMENT '通知内容', + `type` tinyint NOT NULL COMMENT '类型: 1=续费提醒, 2=订单通知, 3=系统公告, 4=邀请奖励', + `ref_id` bigint DEFAULT NULL COMMENT '关联业务ID(订单ID/订阅ID等,按 type 解析)', + `is_read` tinyint NOT NULL DEFAULT 0 COMMENT '是否已读: 0=未读, 1=已读', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`), + KEY `idx_user_id` (`user_id`), + KEY `idx_is_read` (`is_read`), + KEY `idx_type` (`type`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统通知表'; + + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/db/ishare_schema_v3_delta.sql b/db/ishare_schema_v3_delta.sql new file mode 100644 index 0000000..581f991 --- /dev/null +++ b/db/ishare_schema_v3_delta.sql @@ -0,0 +1,129 @@ +-- ============================================================ +-- iShare 数据库设计 v2 → v3 增量脚本 +-- 修订时间: 2026-02-17 +-- 处理评审问题: R1, R2, I1, I2, I3(文档), L1, L2 +-- ============================================================ + +USE pigxx_app; +SET NAMES utf8mb4; + +-- ============================================================ +-- R2: 修复 as_user_sub_member 唯一键问题 +-- 原 UNIQUE(sub_id, user_id) 导致续费覆盖历史记录 +-- 改为:允许多条记录,逻辑约束同 sub_id+user_id 只有一条 status=1 +-- ============================================================ +ALTER TABLE `as_user_sub_member` + DROP INDEX IF EXISTS `uk_sub_user`; + +-- 补充索引(定时任务/我的订阅高频查询) +ALTER TABLE `as_user_sub_member` + ADD INDEX IF NOT EXISTS `idx_user_status` (`user_id`, `status`), + ADD INDEX IF NOT EXISTS `idx_expire_status` (`expire_time`, `status`); + +-- L1: status 增加 4=等待车主录入凭据(广场拼车场景) +-- 注:仅修改注释,逻辑不变;应用层处理状态值 +ALTER TABLE `as_user_sub_member` + MODIFY COLUMN `status` tinyint NOT NULL DEFAULT 0 + COMMENT '状态: 0=待激活, 1=使用中, 2=已到期, 3=已退订, 4=等待车主录入凭据'; + + +-- ============================================================ +-- I2: as_sub_product.sub_plan_ids 逗号分隔改为关联表 +-- ============================================================ + +-- 新增 M:N 关联表 +CREATE TABLE IF NOT EXISTS `as_product_plan_rel` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `product_id` bigint NOT NULL COMMENT '产品ID(→ as_sub_product.id)', + `plan_id` bigint NOT NULL COMMENT '订阅计划ID(→ as_sub_plan.id)', + `sort_order` int NOT NULL DEFAULT 0 COMMENT '排序权重(同产品内多计划的展示顺序)', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_product_plan` (`product_id`, `plan_id`), + KEY `idx_product_id` (`product_id`), + KEY `idx_plan_id` (`plan_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci + COMMENT='产品-订阅计划关联表(M:N)'; + +-- 移除旧的逗号分隔字段 +ALTER TABLE `as_sub_product` + DROP COLUMN IF EXISTS `sub_plan_ids`; + +-- 补充 as_sub_product 高频查询索引 +ALTER TABLE `as_sub_product` + ADD INDEX IF NOT EXISTS `idx_product_type_status` (`product_type`, `status`); + + +-- ============================================================ +-- R1: 新增 as_recharge — 钱包充值单 +-- 支持外部支付充值时追踪(待支付→成功→到账) +-- ============================================================ +CREATE TABLE IF NOT EXISTS `as_recharge` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `recharge_no` varchar(32) NOT NULL COMMENT '充值单号(RC+时间戳+随机,业务唯一)', + `user_id` bigint NOT NULL COMMENT '用户ID(→ app_user.user_id)', + `amount` decimal(10,2) NOT NULL COMMENT '充值金额', + `pay_type` tinyint NOT NULL COMMENT '支付方式: 1=人工充值(管理员), 2=支付宝, 3=微信支付', + `pay_no` varchar(64) DEFAULT NULL COMMENT '第三方支付单号(外部支付时回填)', + `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态: 0=待支付, 1=已支付/已到账, 2=支付失败, 3=已取消', + `remark` varchar(256) DEFAULT NULL COMMENT '备注(人工充值时填写原因)', + `operator_id` bigint DEFAULT NULL COMMENT '操作人ID(人工充值时为管理员ID)', + `expire_time` datetime DEFAULT NULL COMMENT '订单过期时间(外部支付时 +15min)', + `pay_time` datetime DEFAULT NULL COMMENT '实际支付/到账时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_recharge_no` (`recharge_no`), + KEY `idx_user_id` (`user_id`), + KEY `idx_status` (`status`), + KEY `idx_pay_no` (`pay_no`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci + COMMENT='钱包充值单表(含外部支付追踪)'; + + +-- ============================================================ +-- I1: 新增 as_banner — 首页广告位/Banner +-- ============================================================ +CREATE TABLE IF NOT EXISTS `as_banner` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `title` varchar(128) NOT NULL COMMENT 'Banner 标题(后台管理用)', + `image_url` varchar(512) NOT NULL COMMENT 'Banner 图片 URL', + `link_type` tinyint NOT NULL DEFAULT 0 COMMENT '跳转类型: 0=无跳转, 1=商品详情, 2=外部链接, 3=平台分类', + `link_target` varchar(512) DEFAULT NULL COMMENT '跳转目标(商品ID/URL/分类ID,按 link_type 解析)', + `sort_order` int NOT NULL DEFAULT 0 COMMENT '排序权重(升序,值小靠前)', + `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态: 0=草稿, 1=展示中, 2=已下线', + `start_time` datetime DEFAULT NULL COMMENT '展示开始时间(NULL=立即生效)', + `end_time` datetime DEFAULT NULL COMMENT '展示结束时间(NULL=长期有效)', + `create_by` varchar(64) DEFAULT NULL COMMENT '创建人', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `idx_status_sort` (`status`, `sort_order`), + KEY `idx_time_range` (`start_time`, `end_time`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci + COMMENT='首页 Banner 广告位表'; + + +-- ============================================================ +-- L2: 补充关键查询索引 +-- ============================================================ + +-- as_order: 用户订单列表 / 状态过滤 +ALTER TABLE `as_order` + ADD INDEX IF NOT EXISTS `idx_user_status` (`user_id`, `status`); + +-- as_notification: 未读消息数 +ALTER TABLE `as_notification` + ADD INDEX IF NOT EXISTS `idx_user_read` (`user_id`, `is_read`); + +-- as_user_sub: 商品下的可用合租槽 +ALTER TABLE `as_user_sub` + ADD INDEX IF NOT EXISTS `idx_product_status` (`product_id`, `status`); + +-- as_sub_account: 产品下的账号列表 +ALTER TABLE `as_sub_account` + ADD INDEX IF NOT EXISTS `idx_product_status` (`product_id`, `status`); + +-- ============================================================ +-- END +-- ============================================================ diff --git a/db/ishare_schema_v4_delta.sql b/db/ishare_schema_v4_delta.sql new file mode 100644 index 0000000..2412cea --- /dev/null +++ b/db/ishare_schema_v4_delta.sql @@ -0,0 +1,59 @@ +-- ============================================================ +-- iShare 数据库设计 v3 → v4 增量脚本 +-- 修订时间: 2026-02-17 +-- 依据: 决策确认(决策1-4,6) +-- ============================================================ + +USE pigxx_app; +SET NAMES utf8mb4; + +-- ============================================================ +-- 决策4: 新增 as_invite_config — 邀请返现规则配置表 +-- 返现类型/金额/触发条件均可配置,支持多套规则(启用一套) +-- ============================================================ +CREATE TABLE IF NOT EXISTS `as_invite_config` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(64) NOT NULL COMMENT '规则名称(管理后台展示用)', + `reward_type` tinyint NOT NULL DEFAULT 1 COMMENT '返现类型: 1=固定金额, 2=按比例(%)', + `reward_value` decimal(10,4) NOT NULL DEFAULT 0 COMMENT '返现值(type=1时为金额CNY; type=2时为百分比,如5.00=5%)', + `trigger_type` tinyint NOT NULL DEFAULT 1 COMMENT '触发条件: 1=被邀请人首次购买, 2=被邀请人每次购买', + `min_order_amount` decimal(10,2) DEFAULT NULL COMMENT '触发最低订单金额(NULL=不限)', + `reward_delay_days` int NOT NULL DEFAULT 0 COMMENT '返现延迟天数(0=立即,N=N天后发放,防退款刷单)', + `is_active` tinyint NOT NULL DEFAULT 0 COMMENT '是否启用: 0=禁用, 1=启用(同一时刻只有一条有效)', + `remark` varchar(256) DEFAULT NULL COMMENT '规则备注', + `create_by` varchar(64) DEFAULT NULL COMMENT '创建人', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `idx_is_active` (`is_active`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci + COMMENT='邀请返现规则配置表(可配置,启用一套)'; + + +-- ============================================================ +-- 决策2: Phase 1 无拼车广场 +-- as_user_sub_member.status=4(等待车主录入凭据)一期不启用 +-- 修改注释说明,字段值保留供 Phase 2 使用 +-- ============================================================ +ALTER TABLE `as_user_sub_member` + MODIFY COLUMN `status` tinyint NOT NULL DEFAULT 0 + COMMENT '状态: 0=待激活, 1=使用中, 2=已到期, 3=已退订 | Phase2: 4=等待车主录入凭据(拼车广场)'; + +-- as_sub_product.product_type=2(个人发布)Phase 1 不启用 +-- 修改注释说明 +ALTER TABLE `as_sub_product` + MODIFY COLUMN `product_type` tinyint NOT NULL DEFAULT 1 + COMMENT '产品类型: 1=自营(Phase1启用), 2=个人发布(Phase2拼车广场)'; + + +-- ============================================================ +-- 决策6: 提现功能 Phase 2 +-- as_wallet_log.type=5(提现)一期不启用,字段保留 +-- ============================================================ +ALTER TABLE `as_wallet_log` + MODIFY COLUMN `type` tinyint NOT NULL + COMMENT '流水类型: 1=充值, 2=消费, 3=退款, 4=邀请返现 | Phase2: 5=提现'; + +-- ============================================================ +-- END +-- ============================================================ diff --git a/iShare-dev-plan.md b/iShare-dev-plan.md new file mode 100644 index 0000000..67938d0 --- /dev/null +++ b/iShare-dev-plan.md @@ -0,0 +1,277 @@ +# iShare 开发规划 + +> 流媒体账号合租分享平台 +> 基于 PigX 5.11.0 二次开发 +> 制定日期: 2026-02-17 + +--- + +## 一、项目背景 + +| 项目 | 说明 | +|------|------| +| 产品定位 | 流媒体订阅合租平台(Netflix/Spotify/Apple TV 等合租分享) | +| 核心价值 | 用户以正价 10%-30% 享受正版流媒体服务 | +| 已有资产 | iShare 旧版代码(基于 PigX 5.2)、数据库设计、Figma 设计稿 | +| 目标框架 | PigX 5.11.0(最新版,Java 17 + Spring Boot 3) | +| 代码仓库 | https://git.puro.im/purovps/pigx(PigX 框架备份)| + +--- + +## 二、技术路线 + +### 2.1 为什么迁移到 PigX 5.11.0 + +| 维度 | 旧版 (5.2) | 新版 (5.11.0) | +|------|-----------|--------------| +| Java | JDK 8 | JDK 17 (LTS) | +| Spring Boot | 2.x | 3.5.9 | +| Spring Cloud Alibaba | 旧版 | 2023.0.3.3 | +| 包名 | javax.* | jakarta.* | +| 部署模式 | 仅微服务 | 支持单体(pigx-boot) + 微服务双模式 | +| AI 能力 | 无 | LangChain4j + Spring AI + pgvector | +| 前端 | Vue2 | Vue3 + TypeScript + Vite + Tailwind | + +**结论**: 5.11.0 支持单体模式部署,开发初期用 `pigx-boot` 单体模式,极大降低运维复杂度;后期需要时再拆微服务。 + +### 2.2 整体技术栈 + +**后端** +- Java 17 + Spring Boot 3.5.9 +- Spring Cloud Alibaba 2023(微服务模式时) +- MyBatis-Plus + MySQL(业务数据) +- Redis(缓存、Session) +- Nacos(配置中心、服务发现) +- Maven 多模块项目 + +**前端(管理后台)** +- Vue 3 + TypeScript + Vite +- Tailwind CSS +- 基于 pigx-ui 二次开发 + +**前端(用户 H5/Web)** +- Vue 3 + TypeScript + Vite(独立项目) +- 移动端优先,响应式设计 +- 基于 Figma 设计稿实现 + +**部署** +- 开发阶段: Docker Compose 单体部署(pigx-boot) +- 生产阶段: Docker + Drone CI/CD 自动化 +- 数据库: MySQL(复用 VPS 上的 MariaDB) + +### 2.3 仓库规划 + +| 仓库 | 说明 | Git 地址(待创建)| +|------|------|-----------------| +| `ishare-backend` | PigX 后端主仓库(含 pigx-ishare 业务模块) | git.puro.im/purovps/ishare-backend | +| `ishare-admin` | 管理后台前端(基于 pigx-ui) | git.puro.im/purovps/ishare-admin | +| `ishare-web` | 用户端 H5/Web 前端 | git.puro.im/purovps/ishare-web | + +--- + +## 三、架构设计 + +### 3.1 模块结构(后端) + +``` +ishare-backend/ +├── pigx-boot/ # 单体部署启动器(开发阶段使用) +├── pigx-ishare/ # ★ iShare 业务模块(核心新增) +│ └── src/main/java/ +│ ├── controller/ # REST API +│ ├── service/ # 业务逻辑 +│ ├── mapper/ # MyBatis Mapper +│ ├── entity/ # 实体类 +│ └── dto/ # 数据传输对象 +├── pigx-auth/ # 认证(PigX 原版,无侵入) +├── pigx-upms-biz/ # 用户权限管理(PigX 原版) +├── pigx-gateway/ # 网关(微服务模式时使用) +├── pigx-common/ # 公共模块(PigX 原版) +├── db/ +│ ├── 0pigxx_boot.sql # PigX 基础表 +│ └── 1ishare_schema.sql # iShare 业务表(迁移自现有设计) +└── docker-compose.yml # 本地开发环境 +``` + +### 3.2 数据库设计(沿用现有,小幅调整) + +**核心业务表(as_*)**(已有设计,直接复用) +- `as_platform` — 流媒体平台 +- `as_platform_type` — 平台分类 +- `as_sub_plan` — 订阅计划 +- `as_sub_payroll` — 付费方案 +- `as_sub_account` — 订阅账号(含加密凭据) +- `as_sub_product` — 合租商品 +- `as_sub_product_comment` — 商品评价 +- `as_user_sub` — 用户订阅关系 + +**新增考虑**(二期) +- `as_order` — 订单表(支付流程) +- `as_withdraw` — 提现记录 +- `as_invite` — 邀请关系(推广中心) + +**App 基础表(app_*)**(PigX 原版提供) +- `app_user`、`app_social_details`(社交登录) +- `app_page`、`app_tabbar`(页面装修) + +### 3.3 核心业务流程 + +``` +用户端: + 注册/登录(手机/邮箱/社交) + → 浏览平台列表 + 筛选 + → 查看合租商品详情 + → 下单付款(一期:手动确认) + → 获取账号信息 + → 评价 + +车主端(合租发起方): + 发布合租商品 → 等待拼客 → 管理席位 → 续费/关闭 + +管理后台: + 平台管理 → 订阅计划管理 → 商品审核 → 订单管理 → 用户管理 +``` + +--- + +## 四、开发阶段规划 + +### Phase 0: 环境搭建(1-2天) + +- [ ] 在 Gitea 创建三个仓库(ishare-backend / ishare-admin / ishare-web) +- [ ] fork/copy 新版 PigX 5.11.0 到 ishare-backend,清理无关模块(pigx-knowledge AI相关) +- [ ] 本地搭建开发环境(MySQL + Redis + IDEA) +- [ ] 配置 VPS Drone CI/CD pipeline(`.drone.yml`) +- [ ] 创建 iShare 数据库,导入建表 SQL + +### Phase 1: 后端基础功能(1-2周) + +**目标**: 完成核心 CRUD API,管理后台可用 + +- [ ] 新增 `pigx-ishare` Maven 模块,接入 pigx-boot +- [ ] 迁移 as-app-server 代码到 Java 17(javax → jakarta,注解调整) +- [ ] 实现平台管理接口(CRUD: `as_platform` / `as_platform_type`) +- [ ] 实现订阅计划管理接口(`as_sub_plan` / `as_sub_payroll`) +- [ ] 实现商品管理接口(`as_sub_product` + 评价) +- [ ] 实现账号管理接口(`as_sub_account`,账号密码加密存储) +- [ ] 实现用户订阅管理(`as_user_sub`) +- [ ] App 用户注册/登录 API(手机+邮箱+验证码,复用 pigx-auth) +- [ ] Swagger/Knife4j 接口文档 + +### Phase 2: 管理后台前端(1周) + +**目标**: 管理员可通过后台管理数据 + +- [ ] fork pigx-ui 到 ishare-admin,调整品牌样式 +- [ ] 平台管理页面 +- [ ] 订阅计划 + 付费方案页面 +- [ ] 合租商品管理页面(含审核) +- [ ] 用户管理页面 +- [ ] 订单/订阅查看页面 + +### Phase 3: 用户端 H5(2-3周) + +**目标**: 用户可完成合租全流程 + +按 Figma 设计稿实现: + +- [ ] 首页/欢迎页(品牌展示) +- [ ] 登录/注册页(手机+邮箱+社交登录入口) +- [ ] 忘记密码(验证码找回) +- [ ] 主页/服务列表(平台卡片 + 分类筛选) +- [ ] 服务详情页(介绍 + 价格套餐 + 评价) +- [ ] 购买流程(选套餐 → 确认订单 → 支付 → 获取账号) +- [ ] 广场/拼车(浏览他人发起的合租) +- [ ] 推广中心(邀请码 + 返现记录) +- [ ] 个人中心(我的订阅 + 账单 + 设置) +- [ ] 底部 Tab 导航(首页 / 广场 / 推广 / 我的) + +### Phase 4: 支付集成(按需) + +- [ ] 对接支付宝/微信支付(或先用余额/人工确认模式) +- [ ] 订单状态流转(待付款→已付款→使用中→已到期) +- [ ] 自动续费提醒 + +### Phase 5: 测试 & 上线 + +- [ ] 接口联调测试 +- [ ] 账号信息安全审计(加密方案验证) +- [ ] VPS 生产环境部署 +- [ ] 性能基准测试(并发下单) + +--- + +## 五、CI/CD 流程 + +```yaml +# .drone.yml 结构(参考 jshERP 配置) +steps: + - name: backend-build + image: maven:3.9-eclipse-temurin-17 + commands: + - mvn clean package -DskipTests -P boot + + - name: frontend-admin-build + image: node:18-alpine + commands: + - cd ../ishare-admin && npm ci && npm run build + + - name: frontend-web-build + image: node:18-alpine + commands: + - cd ../ishare-web && npm ci && npm run build + + - name: deploy + image: docker:dind + commands: + - docker-compose up -d --build +``` + +触发条件: +- push 到 `main` 分支 → 自动构建 + 部署到 VPS +- PR → 只跑构建,不部署 + +--- + +## 六、里程碑 + +| 里程碑 | 内容 | 预计时间 | +|--------|------|---------| +| M0 | 环境搭建完成,空项目跑通 CI | 第 1 周 | +| M1 | 后端 API 完成,Swagger 文档可访问 | 第 2-3 周 | +| M2 | 管理后台可用,数据录入正常 | 第 3-4 周 | +| M3 | 用户端 H5 完成,全流程可跑通 | 第 5-7 周 | +| M4 | 支付接入,正式上线 | 第 8+ 周 | + +--- + +## 七、关键技术决策 + +### Q1: 为什么不直接改旧代码,而是基于新 PigX 重新集成? + +旧代码基于 PigX 5.2(Java 8 + Spring Boot 2),Spring Boot 2 已于 2023 年 EOL,Java 8 缺少现代特性。新版 5.11.0 支持单体模式,开发阶段不需要 Nacos/Gateway,本地启动一个 JAR 即可,和旧版微服务架构相比开发效率高得多。 + +### Q2: 单体模式 vs 微服务? + +**开发阶段**: 用 `pigx-boot` 单体模式 — 一个进程,本地开发零运维负担。 +**生产上线后**: 如并发压力大,再按模块拆分微服务(业务模块无需改代码,只需改部署配置)。 + +### Q3: 用户端用 H5 还是小程序? + +一期先做响应式 H5(Vue3),可在微信内置浏览器打开,无需发布审核。小程序适配二期按需追加。 + +### Q4: 账号密码安全? + +`as_sub_account` 存储平台登录密码,需要对称加密(AES)存储,密钥由服务端持有,不直接暴露明文。PigX 本身已有 Jasypt 配置加密,沿用即可。 + +--- + +## 八、参考资源 + +| 资源 | 地址 | +|------|------| +| PigX 框架(最新版) | https://git.puro.im/purovps/pigx | +| iShare 旧版代码 | https://git.puro.im/purovps/pigx_ishare/src/branch/pigx_ishare | +| 数据库设计文档 | https://git.puro.im/purovps/pigx_ishare/src/branch/pigx_ishare/DATABASE_DESIGN.md | +| Figma 设计稿 | iShare_Design/iShare_设计文档.html | +| VPS 环境 | https://git.puro.im/purovps/vps_env/src/branch/main/vps-environment.md | diff --git a/memory_2026-02-17.md b/memory_2026-02-17.md new file mode 100644 index 0000000..0626d2f --- /dev/null +++ b/memory_2026-02-17.md @@ -0,0 +1,201 @@ +# 2026-02-17 日记 + +## 上午/下午 + +### 1. 补充 VPS 环境文档 +- 对比记忆 vs Gitea 文档,发现几处缺漏 +- 已补充推送到 Gitea:https://git.puro.im/purovps/vps_env/src/branch/main/vps-environment.md +- 补充内容: + - Redis (localhost:6379 无密码) / Prometheus (9090) / Loki (3100) + - jshERP 架构:后端容器 `jsherp`(host network, 9999)、前端静态 `/opt/jshERP-web/` + - Drone Trusted 模式、Dockerfile 需要 fontconfig + ttf-dejavu + - 踩坑记录:Redis slave 问题、Portainer 改 9000 (HTTP)、前端 403 改到 /opt/jshERP-web/ 等 + - Caddy conf.d 路径:devops.conf / erp.conf / im.conf / claw.conf + - Mattermost Bot:@erp_devbot token,助手启停方法 + - Fail2ban + Swap 4GB + +### 2. iShare 开发规划 +- 项目仓库:https://git.puro.im/purovps/pigx_ishare +- 规划文档已推送:https://git.puro.im/purovps/pigx_ishare/src/branch/master/iShare-dev-plan.md +- 技术路线决策: + - 基于 PigX 5.11.0 二次开发,新增 `pigx-ishare` 业务模块(不动框架原代码) + - Java 17 + Spring Boot 3(javax → jakarta 迁移) + - 开发阶段用 `pigx-boot` 单体模式,一个 JAR 跑全部;上线后按需拆微服务 + - 管理后台:pigx-ui(Vue3 + TypeScript + Tailwind) + - 用户端:独立 H5 项目,响应式移动端优先 +- 仓库规划:3个独立仓库(ishare-backend / ishare-admin / ishare-web) +- 开发周期:约 7-8 周到 MVP(不含支付) +- **下一步待定:开始执行哪个 Phase** + +## 晚上 +- /compact 压缩后 /new 新开 session +- Ami 粘贴了上次对话记录,同步上下文 + +--- + +## ✅ 待办:iShare 开发执行 + +### 项目概况 +- **产品**:流媒体订阅合租分享平台(Netflix/Spotify 等) +- **技术栈**:PigX 5.11.0(Java 17 + Spring Boot 3)二次开发 +- **规划文档**:https://git.puro.im/purovps/pigx_ishare/src/branch/master/iShare-dev-plan.md +- **PigX 框架**:https://git.puro.im/purovps/pigx +- **旧版代码**:https://git.puro.im/purovps/pigx_ishare/src/branch/pigx_ishare + +### 仓库规划(待创建) +- `ishare-backend` — 后端主仓库(Fork PigX 5.11.0 + pigx-ishare 模块) +- `ishare-admin` — 管理后台(Fork pigx-ui) +- `ishare-web` — 用户端 H5(独立 Vue3 项目) + +### 开发阶段(已调整优先级) +- [ ] **Phase D(最高优先)**:系统设计 — 功能清单 + 业务流程 + 数据库设计 ← 进行中 +- [ ] **Phase 0**(1-2天):创建仓库 + Fork PigX + 本地环境 + Drone CI/CD + 建库 SQL +- [ ] **Phase 1**(1-2周):后端核心 CRUD API(平台/计划/商品/账号/用户订阅) +- [ ] **Phase 2**(1周):管理后台前端(ishare-admin) +- [ ] **Phase 3**(2-3周):用户端 H5(ishare-web,按 Figma 设计稿) +- [ ] **Phase 4**(按需):支付集成(支付宝/微信) +- [ ] **Phase 5**:测试 + 上线 + +### Phase D 完成状态 +- [x] 系统角色定义(4个角色) +- [x] 功能模块清单(用户端11模块 + 管理后台9模块) +- [x] 核心业务流程(注册/购买/凭据查看/续费/拼车/邀请 共6条) +- [x] 数据库完整设计(现有8表修订 + 新增5表:as_order/as_wallet/as_wallet_log/as_invite/as_notification) +- [x] 接口设计要点(AES加密/席位并发控制/价格快照) +- [ ] 待决策项确认(6个决策点,需 Ami 确认) +- 设计文档:https://git.puro.im/purovps/pigx_ishare/src/branch/master/SYSTEM_DESIGN.md + +### 关键设计决策 +- 开发阶段用 `pigx-boot` 单体模式(一个 JAR),上线后按需拆微服务 +- 用户端做响应式 H5,二期再考虑小程序 +- 账号密码 AES 加密存储(复用 PigX Jasypt) +- 数据库复用 VPS MariaDB,CI/CD 复用 Drone + +### 下一步 +→ 确认从 **Phase 0** 开始执行 + +--- + +## 🛠️ OpenClaw 配置修复(2026-02-17 晚) + +### QMD 记忆后端修复 +- **问题**:`qmd-wrapper.sh` 强制用 nvm v24 Node,但 `better-sqlite3` 编译于 v22(MODULE_VERSION 127),版本冲突导致 `qmd update` 每次都失败 +- **修复**:改 wrapper 用 `/usr/bin/node`(系统 v22),兼容 better-sqlite3 +- **文件**:`/home/macsvr/clawd/scripts/qmd-wrapper.sh` +- **结果**:QMD 正常索引 78 个文档,BM25 记忆检索恢复正常 + +### Local Embedding(memorySearch) +- 重新启用(之前临时关闭) +- 模型:`hf:ggml-org/embeddinggemma-300M-GGUF/embeddinggemma-300M-Q8_0.gguf` +- 文件存在:`~/.node-llama-cpp/models/hf_ggml-org_embeddinggemma-300M-Q8_0.gguf` + +--- + +## 📐 iShare Phase D:数据库设计 v2.0 完成 + +### 已推送到 Gitea +- 设计文档:https://git.puro.im/purovps/pigx_ishare/src/branch/master/DATABASE_DESIGN_V2.md +- 建表 SQL:https://git.puro.im/purovps/pigx_ishare/src/branch/master/db/ishare_schema_v2.sql + +### 修复的原版缺陷(15项) +**严重(4项):** +1. `as_user_sub.remark` int→varchar(字段类型 Bug) +2. `as_user_sub` 缺 `status`、`expire_time`(订阅生命周期无法管理) +3. `as_sub_account.passwd_salt` int→varchar(64)(加密 Salt 不能用 int) +4. 缺少个人订阅记录表(无法追踪谁加入了哪个合租位) + +**重要(6项):** +5. `as_sub_product.Tags`→`tags`(Java 命名 Bug) +6. `as_sub_plan.platform_id` varchar→bigint,`capacity` varchar→int +7. `as_sub_payroll.sub_plans`→`sub_plan_id`(语义混乱) +8. 7 处 int/Long→bigint 类型对齐 +9. `as_sub_product` 缺 `platform_id`、`status`、`cover_image` +10. `as_sub_payroll` 缺 `duration_months`、`original_price` + +### 新增 6 张表 +| 表 | 作用 | +|----|------| +| `as_user_sub_member` | 个人订阅记录(最关键缺失表) | +| `as_order` | 完整订单(含状态机) | +| `as_wallet` | 用户钱包(含乐观锁) | +| `as_wallet_log` | 钱包流水 | +| `as_invite` | 邀请关系/返现 | +| `as_notification` | 系统通知 | + +**总计:9 App 基础表 + 14 业务表 = 23 张表** + +### Phase D 状态 +- [x] 系统角色/功能模块清单 +- [x] 核心业务流程(6条) +- [x] 数据库设计 v2.0(修复+新增) +- [ ] 待决策项确认(6个,见 SYSTEM_DESIGN.md) +- [ ] Phase 0 环境搭建(等 Phase D 决策确认后) + +--- + +## 🌙 晚上(Session 2) + +### iShare Phase D 完成 + +#### 数据库评审(7 个问题全部修复) + +| 问题 | 处理 | +|------|------| +| R1 充值流水缺失 | 新增 `as_recharge` 表 | +| R2 续费唯一键问题 | 移除 UNIQUE KEY,续费改为新建记录 | +| I1 Banner 表缺失 | 新增 `as_banner` 表 | +| I2 M:N 逗号分隔 | 新增 `as_product_plan_rel`,移除 `sub_plan_ids` | +| I3 文档字段不一致 | 概要统一至 v2 修订字段名 | +| L1 拼车状态未建模 | `status=4` 等待车主录入凭据 | +| L2 索引缺失 | 补充 12 项关键索引 | + +**表数量:v2(23张) → v3(27张)** + +#### 5 个决策项确认 + +| # | 决策 | +|---|------| +| 1 | 三种支付全支持(复用 pigx-pay) | +| 2 | 拼车广场 Phase 2,一期仅自营 | +| 3 | 凭据查看需二次验证(SMS OTP) | +| 4 | 邀请返现完全可配置,新增 `as_invite_config` 表 | +| 6 | 提现 Phase 2 | + +**最终:28 张表,Phase D 完成** + +#### Gitea 提交记录 +- `v1-initial-design` — 初版设计快照 +- `v2-db-reviewed` — 评审修复完成 +- `v3-phase-d-complete` — Phase D 全部完成(决策确认) + +**新增文件:** +- `db/ishare_schema_v3_delta.sql` / `db/ishare_schema_v4_delta.sql` +- `DECISIONS.md` — 完整决策记录 +- `DATABASE_DESIGN_OVERVIEW.md` — v4 最终版概要 + +--- + +## 📋 前置信息整理(开发背景) + +### VPS 环境文档同步(2026-02-17 下午) +文档与记忆对比,发现缺漏并已补充推送: + +**文档里有但记忆缺的(新信息):** +- LCMP (teddysun/lcmp) 一键安装 + lcmp-guide.md +- PHP 8.4.18 (php8.4-fpm) +- MariaDB 11.4.10 版本 + +**记忆里有但文档缺的(已补充):** +- Redis (localhost:6379, 无密码) / Prometheus (9090) / Loki (3100) +- jshERP 架构:容器 `jsherp`(host network, 9999)、前端 `/opt/jshERP-web/`、Drone Trusted 模式、Dockerfile 需 fontconfig + ttf-dejavu +- 踩坑记录:Redis slave 问题、Portainer 改 9000 (HTTP)、前端 403 改路径等 +- Caddy conf.d 路径:devops.conf / erp.conf / im.conf / claw.conf +- Mattermost Bot:@erp_devbot token,MS 助手启停方法 +- 安全基础:Swap 4GB、Fail2ban + +文档地址:https://git.puro.im/purovps/vps_env/src/branch/main/vps-environment.md + +### iShare 规划来源 +- 旧版代码(基于 PigX 5.2):https://git.puro.im/purovps/pigx_ishare/src/branch/pigx_ishare +- 新版 PigX 框架:https://git.puro.im/purovps/pigx +- 已有资产:旧版代码 + 数据库设计 + Figma 设计稿(iShare_Design/iShare_设计文档.html)