Files
junhong_cmp_fiber/docs/fix-agent-wallet-order-creation/部署指南.md
huang 8ed3d9da93
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m0s
feat: 实现代理钱包订单创建和订单角色追踪功能
新增功能:
- 代理在后台使用 wallet 支付时,订单直接完成(扣款 + 激活套餐)
- 支持代理自购和代理代购场景
- 新增订单角色追踪字段(operator_id、operator_type、actual_paid_amount、purchase_role)
- 订单查询支持 OR 逻辑(buyer_id 或 operator_id)
- 钱包流水记录交易子类型和关联店铺
- 佣金逻辑调整:代理代购不产生佣金

数据库变更:
- 订单表新增 4 个字段和 2 个索引
- 钱包流水表新增 2 个字段
- 包含迁移脚本和回滚脚本

文档:
- 功能总结文档
- 部署指南
- OpenAPI 文档更新
- Specs 同步(新增 agent-order-role-tracking capability)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-28 14:11:42 +08:00

539 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 代理钱包订单创建功能部署指南
## 部署前检查清单
### 代码检查
- [x] 编译通过:`go build ./...`
- [x] OpenAPI 文档更新:`go run cmd/gendocs/main.go`
- [ ] 测试环境验证通过
- [ ] Code Review 通过
### 数据库准备
- [ ] 测试环境迁移脚本执行成功
- [ ] 生产环境数据库备份完成
- [ ] 回滚脚本准备完毕
---
## 数据库迁移
### 迁移脚本清单
**脚本位置**`migrations/`
| 序号 | 文件名 | 说明 | 执行时间 |
|------|--------|------|----------|
| 000067 | `add_operator_fields_to_orders.up.sql` | 订单表新增字段和索引 | < 5 秒 |
| 000068 | `add_transaction_subtype_to_wallet_transaction.up.sql` | 钱包流水表新增字段 | < 1 秒 |
**回滚脚本**
| 序号 | 文件名 | 说明 |
|------|--------|------|
| 000067 | `add_operator_fields_to_orders.down.sql` | 删除订单表字段和索引 |
| 000068 | `add_transaction_subtype_to_wallet_transaction.down.sql` | 删除钱包流水表字段 |
---
### 迁移执行步骤
#### 步骤 1备份数据库
```bash
# 生产环境数据库备份
pg_dump -h <host> -U <user> -d junhong_cmp -F c -b -v -f "backup_$(date +%Y%m%d_%H%M%S).dump"
```
**验证备份**
```bash
pg_restore --list backup_*.dump | head -20
```
---
#### 步骤 2执行迁移测试环境
**使用 migrate 工具**
```bash
# 切换到项目目录
cd /path/to/junhong_cmp_fiber
# 执行迁移
migrate -path migrations -database "postgresql://<user>:<password>@<host>:<port>/junhong_cmp?sslmode=disable" up
# 验证迁移版本
migrate -path migrations -database "postgresql://<user>:<password>@<host>:<port>/junhong_cmp?sslmode=disable" version
```
**手动执行(可选)**
```bash
# 连接数据库
psql -h <host> -U <user> -d junhong_cmp
# 执行迁移脚本
\i migrations/000067_add_operator_fields_to_orders.up.sql
\i migrations/000068_add_transaction_subtype_to_wallet_transaction.up.sql
```
---
#### 步骤 3验证迁移结果
**检查字段**
```sql
-- 验证订单表字段
\d tb_order
-- 预期输出包含:
-- operator_id | integer | | |
-- operator_type | character varying(20) | | |
-- actual_paid_amount | bigint | | |
-- purchase_role | character varying(50) | | |
```
**检查索引**
```sql
-- 验证索引
SELECT indexname, indexdef
FROM pg_indexes
WHERE tablename = 'tb_order'
AND indexname IN ('idx_orders_operator_id', 'idx_orders_purchase_role');
-- 预期输出:
-- idx_orders_operator_id | CREATE INDEX idx_orders_operator_id ON public.tb_order USING btree (operator_id)
-- idx_orders_purchase_role | CREATE INDEX idx_orders_purchase_role ON public.tb_order USING btree (purchase_role)
```
**检查钱包流水表**
```sql
-- 验证钱包流水表字段
\d tb_agent_wallet_transaction
-- 预期输出包含:
-- transaction_subtype | character varying(50) | | |
-- related_shop_id | integer | | |
```
---
#### 步骤 4数据回填可选
**回填历史订单**
```bash
psql -h <host> -U <user> -d junhong_cmp -f migrations/backfill_order_purchase_role.sql
```
**验证回填结果**
```sql
SELECT purchase_role, operator_type, COUNT(*) as count
FROM tb_order
WHERE purchase_role IS NOT NULL
GROUP BY purchase_role, operator_type;
-- 预期输出示例:
-- purchased_by_platform | platform | 1234
```
---
#### 步骤 5执行迁移生产环境
**时间窗口**:选择低峰期(凌晨 2:00 - 4:00
**执行命令**(与测试环境相同):
```bash
migrate -path migrations -database "postgresql://<prod_host>:<prod_port>/<db>?sslmode=require" up
```
**监控指标**
- 迁移执行时间
- 索引创建时间CONCURRENTLY不锁表
- 数据库连接数
- 慢查询日志
---
### 回滚步骤
**场景**:迁移失败或发现严重 Bug
#### 步骤 1停止应用
```bash
# 停止应用服务
systemctl stop junhong-cmp-api
```
#### 步骤 2执行回滚
```bash
# 回滚到上一版本
migrate -path migrations -database "postgresql://<host>:<port>/<db>?sslmode=disable" down 2
```
**或手动执行回滚脚本**
```bash
psql -h <host> -U <user> -d junhong_cmp <<EOF
\i migrations/000068_add_transaction_subtype_to_wallet_transaction.down.sql
\i migrations/000067_add_operator_fields_to_orders.down.sql
EOF
```
#### 步骤 3验证回滚
```sql
-- 验证字段已删除
\d tb_order
\d tb_agent_wallet_transaction
-- 验证索引已删除
SELECT indexname FROM pg_indexes WHERE tablename = 'tb_order';
```
#### 步骤 4恢复应用旧版本代码
```bash
# 回滚代码到上一版本
git checkout <previous_commit>
# 重新编译
go build -o api cmd/api/main.go
# 启动应用
systemctl start junhong-cmp-api
```
---
## 代码部署
### 灰度发布计划
**阶段 1灰度服务器10% 流量)**
**时间**:低峰期(周一至周五 02:00 - 04:00
**步骤**
1. 部署代码到灰度服务器
2. 切换 10% 流量到灰度服务器
3. 观察 2 小时,监控关键指标
4. 手工测试代理自购、代理代购场景
**验证项**
- [ ] 应用启动成功
- [ ] 健康检查通过:`curl http://localhost:8080/health`
- [ ] 订单创建成功率 > 95%
- [ ] 钱包扣款成功率 > 99%
- [ ] 无严重错误日志
---
**阶段 2全量发布100% 流量)**
**时间**:灰度验证通过后 24 小时
**步骤**
1. 部署代码到所有服务器
2. 逐步切换流量20% → 50% → 100%
3. 持续监控 24 小时
**验证项**
- [ ] 所有服务器应用启动成功
- [ ] 订单创建成功率 > 95%
- [ ] 钱包扣款成功率 > 99%
- [ ] 错误日志无异常峰值
- [ ] 用户反馈无异常
---
### 发布命令
**构建**
```bash
# 构建二进制文件
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o api cmd/api/main.go
# 验证版本
./api --version
```
**部署**
```bash
# 停止服务
systemctl stop junhong-cmp-api
# 备份旧版本
cp /opt/junhong-cmp/api /opt/junhong-cmp/api.backup
# 替换新版本
cp api /opt/junhong-cmp/api
# 启动服务
systemctl start junhong-cmp-api
# 检查状态
systemctl status junhong-cmp-api
```
**验证**
```bash
# 健康检查
curl http://localhost:8080/health
# 查看日志
journalctl -u junhong-cmp-api -f
```
---
## 监控指标
### 关键业务指标
**订单创建**
- 订单创建成功率(总体)
- 订单创建成功率(按 payment_method 分组)
- 订单创建耗时P50、P95、P99
- 订单创建 QPS
**钱包扣款**
- 钱包扣款成功率
- 钱包扣款失败原因分布(余额不足、并发冲突、其他)
- 钱包余额不足次数
**订单查询**
- 订单列表查询耗时P95
- OR 查询性能(慢查询日志)
---
### 错误日志监控
**关键错误**
```bash
# 余额不足
grep "余额不足" /var/log/junhong-cmp/app.log | wc -l
# 并发冲突
grep "并发冲突" /var/log/junhong-cmp/app.log | wc -l
# 套餐激活失败
grep "套餐激活失败" /var/log/junhong-cmp/app.log | wc -l
# 成本价查询失败
grep "店铺没有该套餐的分配配置" /var/log/junhong-cmp/app.log | wc -l
```
---
### 数据库性能监控
**慢查询**
```sql
-- 查看慢查询
SELECT query, calls, total_time, mean_time
FROM pg_stat_statements
WHERE query LIKE '%tb_order%'
AND mean_time > 100
ORDER BY mean_time DESC
LIMIT 10;
```
**索引使用率**
```sql
-- 检查新索引是否被使用
SELECT schemaname, tablename, indexname, idx_scan, idx_tup_read, idx_tup_fetch
FROM pg_stat_user_indexes
WHERE indexname IN ('idx_orders_operator_id', 'idx_orders_purchase_role');
```
**OR 查询性能**
```sql
-- EXPLAIN 分析
EXPLAIN ANALYZE
SELECT * FROM tb_order
WHERE (buyer_type = 'agent' AND buyer_id = 10) OR operator_id = 10
LIMIT 20;
```
---
### 告警规则
**业务告警**
| 指标 | 阈值 | 级别 |
|------|------|------|
| 订单创建成功率 | < 95% | P1 |
| 钱包扣款成功率 | < 99% | P1 |
| 订单创建耗时 P99 | > 1000ms | P2 |
| 并发冲突次数 | > 100/分钟 | P2 |
| 余额不足次数 | > 500/小时 | P3 |
**系统告警**
| 指标 | 阈值 | 级别 |
|------|------|------|
| 应用进程退出 | - | P0 |
| 数据库连接数 | > 80% | P1 |
| 慢查询(订单相关) | > 1000ms | P2 |
---
## 验证测试
### 功能验证清单
**代理自购**
- [ ] 创建订单成功
- [ ] 钱包余额正确扣减
- [ ] 订单状态为已支付
- [ ] 套餐已激活
- [ ] 钱包流水记录正确transaction_subtype = "self_purchase"
- [ ] 订单响应字段完整operator_id、purchase_role 等)
**代理代购**
- [ ] 创建订单成功
- [ ] 钱包余额按操作者成本价扣减
- [ ] 订单金额显示买家成本价
- [ ] actual_paid_amount 为操作者成本价
- [ ] 套餐已激活
- [ ] 钱包流水记录正确transaction_subtype = "purchase_for_subordinate"、related_shop_id、remark 包含店铺名称)
- [ ] 未产生佣金记录
**平台代购**
- [ ] 创建订单成功
- [ ] 钱包余额未扣减
- [ ] 订单状态为已支付
- [ ] 套餐已激活
- [ ] 产生佣金记录
- [ ] purchase_role = "purchased_by_platform"
**订单查询**
- [ ] 代理可查询作为买家或操作者的订单
- [ ] purchase_role 筛选生效
- [ ] 订单列表响应包含新字段
**边界场景**
- [ ] 余额不足时返回明确错误
- [ ] 并发扣款时乐观锁生效
- [ ] 幂等性检查防止重复创建
- [ ] H5 端 wallet 订单不受影响(仍为待支付)
---
### 性能验证
**压力测试**(可选):
```bash
# 订单创建并发测试
ab -n 1000 -c 50 -H "Authorization: Bearer <token>" \
-p order_request.json \
-T "application/json" \
http://localhost:8080/api/admin/orders
# 订单列表查询性能测试
ab -n 5000 -c 100 -H "Authorization: Bearer <token>" \
http://localhost:8080/api/admin/orders?page=1&page_size=20
```
**预期结果**
- 订单创建 QPS > 50
- 订单创建 P95 < 200ms
- 订单列表查询 P95 < 100ms
---
## 回滚预案
### 回滚触发条件
满足以下任一条件时立即回滚:
- 订单创建成功率 < 90%(持续 5 分钟)
- 钱包扣款成功率 < 95%(持续 5 分钟)
- 发现严重 Bug重复扣款、金额计算错误、数据丢失
- 用户投诉量激增
---
### 快速回滚步骤
**步骤 1立即回滚代码**< 5 分钟)
```bash
# 停止服务
systemctl stop junhong-cmp-api
# 恢复旧版本
cp /opt/junhong-cmp/api.backup /opt/junhong-cmp/api
# 启动服务
systemctl start junhong-cmp-api
```
**步骤 2回滚数据库**(可选,< 10 分钟)
仅当数据异常时执行:
```bash
# 执行回滚脚本
migrate -path migrations -database "..." down 2
```
**步骤 3验证回滚成功**
- [ ] 应用启动成功
- [ ] 健康检查通过
- [ ] 订单创建成功率恢复
- [ ] 用户反馈恢复正常
---
## 上线后观察
### 观察期7 天)
**每日检查**
- [ ] 订单创建成功率
- [ ] 钱包扣款成功率
- [ ] 错误日志无异常
- [ ] 用户反馈无异常
- [ ] 数据库慢查询无新增
**周报总结**
- 订单创建总量、成功率
- 钱包扣款总量、成功率
- 代理自购 vs 代理代购占比
- 错误类型分布
- 性能指标趋势
---
## 联系人
**技术负责人**[姓名]
**运维负责人**[姓名]
**产品负责人**[姓名]
**紧急联系方式**
- 技术值班电话:[电话]
- 运维值班电话:[电话]
---
## 附录
### 相关文档
- [功能总结](./功能总结.md)
- [提案文档](../../openspec/changes/fix-agent-wallet-order-creation/proposal.md)
- [设计文档](../../openspec/changes/fix-agent-wallet-order-creation/design.md)
- [任务清单](../../openspec/changes/fix-agent-wallet-order-creation/tasks.md)
### 迁移脚本内容
详见 `migrations/` 目录:
- `000067_add_operator_fields_to_orders.up.sql`
- `000067_add_operator_fields_to_orders.down.sql`
- `000068_add_transaction_subtype_to_wallet_transaction.up.sql`
- `000068_add_transaction_subtype_to_wallet_transaction.down.sql`
- `backfill_order_purchase_role.sql`