完善退款审批材料与恢复流程
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:
@@ -5,6 +5,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/bytedance/sonic"
|
||||
"github.com/hibiken/asynq"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||||
@@ -25,12 +26,21 @@ func NewApprovalRecoveryTaskHandler(contexts *ApprovalContextRepository, infos *
|
||||
return &ApprovalRecoveryTaskHandler{contexts: contexts, infos: infos, queue: queueClient, now: time.Now}
|
||||
}
|
||||
|
||||
// Handle 扫描未终态和结果未知记录;结果未知只查询关联,绝不重新调用 applyevent。
|
||||
func (h *ApprovalRecoveryTaskHandler) Handle(ctx context.Context, _ *asynq.Task) error {
|
||||
// Handle 支持全局扫描任务与按实例人工任务,二者共享同一 unknown 确认算法。
|
||||
func (h *ApprovalRecoveryTaskHandler) Handle(ctx context.Context, task *asynq.Task) error {
|
||||
if h == nil || h.contexts == nil || h.infos == nil || h.queue == nil {
|
||||
return errors.New(errors.CodeServiceUnavailable, "企业微信审批主动恢复任务未配置")
|
||||
}
|
||||
var payload struct {
|
||||
InstanceID uint `json:"instance_id"`
|
||||
}
|
||||
if task != nil && len(task.Payload()) > 0 {
|
||||
_ = sonic.Unmarshal(task.Payload(), &payload)
|
||||
}
|
||||
now := h.now().UTC()
|
||||
if payload.InstanceID > 0 {
|
||||
return h.recoverUnknownInstance(ctx, payload.InstanceID, now)
|
||||
}
|
||||
if err := h.contexts.PromoteStaleSendingToUnknown(ctx, now.Add(-constants.WeComApprovalSendingLease)); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -53,48 +63,58 @@ func (h *ApprovalRecoveryTaskHandler) enqueuePendingSync(ctx context.Context, no
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *ApprovalRecoveryTaskHandler) recoverUnknownInstance(ctx context.Context, instanceID uint, now time.Time) error {
|
||||
record, err := h.contexts.GetRecoveryRecord(ctx, instanceID)
|
||||
if err != nil || record == nil {
|
||||
return err
|
||||
}
|
||||
claimed, err := h.contexts.ClaimUnknownRecovery(ctx, instanceID, now.Add(-constants.WeComApprovalPollingInterval))
|
||||
if err != nil || !claimed {
|
||||
return err
|
||||
}
|
||||
return h.recoverUnknownRecord(ctx, *record, now)
|
||||
}
|
||||
|
||||
func (h *ApprovalRecoveryTaskHandler) recoverUnknownRecord(ctx context.Context, record ApprovalRecoveryRecord, now time.Time) error {
|
||||
spNo, submissionIntegrationID, err := h.contexts.FindSuccessfulSubmissionSPNo(ctx, record.InstanceID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
integrationIDs := []string{submissionIntegrationID}
|
||||
if spNo == "" {
|
||||
var ids []string
|
||||
spNo, ids, err = h.findUniqueSPNo(ctx, record, now)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
integrationIDs = append(integrationIDs, ids...)
|
||||
}
|
||||
if spNo == "" {
|
||||
return nil
|
||||
}
|
||||
recovered, err := h.contexts.RecoverSubmitted(ctx, record.InstanceID, spNo, integrationIDs, constants.AuditActorScheduledJob, constants.ApprovalAuditActorRecoveryJob, constants.AuditSourceScheduler)
|
||||
if err != nil || !recovered {
|
||||
return err
|
||||
}
|
||||
return h.enqueueDetailSync(ctx, record.ApplicationID, spNo)
|
||||
}
|
||||
|
||||
func (h *ApprovalRecoveryTaskHandler) recoverUnknown(ctx context.Context, now time.Time) error {
|
||||
cutoff := now.Add(-constants.WeComApprovalPollingInterval)
|
||||
records, err := h.contexts.ListUnknownRecovery(ctx, cutoff, constants.WeComApprovalUnknownRecoveryBatchSize)
|
||||
records, err := h.contexts.ListUnknownRecovery(ctx, now.Add(-constants.WeComApprovalPollingInterval), constants.WeComApprovalUnknownRecoveryBatchSize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, record := range records {
|
||||
claimed, err := h.contexts.ClaimUnknownRecovery(ctx, record.InstanceID, cutoff)
|
||||
claimed, err := h.contexts.ClaimUnknownRecovery(ctx, record.InstanceID, now.Add(-constants.WeComApprovalPollingInterval))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !claimed {
|
||||
continue
|
||||
}
|
||||
spNo, submissionIntegrationID, err := h.contexts.FindSuccessfulSubmissionSPNo(ctx, record.InstanceID)
|
||||
if err != nil {
|
||||
if err := h.recoverUnknownRecord(ctx, record, now); err != nil {
|
||||
return err
|
||||
}
|
||||
integrationIDs := []string{submissionIntegrationID}
|
||||
if spNo == "" {
|
||||
var recoveryIntegrationIDs []string
|
||||
spNo, recoveryIntegrationIDs, err = h.findUniqueSPNo(ctx, record, now)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
integrationIDs = append(integrationIDs, recoveryIntegrationIDs...)
|
||||
}
|
||||
if spNo == "" {
|
||||
continue
|
||||
}
|
||||
recovered, err := h.contexts.RecoverSubmitted(
|
||||
ctx, record.InstanceID, spNo, integrationIDs,
|
||||
constants.AuditActorScheduledJob, constants.ApprovalAuditActorRecoveryJob, constants.AuditSourceScheduler,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if recovered {
|
||||
if err := h.enqueueDetailSync(ctx, record.ApplicationID, spNo); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user