import { describe, expect, it } from "vitest"; import { classifyMail } from "@/services/parse/classify"; import { extractMailInstructions } from "@/services/parse/split-instructions"; describe("product rules: latest confirmable + WO fallback", () => { it("mail1-like: classify WORK_ORDER; UI via workOrderActions record", () => { const subject = "Fw: TIIU8073522-90022"; const body = [ "\u53d1\u81ea\u6211\u7684iPhone", "------------------ \u539f\u59cb\u7535\u5b50\u90ae\u4ef6 ------------------", "\u4e3b\u9898 TIIU8073522-90022", "BAZUS001787430-90022 4PX \u9884\u7ea6\u7801: ==CNF26070717 \u9884\u7ea6\u7801", ].join("\n"); const ev = classifyMail({ subject, body, filenames: [] }); expect(ev.mail_type).toBe("WORK_ORDER"); // 详情页传入 mail_record.work_order_actions 时补当前工单单元 const units = extractMailInstructions({ subject, body, workOrderActions: ["\u5de5\u5355"], }); expect(units.some((u) => u.uiKind === "work_order" && u.isCurrent)).toBe( true, ); }); it("only newest instruction segment isCurrent", () => { const body = [ "\u65b0\u589e\u8f6c\u4ed3\uff0c\u8bf7\u7559\u610f", "------------------ \u539f\u59cb\u7535\u5b50\u90ae\u4ef6 ------------------", "\u53d1\u4ef6\u4eba\uff1aa@b.com", "\u4e3b\u9898\uff1a\u66f4\u65b0\u6d3e\u9001\u5355", "\u67dc\u53f7\uff1aMATU2745683 \u66f4\u65b0\u6d3e\u9001\u5355\uff0c\u8bf7\u67e5\u6536", ].join("\n"); const units = extractMailInstructions({ subject: "MATU2745683", body, }); const current = units.filter((u) => u.isCurrent); expect(current.some((u) => u.uiKind === "transfer")).toBe(true); // 已有当前转仓时,历史软词「更新派送单」不出客户指令卡 expect(units.some((u) => u.uiKind === "customer_instruction")).toBe(false); expect(current.every((u) => u.segmentIndex === current[0].segmentIndex)).toBe( true, ); }); it("LINK EVER: transfer only; no WO from work_order_actions=转仓", () => { const subject = "Fw: \u8f6c\u53d1\uff1aLINK EVER INC + MATS4583030000+ \u67dc\u53f7\uff1aMATU2745683+ ETA : 7/13"; const body = [ "\u53d1\u81ea\u6211\u7684iPhone", "------------------ \u539f\u59cb\u7535\u5b50\u90ae\u4ef6 ------------------", "\u5bc4\u4ef6\u4eba\uff1a date ", "---- \u8f6c\u53d1\u7684\u90ae\u4ef6 ----", "\u53d1\u4ef6\u4ebaop7", "\u65e5\u671f 2026\u5e7407\u670810\u65e5 16:44", "\u4e3b\u9898 \u56de\u590d: LINK EVER INC + MATS4583030000+ \u67dc\u53f7\uff1aMATU2745683+ ETA : 7/13", "\u65b0\u589e\u8f6c\u4ed3\uff0c\u8bf7\u7559\u610f", "\u67dc\u53f7\uff1aMATU2745683\u5361\u6d3e\u8d44\u6599.xlsx", "", "\u53d1\u4ef6\u4eba\uff1a op7", "\u53d1\u9001\u65f6\u95f4\uff1a 2026-07-02 18:09", "\u4e3b\u9898\uff1a LINK EVER INC + MATS4583030000+ \u67dc\u53f7\uff1a MATU2745683+ ETA : 7/13", "\u67dc\u53f7\uff1aMATU2745683 \u66f4\u65b0\u6d3e\u9001\u5355\uff0c\u8bf7\u67e5\u6536", ].join("\n"); const units = extractMailInstructions({ subject, body, filenames: ["\u67dc\u53f7\uff1aMATU2745683\u5361\u6d3e\u8d44\u6599.xlsx"], workOrderActions: ["\u8f6c\u4ed3"], }); expect(units.map((u) => u.uiKind)).toEqual(["transfer"]); expect(units[0].isCurrent).toBe(true); expect(units.some((u) => u.uiKind === "work_order")).toBe(false); expect(units.some((u) => u.uiKind === "customer_instruction")).toBe(false); }); it("soft keywords map to customer_instruction (not work_order)", () => { for (const kw of [ "\u66f4\u65b0\u6d3e\u9001\u5355", "\u6539\u81ea\u63d0", "\u62c6\u67dc\u6e05\u5355", "\u5361\u8f6c\u6d77", ]) { const units = extractMailInstructions({ subject: kw, body: kw, }); expect(units.some((u) => u.uiKind === "customer_instruction")).toBe( true, ); expect(units.some((u) => u.uiKind === "work_order")).toBe(false); } }); });