完善退款审批材料与恢复流程
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m35s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m35s
This commit is contained in:
@@ -161,8 +161,7 @@ func (s *CreationService) TriggerHistorical(ctx context.Context, refundID uint,
|
||||
if err := tx.WithContext(ctx).Create(attempt).Error; err != nil {
|
||||
return errors.Wrap(errors.CodeDatabaseError, err, "创建退款审批尝试记录失败")
|
||||
}
|
||||
|
||||
submitterSnapshot, requestSnapshot, err := refundSnapshots(¤t, account, "", material)
|
||||
submitterSnapshot, requestSnapshot, err := refundSnapshots(¤t, attempt, account, material)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -226,10 +225,7 @@ func (s *CreationService) Execute(ctx context.Context, command CreateCommand) (*
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
submitterSnapshot, requestSnapshot, err := refundSnapshots(command.Refund, account, command.ApplicantRemark, command.Material)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var submitterSnapshot, requestSnapshot []byte
|
||||
var approvalStatus int
|
||||
var attempt *model.RefundRequestAttempt
|
||||
err = s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
@@ -255,6 +251,10 @@ func (s *CreationService) Execute(ctx context.Context, command CreateCommand) (*
|
||||
if err := tx.WithContext(ctx).Create(attempt).Error; err != nil {
|
||||
return errors.Wrap(errors.CodeDatabaseError, err, "创建退款审批尝试记录失败")
|
||||
}
|
||||
submitterSnapshot, requestSnapshot, err = refundSnapshots(command.Refund, attempt, account, command.Material)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
reference, err := s.approval.CreateInTx(ctx, tx, approvalapp.CreateRequest{
|
||||
Preparation: preparation, BusinessType: constants.ApprovalBusinessTypeRefund,
|
||||
BusinessID: attempt.ID, SubmitterAccountID: command.SubmitterAccountID,
|
||||
@@ -359,7 +359,7 @@ func (s *CreationService) Resubmit(ctx context.Context, refundID uint, command R
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
submitterSnapshot, requestSnapshot, err := refundSnapshots(¤t, account, command.ApplicantRemark, command.Material)
|
||||
submitterSnapshot, requestSnapshot, err := refundSnapshots(¤t, attempt, account, command.Material)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -478,6 +478,7 @@ func buildAttempt(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
customerAccountInfo, customerVoucherKeys := refundCustomerMaterial(refund)
|
||||
return &model.RefundRequestAttempt{
|
||||
RefundID: refund.ID,
|
||||
AttemptNo: attemptNo,
|
||||
@@ -486,14 +487,22 @@ func buildAttempt(
|
||||
FrozenActualReceivedAmount: refund.FrozenActualReceivedAmount,
|
||||
RefundReason: refund.RefundReason,
|
||||
Remark: strings.TrimSpace(applicantRemark),
|
||||
CustomerAccountInfo: refund.CustomerAccountInfo,
|
||||
CustomerVoucherKeys: refund.RefundVoucherKey,
|
||||
CustomerAccountInfo: customerAccountInfo,
|
||||
CustomerVoucherKeys: customerVoucherKeys,
|
||||
PackageUsageSnapshot: snapshot,
|
||||
ChannelRefundRequestNo: strings.TrimSpace(channelRefundRequestNo),
|
||||
SubmittedByAccountID: refund.Creator,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// refundCustomerMaterial 只为客户收款信息退款冻结客户收款材料;其它退款方式保持空材料,避免伪造占位内容。
|
||||
func refundCustomerMaterial(refund *model.RefundRequest) (string, model.StringJSONBArray) {
|
||||
if refund == nil || refund.Method != constants.RefundMethodCustomerAccount {
|
||||
return "", model.StringJSONBArray{}
|
||||
}
|
||||
return strings.TrimSpace(refund.CustomerAccountInfo), append(model.StringJSONBArray(nil), refund.RefundVoucherKey...)
|
||||
}
|
||||
|
||||
// nextAttemptNo 返回该退款申请的下一条审批尝试序号;退款申请行已加锁,序号在同一事务内唯一。
|
||||
func nextAttemptNo(ctx context.Context, tx *gorm.DB, refundID uint) (int, error) {
|
||||
var row struct {
|
||||
@@ -593,36 +602,28 @@ func updateRefundLatest(ctx context.Context, tx *gorm.DB, refund *model.RefundRe
|
||||
return nil
|
||||
}
|
||||
|
||||
// refundSnapshots 冻结提交人与审批业务快照。
|
||||
// 审批业务快照是企微表单构建的数据源,因此本变更新增的审批材料字段必须在此出现,
|
||||
// 且即使不可解析也要以空值或零值写入:控件映射已配置时缺失键会被表单构建明确拒绝。
|
||||
func refundSnapshots(refund *model.RefundRequest, account *model.Account, applicantRemark string, material RefundMaterial) ([]byte, []byte, error) {
|
||||
submitterSnapshot, err := sonic.Marshal(map[string]any{
|
||||
"account_id": account.ID, "account_name": account.Username, "user_type": account.UserType,
|
||||
})
|
||||
// refundSnapshots 冻结提交人与审批业务快照,业务可变字段全部取不可变审批尝试。
|
||||
func refundSnapshots(refund *model.RefundRequest, attempt *model.RefundRequestAttempt, account *model.Account, material RefundMaterial) ([]byte, []byte, error) {
|
||||
if refund == nil || attempt == nil || account == nil {
|
||||
return nil, nil, errors.New(errors.CodeInvalidParam, "退款审批快照参数不完整")
|
||||
}
|
||||
submitterSnapshot, err := sonic.Marshal(map[string]any{"account_id": account.ID, "account_name": account.Username, "user_type": account.UserType})
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(errors.CodeInternalError, err, "编码退款提交人快照失败")
|
||||
}
|
||||
customerAccountInfo, customerVoucherKeys := refundCustomerMaterialFromAttempt(attempt)
|
||||
requestSnapshot, err := sonic.Marshal(map[string]any{
|
||||
constants.ApprovalFieldRefundNo: refund.RefundNo,
|
||||
constants.ApprovalFieldOrderID: refund.OrderID,
|
||||
constants.ApprovalFieldOrderNo: refund.OrderNo,
|
||||
constants.ApprovalFieldAssetIdentifier: refund.AssetIdentifier,
|
||||
constants.ApprovalFieldAssetType: refund.OrderType,
|
||||
constants.ApprovalFieldActualReceivedAmount: formatCentAmount(refund.FrozenActualReceivedAmount),
|
||||
constants.ApprovalFieldRequestedRefundAmount: formatCentAmount(refund.RequestedRefundAmount),
|
||||
constants.ApprovalFieldRefundVoucherKey: []string(refund.RefundVoucherKey),
|
||||
constants.ApprovalFieldRefundReason: refund.RefundReason,
|
||||
constants.ApprovalFieldPackageUsageID: refund.PackageUsageID,
|
||||
constants.ApprovalFieldRefundAssetType: material.AssetType,
|
||||
constants.ApprovalFieldRefundDeviceType: material.DeviceType,
|
||||
constants.ApprovalFieldRefundDeviceModel: material.DeviceModel,
|
||||
constants.ApprovalFieldRefundPackageUsedMB: material.PackageUsedMB,
|
||||
constants.ApprovalFieldRefundPackageTotalMB: material.PackageTotalMB,
|
||||
constants.ApprovalFieldRefundChannelTradeNo: material.OriginalChannelTradeNo,
|
||||
constants.ApprovalFieldRefundApplicantRemark: strings.TrimSpace(applicantRemark),
|
||||
constants.ApprovalFieldSubmitterID: account.ID,
|
||||
constants.ApprovalFieldSubmitterName: account.Username,
|
||||
constants.ApprovalFieldRefundNo: refund.RefundNo, constants.ApprovalFieldOrderID: refund.OrderID, constants.ApprovalFieldOrderNo: refund.OrderNo,
|
||||
constants.ApprovalFieldAssetIdentifier: refund.AssetIdentifier, constants.ApprovalFieldAssetType: refund.OrderType,
|
||||
constants.ApprovalFieldActualReceivedAmount: formatCentAmount(attempt.FrozenActualReceivedAmount), constants.ApprovalFieldRequestedRefundAmount: formatCentAmount(attempt.RefundAmount),
|
||||
constants.ApprovalFieldRefundVoucherKey: []string(attempt.CustomerVoucherKeys), constants.ApprovalFieldRefundReason: attempt.RefundReason,
|
||||
constants.ApprovalFieldPackageUsageID: refund.PackageUsageID, constants.ApprovalFieldRefundAssetType: material.AssetType,
|
||||
constants.ApprovalFieldRefundDeviceType: material.DeviceType, constants.ApprovalFieldRefundDeviceModel: material.DeviceModel,
|
||||
constants.ApprovalFieldRefundPackageUsedMB: material.PackageUsedMB, constants.ApprovalFieldRefundPackageTotalMB: material.PackageTotalMB,
|
||||
constants.ApprovalFieldRefundChannelTradeNo: material.OriginalChannelTradeNo, constants.ApprovalFieldRefundApplicantRemark: attempt.Remark,
|
||||
constants.ApprovalFieldRefundMethodCode: attempt.Method, constants.ApprovalFieldRefundMethod: constants.RefundMethodName(attempt.Method),
|
||||
constants.ApprovalFieldCustomerAccountInfo: customerAccountInfo, constants.ApprovalFieldCustomerVoucherKey: []string(customerVoucherKeys),
|
||||
constants.ApprovalFieldSubmitterID: account.ID, constants.ApprovalFieldSubmitterName: account.Username,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(errors.CodeInternalError, err, "编码退款审批业务快照失败")
|
||||
@@ -630,6 +631,13 @@ func refundSnapshots(refund *model.RefundRequest, account *model.Account, applic
|
||||
return submitterSnapshot, requestSnapshot, nil
|
||||
}
|
||||
|
||||
func refundCustomerMaterialFromAttempt(attempt *model.RefundRequestAttempt) (string, model.StringJSONBArray) {
|
||||
if attempt == nil || attempt.Method != constants.RefundMethodCustomerAccount {
|
||||
return "", model.StringJSONBArray{}
|
||||
}
|
||||
return strings.TrimSpace(attempt.CustomerAccountInfo), append(model.StringJSONBArray(nil), attempt.CustomerVoucherKeys...)
|
||||
}
|
||||
|
||||
func formatCentAmount(amount int64) string {
|
||||
return fmt.Sprintf("%d.%02d", amount/100, amount%100)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user