diff --git a/docs/需求文档.md b/docs/需求文档.md index e69de29..2099b44 100644 --- a/docs/需求文档.md +++ b/docs/需求文档.md @@ -0,0 +1,728 @@ +# 营销系统数据导出工具需求文档 + +## 1. 项目概述 + +### 1.1 项目背景 + +营销系统数据导出工具(MarketingSystemDataExportTool)是一个面向营销系统和易码通系统的订单数据导出平台。该工具旨在为业务人员提供灵活、高效的数据导出能力,支持自定义导出模板、多种过滤条件和多种输出格式。 + +### 1.2 系统目标 + +- 提供统一的数据导出入口,支持营销系统和易码通两个数据源 +- 支持用户自定义导出模板,灵活配置导出字段 +- 提供丰富的过滤条件,满足多样化的数据查询需求 +- 支持大数据量导出,具备分片处理和进度跟踪能力 +- 提供友好的 Web 界面,降低使用门槛 + +### 1.3 技术栈 + +| 层级 | 技术选型 | +|------|----------| +| 后端 | Go 1.21 | +| 前端 | Vue 3 + Element Plus (CDN 引入) | +| 数据库 | MySQL | +| 导出格式 | CSV、Excel (XLSX) | + +--- + +## 2. 系统架构 + +### 2.1 整体架构 + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Web 前端 │ +│ (Vue 3 + Element Plus) │ +└─────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ Go HTTP 服务 │ +│ (端口: 8077) │ +└─────────────────────────────────────────────────────────────┘ + │ + ┌───────────────────┼───────────────────┐ + ▼ ▼ ▼ +┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ +│ 元数据库 │ │ 营销系统数据库 │ │ 易码通数据库 │ +│ (模板/任务存储) │ │ (Marketing) │ │ (YMT) │ +└─────────────────┘ └─────────────────┘ └─────────────────┘ +``` + +### 2.2 数据库连接 + +系统连接三个 MySQL 数据库: + +1. **元数据库 (Meta DB)**:存储导出模板和导出任务信息 +2. **营销系统数据库 (Marketing DB)**:营销系统业务数据 +3. **易码通数据库 (YMT DB)**:易码通业务数据 + +--- + +## 3. 功能模块 + +### 3.1 导出模板管理 + +#### 3.1.1 功能描述 + +导出模板用于定义数据导出的配置,包括数据源选择、导出字段、过滤条件等。 + +#### 3.1.2 模板属性 + +| 字段 | 类型 | 说明 | +|------|------|------| +| id | uint64 | 模板唯一标识 | +| name | string | 模板名称 | +| datasource | string | 数据源:`marketing` / `ymt` | +| main_table | string | 主表:`order` / `order_info` | +| fields_json | JSON | 导出字段列表 | +| filters_json | JSON | 过滤条件 | +| file_format | string | 输出格式:`csv` / `xlsx` | +| visibility | string | 可见性:`private` / `public` | +| owner_id | uint64 | 所有者 ID | +| enabled | bool | 是否启用 | +| explain_json | JSON | SQL 执行计划 | +| explain_score | int | 执行计划评分 | + +#### 3.1.3 接口列表 + +| 方法 | 路径 | 说明 | +|------|------|------| +| POST | `/api/templates` | 创建模板 | +| GET | `/api/templates` | 获取模板列表 | +| GET | `/api/templates/{id}` | 获取模板详情 | +| PATCH | `/api/templates/{id}` | 更新模板 | +| DELETE | `/api/templates/{id}` | 删除模板 | +| POST | `/api/templates/{id}/validate` | 验证模板(执行 EXPLAIN) | + +#### 3.1.4 业务规则 + +1. 模板名称必填 +2. 必须选择至少一个导出字段 +3. 删除模板时,若有关联的导出任务则执行软删除(标记 enabled=0) +4. 模板验证时执行 EXPLAIN 分析,评分低于 60 分禁止导出 + +--- + +### 3.2 数据导出任务 + +#### 3.2.1 功能描述 + +导出任务基于模板执行实际的数据导出操作,支持异步执行、进度跟踪和文件下载。 + +#### 3.2.2 任务属性 + +| 字段 | 类型 | 说明 | +|------|------|------| +| id | uint64 | 任务唯一标识 | +| template_id | uint64 | 关联模板 ID | +| status | string | 状态:`queued`/`running`/`completed`/`failed`/`canceled` | +| requested_by | uint64 | 请求者 ID | +| permission_scope_json | JSON | 权限范围 | +| options_json | JSON | 任务选项 | +| row_estimate | int64 | 预估行数 | +| total_rows | int64 | 实际行数 | +| file_format | string | 文件格式 | +| started_at | datetime | 开始时间 | +| finished_at | datetime | 完成时间 | + +#### 3.2.3 接口列表 + +| 方法 | 路径 | 说明 | +|------|------|------| +| POST | `/api/exports` | 创建导出任务 | +| GET | `/api/exports` | 获取任务列表(分页) | +| GET | `/api/exports/{id}` | 获取任务详情 | +| GET | `/api/exports/{id}/sql` | 获取任务 SQL | +| GET | `/api/exports/{id}/download` | 下载导出文件 | +| POST | `/api/exports/{id}/cancel` | 取消任务 | +| POST | `/api/exports/{id}/recompute` | 重新计算行数 | + +#### 3.2.4 导出流程 + +``` +1. 创建导出任务 + │ + ▼ +2. 解析模板配置 + │ + ▼ +3. 合并过滤条件 + │ + ▼ +4. 构建 SQL 查询 + │ + ▼ +5. 执行 EXPLAIN 分析 + │ + ├── 评分 < 60 → 拒绝执行 + │ + ▼ +6. 估算数据行数 + │ + ▼ +7. 创建任务记录 + │ + ▼ +8. 异步执行导出 + │ + ├── CSV 格式:分片写入,每文件最多 30 万行 + │ + ├── XLSX 格式:流式写入,每文件最多 30 万行 + │ + ▼ +9. 生成 ZIP 压缩包(多文件时) + │ + ▼ +10. 更新任务状态为完成 +``` + +#### 3.2.5 业务规则 + +1. **时间过滤必填**:营销系统订单导出必须提供 `create_time_between` 过滤条件 +2. **EXPLAIN 评分阈值**:评分低于 60 分的查询禁止执行 +3. **文件分片**:单文件最大行数为 30 万行,超过自动分片 +4. **进度更新**:CSV 每 1000 行更新一次进度,XLSX 每 200 行更新一次 +5. **分块导出**:大数据量导出按 10 天为周期分块查询 + +--- + +### 3.3 数据源与字段 + +#### 3.3.1 支持的数据源 + +| 数据源 | 标识 | 说明 | +|--------|------|------| +| 营销系统 | `marketing` | 营销系统订单数据 | +| 易码通 | `ymt` | 易码通订单数据 | + +#### 3.3.2 订单类型 + +**营销系统订单类型:** + +| 类型值 | 说明 | +|--------|------| +| 1 | 直充卡密 | +| 2 | 立减金 | +| 3 | 红包 | + +**易码通订单类型:** + +| 类型值 | 说明 | +|--------|------| +| 1 | 红包订单 | +| 2 | 直充卡密订单 | +| 3 | 立减金订单 | + +#### 3.3.3 可导出表 + +**营销系统可导出表:** + +| 表名 | 中文名 | 说明 | +|------|--------|------| +| order | 订单主表 | 核心订单数据 | +| order_detail | 订单详情 | 订单扩展信息 | +| order_cash | 红包订单 | 红包类型订单明细 | +| order_voucher | 立减金订单 | 立减金类型订单明细 | +| plan | 活动计划 | 营销活动计划 | +| key_batch | KEY 批次 | KEY 码批次信息 | +| code_batch | 兑换码批次 | 兑换码批次信息 | +| voucher | 立减金 | 立减金信息 | +| voucher_batch | 立减金批次 | 立减金批次信息 | +| merchant_key_send | 开放平台发放记录 | 开放平台 KEY 发放记录 | + +**易码通可导出表:** + +| 表名 | 中文名 | 说明 | +|------|--------|------| +| order_info | 订单主表 | 核心订单数据 | +| order_cash | 红包订单 | 红包类型订单明细 | +| order_voucher | 立减金订单 | 立减金类型订单明细 | +| order_digit | 直充卡密订单 | 直充卡密订单明细 | +| merchant | 客户 | 客户信息 | +| activity | 活动 | 活动信息 | +| goods_voucher_batch | 立减金批次表 | 立减金批次配置 | +| goods_voucher_subject_config | 立减金主体配置 | 立减金主体配置 | + +--- + +### 3.4 过滤条件 + +#### 3.4.1 通用过滤条件 + +| 过滤键 | 说明 | 适用数据源 | +|--------|------|------------| +| creator_in | 创建者 ID 列表 | 全部 | +| create_time_between | 创建时间范围(必填) | 全部 | +| type_eq | 订单类型 | 全部 | +| out_trade_no_eq | 支付流水号 | 全部 | +| account_eq | 账号 | 全部 | +| plan_id_eq | 计划/活动 ID | 全部 | +| product_id_eq | 商品 ID | 全部 | +| reseller_id_eq | 分销商/客户 ID | 全部 | + +#### 3.4.2 营销系统特有过滤 + +| 过滤键 | 说明 | +|--------|------| +| key_batch_id_eq | KEY 批次 ID | +| code_batch_id_eq | 兑换码批次 ID | +| order_cash_cash_activity_id_eq | 红包批次 ID | +| order_voucher_channel_activity_id_eq | 立减金渠道批次 ID | +| voucher_batch_channel_activity_id_eq | 立减金批次渠道批次 ID | +| merchant_out_biz_no_eq | 商户业务号 | + +#### 3.4.3 易码通特有过滤 + +| 过滤键 | 说明 | +|--------|------| +| merchant_id_in | 客户 ID 列表 | +| order_voucher_channel_activity_id_eq | 立减金渠道批次号 | + +--- + +### 3.5 字段处理与转换 + +#### 3.5.1 枚举值转换 + +系统自动将数据库中的枚举值转换为中文标签: + +**订单状态(营销系统):** + +| 值 | 标签 | +|----|------| +| 0 | 待充值 | +| 1 | 充值中 | +| 2 | 已完成 | +| 3 | 充值失败 | +| 4 | 已取消 | +| 5 | 已过期 | +| 6 | 待支付 | + +**订单状态(易码通):** + +| 值 | 标签 | +|----|------| +| 1 | 待充值 | +| 2 | 充值中 | +| 3 | 充值成功 | +| 4 | 充值失败 | +| 5 | 已过期 | +| 6 | 已作废 | +| 7 | 已核销 | +| 8 | 核销失败 | +| 9 | 订单重置 | +| 10 | 卡单 | + +**支付状态(营销系统):** + +| 值 | 标签 | +|----|------| +| 1 | 待支付 | +| 2 | 已支付 | +| 3 | 已退款 | + +**支付状态(易码通):** + +| 值 | 标签 | +|----|------| +| 1 | 待支付 | +| 2 | 支付中 | +| 3 | 已支付 | +| 4 | 取消支付 | +| 5 | 退款中 | +| 6 | 退款成功 | + +#### 3.5.2 特殊字段处理 + +1. **KEY 解密** + - 易码通:使用 SM4 算法解密 + - 营销系统:使用 Base58 解码 + +2. **卡密脱敏** + - 营销系统卡密字段自动脱敏:前 6 位 + `****` + 后 4 位 + +3. **支付渠道解析** + - 活动渠道字段(JSON 数组)自动解析为渠道名称列表 + +--- + +### 3.6 辅助查询接口 + +#### 3.6.1 营销系统辅助接口 + +| 方法 | 路径 | 说明 | +|------|------|------| +| GET | `/api/creators` | 获取创建者列表 | +| GET | `/api/resellers` | 获取分销商列表 | +| GET | `/api/plans` | 获取活动计划列表 | +| GET | `/api/fields` | 获取可用字段列表 | +| GET | `/api/metadata/fields` | 获取字段元数据(含中文标签) | + +#### 3.6.2 易码通辅助接口 + +| 方法 | 路径 | 说明 | +|------|------|------| +| GET | `/api/ymt/users` | 获取用户列表 | +| GET | `/api/ymt/merchants` | 获取客户列表 | +| GET | `/api/ymt/activities` | 获取活动列表 | + +#### 3.6.3 工具接口 + +| 方法 | 路径 | 说明 | +|------|------|------| +| GET | `/api/utils/decode_key` | 解密 KEY 码 | + +--- + +## 4. 前端功能 + +### 4.1 模板管理页面 + +#### 4.1.1 功能列表 + +- 模板列表展示(支持分页) +- 创建新模板 +- 编辑已有模板 +- 删除模板 +- 查看模板执行历史 + +#### 4.1.2 模板创建/编辑 + +**表单字段:** + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| 模板名称 | 文本 | 是 | 模板显示名称 | +| 数据源 | 下拉 | 是 | 营销系统/易码通 | +| 订单类型 | 下拉 | 是 | 直充卡密/立减金/红包 | +| 导出字段 | 树形选择 | 是 | 支持多级表关联选择 | +| 输出格式 | 下拉 | 是 | XLSX/CSV | +| 可见性 | 下拉 | 是 | 个人/公共 | + +### 4.2 导出执行页面 + +#### 4.2.1 功能列表 + +- 选择模板执行导出 +- 配置过滤条件 +- 查看导出任务列表 +- 实时进度跟踪 +- 下载导出文件 +- 查看执行 SQL + +#### 4.2.2 过滤条件表单 + +**通用过滤:** + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| 时间范围 | 日期范围 | 是 | 创建时间过滤 | + +**营销系统过滤:** + +| 字段 | 类型 | 说明 | +|------|------|------| +| 创建者 | 多选 | 可选多个创建者 | +| 分销商 | 下拉 | 依赖创建者选择 | +| 活动计划 | 下拉 | 依赖分销商选择 | +| 立减金批次 | 文本 | 立减金订单可用 | + +**易码通过滤:** + +| 字段 | 类型 | 说明 | +|------|------|------| +| 创建者 | 下拉 | 单选 | +| 客户 | 下拉 | 依赖创建者选择 | +| 活动 | 下拉 | 依赖客户选择 | + +### 4.3 任务状态展示 + +| 状态 | 显示 | 说明 | +|------|------|------| +| queued | 排队中 | 任务等待执行 | +| running | 进行中(显示百分比) | 正在导出数据 | +| completed | 已完成 | 可下载文件 | +| failed | 失败 | 导出失败 | +| canceled | 已取消 | 用户取消 | + +--- + +## 5. 安全与权限 + +### 5.1 数据权限 + +1. **用户隔离**:通过 URL 参数 `userId` 标识当前用户 +2. **模板权限**: + - 私有模板:仅创建者可见 + - 公共模板:所有用户可见 +3. **数据过滤**:导出时自动注入 `creator_in` 过滤条件 + +### 5.2 接口安全 + +1. **访问控制中间件**:支持配置 IP 白名单和请求头验证 +2. **请求追踪**:每个请求生成唯一 `trace_id` 便于问题排查 + +### 5.3 数据脱敏 + +1. 卡密字段自动脱敏处理 +2. KEY 码加密存储,导出时解密 + +--- + +## 6. 性能优化 + +### 6.1 SQL 优化 + +1. **EXPLAIN 预检**:执行前分析 SQL 执行计划 +2. **评分机制**:基于执行计划评估查询效率 +3. **索引建议**:提供优化建议 + +### 6.2 导出优化 + +1. **分块查询**:大时间范围按 10 天分块 +2. **流式写入**:避免内存溢出 +3. **游标分页**:基于主键游标分批读取 +4. **自适应批次**:根据数据量动态调整批次大小 + +| 估算行数 | 批次大小 (CSV) | +|----------|----------------| +| < 50,000 | 10,000 | +| < 200,000 | 20,000 | +| < 500,000 | 50,000 | +| ≥ 2,000,000 | 100,000 | + +### 6.3 文件存储 + +1. **本地存储**:文件保存在 `storage/` 目录 +2. **自动压缩**:多文件自动打包为 ZIP +3. **文件命名**:`export_job_{id}_{timestamp}.{ext}` + +--- + +## 7. 部署配置 + +### 7.1 配置文件 + +配置文件路径:`server/config.yaml` + +```yaml +app: + port: "8077" + marketing_db: + host: "localhost" + port: "3306" + user: "root" + password: "" + name: "marketing" + ymt_db: + host: "localhost" + port: "3306" + user: "root" + password: "" + name: "ymt" + ymt_test_db: + host: "localhost" + port: "3306" + user: "root" + password: "" + name: "meta" +``` + +### 7.2 环境变量 + +支持通过环境变量覆盖配置: + +| 变量名 | 说明 | +|--------|------| +| MARKETING_DB_HOST | 营销系统数据库主机 | +| MARKETING_DB_PORT | 营销系统数据库端口 | +| MARKETING_DB_USER | 营销系统数据库用户 | +| MARKETING_DB_PASSWORD | 营销系统数据库密码 | +| MARKETING_DB_NAME | 营销系统数据库名 | +| YMT_DB_HOST | 易码通数据库主机 | +| YMT_DB_PORT | 易码通数据库端口 | +| YMT_DB_USER | 易码通数据库用户 | +| YMT_DB_PASSWORD | 易码通数据库密码 | +| YMT_DB_NAME | 易码通数据库名 | +| YMT_TEST_DB_HOST | 元数据库主机 | +| YMT_TEST_DB_PORT | 元数据库端口 | +| YMT_TEST_DB_USER | 元数据库用户 | +| YMT_TEST_DB_PASSWORD | 元数据库密码 | +| YMT_TEST_DB_NAME | 元数据库名 | +| YMT_KEY_DECRYPT_KEY_B64 | SM4 解密密钥(Base64) | + +### 7.3 数据库连接池 + +支持通过环境变量配置连接池: + +| 变量名前缀 | 说明 | +|------------|------| +| YMT_DB_ | 易码通数据库连接池 | +| MARKETING_DB_ | 营销系统数据库连接池 | +| YMT_TEST_DB_ | 元数据库连接池 | + +--- + +## 8. 字段清单 + +### 8.1 订单主表字段 + +| 字段标识 | 中文名 | +|----------|--------| +| order.order_number | 订单编号 | +| order.key | KEY | +| order.creator | 创建者ID | +| order.out_trade_no | 支付流水号 | +| order.type | 订单类型 | +| order.status | 订单状态 | +| order.account | 账号 | +| order.product_id | 商品ID | +| order.reseller_id | 分销商ID | +| order.plan_id | 计划ID | +| order.pay_type | 支付方式 | +| order.pay_status | 支付状态 | +| order.contract_price | 合同单价 | +| order.num | 数量 | +| order.total | 总金额 | +| order.pay_amount | 支付金额 | +| order.create_time | 创建时间 | +| order.update_time | 更新时间 | +| order.official_price | 官方价 | +| order.merchant_name | 客户名称 | +| order.activity_name | 活动名称 | +| order.goods_name | 商品名称 | +| order.pay_time | 支付时间 | +| order.card_code | 卡密(脱敏) | +| order.supplier_name | 供应商名称 | +| order.cost_price | 成本价 | +| order.is_inner | 供应商类型 | +| order.recharge_suc_time | 充值成功时间 | + +### 8.2 红包订单字段 + +| 字段标识 | 中文名 | +|----------|--------| +| order_cash.order_no | 订单号 | +| order_cash.trade_no | 交易号 | +| order_cash.channel | 渠道 | +| order_cash.denomination | 红包面额 | +| order_cash.account | 领取账号 | +| order_cash.receive_name | 真实姓名 | +| order_cash.cash_activity_id | 红包批次号 | +| order_cash.receive_status | 领取状态 | +| order_cash.receive_time | 拆红包时间 | +| order_cash.success_time | 成功时间 | +| order_cash.amount | 红包额度 | + +### 8.3 立减金订单字段 + +| 字段标识 | 中文名 | +|----------|--------| +| order_voucher.channel | 渠道 | +| order_voucher.channel_activity_id | 渠道立减金批次 | +| order_voucher.channel_voucher_id | 渠道立减金ID | +| order_voucher.status | 状态 | +| order_voucher.receive_mode | 领取方式 | +| order_voucher.grant_time | 领取时间 | +| order_voucher.usage_time | 核销时间 | +| order_voucher.refund_time | 退款时间 | +| order_voucher.overdue_time | 过期时间 | +| order_voucher.refund_amount | 退款金额 | +| order_voucher.official_price | 官方价 | +| order_voucher.account_no | 账户号 | + +### 8.4 直充卡密订单字段(易码通) + +| 字段标识 | 中文名 | +|----------|--------| +| order_digit.order_no | 订单号 | +| order_digit.card_no | 卡号 | +| order_digit.account | 充值账号 | +| order_digit.success_time | 到账时间 | +| order_digit.order_type | 商品类型 | +| order_digit.end_time | 卡密有效期 | +| order_digit.code | 验证码 | +| order_digit.sms_channel | 短信渠道 | + +### 8.5 客户/分销商字段 + +| 字段标识 | 中文名 | +|----------|--------| +| merchant.id | 客户ID | +| merchant.name | 客户名称 | +| merchant.merchant_no | 商户编码 | +| merchant.subject | 客户主体 | +| merchant.third_party | 供应商类型 | +| merchant.balance | 客户余额 | +| merchant.contact_name | 联系人名称 | +| merchant.contact_phone | 联系人电话 | + +### 8.6 活动字段 + +| 字段标识 | 中文名 | +|----------|--------| +| activity.id | 活动ID | +| activity.name | 活动名称 | +| activity.activity_no | 活动编号 | +| activity.status | 状态 | +| activity.settlement_type | 结算方式 | +| activity.begin_time | 开始时间 | +| activity.end_time | 结束时间 | +| activity.channels | 支付渠道 | +| activity.amount | 支付金额 | + +--- + +## 9. 附录 + +### 9.1 接口响应格式 + +**成功响应:** + +```json +{ + "code": 0, + "message": "ok", + "data": { ... } +} +``` + +**失败响应:** + +```json +{ + "code": 1, + "message": "错误信息", + "category": "错误分类" +} +``` + +### 9.2 文件存储结构 + +``` +storage/ +├── export_job_1_20241217100000.xlsx +├── export_job_2_20241217110000.csv +├── export_job_3_20241217120000.zip +│ ├── export_job_3_part1.xlsx +│ └── export_job_3_part2.xlsx +└── ... +``` + +### 9.3 日志格式 + +系统采用 JSON 格式日志,存储在 `log/` 目录: + +```json +{ + "level": "INFO", + "event": "export_sql", + "datasource": "marketing", + "main_table": "order", + "file_format": "xlsx", + "sql": "SELECT ...", + "args": [...], + "timestamp": "2024-12-17T10:00:00Z" +} +```