package employeecollection import ( "context" "time" approvalapp "github.com/break/junhong_cmp_fiber/internal/application/approval" "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" ) // applicationSubmissionRow 是核销申请最新审批实例的提交事实。 type applicationSubmissionRow struct { InstanceID uint `gorm:"column:instance_id"` InstanceStatus int `gorm:"column:instance_status"` SubmissionStatus int `gorm:"column:submission_status"` LastError string `gorm:"column:last_error"` LastRecoveryAt *time.Time `gorm:"column:last_recovery_at"` } // fillApplicationSubmission 按最新审批实例一次批量读取企微审批上下文,填充提交状态、脱敏摘要、可恢复与最近恢复时间。 // 无审批实例或无企微上下文的申请保持零值。 func (q *ApplicationQuery) fillApplicationSubmission(ctx context.Context, responses []*dto.EmployeeCollectionApplicationResponse) error { instanceIDs := make([]uint, 0, len(responses)) for _, response := range responses { if response != nil && response.LatestApprovalInstanceID != 0 { instanceIDs = append(instanceIDs, response.LatestApprovalInstanceID) } } if len(instanceIDs) == 0 { return nil } var rows []applicationSubmissionRow if err := q.db.WithContext(ctx).Raw( `SELECT ai.id AS instance_id, ai.status AS instance_status, COALESCE(wc.submission_status, 0) AS submission_status, COALESCE(wc.last_error, '') AS last_error, wc.last_recovery_at FROM tb_approval_instance ai LEFT JOIN tb_wecom_approval_context wc ON wc.approval_instance_id = ai.id WHERE ai.id IN ?`, instanceIDs).Scan(&rows).Error; err != nil { return errors.Wrap(errors.CodeDatabaseError, err, "批量查询核销申请审批提交状态失败") } byInstance := make(map[uint]applicationSubmissionRow, len(rows)) for _, row := range rows { byInstance[row.InstanceID] = row } for _, response := range responses { if response == nil { continue } row, ok := byInstance[response.LatestApprovalInstanceID] if !ok { continue } response.ApprovalSubmissionStatus = row.SubmissionStatus response.ApprovalSubmissionName = constants.GetWeComSubmissionStatusName(row.SubmissionStatus) if row.SubmissionStatus == constants.WeComSubmissionStatusFailed { response.ApprovalFailureSummary = approvalapp.SubmissionFailureReason(row.LastError) } // 提交失败为终态不可恢复;只有审批中的申请且实例仍在提交中、审批中或结果未知时可恢复。 response.Recoverable = response.Status == constants.EmployeeCollectionApplicationStatusPending && (row.InstanceStatus == constants.ApprovalStatusSubmitting || row.InstanceStatus == constants.ApprovalStatusPending || row.InstanceStatus == constants.ApprovalStatusSubmissionUnknown) if row.LastRecoveryAt != nil { response.LastRecoveryAt = row.LastRecoveryAt.UTC().Format(time.RFC3339) } } return nil }