const OVER_HEIGHT = (() => { // 选项类型,生成的超高子目所在位置 const Option = { // 对应清单或分部下(默认) SEPARATION: 1, // 指定措施清单011704001 MEASURE: 2, // 指定具体位置,显示分部分项以及措施项目的树结构显示叶子清单(分项)供勾选 SPECIFIC: 3, }; // 选项二时的前九位清单编号 const fixedCodeReg = /^011704001/; // 源数据 let sourceData; // 下拉项 let comboData; function init(source) { sourceData = source || []; comboData = sourceData ? sourceData .filter(item => !item.extra) .map(item => item.name) : []; } // 获取下拉项 function getComboData() { return comboData; } function getOverHeightItem(value) { return sourceData.find(item => item.name === value); } // 获取系数 function getRate(overHeightItem) { return overHeightItem.labourRate || overHeightItem.machineRate || overHeightItem.labourMachineRate || null; } // 下拉项是否需要计算(生成子目) function isNeedToCalc(overHeightItem) { if (!overHeightItem) { return false; } const rate = getRate(overHeightItem); return !!rate; } // 是否是超高子目 function isOverHeight(node) { return node && node.sourceType === projectObj.project.Ration.getSourceType() && node.data.type === rationType.overHeight; } function overHeightCol() { return projectObj.project.projSetting.main_tree_col.cols.findIndex(item => item.data.field === 'overHeight'); } // 有效化变化节点的值,若值为无效值(下拉项中不存在),则将变化节点的值设成原值 function validateData(changedData) { changedData.forEach(item => { if (!comboData.includes(item.value)) { item.value = item.node.data.overHeight; } }); } // 简化变化节点:由于子项值继承父项,且变更节点中可能存在父子关系,因此需要去除子项节点 function simplifyData(changedData) { const rst = []; const nodes = changedData.map(item => item.node); changedData.forEach(item => { let parent = item.parent; // 父项不存在变化节点中才将此数据放入返回数组中 while (parent) { if (nodes.includes(parent)) { return; } parent = parent.parent; } rst.push(item); }); return rst; } // 设置单元格文本,单元格文本数据为暂存数据,方便后续获取更新、新增数据,若后续操作失败,则可用节点数据恢复单元格文本内容。 function setTexts(changedData) { const sheet = projectObj.project.mainController.sheet; const func = () => { const overHeightCol = overHeightCol(); changedData.forEach(item => { // 子项值随父项 const nodes = [item.node, ...item.node.getPosterity()]; nodes.forEach(node => sheet.setText(node.serialNo(), overHeightCol, item.value)); }); }; TREE_SHEET_HELPER.massOperationSheet(sheet, func); } // 获取措施项目固定的节点: 选项二时 function getMeasureFixedNode() { const measureNode = projectObj.project.mainTree.items.find(node => node.getFlag() === fixedFlag.MEASURE); const measureChildren = measureNode.getPosterity(); return measureChildren.find(node => node.data.code && fixedCodeReg.test(node.data.code)); } // 获取指定清单节点:选项三时 function getSpecificNode() { // 选项三指定清单时,指定的清单ID会存在项目属性中 const specificID = projectObj.project.projectInfo.property.overHeightSpecificID; return specificID ? projectObj.project.mainTree.nodes[`id_${specificID}`] : null; } // 操作检验,若选项为2、3时,需检验指定清单是否还存在,不存在则取消操作和提示 function checkAction(option = Option.SEPARATION) { if (option === Option.SEPARATION) { return true; } else if (option === Option.MEASURE) { const isValid = !!getMeasureFixedNode(); if (!isValid) { $('#overHeightMeasure').modal('show'); } return isValid; } else { const isValid = !!getSpecificNode(); if (!isValid) { $('#overHeightSpecific').modal('show'); } return isValid; } } // 超高降效下拉项或选项是否改变了 function isValueChanged() { const updateData = getUpdateData(); return updateData.bills.length || updateData.ration.length; } /* * 获取更新数据:对比项目节点中超高降效的新旧值,新值为暂存的单元格文本,旧值为节点data数据 * @return {Object} {bills: [{ID: Number, overHeight: String}], ration: [{ID: Number, overHeight: String}]} * */ function getUpdateData() { const rst = { bills: [], ration: [], }; const nodes = projectObj.project.mainTree.items; const sheet = projectObj.project.mainController.sheet; const overHeightCol = overHeightCol(); nodes.forEach((node, index) => { const newValue = node.data.overHeight; const oldValue = sheet.getText(index, overHeightCol); // 非严等 if (newValue != oldValue) { const type = node.sourceType === projectObj.project.Bills.getSourceType() ? 'bills' : 'ration'; rst[type].push({ ID: node.data.ID, overHeight: newValue }); } }); return rst; } /* * 获取删除数据:项目中所有超高子目 * @return {Array} [{ID: Number}] * */ function getDeleteData() { const rations = projectObj.project.Ration.datas; return rations .filter(ration => ration.type === rationType.overHeight) .map(ration => ({ ID: ration.ID })); } // 更改了超高降效列(edited、rangeChanged),触发事件 function handleValueChanged(changedData) { validateData(changedData); changedData = simplifyData(changedData); setTexts(changedData); const valuedChanged = isValueChanged(); if (!valuedChanged) { return; } // 选项2、选项3情况下下拉可能会遇到,相关清单已经被删除,需要检测 const actionValid = checkAction(projectObj.project.projectInfo.property.overHeightOption); // actionValid为false的时候,可能后续需要恢复单元格文本值,根据后续用户在弹窗中的选择 todo if (!actionValid) { return; } } // 获取需要生成超高子目的定额节点 function getNeedCalcRationItems() { // 从整个项目中筛选当前下拉项单元格的文本是需要计算的定额节点 const nodes = projectObj.project.mainTree.items; const sheet = projectObj.project.mainController.sheet; const overHeightCol = overHeightCol(); const rst = []; nodes.forEach(node => { if (node.sourceType !== projectObj.project.Ration.getSourceType() || node.data.type === rationType.overHeight) { return; } const overHeight = sheet.getText(node.serialNo(), overHeightCol); const overHeightItem = getOverHeightItem(overHeight); if (isNeedToCalc(overHeightItem)) { rst.push({ node, overHeightItem}); } }); return rst; } function handleConfirmed(option = Option.SEPARATION) { } return { init, getComboData, isOverHeight } })();