Files
ForgeFlow-ERP/frontend/src/utils/codeRules.js
T
2026-06-12 16:00:56 +08:00

170 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const CHINESE_CODE_INITIALS = {
产: "C",
品: "P",
原: "Y",
料: "L",
本: "B",
体: "T",
垃: "L",
圾: "J",
桶: "T",
垫: "D",
电: "D",
脑: "N",
支: "Z",
架: "J",
钢: "G",
板: "B",
卷: "J",
铝: "L",
合: "H",
金: "J",
铁: "T",
铜: "T",
不: "B",
锈: "X",
冷: "L",
热: "R",
轧: "Z",
镀: "D",
锌: "X",
冲: "C",
压: "Y",
件: "J",
片: "P",
管: "G",
棒: "B",
圆: "Y",
方: "F",
型: "X",
材: "C",
外: "W",
壳: "K",
底: "D",
座: "Z",
盖: "G",
盒: "H",
箱: "X",
门: "M",
锁: "S",
扣: "K",
连: "L",
接: "J"
};
function normalizeText(value) {
return String(value || "").trim();
}
export function normalizeCodeToken(value, maxLength = 24) {
const text = normalizeText(value).toUpperCase();
if (!text) {
return "";
}
const chunks = [];
let current = "";
let currentKind = "";
const flushCurrent = () => {
if (current) {
chunks.push(current);
}
current = "";
currentKind = "";
};
for (const char of text.replaceAll("×", "X").replaceAll("*", "X")) {
let kind = "";
let tokenChar = "";
if (/^[A-Z0-9.]$/.test(char)) {
kind = "LATIN";
tokenChar = char;
} else if (/^[\u4e00-\u9fff]$/.test(char)) {
const mapped = CHINESE_CODE_INITIALS[char];
if (mapped) {
kind = "CJK";
tokenChar = mapped;
} else {
kind = "CJK_RAW";
tokenChar = char;
}
} else {
flushCurrent();
continue;
}
if (currentKind && currentKind !== kind) {
flushCurrent();
}
currentKind = kind;
current += tokenChar;
}
flushCurrent();
return chunks.join("-").slice(0, maxLength).replace(/^[.-]+|[.-]+$/g, "");
}
function buildCodePrefix(parts, maxLength = 42) {
const tokens = parts.map((part) => normalizeCodeToken(part)).filter(Boolean);
if (!tokens.length) {
return "";
}
return tokens.join("-").slice(0, maxLength).replace(/^[.-]+|[.-]+$/g, "");
}
export function buildNextProductSpecCode(products = []) {
let maxNo = 0;
for (const product of products || []) {
const code = normalizeText(product?.item_code);
const match = code.match(/^产品需规(\d{5})$/);
if (match) {
maxNo = Math.max(maxNo, Number(match[1]));
}
}
return `产品需规${String(maxNo + 1).padStart(5, "0")}`;
}
export function buildProductCodePreview(form, savedCode = "", nextCode = "") {
if (normalizeText(savedCode)) {
return savedCode;
}
return normalizeText(nextCode) || "产品需规00001";
}
export function buildNextMaterialCode(materials = []) {
let maxNo = 0;
for (const material of materials || []) {
const code = normalizeText(material?.item_code);
const match = code.match(/^原材料(\d{5})$/);
if (match) {
maxNo = Math.max(maxNo, Number(match[1]));
}
}
return `原材料${String(maxNo + 1).padStart(5, "0")}`;
}
export function buildMaterialCodePreview(form, savedCode = "", nextCode = "") {
if (normalizeText(savedCode)) {
return savedCode;
}
return normalizeText(nextCode) || "原材料00001";
}
export function buildBomCodePreview(productCode, savedCode = "") {
if (normalizeText(savedCode)) {
return savedCode;
}
const prefix = buildCodePrefix(["BOM", productCode || "产品编码"], 50) || "BOM-产品编码";
return prefix;
}
export function buildRouteCodePreview(productCode, savedCode = "") {
if (normalizeText(savedCode)) {
return savedCode;
}
const prefix = buildCodePrefix(["ROUTE", productCode || "产品编码"], 50) || "ROUTE-产品编码";
return prefix;
}