Files
makemd/server/src/services/DisputeResolverService.ts

99 lines
3.2 KiB
TypeScript
Raw Normal View History

import { logger } from '../utils/logger';
import db from '../config/database';
export interface DisputeEvent {
tenantId: string;
orderId: string;
externalDisputeId: string;
reason: string;
customerMessage: string;
evidenceUrls: string[];
}
/**
* [BIZ_AUTO_05] AI
* @description 退
*/
export class DisputeResolverService {
private static readonly DISPUTE_TABLE = 'cf_disputes';
/**
*
*/
static async initTable(): Promise<void> {
const hasTable = await db.schema.hasTable(this.DISPUTE_TABLE);
if (!hasTable) {
console.log(`📦 Creating ${this.DISPUTE_TABLE} table...`);
await db.schema.createTable(this.DISPUTE_TABLE, (table) => {
table.increments('id').primary();
table.string('tenant_id', 64).notNullable();
table.string('order_id', 64).notNullable();
table.string('external_dispute_id', 128).unique();
table.string('reason', 255);
table.string('status', 32).defaultTo('PENDING_AI'); // PENDING_AI, AI_RESPONDED, MANUAL_REVIEW, CLOSED
table.text('ai_response');
table.timestamps(true, true);
table.index(['tenant_id', 'status']);
});
console.log(`✅ Table ${this.DISPUTE_TABLE} created`);
}
}
/**
* (BIZ_AUTO_05)
*/
static async processDispute(event: DisputeEvent): Promise<void> {
logger.info(`[DisputeResolver] Processing dispute ${event.externalDisputeId} for Order: ${event.orderId}`);
// 1. 记录争议
await db(this.DISPUTE_TABLE).insert({
tenant_id: event.tenantId,
order_id: event.orderId,
external_dispute_id: event.externalDisputeId,
reason: event.reason,
status: 'PENDING_AI',
created_at: new Date(),
updated_at: new Date()
});
// 2. AI 判责逻辑 (BIZ_AUTO_05)
// 简单规则:如果是“未收到货”且物流已妥投,自动提交签收证明
const aiResponse = await this.analyzeAndRespond(event);
// 3. 更新状态
await db(this.DISPUTE_TABLE).where({ external_dispute_id: event.externalDisputeId }).update({
ai_response: aiResponse,
status: 'AI_RESPONDED',
updated_at: new Date()
});
}
/**
* [BIZ_AI_16-EXT] ( AGI )
*/
static async initiateDispute(tenantId: string, orderId: string, reason: string): Promise<string> {
const externalDisputeId = `EXT-DISP-${Date.now()}`;
logger.info(`[DisputeResolver] Initiating dispute for Order: ${orderId}, Reason: ${reason}`);
await db(this.DISPUTE_TABLE).insert({
tenant_id: tenantId,
order_id: orderId,
external_dispute_id: externalDisputeId,
reason: reason,
status: 'PENDING_AI',
created_at: new Date(),
updated_at: new Date()
});
return externalDisputeId;
}
private static async analyzeAndRespond(event: DisputeEvent): Promise<string> {
// 模拟 AI 分析
if (event.reason.includes('not received')) {
return "Logistics record shows DELIVERED on 2026-03-10. Attaching delivery proof.";
}
return "Product matches description. Customer provided no clear evidence of defect. Requesting more details.";
}
}