diff --git a/docs/admin_reference_prd/rendered/page-9.png b/docs/admin_reference_prd/rendered/page-9.png new file mode 100644 index 0000000..0041ced Binary files /dev/null and b/docs/admin_reference_prd/rendered/page-9.png differ diff --git a/docs/admin_reference_prd/后台功能与数据库表映射.md b/docs/admin_reference_prd/后台功能与数据库表映射.md new file mode 100644 index 0000000..d5aeb83 --- /dev/null +++ b/docs/admin_reference_prd/后台功能与数据库表映射.md @@ -0,0 +1,130 @@ +# 后台功能与数据库表映射 + +> 更新时间:2026-10-09 +> 范围:当前 HotGo 后台、已实现业务模块及数据库 `olons_admin` 现有表 +> 说明:一个页面可能关联多张表;部分公共表会被多个业务模块共同使用。 + +## 1. 当前业务菜单 + +| 一级菜单 | 功能 | 核心表 | 关联表 | 说明 | +| --- | --- | --- | --- | --- | +| 主页 | 首页数据看板 | `hg_dashboard_daily_stat` | `hg_app_member`、`hg_trade_order`、`hg_recharge_order`、`hg_withdrawal_order`、`hg_task_submission` | 展示会员、订单、充值、提现、任务等汇总数据;部分指标实时统计,日指标可落汇总表。 | +| 主页 | 网站设置 | `hg_site_config_version` | — | 站点名称、Logo、隐私网址、交易限制、佣金、时间段、功能开关、自动派单等整份保存在 `config_json`;当前页面直接保存并生效。 | +| 主页 | 文本管理 | `hg_content` | `hg_content_version` | `hg_content` 保存内容主档,`hg_content_version` 保存正文版本。 | +| 主页 | Banner 设置 | `hg_banner` | `hg_sys_attachment` | 管理 Banner 图片、位置、跳转方式、展示时间和排序。 | +| 主页 | 手工商城 | `hg_product` | `hg_sys_attachment` | 与商品管理共用商品表,以 `product_type=2` 区分手工商城商品;当前只维护名称、价格和展示图片。 | +| 会员管理 | 会员列表 | `hg_app_member` | `hg_app_member_profile`、`hg_app_member_address`、`hg_app_member_payment_account`、`hg_app_member_status_log` | 会员主档、实名/扩展资料、地址、银行卡或收款账户、状态变更记录。 | +| 会员管理 | 会员列表—余额与账变 | `hg_wallet_account` | `hg_wallet_ledger`、`hg_wallet_adjustment_request` | 钱包余额保存在账户表,所有变动写入不可变流水;人工账变入口保留在会员列表操作栏。 | +| 会员管理 | 会员等级 | `hg_app_member_level` | `hg_app_member_level_version`、`hg_app_member` | 等级规则及等级版本;会员主档关联当前等级。 | +| 会员管理 | 任务大厅 | `hg_task_hall` | `hg_task_hall_level`、`hg_app_member_level` | 配置大厅入口及允许参与的会员等级。 | +| 交易管理 | 订单列表 | `hg_trade_order` | `hg_app_member`、`hg_product`、`hg_task`、`hg_wallet_ledger` | 交易订单主档及会员、商品、任务、资金流水关联。 | +| 交易管理 | 充值管理 | `hg_recharge_order` | `hg_payment_channel`、`hg_wallet_account`、`hg_wallet_ledger`、`hg_finance_review` | 充值申请、渠道信息、审核结果和入账流水。 | +| 交易管理 | 提现管理 | `hg_withdrawal_order` | `hg_wallet_account`、`hg_wallet_ledger`、`hg_finance_review`、`hg_app_member_payment_account` | 提现申请、余额冻结/扣减/退回、审核以及收款账户信息。 | +| 交易管理 | 客服管理 | `hg_customer_service` | — | 客服名称、联系方式、工作时间、在线状态和排序。 | +| 商品管理 | 商品列表 | `hg_product` | `hg_product_category`、`hg_sys_attachment` | 正式商品主档,以 `product_type=1` 区分;分类保存在商品分类表。 | +| 任务管理 | 任务列表 | `hg_task` | `hg_task_level`、`hg_product`、`hg_app_member_level` | 任务主体、关联商品、适用会员等级及佣金规则。 | +| 任务管理 | 会员任务审核 | `hg_task_submission` | `hg_task`、`hg_app_member`、`hg_app_member_level`、`hg_wallet_account`、`hg_wallet_ledger` | 审核会员提交的任务;通过后结算佣金并生成钱包流水。 | + +## 2. 已隐藏菜单但保留的业务能力 + +| 原菜单 | 保留表 | 当前入口/处理方式 | +| --- | --- | --- | +| 资金调账 | `hg_wallet_adjustment_request`、`hg_wallet_account`、`hg_wallet_ledger` | 独立菜单已隐藏;相关权限和接口保留,由会员列表中的“账变”操作进入。 | +| 会员通知 | `hg_app_member_notice` | 独立菜单已隐藏;通知/弹幕相关能力和接口保留,可从会员列表操作或后续 C 端消息中心复用。 | +| 审批中心 | `hg_approval_request`、`hg_approval_action` | 独立治理菜单已移除;表和服务仍可供高风险业务复用。 | +| 业务审计 | `hg_biz_audit_log` | 独立菜单已移除;重要操作仍可写入审计记录。 | + +## 3. HotGo 原生后台功能 + +### 3.1 组织与权限 + +| 功能 | 核心表 | 说明 | +| --- | --- | --- | +| 后台用户 | `hg_admin_member` | 后台管理员账号。 | +| 部门管理 | `hg_admin_dept` | 组织部门树。 | +| 岗位管理 | `hg_admin_post`、`hg_admin_member_post` | 岗位定义及管理员岗位关系。 | +| 角色权限 | `hg_admin_role`、`hg_admin_member_role` | 角色树、管理员角色关系。子角色可选菜单不得超过直接父角色范围。 | +| 菜单权限 | `hg_admin_menu`、`hg_admin_role_menu` | 菜单、页面、按钮权限及角色菜单关系。 | +| 接口鉴权 | `hg_admin_role_casbin` | Casbin 接口权限规则。 | +| 第三方登录 | `hg_admin_oauth` | 后台账号第三方授权关系。 | + +### 3.2 系统设置与运维 + +| 功能 | 核心表 | 说明 | +| --- | --- | --- | +| 配置管理 | `hg_sys_config` | HotGo 系统配置。网站业务配置不写入此表,而写入 `hg_site_config_version`。 | +| 字典管理 | `hg_sys_dict_type`、`hg_sys_dict_data` | 动态字典类型和选项数据;代码枚举通过 HotGo 字典注册机制提供。 | +| 定时任务 | `hg_sys_cron_group`、`hg_sys_cron` | 定时任务分组、执行策略及状态。 | +| 黑名单 | `hg_sys_blacklist` | IP 等访问黑名单。 | +| 通知公告 | `hg_admin_notice`、`hg_admin_notice_read` | 面向后台管理员的公告及阅读状态,与会员通知不是同一张表。 | +| 附件管理 | `hg_sys_attachment` | 上传文件和图片元数据。 | +| 地区编码 | `hg_sys_provinces` | 省市区层级数据。 | +| 操作日志 | `hg_sys_log` | 后台接口操作日志。 | +| 登录日志 | `hg_sys_login_log` | 后台登录记录。 | +| 短信/邮件日志 | `hg_sys_sms_log`、`hg_sys_ems_log` | 短信和邮件发送记录。 | +| 服务日志 | `hg_sys_serve_log` | 服务运行日志。 | +| 服务授权/监控 | `hg_sys_serve_license` | 服务连接与授权状态;在线用户主要依赖会话/缓存,不单独落业务表。 | + +### 3.3 HotGo 资金与支付基础能力 + +| 功能 | 核心表 | 说明 | +| --- | --- | --- | +| 后台资金账户 | `hg_admin_cash`、`hg_admin_credits_log` | HotGo 原生后台账户资金及积分/余额变动。与 C 端会员钱包表分离。 | +| HotGo 订单 | `hg_admin_order` | HotGo 原生支付订单,与业务交易订单 `hg_trade_order` 分离。 | +| 支付与退款日志 | `hg_pay_log`、`hg_pay_refund` | 支付请求、回调及退款记录。 | + +### 3.4 插件与开发工具 + +| 功能 | 核心表 | 说明 | +| --- | --- | --- | +| 插件管理 | `hg_sys_addons_install`、`hg_sys_addons_config` | 插件安装状态及插件配置。 | +| 代码生成 | `hg_sys_gen_codes` | 代码生成配置。 | +| 示例插件 | `hg_addon_hgexample_table`、`hg_addon_hgexample_tenant_order` | HotGo 示例数据,不属于正式业务。 | +| 生成示例 | `hg_sys_gen_curd_demo`、`hg_sys_gen_tree_demo`、`hg_test_category` | CRUD/树表/分类演示,不属于正式业务。 | + +## 4. 公共支撑表 + +| 表 | 用途 | 典型使用模块 | +| --- | --- | --- | +| `hg_approval_request` | 审批请求主表 | 会员状态、资金调账、充值、提现等高风险操作。 | +| `hg_approval_action` | 审批动作流水 | 记录提交、通过、拒绝等动作。 | +| `hg_biz_audit_log` | 业务审计日志 | 资金、任务审核、状态变化等重要操作。 | +| `hg_sensitive_access_log` | 敏感数据查看记录 | 会员手机号、实名、银行卡等完整信息查看。 | +| `hg_idempotency_record` | 幂等控制 | 支付、审核执行、钱包入账等不可重复操作。 | +| `hg_outbox_event` | 事务消息/事件出站箱 | 业务提交后异步通知或跨模块事件。 | +| `hg_dashboard_daily_stat` | 每日统计快照 | 首页看板。 | + +## 5. 核心数据关系 + +```text +会员 hg_app_member +├── 扩展资料 hg_app_member_profile +├── 地址 hg_app_member_address +├── 收款账户 hg_app_member_payment_account +├── 等级 hg_app_member_level +├── 钱包 hg_wallet_account +│ ├── 账变流水 hg_wallet_ledger +│ └── 人工调账 hg_wallet_adjustment_request +├── 交易订单 hg_trade_order +├── 充值订单 hg_recharge_order +├── 提现订单 hg_withdrawal_order +└── 任务提交 hg_task_submission + +商品 hg_product +├── 分类 hg_product_category +├── 交易订单 hg_trade_order +└── 任务 hg_task + ├── 等级投放 hg_task_level + └── 会员提交 hg_task_submission +``` + +## 6. 数据存储约定 + +- 业务金额统一以“分”存入 `bigint` 字段,页面负责格式化为元。 +- 会员敏感信息采用密文、检索哈希和脱敏展示值分离保存。 +- 钱包余额以 `hg_wallet_account` 为当前值,`hg_wallet_ledger` 为不可变账变依据。 +- 网站设置字段集中保存在 `hg_site_config_version.config_json`,因此新增配置项通常无需增加数据库列。 +- 商品管理和手工商城共用 `hg_product`,通过 `product_type` 区分。 +- 后台管理员资金表与 C 端会员钱包表完全分离,禁止混用。 +- 带 `tenant_id` 的业务表通过 HotGo 多租户过滤器隔离数据。 +- 带 `deleted_at` 的表使用软删除,不直接物理删除历史业务记录。 diff --git a/docs/admin_reference_prd/后台管理系统开发总结.md b/docs/admin_reference_prd/后台管理系统开发总结.md new file mode 100644 index 0000000..e9ab66c --- /dev/null +++ b/docs/admin_reference_prd/后台管理系统开发总结.md @@ -0,0 +1,453 @@ +# 后台管理系统开发总结 + +> 文档版本:V1.0 +> 编制日期:2026-10-08 +> 需求基线:[后台管理系统需求文档](./后台管理系统需求文档.md) +> 概要设计:[后台管理系统概要设计](./后台管理系统概要设计.md) +> 项目目录:`/Users/youshunlai/go_workspace/olons_admin` + +## 1. 文档说明 + +本文档汇总当前已经完成的后台管理系统开发内容,用于后续联调、测试、验收和继续开发。 + +文档中的状态分为: + +- **已开发**:已完成数据库、后端接口、前端页面和菜单权限的主体实现。 +- **复用现有系统**:HotGo 已提供对应能力,本项目不重复开发。 +- **后续补充**:已有基础模型,但仍需按专项设计补齐业务闭环。 + +## 2. 总体完成情况 + +| 章节 | 模块 | 当前状态 | 说明 | +| --- | --- | --- | --- | +| 第 4 章 | 首页数据看板 | 已开发 | 已接入真实业务统计与待办入口 | +| 第 5 章 | 门户、内容与 Banner | 已开发 | 已完成配置版本、文本、Banner、手工商城 | +| 第 6 章 | 会员管理 | 已开发 | 已完成会员、隐私、团队、钱包调账和通知 | +| 第 7 章 | 会员等级与任务大厅 | 已开发 | 已完成等级版本发布和任务大厅管理 | +| 第 8 章 | 交易管理 | 已开发 | 已完成订单、充值、提现和客服管理 | +| 第 9 章 | 商品与任务管理 | 已开发 | 已完成商品、任务和会员任务审核 | +| 第 10 章 | 管理员、角色与权限 | 复用现有系统 | HotGo 原有组织、管理员、角色和菜单权限满足主体需求 | +| 第 11 章 | 数据字典与个人设置 | 复用现有系统 | HotGo 原有字典、个人资料和安全设置满足主体需求 | +| 第 12 章 | 状态机与数据模型 | 后续补充 | 核心模型已有,冲正、归档和严格状态转换仍需补强 | + +## 3. 技术实现概况 + +### 3.1 后端 + +- Go + GoFrame v2。 +- 遵循 `api → controller → service → logic → dao` 分层。 +- 业务模块使用主模块实现,没有引入额外 Addon。 +- 表字段通过 `dao.Xxx.Columns()` 引用。 +- 多租户数据通过现有 `handler.Model` 和 `hook.SaveTenant` 处理。 +- 金额统一按“分”存储,比例统一按“万分比”存储。 +- 业务字典优先复用 HotGo 字典系统,代码枚举统一在 `internal/consts` 注册。 + +### 3.2 前端 + +- Vue 3 + Vite + TypeScript。 +- UI 统一使用 Naive UI 和项目已有的 `BasicTable`、`BasicForm`、`BasicModal`。 +- HTTP 请求统一通过 `@/utils/http/axios` 的 `http.request`。 +- 菜单由后端数据驱动,页面操作使用接口路径进行权限判断。 +- 状态标签和筛选项从后端字典加载,不在页面硬编码业务枚举。 + +### 3.3 基础治理 + +在业务模块开发前已建设以下共用能力: + +- 审批请求与审批动作。 +- 业务审计日志和哈希链。 +- 敏感信息查看记录。 +- 幂等记录。 +- Outbox 事件表。 +- 看板每日汇总表。 +- 高风险操作的申请、审批、执行分离。 + +对应迁移: + +- `20261008_001_governance.sql` +- `20261008_002_governance_menu.sql` + +## 4. 第 4 章:首页数据看板 + +### 4.1 已实现功能 + +- 今日新增会员、订单、充值、提现等核心指标。 +- 业务金额、订单和会员数据汇总。 +- 待审批和异常业务入口。 +- 按管理员权限控制敏感金额展示。 +- 原 HotGo 控制台菜单复用并扩展业务统计接口。 + +### 4.2 主要接口 + +- `GET /console/stat` +- `GET /dashboard/summary` + +### 4.3 主要代码 + +- 后端:`server/internal/logic/sys/dashboard.go` +- 前端:`web/src/views/dashboard/console/` +- 前端 API:`web/src/api/dashboard/console.ts` +- 菜单迁移:`20261008_003_dashboard_menu.sql` + +### 4.4 测试 + +- 已增加 `server/internal/logic/sys/dashboard_test.go`。 + +## 5. 第 5 章:门户、内容与 Banner 管理 + +### 5.1 网站设置 + +- 站点配置按完整快照保存。 +- 支持草稿保存、提交审批、发布和历史版本查看。 +- 支持根据历史版本生成回滚草稿。 +- 使用摘要和乐观锁避免并发覆盖。 + +主要接口: + +- `/siteConfig/current` +- `/siteConfig/history` +- `/siteConfig/save` +- `/siteConfig/submit` +- `/siteConfig/publish` +- `/siteConfig/rollback` + +### 5.2 文本管理 + +- 文本内容列表、详情、新增和编辑。 +- 内容正文按版本保存。 +- 支持发布、下线和软删除。 +- 保存当前发布版本 ID,历史版本不被覆盖。 + +主要接口: + +- `/portalContent/list` +- `/portalContent/view` +- `/portalContent/edit` +- `/portalContent/publish` +- `/portalContent/offline` +- `/portalContent/delete` + +### 5.3 Banner 管理 + +- Banner 列表、详情、新增、编辑和删除。 +- 支持投放位置、图片、替代文本、跳转方式、生效时间、排序和发布状态。 +- 支持发布和下线状态切换。 + +### 5.4 手工商城 + +- 手工商城商品列表、详情、新增、编辑、删除和上下架。 +- 支持商品类型、支付方式、金额、封面、详情、推荐和展示时间。 + +### 5.5 数据表与代码 + +新增数据表: + +- `hg_site_config_version` +- `hg_content` +- `hg_content_version` +- `hg_banner` +- `hg_product` + +主要代码: + +- 后端:`server/internal/logic/sys/portal.go` +- API:`server/api/admin/portal/portal.go` +- 前端:`web/src/views/portal/` +- 前端 API:`web/src/api/portal/index.ts` +- 迁移:`20261008_004_portal_content.sql` +- 测试:`server/internal/logic/sys/portal_test.go` + +## 6. 第 6 章:会员管理 + +### 6.1 会员主档 + +- 会员列表、详情、新增、编辑和注销。 +- 用户名、等级、上级、风控、信用分、自动派单和测试账号管理。 +- 手机号、姓名、证件号按密文、检索哈希和脱敏值分离保存。 +- 注销采用状态和软删除标记,不删除历史审计主体。 + +### 6.2 收款账户和地址 + +- 多类型收款账户管理。 +- 银行卡、开户名和手机号敏感字段加密及脱敏。 +- 会员地址列表、新增、编辑和删除。 + +### 6.3 敏感信息查看 + +- 完整敏感值通过独立授权接口查看。 +- 必须填写查看目的。 +- 记录操作人、目标、字段集、授权号和查看结果。 + +### 6.4 团队关系 + +- 支持查询会员下级团队。 +- 使用 `pid`、`level` 和 `tree` 保存层级关系。 +- 支持控制查询层级和分页。 + +### 6.5 会员状态 + +- 支持发起会员状态变更审批。 +- 审批通过后由执行接口完成状态变更。 +- 保存状态变更原因、审批单和操作记录。 + +### 6.6 钱包调账 + +- 钱包账户区分可用余额和冻结余额。 +- 调账必须先申请审批,再执行入账。 +- 每次资金变化写入不可变台账。 +- 支持幂等键、前后余额和冲正关联字段。 + +### 6.7 会员通知 + +- 支持全体或指定会员通知。 +- 区分真实通知与运营模拟。 +- 支持有效期和撤回。 + +### 6.8 数据表与代码 + +新增数据表: + +- `hg_app_member` +- `hg_app_member_profile` +- `hg_app_member_address` +- `hg_app_member_payment_account` +- `hg_app_member_status_log` +- `hg_wallet_account` +- `hg_wallet_ledger` +- `hg_wallet_adjustment_request` +- `hg_app_member_notice` + +主要代码: + +- 后端:`server/internal/logic/sys/app_member.go` +- API:`server/api/admin/appmember/appmember.go` +- 前端:`web/src/views/app-member/list/`、`wallet/`、`notice/` +- 前端 API:`web/src/api/appMember/index.ts` +- 迁移:`20261008_005_member_management.sql` + +## 7. 第 7 章:会员等级与任务大厅 + +### 7.1 会员等级 + +- 会员等级列表和详情。 +- 等级规则保存为不可变版本。 +- 支持草稿、提交审批、发布、历史版本和回滚草稿。 +- 使用乐观锁防止并发覆盖。 +- 支持等级启停和删除。 + +主要接口: + +- `/memberLevel/list` +- `/memberLevel/view` +- `/memberLevel/save` +- `/memberLevel/submit` +- `/memberLevel/publish` +- `/memberLevel/rollback` +- `/memberLevel/history` +- `/memberLevel/status` +- `/memberLevel/delete` + +### 7.2 任务大厅 + +- 任务大厅列表、详情、新增和编辑。 +- 支持封面、描述、开放时间、排序和发布状态。 +- 支持配置允许进入的会员等级。 +- 支持发布、下线和删除。 + +### 7.3 数据表与代码 + +新增数据表: + +- `hg_app_member_level` +- `hg_app_member_level_version` +- `hg_task_hall` +- `hg_task_hall_level` + +主要代码: + +- 后端:`member_level.go`、`task_hall.go` +- API:`server/api/admin/memberlevel/`、`taskhall/` +- 前端:`web/src/views/app-member/level/`、`task-hall/` +- 前端 API:`web/src/api/memberLevel/`、`taskHall/` +- 迁移:`20261008_006_member_level_task_hall.sql` + +## 8. 第 8 章:交易管理 + +### 8.1 交易订单 + +- 订单列表和详情。 +- 支持商品、任务和手工商城订单类型。 +- 保存商品名称、金额、会员等级和规则快照。 +- 人工取消匹配、重新匹配和解冻必须经过审批。 +- 执行时重新检查订单和审批状态。 + +### 8.2 充值管理 + +- 充值列表、金额汇总和详情。 +- 支持线上支付和人工充值。 +- 人工审核采用申请与执行分离。 +- 审核通过后在事务内更新钱包并写入台账。 +- 审核结果保存审批单、财务复核快照和审核原因。 + +### 8.3 提现管理 + +- 提现列表和脱敏详情。 +- 支持初审、复核、付款中、成功、失败和驳回状态。 +- 提现审核和执行通过事务、行锁、审批和台账处理。 +- 付款结果单独登记,保存外部付款单号。 + +### 8.4 客服管理 + +- 客服列表、详情、新增、编辑、启停和删除。 +- 支持客服类型、显示名称、联系方式、工作时间和排序。 + +### 8.5 数据表与代码 + +新增数据表: + +- `hg_trade_order` +- `hg_payment_channel` +- `hg_recharge_order` +- `hg_withdrawal_order` +- `hg_finance_review` +- `hg_customer_service` + +主要代码: + +- 后端:`trade_order.go`、`recharge_order.go`、`withdrawal_order.go`、`customer_service.go` +- API:`server/api/admin/tradeorder/`、`rechargeorder/`、`withdrawalorder/`、`customerservice/` +- 前端:`web/src/views/trade/` +- 前端 API:`web/src/api/trade/index.ts` +- 迁移:`20261008_007_trade_management.sql` + +## 9. 第 9 章:商品与任务管理 + +### 9.1 商品管理 + +- 商品列表、详情、新增和编辑。 +- 支持分类、类型、支付方式、店铺、价格、封面、详情和展示时间。 +- 支持上下架、推荐切换和删除。 + +### 9.2 任务管理 + +- 任务列表、详情、新增和编辑。 +- 支持任务大厅、会员等级、封面、详情、固定佣金和比例佣金。 +- 支持每日数量、单会员限制和任务有效期。 +- 支持发布、下线和删除。 + +### 9.3 会员任务审核 + +- 按会员、任务和审核状态查询提交记录。 +- 展示任务、会员、等级、佣金、成功率、证据和审核结果。 +- 待审核记录支持通过和驳回。 +- 驳回保存标准原因、补充说明和是否允许重新提交。 +- 审核通过后在事务内结算佣金并写入钱包台账。 + +### 9.4 数据表与代码 + +新增数据表: + +- `hg_product_category` +- `hg_task` +- `hg_task_level` +- `hg_task_submission` + +主要代码: + +- 后端:`product.go`、`task.go`、`task_submission.go` +- API:`server/api/admin/product/`、`task/`、`tasksubmission/` +- 前端:`web/src/views/product-task/` +- 前端 API:`web/src/api/productTask/index.ts` +- 迁移:`20261008_008_product_task_management.sql` + +菜单“商品与任务”的根布局标识已统一为 HotGo 识别的 `LAYOUT`,进入子页面时左侧菜单和顶部布局可以正常保留。 + +## 10. 复用 HotGo 的现有功能 + +### 10.1 管理员、角色与权限 + +第 10 章不重复开发,复用: + +- 组织管理中的管理员维护。 +- 角色管理和菜单权限树。 +- 接口路径权限控制。 +- 部门、岗位和数据权限。 +- 登录、禁用、密码重置等现有能力。 + +### 10.2 数据字典与个人设置 + +第 11 章不重复开发,复用: + +- “系统设置 → 字典管理”的字典类型和字典数据 CRUD。 +- 字典标签、键值、值类型、标签样式、排序和状态。 +- “个人中心 → 个人设置”的基本资料维护。 +- 手机号和邮箱验证码换绑。 +- 当前密码校验和登录密码修改。 + +密码强度、全部会话撤销、敏感配置版本管理等属于后续安全增强,不纳入当前已开发范围。 + +## 11. 数据库迁移清单 + +| 顺序 | 文件 | 用途 | +| ---: | --- | --- | +| 1 | `20261008_001_governance.sql` | 审批、审计、幂等、Outbox、看板汇总 | +| 2 | `20261008_002_governance_menu.sql` | 治理模块菜单和权限 | +| 3 | `20261008_003_dashboard_menu.sql` | 首页看板菜单和权限 | +| 4 | `20261008_004_portal_content.sql` | 门户、内容、Banner、手工商城 | +| 5 | `20261008_005_member_management.sql` | 会员、敏感资料、钱包和通知 | +| 6 | `20261008_006_member_level_task_hall.sql` | 会员等级和任务大厅 | +| 7 | `20261008_007_trade_management.sql` | 订单、充值、提现和客服 | +| 8 | `20261008_008_product_task_management.sql` | 商品、任务和会员任务审核 | + +以上迁移均采用可重复执行的建表或条件插入方式,菜单、字典和角色权限随对应业务迁移配置。 + +## 12. 当前运行与交付状态 + +- 本地后端运行地址:`http://127.0.0.1:8000`。 +- 本地前端运行地址:`http://127.0.0.1:8001`。 +- 动态菜单已加载首页、治理、门户、会员、交易、商品与任务模块。 +- 第 4~9 章页面已经可以从后台菜单进入查看。 +- 第 10、11 章继续使用 HotGo 原有页面。 + +### 12.1 本地演示数据 + +已为本次新增的 35 张业务表写入关联演示数据,覆盖审批、发布、会员、风控、订单、充值、提现、任务审核、调账和客服等全部已定义状态。演示业务编号统一使用 `DEMO` 前缀。 + +可重复执行的数据脚本: + +```text +server/storage/data/seeds/20261008_business_demo_data.sql +``` + +本地重新导入命令: + +```bash +mysql -h127.0.0.1 -P3306 -uroot -proot olons_admin \ + < server/storage/data/seeds/20261008_business_demo_data.sql +``` + +正式上线前仍需执行完整的接口回归、权限角色矩阵检查、并发资金测试和生产配置核对。 + +--- + +## 补充项:第 12 章状态机与数据模型补强 + +第 12 章不是新的一级菜单,而是对现有会员、资金、任务和内容模块的业务约束补强。当前核心数据表、审批、台账和审计基础已经具备,但以下内容尚未列入“已完成”: + +1. 会员状态合法转换和注销不可逆。 +2. 充值成功后的审批冲正。 +3. 已结算任务佣金的审批冲正。 +4. 文本内容归档和历史版本生成回滚草稿。 +5. 状态转换、重复执行、并发执行和余额不足测试。 + +专项设计已单独整理,后续开发以该文档为实施依据: + +[第12章状态机与数据模型补强设计](./第12章状态机与数据模型补强设计.md) + +建议后续新增迁移: + +```text +server/storage/data/migrations/20261008_009_state_machine_hardening.sql +``` + +MFA 真实认证流程不与本次状态机补强混合实施,后续作为独立安全增强项处理。 diff --git a/docs/admin_reference_prd/后台管理系统概要设计.md b/docs/admin_reference_prd/后台管理系统概要设计.md new file mode 100644 index 0000000..35b1924 --- /dev/null +++ b/docs/admin_reference_prd/后台管理系统概要设计.md @@ -0,0 +1,1244 @@ +# 后台管理系统概要设计 + +> 文档版本:V1.0 +> 编制日期:2026-10-08 +> 依据:[后台管理系统需求文档](./后台管理系统需求文档.md) +> 技术基线:Go 1.24 + GoFrame v2.10 + Vue 3 + TypeScript + Naive UI + MySQL 8.0 + Redis + +## 目录 + +- [1. 文档目标](#1-文档目标) +- [2. 设计原则](#2-设计原则) +- [3. 技术架构](#3-技术架构) +- [4. 系统模块设计](#4-系统模块设计) +- [5. 核心业务流程](#5-核心业务流程) +- [6. 数据库设计](#6-数据库设计) +- [7. 字典与状态设计](#7-字典与状态设计) +- [8. 接口设计约定](#8-接口设计约定) +- [9. 缓存、队列与定时任务](#9-缓存队列与定时任务) +- [10. 安全设计](#10-安全设计) +- [11. 可观测性与运维](#11-可观测性与运维) +- [12. 性能与容量设计](#12-性能与容量设计) +- [13. 开发与数据库迁移顺序](#13-开发与数据库迁移顺序) +- [14. 测试策略](#14-测试策略) +- [15. 分阶段交付](#15-分阶段交付) +- [16. 需进一步确认的设计决策](#16-需进一步确认的设计决策) + +--- + +## 1. 文档目标 + +本文档用于将需求基线转换为可实施的系统概要设计,作为后续详细设计、数据库建模、接口定义、代码开发、测试与上线评审的共同输入。 + +本版设计重点解决: + +- C 端与后台在配置、状态、金额和业务单号上的一致性。 +- 会员隐私数据、银行卡与钱包账户的加密、脱敏、临时授权和审计。 +- 充值、提现、账变、奖励金等资金操作的幂等、台账、冻结、复核与冲正。 +- 站点配置、文本、Banner、会员等级等高影响配置的草稿、审批、发布、版本和回滚。 +- 管理员 RBAC、数据权限、敏感操作复核与不可篡改审计。 + +### 1.1 范围边界 + +本设计覆盖需求文档中的 21 个后台页面和对应 C 端业务闭环。不包含支付机构的具体 SDK 选型、实名认证供应商选型、法律合规结论和生产密钥管理实施细节。这些内容需在接入真实资金前单独评审。 + +## 2. 设计原则 + +1. **单一事实源**:字典、状态、金额口径和配置版本由后端统一提供,前端不硬编码枚举。 +2. **台账驱动资金**:余额不允许普通 CRUD 直接修改,所有变动必须由不可变台账产生。 +3. **敏感数据分离**:会员主表不保存可直接展示的完整敏感值;密文、检索哈希和脱敏值分字段存储。 +4. **最小权限**:菜单权限、接口权限、数据权限和敏感值查看权限分层判定。 +5. **高风险双人复核**:资金、权限、禁用会员和发布配置采用“申请人 ≠ 复核人”。 +6. **服务端状态机**:客户端只发送意图,不直接指定结果状态。 +7. **可追溯与可冲正**:已生效的资金与审批记录不原地覆盖,通过反向记录冲正。 +8. **兼容 HotGo 规范**:遵循 `api → controller → service → logic → dao` 分层,字典由 `internal/consts` 注册,路由由 `genrouter` 加载。 + +## 3. 技术架构 + +```mermaid +flowchart LR + A[后台 Web
Vue 3 + Naive UI] -->|HTTPS /admin| B[GoFrame HTTP API] + C[C 端] -->|HTTPS /api| B + B --> D[认证、RBAC
Casbin + Middleware] + B --> E[业务 Service / Logic] + E --> F[(MySQL 8.0)] + E --> G[(Redis / Cache)] + E --> H[对象存储
附件/凭证/图片] + E --> I[队列 / Outbox] + I --> J[通知、统计、对账消费者] + E --> K[支付/客服/实名等外部服务] + B --> L[日志、Trace、指标、告警] +``` + +### 3.1 部署单元 + +| 单元 | 职责 | 状态 | +| --- | --- | --- | +| `web` | 后台 SPA,路由由后端菜单驱动 | 无状态 | +| `server` | 管理 API、C 端 API、业务状态机、审批和台账 | 无状态,可水平扩展 | +| MySQL | 核心业务数据、台账、审批和审计 | 主从/高可用 | +| Redis | 会话、限流、短期缓存、分布式锁 | 不作资金最终事实源 | +| 对象存储 | Banner、商品、任务、凭证和收款码 | 通过 `hg_sys_attachment` 管理元数据 | +| 队列 | 通知、统计、回调重试和对账 | 必须与 Outbox 表组合 | + +### 3.2 代码模块划分 + +本项目属于系统核心业务,采用主模块实现,不作为临时 Addon。 + +| 业务域 | 后端模块建议 | 前端视图建议 | +| --- | --- | --- | +| 看板 | `dashboard` | `views/dashboard/business` | +| 站点与内容 | `siteConfig`, `content`, `banner`, `customerService` | `views/content/*` | +| 会员 | `appMember`, `memberLevel`, `memberPaymentAccount` | `views/member/*` | +| 商品 | `productCategory`, `product` | `views/product/*` | +| 任务 | `taskHall`, `task`, `taskSubmission` | `views/task/*` | +| 交易 | `tradeOrder`, `recharge`, `withdrawal` | `views/trade/*` | +| 资产 | `wallet`, `walletLedger`, `walletAdjustment` | `views/finance/*` | +| 治理 | `approval`, `sensitiveAccess`, `bizAudit` | `views/governance/*` | + +每个模块依次在以下位置实现: + +```text +server/api/admin// +server/internal/controller/admin/sys/.go +server/internal/service/sys.go +server/internal/logic/sys/.go +server/internal/model/input/sysin/.go +server/internal/router/genrouter/.go +web/src/api//index.ts +web/src/views// +``` + +## 4. 系统模块设计 + +### 4.1 认证与权限 + +复用现有 `hg_admin_member`、`hg_admin_role`、`hg_admin_menu`、`hg_admin_member_role`、`hg_admin_role_menu` 和 Casbin 能力。 + +权限判定顺序: + +1. 校验管理员会话、账号状态和 MFA 状态。 +2. 按路由权限标识判定功能权限。 +3. 通过 `handler.FilterAuth` 或 `FilterAuthWithField` 施加数据范围。 +4. 对完整手机号、银行卡、收款码等额外校验敏感值查看权限和二次认证。 +5. 资金、权限和配置发布类操作进入审批流,申请人不得审批自己的申请。 + +### 4.2 站点配置与内容发布 + +- 站点配置按版本存储为 JSON,同时记录 Schema 版本、摘要和生效时间。 +- 业务代码不从零散 key-value 直接组装核心规则,而是读取唯一的“已发布版本”。 +- 文本内容使用主表 + 版本表;发布仅更新主表的 `published_version_id`。 +- Banner 和客服渠道为结构化数据,支持有效期、排序、启停和作用域。 +- 发布后删除缓存,通过 Outbox 发送“配置已更新”事件。 + +### 4.3 会员与隐私数据 + +- C 端会员使用 `hg_app_member`,不与后台管理员 `hg_admin_member` 混用。 +- 登录检索使用 `mobile_hash`,列表展示使用 `mobile_mask`,完整手机号仅存在 `mobile_cipher`。 +- 哈希使用带服务端 Pepper 的 HMAC-SHA-256,避免穷举原始手机号。 +- 收款账户、地址和身份信息分表存储,列表查询不联表返回完整密文。 +- 敏感值查看接口使用一次性授权令牌,返回短时数据,不缓存且写入专用审计表。 + +### 4.4 商品、任务和交易订单 + +- 商品、任务和会员等级均可停用;被历史订单引用后不得物理删除。 +- 交易订单保存商品、任务、等级和佣金规则快照,后续修改基础配置不影响在途订单。 +- 订单状态由 Logic 层状态机转换,更新时携带 `version` 作为乐观锁。 +- 任务提交通过独立审核表流转,任务通过后由结算服务写入佣金台账。 + +### 4.5 钱包与资金安全 + +资金字段统一使用 `bigint` 存储最小货币单位(CNY 为分),字段名以 `_amount` 或 `_balance` 结尾,不使用 `float64` 参与资金计算。每个资金动作在单个数据库事务内完成: + +1. 锁定业务单和钱包行。 +2. 校验业务单状态、幂等键、可用/冻结余额和审批结果。 +3. 写入不可变台账,台账同时记录变更前后值。 +4. 更新钱包汇总值和版本号。 +5. 更新业务单状态并写入 Outbox 事件。 +6. 事务提交后异步通知 C 端、更新看板和执行对账。 + +### 4.6 统一审批 + +`hg_approval_request` 和 `hg_approval_action` 提供通用审批能力,覆盖: + +- 提现审核与大额复核。 +- 人工充值、账变、奖励金和冲正。 +- 会员禁用、解禁和异常解冻。 +- 角色权限变更。 +- 站点配置、会员等级和重要内容发布。 + +审批请求保存目标类型、目标 ID、操作类型、变更摘要和完整 payload 快照。业务表只引用审批单号,审批通过后由对应业务 Logic 执行最终变更。 + +## 5. 核心业务流程 + +### 5.1 充值入账 + +```mermaid +sequenceDiagram + participant U as C 端会员 + participant API as API + participant P as 支付渠道 + participant R as 充值订单 + participant W as 钱包/台账 + U->>API: 创建充值订单 + API->>R: 写入 pending_payment + API->>P: 创建支付 + P-->>API: 异步回调 + API->>R: 验签、金额、商户、幂等校验 + API->>W: 事务内写台账并增加余额 + API->>R: 置为 success + API-->>U: 通知到账 +``` + +人工凭证充值不经过自动回调,进入初审和复核。两条路径共用同一个入账方法和幂等约束。 + +### 5.2 提现与资金冻结 + +```mermaid +stateDiagram-v2 + [*] --> pending_review: 提交申请并冻结金额 + pending_review --> reviewing: 初审通过 + pending_review --> rejected: 初审驳回 + reviewing --> processing: 复核通过 + reviewing --> rejected: 复核驳回 + processing --> success: 通道付款成功 + processing --> failed: 付款失败 + pending_review --> cancelled: 会员撤销 + rejected --> [*]: 解冻 + cancelled --> [*]: 解冻 + failed --> pending_review: 审核后重试 + success --> [*]: 扣减冻结金额 +``` + +创建提现订单时立即将 `available_balance` 转入 `frozen_balance`;驳回或撤销时解冻;付款成功时扣减冻结余额。每一步均产生台账。 + +### 5.3 任务审核与佣金 + +1. 会员领取任务时生成交易订单,固化商品、任务、等级和佣金快照。 +2. 会员提交任务证据,产生 `task_submission`。 +3. 后台审核通过时更新提交记录,调用结算服务写入佣金台账。 +4. 同一提交记录仅允许产生一笔有效佣金台账。 +5. 已结算记录如需撤销,必须新建冲正审批并写入反向台账。 + +### 5.4 配置发布 + +1. 编辑者基于已发布版本创建草稿。 +2. 前端完成基础校验,后端 `Filter()` 完成 Schema 和跨字段校验。 +3. 提交审批后草稿锁定,禁止再编辑。 +4. 审批人查看前后差异并通过或驳回。 +5. 即时或定时发布,原版本置为历史版本。 +6. 清理配置缓存,通知 C 端与后台重新拉取版本。 + +## 6. 数据库设计 + +### 6.1 数据库基线 + +- 生产基线为 MySQL 8.0,存储引擎 InnoDB,字符集 `utf8mb4`,排序规则统一为 `utf8mb4_0900_ai_ci`。 +- 时间字段使用 `datetime(3)` 保存 UTC,展示时根据用户时区转换。 +- 主键使用 `bigint unsigned`;全局业务单号使用时间有序 ID 或雪花 ID,字符串形式最长 32 位。 +- 金额使用 `bigint` 最小货币单位;比例使用 `int` 万分比,`10000 = 100%`。 +- 新增业务表使用 `hg_` 前缀;不直接修改 CLI 生成的 `entity`、`do` 和 `dao/internal`。 +- 为适配 HotGo 代码生成和多库兼容,业务关系使用逻辑外键 + 索引,默认不创建物理外键。 +- 可编辑业务表使用软删除;台账、审批动作、回调、幂等、Outbox 和审计表禁止删除。 + +### 6.2 通用字段 + +所有新表至少包含 `id`、`tenant_id` 和 `created_at`。可编辑业务表默认使用以下完整模板;台账、审批动作、回调、幂等、Outbox 和审计等不可变表仅保留上述三个基础字段与各自明确定义的业务字段,不设置 `updated_at`、`deleted_at`、`updated_by` 和 `deleted_by`。 + +| 字段 | 类型 | 约束 | 说明 | +| --- | --- | --- | --- | +| `id` | bigint unsigned | PK, auto_increment | 主键 | +| `tenant_id` | bigint unsigned | NOT NULL DEFAULT 0, INDEX | 租户;单租户部署为 0 | +| `status` | tinyint | NOT NULL DEFAULT 1, INDEX | 仅需通用启停时复用 `sys_normal_disable`:1正常、2停用;已有完整业务状态字段的表可省略此字段 | +| `sort` | int | NOT NULL DEFAULT 0 | 排序值,越小越靠前 | +| `version` | int unsigned | NOT NULL DEFAULT 0 | 乐观锁 | +| `remark` | varchar(500) | NULL | 内部备注 | +| `created_by` | bigint unsigned | NOT NULL DEFAULT 0 | 后台创建人;C 端创建时为 0 | +| `updated_by` | bigint unsigned | NOT NULL DEFAULT 0 | 最后后台更新人 | +| `deleted_by` | bigint unsigned | NOT NULL DEFAULT 0 | 软删除人 | +| `created_at` | datetime(3) | NOT NULL | 创建时间 | +| `updated_at` | datetime(3) | NOT NULL | 更新时间 | +| `deleted_at` | datetime(3) | NULL, INDEX | 软删除时间 | + +### 6.3 表关系概览 + +一期共规划 39 张新业务表,按域划分如下: + +| 业务域 | 表数 | 主要表 | +| --- | ---: | --- | +| 配置与内容 | 5 | 配置版本、内容与版本、Banner、客服渠道 | +| 会员 | 8 | 等级与版本、会员、隐私资料、地址、收款账户、会话、状态记录 | +| 商品与任务 | 7 | 分类、商品、任务大厅、任务、等级关系、任务提交 | +| 交易与资金 | 11 | 交易订单、钱包、台账、支付渠道、充值、提现、账变、审核、回调、对账 | +| 治理与可靠性 | 7 | 审批、敏感查看、审计、幂等、Outbox、看板汇总 | +| 通知 | 1 | C 端通知 | + +```mermaid +erDiagram + APP_MEMBER_LEVEL ||--o{ APP_MEMBER : owns + APP_MEMBER ||--|| APP_MEMBER_PROFILE : has + APP_MEMBER ||--o{ APP_MEMBER_ADDRESS : has + APP_MEMBER ||--o{ APP_MEMBER_PAYMENT_ACCOUNT : binds + APP_MEMBER ||--o{ APP_MEMBER_SESSION : logs_in + APP_MEMBER ||--|| WALLET_ACCOUNT : owns + WALLET_ACCOUNT ||--o{ WALLET_LEDGER : produces + PRODUCT_CATEGORY ||--o{ PRODUCT : contains + TASK_HALL ||--o{ TASK_HALL_LEVEL : permits + APP_MEMBER_LEVEL ||--o{ TASK_HALL_LEVEL : allowed + TASK_HALL ||--o{ TASK : groups + TASK ||--o{ TASK_LEVEL : permits + APP_MEMBER_LEVEL ||--o{ TASK_LEVEL : allowed + TASK ||--o{ TRADE_ORDER : creates + APP_MEMBER ||--o{ TRADE_ORDER : places + TRADE_ORDER ||--o| TASK_SUBMISSION : submits + APP_MEMBER ||--o{ RECHARGE_ORDER : recharges + APP_MEMBER ||--o{ WITHDRAWAL_ORDER : withdraws + APP_MEMBER_PAYMENT_ACCOUNT ||--o{ WITHDRAWAL_ORDER : receives + APPROVAL_REQUEST ||--o{ APPROVAL_ACTION : contains + APPROVAL_REQUEST ||--o{ FINANCE_REVIEW : drives + CONTENT ||--o{ CONTENT_VERSION : versions + SITE_CONFIG_VERSION ||--o| APPROVAL_REQUEST : publishes + PAYMENT_CHANNEL ||--o{ RECHARGE_ORDER : handles + PAYMENT_CHANNEL ||--o{ WITHDRAWAL_ORDER : handles +``` + +### 6.4 现有系统表复用 + +| 表 | 用途 | 设计处理 | +| --- | --- | --- | +| `hg_admin_member` | 后台管理员 | 直接复用,不存 C 端会员 | +| `hg_admin_role` / `hg_admin_menu` | 角色、菜单、接口权限 | 直接复用,增加业务菜单数据 | +| `hg_admin_member_role` / `hg_admin_role_menu` | RBAC 关系 | 直接复用 | +| `hg_sys_attachment` | 文件与对象存储元数据 | 图片、凭证、收款码统一引用附件 ID | +| `hg_sys_dict_type` / `hg_sys_dict_data` | 可维护字典 | 用于非核心动态选项 | +| `hg_sys_config` | HotGo 系统自身配置 | 仅保留框架配置,不承载需审批的业务配置 | +| `hg_sys_log` / `hg_sys_login_log` | 请求与登录日志 | 保留,与业务审计表互补 | + +字典功能不新建表、不新建 API、不另做前端 Store。统一复用 `hg_sys_dict_type`、`hg_sys_dict_data`、`server/internal/library/dict`、`/dictData/option`、`/dictData/options` 和 `web/src/store/modules/dict.ts`。详细复用规则见第 7 章。 + +### 6.5 配置与内容域 + +#### 6.5.1 `hg_site_config_version` 站点配置版本 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `config_no` | varchar(32) | NOT NULL, UNIQUE(`tenant_id`,`config_no`) | 配置版本号 | +| `config_group` | varchar(64) | NOT NULL, INDEX | `site_basic`/`trade_rule`/`time_window` 等 | +| `schema_version` | varchar(32) | NOT NULL | 校验 Schema 版本 | +| `config_json` | json | NOT NULL | 完整配置快照 | +| `config_digest` | char(64) | NOT NULL | SHA-256,用于差异与一致性校验 | +| `publish_status` | tinyint | NOT NULL, INDEX | 1草稿 2待审 3已发布 4已回滚 5已失效 | +| `effective_at` | datetime(3) | NULL, INDEX | 计划生效时间 | +| `published_at` | datetime(3) | NULL | 实际发布时间 | +| `approval_request_id` | bigint unsigned | NOT NULL DEFAULT 0, INDEX | 关联审批单 | +| `base_version_id` | bigint unsigned | NOT NULL DEFAULT 0 | 基础版本 | + +索引:`INDEX idx_config_current (tenant_id, config_group, publish_status, effective_at)`。同一租户和配置组在某一时点只允许一个有效已发布版本,由发布事务保证。 + +#### 6.5.2 `hg_content` 内容主表 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `content_key` | varchar(64) | UNIQUE(`tenant_id`,`content_key`) | 稳定内容标识,删除后不复用 | +| `content_type` | varchar(32) | NOT NULL, INDEX | notice/about/faq/rule/activity/popup | +| `title` | varchar(200) | NOT NULL | 后台标题 | +| `published_version_id` | bigint unsigned | NOT NULL DEFAULT 0 | 当前发布版本 | +| `publish_status` | tinyint | NOT NULL, INDEX | 内容状态 | +| `published_at` | datetime(3) | NULL | 发布时间 | + +#### 6.5.3 `hg_content_version` 内容版本 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `content_id` | bigint unsigned | NOT NULL, INDEX | 内容主表 ID | +| `version_no` | int unsigned | UNIQUE(`content_id`,`version_no`) | 递增版本 | +| `title` | varchar(200) | NOT NULL | 展示标题 | +| `summary` | varchar(500) | NULL | 摘要 | +| `body_html` | longtext | NOT NULL | 服务端清洗后 HTML | +| `body_text` | longtext | NULL | 搜索与降级文本 | +| `asset_ids` | json | NULL | 正文引用附件 ID | +| `publish_status` | tinyint | NOT NULL, INDEX | 1草稿 2待审 3已发布 4已下线 5已归档 | +| `effective_at` | datetime(3) | NULL | 定时发布 | +| `approval_request_id` | bigint unsigned | NOT NULL DEFAULT 0 | 审批单 | + +#### 6.5.4 `hg_banner` Banner + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `name` | varchar(100) | NOT NULL | 后台名称 | +| `position` | varchar(32) | NOT NULL, INDEX | home_top/home_popup 等 | +| `image_attachment_id` | bigint unsigned | NOT NULL | 图片附件 | +| `alt_text` | varchar(200) | NOT NULL | 替代文本 | +| `target_type` | tinyint | NOT NULL | 1无跳转 2内部路由 3外部 URL | +| `target_value` | varchar(500) | NULL | 跳转值 | +| `start_at` / `end_at` | datetime(3) | NULL, INDEX | 有效期 | +| `publish_status` | tinyint | NOT NULL, INDEX | 草稿/已发布/已下线 | + +#### 6.5.5 `hg_customer_service_channel` 客服渠道 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `name` | varchar(100) | NOT NULL | 渠道名称 | +| `channel_type` | tinyint | NOT NULL | 1内置工单 2外部链接 3客服电话 4即时通讯 | +| `entry_url_cipher` | varchar(1024) | NULL | 加密入口地址 | +| `fallback_text` | varchar(500) | NULL | 降级联系方式 | +| `work_time_json` | json | NOT NULL | 工作时段及时区 | +| `allowed_origins` | json | NULL | iframe 来源白名单 | + +### 6.6 会员域 + +#### 6.6.1 `hg_app_member_level` 会员等级 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `level_code` | varchar(32) | UNIQUE(`tenant_id`,`level_code`) | 稳定等级编码 | +| `name` | varchar(64) | NOT NULL | 等级名称 | +| `current_version_id` | bigint unsigned | NOT NULL DEFAULT 0 | 当前规则版本 | +| `member_count` | bigint unsigned | NOT NULL DEFAULT 0 | 可重建的统计值 | + +#### 6.6.2 `hg_app_member_level_version` 等级规则版本 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `level_id` | bigint unsigned | NOT NULL, INDEX | 等级 ID | +| `version_no` | int unsigned | UNIQUE(`level_id`,`version_no`) | 版本号 | +| `upgrade_amount` | bigint | NOT NULL DEFAULT 0 | 升级金额,分 | +| `gift_amount` | bigint | NOT NULL DEFAULT 0 | 赠送金额,分 | +| `daily_order_limit` | int unsigned | NOT NULL DEFAULT 0 | 每日接单次数 | +| `commission_rate` | int unsigned | NOT NULL DEFAULT 0 | 佣金万分比 | +| `daily_withdraw_limit` | int unsigned | NOT NULL DEFAULT 0 | 每日提现次数 | +| `rule_json` | json | NULL | 扩展规则快照 | +| `publish_status` | tinyint | NOT NULL, INDEX | 发布状态 | +| `effective_at` | datetime(3) | NULL | 生效时间 | + +#### 6.6.3 `hg_app_member` C 端会员 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `member_no` | varchar(32) | UNIQUE(`tenant_id`,`member_no`) | 对外会员号 | +| `username` | varchar(64) | UNIQUE(`tenant_id`,`username`) | 登录名,注销后不复用 | +| `mobile_cipher` | varchar(512) | NOT NULL | 手机号密文 | +| `mobile_hash` | char(64) | UNIQUE(`tenant_id`,`mobile_hash`) | 带 Pepper 检索哈希,注销后按合规策略做不可逆匿名化 | +| `mobile_mask` | varchar(32) | NOT NULL | 脱敏手机号 | +| `password_hash` | varchar(255) | NOT NULL | Argon2id/bcrypt 结果 | +| `trade_password_hash` | varchar(255) | NULL | 交易密码,不可回显 | +| `level_id` | bigint unsigned | NOT NULL, INDEX | 会员等级 | +| `parent_id` | bigint unsigned | NOT NULL DEFAULT 0, INDEX | 直接上级 | +| `level` | int unsigned | NOT NULL DEFAULT 1 | 关系树级别 | +| `tree` | varchar(1024) | NOT NULL DEFAULT '' | 关系树路径 | +| `invite_code` | varchar(32) | UNIQUE(`tenant_id`,`invite_code`) | 邀请码 | +| `member_status` | tinyint | NOT NULL DEFAULT 1, INDEX | 会员生命周期:正常/受限/禁用/注销 | +| `risk_status` | tinyint | NOT NULL DEFAULT 1, INDEX | 1正常 2观察 3限制 4冻结 | +| `auto_dispatch` | tinyint | NOT NULL DEFAULT 2 | 复用 `sys_switch`:1开启、2关闭 | +| `credit_score` | int | NOT NULL DEFAULT 100 | 信用分 | +| `last_login_at` | datetime(3) | NULL | 最后登录时间 | +| `last_login_ip_cipher` | varchar(512) | NULL | 加密 IP | +| `last_login_region` | varchar(128) | NULL | IP 地区粗粒度结果 | + +重要索引:`idx_member_parent (tenant_id,parent_id,status)`、`idx_member_level (tenant_id,level_id,status)`、`idx_member_created (tenant_id,created_at,id)`。 + +#### 6.6.4 `hg_app_member_profile` 会员隐私资料 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `member_id` | bigint unsigned | UNIQUE | 会员 ID | +| `real_name_cipher` | varchar(512) | NULL | 姓名密文 | +| `real_name_mask` | varchar(64) | NULL | 脱敏姓名 | +| `id_no_cipher` | varchar(1024) | NULL | 证件号密文 | +| `id_no_hash` | char(64) | NULL, INDEX | 证件检索哈希 | +| `id_no_mask` | varchar(64) | NULL | 脱敏证件号 | +| `avatar_attachment_id` | bigint unsigned | NOT NULL DEFAULT 0 | 头像 | +| `kyc_status` | tinyint | NOT NULL DEFAULT 0, INDEX | 0未认证 1审核中 2已认证 3驳回 | +| `kyc_verified_at` | datetime(3) | NULL | 认证时间 | + +#### 6.6.5 `hg_app_member_address` 会员地址 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `member_id` | bigint unsigned | NOT NULL, INDEX | 会员 ID | +| `receiver_name_cipher` / `receiver_name_mask` | varchar(512)/varchar(64) | NOT NULL | 收件人密文/脱敏值 | +| `receiver_mobile_cipher` / `receiver_mobile_mask` | varchar(512)/varchar(32) | NOT NULL | 电话密文/脱敏值 | +| `province_id` / `city_id` / `district_id` | bigint unsigned | NOT NULL DEFAULT 0 | 省市区 | +| `address_cipher` | varchar(1024) | NOT NULL | 详细地址密文 | +| `is_default` | tinyint | NOT NULL DEFAULT 0 | 默认地址 | + +#### 6.6.6 `hg_app_member_payment_account` 收款账户 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `member_id` | bigint unsigned | NOT NULL, INDEX | 会员 ID | +| `account_type` | tinyint | NOT NULL, INDEX | 1银行卡 2数字钱包 3云闪付 4支付宝 5微信 | +| `bank_code` | varchar(32) | NULL | 银行编码 | +| `bank_name` | varchar(100) | NULL | 银行名称快照 | +| `holder_name_cipher` / `holder_name_mask` | varchar(512)/varchar(64) | NOT NULL | 户名 | +| `account_no_cipher` | varchar(1024) | NOT NULL | 账号密文 | +| `account_no_hash` | char(64) | NOT NULL, INDEX | 检索与去重哈希 | +| `account_no_mask` | varchar(64) | NOT NULL | 脱敏账号 | +| `qr_attachment_id` | bigint unsigned | NOT NULL DEFAULT 0 | 收款码附件 | +| `verify_status` | tinyint | NOT NULL DEFAULT 0 | 校验状态 | +| `is_default` | tinyint | NOT NULL DEFAULT 0 | 默认收款账户 | + +唯一约束:`UNIQUE (tenant_id,member_id,account_type,account_no_hash)`。已解绑账户可重新启用,不重复插入。MySQL 中 `NULL` 不能可靠表示“仅未删除数据唯一”,因此本设计不将可空 `deleted_at` 加入唯一索引。 + +#### 6.6.7 `hg_app_member_session` 会员会话 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `member_id` | bigint unsigned | NOT NULL, INDEX | 会员 ID | +| `session_no` | varchar(64) | UNIQUE | 会话号 | +| `refresh_token_hash` | char(64) | NOT NULL | 刷新令牌哈希 | +| `device_id_hash` | char(64) | NULL, INDEX | 设备标识哈希 | +| `ip_cipher` | varchar(512) | NULL | IP 密文 | +| `user_agent` | varchar(512) | NULL | 客户端信息 | +| `expires_at` | datetime(3) | NOT NULL, INDEX | 过期时间 | +| `revoked_at` | datetime(3) | NULL | 撤销时间 | + +#### 6.6.8 `hg_app_member_status_log` 会员状态记录 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `member_id` | bigint unsigned | NOT NULL, INDEX | 会员 ID | +| `from_status` / `to_status` | tinyint | NOT NULL | 状态变更 | +| `reason_code` | varchar(64) | NOT NULL | 标准原因 | +| `reason_text` | varchar(500) | NULL | 补充说明 | +| `effective_at` / `expire_at` | datetime(3) | NULL | 生效和到期时间 | +| `approval_request_id` | bigint unsigned | NOT NULL DEFAULT 0 | 审批单 | +| `operator_id` | bigint unsigned | NOT NULL | 操作人 | + +该表为追加表,不软删除。 + +### 6.7 商品与任务域 + +#### 6.7.1 `hg_product_category` 商品分类 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `pid` | bigint unsigned | NOT NULL DEFAULT 0, INDEX | 父级 ID | +| `level` | int unsigned | NOT NULL DEFAULT 1 | 树等级 | +| `tree` | varchar(512) | NOT NULL DEFAULT '' | 关系树 | +| `category_code` | varchar(32) | UNIQUE(`tenant_id`,`category_code`) | 分类编码 | +| `name` | varchar(100) | NOT NULL | 分类名称 | + +#### 6.7.2 `hg_product` 商品 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `product_no` | varchar(32) | UNIQUE(`tenant_id`,`product_no`) | 商品编号 | +| `category_id` | bigint unsigned | NOT NULL, INDEX | 分类 | +| `product_type` | tinyint | NOT NULL DEFAULT 1, INDEX | 1标准商品 2手工商城商品 | +| `payment_type` | varchar(32) | NOT NULL DEFAULT 'balance', INDEX | 优先复用并按需扩展现有 `payType` 枚举字典 | +| `name` | varchar(200) | NOT NULL, INDEX | 商品名称 | +| `shop_name` | varchar(100) | NOT NULL | 店铺名称快照 | +| `price_amount` | bigint | NOT NULL | 单价,分 | +| `currency` | char(3) | NOT NULL DEFAULT 'CNY' | 币种 | +| `cover_attachment_id` | bigint unsigned | NOT NULL | 封面 | +| `detail_html` | longtext | NULL | 清洗后富文本 | +| `is_recommended` | tinyint | NOT NULL DEFAULT 2, INDEX | 复用 `sys_switch`:1推荐、2不推荐 | +| `publish_status` | tinyint | NOT NULL, INDEX | 草稿/上架/下架 | +| `start_at` / `end_at` | datetime(3) | NULL | 展示时间 | + +#### 6.7.3 `hg_task_hall` 任务大厅 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `hall_code` | varchar(32) | UNIQUE(`tenant_id`,`hall_code`) | 大厅编码 | +| `name` | varchar(100) | NOT NULL | 名称 | +| `icon_attachment_id` | bigint unsigned | NOT NULL | 图标 | +| `summary` | varchar(500) | NULL | 简介 | +| `commission_rate` | int unsigned | NOT NULL DEFAULT 0 | 万分比 | +| `publish_status` | tinyint | NOT NULL, INDEX | 发布状态 | + +#### 6.7.4 `hg_task_hall_level` 任务大厅可用等级 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `id` | bigint unsigned | PK, auto_increment | 主键 | +| `tenant_id` | bigint unsigned | NOT NULL DEFAULT 0 | 租户 | +| `hall_id` | bigint unsigned | NOT NULL, INDEX | 任务大厅 | +| `level_id` | bigint unsigned | NOT NULL, INDEX | 会员等级 | +| `created_at` | datetime(3) | NOT NULL | 创建时间 | + +唯一约束:`UNIQUE (tenant_id,hall_id,level_id)`。 + +#### 6.7.5 `hg_task` 任务 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `task_no` | varchar(32) | UNIQUE(`tenant_id`,`task_no`) | 任务编号 | +| `hall_id` | bigint unsigned | NOT NULL, INDEX | 任务大厅 | +| `title` | varchar(200) | NOT NULL | 标题 | +| `description` | varchar(1000) | NULL | 描述 | +| `detail_html` | longtext | NULL | 详情 | +| `cover_attachment_id` | bigint unsigned | NOT NULL | 封面 | +| `commission_amount` | bigint | NOT NULL DEFAULT 0 | 固定佣金,分 | +| `commission_rate` | int unsigned | NOT NULL DEFAULT 0 | 比例佣金,万分比 | +| `daily_limit` | int unsigned | NOT NULL DEFAULT 0 | 每日总量,0 不限 | +| `per_member_limit` | int unsigned | NOT NULL DEFAULT 1 | 单会员限制 | +| `start_at` / `end_at` | datetime(3) | NULL, INDEX | 任务周期 | +| `publish_status` | tinyint | NOT NULL, INDEX | 发布状态 | + +#### 6.7.6 `hg_task_level` 任务可用等级 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `id` | bigint unsigned | PK, auto_increment | 主键 | +| `tenant_id` | bigint unsigned | NOT NULL DEFAULT 0 | 租户 | +| `task_id` | bigint unsigned | NOT NULL, INDEX | 任务 | +| `level_id` | bigint unsigned | NOT NULL, INDEX | 会员等级 | +| `created_at` | datetime(3) | NOT NULL | 创建时间 | + +唯一约束:`UNIQUE (tenant_id,task_id,level_id)`。 + +#### 6.7.7 `hg_task_submission` 会员任务提交 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `submission_no` | varchar(32) | UNIQUE | 提交单号 | +| `trade_order_id` | bigint unsigned | UNIQUE | 交易订单 | +| `task_id` | bigint unsigned | NOT NULL, INDEX | 任务 | +| `member_id` | bigint unsigned | NOT NULL, INDEX | 会员 | +| `evidence_text` | varchar(2000) | NULL | 提交说明 | +| `evidence_attachment_ids` | json | NULL | 证据附件 ID | +| `submission_status` | tinyint | NOT NULL, INDEX | 1待审 2通过 3驳回 4已结算 5已冲正 | +| `commission_amount` | bigint | NOT NULL DEFAULT 0 | 审核时的佣金快照 | +| `reviewed_by` | bigint unsigned | NOT NULL DEFAULT 0 | 审核人 | +| `reviewed_at` | datetime(3) | NULL | 审核时间 | +| `review_reason` | varchar(500) | NULL | 审核意见 | +| `settled_at` | datetime(3) | NULL | 结算时间 | + +### 6.8 交易与资金域 + +#### 6.8.1 `hg_trade_order` 交易订单 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `order_no` | varchar(32) | UNIQUE | 订单号 | +| `member_id` | bigint unsigned | NOT NULL, INDEX | 会员 | +| `task_id` / `product_id` | bigint unsigned | NOT NULL DEFAULT 0, INDEX | 任务/商品 | +| `order_type` | tinyint | NOT NULL, INDEX | 1商品 2任务 3手工商城 | +| `quantity` | int unsigned | NOT NULL DEFAULT 1 | 数量 | +| `unit_price_amount` | bigint | NOT NULL | 单价,分 | +| `total_amount` | bigint | NOT NULL | 订单金额,分 | +| `commission_amount` | bigint | NOT NULL DEFAULT 0 | 佣金,分 | +| `currency` | char(3) | NOT NULL DEFAULT 'CNY' | 币种 | +| `member_level_id` | bigint unsigned | NOT NULL | 下单时等级 | +| `rule_snapshot` | json | NOT NULL | 商品、等级、佣金规则快照 | +| `order_status` | tinyint | NOT NULL, INDEX | 匹配中/待处理/处理中/完成/超时/冻结/取消/失败 | +| `freeze_status` | tinyint | NOT NULL DEFAULT 0 | 冻结状态 | +| `matched_at` / `completed_at` / `unfrozen_at` | datetime(3) | NULL | 业务节点 | + +索引:`idx_order_member_time (tenant_id,member_id,created_at,id)`、`idx_order_status_time (tenant_id,order_status,created_at,id)`。 + +#### 6.8.2 `hg_wallet_account` 钱包账户 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `member_id` | bigint unsigned | UNIQUE(`tenant_id`,`member_id`,`currency`) | 会员 | +| `currency` | char(3) | NOT NULL DEFAULT 'CNY' | 币种 | +| `available_balance` | bigint | NOT NULL DEFAULT 0 | 可用余额,分 | +| `frozen_balance` | bigint | NOT NULL DEFAULT 0 | 冻结余额,分 | +| `total_income` | bigint | NOT NULL DEFAULT 0 | 累计收入,可重建 | +| `total_expense` | bigint | NOT NULL DEFAULT 0 | 累计支出,可重建 | +| `account_status` | tinyint | NOT NULL DEFAULT 1 | 1正常 2只收不付 3冻结 4关闭 | +| `version` | int unsigned | NOT NULL DEFAULT 0 | 乐观锁 | + +检查约束:`available_balance >= 0`、`frozen_balance >= 0`。 + +#### 6.8.3 `hg_wallet_ledger` 钱包台账 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `ledger_no` | varchar(32) | UNIQUE | 台账号 | +| `account_id` | bigint unsigned | NOT NULL, INDEX | 钱包账户 | +| `member_id` | bigint unsigned | NOT NULL, INDEX | 会员 | +| `biz_type` | varchar(32) | NOT NULL, INDEX | recharge/withdraw/freeze/unfreeze/commission/adjust/reversal | +| `biz_no` | varchar(32) | NOT NULL | 业务单号 | +| `entry_type` | tinyint | NOT NULL | 1可用余额 2冻结余额 | +| `direction` | tinyint | NOT NULL | 1收入 2支出 | +| `amount` | bigint | NOT NULL | 变动绝对值,分 | +| `before_balance` / `after_balance` | bigint | NOT NULL | 变动前后值 | +| `currency` | char(3) | NOT NULL | 币种 | +| `reversal_of` | bigint unsigned | NOT NULL DEFAULT 0, INDEX | 被冲正台账 ID | +| `idempotency_key` | varchar(128) | NOT NULL | 幂等键 | +| `occurred_at` | datetime(3) | NOT NULL, INDEX | 业务发生时间 | +| `created_at` | datetime(3) | NOT NULL | 入库时间 | + +唯一约束:`UNIQUE (account_id,idempotency_key)`。表中不设置 `updated_at`、`deleted_at`,禁止 UPDATE 和 DELETE。 + +#### 6.8.4 `hg_payment_channel` 支付渠道 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `channel_code` | varchar(32) | UNIQUE(`tenant_id`,`channel_code`) | 渠道编码 | +| `name` | varchar(100) | NOT NULL | 渠道名称 | +| `channel_type` | tinyint | NOT NULL, INDEX | 1微信 2支付宝 3银行卡 4人工 | +| `direction` | tinyint | NOT NULL | 1充值 2提现 3双向 | +| `config_cipher` | longtext | NULL | 渠道密钥加密密文,不返回前端 | +| `min_amount` / `max_amount` | bigint | NOT NULL DEFAULT 0 | 金额限制 | +| `fee_type` | tinyint | NOT NULL DEFAULT 1 | 1固定 2比例 3混合 | +| `fee_fixed_amount` | bigint | NOT NULL DEFAULT 0 | 固定手续费 | +| `fee_rate` | int unsigned | NOT NULL DEFAULT 0 | 费率万分比 | + +#### 6.8.5 `hg_recharge_order` 充值订单 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `recharge_no` | varchar(32) | UNIQUE | 充值单号 | +| `member_id` | bigint unsigned | NOT NULL, INDEX | 会员 | +| `channel_id` | bigint unsigned | NOT NULL, INDEX | 支付渠道 | +| `request_amount` / `paid_amount` | bigint | NOT NULL | 申请/实付金额 | +| `currency` | char(3) | NOT NULL DEFAULT 'CNY' | 币种 | +| `external_no` | varchar(128) | NULL, INDEX | 外部支付单号 | +| `voucher_attachment_ids` | json | NULL | 人工凭证 | +| `recharge_status` | tinyint | NOT NULL, INDEX | 待支付/待审/成功/驳回/过期/取消 | +| `paid_at` / `reviewed_at` / `credited_at` | datetime(3) | NULL | 关键时间 | +| `approval_request_id` | bigint unsigned | NOT NULL DEFAULT 0 | 人工审核单 | +| `ledger_id` | bigint unsigned | NOT NULL DEFAULT 0 | 入账台账 | + +索引:`idx_recharge_member_time`、`idx_recharge_status_time`;外部单号在非空时必须唯一,由 Logic 与幂等表联合保证。 + +#### 6.8.6 `hg_withdrawal_order` 提现订单 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `withdrawal_no` | varchar(32) | UNIQUE | 提现单号 | +| `member_id` | bigint unsigned | NOT NULL, INDEX | 会员 | +| `payment_account_id` | bigint unsigned | NOT NULL | 收款账户 | +| `channel_id` | bigint unsigned | NOT NULL DEFAULT 0 | 付款渠道 | +| `request_amount` | bigint | NOT NULL | 申请金额 | +| `fee_amount` | bigint | NOT NULL DEFAULT 0 | 手续费 | +| `actual_amount` | bigint | NOT NULL | 实际到账 | +| `currency` | char(3) | NOT NULL DEFAULT 'CNY' | 币种 | +| `account_snapshot_cipher` | longtext | NOT NULL | 收款账户加密快照 | +| `account_mask` | varchar(128) | NOT NULL | 脱敏快照 | +| `risk_result` | json | NULL | 风控命中摘要 | +| `withdrawal_status` | tinyint | NOT NULL, INDEX | 待审/复核中/处理中/成功/失败/驳回/取消 | +| `approval_request_id` | bigint unsigned | NOT NULL DEFAULT 0 | 审批单 | +| `external_no` | varchar(128) | NULL, INDEX | 外部付款单号 | +| `freeze_ledger_id` / `final_ledger_id` | bigint unsigned | NOT NULL DEFAULT 0 | 冻结/完成台账 | +| `reviewed_at` / `processed_at` / `completed_at` | datetime(3) | NULL | 关键时间 | + +#### 6.8.7 `hg_wallet_adjustment_request` 账变申请 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `request_no` | varchar(32) | UNIQUE | 申请单号 | +| `member_id` / `account_id` | bigint unsigned | NOT NULL, INDEX | 会员与钱包 | +| `adjust_type` | tinyint | NOT NULL | 1奖励 2补款 3扣款 4冲正 5其他 | +| `direction` | tinyint | NOT NULL | 收入/支出 | +| `amount` | bigint | NOT NULL | 金额,分 | +| `reason_code` / `reason_text` | varchar(64)/varchar(500) | NOT NULL | 原因 | +| `evidence_attachment_ids` | json | NULL | 凭证 | +| `request_status` | tinyint | NOT NULL, INDEX | 草稿/待审/通过/驳回/已执行/失败 | +| `approval_request_id` | bigint unsigned | NOT NULL DEFAULT 0 | 审批单 | +| `ledger_id` | bigint unsigned | NOT NULL DEFAULT 0 | 执行后台账 | + +#### 6.8.8 `hg_finance_review` 财务审核记录 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `approval_request_id` | bigint unsigned | NOT NULL, INDEX | 审批单 | +| `biz_type` / `biz_id` | varchar(32)/bigint unsigned | NOT NULL, INDEX | 充值/提现/账变等 | +| `review_stage` | tinyint | NOT NULL | 1初审 2复核 3放款 | +| `reviewer_id` | bigint unsigned | NOT NULL, INDEX | 审核人 | +| `decision` | tinyint | NOT NULL | 1通过 2驳回 3退回补充 | +| `reason_code` / `reason_text` | varchar(64)/varchar(500) | NOT NULL | 意见 | +| `snapshot_json` | json | NOT NULL | 审核时数据快照 | +| `created_at` | datetime(3) | NOT NULL | 审核时间 | + +唯一约束:`UNIQUE (approval_request_id,review_stage,reviewer_id)`。申请人与审核人不同的约束由 Logic 保证。 + +#### 6.8.9 `hg_payment_callback` 支付回调记录 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `channel_id` | bigint unsigned | NOT NULL, INDEX | 渠道 | +| `callback_no` | varchar(128) | UNIQUE | 渠道回调唯一号 | +| `biz_type` / `biz_no` | varchar(32)/varchar(32) | NOT NULL, INDEX | 业务定位 | +| `headers_digest` | char(64) | NOT NULL | Header 摘要 | +| `payload_cipher` | longtext | NOT NULL | 回调加密原文 | +| `verify_status` | tinyint | NOT NULL | 验签结果 | +| `process_status` | tinyint | NOT NULL, INDEX | 待处理/成功/失败/已忽略 | +| `error_message` | varchar(1000) | NULL | 处理失败摘要 | +| `received_at` / `processed_at` | datetime(3) | NOT NULL/NULL | 回调时间 | + +该表不软删除,原文禁止直接记入通用日志。 + +#### 6.8.10 `hg_reconciliation_batch` 对账批次 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `batch_no` | varchar(32) | UNIQUE | 对账批次号 | +| `channel_id` | bigint unsigned | NOT NULL DEFAULT 0, INDEX | 渠道,0 表示内部台账对账 | +| `reconcile_date` | date | NOT NULL, INDEX | 对账日期 | +| `source_type` | tinyint | NOT NULL | 1渠道账单 2业务单/台账 3钱包/台账 | +| `file_attachment_id` | bigint unsigned | NOT NULL DEFAULT 0 | 原始账单文件 | +| `total_count` / `matched_count` / `difference_count` | bigint unsigned | NOT NULL DEFAULT 0 | 数量汇总 | +| `total_amount` / `difference_amount` | bigint | NOT NULL DEFAULT 0 | 金额汇总 | +| `batch_status` | tinyint | NOT NULL, INDEX | 1待执行 2执行中 3完成 4有差异 5失败 | +| `started_at` / `finished_at` | datetime(3) | NULL | 执行时间 | + +唯一约束:`UNIQUE (tenant_id,channel_id,reconcile_date,source_type)`。 + +#### 6.8.11 `hg_reconciliation_item` 对账差异项 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `batch_id` | bigint unsigned | NOT NULL, INDEX | 对账批次 | +| `biz_type` / `biz_no` | varchar(32)/varchar(32) | NOT NULL, INDEX | 内部业务单 | +| `external_no` | varchar(128) | NULL, INDEX | 渠道单号 | +| `difference_type` | tinyint | NOT NULL, INDEX | 1内部多 2渠道多 3金额差 4状态差 5时间差 | +| `internal_amount` / `external_amount` | bigint | NOT NULL DEFAULT 0 | 内部/外部金额 | +| `internal_status` / `external_status` | varchar(32) | NULL | 状态快照 | +| `item_status` | tinyint | NOT NULL, INDEX | 1待处理 2已确认 3已修复 4已忽略 | +| `handler_id` | bigint unsigned | NOT NULL DEFAULT 0 | 处理人 | +| `handle_reason` | varchar(500) | NULL | 处理说明 | +| `handled_at` | datetime(3) | NULL | 处理时间 | + +差异修复如涉及资金,必须发起账变或冲正审批,禁止在对账页面直接修改台账。 + +### 6.9 审批、审计与可靠性域 + +#### 6.9.1 `hg_approval_request` 审批请求 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `approval_no` | varchar(32) | UNIQUE | 审批单号 | +| `approval_type` | varchar(32) | NOT NULL, INDEX | withdrawal/config/permission/member_status/adjustment | +| `target_type` / `target_id` | varchar(32)/bigint unsigned | NOT NULL, INDEX | 目标定位 | +| `action` | varchar(64) | NOT NULL | 拟执行动作 | +| `title` | varchar(200) | NOT NULL | 审批摘要 | +| `payload_json` | json | NOT NULL | 待执行数据快照 | +| `diff_json` | json | NULL | 前后差异 | +| `risk_level` | tinyint | NOT NULL DEFAULT 1 | 1低 2中 3高 4极高 | +| `required_approvals` | int unsigned | NOT NULL DEFAULT 1 | 需要的通过数 | +| `approval_status` | tinyint | NOT NULL, INDEX | 草稿/待审/审批中/通过/驳回/取消/已执行/失败 | +| `applicant_id` | bigint unsigned | NOT NULL, INDEX | 申请人 | +| `submitted_at` / `decided_at` / `executed_at` | datetime(3) | NULL | 关键时间 | +| `expire_at` | datetime(3) | NULL | 超时时间 | + +#### 6.9.2 `hg_approval_action` 审批动作 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `approval_request_id` | bigint unsigned | NOT NULL, INDEX | 审批请求 | +| `step_no` | int unsigned | NOT NULL | 节点顺序 | +| `actor_id` | bigint unsigned | NOT NULL, INDEX | 操作人 | +| `action` | tinyint | NOT NULL | 1提交 2通过 3驳回 4退回 5取消 6执行 | +| `reason_code` / `comment` | varchar(64)/varchar(1000) | NULL | 原因和意见 | +| `snapshot_json` | json | NOT NULL | 当时快照 | +| `actor_ip_cipher` | varchar(512) | NULL | 操作 IP 密文 | +| `mfa_verified` | tinyint | NOT NULL DEFAULT 0 | 是否二次认证 | +| `created_at` | datetime(3) | NOT NULL | 动作时间 | + +追加表,不允许 UPDATE/DELETE。 + +#### 6.9.3 `hg_sensitive_access_log` 敏感数据查看日志 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `access_no` | varchar(32) | UNIQUE | 查看流水号 | +| `actor_id` | bigint unsigned | NOT NULL, INDEX | 管理员 | +| `target_type` / `target_id` | varchar(32)/bigint unsigned | NOT NULL, INDEX | 被查看对象 | +| `field_set` | json | NOT NULL | 查看的字段集,不保存字段值 | +| `purpose_code` / `purpose_text` | varchar(64)/varchar(500) | NOT NULL | 用途 | +| `authorization_no` | varchar(64) | NULL | 授权号 | +| `mfa_verified` | tinyint | NOT NULL | 二次认证 | +| `result` | tinyint | NOT NULL | 允许/拒绝/失败 | +| `trace_id` | varchar(64) | NOT NULL, INDEX | 链路 ID | +| `created_at` | datetime(3) | NOT NULL, INDEX | 查看时间 | + +#### 6.9.4 `hg_biz_audit_log` 业务审计日志 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `audit_no` | varchar(32) | UNIQUE | 审计号 | +| `actor_type` / `actor_id` | tinyint/bigint unsigned | NOT NULL, INDEX | 管理员/会员/系统 | +| `module` / `action` | varchar(64) | NOT NULL, INDEX | 模块与动作 | +| `target_type` / `target_id` | varchar(64)/bigint unsigned | NOT NULL, INDEX | 目标 | +| `before_digest` / `after_digest` | char(64) | NULL | 变更前后摘要 | +| `change_json` | json | NULL | 已脱敏差异 | +| `reason` | varchar(500) | NULL | 操作原因 | +| `approval_no` | varchar(32) | NULL, INDEX | 审批单号 | +| `trace_id` | varchar(64) | NOT NULL, INDEX | 链路 ID | +| `prev_hash` / `row_hash` | char(64) | NULL/NOT NULL | 防篡改哈希链 | +| `created_at` | datetime(3) | NOT NULL, INDEX | 时间 | + +不在 `change_json` 中存储密码、令牌、完整手机、卡号、证件号和渠道密钥。 + +#### 6.9.5 `hg_idempotency_record` 幂等记录 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `scope` | varchar(64) | NOT NULL | 业务作用域 | +| `idempotency_key` | varchar(128) | NOT NULL | 客户端/系统幂等键 | +| `request_digest` | char(64) | NOT NULL | 请求摘要 | +| `resource_type` / `resource_id` | varchar(64)/bigint unsigned | NULL | 产生的资源 | +| `process_status` | tinyint | NOT NULL | 1处理中 2成功 3失败 | +| `response_code` | int | NULL | 结果码 | +| `response_digest` | char(64) | NULL | 响应摘要 | +| `expire_at` | datetime(3) | NOT NULL, INDEX | 保留到期时间 | +| `created_at` / `updated_at` | datetime(3) | NOT NULL | 时间 | + +唯一约束:`UNIQUE (tenant_id,scope,idempotency_key)`。 + +#### 6.9.6 `hg_outbox_event` 事件出站箱 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `event_no` | varchar(32) | UNIQUE | 事件号 | +| `aggregate_type` / `aggregate_id` | varchar(64)/bigint unsigned | NOT NULL, INDEX | 聚合根 | +| `event_type` | varchar(128) | NOT NULL, INDEX | `wallet.credited` 等 | +| `payload_json` | json | NOT NULL | 已脱敏事件数据 | +| `publish_status` | tinyint | NOT NULL DEFAULT 1, INDEX | 1待发送 2已发送 3失败 4死信 | +| `retry_count` | int unsigned | NOT NULL DEFAULT 0 | 重试次数 | +| `next_retry_at` | datetime(3) | NULL, INDEX | 下次重试 | +| `last_error` | varchar(1000) | NULL | 最后错误 | +| `created_at` / `published_at` | datetime(3) | NOT NULL/NULL | 时间 | + +#### 6.9.7 `hg_dashboard_daily_stat` 看板日汇总 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `stat_date` | date | NOT NULL | 统计日期 | +| `dimension_type` / `dimension_value` | varchar(32)/varchar(64) | NOT NULL | 全局/渠道/等级等 | +| `metric_code` | varchar(64) | NOT NULL | 指标编码 | +| `metric_count` | bigint | NOT NULL DEFAULT 0 | 数量 | +| `metric_amount` | bigint | NOT NULL DEFAULT 0 | 金额,分 | +| `calculated_at` | datetime(3) | NOT NULL | 计算时间 | + +唯一约束:`UNIQUE (tenant_id,stat_date,dimension_type,dimension_value,metric_code)`。看板可展示汇总值,但财务对账必须以业务单和台账为准。 + +### 6.10 通知表 + +#### `hg_app_notification` C 端通知 + +| 字段 | 类型 | 约束/索引 | 说明 | +| --- | --- | --- | --- | +| `notification_no` | varchar(32) | UNIQUE | 通知号 | +| `member_id` | bigint unsigned | NOT NULL, INDEX | 接收会员 | +| `notification_type` | varchar(32) | NOT NULL, INDEX | system/order/finance/task/security | +| `title` | varchar(200) | NOT NULL | 标题 | +| `content` | varchar(2000) | NOT NULL | 纯文本内容 | +| `biz_type` / `biz_id` | varchar(32)/bigint unsigned | NULL, INDEX | 关联业务 | +| `read_at` | datetime(3) | NULL | 已读时间 | +| `expire_at` | datetime(3) | NULL | 过期时间 | +| `created_at` | datetime(3) | NOT NULL, INDEX | 创建时间 | + +需求中的“弹幕/模拟会员”不作为真实会员行为实现。如确需运营轮播消息,使用显式标注为“平台消息”的通知类型,不关联伪造会员 ID,不进入真实统计。 + +### 6.11 核心索引和分区策略 + +| 场景 | 策略 | +| --- | --- | +| 会员查询 | 手机精确查询走 `mobile_hash`;用户名走唯一索引;列表按 `(tenant_id,created_at,id)` 游标分页 | +| 订单查询 | 业务单号唯一索引;高频列表索引必须以 `tenant_id` 开头,紧跟状态/会员和时间 | +| 台账 | `(account_id,occurred_at,id)` 和 `(biz_type,biz_no)`;按月度作冷热分层,不盲目对在线主表分区 | +| 审计 | `(target_type,target_id,created_at)`、`(actor_id,created_at)`、`trace_id`;超过在线保留期后归档到独立存储 | +| Outbox | `(publish_status,next_retry_at,id)` 供消费者抢占;已发送数据定期归档 | +| 看板 | 当日数据可实时聚合,历史数据读日汇总表 | + +## 7. 字典与状态设计 + +本系统不建设新的字典体系,完整复用 HotGo 已有的三类字典能力。三类字典通过同一组接口和前端 Store 向页面提供选项。 + +### 7.1 HotGo 现有字典机制 + +| 类型 | 现有实现 | 适用场景 | 是否可在后台修改 | +| --- | --- | --- | --- | +| 数据库字典 | `hg_sys_dict_type` + `hg_sys_dict_data` | 驳回原因、内容分类等运营可维护选项 | 是 | +| 枚举字典 | `internal/consts` + `dict.RegisterEnums()` | 状态机、资金方向、账户类型等稳定业务枚举 | 否,随代码版本发布 | +| 方法字典 | `dict.RegisterFunc()` | 会员等级、商品分类、任务大厅、支付渠道等数据库动态选项 | 数据由对应业务模块维护 | + +后端选项查询继续使用现有 `/dictData/option/{type}` 和 `/dictData/options`。`SysDictData.Select()` 已按“内置枚举/方法字典优先,数据库字典兜底”加载,新业务不重复实现查询逻辑。 + +### 7.2 直接复用的现有字典 + +| 现有字典 key | 复用场景 | 处理 | +| --- | --- | --- | +| `sys_normal_disable` | 所有可维护业务表的 `status` | 直接使用 1正常、2停用,不再定义启停枚举 | +| `sys_switch` | 自动派单、是否推荐、默认开关 | 直接使用 1开启、2关闭 | +| `sys_user_sex` | 会员或管理员性别 | 如业务确需则直接使用 | +| `payType` | 支付方式选项 | 优先复用现有微信/支付宝/QQ 值;为原 `PayTypeOptions` 补充 `balance`、`bank_transfer`、`manual` 等本项目确需值,不另建同义字典 | +| `payStatus` | 简单支付结果展示 | 仅在“待支付/已支付”语义完全一致时复用 | +| `creditType` / `creditGroup` | 旧资金日志兼容、余额/积分分类 | 数据迁移时复用映射;新钱包台账扩展原枚举而不建第二套同义字典 | + +`orderStatus` 是 HotGo 原商品订单状态(待付款、已发货、退款等),与本项目的任务匹配订单状态语义不同,不强行复用其数值。保留原字典供框架旧模块使用,新增独立的 `tradeOrderStatus` 枚举字典,避免同一值在两种业务中含义不同。 + +### 7.3 新增枚举字典(依然使用 HotGo 注册机制) + +以下仅新增 `internal/consts` 常量和 `dict.RegisterEnums()` 注册,不新增字典表或接口: + +| 字典 key | Go 选项变量 | 核心值 | +| --- | --- | --- | +| `appMemberStatus` | `AppMemberStatusOptions` | 1正常 2受限 3禁用 4注销 | +| `appMemberRiskStatus` | `AppMemberRiskStatusOptions` | 1正常 2观察 3限制 4冻结 | +| `bizPublishStatus` | `BizPublishStatusOptions` | 1草稿 2待审 3已发布 4已下线 5已归档 | +| `tradeOrderStatus` | `TradeOrderStatusOptions` | 1匹配中 2待处理 3处理中 4完成 5超时 6冻结 7取消 8失败 | +| `rechargeStatus` | `RechargeStatusOptions` | 1待支付 2待审 3成功 4驳回 5过期 6取消 | +| `withdrawalStatus` | `WithdrawalStatusOptions` | 1待审 2复核中 3处理中 4成功 5失败 6驳回 7取消 | +| `taskSubmissionStatus` | `TaskSubmissionStatusOptions` | 1待审 2通过 3驳回 4已结算 5已冲正 | +| `approvalStatus` | `ApprovalStatusOptions` | 1草稿 2待审 3审批中 4通过 5驳回 6取消 7已执行 8执行失败 | +| `ledgerBizType` | `LedgerBizTypeOptions` | recharge/withdraw/freeze/unfreeze/commission/reward/adjust/reversal | +| `paymentAccountType` | `PaymentAccountTypeOptions` | 1银行卡 2数字钱包 3云闪付 4支付宝 5微信 | + +资金、审批和状态机值必须是代码枚举,因为 Logic 会依赖其稳定语义。它们在 HotGo 字典管理页面中仍会以“内置字典 → 枚举字典”展示,但不允许运营人员修改值。 + +### 7.4 复用数据库字典的运营选项 + +以下选项在现有“系统设置 → 字典管理”中新增类型和数据,不新建业务字典表: + +| 数据库字典 key | 用途 | 修改影响 | +| --- | --- | --- | +| `member_disable_reason` | 会员禁用/限制标准原因 | 只影响后续新申请,历史记录保留 label 快照 | +| `recharge_reject_reason` | 充值驳回原因 | 同上 | +| `withdrawal_reject_reason` | 提现驳回原因 | 同上 | +| `task_reject_reason` | 任务审核驳回原因 | 同上 | +| `wallet_adjust_reason` | 账变/奖励金原因 | 同上,且操作仍需审批 | +| `content_type` | 公告、简介、FAQ、规则、活动等内容分类 | 新类型可由运营增加,但 C 端特殊展示类型需代码支持 | + +这些字典的 `value_type`、`list_class`、`sort`、`status` 继续由 `hg_sys_dict_data` 承载。删除前必须检查是否已被业务使用;已使用选项应停用而不是删除。 + +### 7.5 方法字典 + +下列选择器来自业务表,使用 `dict.RegisterFunc()` 注册,不将业务数据复制到 `hg_sys_dict_data`: + +| 方法字典 key | 数据源 | 缓存策略 | +| --- | --- | --- | +| `memberLevelOption` | `hg_app_member_level` | 可缓存,等级更新后 `dict.ClearFuncCache()` | +| `productCategoryOption` | `hg_product_category` | 可缓存,分类更新后清理 | +| `taskHallOption` | `hg_task_hall` | 可缓存,大厅更新后清理 | +| `paymentChannelOption` | `hg_payment_channel` | 可缓存,渠道更新后清理 | + +### 7.6 后端与前端用法 + +后端在 `Filter(ctx)` 或 Logic 中使用现有方法校验字典值: + +```go +if !dict.HasOptionKey(consts.WithdrawalStatusOptions, in.WithdrawalStatus) { + return gerror.New("提现状态不合法") +} +``` + +前端在每个模块 `model.ts` 中继续使用现有 Pinia 字典 Store: + +```ts +const dict = useDictStore(); + +export function loadOptions() { + dict.loadOptions([ + 'sys_normal_disable', + 'sys_switch', + 'withdrawalStatus', + 'withdrawal_reject_reason', + 'paymentChannelOption', + ]); +} + +// 表格显示 +dict.getLabel('withdrawalStatus', row.withdrawalStatus); + +// 下拉选项 +computed(() => dict.getOptionUnRef('withdrawal_reject_reason')); +``` + +不在 Vue 模板、`model.ts` 或 API 文件中重复定义 label/value 数组。 + +### 7.7 字典与业务配置的边界 + +- **字典**:为字段提供有限选项、标签、颜色和排序,复用 HotGo 字典系统。 +- **业务配置**:交易时段、最低余额、佣金比例、额度和功能开关等会直接影响 C 端和资金,使用 `hg_site_config_version` 的审批、发布和回滚机制,不塞入字典表。 +- **业务主数据**:会员等级、商品分类、支付渠道等有独立属性和关系,使用业务表,只通过方法字典提供下拉选项。 + +## 8. 接口设计约定 + +### 8.1 路由与方法 + +- 后台路由使用 HotGo 现有 `/admin` 前缀,不再叠加 `/admin-api/v1`。 +- 列表与详情使用 GET;新增、编辑、状态变更和审批使用 POST。 +- 标准 CRUD 按 `/module/list`、`/view`、`/edit`、`/delete`、`/status`、`/export` 组织。 +- 高风险动作不复用通用 `edit`,使用显式语义接口,如 `/withdrawal/review`、`/walletAdjustment/submit`、`/approval/approve`。 + +### 8.2 写请求通用要求 + +- 资金、审核、发布类接口必须携带 `idempotencyKey`。 +- 更新可并发编辑的数据必须携带 `version`,冲突返回明确错误。 +- 审核、驳回、禁用、删除、导出和敏感查看必须携带原因。 +- 资金与权限写接口返回审计号或审批单号。 +- Controller 仅做参数透传和结果组装;所有业务校验在 `sysin.Filter()` 或 Logic 中完成。 + +### 8.3 错误码分类 + +| 分类 | 示例 | 前端处理 | +| --- | --- | --- | +| 参数错误 | 时间区间反向、金额超限 | 定位到字段 | +| 状态冲突 | 订单已处理、版本过期 | 刷新当前数据 | +| 权限拒绝 | 无敏感值查看权限 | 不展示目标数据 | +| 审批约束 | 申请人尝试审批自己 | 提示职责分离 | +| 余额不足 | 可用余额小于提现金额 | 显示当前可用余额 | +| 外部服务错误 | 支付通道超时 | 显示可重试状态与 `traceId` | + +## 9. 缓存、队列与定时任务 + +### 9.1 缓存 + +| Key | TTL | 用途 | +| --- | --- | --- | +| `site:config:{tenant}:{group}` | 5 分钟 | 当前已发布站点配置 | +| `content:published:{tenant}:{key}` | 10 分钟 | 已发布内容 | +| `member:level:{tenant}:{id}` | 10 分钟 | 当前等级规则 | +| `dashboard:summary:{tenant}:{date}` | 1 分钟 | 看板汇总 | +| `sensitive:grant:{token}` | 1–5 分钟 | 一次性敏感查看授权 | +| `lock:finance:{bizNo}` | 小于 30 秒 | 防止跨实例重复处理 | + +统一通过 `cache.Instance()` 使用,不在业务代码中直接调用 Redis。更新成功后主动删除缓存。 + +### 9.2 队列主题 + +| Topic 常量 | 事件 | 消费者 | +| --- | --- | --- | +| `QueueBizNotification` | 订单、充值、提现、任务状态变更 | C 端站内信/短信/推送 | +| `QueueDashboardStat` | 会员、订单、台账事件 | 看板汇总 | +| `QueuePaymentCallback` | 通道回调待处理 | 支付处理器 | +| `QueueReconciliation` | 入账、付款和冲正 | 对账服务 | +| `QueueAuditArchive` | 审计日志归档 | 审计归档服务 | + +### 9.3 定时任务 + +| 任务名 | 频率 | 职责 | +| --- | --- | --- | +| `publishScheduledContent` | 每分钟 | 发布到期内容、Banner 和配置 | +| `expireTradeOrders` | 每分钟 | 处理超时订单 | +| `retryOutboxEvents` | 每 10 秒 | 发送 Outbox 并执行指数退避 | +| `reconcileFinanceDaily` | 每日 | 业务单、台账、钱包和渠道对账 | +| `aggregateDashboardDaily` | 每小时/每日 | 重建看板汇总 | +| `expireSessionsAndGrants` | 每 10 分钟 | 清理会话与临时授权 | + +## 10. 安全设计 + +### 10.1 数据保护 + +- 密文字段使用 AEAD(AES-256-GCM 或等价算法),每条记录使用唯一 nonce。 +- 业务库只保存密文;主密钥位于 KMS/密钥管理系统,不存在代码、数据库和普通配置文件。 +- 密钥定期轮换,密文保存密钥版本,支持惰性重加密。 +- 通用请求日志对密码、令牌、卡号、证件号、收款码 URL 和渠道密钥执行强制红线过滤。 + +### 10.2 Web 安全 + +- 富文本在服务端执行标签、属性和 URL 协议白名单清洗。 +- 设置 CSP、`X-Content-Type-Options`、`Referrer-Policy` 和合理的 iframe `sandbox`。 +- 文件上传校验 MIME、扩展名、文件头、尺寸和大小,异步病毒扫描,不使用用户原始文件名作为存储键。 +- 后台使用 MFA;资金、完整敏感值和权限修改触发再认证。 + +### 10.3 资金安全不变式 + +1. 钱包可用余额和冻结余额不得为负数。 +2. 每笔台账的 `after_balance = before_balance ± amount`。 +3. 同一账户同一幂等键只能有一条台账。 +4. 充值成功必须且只能对应一笔入账台账。 +5. 提现成功必须存在冻结和扣减冻结两类台账。 +6. 资金纠错只能冲正,不得修改或删除历史台账。 +7. 申请人、初审人和复核人按风险级别实施职责分离。 + +## 11. 可观测性与运维 + +### 11.1 指标 + +- API 请求数、成功率、P50/P95/P99 延迟和错误码分布。 +- 待审充值/提现数、审批时长、通道成功率、回调验签失败数。 +- 钱包与台账对账差异数、重复幂等请求数、事务冲突数。 +- Outbox 积压、重试数、死信数和消费延迟。 +- 敏感数据查看次数、拒绝次数、非工作时段查看和大量导出。 + +### 11.2 告警 + +| 级别 | 场景 | +| --- | --- | +| P0 | 钱包与台账不平、重复入账、未经审批的资金变更、密钥泄漏 | +| P1 | 支付通道大面积失败、Outbox 严重积压、异常批量敏感查看 | +| P2 | 单个外部服务降级、定时发布延迟、看板汇总延迟 | + +### 11.3 备份与恢复 + +- MySQL 全量备份 + binlog 时点恢复,目标 RPO ≤ 5 分钟,RTO ≤ 30 分钟。 +- 对象存储开启版本和生命周期,资金凭证在留存期内不得物理删除。 +- 每季度执行恢复演练,演练必须验证业务单、钱包和台账的一致性。 + +## 12. 性能与容量设计 + +| 指标 | 一期目标 | +| --- | --- | +| 会员 | 10 万 | +| 交易订单 | 1,000 万级历史数据 | +| 钱包台账 | 3,000 万级历史数据 | +| 后台并发用户 | 200 | +| 后台列表 | P95 < 1s | +| 普通写操作 | P95 < 1.5s | +| 资金事务 | P95 < 2s,不包外部通道等待 | + +列表默认使用索引覆盖的时间倒序与游标分页。需跳页的后台页面可保留普通分页,但必须限制最大页深;大量数据导出使用异步任务,不在 HTTP 请求中生成。 + +## 13. 开发与数据库迁移顺序 + +1. **基础治理**:字典常量、审批、审计、幂等、Outbox、敏感字段加密工具。 +2. **会员域**:会员等级、会员、隐私资料、收款账户、状态记录和会话。 +3. **内容配置域**:站点配置版本、内容版本、Banner、客服渠道。 +4. **商品任务域**:分类、商品、任务大厅、任务、交易订单和任务提交。 +5. **资金域沙箱**:钱包、台账、充值、提现、账变、财务审核和回调。 +6. **外部通道**:支付、实名、短信和客服等外部服务。 +7. **历史迁移**:脱敏盘点、数据清洗、密文转换、台账校验和切换。 + +每批建表 SQL 合入前,使用 GoFrame CLI 重新生成 `entity`、`do`、`dao/internal` 和 `dao`;禁止手动修改生成文件。 + +## 14. 测试策略 + +### 14.1 单元测试 + +- 金额计算、手续费计算、佣金计算和边界值。 +- 所有状态机的允许与禁止转换。 +- 脱敏、加密、哈希检索和密钥版本轮换。 +- 站点配置跨字段校验,特别是时间反向和比例超限。 +- 审批人与申请人分离、审批数量与权限校验。 + +### 14.2 集成测试 + +- 重复充值回调只入账一次。 +- 并发提现不得使钱包余额为负。 +- 提现驳回、撤销和付款失败的冻结与解冻一致。 +- 任务重复审核不得重复发放佣金。 +- 已发布配置回滚后,C 端和后台读取同一版本。 +- 敏感查看令牌单次使用、过期失效并产生审计记录。 + +### 14.3 数据不变式测试 + +在 CI 和生产对账中定期执行: + +```text +钱包可用余额 = 对应可用余额台账累计值 +钱包冻结余额 = 对应冻结台账累计值 +充值成功单数 = 充值入账唯一业务单数 +提现成功单数 = 提现最终扣款唯一业务单数 +已结算任务数 = 任务佣金有效台账业务单数 +``` + +## 15. 分阶段交付 + +| 阶段 | 后端 | 前端 | 数据库 | 退出条件 | +| --- | --- | --- | --- | --- | +| S1 基础 | RBAC、审批、审计、幂等、Outbox | 统一列表/弹窗/审批组件 | 治理域表 | 安全评审通过 | +| S2 配置会员 | 配置、内容、会员、脱敏 | 对应页面 | 配置与会员域表 | C 端版本联调通过 | +| S3 商品任务 | 商品、任务、订单、审核 | 对应页面 | 商品任务域表 | 沙箱任务闭环通过 | +| S4 资金沙箱 | 钱包、台账、充值、提现、对账 | 财务页面 | 资金域表 | 并发、幂等、对账测试通过 | +| S5 生产通道 | 外部支付与风控 | 运营看板与降级 | 回调与统计 | 小流量、限额、人工对账通过 | + +## 16. 需进一步确认的设计决策 + +1. 生产是否需要真实资金、支持币种以及法定小数位。 +2. 单租户还是多租户部署;本设计预留 `tenant_id`,单租户使用 0。 +3. 提现初审、复核、放款的金额阈值和岗位矩阵。 +4. 会员实名认证所需字段、外部供应商与数据留存期。 +5. 会员关系树与层级返佣是否保留;若保留,需先完成合规评审和返佣规则详细设计。 +6. 客服使用自建工单还是第三方服务;第三方可接收的会员数据范围。 +7. 原系统历史数据的字段映射、缺失值处理、重复账号合并和台账校验方案。 + +上述决策不阻塞 S1–S3 的基础开发,但在真实充值、提现和历史资金数据迁移前必须完成确认。 diff --git a/docs/admin_reference_prd/后台管理系统需求文档.docx b/docs/admin_reference_prd/后台管理系统需求文档.docx new file mode 100644 index 0000000..c39c47c Binary files /dev/null and b/docs/admin_reference_prd/后台管理系统需求文档.docx differ diff --git a/docs/admin_reference_prd/后台管理系统需求文档.md b/docs/admin_reference_prd/后台管理系统需求文档.md new file mode 100644 index 0000000..3681174 --- /dev/null +++ b/docs/admin_reference_prd/后台管理系统需求文档.md @@ -0,0 +1,508 @@ +# 后台管理系统需求文档 + +参考管理端功能拆解、C 端映射与安全重构方案 + +目标:基于参考管理系统的实际页面、按钮、链接与弹窗,形成可直接用于产品设计、前后端开发、测试和运维的后台需求基线;保留业务闭环,不复制品牌资产和真实用户数据。 + +主要读者:产品负责人、交互设计师、前端开发、后端开发、测试、运营、客服、财务、风控、安全与审计。 + +观察日期:2026-10-07 参考环境:Web 管理后台 文档版本:V1.0 + +> **结论:** 后台覆盖门户配置、会员、交易、商品、任务、RBAC 与个人设置七大域。复刻时应优先修复敏感数据裸露、资金操作单人审批、配置无校验、接口错误和审计不足。 + +## 目录 + +- [1 文档范围与走查方法](#1-文档范围与走查方法) +- [2 产品定位与后台角色](#2-产品定位与后台角色) +- [3 C 端与后台功能映射](#3-c-端与后台功能映射) +- [4 首页数据看板](#4-首页数据看板) +- [5 门户、内容与 Banner 管理](#5-门户内容与-banner-管理) +- [6 会员管理](#6-会员管理) +- [7 会员等级与任务大厅](#7-会员等级与任务大厅) +- [8 交易管理](#8-交易管理) +- [9 商品与任务管理](#9-商品与任务管理) +- [10 管理员、角色与权限](#10-管理员角色与权限) +- [11 数据字典与个人设置](#11-数据字典与个人设置) +- [12 状态机与数据模型](#12-状态机与数据模型) +- [13 推荐接口清单](#13-推荐接口清单) +- [14 安全、隐私与审计](#14-安全隐私与审计) +- [15 非功能需求](#15-非功能需求) +- [16 端到端验收场景](#16-端到端验收场景) +- [17 研发里程碑](#17-研发里程碑) +- [18 原型图说明](#18-原型图说明) +- [19 待确认事项](#19-待确认事项) + +--- + +## 1 文档范围与走查方法 + +本需求对后台 21 个可见页面入口进行了逐项走查,并打开新增、编辑、查看、分配、审核等代表性弹窗。为了保护现网数据,没有执行最终确定、上传、删除、禁用、设为假人、审核通过或驳回、资金调整、奖励金发放、权限保存和改密。 + +### 1.1 已覆盖入口 + +| 一级模块 | 页面 | 主要控件 | +| --- | --- | --- | +| 主页 | 首页、网站设置、文本管理、Banner 设置、手工商城 | 指标卡、保存、上传、编辑、删除、发布 | +| 会员管理 | 会员列表、会员等级、任务大厅 | 搜索、新增、编辑、团队、账变、奖励金、等级配置 | +| 交易管理 | 订单、充值、提现、客服 | 筛选、自动刷新、匹配、凭证、审核、客服嵌入 | +| 商城管理 | 商品列表 | 搜索、新增、编辑、推荐、删除、富文本 | +| 任务管理 | 任务列表、会员任务审核 | 任务新增、编辑、通过、驳回 | +| 管理员 | 后台管理员、角色、权限、数据字典 | 账号、角色、权限树、配置项 | +| 设置 | 基本资料、修改密码 | 资料修改、密码修改 | + +### 1.2 操作边界 + +- 只验证页面、按钮和弹窗是否可达,未提交会改变会员、资金、权限或配置的数据。 +- 删除、禁用、设为假人、审核、账变、奖励金、改密等高风险入口仅记录需求,不执行最终动作。 +- 原型图基于实测界面脱敏重绘,手机号、姓名、IP、银行卡、订单号均为掩码或虚构值。 +- 接口名称以推荐实现命名;现网真实接口需在开发前通过代码或服务端文档二次核验。 + +### 1.3 证据等级 + +| 等级 | 定义 | 使用方式 | +| --- | --- | --- | +| A 实测 | 页面、按钮、表格或弹窗在走查中直接可见 | 可作为复刻基线 | +| B 推导 | 由相邻页面、C 端闭环或字段关系推导 | 开发前需确认 | +| C 建议 | 为安全、合规、可用性提出的重构要求 | 作为新系统强制规范 | + +## 2 产品定位与后台角色 + +该后台用于运营一个移动端会员任务与账户平台。C 端会员进行注册、余额储入、领取订单、任务提交、佣金结算、提现和客服咨询;后台完成内容配置、会员治理、商品与任务配置、交易审核、财务对账和权限审计。 + +| 角色 | 职责 | 允许范围 | 禁止范围 | +| --- | --- | --- | --- | +| 超级管理员 | 系统与权限治理 | 账号、角色、权限、系统参数 | 不得绕过双人复核直接放款 | +| 运营 | 内容、Banner、商品、任务、等级 | 草稿、预览、发布申请 | 不得查看完整银行卡或改余额 | +| 客服 | 会员与订单查询、工单 | 脱敏资料、只读订单、备注 | 不得资金审核或导出全量用户 | +| 财务 | 充值、提现、对账 | 凭证、审核、支付状态 | 不得修改会员身份与权限 | +| 风控 | 异常行为与冻结复核 | 设备、IP 风险、冻结申请 | 不得单人完成冻结与解冻 | +| 审计 | 只读复核与导出 | 日志、审批链、差异报表 | 不得修改业务数据 | + +### 2.1 信息架构 + +采用“一级业务域 + 二级页面 + 多标签工作区”的桌面后台结构。一级菜单固定在左侧,二级页面以标签页打开;标签支持关闭、刷新和回到首页。任何页面刷新后,应保持当前路由但不保留未提交敏感表单。 + +### 2.2 全局交互规范 + +- 列表页统一:查询区、主操作区、表格、固定操作列、分页;查询条件可重置并写入 URL。 +- 弹窗统一:标题、关闭、表单、确定、取消;确定前做前后端双重校验,提交后禁止重复点击。 +- 危险操作使用红色按钮并要求对象、影响、理由和二次确认;资金与权限操作额外要求复核人。 +- 敏感值默认脱敏;查看完整值需单独权限、再次确认、限定时长,并记录操作者、目标、时间和用途。 +- 加载超过 2 秒展示骨架与取消,接口失败展示错误码、重试和上报入口,不长期停留空白页。 +- 操作成功后提供结果提示与审计编号;失败不得只显示“error”。 + +## 3 C 端与后台功能映射 + +后台不是独立工具,其配置和操作必须能解释 C 端每个入口、状态和金额。以下矩阵为联调的单一事实源。 + +| C 端能力 | 后台来源 | 后台操作 | 一致性要求 | +| --- | --- | --- | --- | +| 首页横幅与快捷入口 | Banner、网站设置 | 排序、有效期、跳转、开关 | 发布后按版本生效 | +| 平台简介/规则/公告 | 文本管理 | 富文本编辑、预览、发布 | CSP 与 HTML 白名单 | +| 手工商城 | 手工商城 | 商品增删改、图片、价格、时间 | C 端仅显示已上架 | +| 会员等级 | 会员等级 | 门槛、赠送、次数、佣金、提现次数 | 计算与展示同源 | +| 领取中心 | 网站设置、商品、订单 | 营业时间、最低余额、匹配规则 | 服务端状态机判定 | +| 订单记录 | 订单列表 | 查询、冻结、匹配、异常处理 | 业务单号和台账可追溯 | +| 储入 | 充值管理 | 凭证、审核、入账、驳回 | 幂等入账与自动对账 | +| 取出 | 提现管理、银行卡信息 | 收款资料、审核、通道、结果 | 金额、手续费、到账同源 | +| 任务大厅与任务 | 任务大厅、任务列表、会员任务审核 | 配置、分发、审核 | 等级、佣金、状态一致 | +| 个人资料 | 会员列表 | 资料、团队、状态、风控 | 敏感字段默认脱敏 | +| 通知与弹幕 | 文本、会员弹幕 | 发布、定向、撤回、查看记录 | 真实性标识和审计 | +| 客服 | 客服管理 | 客服入口、工作时间、会话映射 | 失败有备用通道 | + +![C 端与后台业务闭环原型](assets/prototype_06_flow.png) + +图 1 C 端与后台业务闭环(脱敏重绘原型) + +## 4 首页数据看板 + +首页展示用户、商品、订单、充值、提现、佣金、利息宝转入、下级返佣与账户余额等汇总卡,并展示微信、支付宝和银行卡渠道统计。新系统应把口径、时间区间、刷新时间和数据延迟显式化。 + +| 指标 | 定义 | 筛选维度 | 权限 | +| --- | --- | --- | --- | +| 用户总量/新增 | 去重有效会员数 | 今日、昨日、自定义日期 | 运营只读 | +| 充值用户 | 至少一笔成功充值的会员数 | 时间、渠道、等级 | 财务/运营 | +| 订单量与金额 | 按订单状态和完成时间统计 | 状态、商品、等级 | 运营/财务 | +| 充值/提现 | 成功与待处理金额分开 | 渠道、状态、时间 | 财务 | +| 佣金/返佣 | 任务佣金与层级返佣分开 | 类型、等级、时间 | 财务/审计 | +| 账户余额 | 钱包可用与冻结余额总和 | 币种、账户状态 | 财务/审计 | + +- 卡片可点击进入对应明细页,并继承时间筛选;无权限用户只能看到隐藏金额或不可点击状态。 +- 页面顶部展示“数据截至时间”和刷新按钮;自动刷新不得造成重复请求风暴。 + +![后台首页看板脱敏原型](assets/prototype_01_dashboard.png) + +图 2 后台首页看板(按实测界面脱敏重绘) + +## 5 门户、内容与 Banner 管理 + +### 5.1 网站设置 + +| 配置组 | 字段 | 要求 | +| --- | --- | --- | +| 品牌 | Logo、站点名称、隐私政策 URL | Logo 可预览;URL 仅允许 HTTPS 白名单 | +| 交易 | 交易余额、等待时间、每日次数、奖励次数 | 数值范围校验;修改按版本发布 | +| 佣金 | 0–5 级普通佣金 | Decimal;总和上限;法务开关 | +| 时间 | 提现、充值、交易、签到时间 | 支持多区间;禁止结束早于开始 | +| 门槛 | 最低充值、自动派单时间与金额 | 最小值≤最大值;币种与单位清晰 | +| 开关 | 免费领取、手工商城、首页任务、签到、商品模式、验证码 | 每项写明 C 端影响和降级文案 | + +实测问题:交易等待时间输入框提示语与字段无关;签到时段出现“18:00–17:00”反向区间。新系统保存前必须做语义校验,并支持草稿、预览、发布、回滚。 + +### 5.2 文本管理 + +内容类型包括平台公告、平台简介、订单规则、代理合作、FAQ、指南、利息宝规则、首页滚动、订单提示、活动、首页弹窗和公司资质。编辑器需支持标题、正文、图片、链接、预览、定时发布、版本和回滚。 + +- 富文本使用标签/属性白名单;禁止 script、事件属性、javascript: URL 和未知 iframe。 +- 现网编辑弹窗标题错误显示“编辑商品”,新系统标题必须与内容类型一致。 + +### 5.3 Banner 设置 + +支持多张首页 Banner 的上传、删除、排序、上下线、有效期、跳转类型与替代文本。上传前预览并校验尺寸、比例、MIME、文件大小和恶意内容。删除需要二次确认,已发布素材优先下线而非物理删除。 + +### 5.4 手工商城 + +列表字段为图片、名称、价格、时间与操作;新增/编辑字段为产品名称、价格、图片与展示时间。现网新增弹窗曾长时间停留 loading,需增加 8 秒超时、重试和错误上报。 + +## 6 会员管理 + +### 6.1 会员列表 + +查询条件:用户名、手机号、注册时间、状态、自动派单。列表字段:ID、账号、绑卡姓名、用户名、账户余额、冻结金额、上级用户、邀请码、注册时间、最后登录 IP、IP 属地、自动抢单、状态、当日交易次数。 + +| 操作 | 页面或弹窗 | 关键校验 | 审计要求 | +| --- | --- | --- | --- | +| 添加/编辑 | 会员表单 | 手机号唯一;余额不可由普通编辑修改;密码强度 | 记录前后值,密码永不回显 | +| 银行卡信息 | 开户人、银行、电话、卡号、数字钱包、云闪付、收款码 | 必要性与格式;图片扫描 | 完整值查看留痕 | +| 地址信息 | 姓名、电话、地区、详细地址 | 最小化收集;字段脱敏 | 查看和修改留痕 | +| 查看团队 | 当前用户、层级、人数、余额、佣金、充值、提现 | 仅展示授权层级 | 导出单独授权 | +| 账变 | 余额调整或流水 | 金额、类型、理由、业务单号 | 双人复核;不可直接改余额 | +| 弹幕 | 会员定向或模拟内容 | 标注来源、有效期、撤回 | 禁止伪造真实用户行为 | +| 奖励金 | 奖励金额与原因 | 非负、额度、幂等 | 财务复核与凭证 | +| 设为假人 | 账号标记 | 不得混入真实统计或 C 端荣誉榜 | 仅测试环境默认启用 | +| 禁用 | 账号状态 | 理由、范围、时长、申诉 | 双人复核;通知用户 | +| 删除 | 软删除/注销 | 检查资金与订单;不可物理删台账 | 高风险二次确认 | + +> **P0 风险:** 现网页面默认显示完整手机号、姓名与登录 IP。新系统必须默认脱敏,按角色和目的临时授权查看;列表、导出、日志、埋点和截图统一执行同一脱敏规则。 + +![会员列表脱敏原型](assets/prototype_02_member_list.png) + +图 3 会员列表脱敏原型 + +![会员编辑弹窗原型](assets/prototype_03_member_modal.png) + +图 4 添加会员弹窗原型 + +## 7 会员等级与任务大厅 + +### 7.1 会员等级 + +列表字段为等级名称、升级价格、赠送金额、接单次数、佣金比例和提现次数;支持编辑与受控删除。等级配置直接影响 C 端充值、领取和提现,必须使用版本化发布,不得修改后立即影响进行中的订单。 + +| 规则 | 校验 | 生效策略 | +| --- | --- | --- | +| 升级价格/赠送金额 | ≥0;货币精度;赠送比例上限 | 新会员或下个结算周期 | +| 接单次数 | 整数;按日重置时区明确 | 发布后次日生效 | +| 佣金比例 | 0–1 Decimal;展示百分比 | 锁定到任务订单快照 | +| 提现次数 | 整数;与提现时间窗一致 | 发布后次日生效 | +| 删除等级 | 无有效会员与在途订单方可删除 | 优先停用并保留历史 | + +### 7.2 任务大厅 + +页面字段为名称、图标、比例、简介、创建时间;新增弹窗还包含会员等级。实测列表接口直接显示“数据接口请求异常:error”,但新增弹窗可打开。新系统需要标准错误码、可重试状态、traceId 与空数据区分。 + +- 任务大厅条目必须绑定可用会员等级、比例单位、图标和 C 端跳转。 +- 停用条目不影响已领取任务;删除仅允许无历史引用的数据,建议统一软删除。 + +## 8 交易管理 + +### 8.1 订单列表 + +查询条件:订单号、手机号、用户名、日期;支持开启/关闭自动刷新。列表含绑卡姓名、用户名、自动派单、余额、手机号、当日交易次数、商品、数量、金额、佣金、下单时间、解冻时间、消息、订单状态、冻结状态和操作。 + +| 状态 | 后台操作 | 约束 | +| --- | --- | --- | +| 匹配中 | 查看进度、取消匹配 | 同一会员仅一笔匹配;需幂等 | +| 待处理 | 查看详情、发送提醒 | 不可手动完成;服务端倒计时 | +| 冻结 | 查看风险、发起解冻复核 | 冻结理由、时长、申诉路径 | +| 已完成 | 查看台账 | 金额、佣金、解冻三方一致 | +| 异常/失败 | 重新匹配、人工处理申请 | 人工改状态必须双人审批 | + +### 8.2 充值管理 + +顶部展示全部、用户已支付、用户未支付、手动审核、手动驳回等汇总金额。列表字段:订单号、真实姓名、手机号、余额、交易金额、打款凭证、添加时间、支付方式、类型、处理时间、备注和操作。 + +- 审核通过前校验凭证、订单金额、收款主体、重复订单和账户状态;入账使用幂等键。 +- 驳回必须选择标准原因并可补充说明;通知 C 端且允许补充材料。 + +### 8.3 提现管理 + +查询条件:订单号、用户名、日期。列表含用户余额、提现金额、手续费、实际到账、银行名称、开户名称、银行卡号、云闪付、数字钱包、支付宝/微信收款码、发起与处理时间、操作。 + +> **P0 风险:** 现网直接显示完整银行卡号与多个钱包账号。新系统列表只显示掩码,完整值不进入普通 DOM;付款处理时通过一次性授权查看,超时自动隐藏。 + +![提现审核脱敏原型](assets/prototype_04_withdrawal.png) + +图 5 提现审核脱敏原型 + +### 8.4 客服管理 + +实测页面在加载后保持空白。新系统至少提供客服账号、名称、工作时间、在线状态、跳转 URL、排序、启停和会话映射;第三方 iframe 失败时显示备用联系方式和错误编号。 + +## 9 商品与任务管理 + +### 9.1 商品列表 + +查询条件:商品名称、支付类型。列表:ID、图片、名称、商品价格、店铺名称、创建时间、是否推荐、操作。新增/编辑字段:商品名称、分类、店铺名称、商品单价、展示图片、商品详情富文本。 + +- 推荐/不推荐为明确状态切换,提交前展示影响范围;列表筛选和 C 端排序一致。 +- 价格采用 Decimal;图片与富文本执行内容安全校验;商品被订单引用后只允许停用。 + +### 9.2 任务列表 + +按会员类型筛选;字段为任务编号、封面、标题、描述、等级、佣金、创建时间。新增弹窗含标题、描述、封面、等级、佣金和详情。实测新增任务弹窗标题误用“添加大厅任务”,需修正。 + +### 9.3 会员任务审核 + +按手机号、用户名查询;列表含记录 ID、用户名、手机、任务标题、等级、佣金、成功率、状态、备注、创建时间和操作。待审核记录支持通过与驳回。 + +| 动作 | 前置条件 | 提交内容 | 结果 | +| --- | --- | --- | --- | +| 通过 | 任务存在、会员有效、未重复审核 | 审核意见、证据摘要、幂等键 | 发放佣金或进入结算队列 | +| 驳回 | 记录为待审核 | 标准原因、补充说明、是否允许重提 | 通知会员并保留证据 | +| 撤回审核 | 仅异常且未结算 | 变更单与复核人 | 冲正而非修改历史记录 | + +## 10 管理员、角色与权限 + +### 10.1 后台管理员 + +查询条件为登录名、手机、邮箱、角色;列表含姓名、登录名、手机号、邮箱、角色、更新时间和创建时间。新增字段为姓名、用户名、密码、手机、邮箱和多选角色。 + +- 密码强度至少 12 位,禁止默认密码,首次登录强制改密;密码永不回显。 +- 禁用优先于删除;删除账号时保留历史审计主体,不得影响日志可追溯性。 + +### 10.2 角色管理 + +角色列表支持新增、编辑、删除和分配权限。分配弹窗为可展开/折叠的权限树。保存权限属于高风险操作,必须展示新增与移除差异,并由另一名管理员复核。 + +### 10.3 权限管理 + +权限树字段为 ID、名称、权限标识、父级 ID 和操作;支持添加顶级权限、添加子级、编辑、删除、展开/折叠。权限标识唯一且不可随意改名;被角色引用时禁止删除。 + +![RBAC 角色权限原型](assets/prototype_05_rbac.png) + +图 6 建议 RBAC 权限矩阵 + +## 11 数据字典与个人设置 + +### 11.1 数据字典 + +列表字段为 ID、名称、值、创建时间;支持新增、编辑、删除。现网同时存在英文 key、中文名称和缺失名称的条目,并与网站设置重复维护。建议将字典拆为“系统常量”和“业务配置”,以结构化 Schema 管理。 + +| 字段 | 要求 | +| --- | --- | +| key | 全局唯一;小写或大写规范统一;发布后不可改名 | +| value | 按 Schema 校验类型、范围、枚举、时间段和单位 | +| description | 必填,说明业务含义、C 端影响和默认值 | +| scope | 环境、租户、渠道、会员等级等作用域 | +| version | 草稿、已发布、已回滚;记录生效时间 | +| secret | 敏感配置不得明文显示,使用密钥管理系统 | + +### 11.2 基本资料 + +字段为用户名(不可修改)、名称、手机、邮箱,提交按钮为“确认修改”。修改手机或邮箱需验证当前身份和新联系方式;成功后记录审计并通知原联系方式。 + +### 11.3 修改密码 + +字段为当前密码、新密码、确认新密码,现网提示 6–16 个字符。新系统建议至少 12 位并支持密码管理器;最终提交必须由用户本人完成,成功后撤销其他会话并发送安全通知。 + +## 12 状态机与数据模型 + +### 12.1 核心状态机 + +| 实体 | 状态 | 允许转换 | +| --- | --- | --- | +| 会员 | 正常、受限、禁用、注销 | 正常→受限/禁用;复核后恢复;注销不可逆 | +| 订单 | 匹配中、待处理、处理中、完成、超时、冻结、取消、失败 | 仅服务端状态机转换 | +| 充值 | 待支付、待审核、成功、驳回、过期、取消 | 成功后只允许冲正 | +| 提现 | 待审核、复核中、处理中、成功、失败、驳回、取消 | 付款前可取消;成功后只允许冲正 | +| 任务审核 | 待审核、通过、驳回、已结算、已冲正 | 结算后不可回到待审核 | +| 内容 | 草稿、待审、已发布、已下线、已归档 | 发布需审批;可回滚版本 | +| 配置 | 草稿、待发布、已发布、已回滚 | 发布后生成不可变版本 | + +### 12.2 核心实体 + +| 实体 | 关键字段 | 约束 | +| --- | --- | --- | +| AdminUser | id, loginName, roles, status, mfa, lastLogin | 管理员身份与会话 | +| Role/Permission | roleId, permissionKey, scope | 最小权限与数据范围 | +| Member | id, mobileEnc, nameEnc, levelId, status | 敏感字段加密、索引分离 | +| Wallet | available, frozen, currency, version | 只允许台账事务修改 | +| LedgerEntry | bizNo, type, amount, before, after, reversalOf | 不可变、幂等、可冲正 | +| Order | orderNo, memberId, productSnapshot, amount, commission, status | 保存规则快照 | +| Deposit/Withdrawal | bizNo, amount, fee, channel, status, reviewer | 审批链与支付回执 | +| Content/Banner | type, body, version, publishAt, operator | 预览与版本化发布 | +| ConfigVersion | key, value, schema, effectiveAt | 语义校验与回滚 | +| AuditLog | actor, action, target, before, after, reason, traceId | 防篡改与长期留存 | + +## 13 推荐接口清单 + +接口为新系统建议设计,统一前缀 /admin-api/v1。响应包含 data、code、message、traceId;所有写接口必须携带 Idempotency-Key,资金与权限写操作同时携带审批单号。 + +| 方法 | 路径 | 用途 | 关键参数 | +| --- | --- | --- | --- | +| GET | /dashboard/summary | 首页指标 | timeRange, dimensions | +| GET/PUT | /site-settings | 读取/保存站点配置草稿 | version, settings | +| POST | /site-settings/publish | 发布配置 | draftVersion, reason | +| GET/POST | /contents | 内容列表/新建 | type, status, body | +| POST | /contents/{id}/publish | 内容发布 | publishAt, approver | +| GET/POST | /banners | Banner 查询/新建 | imageAssetId, sort, target | +| GET/POST | /members | 会员查询/新建 | filters, profile | +| GET/PATCH | /members/{id} | 会员详情/编辑 | editableProfile, version | +| POST | /members/{id}/adjustment-requests | 账变申请 | type, amount, reason, evidence | +| POST | /members/{id}/status-requests | 禁用/解禁申请 | targetStatus, reason, duration | +| GET/POST | /member-levels | 等级查询/草稿 | rules, effectiveAt | +| GET/POST | /products | 商品查询/新建 | category, price, assets, detail | +| GET/POST | /tasks | 任务查询/新建 | levelIds, commission, detail | +| GET | /orders | 订单列表 | orderNo, member, status, timeRange | +| POST | /orders/{id}/exception-requests | 异常处理申请 | action, reason | +| GET | /deposits | 充值列表 | status, channel, timeRange | +| POST | /deposits/{id}/review | 充值审核 | decision, reason, version | +| GET | /withdrawals | 提现列表 | status, member, timeRange | +| POST | /withdrawals/{id}/review | 提现审核 | decision, reason, version | +| GET | /withdrawals/{id}/sensitive-view | 一次性查看收款信息 | purpose, challengeToken | +| GET/POST | /task-submissions | 任务审核列表/决定 | decision, reason | +| GET/POST | /admin-users | 管理员查询/新建 | profile, roleIds | +| GET/POST | /roles | 角色查询/新建 | name, scope | +| POST | /roles/{id}/permission-change-requests | 权限变更申请 | add, remove, reason | +| GET | /audit-logs | 审计查询 | actor, action, target, timeRange | + +## 14 安全、隐私与审计 + +| 风险 | 现网表现 | 新系统要求 | 优先级 | +| --- | --- | --- | --- | +| 个人信息裸露 | 完整手机号、姓名、IP | 默认脱敏;临时授权;全链路审计 | P0 | +| 金融信息裸露 | 完整银行卡与钱包账号 | 应用层加密;非 DOM 展示;一次性查看 | P0 | +| 资金单人操作 | 通过/驳回、账变、奖励入口直接可达 | 职责分离、双人复核、额度和幂等 | P0 | +| 伪造行为 | 设为假人、弹幕入口 | 测试数据隔离;禁止混入真实榜单与统计 | P0 | +| 富文本 XSS | 商品与内容支持富文本 | 白名单、CSP、上传扫描、预览隔离 | P0 | +| 配置误发布 | 时间反向、字段提示错误 | Schema 校验、预览、审批、回滚 | P0 | +| 接口不可用 | 任务大厅 error、客服空白 | 错误码、重试、熔断、监控和降级 | P1 | +| 权限漂移 | 多角色与权限树直接保存 | 差异预览、审批、定期复核 | P0 | + +### 14.1 审计日志 + +- 记录登录、查看敏感信息、导出、查询大范围数据、资金审核、账变、奖励、冻结、配置发布、权限变更和改密。 +- 字段至少包含操作者、角色、MFA、目标、动作、前值、后值、理由、审批人、IP、设备、traceId、时间和结果。 +- 日志写入独立存储并防篡改;业务管理员无删除权限;按监管与公司政策设定留存期。 +- 导出文件水印、加密、限时下载;下载与转发均可追踪。 + +### 14.2 登录与会话 + +- 管理员必须启用 MFA;高风险动作触发再次认证。 +- 闲置 15–30 分钟自动锁定;会话撤销、设备列表和异地登录提醒。 +- 连续失败触发限流与告警;不得依赖前端验证码作为唯一防护。 +- 服务端密码使用 Argon2id 或 bcrypt;任何日志、监控和前端状态都不得保存密码。 + +## 15 非功能需求 + +| 类别 | 目标 | 验收指标 | +| --- | --- | --- | +| 性能 | 常用列表与详情快速可用 | 列表 P95<1s;写操作 P95<1.5s;首屏<2.5s | +| 可用性 | 关键交易全年可用 | 资金审核 99.95%;其余 99.9% | +| 容量 | 支持 10 万会员与百万级订单 | 游标分页、索引与冷热分层 | +| 并发 | 自动刷新与多运营并发安全 | 乐观锁、版本号、冲突提示 | +| 可观测 | 定位每次请求与资金变更 | traceId、指标、日志、告警、审计关联 | +| 兼容 | 主流桌面浏览器 | Chrome/Edge 最近两个稳定版;1366×768 可用 | +| 可访问 | 键盘与读屏可操作 | 焦点、标签、颜色对比、44px 点击区 | +| 灾备 | 配置与交易可恢复 | RPO≤5 分钟,RTO≤30 分钟;季度演练 | + +### 15.1 列表与弹窗通用验收 + +- 查询条件、分页、排序、刷新后可恢复;空数据、加载中、失败、无权限均有独立状态。 +- 横向宽表固定关键列和操作列;敏感字段不因横向滚动或 tooltip 意外暴露。 +- 弹窗关闭与取消不产生写操作;表单脏数据关闭前提示;成功后只刷新受影响区域。 +- 重复点击、网络重试和浏览器回退不会重复创建、重复审核或重复入账。 +- 所有时间显示时区,金额显示币种和精度,百分比与小数含义统一。 + +## 16 端到端验收场景 + +| 编号 | 场景与验收路径 | +| --- | --- | +| A01 内容发布 | 运营新建公告→预览→提交审核→审批→定时发布→C 端显示相同版本→回滚 | +| A02 会员查询 | 客服按掩码手机号查询→查看脱敏资料→申请查看完整值→审计留痕→超时隐藏 | +| A03 任务闭环 | 配置任务→C 端领取→生成订单→提交→后台审核→佣金入账→台账核对 | +| A04 充值审核 | C 端提交→后台待审核→重复回调→单次入账→通知→对账一致 | +| A05 提现复核 | C 端申请→风控命中→财务初审→复核→通道付款→状态与到账金额一致 | +| A06 禁用会员 | 客服发起→填写理由和时长→风控复核→会员受限→通知与申诉→解禁 | +| A07 账变 | 运营申请奖励→财务复核→台账入账→重复提交被幂等拦截→审计可追溯 | +| A08 权限变更 | 管理员申请新增提现审核权限→展示差异→复核→即时生效→历史会话重新鉴权 | +| A09 配置错误 | 输入反向时间/非法比例→前后端阻止→错误定位到字段→不生成草稿版本 | +| A10 服务降级 | 任务大厅 API 失败/客服 iframe 失败→清晰错误→重试/备用入口→告警产生 | + +### 16.1 发布门槛 + +- P0 风险全部关闭;资金、权限、隐私与上传通过专项安全测试。 +- C 端和后台使用同一配置版本、状态枚举、金额口径和错误码。 +- 关键写操作完成幂等、并发、回滚、重试、超时与断网测试。 +- 审计日志可以从一次用户投诉还原完整操作者、审批链和资金流水。 +- 备份恢复、支付对账、权限复核和事故响应完成演练。 + +## 17 研发里程碑 + +| 阶段 | 范围 | 退出条件 | +| --- | --- | --- | +| M0 设计基线 | 信息架构、组件、状态机、RBAC、字段字典 | 产品/设计/技术/安全评审通过 | +| M1 基础后台 | 登录、管理员、角色、权限、审计、内容、Banner | MFA、审计、发布流可用 | +| M2 会员与配置 | 会员、等级、团队、配置中心 | 脱敏、临时授权、版本发布完成 | +| M3 商品与任务 | 商品、任务、任务大厅、审核 | C 端联调与佣金快照通过 | +| M4 交易与资金 | 订单、充值、提现、对账、复核 | 支付沙箱、幂等、双人复核通过 | +| M5 运营与稳定性 | 看板、客服、监控、灾备、性能 | SLO、告警、恢复演练通过 | + +### 17.1 建议开发顺序 + +1. 先建设统一认证、RBAC、审计、脱敏和配置发布,再开发具体业务页。 +1. 会员、商品、任务可先使用模拟资金;充值和提现必须最后接真实通道。 +1. 资金域上线前实行沙箱、小流量、额度限制和人工对账。 +1. 上线后第一周每日权限复核、账务核对和错误率复盘。 + +## 18 原型图说明 + +文档中的界面图按实测后台的布局、菜单、表格、弹窗和业务字段脱敏重绘,可直接用于讨论信息层级和交互。它们不是视觉稿:品牌、颜色、图标和真实数据应在 UI 设计阶段重新建立。 + +### 18.1 首页看板(脱敏重绘) + +![后台首页看板脱敏原型](assets/prototype_01_dashboard.png) + +### 18.2 会员列表(脱敏重绘) + +![会员列表脱敏原型](assets/prototype_02_member_list.png) + +### 18.3 会员弹窗(脱敏重绘) + +![会员编辑弹窗原型](assets/prototype_03_member_modal.png) + +### 18.4 提现审核(脱敏重绘) + +![提现审核脱敏原型](assets/prototype_04_withdrawal.png) + +### 18.5 角色权限(脱敏重绘) + +![RBAC 角色权限原型](assets/prototype_05_rbac.png) + +### 18.6 业务闭环(脱敏重绘) + +![C 端与后台业务闭环原型](assets/prototype_06_flow.png) + +## 19 待确认事项 + +- 目标系统是否处理真实资金,适用司法辖区、支付牌照与实名要求是什么。 +- “设为假人、弹幕、奖励金、层级返佣”是否保留;若保留,业务合法性和真实性如何证明。 +- 充值、提现、账变和会员禁用的初审/复核角色与金额阈值。 +- C 端现有接口能否修改,还是需要后台兼容旧字段和状态枚举。 +- 客服使用自建工单还是第三方服务,允许向第三方传输哪些数据。 +- 运营内容是否需要多语言、定时发布、区域差异与灰度发布。 +- 历史用户、订单、银行卡和台账的迁移范围、清洗规则和保留年限。 +- 生产环境数据导出、敏感值查看和紧急权限的审批人。 + +在上述事项确认前,可以完成认证、RBAC、审计、内容、会员脱敏查询、商品任务配置和沙箱交易;不得接入真实收款、放款或自动资金调整。 diff --git a/docs/admin_reference_prd/第12章状态机与数据模型补强设计.md b/docs/admin_reference_prd/第12章状态机与数据模型补强设计.md new file mode 100644 index 0000000..0b0901e --- /dev/null +++ b/docs/admin_reference_prd/第12章状态机与数据模型补强设计.md @@ -0,0 +1,484 @@ +# 第 12 章状态机与数据模型补强设计 + +> 文档版本:V1.0 +> 编制日期:2026-10-08 +> 依据:[后台管理系统需求文档](./后台管理系统需求文档.md)第 12 章 +> 关联设计:[后台管理系统概要设计](./后台管理系统概要设计.md) +> 适用项目:`olons_admin` + +## 1. 文档目标 + +本文档用于补齐需求文档第 12 章中尚未闭环的状态机、资金冲正、内容归档与历史版本回滚能力,作为数据库迁移、后端接口、前端操作、权限配置和测试验收的实施依据。 + +本次设计遵循以下原则: + +1. 复用现有 HotGo 分层、字典、审批、审计、权限和多租户能力。 +2. 不修改已经投入使用的状态编号,只追加新状态或转换规则。 +3. 客户端只提交业务意图,最终状态由服务端状态机决定。 +4. 已生效资金不得修改或删除历史台账,只能生成反向流水冲正。 +5. 历史内容和配置不得原地覆盖,回滚必须生成新的草稿版本。 +6. 所有高风险执行都必须重新检查业务状态、审批状态和当前数据版本。 + +## 2. 实施范围 + +### 2.1 本期范围 + +- 会员状态合法转换和注销不可逆。 +- 充值入账后的审批冲正。 +- 任务佣金结算后的审批冲正。 +- 文本内容归档和历史版本生成回滚草稿。 +- 状态转换、重复执行、并发执行和资金一致性测试。 +- 新增操作对应的菜单权限、业务审计和幂等保护。 + +### 2.2 不在本期范围 + +- 管理员 MFA 的真实认证流程。 +- 支付渠道退款接口和外部清算实现。 +- 新建独立的状态机管理页面。 +- 修改 HotGo 原有管理员、角色、字典和个人设置模块。 +- 直接修改 GoFrame CLI 生成的 `entity`、`do`、`dao/internal` 文件。 + +MFA 数据字段继续保留,但真实验证码、再认证凭证和会话升级机制后续单独设计开发。 + +## 3. 现状评估 + +| 领域 | 已有能力 | 本次缺口 | +| --- | --- | --- | +| 会员 | 正常、禁用、注销;风险状态;双人审批;状态日志 | 未限制全部非法转换,注销后仍可能被旧审批恢复 | +| 钱包 | 可用余额、冻结余额、乐观锁、不可变台账、幂等键、`reversal_of` | 充值和任务佣金尚未提供完整冲正入口 | +| 充值 | 待支付、待审核、成功、驳回、过期、取消;审核入账 | 成功后无冲正状态、审批和执行流程 | +| 任务审核 | 待审核、通过、驳回、已结算、已冲正;佣金台账字段 | 已冲正仅有字典和字段,缺少业务实现 | +| 内容 | 草稿、待审、已发布、已下线、已归档;内容版本 | 缺少归档和历史版本生成回滚草稿接口 | +| 配置 | 草稿、审批、发布、版本、回滚草稿 | 已满足本章要求,本期不重做 | +| 审计 | Trace ID、前后摘要、哈希链、审批单号 | 新增流程需要补充结构化差异和冲正关联信息 | + +## 4. 状态机设计 + +### 4.1 通用规则 + +每个状态变更必须依次执行: + +1. 查询目标记录并加行锁。 +2. 校验记录存在且属于当前租户。 +3. 校验当前状态与申请时的 `fromStatus` 一致。 +4. 校验 `fromStatus → toStatus` 在允许转换表中。 +5. 校验审批已通过、尚未执行,且申请人与执行人符合职责分离要求。 +6. 在同一事务内完成业务状态、台账、审批执行时间和审计记录更新。 +7. 事务提交后再触发缓存清理、通知或 Outbox 事件。 + +状态转换判断统一放在后端,不接受前端直接指定任意结果状态。 + +### 4.2 会员状态 + +现有会员状态编号保持不变: + +| 常量 | 值 | 含义 | +| --- | ---: | --- | +| `AppMemberStatusNormal` | 1 | 正常 | +| `AppMemberStatusDisabled` | 2 | 禁用 | +| `AppMemberStatusCancelled` | 3 | 已注销 | + +允许转换: + +| 当前状态 | 目标状态 | 是否允许 | 说明 | +| --- | --- | --- | --- | +| 正常 | 禁用 | 是 | 必须审批 | +| 正常 | 注销 | 是 | 必须审批,执行后不可恢复 | +| 禁用 | 正常 | 是 | 必须审批 | +| 禁用 | 注销 | 是 | 必须审批 | +| 注销 | 任意状态 | 否 | 注销不可逆 | +| 任意状态 | 相同状态 | 否 | 防止无意义重复申请 | + +需求中的“受限”继续由现有 `risk_status` 表达,不新增或重排会员主状态: + +- `AppMemberRiskNormal`:正常。 +- `AppMemberRiskWatch`:观察或限制部分能力。 +- `AppMemberRiskBlocked`:拦截高风险能力。 + +发起状态审批时保存 `fromStatus`;执行时必须重新比对。如果会员状态已变化,则旧审批失效,不得覆盖最新状态。 + +### 4.3 充值状态 + +保留现有 1~6 状态,追加: + +| 常量 | 值 | 含义 | +| --- | ---: | --- | +| `RechargeReversed` | 7 | 已冲正 | + +核心转换: + +| 当前状态 | 目标状态 | 触发方式 | +| --- | --- | --- | +| 用户未支付 | 手动审核 | 支付凭证或支付结果进入审核 | +| 用户未支付 | 已过期/已取消 | 超时任务或用户取消 | +| 手动审核 | 已入账 | 审批通过并写入入账台账 | +| 手动审核 | 手动驳回 | 审批驳回 | +| 已入账 | 已冲正 | 冲正审批通过并生成反向台账 | + +`已入账 → 已冲正` 是成功充值唯一允许的后续资金状态转换。已冲正记录不得再次冲正。 + +### 4.4 任务审核状态 + +保留现有状态编号: + +| 常量 | 值 | 含义 | +| --- | ---: | --- | +| `TaskSubmissionPending` | 1 | 待审核 | +| `TaskSubmissionApproved` | 2 | 已通过 | +| `TaskSubmissionRejected` | 3 | 已驳回 | +| `TaskSubmissionSettled` | 4 | 已结算 | +| `TaskSubmissionReversed` | 5 | 已冲正 | + +当前佣金为同步结算时,可在同一事务中完成“待审核 → 已通过 → 已结算”,数据库最终状态为“已结算”;若以后改为异步结算,“已通过”可作为中间状态。 + +允许转换: + +| 当前状态 | 目标状态 | 说明 | +| --- | --- | --- | +| 待审核 | 已驳回 | 保存驳回原因和是否允许重提 | +| 待审核 | 已结算 | 审核通过并成功写入佣金台账 | +| 已结算 | 已冲正 | 冲正审批通过并写入反向台账 | +| 已驳回 | 其他状态 | 禁止;重新提交需生成新提交记录 | +| 已冲正 | 其他状态 | 禁止 | + +### 4.5 内容状态 + +使用现有 `BizPublishStatusOptions`: + +```text +草稿 → 待审 → 已发布 → 已下线 → 已归档 +``` + +规则: + +- 只有草稿可以提交审核。 +- 只有审批通过的版本可以发布。 +- 只有已发布内容可以下线。 +- 只有已下线内容可以归档。 +- 已归档内容不可直接编辑、发布或恢复。 +- 历史版本回滚不修改历史版本,而是复制为一个版本号更大的新草稿。 + +站点配置继续使用现有“历史版本 → 新回滚草稿 → 审批 → 发布”流程,不增加直接覆盖线上配置的接口。 + +## 5. 数据库变更 + +新增迁移文件: + +```text +server/storage/data/migrations/20261008_009_state_machine_hardening.sql +``` + +### 5.1 `hg_recharge_order` + +| 字段 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| `reversal_approval_id` | bigint unsigned | 0 | 冲正审批单 ID | +| `reversal_ledger_id` | bigint unsigned | 0 | 冲正台账 ID | +| `reversed_at` | datetime(3) | NULL | 冲正执行时间 | + +建议增加索引: + +```sql +KEY `idx_recharge_reversal_approval` (`tenant_id`,`reversal_approval_id`) +``` + +### 5.2 `hg_task_submission` + +保留已有 `reversal_approval_id`,新增: + +| 字段 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| `reversal_ledger_id` | bigint unsigned | 0 | 佣金冲正台账 ID | +| `reversed_at` | datetime(3) | NULL | 冲正执行时间 | + +建议增加索引: + +```sql +KEY `idx_task_submission_reversal` (`tenant_id`,`reversal_approval_id`) +``` + +### 5.3 `hg_content_version` + +为了保留回滚来源,新增: + +| 字段 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| `base_version_id` | bigint unsigned | 0 | 新版本来源的历史版本 ID | + +正常新增版本可为 0;通过回滚生成的新草稿必须保存来源版本 ID。 + +### 5.4 生成代码 + +迁移执行后,使用 GoFrame CLI 重新生成下列表对应的代码: + +- `hg_recharge_order` +- `hg_task_submission` +- `hg_content_version` + +生成范围包括 `entity`、`do`、`dao/internal` 和 `dao`,禁止手工修改生成文件。 + +## 6. 后端接口设计 + +### 6.1 会员状态 + +复用现有接口: + +- `POST /appMember/statusRequest` +- `POST /appMember/statusExecute` + +补强内容: + +- `StatusRequest` 校验允许转换并写入申请时状态。 +- `StatusExecute` 锁定会员记录后再次校验允许转换。 +- 已注销会员禁止发起和执行任何恢复状态请求。 +- 业务审计必须记录 `before.memberStatus` 和 `after.memberStatus`。 + +### 6.2 充值冲正 + +新增接口: + +| 接口 | Method | 权限 | 说明 | +| --- | --- | --- | --- | +| `/rechargeOrder/reversalRequest` | POST | `/rechargeOrder/reversalRequest` | 发起充值冲正审批 | +| `/rechargeOrder/reversalExecute` | POST | `/rechargeOrder/reversalExecute` | 执行已通过的充值冲正 | + +申请参数至少包括: + +- 充值单 ID。 +- 标准原因编码。 +- 补充说明。 +- 幂等键。 +- 证据附件或证据摘要,按现有 JSON 附件格式保存。 + +申请前置条件: + +- 充值单状态为“已入账”。 +- 存在原入账台账。 +- 尚未发起或执行冲正。 +- 原审批和入账结果有效。 + +执行必须在同一事务中: + +1. 锁定审批单、充值单、钱包账户和原台账。 +2. 校验审批已通过且未执行。 +3. 校验充值单仍为“已入账”。 +4. 校验原台账属于该充值单和该钱包。 +5. 生成金额相同、方向相反的新台账,并设置 `reversal_of=原台账ID`。 +6. 更新钱包余额和乐观锁版本,余额不得为负数。 +7. 更新充值单为“已冲正”,保存冲正审批、台账和时间。 +8. 标记审批已执行并写入业务审计。 + +### 6.3 任务佣金冲正 + +新增接口: + +| 接口 | Method | 权限 | 说明 | +| --- | --- | --- | --- | +| `/taskSubmission/reversalRequest` | POST | `/taskSubmission/reversalRequest` | 发起佣金冲正审批 | +| `/taskSubmission/reversalExecute` | POST | `/taskSubmission/reversalExecute` | 执行已通过的佣金冲正 | + +申请前置条件: + +- 提交记录状态为“已结算”。 +- `ledger_id` 有效。 +- 尚未发起或执行冲正。 +- 必须填写标准原因和补充说明。 + +执行逻辑与充值冲正一致,但业务状态更新为 `TaskSubmissionReversed`,冲正流水指向佣金原流水。 + +### 6.4 内容归档与回滚 + +新增接口: + +| 接口 | Method | 权限 | 说明 | +| --- | --- | --- | --- | +| `/content/archive` | POST | `/content/archive` | 将已下线内容归档 | +| `/content/rollback` | POST | `/content/rollback` | 根据历史版本生成新草稿 | + +归档规则: + +- 当前内容必须为“已下线”。 +- 归档后不可编辑或直接重新发布。 +- 保存操作人、原因和审计记录。 + +回滚规则: + +- 指定内容 ID 和历史版本 ID。 +- 历史版本必须属于该内容。 +- 新版本号为当前最大版本号加 1。 +- 复制历史版本正文、摘要、封面和附件信息。 +- 新版本状态为“草稿”,`base_version_id` 指向来源版本。 +- 不修改当前线上版本和历史版本。 + +## 7. 后端代码影响范围 + +按 HotGo 分层补充以下内容: + +| 层级 | 主要文件 | +| --- | --- | +| 常量与字典 | `server/internal/consts/trade.go`、`product_task.go`、`portal.go` | +| API 契约 | `server/api/admin/rechargeorder/`、`tasksubmission/`、`portal/` | +| Controller | `server/internal/controller/admin/sys/` 对应薄控制器 | +| Service | 在 `server/internal/service/sys.go` 的现有接口中追加方法 | +| Input | `server/internal/model/input/sysin/` 对应模块文件 | +| Logic | `app_member.go`、`recharge_order.go`、`task_submission.go`、`portal.go` | +| 路由 | 复用现有模块控制器注册,无需新增一级菜单 | +| 迁移 | `20261008_009_state_machine_hardening.sql` | + +状态值合法性通过后端字典校验;字段名使用 `dao.Xxx.Columns()`,禁止在 Logic 中硬编码数据库列名。 + +## 8. 前端设计 + +不增加一级菜单,只在现有页面增加操作入口。 + +### 8.1 充值管理 + +- 状态为“已入账”且拥有申请权限时显示“申请冲正”。 +- 已存在冲正审批时显示审批状态,不允许重复申请。 +- 审批通过且拥有执行权限时显示“执行冲正”。 +- 已冲正记录显示原台账和冲正台账关联信息。 + +### 8.2 会员任务审核 + +- 状态为“已结算”时显示“申请冲正”。 +- 申请弹窗包含原因字典、补充说明和证据。 +- 审批通过后由有执行权限的管理员执行。 +- 状态为“已冲正”后不再显示审核或冲正按钮。 + +### 8.3 文本管理 + +- 已下线内容显示“归档”。 +- 历史版本列表显示“生成回滚草稿”。 +- 回滚前明确提示“不会覆盖当前线上版本”。 +- 已归档内容的编辑和发布按钮禁用。 + +前端继续使用 Naive UI、`BasicTable`、`BasicForm`、`BasicModal` 和 `http.request`,状态标签通过后端字典渲染。 + +## 9. 权限设计 + +新增操作权限: + +```text +/rechargeOrder/reversalRequest +/rechargeOrder/reversalExecute +/taskSubmission/reversalRequest +/taskSubmission/reversalExecute +/content/archive +/content/rollback +``` + +权限规则: + +- 申请权限和执行权限分离。 +- 申请人不得审批或执行自己的高风险申请。 +- 执行接口必须独立校验权限,不能只依赖前端按钮隐藏。 +- 新权限通过 `hg_admin_menu` 的按钮类型记录配置,并授权给管理角色和业务角色。 + +## 10. 台账、幂等与审计 + +### 10.1 台账要求 + +- 原台账不可更新和删除。 +- 冲正台账金额必须等于原台账金额。 +- 冲正台账方向必须与原台账相反。 +- `reversal_of` 必须指向原台账 ID。 +- 同一原台账只能存在一条有效冲正台账。 +- 钱包变更后必须满足 `after_amount = before_amount ± amount`。 +- 可用余额和冻结余额不得小于 0。 + +### 10.2 幂等要求 + +- 申请接口使用调用方传入的幂等键。 +- 执行接口以审批单 ID 和业务单 ID 共同保证幂等。 +- 重复执行已完成审批时返回清晰业务错误,不重复写钱包和台账。 +- 数据库唯一索引冲突必须转换为用户可理解的业务错误。 + +### 10.3 审计要求 + +业务审计至少记录: + +- 模块和动作。 +- 操作人、目标类型和目标 ID。 +- 原状态和目标状态。 +- 原台账 ID 和冲正台账 ID。 +- 冲正金额、原因和证据摘要。 +- 审批单号和 Trace ID。 +- 变更前后摘要与结构化差异。 + +## 11. 异常与并发处理 + +| 场景 | 处理要求 | +| --- | --- | +| 重复点击执行 | 只允许第一次成功,后续返回“审批已执行” | +| 两个管理员同时执行 | 通过事务行锁保证只有一个事务成功 | +| 审批后业务状态变化 | 拒绝执行,要求重新发起审批 | +| 钱包余额不足以冲正 | 整体回滚,不产生台账和状态变化 | +| 原台账不存在或归属不符 | 拒绝执行并记录 Warning 日志 | +| 审批通过但事务失败 | 审批保持未执行,可排查后重试 | +| 审计写入失败 | 核心事务整体回滚 | +| 通知发送失败 | 不回滚核心事务,记录 Warning 并通过队列重试 | + +## 12. 测试方案 + +### 12.1 状态机测试 + +每个状态机都要覆盖: + +- 所有允许转换成功。 +- 所有禁止转换失败。 +- 相同状态重复申请失败。 +- 注销会员恢复失败。 +- 申请后状态变化导致执行失败。 +- 已执行审批重复执行失败。 + +### 12.2 资金测试 + +- 充值入账冲正后余额正确。 +- 任务佣金冲正后余额正确。 +- 原台账保持不变。 +- 冲正台账方向、金额和 `reversal_of` 正确。 +- 幂等键重复提交不产生重复台账。 +- 两个并发执行请求只生成一条冲正台账。 +- 余额不足时业务状态、钱包和台账均不变化。 +- 审计日志、审批单和台账可以相互追溯。 + +### 12.3 内容测试 + +- 只有已下线内容可以归档。 +- 已归档内容不可编辑和发布。 +- 历史版本回滚生成新草稿。 +- 回滚不改变当前发布版本。 +- 新草稿的 `base_version_id`、版本号和内容正确。 + +### 12.4 回归测试 + +- 原充值审核、提现审核和任务审核流程不受影响。 +- 原会员禁用和恢复流程仍可使用。 +- 原站点配置版本与回滚流程不受影响。 +- 字典加载、权限菜单和审计列表正常。 + +## 13. 验收标准 + +满足以下条件后视为第 12 章补强完成: + +1. 注销会员无法通过任何后台状态接口恢复。 +2. 充值成功后只能通过审批冲正,不允许直接修改余额或原台账。 +3. 已结算任务佣金可以通过审批冲正,且不可重复冲正。 +4. 每次冲正都能从业务单追溯到原台账、冲正台账、审批单和审计记录。 +5. 已下线内容可以归档,历史版本可以生成新草稿且不覆盖线上数据。 +6. 所有新增接口具有后端权限校验和明确的中文业务错误。 +7. 非法转换、重复执行、并发执行和余额不足测试全部通过。 +8. 后端编译、前端类型检查和现有模块回归测试通过。 + +## 14. 推荐实施顺序 + +1. 新增数据库迁移并用 GoFrame CLI 重新生成模型和 DAO。 +2. 补充状态字典和统一转换判断。 +3. 修复会员状态申请与执行校验。 +4. 实现充值冲正申请与执行。 +5. 实现任务佣金冲正申请与执行。 +6. 实现内容归档和历史版本回滚草稿。 +7. 增加按钮权限和角色授权。 +8. 增加前端操作按钮、弹窗和状态展示。 +9. 完成状态机、资金并发和回归测试。 + diff --git a/docs/guide-zh-CN/README.md b/docs/guide-zh-CN/README.md new file mode 100644 index 0000000..2aff16d --- /dev/null +++ b/docs/guide-zh-CN/README.md @@ -0,0 +1,60 @@ +## 目录 + +#### 介绍安装 + +- [系统介绍](../../README.md) +- [环境搭建](start-environment.md) +- [系统安装](start-installation.md) +- [生产部署](start-deploy.md) +- [如何提问](start-questions.md) +- [常见问题](start-issue.md) +- [更新历史](start-update-log.md) + + +#### 系统开发 + +- [目录结构](sys-catalog.md) +- [开发规范](sys-exploit.md) +- [控制台](sys-console.md) +- [中间件/拦截器](sys-middleware.md) +- [WebHook](sys-webhook.md) +- [权限控制](sys-auth.md) +- [支付网关](sys-payment.md) +- [定时任务](sys-cron.md) +- [消息队列](sys-queue.md) +- [功能扩展库](sys-library.md) +- [工具方法](sys-utility.md) +- [WebSocket服务器](sys-websocket-server.md) +- [TCP服务器](sys-tcp-server.md) +- [SaaS多租户](sys-tenant.md) +- [国际化](sys-i18n.md) +- [单元测试](sys-test.md) + + +#### 插件模块开发 + +- [模块介绍及目录](addon-introduce-catalog.md) +- [模块开发流程](addon-flow.md) +- [模块辅助说明](addon-helper.md) + + +#### 生成代码 +- [使用前提](code-start.md) +- [数据库](sys-db.md) +- [生成配置](code-config.md) +- [生成CURD](code-curd.md) +- [生成关联表CURD](code-curd-join.md) +- [生成树型CURD](code-tree.md) +- [生成业务模板](code-business.md) +- [生成模板开发](code-template-dev.md) +- [生成常见问题](code-help.md) + + +### 前端开发 +- [表单组件](web-form.md) +- [WebSocket客户端](sys-websocket-client.md) +- [独立部署](web-deploy.md) + + +#### 附录 +- [网址收录](append-website.md) \ No newline at end of file diff --git a/docs/guide-zh-CN/addon-flow.md b/docs/guide-zh-CN/addon-flow.md new file mode 100644 index 0000000..209cc56 --- /dev/null +++ b/docs/guide-zh-CN/addon-flow.md @@ -0,0 +1,216 @@ +## 模块开发流程 + +目录 + +- 创建新插件 +- 开发 +- 调用主模块服务接口 +- 访问路径 +- 数据迁移 + + + +### 创建新插件 + +1、HotGo 后台进入 开发工具->插件管理->找到创建新插件,根据引导进行创建即可。 + +```shell +创建成功后默认情况下会在以下目录中生成插件文件,假设新生成的插件名为:hgexample + +1. /server/addons/hgexample/ # 插件模块目录 +2. /server/addons/modules/hgexample.go # 隐式注册插件文件 +3. /server/resource/addons/hgexample # 静态资源和页面模板目录,属于扩展功能选项,勾选对应选项后才会生成 +4. /web/src/api/addons/hgexample # webApi目录 +5. /web/src/views/addons/hgexample # web页面目录 + +# 默认情况下没有为web页面生成菜单权限,因为在实际场景中插件不一定需要用到web页面,所以如有需要请手动到后台 权限管理 -> 菜单权限->自行添加菜单和配置权限 +``` + + +2、创建插件完毕重启服务端后,插件管理中会出现你新创建的插件信息。操作栏有几个按钮,在此进行说明 +- 安装:会自动执行 server/hgexample/main.go 文件中的Install方法,方法中的具体逻辑默认为空,可以根据实际情况自行配置。如生成后台菜单、生成插件配置表初始化数据、迁移home页面、web项目文件等。 +```go +// Install 安装模块 +func (m *module) Install(ctx context.Context) (err error) { + // ... + return +} +``` + +- 更新:会自动执行 server/hgexample/main.go 文件中的Upgrade方法,方法中的具体逻辑默认为空,可以根据实际情况自行配置。 +```go +// Upgrade 更新模块 +func (m *module) Upgrade(ctx context.Context) (err error) { + // ... + return +} +``` + +- 卸载:会自动执行 server/hgexample/main.go 文件中的UnInstall方法,方法中的具体逻辑默认为空,可以根据实际情况自行配置。如会清除所有的数据表和已安装的信息等。 +```go +// UnInstall 卸载模块 +func (m *module) UnInstall(ctx context.Context) (err error) { + // ... + return +} +``` + + + +### 开发 + +完全可以根据HotGo正常的开发流程去开发对应的API、控制器、业务逻辑、插件内的应用 + +### 调用主模块服务接口 + +这里推荐的方式是在插件input层新建一个结构,继承主模块中的input结构。这样做的目的是为了服务与服务之间的输入/输出关系解耦,便于参数扩展和避免插件模块下使用`gf gen service`时出现`import cycle not allowed`。 + +一个简单的例子: +> 假设hgexample插件模块要通过主模块的服务接口更新插件配置 + +插件模块input:\server\addons\hgexample\model\input\sysin\config.go +```go +package sysin + +import ( + "hotgo/internal/model/input/sysin" +) + +// UpdateConfigInp 更新指定配置 +type UpdateConfigInp struct { + sysin.UpdateAddonsConfigInp +} + +``` + +插件模块业务逻辑:\server\addons\hgexample\logic\sys\config.go +```go +package sys + +import ( + "context" + "hotgo/addons/hgexample/global" + "hotgo/addons/hgexample/model/input/sysin" + "hotgo/addons/hgexample/service" + isc "hotgo/internal/service" +) + +type sSysConfig struct{} + +func NewSysConfig() *sSysConfig { + return &sSysConfig{} +} + +func init() { + service.RegisterSysConfig(NewSysConfig()) +} + +// UpdateConfigByGroup 更新指定分组的配置 +func (s *sSysConfig) UpdateConfigByGroup(ctx context.Context, in sysin.UpdateConfigInp) error { + in.UpdateAddonsConfigInp.AddonName = global.GetSkeleton().Name + return isc.SysAddonsConfig().UpdateConfigByGroup(ctx, in.UpdateAddonsConfigInp) +} + +``` + +主模块input:\server\internal\model\input\sysin\addons_config.go +```go +package sysin + +import ( + "github.com/gogf/gf/v2/frame/g" +) + +// UpdateAddonsConfigInp 更新指定插件的配置 +type UpdateAddonsConfigInp struct { + AddonName string `json:"addonName"` + Group string `json:"group"` + List g.Map `json:"list"` +} + +``` + +主模块业务逻辑:\server\internal\logic\sys\addons_config.go +```go +package sys + +import ( + "context" + "hotgo/internal/model/input/sysin" + "hotgo/internal/service" +) + +type sSysAddonsConfig struct{} + +func NewSysAddonsConfig() *sSysAddonsConfig { + return &sSysAddonsConfig{} +} + +func init() { + service.RegisterSysAddonsConfig(NewSysAddonsConfig()) +} + +// UpdateConfigByGroup 更新指定分组的配置 +func (s *sSysAddonsConfig) UpdateConfigByGroup(ctx context.Context, in sysin.UpdateAddonsConfigInp) error { + // ... + return nil +} + +``` + + + + +### 访问路径 + +#### 后台插件访问路径 + +``` +// IP+端口或域名/admin/插件名称/API路径 +如:127.0.0.1:8000/admin/hgexample/index/test +``` + +- 对应控制器路径:`server/addons/hgexample/controller/admin/sys/index.go` + +#### 前端API插件访问路径 + +``` +// IP+端口或域名/api/插件名称/API路径 +如:127.0.0.1:8000/api/hgexample/index/test +``` + +- 对应控制器路径:`server/addons/hgexample/controller/api/index.go` + +#### 前台页面插件访问路径 + +``` +// IP+端口或域名/home/插件名称/API路径 +如:127.0.0.1:8000/home/hgexample/index/test +``` + +- 对应控制器路径:`server/addons/hgexample/controller/home/index.go` +- 对应模板路径:`server/addons/hgexample/resource/public/template` + +#### 静态资源插件访问路径 + +``` +// IP+端口或域名/home/插件名称/API路径 +如:127.0.0.1:8000/addons/hgexample/default +``` + +- 对应资源路径:`server/addons/hgexample/resource/public` + + +#### Websocket插件访问路径 + +``` +// IP+端口或域名/socket/插件名称/API路径 +如:127.0.0.1:8000/socket/hgexample/index/test +``` + +- 对应控制器路径:`server/addons/hgexample/controller/socket/index.go` + + +### 数据迁移 + +- 可以将数据迁移逻辑写进server/xxx插件/main.go 文件中的Install方法中,并遵循系统规范进行数据安装 diff --git a/docs/guide-zh-CN/addon-helper.md b/docs/guide-zh-CN/addon-helper.md new file mode 100644 index 0000000..57d4d56 --- /dev/null +++ b/docs/guide-zh-CN/addon-helper.md @@ -0,0 +1,86 @@ +## 模块辅助说明 + +目录 + +- 模块结构 +- 获取模块信息 +- 插件路由规则 + + +#### 模块结构 +- 文件路径:server/internal/library/addons/module.go + +```go +// Skeleton 模块骨架 +type Skeleton struct { + Label string `json:"label"` // 标识 + Name string `json:"name"` // 名称 + Group int `json:"group"` // 分组 + Logo string `json:"logo"` // logo + Brief string `json:"brief"` // 简介 + Description string `json:"description"` // 详细描述 + Author string `json:"author"` // 作者 + Version string `json:"version"` // 版本号 + RootPath string `json:"rootPath"` // 根路径 + View *gview.View `json:"view"` // 模板引擎 +} + +func (s *Skeleton) GetModule() Module { + return GetModule(s.Name) +} + +// Module 插件模块 +type Module interface { + Start(option *Option) (err error) // 启动模块 + Stop() (err error) // 停止模块 + Ctx() context.Context // 上下文 + GetSkeleton() *Skeleton // 获取模块 + Install(ctx context.Context) (err error) // 安装模块 + Upgrade(ctx context.Context) (err error) // 更新模块 + UnInstall(ctx context.Context) (err error) // 卸载模块 +} +``` + +#### 获取模块信息 + +- 在插件模块内 + +```go +package main + +import ( + "fmt" + "hotgo/addons/hgexample/global" +) + +func test() { + fmt.Printf("当前插件模块是:%+v", global.GetSkeleton()) +} +``` + +- 在插件模块外 + +```go +package main + +import ( + "context" + "fmt" + "hotgo/internal/library/addons" + "hotgo/internal/library/contexts" +) + +func test(ctx context.Context) { + fmt.Printf("当前是否为插件请求:%v", contexts.IsAddonRequest(ctx)) + if contexts.IsAddonRequest(ctx) { + fmt.Printf("当前插件名称:%v", contexts.GetAddonName(ctx)) + fmt.Printf("当前插件信息:%v", addons.GetModule(contexts.GetAddonName(ctx))) + } +} +``` + +- 更多辅助方法请参考插件功能库:server/internal/library/addons + +#### 插件路由规则 +- 如果你不喜欢现在的路由风格,可以自行调整。修改位置在:\server\internal\library\addons\addons.go的RouterPrefix方法。 +- 注意调整后如web前端页面中如有之前的路由风格也需同步修改。 diff --git a/docs/guide-zh-CN/addon-introduce-catalog.md b/docs/guide-zh-CN/addon-introduce-catalog.md new file mode 100644 index 0000000..c7f98f1 --- /dev/null +++ b/docs/guide-zh-CN/addon-introduce-catalog.md @@ -0,0 +1,40 @@ +## 模块介绍及目录 + +目录 + +- 模块介绍 +- 启动流程 +- 目录结构 + +### 模块介绍 + +> 定位:开发独立、临时性、工具类型的功能时推荐使用插件化开发,例如:小游戏(大转盘/消消乐/抽奖/大屏互动/红包等)、小插件(广告管理/文章管理/友情链接等等)、小模块(报名/投票/签到)、小程序、大型插件微商城等等。 + +> 插件模块方便多项目复用,同时完美支持多人协同开发,每个插件模块都有独立的微架构目录结构,多插件之间完全隔离。 + +### 启动流程 + +HotGo 入口文件->隐式注入(hotgo/addons/modules)->注册所有插件->初始化已安装的插件->写入路由组->根据 HotGo 正常的开发和访问流程去开发访问插件 + + +### 目录结构 +- 详细介绍请参考:[目录结构](sys-catalog.md) +``` +/server +├── addons +│ ├── modules +│ ├── xxx插件 +│ | ├── api +│ | ├── consts +│ | ├── controller +│ | ├── crons +│ | ├── global +│ | ├── logic +│ | ├── model +│ | ├── queues +│ | ├── resource +│ | ├── router +│ | ├── service +│ | ├── main.go +│ | └── README.md +``` diff --git a/docs/guide-zh-CN/append-website.md b/docs/guide-zh-CN/append-website.md new file mode 100644 index 0000000..8ca465f --- /dev/null +++ b/docs/guide-zh-CN/append-website.md @@ -0,0 +1,21 @@ +目录 + +- 框架文档 + - [goframe](https://goframe.org/pages/viewpage.action?pageId=1114119) + - [naiveui](https://www.naiveui.com) + - [naive-ui-admin](https://docs.naiveadmin.com/) + + +- 常用组件 + - [websocket](https://github.com/gorilla/websocket) + - [casbin](https://github.com/casbin/casbin) + - [tailwind](https://tailwind.docs.73zls.com/docs/flex-direction) + + +- 系统通用 + - [redis](https://redis.io/) + + +- 其他 + - [awesome-go](https://github.com/avelino/awesome-go) + \ No newline at end of file diff --git a/docs/guide-zh-CN/code-business.md b/docs/guide-zh-CN/code-business.md new file mode 100644 index 0000000..2564b47 --- /dev/null +++ b/docs/guide-zh-CN/code-business.md @@ -0,0 +1,5 @@ +## 生成业务模板 + +根据`api`接口文件一键生成业务模板:api、controller、logic、service + +待写。 diff --git a/docs/guide-zh-CN/code-config.md b/docs/guide-zh-CN/code-config.md new file mode 100644 index 0000000..273dca2 --- /dev/null +++ b/docs/guide-zh-CN/code-config.md @@ -0,0 +1,172 @@ +## 生成配置 + +目录 + +- 模板配置 +- CLI配置 +- 多数据库使用 + +### 模板配置 + +- 配置路径:server/manifest/config/config.yaml + +```yaml +# 生成代码 +hggen: + allowedIPs: [ "127.0.0.1", "*" ] # 白名单,*代表所有,只有允许的IP后台才能使用生成代码功能 + selectDbs: [ "default" ] # 可选生成表的数据库配置名称,支持多库 + disableTables: [ "hg_sys_gen_codes","hg_admin_role_casbin" ] # 禁用的表,禁用以后将不会在选择表中看到 + delimiters: [ "@{", "}" ] # 模板引擎变量分隔符号 + # 生成应用模型,所有生成模板允许自定义,可以参考default模板进行改造 + application: + # CRUD和关系树列表模板 + crud: + templates: + # 默认的主包模板 + - group: "default" # 分组名称 + isAddon: false # 是否为插件模板 false|true + masterPackage: "sys" # 主包名称,需和controllerPath、logicPath、inputPath保持关联 + templatePath: "./resource/generate/default/curd" # 模板路径 + apiPath: "./api/admin" # goApi生成路径 + controllerPath: "./internal/controller/admin/sys" # 控制器生成路径 + logicPath: "./internal/logic/sys" # 主要业务生成路径 + inputPath: "./internal/model/input/sysin" # 表单过滤器生成路径 + routerPath: "./internal/router/genrouter" # 生成路由表路径 + sqlPath: "./storage/data/generate" # 生成sql语句路径 + webApiPath: "../web/src/api" # webApi生成路径 + webViewsPath: "../web/src/views" # web页面生成路径 + + # 默认的插件包模板,{$name}会自动替换成实际的插件名称 + - group: "addon" # 分组名称 + isAddon: true # 是否为插件模板 false|true + masterPackage: "sys" # 主包名称,需和controllerPath、logicPath、inputPath保持关联 + templatePath: "./resource/generate/default/curd" # 模板路径 + apiPath: "./addons/{$name}/api/admin" # goApi生成路径 + controllerPath: "./addons/{$name}/controller/admin/sys" # 控制器生成路径 + logicPath: "./addons/{$name}/logic/sys" # 主要业务生成路径 + inputPath: "./addons/{$name}/model/input/sysin" # 表单过滤器生成路径 + routerPath: "./addons/{$name}/router/genrouter" # 生成路由表路径 + sqlPath: "./storage/data/generate/addons" # 生成sql语句路径 + webApiPath: "../web/src/api/addons/{$name}" # webApi生成路径 + webViewsPath: "../web/src/views/addons/{$name}" # web页面生成路径 + + # 消息队列模板 + queue: + templates: + - group: "default" + templatePath: "./resource/generate/default/queue" + + # 定时任务模板 + cron: + templates: + - group: "default" + templatePath: "./resource/generate/default/cron" + + # 生成插件模块,通过后台创建新插件时使用的模板,允许自定义,可以参考default模板进行改造 + addon: + srcPath: "./resource/generate/default/addon" # 生成模板路径 + webApiPath: "../web/src/api/addons/{$name}" # webApi生成路径 + webViewsPath: "../web/src/views/addons/{$name}" # web页面生成路径 +``` + +### CLI配置 + +- hotgo在生成dao、service配置时,默认了和gf官方一致的配置方式和代码生成规则。所以无论你是通过hotgo亦或gf命令生成,最终代码格式完全一致,遵循一致的代码规范。 + +- 配置路径:[server/hack/config.yaml](../../server/hack/config.yaml) + +```yaml +gfcli: + build: + name: "hotgo" # 编译后的可执行文件名称 + # arch: "all" #不填默认当前系统架构,可选:386,amd64,arm,all + # system: "all" #不填默认当前系统平台,可选:linux,darwin,windows,all + mod: "none" + cgo: 0 + packSrc: "resource" # 将resource目录打包进可执行文件,静态资源无需单独部署 + packDst: "internal/packed/packed.go" # 打包后生成的Go文件路径,一般使用相对路径指定到本项目目录中 + version: "" + output: "./temp/hotgo" # 可执行文件生成路径 + extra: "" + + gen: + dao: + - link: "mysql:hotgo:hg123456.@tcp(127.0.0.1:3306)/hotgo?loc=Local&parseTime=true" +# - link: "pgsql:postgres:hg123456@tcp(127.0.0.1:5432)/hotgo" + group: "default" # 分组 使用hotgo代码生成功能时必须填 + # tables: "" # 指定当前数据库中需要执行代码生成的数据表。如果为空,表示数据库的所有表都会生成。 + tablesEx: "hg_sys_addons_install" # 指定当前数据库中需要排除代码生成的数据表。 + removePrefix: "hg_" + descriptionTag: true + noModelComment: true + jsonCase: "CamelLower" + gJsonSupport: true + clear: true + + service: # 生成业务配置 + srcFolder: "internal/logic" + dstFolder: "internal/service" + dstFileNameCase: "CamelLower" + clear: true +``` + +### 多数据库使用 + +- 假设我们要增加一个库名为`hotgo2`、分组为`default2`的数据库,并要为其生成代码 + +1. 配置[server/hack/config.yaml](../../server/hack/config.yaml) 如下: +```yaml + gen: + dao: + - link: "mysql:hotgo:hg123456.@tcp(127.0.0.1:3306)/hotgo?loc=Local&parseTime=true" + group: "default" # 分组 使用hotgo代码生成功能时必须填 + tablesEx: "hg_sys_addons_install" # 指定当前数据库中需要排除代码生成的数据表。 + removePrefix: "hg_" + descriptionTag: true + noModelComment: true + jsonCase: "CamelLower" + gJsonSupport: true + clear: false + - link: "mysql:hotgo2:hg123456.@tcp(127.0.0.1:3306)/hotgo2?loc=Local&parseTime=true" + group: "default2" # 分组 使用hotgo代码生成功能时必须填 + tablesEx: "hg_sys_addons_install" # 指定当前数据库中需要排除代码生成的数据表。 + removePrefix: "" + descriptionTag: true + noModelComment: true + jsonCase: "CamelLower" + gJsonSupport: true + clear: false +``` + +2. 配置`server/manifest/config/config.yaml`, + +`database`配置如下: +```yaml +database: + logger: + level: "all" + stdout: true + default: + link: "mysql:hotgo:hg123456.@tcp(127.0.0.1:3306)/hotgo?loc=Local&parseTime=true" +# link: "pgsql:postgres:hg123456@tcp(127.0.0.1:5432)/hotgo" + debug: true + Prefix: "hg_" + default2: + link: "mysql:hotgo2:hg123456.@tcp(127.0.0.1:3306)/hotgo2?loc=Local&parseTime=true" + debug: true + Prefix: "" +``` + +`hggen`配置如下: +```yaml +hggen: + allowedIPs: ["127.0.0.1", "*"] # 白名单,*代表所有,只有允许的IP后台才能使用生成代码功能 + selectDbs: [ "default", "default2" ] # 可选生成表的数据库配置名称,支持多库 + disableTables : ["hg_sys_gen_codes","hg_admin_role_casbin"] # 禁用的表,禁用以后将不会在选择表中看到 + delimiters: ["@{", "}"] # 模板引擎变量分隔符号 +``` + +3. 登录HotGo后台 -> 开发工具 -> 代码生成 -> 找到立即生成按钮并打开,就会发现`数据库`选项增加了一个`default2`,后续生成步骤和生成例子完全一样 + +> 注意:上述的配置中所有的`default2`名称必须保持一致 + diff --git a/docs/guide-zh-CN/code-curd-join.md b/docs/guide-zh-CN/code-curd-join.md new file mode 100644 index 0000000..a732158 --- /dev/null +++ b/docs/guide-zh-CN/code-curd-join.md @@ -0,0 +1,115 @@ +## 生成关联表CURD + +### 热编译启动 +- 推荐使用热编译方式启动HotGo,这样生成完成页面自动刷新即可看到新生成内容,无需手动重启 + +```shell +# 服务端 +cd server +gf run main.go + +# web端 +cd web +pnpm run dev 或 npm run dev +``` + +以下是一个关联表的CURD生成流程 + +### 创建表结构 +- 以下表结构和数据为了方便功能演示已经内置无需再次创建 + + +- 创建主表:hg_sys_gen_curd_demo +```sql +CREATE TABLE `hg_sys_gen_curd_demo` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `category_id` bigint(20) DEFAULT '0' COMMENT '分类ID', + `title` varchar(64) NOT NULL COMMENT '标题', + `description` varchar(255) DEFAULT '' COMMENT '描述', + `content` text COMMENT '内容', + `image` varchar(255) DEFAULT NULL COMMENT '单图', + `attachfile` varchar(255) DEFAULT NULL COMMENT '附件', + `city_id` bigint(20) DEFAULT '0' COMMENT '所在城市', + `switch` int(11) DEFAULT '1' COMMENT '显示开关', + `sort` int(11) DEFAULT NULL COMMENT '排序', + `status` tinyint(1) DEFAULT '1' COMMENT '状态', + `created_by` bigint(20) DEFAULT '0' COMMENT '创建者', + `updated_by` bigint(20) DEFAULT '0' COMMENT '更新者', + `created_at` datetime DEFAULT NULL COMMENT '创建时间', + `updated_at` datetime DEFAULT NULL COMMENT '修改时间', + `deleted_at` datetime DEFAULT NULL COMMENT '删除时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COMMENT='系统_生成curd演示'; +``` + +创建关联表:hg_test_category +```sql +CREATE TABLE `hg_test_category` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '分类ID', + `name` varchar(255) NOT NULL COMMENT '分类名称', + `short_name` varchar(128) DEFAULT NULL COMMENT '简称', + `description` varchar(255) DEFAULT NULL COMMENT '描述', + `sort` int(11) NOT NULL COMMENT '排序', + `remark` varchar(255) DEFAULT NULL COMMENT '备注', + `status` tinyint(1) DEFAULT '1' COMMENT '状态', + `created_at` datetime DEFAULT NULL COMMENT '创建时间', + `updated_at` datetime DEFAULT NULL COMMENT '修改时间', + `deleted_at` datetime DEFAULT NULL COMMENT '删除时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COMMENT='测试分类'; +``` + +### 表字段要求 +- 使用生成时,表中必须具有以下字段和属性 + +| 字段名称 | 字段含义 | 字段类型 | 可为空 | +|--------|----------------------|---------------------|-----| +| id | 主键ID | bigint(20) | 否 | + + + +### 创建生成配置 +- 登录HotGo后台 -> 开发工具 -> 代码生成 -> 找到立即生成按钮并打开,选择和填写如下参数: + +![](images/code/join-add.png) + + +### 基本设置 +- 确认无误后,点击生成配置会跳转到生成配置页面,如下: +- 你可以在该页面调整生成表格表头/表列的接口功能、菜单权限、高级设置和关联表设置 + +![](images/code/join-init.png) + +### 主表字段设置 + +- 在该页面你可以调整生成表格字段名称、表单组件、表单编辑/验证项、列表展示/查询项、字段排序、重置和同步字段 + +![](images/code/join-fields.png) + + +### 关联表字段设置 +- 在该页面你可以调整生成表格关联表字段名称、列表展示/查询项、字段排序、重置和同步字段 +- 如果存在多个关联表,也可以对多个关联表字段进行设置 + +![](images/code/join-fields2.png) + +### 预览并生成 + +点击`预览代码`查看生成的代码内容。如果无需继续调整直接点击`提交生成`即可,以下是预览代码效果: + +![](images/code/join-preview.png) + +- 如果你使用的热编译,那么页面会在生成成功后立即刷新,刷新完成你即可在后台菜单栏中看到`测试表格`菜单。如果不是使用热编译启动,请手动重启服务后刷新。 + + +### 生成完成 + +- 让我们看看生成的表格页面,效果如下: + +![](images/code/join-list.png) + +### 常见问题 + +- [生成常见问题](code-help.md) + + diff --git a/docs/guide-zh-CN/code-curd.md b/docs/guide-zh-CN/code-curd.md new file mode 100644 index 0000000..46a30bc --- /dev/null +++ b/docs/guide-zh-CN/code-curd.md @@ -0,0 +1,84 @@ +## 生成CURD + +### 热编译启动 +- 推荐使用热编译方式启动HotGo,这样生成完成页面自动刷新即可看到新生成内容,无需手动重启 + +```shell +# 服务端 +cd server +gf run main.go + +# web端 +cd web +pnpm run dev 或 npm run dev +``` + +以下是一个基本的CURD生成流程 + +### 创建表结构 +- 以下表结构和数据为了方便功能演示已经内置无需再次创建 + +```sql +CREATE TABLE `hg_test_category` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '分类ID', + `name` varchar(255) NOT NULL COMMENT '分类名称', + `short_name` varchar(128) DEFAULT NULL COMMENT '简称', + `description` varchar(255) DEFAULT NULL COMMENT '描述', + `sort` int(11) NOT NULL COMMENT '排序', + `remark` varchar(255) DEFAULT NULL COMMENT '备注', + `status` tinyint(1) DEFAULT '1' COMMENT '状态', + `created_at` datetime DEFAULT NULL COMMENT '创建时间', + `updated_at` datetime DEFAULT NULL COMMENT '修改时间', + `deleted_at` datetime DEFAULT NULL COMMENT '删除时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COMMENT='测试分类'; +``` + +### 表字段要求 +- 使用生成时,表中必须具有以下字段和属性 + +| 字段名称 | 字段含义 | 字段类型 | 可为空 | +|--------|----------------------|---------------------|-----| +| id | 主键ID | bigint(20) | 否 | + + +### 创建生成配置 +- 登录HotGo后台 -> 开发工具 -> 代码生成 -> 找到立即生成按钮并打开,选择和填写如下参数: + +![](images/code/curd-add.png) + + +### 基本设置 +- 确认无误后,点击生成配置会跳转到生成配置页面,如下: +- 你可以在该页面调整生成表格表头/表列的接口功能、菜单权限、高级设置和关联表设置 + +![](images/code/curd-init.png) + +### 表字段设置 + +- 在该页面你可以调整生成表格字段名称、表单组件、表单编辑/验证项、列表展示/查询项、字段排序、重置和同步字段 + +![](images/code/curd-fields.png) + +### 预览并生成 + +点击`预览代码`查看生成的代码内容。如果无需继续调整直接点击`提交生成`即可,以下是预览代码效果: + +![](images/code/curd-preview.png) + +- 如果你使用的热编译,那么页面会在生成成功后立即刷新,刷新完成你即可在后台菜单栏中看到`测试表格`菜单。如果不是使用热编译启动,请手动重启服务后刷新。 + + +### 生成完成 + +- 让我们看看生成的表格页面,效果如下: + +![](images/code/curd-list.png) + + +### 常见问题 + +- [生成常见问题](code-help.md) + + + diff --git a/docs/guide-zh-CN/code-help.md b/docs/guide-zh-CN/code-help.md new file mode 100644 index 0000000..8f220b1 --- /dev/null +++ b/docs/guide-zh-CN/code-help.md @@ -0,0 +1,18 @@ +## 生成常见问题 + +### 生成完后页面提示:服务器错误,请稍候重试! + +- 热编译环境下,web端往往会快于服务端重启并加载完成,此时接口访问会出现`服务器错误,请稍候重试!`或`404`。这是服务端正在重启导致的,一般稍等几秒就好,如果不行就手动重启下服务端。 + + +### fetching tables failed: SHOW TABLES: Error 1045 (28000): Access denied for user * (using password: YES) + +- 请去确认`server/manifest/config/config.yaml`和`server/hack/config.yaml`下的数据库配置一致并且权限正确 +- 参考:[生成配置](code-config.md) + + +### 为什么后台找不到开发工具菜单 + +- 请去确认`server/manifest/config/config.yaml`中的`system.mode`不为`product`。product模式下后台【开发工具】菜单自动隐藏 + + diff --git a/docs/guide-zh-CN/code-start.md b/docs/guide-zh-CN/code-start.md new file mode 100644 index 0000000..ddeea5e --- /dev/null +++ b/docs/guide-zh-CN/code-start.md @@ -0,0 +1,20 @@ +## 使用前提 + + +在HotGo中可以通过后台开发工具快速的一键生成CRUD,自动生成Api、控制器、业务逻辑、Web页面、表单组件、菜单权限等。 + + +- hotgo 版本号 >= 2.13.1 +- 使用前必须配置 [生成配置](code-config.md) +- 使用前必须了解 [数据库](sys-db.md) + + +相关目录 + +- [生成配置](code-config.md) +- [生成CURD](code-curd.md) +- [生成关联表CURD](code-curd-join.md) +- [生成树型CURD](code-tree.md) +- [生成业务模板](code-business.md) +- [生成模板开发](code-template-dev.md) +- [生成常见问题](code-help.md) \ No newline at end of file diff --git a/docs/guide-zh-CN/code-template-dev.md b/docs/guide-zh-CN/code-template-dev.md new file mode 100644 index 0000000..6747ac8 --- /dev/null +++ b/docs/guide-zh-CN/code-template-dev.md @@ -0,0 +1,59 @@ +## 生成模板开发 + +### 自定义生成模板 + +- HotGo允许你新建新的模板分组来满足你的需求,模板可根据现有模板基础拷贝一份出来做改造,默认模板目录:[server/resource/generate/default](../../server/resource/generate/default) + +- 系统内置了两组CURD生成模板,请参考[生成模板配置](sys-code.md#生成模板配置)。default:是默认的生成到主模块下;addon:是默认生成到指定的插件下 + + + +### 内置gf-cli + +- 为了确保生成代码的依赖稳定性,在面对`gf`版本更新可能导致向下不兼容情况时,HotGo将`gf-cli`工具内置到系统中并进行在线执行调整,从而提供更可靠和一致的生成代码功能。 + +- 后续我们也将开放在线运行`gf gen ...`功能。在做插件开发时也会支持到在线生成插件下的service接口,这将会使得插件开发更加方便 + + + +### 指定gf-cli版本 + +- HotGo多数情况下会和最新版本的gf-cli保持同步,如果更新不及时或你不想使用最新版本的gf-cli来生成代码,可以找到自己想要的版本进行替换即可。 + +- 下面大致做一些替换步骤说明: + +1. 打开`github.com/gogf/gf` 找到你想要使用的版本`clone`下来 +2. 将`clone`代码中`gf/cmd/gf/internal/`目录覆盖到`server/internal/library/hggen/internal` +3. 将覆盖过来的目录文件中引入包名`github.com/gogf/gf/cmd/gf/v2/`批量改为`hotgo/internal/library/hggen/` +4. 运行`go mod tidy` +5. 运行`go run main.go`,如果没有报错,那么恭喜你已经完成了。如果有报错一般都是版本差异带来的影响,需要根据情况自行调整 + + + +### 指定数据库驱动 + +> HotGo默认使用mysql驱动,如果你想用其他数据库驱动打开下方文件中注释即可,目前已支持mysql、pgsql + +- 修改文件路径:[server/internal/library/hggen/internal/cmd/cmd_gen_dao.go](../../server/internal/library/hggen/internal/cmd/cmd_gen_dao.go) + +```go +package cmd + +import ( + //_ "github.com/gogf/gf/contrib/drivers/clickhouse/v2" + //_ "github.com/gogf/gf/contrib/drivers/mssql/v2" + _ "github.com/gogf/gf/contrib/drivers/mysql/v2" + //_ "github.com/gogf/gf/contrib/drivers/oracle/v2" + _ "github.com/gogf/gf/contrib/drivers/pgsql/v2" + //_ "github.com/gogf/gf/contrib/drivers/sqlite/v2" + + "hotgo/internal/library/hggen/internal/cmd/gendao" +) + +type ( + cGenDao = gendao.CGenDao +) + +``` + +修改完成后运行`go mod tidy` diff --git a/docs/guide-zh-CN/code-tree.md b/docs/guide-zh-CN/code-tree.md new file mode 100644 index 0000000..6583660 --- /dev/null +++ b/docs/guide-zh-CN/code-tree.md @@ -0,0 +1,93 @@ +## 生成树型CURD + +### 热编译启动 +- 推荐使用热编译方式启动HotGo,这样生成完成页面自动刷新即可看到新生成内容,无需手动重启 + +```shell +# 服务端 +cd server +gf run main.go + +# web端 +cd web +pnpm run dev 或 npm run dev +``` + +以下是一个基本的树形CURD生成流程 + +### 创建表结构 +- 以下表结构和数据为了方便功能演示已经内置无需再次创建 + +```sql +CREATE TABLE `hg_sys_gen_tree_demo` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `pid` bigint(20) DEFAULT NULL COMMENT '上级ID', + `level` int(11) DEFAULT '1' COMMENT '关系树级别', + `tree` varchar(512) COMMENT '关系树', + `category_id` bigint(20) DEFAULT '0' COMMENT '分类ID', + `title` varchar(64) NOT NULL COMMENT '标题', + `description` varchar(255) DEFAULT '' COMMENT '描述', + `sort` int(11) DEFAULT NULL COMMENT '排序', + `status` tinyint(1) DEFAULT '1' COMMENT '状态', + `created_by` bigint(20) DEFAULT '0' COMMENT '创建者', + `updated_by` bigint(20) DEFAULT '0' COMMENT '更新者', + `created_at` datetime DEFAULT NULL COMMENT '创建时间', + `updated_at` datetime DEFAULT NULL COMMENT '修改时间', + `deleted_at` datetime DEFAULT NULL COMMENT '删除时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb4 COMMENT='系统_生成树表演示'; +``` + +### 表字段要求 +- 使用生成时,表中必须具有以下字段和属性 + +| 字段名称 | 字段含义 | 字段类型 | 可为空 | +|--------|----------------------|---------------------|-----| +| id | 主键ID | bigint(20) | 否 | +| pid | 上级树ID | bigint(20) | 是 | +| level | 关系树级别 | int(11) | 否 | +| tree | 关系树 | varchar(512) | 是 | + +### 创建生成配置 +- 登录HotGo后台 -> 开发工具 -> 代码生成 -> 找到立即生成按钮并打开,选择和填写如下参数: + +![](images/code/tree-add.png) + + +### 基本设置 +- 确认无误后,点击生成配置会跳转到生成配置页面,如下: +- 你可以在该页面调整生成表格表头/表列的接口功能、菜单权限、高级设置和关联表设置 +- 相比普通CURD,这里多了`树名称字段`和`树表格样式`选项 + +![](images/code/tree-init.png) + +### 表字段设置 + +- 在该页面你可以调整生成表格字段名称、表单组件、表单编辑/验证项、列表展示/查询项、字段排序、重置和同步字段 +- 树表中的pid、level、tree字段由系统维护,单独设置编辑表单功能无效! + +![](images/code/tree-fields.png) + +### 预览并生成 + +点击`预览代码`查看生成的代码内容。如果无需继续调整直接点击`提交生成`即可,以下是预览代码效果: + +![](images/code/tree-preview.png) + +- 如果你使用的热编译,那么页面会在生成成功后立即刷新,刷新完成你即可在后台菜单栏中看到`测试表格`菜单。如果不是使用热编译启动,请手动重启服务后刷新。 + + +### 生成完成 + +- 让我们看看生成的表格页面,效果如下: + +- 普通树表 +![](images/code/tree-list.png) + +- 选项式树表 +![](images/code/tree-list2.png) + +### 常见问题 + +- [生成常见问题](code-help.md) + diff --git a/docs/guide-zh-CN/images/code/curd-add.png b/docs/guide-zh-CN/images/code/curd-add.png new file mode 100644 index 0000000..14ef083 Binary files /dev/null and b/docs/guide-zh-CN/images/code/curd-add.png differ diff --git a/docs/guide-zh-CN/images/code/curd-fields.png b/docs/guide-zh-CN/images/code/curd-fields.png new file mode 100644 index 0000000..00fe790 Binary files /dev/null and b/docs/guide-zh-CN/images/code/curd-fields.png differ