Files
junhong_cmp_fiber/internal/application/approval/submission_failure.go
邹进 6298a9061f fix: 第1批 M8、M13、M14 审批提交失败终态与退款关闭类终态定位
- 审批核心在实例进入提交失败的同一事务内写 submission_failed 决策投递与终态事件,消费入口单独放行
- 核销(4)、退款(7)、扫码注册(3)、资料资格(4)、线下充值(7)、佣金提现(5)新增“审批提交失败”终态并释放预占/冻结
- 三处恢复入口不再重放提交失败;退款关闭类终态按审批尝试定位退款单(M13)
- 核销列表与详情批量返回审批提交状态;筛选、字段说明、状态名称、退款导出加入新状态
- 迁移 000239 放宽五张业务表状态约束与决策投递取值约束(测试库已执行 up/down/up)
- OpenSpec Change fix-approval-submission-failure-terminal:18/26,测试部署后端到端验证与存量补数据待完成
2026-10-12 00:03:46 +09:00

45 lines
1.7 KiB
Go
Raw Permalink 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.
package approval
import (
"context"
"strings"
"gorm.io/gorm"
"github.com/break/junhong_cmp_fiber/pkg/constants"
"github.com/break/junhong_cmp_fiber/pkg/errors"
)
// ConfirmSubmissionFailed 在业务消费事务内锁定审批实例并确认其仍为“提交失败”,返回可对外展示的失败原因。
// 实例已不是提交失败(例如被恢复重放)时 ok 为 false,业务消费者应不改变业务单。
// 原因只返回固定白名单文案,禁止透传企微原文或内部错误。
func ConfirmSubmissionFailed(ctx context.Context, tx *gorm.DB, instanceID uint) (string, bool, error) {
var row struct {
Status int `gorm:"column:status"`
LastError string `gorm:"column:last_error"`
}
result := tx.WithContext(ctx).Raw(
`SELECT ai.status, COALESCE(wc.last_error, '') AS last_error
FROM tb_approval_instance ai
LEFT JOIN tb_wecom_approval_context wc ON wc.approval_instance_id = ai.id
WHERE ai.id = ? FOR UPDATE OF ai`, instanceID).Scan(&row)
if result.Error != nil {
return "", false, errors.Wrap(errors.CodeDatabaseError, result.Error, "锁定提交失败审批实例失败")
}
if result.RowsAffected == 0 {
return "", false, errors.New(errors.CodeNotFound, "审批实例不存在")
}
if row.Status != constants.ApprovalStatusSubmissionFailed {
return "", false, nil
}
return SubmissionFailureReason(row.LastError), true, nil
}
// SubmissionFailureReason 把企微提交失败原文转换为稳定白名单文案。
func SubmissionFailureReason(lastError string) string {
if strings.TrimSpace(lastError) == "" {
return constants.ApprovalSubmissionFailedStatusName
}
return constants.ApprovalSubmissionFailedReason
}