63 lines
1.9 KiB
Go
63 lines
1.9 KiB
Go
package jobs
|
||
|
||
import (
|
||
"context"
|
||
"time"
|
||
|
||
jobs_args "quyun/v2/app/jobs/args"
|
||
"quyun/v2/app/services"
|
||
|
||
. "github.com/riverqueue/river"
|
||
log "github.com/sirupsen/logrus"
|
||
)
|
||
|
||
var _ Worker[jobs_args.OrderRefundJob] = (*OrderRefundJobWorker)(nil)
|
||
|
||
// OrderRefundJobWorker 负责执行订单退款的异步处理。
|
||
//
|
||
// @provider(job)
|
||
type OrderRefundJobWorker struct {
|
||
WorkerDefaults[jobs_args.OrderRefundJob]
|
||
}
|
||
|
||
func (w *OrderRefundJobWorker) Work(ctx context.Context, job *Job[jobs_args.OrderRefundJob]) error {
|
||
args := job.Args
|
||
|
||
logger := log.WithFields(log.Fields{
|
||
"job_kind": args.Kind(),
|
||
"tenant_id": args.TenantID,
|
||
"order_id": args.OrderID,
|
||
"operator_user_id": args.OperatorUserID,
|
||
"force": args.Force,
|
||
"attempt": job.Attempt,
|
||
})
|
||
|
||
// 只允许在异步 worker 层做执行,不要在这里再次入队其他任务(避免耦合与递归依赖)。
|
||
logger.Info("jobs.order_refund.start")
|
||
|
||
_, err := services.Order.ProcessRefundingOrder(ctx, &services.ProcessRefundingOrderParams{
|
||
TenantID: args.TenantID,
|
||
OrderID: args.OrderID,
|
||
OperatorUserID: args.OperatorUserID,
|
||
Force: args.Force,
|
||
Reason: args.Reason,
|
||
Now: time.Now().UTC(),
|
||
})
|
||
if err != nil {
|
||
// 业务层会返回可识别的“不可重试”错误:由它内部完成状态落库(failed)后,这里直接 cancel。
|
||
if services.IsRefundJobNonRetryableError(err) {
|
||
// best-effort:将订单标记为 failed,便于管理员重新发起退款(paid/failed -> refunding)。
|
||
if markErr := services.Order.MarkRefundFailed(ctx, args.TenantID, args.OrderID, time.Now().UTC()); markErr != nil {
|
||
logger.WithError(markErr).Warn("jobs.order_refund.mark_failed_failed")
|
||
}
|
||
logger.WithError(err).Warn("jobs.order_refund.cancel")
|
||
return JobCancel(err)
|
||
}
|
||
logger.WithError(err).Warn("jobs.order_refund.retry")
|
||
return err
|
||
}
|
||
|
||
logger.Info("jobs.order_refund.ok")
|
||
return nil
|
||
}
|