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

12 KiB
Raw Blame History

代理钱包订单创建功能部署指南

部署前检查清单

代码检查

  • 编译通过:go build ./...
  • 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备份数据库

# 生产环境数据库备份
pg_dump -h <host> -U <user> -d junhong_cmp -F c -b -v -f "backup_$(date +%Y%m%d_%H%M%S).dump"

验证备份

pg_restore --list backup_*.dump | head -20

步骤 2执行迁移测试环境

使用 migrate 工具

# 切换到项目目录
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

手动执行(可选)

# 连接数据库
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验证迁移结果

检查字段

-- 验证订单表字段
\d tb_order

-- 预期输出包含:
-- operator_id           | integer                  |           |          |
-- operator_type         | character varying(20)    |           |          |
-- actual_paid_amount    | bigint                   |           |          |
-- purchase_role         | character varying(50)    |           |          |

检查索引

-- 验证索引
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)

检查钱包流水表

-- 验证钱包流水表字段
\d tb_agent_wallet_transaction

-- 预期输出包含:
-- transaction_subtype   | character varying(50)    |           |          |
-- related_shop_id       | integer                  |           |          |

步骤 4数据回填可选

回填历史订单

psql -h <host> -U <user> -d junhong_cmp -f migrations/backfill_order_purchase_role.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

执行命令(与测试环境相同):

migrate -path migrations -database "postgresql://<prod_host>:<prod_port>/<db>?sslmode=require" up

监控指标

  • 迁移执行时间
  • 索引创建时间CONCURRENTLY不锁表
  • 数据库连接数
  • 慢查询日志

回滚步骤

场景:迁移失败或发现严重 Bug

步骤 1停止应用

# 停止应用服务
systemctl stop junhong-cmp-api

步骤 2执行回滚

# 回滚到上一版本
migrate -path migrations -database "postgresql://<host>:<port>/<db>?sslmode=disable" down 2

或手动执行回滚脚本

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验证回滚

-- 验证字段已删除
\d tb_order
\d tb_agent_wallet_transaction

-- 验证索引已删除
SELECT indexname FROM pg_indexes WHERE tablename = 'tb_order';

步骤 4恢复应用旧版本代码

# 回滚代码到上一版本
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%
  • 错误日志无异常峰值
  • 用户反馈无异常

发布命令

构建

# 构建二进制文件
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o api cmd/api/main.go

# 验证版本
./api --version

部署

# 停止服务
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

验证

# 健康检查
curl http://localhost:8080/health

# 查看日志
journalctl -u junhong-cmp-api -f

监控指标

关键业务指标

订单创建

  • 订单创建成功率(总体)
  • 订单创建成功率(按 payment_method 分组)
  • 订单创建耗时P50、P95、P99
  • 订单创建 QPS

钱包扣款

  • 钱包扣款成功率
  • 钱包扣款失败原因分布(余额不足、并发冲突、其他)
  • 钱包余额不足次数

订单查询

  • 订单列表查询耗时P95
  • OR 查询性能(慢查询日志)

错误日志监控

关键错误

# 余额不足
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

数据库性能监控

慢查询

-- 查看慢查询
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;

索引使用率

-- 检查新索引是否被使用
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 查询性能

-- 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 订单不受影响(仍为待支付)

性能验证

压力测试(可选):

# 订单创建并发测试
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 分钟)

# 停止服务
systemctl stop junhong-cmp-api

# 恢复旧版本
cp /opt/junhong-cmp/api.backup /opt/junhong-cmp/api

# 启动服务
systemctl start junhong-cmp-api

步骤 2回滚数据库(可选,< 10 分钟)

仅当数据异常时执行:

# 执行回滚脚本
migrate -path migrations -database "..." down 2

步骤 3验证回滚成功

  • 应用启动成功
  • 健康检查通过
  • 订单创建成功率恢复
  • 用户反馈恢复正常

上线后观察

观察期7 天)

每日检查

  • 订单创建成功率
  • 钱包扣款成功率
  • 错误日志无异常
  • 用户反馈无异常
  • 数据库慢查询无新增

周报总结

  • 订单创建总量、成功率
  • 钱包扣款总量、成功率
  • 代理自购 vs 代理代购占比
  • 错误类型分布
  • 性能指标趋势

联系人

技术负责人[姓名] 运维负责人[姓名] 产品负责人[姓名]

紧急联系方式

  • 技术值班电话:[电话]
  • 运维值班电话:[电话]

附录

相关文档

迁移脚本内容

详见 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