|
@@ -9,6 +9,9 @@
|
|
|
*/
|
|
|
|
|
|
$(document).ready(() => {
|
|
|
+ const compareTypeKey = 'budget-compareType';
|
|
|
+ const stackedBarCoverKey = 'budget-stackedBarCover';
|
|
|
+ const stackedBarKey = 'budget-stackedBar';
|
|
|
autoFlashHeight();
|
|
|
const compareSpread = SpreadJsObj.createNewSpread($('#cost-compare')[0]);
|
|
|
const compareSheet = compareSpread.getActiveSheet();
|
|
@@ -18,15 +21,16 @@ $(document).ready(() => {
|
|
|
{title: '项目节编号', colSpan: '1', rowSpan: '2', field: 'code', hAlign: 0, width: 150, formatter: '@', cellType: 'tree'},
|
|
|
{title: '名称', colSpan: '1', rowSpan: '2', field: 'name', hAlign: 0, width: 230, formatter: '@'},
|
|
|
{title: '单位', colSpan: '1', rowSpan: '2', field: 'unit', hAlign: 1, width: 50, formatter: '@', cellType: 'unit'},
|
|
|
- {title: '投资估算|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'gu_dgn_qty', hAlign: 2, width: 80},
|
|
|
- {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'gu_dgn_price', hAlign: 2, width: 80, type: 'Number'},
|
|
|
- {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'gu_tp', hAlign: 2, width: 80, type: 'Number'},
|
|
|
- {title: '初步概算|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'gai_dgn_qty', hAlign: 2, width: 80},
|
|
|
- {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'gai_dgn_price', hAlign: 2, width: 80, type: 'Number'},
|
|
|
- {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'gai_tp', hAlign: 2, width: 80, type: 'Number'},
|
|
|
- {title: '施工图预算|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'yu_dgn_qty', hAlign: 2, width: 80},
|
|
|
- {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'yu_dgn_price', hAlign: 2, width: 80, type: 'Number'},
|
|
|
- {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'yu_tp', hAlign: 2, width: 80, type: 'Number'},
|
|
|
+ {title: '投资估算|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'gu_dgn_qty', hAlign: 2, width: 80, bc_type: 'number'},
|
|
|
+ {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'gu_dgn_price', hAlign: 2, width: 80, type: 'Number', bc_type: 'number'},
|
|
|
+ {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'gu_tp', hAlign: 2, width: 80, type: 'Number', bc_type: 'number'},
|
|
|
+ {title: '初步概算|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'gai_dgn_qty', hAlign: 2, width: 80, bc_type: 'number'},
|
|
|
+ {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'gai_dgn_price', hAlign: 2, width: 80, type: 'Number', bc_type: 'number'},
|
|
|
+ {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'gai_tp', hAlign: 2, width: 80, type: 'Number', bc_type: 'number'},
|
|
|
+ {title: '施工图预算|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'yu_dgn_qty', hAlign: 2, width: 80, bc_type: 'number'},
|
|
|
+ {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'yu_dgn_price', hAlign: 2, width: 80, type: 'Number', bc_type: 'number'},
|
|
|
+ {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'yu_tp', hAlign: 2, width: 80, type: 'Number', bc_type: 'number'},
|
|
|
+ {title: '数据对比', colSpan: '1', rowSpan: '2', field: 'stackedBar', hAlign: 0, width: 300, cellType: 'stackedBar', stackedBarCover: false, bc_type: 'grid', visible: false},
|
|
|
],
|
|
|
emptyRows: 0,
|
|
|
headRows: 2,
|
|
@@ -41,28 +45,38 @@ $(document).ready(() => {
|
|
|
|
|
|
};
|
|
|
sjsSettingObj.setFxTreeStyle(spreadSetting, sjsSettingObj.FxTreeStyle.jz);
|
|
|
- SpreadJsObj.initSheet(compareSheet, spreadSetting);
|
|
|
-
|
|
|
let sfSelect;
|
|
|
const compareObj = {
|
|
|
curFinalId() {
|
|
|
return this.finalInfo ? this.finalInfo.id : undefined;
|
|
|
},
|
|
|
initFinalCol() {
|
|
|
- if (spreadSetting.cols.length < 13) {
|
|
|
+ if (spreadSetting.cols.length < 14) {
|
|
|
+ spreadSetting.cols.pop();
|
|
|
spreadSetting.cols.push(...[
|
|
|
- {title: '台账|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'dgn_qty', hAlign: 2, width: 80},
|
|
|
- {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'dgn_price', hAlign: 2, width: 80, type: 'Number'},
|
|
|
- {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'total_price', hAlign: 2, width: 80, type: 'Number'},
|
|
|
- {title: '决算|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'final_dgn_qty', hAlign: 2, width: 80},
|
|
|
- {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'final_dgn_price', hAlign: 2, width: 80, type: 'Number'},
|
|
|
- {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'final_tp', hAlign: 2, width: 80, type: 'Number'},
|
|
|
+ {title: '台账|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'dgn_qty', hAlign: 2, width: 80, bc_type: 'number'},
|
|
|
+ {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'dgn_price', hAlign: 2, width: 80, type: 'Number', bc_type: 'number'},
|
|
|
+ {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'total_price', hAlign: 2, width: 80, type: 'Number', bc_type: 'number'},
|
|
|
+ {title: '决算|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'final_dgn_qty', hAlign: 2, width: 80, bc_type: 'number'},
|
|
|
+ {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'final_dgn_price', hAlign: 2, width: 80, type: 'Number', bc_type: 'number'},
|
|
|
+ {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'final_tp', hAlign: 2, width: 80, type: 'Number', bc_type: 'number'},
|
|
|
+ {title: '数据对比', colSpan: '1', rowSpan: '2', field: 'stackedBar', hAlign: 0, width: 300, cellType: 'stackedBar', stackedBarCover: false, bc_type: 'grid', visible: false},
|
|
|
{title: '增幅%|数量1/数量2', colSpan: '2|1', rowSpan: '1|1', field: 'grow_dgn_qty', hAlign: 2, width: 80},
|
|
|
{title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'grow_tp', hAlign: 2, width: 80, type: 'Number'},
|
|
|
]);
|
|
|
+ this.initShowType();
|
|
|
SpreadJsObj.reLoadSheetHeader(compareSheet);
|
|
|
};
|
|
|
},
|
|
|
+ initShowType() {
|
|
|
+ const type = this.compareType;
|
|
|
+ spreadSetting.cols.forEach(x => {
|
|
|
+ if (!x.bc_type) return;
|
|
|
+ x.visible = x.bc_type === type;
|
|
|
+ });
|
|
|
+ const colIndex = spreadSetting.cols.findIndex(x => { return x.field === 'stackedBar'});
|
|
|
+ spreadSetting.cols[colIndex].stackedBarCover = parseInt(this.stackedBarCover);
|
|
|
+ },
|
|
|
expand(tree, tag) {
|
|
|
switch (tag) {
|
|
|
case "1":
|
|
@@ -77,6 +91,37 @@ $(document).ready(() => {
|
|
|
break;
|
|
|
}
|
|
|
},
|
|
|
+ calcStackedBar(tree) {
|
|
|
+ const calcField = this.stackedBarField;
|
|
|
+ const calcFieldColor = { 'gu_tp': '#657798', 'gai_tp': '#EE6666', 'yu_tp': '#74CBED', 'total_price': '#FAC858', 'final_tp': '#62DAAB' };
|
|
|
+ const calc = function(node, base){
|
|
|
+ // const parent = tree.getParent(node);
|
|
|
+ // if (!parent) {
|
|
|
+ // base = 0;
|
|
|
+ // for (const cf of calcField) {
|
|
|
+ // base = Math.max(node[cf], base);
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ node.stackedBar = [];
|
|
|
+ for (const cf of calcField) {
|
|
|
+ node.stackedBar.push({color: calcFieldColor[cf], percent: ZhCalc.div(node[cf], base), field: cf});
|
|
|
+ }
|
|
|
+ if (node.children) {
|
|
|
+ for (const child of node.children) {
|
|
|
+ calc(child, base);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ let commonBase = 0;
|
|
|
+ tree.children.forEach(x => {
|
|
|
+ for (const cf of calcField) {
|
|
|
+ commonBase = Math.max(x[cf], commonBase);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ for (const child of tree.children) {
|
|
|
+ calc(child, commonBase);
|
|
|
+ }
|
|
|
+ },
|
|
|
loadBudgetData(result) {
|
|
|
const compareTree = createNewPathTree('final', {
|
|
|
id: 'id',
|
|
@@ -136,6 +181,7 @@ $(document).ready(() => {
|
|
|
});
|
|
|
const expandTag = getLocalCache('revise-compare-level');
|
|
|
if (expandTag) compareObj.expand(compareTree, expandTag);
|
|
|
+ this.calcStackedBar(compareTree);
|
|
|
SpreadJsObj.loadSheetData(compareSheet, SpreadJsObj.DataType.Tree, compareTree);
|
|
|
},
|
|
|
loadFinalData(result, msg) {
|
|
@@ -153,10 +199,50 @@ $(document).ready(() => {
|
|
|
finalTree.loadDatas(result.final);
|
|
|
const expandTag = getLocalCache('revise-compare-level');
|
|
|
if (expandTag) compareObj.expand(finalTree, expandTag);
|
|
|
+ this.calcStackedBar(finalTree);
|
|
|
SpreadJsObj.loadSheetData(compareSheet, SpreadJsObj.DataType.Tree, finalTree);
|
|
|
if (sfSelect) sfSelect.reloadSelect(this.finalInfo.tender);
|
|
|
},
|
|
|
+ loadCacheData(){
|
|
|
+ let stackedBarCache = getLocalCache(stackedBarKey);
|
|
|
+ if (stackedBarCache === null) stackedBarCache = 'gai_tp,total_price,final_tp';
|
|
|
+ this.setStackedBarField(stackedBarCache ? stackedBarCache.split(',') : []);
|
|
|
+ this.setCompareType(getLocalCache(compareTypeKey));
|
|
|
+ this.setStackedBarCover(getLocalCache(stackedBarCoverKey));
|
|
|
+ this.initShowType();
|
|
|
+ },
|
|
|
+ setStackedBarField(field){
|
|
|
+ this.stackedBarField = field;
|
|
|
+ setLocalCache(stackedBarKey, field.join(','));
|
|
|
+ if (compareSheet.zh_tree) this.calcStackedBar(compareSheet.zh_tree);
|
|
|
+ const colIndex = spreadSetting.cols.findIndex(x => { return x.field === 'stackedBar'});
|
|
|
+ SpreadJsObj.reloadColData(compareSheet, colIndex);
|
|
|
+ },
|
|
|
+ setCompareType(type) {
|
|
|
+ this.compareType = type;
|
|
|
+ $('[name=showType]').removeClass('active');
|
|
|
+ $(`[tag=${type}]`).addClass('active');
|
|
|
+ if (this.compareType === 'grid') {
|
|
|
+ $('.ml-auto').show();
|
|
|
+ } else {
|
|
|
+ $('.ml-auto').hide();
|
|
|
+ }
|
|
|
+ spreadSetting.cols.forEach(x => {
|
|
|
+ if (!x.bc_type) return;
|
|
|
+ x.visible = x.bc_type === type;
|
|
|
+ });
|
|
|
+ setLocalCache(compareTypeKey, type);
|
|
|
+ },
|
|
|
+ setStackedBarCover(cover){
|
|
|
+ this.stackedBarCover = cover || '1';
|
|
|
+ const colIndex = spreadSetting.cols.findIndex(x => { return x.field === 'stackedBar'});
|
|
|
+ spreadSetting.cols[colIndex].stackedBarCover = parseInt(cover);
|
|
|
+ SpreadJsObj.reloadColData(compareSheet, colIndex);
|
|
|
+ setLocalCache(stackedBarCoverKey, cover);
|
|
|
+ }
|
|
|
};
|
|
|
+ compareObj.loadCacheData();
|
|
|
+ SpreadJsObj.initSheet(compareSheet, spreadSetting);
|
|
|
|
|
|
function compareCode(str1, str2, symbol = '-') {
|
|
|
if (!str1) {
|
|
@@ -322,4 +408,24 @@ $(document).ready(() => {
|
|
|
$('#select-final').on('shown.bs.modal', () => {
|
|
|
if (!sfSelect) sfSelect = new sfObject();
|
|
|
});
|
|
|
+ $('#stackedBar-ok').click(function() {
|
|
|
+ const checked = $('[name=stackedBar]:checked');
|
|
|
+ const field = [];
|
|
|
+ checked.each((i, x) => { field.push(x.value)});
|
|
|
+ compareObj.setStackedBarField(field);
|
|
|
+ });
|
|
|
+ $('#dp-stackedBar').click(function() {
|
|
|
+ const field = compareObj.stackedBarField;
|
|
|
+ const checked = $('[name=stackedBar]');
|
|
|
+ checked.each((i, x) => { x.checked = field.indexOf(x.value) >= 0; });
|
|
|
+ });
|
|
|
+ $('a[name=showType]').click(function () {
|
|
|
+ const type = this.getAttribute('tag');
|
|
|
+ compareObj.setCompareType(type);
|
|
|
+ SpreadJsObj.refreshColumnVisible(compareSheet);
|
|
|
+ });
|
|
|
+ $('a[name=stackedBarCover]').click(function() {
|
|
|
+ const cover = this.getAttribute('tag');
|
|
|
+ compareObj.setStackedBarCover(cover);
|
|
|
+ })
|
|
|
});
|