|
|
@@ -0,0 +1,229 @@
|
|
|
+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
|
|
|
+ }
|
|
|
+})();
|