let budgetSummaryTreeSetting; /* 建设其他费表格相关 */ const budgetSummaryObj = (() => { const { isEmptyVal, isDef, isNumber } = window.commonUtil; const { fixedFlag, BudgetArea, BudgetType } = window.commonConstants; let curBudgetType = BudgetType.BUILDING; // 原始数据 let rawData = []; // ID与原始数据映射表(主要是恢复用) const orgMap = {}; // 建设其他费表格对象 let spread = null; // 建设其他费树 let tree = null; // 计算相关 const calcSetting = { costGrowthRate: 0, growthPeriod: 0, }; // 单位设置下拉框 const setUnitCombo = (sheet, data) => { const unitCol = budgetSummaryTreeSetting.cols.findIndex((item) => item.data.field === "unit"); if (unitCol >= 0) { TREE_SHEET_HELPER.massOperationSheet(sheet, () => { const comboBox = sheetCommonObj.getDynamicCombo(); comboBox .itemHeight(10) .items([ "m", "m2", "m3", "km", "t", "kg", "台班", "工日", "昼夜", "元", "项", "处", "个", "件", "根", "组", "系统", "台", "套", "株", "丛", "缸", "支", "只", "块", "座", "对", "份", "樘", "攒", "榀", ]) .editable(true); data.forEach((item, index) => { sheet.getCell(index, unitCol).cellType(comboBox); }); }); } }; const getFieldByCol = (col) => { const item = budgetSummaryTreeSetting.cols[col]; return (item && item.data && item.data.field) || null; }; // 单元格值验证器 const validator = { text() { return true; }, number(val) { return !isDef(val) || isNumber(val); }, }; const getValidator = (col) => { const item = budgetSummaryTreeSetting.cols[col]; if (!item) { return "text"; } return validator[item.data.type || "text"]; }; // 单元格文本转换处理 const textFactory = { calcBase(node) { if (node.data.calcBase && node.data.calcBase !== "") { return cbParser.toFExpr(node.data.calcBase); } return ""; }, "feesIndex.common.unitFee": (node) => { if (node && node.data.area === BudgetArea.CONSTRUCTION_FEE) { // 实时计算显示单价 const totalFee = _.get(node, "data.feesIndex.common.totalFee", 0); const quantity = node.data.quantity || 0; if (!totalFee || !quantity) { return ""; } return scMathUtil.roundForObj(totalFee / quantity, 2); // 小数位数写死2位置 } if (node && node.data.area === BudgetArea.CONSTRUCTION_OTHER_FEE) { return _.get(node, "data.feesIndex.common.unitFee", "") || ""; } return ""; }, "feesIndex.common.totalFee": (node) => { return _.get(node, "data.feesIndex.common.totalFee", "") || ""; }, "feesIndex.estimation.totalFee": (node) => { return _.get(node, "data.feesIndex.estimation.totalFee", "") || ""; }, "feesIndex.building.totalFee": (node) => { return _.get(node, "data.feesIndex.building.totalFee", "") || ""; }, "feesIndex.installation.totalFee": (node) => { return _.get(node, "data.feesIndex.installation.totalFee", "") || ""; }, "feesIndex.equipment.totalFee": (node) => { return _.get(node, "data.feesIndex.equipment.totalFee", "") || ""; }, "feesIndex.other.totalFee": (node) => { return _.get(node, "data.feesIndex.other.totalFee", "") || ""; }, }; /* 表格事件相关 */ // 根据节点数据刷新表格数据 const refreshData = (sheet, changedCells) => { if (!tree) { return; } TREE_SHEET_HELPER.massOperationSheet(sheet, () => { changedCells.forEach(({ row, col }) => { const node = tree.items[row]; const field = getFieldByCol(col); if (!field || !node) { return; } const textFunc = textFactory[field]; const val = textFunc ? textFunc(node) : node.data[field] || ""; sheet.setValue(row, col, val); }); }); }; // 刷新整个表格 const refreshAll = (sheet) => { const changedCells = []; const colCount = budgetSummaryTreeSetting.cols.length; for (let row = 0; row < tree.items.length; row++) { for (let col = 0; col < colCount; col++) { changedCells.push({ row, col }); } } refreshData(sheet, changedCells); }; // 更新数据 const bulkOperation = async (bulkData) => { if (bulkData.length) { await ajaxPost("/bills/bulkOperation", { bulkData }); } }; // 计算汇总估算总额 const calcEstimate = (nodes) => { const dataArr = []; const parentIDs = new Set(); nodes.forEach((node) => parentIDs.add(node.data.ParentID)); const parentNodes = []; parentIDs.forEach((parentID) => { const node = tree.findNode(parentID); if (!node) { return; } parentNodes.push(node); if (!node.children || !node.children.length) { return; } let estimateFee = 0; node.children.forEach((child) => { const childEstimateItem = (child.data.fees && child.data.fees.find((item) => item.fieldName === "estimation")) || null; const childEstimateFee = childEstimateItem ? childEstimateItem.totalFee : 0; estimateFee = scMathUtil.roundForObj(estimateFee + childEstimateFee, decimalObj.bills.totalPrice); }); const estimateItem = (node.data.fees && node.data.fees.find((item) => item.fieldName === "estimation")) || null; const orgEstimateFee = estimateItem ? estimateItem.totalFee : 0; if (orgEstimateFee !== estimateFee) { if (estimateItem) { estimateItem.totalFee = estimateFee; } else { node.data.fees.push({ fieldName: "estimation", totalFee: estimateFee, unitFee: 0 }); } dataArr.push({ ID: node.data.ID, fees: node.data.fees }); } }); if (parentNodes.length) { dataArr.push(...calcEstimate(parentNodes)); } return dataArr; }; // 编辑相关 const edit = async (sheet, changedCells, calcNodes = null) => { if (!changedCells.length && !calcNodes) { return; } if (changedCells.length) { // 单元格值验证 const isValid = changedCells.every(({ row, col }) => { const val = sheet.getValue(row, col); return getValidator(col)(val); }); // 验证不通过,恢复 if (!isValid) { refreshData(sheet, changedCells); return; } } let needCalc = false; const calcEstimateNodes = []; const nodes = []; try { $.bootstrapLoading.start(); const IDMap = {}; const bulkData = []; changedCells.forEach(({ row, col }) => { const node = tree.items[row]; if (!node) { return; } if (!nodes.find((n) => n.data.ID === node.data.ID)) { nodes.push(node); } const field = getFieldByCol(col); const value = sheet.getValue(row, col) || ""; const data = IDMap[node.data.ID] || (IDMap[node.data.ID] = {}); if (["feesIndex.common.unitFee"].includes(field)) { const fees = node.data.fees || []; const feeItem = fees.find((item) => item.fieldName === "common"); if (feeItem) { feeItem.unitFee = value; } else { fees.push({ fieldName: "common", totalFee: 0, unitFee: +value }); } data[field] = fees; node.data[field] = fees; node.data.feesIndex = getFeeIndex(node.data.fees); } else if (field === "feesIndex.estimation.totalFee") { const fees = node.data.fees || []; const feeItem = fees.find((item) => item.fieldName === "estimation"); if (feeItem) { feeItem.totalFee = value; } else { fees.push({ fieldName: "estimation", totalFee: +value, unitFee: 0 }); } data.fees = fees; node.data.fees = fees; node.data.feesIndex = getFeeIndex(node.data.fees); calcEstimateNodes.push(node); } else { data[field] = value; node.data[field] = value; } if (field === "calcBase") { node.data.userCalcBase = value; projectObj.project.calcBase.calculate(node, null, false); if (!projectObj.project.calcBase.success) { throw projectObj.project.calcBase.errMsg; } else if (isEmptyVal(value)) { // 删除清单基数,单价要清空 calcTools.setFieldValue(node, "feesIndex.common.unitFee", 0); } data.calcBase = node.data.calcBase; data.calcBaseValue = node.data.calcBaseValue; data.tenderCalcBaseValue = node.data.tenderCalcBaseValue; } if (["quantity", "feesIndex.common.unitFee", "calcBase", "feeRate"].includes(field) && node.data.area !== BudgetArea.CONSTRUCTION_FEE) { needCalc = true; } }); calcNodes = calcNodes ? calcNodes : needCalc ? nodes : []; // 重算节点 const dataArr = []; if (calcNodes && calcNodes.length) { const changedNodes = projectObj.project.calcProgram.calcNodes(calcNodes, false, tree); for (const node of changedNodes) { nodes.push(node); if (node.changed) { const data = calcTools.cutNodeForSave(node); dataArr.push(data); } } } // 汇总估算总额 if (calcEstimateNodes.length) { dataArr.push(...calcEstimate(calcEstimateNodes)); } dataArr.forEach((item) => { delete item.projectID; const data = IDMap[item.ID]; if (data) { Object.assign(data, item); } else { IDMap[item.ID] = item; } }); // 保存节点 Object.entries(IDMap).forEach(([ID, data]) => { const node = tree.findNode(ID); if (!node) { return; } // 处理被计算程序计算冲掉的估算总额 const orgData = orgMap[ID]; const orgEstimationItem = orgData.fees && orgData.fees.find((item) => item.fieldName === "estimation"); const orgEstimationFee = orgEstimationItem ? orgEstimationItem.totalFee : 0; const estimationItem = data.fees && data.fees.find((item) => item.fieldName === "estimation"); const estimationFee = estimationItem ? estimationItem.totalFee : 0; if (orgEstimationFee !== estimationFee) { if (!estimationItem && data.fees) { data.fees.push({ fieldName: "estimation", totalFee: orgEstimationFee }); } } // 处理其他费用 if (node.isBelongToFlags([fixedFlag.CONSTRUCTION_OTHER_FEE])) { const fees = data.fees || []; const commonFeeItem = fees.find((item) => item.fieldName === "common"); const otherFeeItem = fees.find((item) => item.fieldName === "other"); if (otherFeeItem) { otherFeeItem.totalFee = (commonFeeItem && commonFeeItem.totalFee) || 0; } else { fees.push({ fieldName: "other", totalFee: (commonFeeItem && commonFeeItem.totalFee) || 0 }); } } const actualID = node.data.area === BudgetArea.CONSTRUCTION_FEE ? node.data.orgProjectID : ID; const updateType = node.data.area === BudgetArea.CONSTRUCTION_FEE ? "updateProject" : "update"; bulkData.push({ type: updateType, data: { ...data, ID: actualID } }); }); await bulkOperation(bulkData); Object.entries(IDMap).forEach(([ID, data]) => { const node = tree.findNode(ID); if (node) { Object.assign(node.data, data); node.data.feesIndex = getFeeIndex(node.data.fees); orgMap[ID] = _.cloneDeep(node.data); } }); refreshAll(sheet); } catch (err) { console.log(err); nodes.forEach((node) => { const orgItem = orgMap[node.data.ID]; if (orgItem) { node.data = _.cloneDeep(orgItem); // Object.assign(node.data, orgItem); } }); refreshData(sheet, changedCells); alert(err); } finally { $.bootstrapLoading.end(); } }; // 是否是属于工程费用区域的节点 const isConstructionFeeArea = (node) => { return node && node.data && node.data.area === BudgetArea.CONSTRUCTION_FEE; }; // 工具栏可操作性 let upLevelDisabled = false; let downLevelDisabled = false; let upMoveDisabled = false; let downMoveDisabled = false; const refreshToolsBar = (node) => { upLevelDisabled = !node || !node.canUpLevel() || isConstructionFeeArea(node) || (node.nextSibling && node.data.calcBase); downLevelDisabled = !node || !node.canDownLevel() || isConstructionFeeArea(node) || isConstructionFeeArea(node.preSibling) || (node.preSibling && node.preSibling.data.calcBase); upMoveDisabled = !node || !node.canUpMove() || isConstructionFeeArea(node) || isConstructionFeeArea(node.preSibling); downMoveDisabled = !node || !node.canDownMove() || isConstructionFeeArea(node) || isConstructionFeeArea(node.nextSibling); if (upLevelDisabled) { $("#budget-upLevel").addClass("disabled"); } else { $("#budget-upLevel").removeClass("disabled"); } if (downLevelDisabled) { $("#budget-downLevel").addClass("disabled"); } else { $("#budget-downLevel").removeClass("disabled"); } if (upMoveDisabled) { $("#budget-upMove").addClass("disabled"); } else { $("#budget-upMove").removeClass("disabled"); } if (downMoveDisabled) { $("#budget-downMove").addClass("disabled"); } else { $("#budget-downMove").removeClass("disabled"); } }; // 表格选中相关 const selectCell = (row, col, setCell = false) => { const node = tree.items[row]; refreshToolsBar(node); tree.selected = node; console.log(node); const sheet = spread.getSheet(0); if (setCell) { sheet.setActiveCell(row, col); } //设置选中行底色和恢复前选中行底色 const refreshNodes = [node]; if (!tree.preSelected) { refreshNodes.push(tree.items[0]); } else { refreshNodes.push(tree.preSelected); } tree.preSelected = node; projectObj.setNodesStyle(sheet, refreshNodes, tree); }; // 事件列表 const events = { EnterCell(sender, args) { args.sheet.repaint(); }, SelectionChanged(sender, args) { const newSel = args.newSelections[0] ? { row: args.newSelections[0].row, col: args.newSelections[0].col } : { row: 0, col: 0 }; selectCell(newSel.row, newSel.col); }, ValueChanged(sender, args) { if (isEmptyVal(args.oldValue) && isEmptyVal(args.newValue)) { return; } edit(args.sheet, [{ row: args.row, col: args.col }]); }, RangeChanged(sender, args) { edit(args.sheet, args.changedCells); }, }; const bindEvents = (sheet) => { Object.entries(events).forEach(([ev, evFunc]) => { sheet.bind(GC.Spread.Sheets.Events[ev], evFunc); }); }; /* 只读相关 */ // 单元格锁定判断 const lockFactory = { code(node) { return !!(node && (node.getFlag() || node.data.area === BudgetArea.CONSTRUCTION_FEE)); }, name(node) { return !!(node && (node.getFlag() || node.data.area === BudgetArea.CONSTRUCTION_FEE)); }, "feesIndex.estimation.totalFee"(node) { return !!(!node || node.children.length); }, "feesIndex.common.unitFee"(node) { return !!(node && node.data.area === BudgetArea.CONSTRUCTION_FEE); }, calcBase(node) { return !!(node && (node.children.length || node.data.area === BudgetArea.CONSTRUCTION_FEE)); }, feeRate(node) { return !!(node && (node.children.length || node.data.area === BudgetArea.CONSTRUCTION_FEE)); }, remark(node) { return !!(node && node.data.area === BudgetArea.CONSTRUCTION_FEE); }, }; const lockData = (sheet, nodes, isMass = true) => { const lock = () => { if (projectReadOnly) { sheet.getRange(0, 0, nodes.length, budgetSummaryTreeSetting.cols.length, GC.Spread.Sheets.SheetArea.viewport).locked(true); return 0; } // 工程费用区域,只读 /* const constructionFeeNode = nodes.find(node => node.getFlag() === fixedFlag.CONSTRUCTION_FEE); if (!constructionFeeNode) { return 0; } const endIndex = constructionFeeNode.posterityCount() + 1; sheet.getRange(0, 0, endIndex, budgetSummaryTreeSetting.cols.length, GC.Spread.Sheets.SheetArea.viewport).locked(true); // 除第一行,章编号 节编号可编辑 if (curBudgetType === BudgetType.RAIL) { const chapterCodeCol = budgetSummaryTreeSetting.cols.findIndex(item => item.data.field === 'chapterCode'); const sectionCodeCol = budgetSummaryTreeSetting.cols.findIndex(item => item.data.field === 'sectionCode'); for (let row = 1; row < endIndex; row++) { if (chapterCodeCol > -1) { sheet.getCell(row, chapterCodeCol).locked(false); } if (sectionCodeCol > -1) { sheet.getCell(row, sectionCodeCol).locked(false); } } } return endIndex; */ }; if (isMass) { TREE_SHEET_HELPER.massOperationSheet(sheet, () => { return lock(); }); } else { return lock(); } }; /* 单元格类型 */ const calcBaseButtonCallback = (hitInfo) => { calcBaseView.onCalcBaseButtonClick(hitInfo, "budget"); }; const cellTypeFactory = { calcBase(node) { const locked = lockFactory.calcBase(node); return sheetCommonObj.getCusButtonCellType(calcBaseButtonCallback, locked); }, }; /* 设置可编辑区域节点的只读性和单元格类型 */ const setCells = (sheet, startRow, nodes) => { for (let row = startRow; row < nodes.length; row++) { const node = nodes[row]; budgetSummaryTreeSetting.cols.forEach((item, col) => { const field = item.data.field; // 锁定单元格 const lockFunc = lockFactory[field]; if (lockFunc) { const isLocked = lockFunc(node); sheet.getCell(row, col).locked(isLocked); } // 设置单元格类型 const cellTypeFunc = cellTypeFactory[field]; if (cellTypeFunc) { const cellType = cellTypeFunc(node); sheet.getCell(row, col).cellType(cellType); } // 单元格文本转换 const textFunc = textFactory[field]; if (textFunc) { sheet.setValue(row, col, textFunc(node)); } }); } }; /* 初始化表格 */ const initSpread = () => { if (!spread) { // spread = sheetCommonObj.createSpread($('#budget-summary-sheet')[0], 1); spread = SheetDataHelper.createNewSpread($("#budget-summary-sheet")[0]); sheetCommonObj.spreadDefaultStyle(spread); // 设置表头 const sheet = spread.getSheet(0); bindEvents(sheet); const headers = sheetCommonObj.getHeadersFromTreeSetting(budgetSummaryTreeSetting); sheetCommonObj.setHeader(sheet, headers); // 右键菜单 initContextMenu(); } else { spread.refresh(); } return spread; }; // 初始化树 const initTree = (data, sheet, setting) => { tree = idTree.createNew({ id: "ID", pid: "ParentID", nid: "NextSiblingID", rootId: -1, autoUpdate: true }); const controller = TREE_SHEET_CONTROLLER.createNew(tree, sheet, setting, false, true); tree.loadDatas(data); tree.items.forEach((node) => { node.source = node; node.sourceType = ModuleNames.bills; }); controller.showTreeData(); sheet.setRowCount(data.length); setUnitCombo(sheet, data); TREE_SHEET_HELPER.massOperationSheet(sheet, () => { const startRow = lockData(sheet, tree.items, false); setCells(sheet, 0, tree.items); // 表格格式化 budgetSummaryTreeSetting.cols.forEach((item, index) => { sheet.setFormatter(-1, index, item.formatter || "@", GC.Spread.Sheets.SheetArea.viewport); }); }); selectCell(sheet.getActiveRowIndex(), sheet.getActiveColumnIndex()); }; /* 右键菜单 */ // 更新树结构数据 const updateTree = (sheet, updateData) => { // 更新数据 updateData.forEach((item) => { if (item.type === "new") { orgMap[item.data.ID] = _.cloneDeep(item.data); rawData.push(item.data); } else if (item.type === "update") { if (orgMap[item.data.ID]) { Object.assign(orgMap[item.data.ID], item.data); } const node = tree.findNode(item.data.ID); if (node) { Object.assign(node.data, item.data); } } else { delete orgMap[item.data.ID]; const removeIndex = rawData.findIndex((d) => d.ID === item.data.ID); if (removeIndex > -1) { rawData.splice(removeIndex, 1); } } }); // 重新初始化树 initTree(rawData, sheet, budgetSummaryTreeSetting); }; let loading = false; // 插入 const insert = async (sheet, selected) => { try { if (loading) { return; } loading = true; $.bootstrapLoading.start(); const updateData = tree.getInsertData(selected.data.ParentID, selected.data.NextSiblingID, uuid.v1()); const newData = updateData.filter((item) => item.type === "new"); newData.forEach((item) => { item.data.fees = []; item.data.flags = []; item.feesIndex = {}; item.flagsIndex = {}; item.data.type = selected.data.type; item.data.projectID = projectObj.project.property.rootProjectID; }); await bulkOperation(updateData); updateTree(sheet, updateData); selectCell(sheet.getActiveRowIndex() + selected.posterityCount() + 1, sheet.getActiveColumnIndex(), true); } catch (err) { alert(err); } finally { $.bootstrapLoading.end(); loading = false; } }; // 删除 const remove = async (sheet, selected) => { try { if (loading) { return; } loading = true; $.bootstrapLoading.start(); const updateData = tree.getDeleteData(selected); await bulkOperation(updateData); updateTree(sheet, updateData); } catch (err) { alert(err); } finally { $.bootstrapLoading.end(); loading = false; } }; // 升级 const upLevel = async (selected) => { if (!spread || !tree) { return; } const sheet = spread.getSheet(0); selected = selected ? selected : tree.selected; try { if (loading || upLevelDisabled) { return; } loading = true; $.bootstrapLoading.start(); const updateData = selected.getUpLevelData(); await bulkOperation(updateData); updateTree(sheet, updateData); } catch (err) { alert(err); } finally { $.bootstrapLoading.end(); loading = false; } }; // 降级 const downLevel = async (selected) => { if (!spread || !tree) { return; } const sheet = spread.getSheet(0); selected = selected ? selected : tree.selected; try { if (loading || downLevelDisabled) { return; } loading = true; $.bootstrapLoading.start(); const updateData = selected.getDownLevelData(); await bulkOperation(updateData); updateTree(sheet, updateData); } catch (err) { alert(err); } finally { $.bootstrapLoading.end(); loading = false; } }; // 上移 const upMove = async (selected) => { if (!spread || !tree) { return; } const sheet = spread.getSheet(0); selected = selected ? selected : tree.selected; try { if (loading || upMoveDisabled) { return; } loading = true; $.bootstrapLoading.start(); const updateData = selected.getUpMoveData(); await bulkOperation(updateData); updateTree(sheet, updateData); const prev = selected.preSibling; const row = sheet.getActiveRowIndex() - prev.posterityCount() - 1; selectCell(row, sheet.getActiveColumnIndex(), true); sheet.showRow(row, GC.Spread.Sheets.VerticalPosition.center); } catch (err) { alert(err); } finally { $.bootstrapLoading.end(); loading = false; } }; // 下移 const downMove = async (selected) => { if (!spread || !tree) { return; } const sheet = spread.getSheet(0); selected = selected ? selected : tree.selected; try { if (loading || downMoveDisabled) { return; } loading = true; $.bootstrapLoading.start(); const updateData = selected.getDownMoveData(); await bulkOperation(updateData); updateTree(sheet, updateData); const next = selected.nextSibling; const row = sheet.getActiveRowIndex() + next.posterityCount() + 1; selectCell(row, sheet.getActiveColumnIndex(), true); sheet.showRow(row, GC.Spread.Sheets.VerticalPosition.center); } catch (err) { alert(err); } finally { $.bootstrapLoading.end(); loading = false; } }; // 初始化右键菜单 const initContextMenu = () => { if (!spread) { return; } let curRow; let curNode; const sheet = spread.getSheet(0); $.contextMenu({ selector: "#budget-summary-sheet", build: function ($trigger, e) { const target = SheetDataHelper.safeRightClickSelection($trigger, e, spread); curRow = target.row; curNode = (tree && tree.items[curRow]) || null; selectCell(target.row, target.col, true); return target.hitTestType === GC.Spread.Sheets.SheetArea.viewport || target.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader; }, items: { insert: { name: "插入行", icon: "fa-sign-in", disabled() { return !curNode || (curNode.data.area === BudgetArea.CONSTRUCTION_FEE && curNode.getFlag() !== fixedFlag.CONSTRUCTION_FEE); }, callback() { insert(sheet, curNode); }, }, remove: { name: "删除行", icon: "fa-remove", disabled() { return !curNode || isConstructionFeeArea(curNode) || curNode.getFlag(); }, callback() { remove(sheet, curNode); }, }, refresh: { name: "刷新数据", icon: "fa-refresh", callback() { init(projectObj.project.property.rootProjectID); }, }, }, }); }; // 初始化 const init = async (constructionID) => { try { $.bootstrapLoading.start(); // 得先计算费用汇总(概算汇总计算基于费用汇总算出来的总金额) await projectObj.project.calcProgram.getGatherFeeData(); const { budgetType, treeData, costGrowthRate, growthPeriod } = await ajaxPost("/bills/initialBudgetSummary", { constructionID }); budgetSummaryTreeSetting = budgetType === BudgetType.BUILDING ? budgetInstallationSetting : budgetRailSetting; curBudgetType = budgetType; calcSetting.costGrowthRate = costGrowthRate; calcSetting.growthPeriod = growthPeriod; $("#costGrowthRate").val(costGrowthRate); $("#growthPeriod").val(growthPeriod); rawData = treeData; rawData.forEach((item) => { if (item.quantity) { item.quantity = parseFloat(item.quantity); } item.feesIndex = getFeeIndex(item.fees); item.flagsIndex = {}; if (item.flags) { item.flags.forEach((flag) => { item.flagsIndex[flag.fieldName] = flag; }); } }); const spread = initSpread(); const sheet = spread.getSheet(0); rawData.forEach((item) => { orgMap[item.ID] = _.cloneDeep(item); }); initTree(rawData, sheet, budgetSummaryTreeSetting); calcBase.initBudget(); // 造价计算 await edit(sheet, [], tree.roots.slice(1)); } catch (err) { console.log(err); alert(err); } finally { $.bootstrapLoading.end(); } }; // 点击tab,重新初始化 $("#tab-budget-summary").click(function () { if (!$(this).hasClass("active")) { init(projectObj.project.property.rootProjectID); } }); $("#budget-upLevel").click(() => { upLevel(); }); $("#budget-downLevel").click(() => { downLevel(); }); $("#budget-upMove").click(() => { upMove(); }); $("#budget-downMove").click(() => { downMove(); }); /* 建设项目设置 */ $("#openConstructionSet").click(() => { $("#constructionSet").modal("show"); }); function isKeyNumber(keyCode) { // 数字 if (keyCode >= 48 && keyCode <= 57) { return true; } else if (keyCode >= 96 && keyCode <= 105) { //小键盘数字 return true; } else if (keyCode == 8 || keyCode == 46 || keyCode == 37 || keyCode == 39 || keyCode == 108 || keyCode == 110) { // Backspace, del, 左右方向键 return true; } else if (keyCode >= 112 && keyCode <= 123) { //F1 -F12 return true; } return false; } //年造价增涨率 $("#costGrowthRate").keydown(function (e) { return isKeyNumber(e.keyCode); }); //计费年限 $("#growthPeriod").keydown(function (e) { return isKeyNumber(e.keyCode); }); // 确认设置 $("#construction-set-ok").click(async () => { try { $.bootstrapLoading.start(); const curCostGrowthRate = $("#costGrowthRate").val(); const curGrowthPeriod = $("#growthPeriod").val(); const bulkData = [ { type: "updateProject", data: { ID: projectObj.project.property.rootProjectID, "property.costGrowthRate": curCostGrowthRate, "property.growthPeriod": curGrowthPeriod, }, }, ]; await bulkOperation(bulkData); calcSetting.costGrowthRate = curCostGrowthRate; calcSetting.growthPeriod = curGrowthPeriod; } catch (err) { alert(err); $("#costGrowthRate").val(calcSetting.costGrowthRate); $("#growthPeriod").val(calcSetting.growthPeriod); } finally { $.bootstrapLoading.end(); } }); // 对外暴露 return { getTree: () => tree, getSheet: () => spread.getSheet(0), calcSetting, edit, }; })();