|
@@ -1,7 +1,7 @@
|
|
|
/* 建设其他费表格相关 */
|
|
|
const budgetSummaryObj = (() => {
|
|
|
|
|
|
- const { isDef, isNumber } = window.commonUtil;
|
|
|
+ const { isEmptyVal, isDef, isNumber } = window.commonUtil;
|
|
|
const { fixedFlag, BudgetArea } = window.commonConstants;
|
|
|
|
|
|
// 原始数据
|
|
@@ -117,11 +117,74 @@ const budgetSummaryObj = (() => {
|
|
|
$.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) {
|
|
@@ -130,19 +193,61 @@ const budgetSummaryObj = (() => {
|
|
|
}
|
|
|
const bindEvents = (sheet) => {
|
|
|
Object.entries(events).forEach(([ev, evFunc]) => {
|
|
|
- sheet.bind(GC.Spread.Sheets.Events[ev], evFunc)
|
|
|
- })
|
|
|
+ sheet.bind(GC.Spread.Sheets.Events[ev], evFunc);
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
/* 只读相关 */
|
|
|
- const lockData = (sheet, nodes) => {
|
|
|
- TREE_SHEET_HELPER.massOperationSheet(sheet, () => {
|
|
|
+ // 单元格锁定判断
|
|
|
+ const lockFactory = {
|
|
|
+ code(node) {
|
|
|
+ return !!(node && node.getFlag());
|
|
|
+ },
|
|
|
+ name(node) {
|
|
|
+ return !!(node && node.getFlag());
|
|
|
+ },
|
|
|
+ calcBase(node) {
|
|
|
+ return !!(node && node.children.length);
|
|
|
+ },
|
|
|
+ feeRate(node) {
|
|
|
+ return !!(node && node.children.length);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ 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;
|
|
|
+ }
|
|
|
// 工程费用区域,只读
|
|
|
const equipmentNode = nodes.find(node => node.getFlag() === fixedFlag.CONSTRUCTION_EQUIPMENT_FEE);
|
|
|
- if (equipmentNode) {
|
|
|
- sheet.getRange(0, 0, equipmentNode.serialNo() + 1, budgetSummaryTreeSetting.cols.length, GC.Spread.Sheets.SheetArea.viewport).locked(true);
|
|
|
+ if (!equipmentNode) {
|
|
|
+ return;
|
|
|
}
|
|
|
- });
|
|
|
+ sheet.getRange(0, 0, equipmentNode.serialNo() + 1, budgetSummaryTreeSetting.cols.length, GC.Spread.Sheets.SheetArea.viewport).locked(true);
|
|
|
+ // 剩下的区域,根据单元格锁定方法,按字段进行锁定判断
|
|
|
+ const startIndex = equipmentNode.serialNo() + 1;
|
|
|
+ for (let row = startIndex; row < nodes.length; row ++) {
|
|
|
+ const node = nodes[row];
|
|
|
+ budgetSummaryTreeSetting.cols.forEach((item, col) => {
|
|
|
+ const field = item.data.field;
|
|
|
+ const lockFunc = lockFactory[field];
|
|
|
+ if (!lockFunc) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const isLocked = lockFunc(node);
|
|
|
+ sheet.getCell(row, col).locked(isLocked);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ if (isMass) {
|
|
|
+ TREE_SHEET_HELPER.massOperationSheet(sheet, () => {
|
|
|
+ lock();
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ lock();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/* 初始化表格 */
|
|
@@ -156,6 +261,7 @@ const budgetSummaryObj = (() => {
|
|
|
bindEvents(sheet);
|
|
|
const headers = sheetCommonObj.getHeadersFromTreeSetting(budgetSummaryTreeSetting);
|
|
|
sheetCommonObj.setHeader(sheet, headers);
|
|
|
+ // 右键菜单
|
|
|
initContextMenu();
|
|
|
} else {
|
|
|
spread.refresh();
|
|
@@ -166,7 +272,7 @@ const budgetSummaryObj = (() => {
|
|
|
// 初始化树
|
|
|
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);
|
|
|
+ const controller = TREE_SHEET_CONTROLLER.createNew(tree, sheet, setting, false, true);
|
|
|
tree.loadDatas(data);
|
|
|
tree.items.forEach(node => {
|
|
|
node.source = node;
|
|
@@ -175,7 +281,14 @@ const budgetSummaryObj = (() => {
|
|
|
controller.showTreeData();
|
|
|
sheet.setRowCount(data.length);
|
|
|
setUnitCombo(sheet, data);
|
|
|
- lockData(sheet, tree.items);
|
|
|
+ TREE_SHEET_HELPER.massOperationSheet(sheet, () => {
|
|
|
+ lockData(sheet, tree.items, false);
|
|
|
+ // 表格格式化
|
|
|
+ budgetSummaryTreeSetting.cols.forEach((item, index) => {
|
|
|
+ sheet.setFormatter(-1, index, item.formatter || '@', GC.Spread.Sheets.SheetArea.viewport);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ selectCell(sheet.getActiveRowIndex(), sheet.getActiveColumnIndex());
|
|
|
}
|
|
|
|
|
|
/* 右键菜单 */
|
|
@@ -200,28 +313,42 @@ const budgetSummaryObj = (() => {
|
|
|
// 重新初始化树
|
|
|
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);
|
|
|
- sheet.setActiveCell(sheet.getActiveRowIndex() + selected.posterityCount() + 1, sheet.getActiveColumnIndex())
|
|
|
+ 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);
|
|
@@ -230,11 +357,21 @@ const budgetSummaryObj = (() => {
|
|
|
alert(err);
|
|
|
} finally {
|
|
|
$.bootstrapLoading.end();
|
|
|
+ loading = false;
|
|
|
}
|
|
|
}
|
|
|
// 升级
|
|
|
- const upLevel = async (sheet, selected) => {
|
|
|
+ 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);
|
|
@@ -243,11 +380,21 @@ const budgetSummaryObj = (() => {
|
|
|
alert(err);
|
|
|
} finally {
|
|
|
$.bootstrapLoading.end();
|
|
|
+ loading = false;
|
|
|
}
|
|
|
}
|
|
|
// 降级
|
|
|
- const downLevel = async (sheet, selected) => {
|
|
|
+ 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);
|
|
@@ -256,47 +403,64 @@ const budgetSummaryObj = (() => {
|
|
|
alert(err);
|
|
|
} finally {
|
|
|
$.bootstrapLoading.end();
|
|
|
+ loading = false;
|
|
|
}
|
|
|
}
|
|
|
// 上移
|
|
|
- const upMove = async (sheet, selected) => {
|
|
|
+ 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;
|
|
|
- sheet.setActiveCell(row, sheet.getActiveColumnIndex());
|
|
|
+ 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 (sheet, selected) => {
|
|
|
+ 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;
|
|
|
- sheet.setActiveCell(row, sheet.getActiveColumnIndex())
|
|
|
+ selectCell(row, sheet.getActiveColumnIndex(), true);
|
|
|
sheet.showRow(row, GC.Spread.Sheets.VerticalPosition.center);
|
|
|
} catch (err) {
|
|
|
alert(err);
|
|
|
} finally {
|
|
|
$.bootstrapLoading.end();
|
|
|
+ loading = false;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
- // 是否是属于工程费用区域的节点
|
|
|
- const isConstructionFeeArea = (node) => {
|
|
|
- return node && node.data && node.data.area === BudgetArea.CONSTRUCTION_FEE;
|
|
|
- }
|
|
|
// 初始化右键菜单
|
|
|
const initContextMenu = () => {
|
|
|
if (!spread) {
|
|
@@ -311,7 +475,7 @@ const budgetSummaryObj = (() => {
|
|
|
const target = SheetDataHelper.safeRightClickSelection($trigger, e, spread);
|
|
|
curRow = target.row;
|
|
|
curNode = tree && tree.items[curRow] || null;
|
|
|
- sheet.setActiveCell(target.row, target.col);
|
|
|
+ selectCell(target.row, target.col, true);
|
|
|
return target.hitTestType === GC.Spread.Sheets.SheetArea.viewport || target.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
|
|
|
},
|
|
|
items: {
|
|
@@ -329,52 +493,52 @@ const budgetSummaryObj = (() => {
|
|
|
name: '删除行',
|
|
|
icon: 'fa-remove',
|
|
|
disabled() {
|
|
|
- return !curNode || isConstructionFeeArea(curNode);
|
|
|
+ return !curNode || isConstructionFeeArea(curNode) || curNode.getFlag();
|
|
|
},
|
|
|
callback() {
|
|
|
remove(sheet, curNode);
|
|
|
}
|
|
|
},
|
|
|
- upLevel: {
|
|
|
- name: '升级',
|
|
|
- icon: 'fa-arrow-left',
|
|
|
- disabled() {
|
|
|
- return !curNode || !curNode.canUpLevel() || isConstructionFeeArea(curNode);
|
|
|
- },
|
|
|
- callback() {
|
|
|
- upLevel(sheet, curNode);
|
|
|
- }
|
|
|
- },
|
|
|
- downLevel: {
|
|
|
- name: '降级',
|
|
|
- icon: 'fa-arrow-right',
|
|
|
- disabled() {
|
|
|
- return !curNode || !curNode.canDownLevel() || isConstructionFeeArea(curNode) || isConstructionFeeArea(curNode.preSibling);
|
|
|
- },
|
|
|
- callback() {
|
|
|
- downLevel(sheet, curNode);
|
|
|
- }
|
|
|
- },
|
|
|
- upMove: {
|
|
|
- name: '上移',
|
|
|
- icon: 'fa-arrow-up',
|
|
|
- disabled() {
|
|
|
- return !curNode || !curNode.canUpMove() || isConstructionFeeArea(curNode) || isConstructionFeeArea(curNode.preSibling);
|
|
|
- },
|
|
|
- callback() {
|
|
|
- upMove(sheet, curNode);
|
|
|
- }
|
|
|
- },
|
|
|
- downMove: {
|
|
|
- name: '下移',
|
|
|
- icon: 'fa-arrow-down',
|
|
|
- disabled() {
|
|
|
- return !curNode || !curNode.canDownMove() || isConstructionFeeArea(curNode) || isConstructionFeeArea(curNode.nextSibling);
|
|
|
- },
|
|
|
- callback() {
|
|
|
- downMove(sheet, curNode);
|
|
|
- }
|
|
|
- },
|
|
|
+ /* upLevel: {
|
|
|
+ name: '升级',
|
|
|
+ icon: 'fa-arrow-left',
|
|
|
+ disabled() {
|
|
|
+ return !curNode || !curNode.canUpLevel() || isConstructionFeeArea(curNode);
|
|
|
+ },
|
|
|
+ callback() {
|
|
|
+ upLevel(sheet, curNode);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ downLevel: {
|
|
|
+ name: '降级',
|
|
|
+ icon: 'fa-arrow-right',
|
|
|
+ disabled() {
|
|
|
+ return !curNode || !curNode.canDownLevel() || isConstructionFeeArea(curNode) || isConstructionFeeArea(curNode.preSibling);
|
|
|
+ },
|
|
|
+ callback() {
|
|
|
+ downLevel(sheet, curNode);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ upMove: {
|
|
|
+ name: '上移',
|
|
|
+ icon: 'fa-arrow-up',
|
|
|
+ disabled() {
|
|
|
+ return !curNode || !curNode.canUpMove() || isConstructionFeeArea(curNode) || isConstructionFeeArea(curNode.preSibling);
|
|
|
+ },
|
|
|
+ callback() {
|
|
|
+ upMove(sheet, curNode);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ downMove: {
|
|
|
+ name: '下移',
|
|
|
+ icon: 'fa-arrow-down',
|
|
|
+ disabled() {
|
|
|
+ return !curNode || !curNode.canDownMove() || isConstructionFeeArea(curNode) || isConstructionFeeArea(curNode.nextSibling);
|
|
|
+ },
|
|
|
+ callback() {
|
|
|
+ downMove(sheet, curNode);
|
|
|
+ }
|
|
|
+ }, */
|
|
|
refresh: {
|
|
|
name: '刷新数据',
|
|
|
icon: 'fa-refresh',
|
|
@@ -420,6 +584,18 @@ const budgetSummaryObj = (() => {
|
|
|
init(projectObj.project.property.rootProjectID);
|
|
|
}
|
|
|
});
|
|
|
+ $('#budget-upLevel').click(() => {
|
|
|
+ upLevel();
|
|
|
+ });
|
|
|
+ $('#budget-downLevel').click(() => {
|
|
|
+ downLevel();
|
|
|
+ });
|
|
|
+ $('#budget-upMove').click(() => {
|
|
|
+ upMove();
|
|
|
+ });
|
|
|
+ $('#budget-downMove').click(() => {
|
|
|
+ downMove();
|
|
|
+ });
|
|
|
|
|
|
// 对外暴露
|
|
|
return {
|