/** * 产品大类树(/basic/product/list)工具 * * 说明:产品树一级节点是「成品 / 半成品 / 原材料」这类根节点,具体产品大类挂在根节点下。 * 部分业务新增时只允许选择某一类产品(如采购台账只选原材料、生产计划只选成品),编辑时要保持完整树。 */ // 根节点名称,兼容「原材料」「原料」两种建法 const RAW_MATERIAL_ROOT_NAMES = ["原材料", "原料"]; const FINISHED_PRODUCT_ROOT_NAMES = ["成品"]; /** * 取节点名称(树接口同时返回 label 与 productName) * @param {object} node 树节点 * @returns {string} 节点名称 */ const getNodeLabel = node => String(node?.label ?? node?.productName ?? "").trim(); /** * 判断节点名称是否命中指定的根节点名称(完全相同或以该名称开头) * @param {object} node 树节点 * @param {Array} rootNames 允许的根节点名称 * @returns {boolean} 是否命中 */ const isRootNodeNamed = (node, rootNames) => { const label = getNodeLabel(node); if (!label) { return false; } return rootNames.some(name => label === name || label.startsWith(name)); }; /** * 只保留指定名称根节点下的产品树,用于新增场景 * @param {Array} tree 接口返回的产品树 * @param {Array} rootNames 允许的根节点名称 * @returns {Array} 过滤后的树(不改动原数据,编辑场景直接传原树即可) */ export const filterProductTreeByRoot = (tree, rootNames = []) => (Array.isArray(tree) ? tree : []).filter(node => isRootNodeNamed(node, rootNames) ); /** * 只保留「原材料」根节点下的产品树 * @param {Array} tree 接口返回的产品树 * @returns {Array} 过滤后的树 */ export const filterRawMaterialTree = tree => filterProductTreeByRoot(tree, RAW_MATERIAL_ROOT_NAMES); /** * 只保留「成品」根节点下的产品树 * @param {Array} tree 接口返回的产品树 * @returns {Array} 过滤后的树 */ export const filterFinishedProductTree = tree => filterProductTreeByRoot(tree, FINISHED_PRODUCT_ROOT_NAMES);