完善退款审批材料与恢复流程
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m35s

This commit is contained in:
2026-09-20 17:59:52 +08:00
parent 4a6cec2730
commit b063617153
29 changed files with 1119 additions and 156 deletions

View File

@@ -30,6 +30,17 @@
业务以本地审批实例和企业微信审批单号去重,终态只推进一次;`errcode/errmsg` 保存到集成日志并映射项目错误,不能直接暴露凭证或底层报文。
## 退款审批模板上线前置
退款审批场景上线前,维护者 MUST 在当前企业微信模板中完成并核对以下控件映射:
- 固定必需:退款方式中文名称(单行文本),用于展示“原路退款”“客户收款信息退款”“退回资产钱包”“退回代理主钱包”。
- 条件必需:客户收款信息(多行文本)与客户收款凭证(附件)。仅当本次审批尝试冻结的退款方式为 `customer_account` 时,二者必须同时配置且本次值非空;其他退款方式不要求、不提交空白占位材料。
保存场景时系统会校验固定退款方式映射,并校验已配置条件控件的业务字段与控件类型;提交时按不可变审批尝试快照再次校验。模板缺少客户收款条件控件时,客户收款退款会明确失败并指出缺失字段/控件,不会创建第二张审批单;修复映射后可通过 `POST /api/admin/refunds/{id}/recover-approval` 恢复原审批实例。已有 `sp_no` 只查询同步,结果未知只确认,明确提交失败且无 `sp_no` 才恢复原提交事件。
本次发布不执行真实企业微信或支付调用;上线验收需由维护者在指定测试企业覆盖四种退款方式、条件材料缺失、模板修复后的原实例恢复、结果未知与重复/并发恢复,并核对审批尝试数、实例数和业务资金事实不变。
## 安全与验证
Secret、access_token、回调 AES Key、成员敏感字段、审批正文与附件 URL 必须脱敏。可信 IP、应用可见范围、模板、回调 URL 和素材权限属于部署侧人工配置。

View File

@@ -4647,8 +4647,7 @@
"operations-report::每日报表快照与不回填历史"
],
"classification": "behavior"
}
,
},
{
"entry_type": "cli",
"entry": "docs/deployment/production-runbook.md",
@@ -4657,5 +4656,33 @@
"asset-device::存量当前卡标识的核对与受控修复"
],
"classification": "behavior"
},
{
"entry_type": "http",
"entry": "POST /api/admin/refunds/{id}/recover-approval",
"capability": "order-refund-exchange",
"requirements": [
"identity-access::数据范围拒绝",
"order-refund-exchange::退款原审批实例可受控恢复"
],
"classification": "behavior"
},
{
"entry_type": "async",
"entry": "constants.OutboxEventTypeApprovalManualSyncRequested",
"capability": "order-refund-exchange",
"requirements": [
"order-refund-exchange::退款原审批实例可受控恢复"
],
"classification": "route_index_or_infrastructure"
},
{
"entry_type": "async",
"entry": "constants.OutboxEventTypeApprovalUnknownRecoveryRequested",
"capability": "order-refund-exchange",
"requirements": [
"order-refund-exchange::退款原审批实例可受控恢复"
],
"classification": "route_index_or_infrastructure"
}
]

View File

@@ -5652,8 +5652,7 @@
],
"exit_status": 0
}
}
,
},
{
"capability": "asset-device",
"requirement": "单槽单卡设备绑定时初始化当前卡标识",
@@ -5741,5 +5740,45 @@
],
"exit_status": 0
}
},
{
"capability": "order-refund-exchange",
"requirement": "退款原审批实例可受控恢复",
"spec": "openspec/specs/order-refund-exchange/spec.md",
"entries": [
"POST /api/admin/refunds/{id}/recover-approval",
"GET /api/admin/refunds",
"GET /api/admin/refunds/{id}",
"constants.OutboxEventTypeApprovalManualSyncRequested",
"constants.OutboxEventTypeApprovalUnknownRecoveryRequested"
],
"handler_consumer_job": [
"internal/routes/refund.go",
"internal/handler/admin/refund.go",
"cmd/worker/main.go",
"internal/infrastructure/wecom/manual_sync_consumer.go",
"internal/infrastructure/wecom/unknown_recovery_consumer.go"
],
"application_service_query": [
"internal/application/refundapproval/recovery.go",
"internal/infrastructure/approval/recovery.go",
"internal/service/refund/service.go"
],
"domain_state_amount": [
"internal/model/refund.go",
"internal/model/wecom_approval_context.go",
"internal/model/approval_instance.go"
],
"store_migration_config": [
"internal/model/outbox_event.go",
"migrations/000189_add_wecom_approval_recovery_timestamps.up.sql"
],
"verification": {
"command": "gofmt -w internal/application/refundapproval/recovery.go internal/infrastructure/approval/recovery.go internal/infrastructure/wecom/manual_sync_consumer.go internal/infrastructure/wecom/unknown_recovery_consumer.go internal/service/refund/service.go cmd/worker/main.go && git diff --check && GOMODCACHE=/tmp/junhong-go-mod-cache GOCACHE=/tmp/junhong-go-build-cache go build ./cmd/api ./cmd/worker",
"literal_output": [
"gofmt completed; git diff --check completed; go build ./cmd/api ./cmd/worker completed"
],
"exit_status": 0
}
}
]