@@ -6,6 +6,7 @@ import { SettlementModule } from '../modules/settlement/settlement.module';
|
||||
import { DeliveryProcessor } from './delivery.processor';
|
||||
import { SettlementScheduler } from './settlement.scheduler';
|
||||
import { MonitorScheduler } from './monitor.scheduler';
|
||||
import { OrderExpiryScheduler } from './order-expiry.scheduler';
|
||||
import { DELIVERY_QUEUE } from './jobs.constants';
|
||||
|
||||
@Module({
|
||||
@@ -15,6 +16,6 @@ import { DELIVERY_QUEUE } from './jobs.constants';
|
||||
TradeModule,
|
||||
SettlementModule,
|
||||
],
|
||||
providers: [DeliveryProcessor, SettlementScheduler, MonitorScheduler],
|
||||
providers: [DeliveryProcessor, SettlementScheduler, MonitorScheduler, OrderExpiryScheduler],
|
||||
})
|
||||
export class JobsModule {}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { Cron } from '@nestjs/schedule';
|
||||
import { TradeService } from '../modules/trade/trade.service';
|
||||
import { AlertService } from '../common/alert/alert.service';
|
||||
|
||||
/**
|
||||
* v3.5.1 #8:订单 30 分钟未支付自动取消。
|
||||
* 每分钟扫描一次:将 status=PENDING_PAY 且 payExpireAt 已过期且非测试订单 翻为 CANCELLED。
|
||||
* 下单时 trade.service 已写入 payExpireAt = now+30min,无需新增字段。
|
||||
*/
|
||||
@Injectable()
|
||||
export class OrderExpiryScheduler {
|
||||
private readonly logger = new Logger(OrderExpiryScheduler.name);
|
||||
|
||||
constructor(
|
||||
private readonly trade: TradeService,
|
||||
private readonly alert: AlertService,
|
||||
) {}
|
||||
|
||||
@Cron('*/1 * * * *', { timeZone: 'Asia/Shanghai' })
|
||||
async handleExpiredPendingOrders() {
|
||||
try {
|
||||
const n = await this.trade.cancelExpiredPendingOrders(200);
|
||||
if (n > 0) this.logger.log(`Auto-cancelled ${n} expired pending orders`);
|
||||
} catch (e) {
|
||||
this.logger.error('Order expiry job failed', e instanceof Error ? e.stack : e);
|
||||
this.alert.notify({
|
||||
level: 'P1',
|
||||
category: 'job',
|
||||
title: '订单自动取消任务失败',
|
||||
detail: e instanceof Error ? e.message : String(e),
|
||||
dedupeKey: `job_order_expiry_fail|${new Date().toISOString().slice(0, 10)}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user