You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
4.3 KiB
133 lines
4.3 KiB
/**
|
|
* 从 MotherShip dashboard 页面正文提取「官网业务拒价/阻断」文案,供前端如实展示。
|
|
* 非 RPA/系统错误,而是承运商或官网规则导致无法出价。
|
|
* 对外统一译为中文,避免英文原文直出给客户。
|
|
*/
|
|
|
|
const ACCESSORIAL_BLOCK_PATTERNS: RegExp[] = [
|
|
/不支持附加服务[^\n。]{0,160}/,
|
|
/(?:承运|运输)合作伙伴[^\n。]{0,80}不提供[^\n。]{0,120}/,
|
|
/住宅地址[^\n。]{0,80}上门取件[^\n。]{0,80}/,
|
|
/unsupported accessorial[^\n.]{0,200}/i,
|
|
/accessorial(?:s)?[^\n.]{0,120}(?:not supported|not available|cannot be)/i,
|
|
/our carrier partners? do not provide[^\n.]{0,220}/i,
|
|
/carrier partners? (?:don'?t|do not) provide[^\n.]{0,220}/i,
|
|
/(?:pickup|pick-up)[^\n.]{0,80}residential[^\n.]{0,120}/i,
|
|
/residential[^\n.]{0,80}(?:pickup|pick-up)[^\n.]{0,120}/i,
|
|
];
|
|
|
|
/** 官网英文阻断 → 中文(客户可见) */
|
|
const PORTAL_EN_TO_ZH: Array<[RegExp, string]> = [
|
|
[
|
|
/no rates found[\s\S]*please review all required fields to proceed/i,
|
|
"未找到可用报价。请检查并填写所有必填项后再继续",
|
|
],
|
|
[/no rates found/i, "未找到可用报价"],
|
|
[
|
|
/please review all required fields to proceed/i,
|
|
"请检查并填写所有必填项后再继续",
|
|
],
|
|
[/unsupported accessorial/i, "不支持该附加服务"],
|
|
[
|
|
/our carrier partners? do not provide[^\n.]*/i,
|
|
"承运合作伙伴不提供此项服务",
|
|
],
|
|
[
|
|
/carrier partners? (?:don'?t|do not) provide[^\n.]*/i,
|
|
"承运合作伙伴不提供此项服务",
|
|
],
|
|
[
|
|
/(?:pickup|pick-up)[^\n.]{0,80}residential|residential[^\n.]{0,80}(?:pickup|pick-up)/i,
|
|
"不支持住宅地址上门取件",
|
|
],
|
|
[/accessorial(?:s)?[^\n.]{0,80}(?:not supported|not available)/i, "不支持该附加服务"],
|
|
];
|
|
|
|
function normalizePortalLine(line: string, keepNewlines = false): string {
|
|
if (keepNewlines) {
|
|
return line
|
|
.replace(/\r/g, "")
|
|
.replace(/[ \t]+/g, " ")
|
|
.replace(/\n+/g, "\n")
|
|
.trim();
|
|
}
|
|
return line.replace(/\s+/g, " ").trim();
|
|
}
|
|
|
|
/** 将单条官网提示译为中文;已是中文则原样返回 */
|
|
export function translatePortalMessageToZh(message: string): string {
|
|
const trimmed = message.trim();
|
|
if (!trimmed) return trimmed;
|
|
if (/[\u4e00-\u9fff]/.test(trimmed)) {
|
|
return trimmed;
|
|
}
|
|
for (const [pattern, zh] of PORTAL_EN_TO_ZH) {
|
|
if (pattern.test(trimmed)) {
|
|
return zh;
|
|
}
|
|
}
|
|
return "承运商官网提示:暂无法完成报价,请检查地址、货物或附加服务后重试";
|
|
}
|
|
|
|
/** 提取页面可见的官网阻断/无价提示(去重、保序) */
|
|
export function extractMothershipPortalQuoteMessages(body: string): string[] {
|
|
const text = body.replace(/\r/g, "");
|
|
const found: string[] = [];
|
|
const push = (msg: string, keepNewlines = false) => {
|
|
const n = normalizePortalLine(msg, keepNewlines);
|
|
if (n && !found.includes(n)) found.push(n);
|
|
};
|
|
const hasNoRates = /No rates found/i.test(text);
|
|
const hasRequired =
|
|
/Please review all required fields to proceed/i.test(text);
|
|
if (hasNoRates && hasRequired) {
|
|
push(
|
|
"No rates found\nPlease review all required fields to proceed",
|
|
true,
|
|
);
|
|
} else if (hasNoRates) {
|
|
push("No rates found");
|
|
} else if (hasRequired) {
|
|
push("Please review all required fields to proceed");
|
|
}
|
|
|
|
for (const p of ACCESSORIAL_BLOCK_PATTERNS) {
|
|
const m = text.match(p);
|
|
if (m?.[0]) push(m[0]);
|
|
}
|
|
|
|
return found;
|
|
}
|
|
|
|
/** 附加服务/承运商规则类阻断(应立刻如实返回,不等 patch/超时) */
|
|
export function extractMothershipAccessorialBlockMessages(
|
|
body: string,
|
|
): string[] {
|
|
const found: string[] = [];
|
|
const push = (msg: string) => {
|
|
const n = normalizePortalLine(msg);
|
|
if (n && !found.includes(n)) found.push(n);
|
|
};
|
|
for (const p of ACCESSORIAL_BLOCK_PATTERNS) {
|
|
const m = body.replace(/\r/g, "").match(p);
|
|
if (m?.[0]) push(m[0]);
|
|
}
|
|
return found;
|
|
}
|
|
|
|
export function formatMothershipPortalQuoteMessage(
|
|
messages: string[],
|
|
): string | null {
|
|
if (messages.length === 0) return null;
|
|
return messages.map(translatePortalMessageToZh).join("\n\n");
|
|
}
|
|
|
|
/** 从整页正文解析;无则 null */
|
|
export function parseMothershipPortalQuoteMessageFromBody(
|
|
body: string,
|
|
): string | null {
|
|
return formatMothershipPortalQuoteMessage(
|
|
extractMothershipPortalQuoteMessages(body),
|
|
);
|
|
}
|