This commit is contained in:
2026-06-30 10:33:56 +08:00
commit 6e047dc0a5
607 changed files with 65966 additions and 0 deletions
@@ -0,0 +1,4 @@
export interface IDeliveryProvider {
scheduleAutoAdvance(orderId: bigint): Promise<void>;
advanceTo(orderId: bigint, targetStatus: string): Promise<void>;
}
@@ -0,0 +1,37 @@
import { Injectable } from '@nestjs/common';
import { InjectQueue } from '@nestjs/bullmq';
import { Queue } from 'bullmq';
import { loadAppConfig } from '@dukang/shared-types';
import { IDeliveryProvider } from './delivery.interface';
import { DELIVERY_QUEUE } from '../../jobs/jobs.constants';
@Injectable()
export class DeliveryMockProvider implements IDeliveryProvider {
private readonly config = loadAppConfig();
constructor(@InjectQueue(DELIVERY_QUEUE) private readonly queue: Queue) {}
async scheduleAutoAdvance(orderId: bigint): Promise<void> {
if (!this.config.mockDeliveryAuto) return;
const steps = [
{ delay: 0, status: 'OUT_WAREHOUSE' },
{ delay: 10000, status: 'SHIPPING' },
{ delay: 30000, status: 'PENDING_RECEIVE' },
{ delay: 60000, status: 'COMPLETED' },
];
for (const step of steps) {
await this.queue.add(
'advance-status',
{ orderId: orderId.toString(), targetStatus: step.status },
{ delay: step.delay, jobId: `${orderId}-${step.status}` },
);
}
}
async advanceTo(orderId: bigint, targetStatus: string): Promise<void> {
await this.queue.add('advance-status', {
orderId: orderId.toString(),
targetStatus,
});
}
}
@@ -0,0 +1,3 @@
export const SMS_PROVIDER = 'SMS_PROVIDER';
export const PAY_PROVIDER = 'PAY_PROVIDER';
export const DELIVERY_PROVIDER = 'DELIVERY_PROVIDER';
@@ -0,0 +1,21 @@
import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bullmq';
import { SmsMockProvider } from './sms/sms.mock.provider';
import { PayMockProvider } from './pay/pay.mock.provider';
import { DeliveryMockProvider } from './delivery/delivery.mock.provider';
import { SMS_PROVIDER, PAY_PROVIDER, DELIVERY_PROVIDER } from './integrations.constants';
import { DELIVERY_QUEUE } from '../jobs/jobs.constants';
@Module({
imports: [BullModule.registerQueue({ name: DELIVERY_QUEUE })],
providers: [
{ provide: SMS_PROVIDER, useClass: SmsMockProvider },
{ provide: PAY_PROVIDER, useClass: PayMockProvider },
{ provide: DELIVERY_PROVIDER, useClass: DeliveryMockProvider },
SmsMockProvider,
PayMockProvider,
DeliveryMockProvider,
],
exports: [SMS_PROVIDER, PAY_PROVIDER, DELIVERY_PROVIDER],
})
export class IntegrationsModule {}
@@ -0,0 +1,3 @@
export interface IPayProvider {
payOrder(orderId: bigint): Promise<{ externalNo: string }>;
}
@@ -0,0 +1,15 @@
import { Injectable } from '@nestjs/common';
import { loadAppConfig } from '@dukang/shared-types';
import { IPayProvider } from './pay.interface';
@Injectable()
export class PayMockProvider implements IPayProvider {
private readonly config = loadAppConfig();
async payOrder(_orderId: bigint): Promise<{ externalNo: string }> {
if (!this.config.mockPay) {
throw new Error('Real WeChat pay not implemented in preV1');
}
return { externalNo: `MOCK-${Date.now()}` };
}
}
@@ -0,0 +1,4 @@
export interface ISmsProvider {
send(phone: string, scene: string): Promise<void>;
verify(phone: string, code: string, scene: string): Promise<void>;
}
@@ -0,0 +1,21 @@
import { Injectable } from '@nestjs/common';
import { loadAppConfig } from '@dukang/shared-types';
import { ISmsProvider } from './sms.interface';
@Injectable()
export class SmsMockProvider implements ISmsProvider {
private readonly config = loadAppConfig();
async send(_phone: string, _scene: string): Promise<void> {
if (!this.config.mockSms) {
throw new Error('Real SMS not implemented in preV1');
}
}
async verify(phone: string, code: string, _scene: string): Promise<void> {
if (this.config.mockSms && code === this.config.mockSmsCode) {
return;
}
throw new Error(`Invalid verification code for ${phone}`);
}
}