Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
- 新增六对成对迁移 000232–000237:H5 弹窗类型、退款结算标识与申请人备注、优先轮询事实字段与两个新终态、通道阈值命中留痕、手机号最近解绑人、提现资格校验留痕 - 退款:原因必填与申请人备注、来源支付与渠道流水冻结、线下处理流水号补录审计、按订单查询可选退款方式、企微审批材料补齐且新增字段缺失映射即明确失败 - 优先轮询:人工关闭、有效期到期独立周期任务、失败与过期人工重触发、事实字段与异常重试查询、资产解析端点只读投影 - 通道阈值:命中事实同事务留痕与命中记录查询;员工账单:列表筛选与详情投影;商户池:列表投影与统计周期语义;H5:弹窗类型与类别排序 - 手机号:有效关联数量与最近解绑人、短信验证码失败次数限制;导出:佣金明细十五列与报表序号列 - 时间筛选:三处新增筛选纳入统一严格解析契约,员工账单产生时间参数改名 - 同步 12 份主 Spec 需求、两端点与异步任务证据链,门禁 context-health 与 OpenSpec 校验通过
89 lines
3.3 KiB
Go
89 lines
3.3 KiB
Go
package refund
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/break/junhong_cmp_fiber/internal/model"
|
|
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
|
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
|
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
|
)
|
|
|
|
// loadAttemptResponses 批量读取退款申请的审批尝试历史,并补齐每次尝试的审批实例状态。
|
|
//
|
|
// 尝试记录按提交次序升序返回,历史材料与审批结果不被覆盖;未接入尝试模式的存量申请返回空切片。
|
|
func (s *Service) loadAttemptResponses(ctx context.Context, refunds []*model.RefundRequest) (map[uint][]dto.RefundAttemptResponse, error) {
|
|
result := make(map[uint][]dto.RefundAttemptResponse, len(refunds))
|
|
refundIDs := make([]uint, 0, len(refunds))
|
|
for _, refund := range refunds {
|
|
if refund == nil || refund.ID == 0 {
|
|
continue
|
|
}
|
|
refundIDs = append(refundIDs, refund.ID)
|
|
result[refund.ID] = []dto.RefundAttemptResponse{}
|
|
}
|
|
if len(refundIDs) == 0 {
|
|
return result, nil
|
|
}
|
|
|
|
var attempts []model.RefundRequestAttempt
|
|
if err := s.db.WithContext(ctx).
|
|
Where("refund_id IN ?", refundIDs).
|
|
Order("refund_id ASC, attempt_no ASC, id ASC").
|
|
Find(&attempts).Error; err != nil {
|
|
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询退款审批尝试记录失败")
|
|
}
|
|
if len(attempts) == 0 {
|
|
return result, nil
|
|
}
|
|
|
|
instanceIDs := make([]uint, 0, len(attempts))
|
|
for index := range attempts {
|
|
if attempts[index].ApprovalInstanceID != nil && *attempts[index].ApprovalInstanceID > 0 {
|
|
instanceIDs = append(instanceIDs, *attempts[index].ApprovalInstanceID)
|
|
}
|
|
}
|
|
statuses := map[uint]int{}
|
|
if len(instanceIDs) > 0 {
|
|
var instances []model.ApprovalInstance
|
|
if err := s.db.WithContext(ctx).Select("id", "status").Where("id IN ?", instanceIDs).Find(&instances).Error; err != nil {
|
|
return nil, errors.Wrap(errors.CodeDatabaseError, err, "批量查询退款审批尝试实例状态失败")
|
|
}
|
|
for _, instance := range instances {
|
|
statuses[instance.ID] = instance.Status
|
|
}
|
|
}
|
|
|
|
for index := range attempts {
|
|
attempt := &attempts[index]
|
|
item := dto.RefundAttemptResponse{
|
|
ID: attempt.ID,
|
|
AttemptNo: attempt.AttemptNo,
|
|
Method: attempt.Method,
|
|
MethodName: constants.RefundMethodName(attempt.Method),
|
|
RefundAmount: attempt.RefundAmount,
|
|
FrozenActualReceivedAmount: attempt.FrozenActualReceivedAmount,
|
|
RefundReason: attempt.RefundReason,
|
|
Remark: attempt.Remark,
|
|
CustomerAccountInfo: attempt.CustomerAccountInfo,
|
|
CustomerVoucherKey: []string(attempt.CustomerVoucherKeys),
|
|
ChannelRefundRequestNo: attempt.ChannelRefundRequestNo,
|
|
SubmittedByAccountID: attempt.SubmittedByAccountID,
|
|
CreatedAt: attempt.CreatedAt.Format("2006-01-02 15:04:05"),
|
|
}
|
|
if len(item.CustomerVoucherKey) == 0 {
|
|
item.CustomerVoucherKey = []string{}
|
|
}
|
|
if attempt.ApprovalInstanceID != nil && *attempt.ApprovalInstanceID > 0 {
|
|
item.ApprovalInstanceID = *attempt.ApprovalInstanceID
|
|
if status, exists := statuses[*attempt.ApprovalInstanceID]; exists {
|
|
value := status
|
|
item.ApprovalStatus = &value
|
|
item.ApprovalStatusName = constants.GetApprovalStatusName(status)
|
|
}
|
|
}
|
|
result[attempt.RefundID] = append(result[attempt.RefundID], item)
|
|
}
|
|
return result, nil
|
|
}
|