'use strict'; /** * * * @author Zhong * @date 2018/6/11 * @version */ //清单指引/精灵获取完清单数据后的回调函数 let doAfterLoadGuidance = null; const billsGuidance = (function () { const libSel = $('#stdBillsGuidanceLibSelect'); //工作内容 let stdBillsJobData = []; //项目特征 let stdBillsFeatureData = []; const bills = { dom: $('#billsGuidance_bills'), workBook: null, cache: [], tree: null, controller: null, treeSetting: { emptyRowHeader: true, rowHeaderWidth: 15, treeCol: 0, emptyRows: 0, headRows: 1, headRowHeight: [40], defaultRowHeight: 21, cols: [{ width: 140, readOnly: true, showHint: true, head: { titleNames: ["项目编码"], spanCols: [1], spanRows: [1], vAlign: [1], hAlign: [1], font: ["Arial"] }, data: { field: "code", vAlign: 1, hAlign: 0, font: "Arial" } }, { width: 190, readOnly: true, head: { titleNames: ["项目名称"], spanCols: [1], spanRows: [1], vAlign: [1], hAlign: [1], font: ["Arial"] }, data: { field: "name", vAlign: 1, hAlign: 0, font: "Arial" } }, { width: 45, readOnly: true, head: { titleNames: ["计量单位"], spanCols: [1], spanRows: [1], vAlign: [1], hAlign: [1], font: ["Arial"] }, data: { field: "unit", vAlign: 1, hAlign: 1, font: "Arial" } } ] }, headers: [ {name: '项目编码', dataCode: 'code', width: 140, vAlign: 'center', hAlign: 'left', formatter: '@'}, {name: '项目名称', dataCode: 'name', width: 190, vAlign: 'center', hAlign: 'left', formatter: '@'}, {name: '单位', dataCode: 'unit', width: 45, vAlign: 'center', hAlign: 'center', formatter: '@'}, ], rowHeaderWidth:1, events: { CellDoubleClick: function (sender, args) { if(!bills.tree){ return; } let node = bills.tree.items[args.row]; if(!node){ return; } if(node.children.length > 0){ node.setExpanded(!node.expanded); //设置展开收起状态 sessionStorage.setItem('stdBillsGuidanceExpState', bills.tree.getExpState(bills.tree.items)); renderSheetFunc(args.sheet, function () { let iCount = node.posterityCount(), i, child; for (i = 0; i < iCount; i++) { child = bills.tree.items[args.row + i + 1]; args.sheet.setRowVisible(args.row + i + 1, child.visible, args.sheetArea); } args.sheet.invalidateLayout(); }); args.sheet.repaint(); } else if(!projectReadOnly) { billsLibObj.insertBills(stdBillsJobData, stdBillsFeatureData, node); } } } }; const options = { workBook: { tabStripVisible: false, allowContextMenu: false, allowCopyPasteExcelStyle : false, allowExtendPasteRange: false, allowUserDragDrop : false, allowUserDragFill: false, scrollbarMaxAlign : true }, sheet: { protectionOptions: {allowResizeRows: true, allowResizeColumns: true}, clipBoardOptions: GC.Spread.Sheets.ClipboardPasteOptions.values } }; //渲染时方法,停止渲染 //@param {Object}sheet {Function}func @return {void} function renderSheetFunc(sheet, func){ sheet.suspendEvent(); sheet.suspendPaint(); if(func){ func(); } sheet.resumeEvent(); sheet.resumePaint(); } //设置表选项 //@param {Object}workBook {Object}opts @return {void} function setOptions (workBook, opts) { for(let opt in opts.workBook){ workBook.options[opt] = opts.workBook[opt]; } for(let opt in opts.sheet){ workBook.getActiveSheet().options[opt] = opts.sheet[opt]; } } //建表头 //@param {Object}sheet {Array}headers @return {void} function buildHeader(sheet, headers) { let fuc = function () { sheet.setColumnCount(headers.length); sheet.setRowHeight(0, 30, GC.Spread.Sheets.SheetArea.colHeader); for(let i = 0, len = headers.length; i < len; i++){ sheet.setValue(0, i, headers[i].name, GC.Spread.Sheets.SheetArea.colHeader); sheet.setColumnWidth(i, headers[i].width, GC.Spread.Sheets.SheetArea.colHeader); if(headers[i].formatter){ sheet.setFormatter(-1, i, headers[i].formatter); } sheet.getRange(-1, i, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[headers[i]['hAlign']]); sheet.getRange(-1, i, -1, 1).vAlign(GC.Spread.Sheets.VerticalAlign[headers[i]['vAlign']]); } }; renderSheetFunc(sheet, fuc); } //表监听事件 //@param {Object}workBook @return {void} function bindEvent(workBook, events) { if(Object.keys(events).length === 0){ return; } const Events = GC.Spread.Sheets.Events; for(let event in events){ workBook.bind(Events[event], events[event]); } } //建表 //@param {Object}module @return {void} function buildSheet(module) { if(!module.workBook){ module.workBook = new GC.Spread.Sheets.Workbook(module.dom[0], {sheetCount: 1}); sheetCommonObj.spreadDefaultStyle(module.workBook); let sheet = module.workBook.getActiveSheet(); if(module === bills){ //默认初始可控制焦点在清单表中 sheet.options.rowHeaderVisible = false; module.workBook.focus(); sheet.options.isProtected = true; sheet.name('stdBillsGuidance_bills'); //设置悬浮提示 TREE_SHEET_HELPER.initSetting(bills.dom[0], bills.treeSetting); } if(module.rowHeaderWidth) { sheet.setColumnWidth(0, module.rowHeaderWidth, GC.Spread.Sheets.SheetArea.rowHeader); } setOptions(module.workBook, options); buildHeader(module.workBook.getActiveSheet(), module.headers); bindEvent(module.workBook, module.events); } } //初始化各工作表 //@param {Array}modules @return {void} function initWorkBooks(modules){ for(let module of modules){ buildSheet(module); } } //点击清单名称后面的问号,弹出补注窗口并设置当前节点(或xxx父节点)的补注 //@param {Number}row(当前焦点行) @return {void} function initRechargeModal(row) { let node = bills.tree.items[row]; while (node && !node.data.recharge){ node = node.parent; } let recharge = node && node.data.recharge ? node.data.recharge : '无内容'; node = bills.tree.items[row]; while (node && !node.data.ruleText){ node = node.parent; } let ruleText = node && node.data.ruleText ? node.data.ruleText : '无内容'; $('#questionTab1').text('补注'); $('#questionTab2').text('工程量计算规则'); $('#questionContent1').html(recharge); $('#questionContent2').html(ruleText); $('#questionModal').modal('show'); } //节点链上含有补注或工程量计算规则数据 //@param {Number}row(行当前行) @return {Boolean} function hasRechargeRuleText(row) { let node = bills.tree.items[row]; if (!node) { return false; } while (node) { if (node.data.recharge || node.data.ruleText) { return true; } node = node.parent; } return false; } //初始化并输出树 //@param {Object}module {Object}sheet {Object}treeSetting {Array}datas function initTree(module, sheet, treeSetting, datas){ module.tree = idTree.createNew({id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1, autoUpdate: true}); module.controller = TREE_SHEET_CONTROLLER.createNew(module.tree, sheet, treeSetting, false); module.tree.loadDatas(datas); if(module === bills){ initExpandStat(); } module.controller.showTreeData(); if(module === bills){ module.workBook.getSheet(0).options.rowHeaderVisible = true; setBillsHint(bills.tree.items, stdBillsJobData, stdBillsFeatureData); renderSheetFunc(sheet, function () { for(let i = 0; i < bills.tree.items.length; i++){ sheet.setCellType(i, 1, TREE_SHEET_HELPER.getQuestionCellType(initRechargeModal, hasRechargeRuleText)); } }); } } //初始化清单的工作内容和项目特征 //@param {Number}billsLibId {Function}callback @return {void} function initJobAndCharacter(billsLibId, callback){ CommonAjax.post('/stdBillsEditor/getJobContent', {userId: userID, billsLibId: billsLibId}, function (datas) { stdBillsJobData = datas; CommonAjax.post('/stdBillsEditor/getItemCharacter', {userId: userID, billsLibId: billsLibId}, function (datas) { stdBillsFeatureData = datas; if(callback){ callback(); } }); }); } //初始化清单展开收起状态 //@return {void} function initExpandStat(){ //读取展开收起状态 let currentExpState = sessionStorage.getItem('stdBillsGuidanceExpState'); if(currentExpState){ bills.tree.setExpandedByState(bills.tree.items, currentExpState); } //非叶子节点默认收起 else{ bills.tree.setRootExpanded(bills.tree.roots, false); } } //设置tag以悬浮提示 function setTagForHint(nodes){ let sheet = bills.workBook.getActiveSheet(); renderSheetFunc(sheet, function () { for(let node of nodes){ sheet.setTag(node.serialNo(), 2, node.data.ruleText ? node.data.ruleText : ''); } }); } //根据编码定位至清单精灵库中 //@param {String}code @return {void} function locateAtBills(code) { let nineCode = code.substring(0, 9); let items = bills.tree.items; let locateBills = _.find(items, function(item){ return item.data.code === nineCode; }); if(locateBills){ expandSearchNodes([locateBills]); sessionStorage.setItem('stdBillsGuidanceExpState', bills.tree.getExpState(bills.tree.items)); } let sheet = bills.workBook.getActiveSheet(); let locateRow = locateBills ? locateBills.serialNo() : 0; sheet.setActiveCell(locateRow, 0); sheet.showRow(locateRow, GC.Spread.Sheets.VerticalPosition.center); } //清单设置悬浮提示信息 //@param {Array}billsNodes(清单节点) {Array}jobs(总的工作内容数据) {Array}items(总的项目特征数据) function setBillsHint(billsNodes, jobs, items) { let jobsMapping = {}, itemsMapping = {}; for(let job of jobs){ jobsMapping[job.id] = job; } for(let item of items){ itemsMapping[item.id] = item; } let tagInfo = []; for(let billsNode of billsNodes){ let hintArr = []; let billsItems = billsNode.data.items; if(billsItems.length > 0){ //项目特征 hintArr.push('项目特征:'); } let itemCount = 1, jobCount = 1; for(let billsItem of billsItems){ let itemData = itemsMapping[billsItem.id]; if(itemData){ //特征值 let eigens = []; for(let eigen of itemData.itemValue){ eigens.push(eigen.value); } eigens = eigens.join(';'); hintArr.push(`${itemCount}.${itemData.content}${eigens === '' ? '' : ': ' + eigens}`); itemCount ++; } } //工作内容 let billsJobs = billsNode.data.jobs; if(billsJobs.length > 0){ hintArr.push('工作内容:'); } for(let billsJob of billsJobs){ let jobData = jobsMapping[billsJob.id]; if(jobData){ hintArr.push(`${jobCount}.${jobData.content}`); jobCount ++; } } if(hintArr.length > 0){ tagInfo.push({row: billsNode.serialNo(), value: hintArr.join('\n')}); } } let sheet = bills.workBook.getActiveSheet(); renderSheetFunc(sheet, function () { for(let tagI of tagInfo){ sheet.setTag(tagI.row, 0, tagI.value); } }); } //初始选择清单指引库 //@param {Number}libID @return {void} function libInitSel(libID,rcallback){ //获取清单 $.bootstrapLoading.start(); CommonAjax.post('/billsGuidance/api/getLibWithBills', {libID: libID, isGuidanceLib: false}, function(rstData){ initViews(); let callback = function () { initTree(bills, bills.workBook.getActiveSheet(), bills.treeSetting, rstData.bills); if(doAfterLoadGuidance){ doAfterLoadGuidance(); } if(rcallback)rcallback(); $.bootstrapLoading.end(); }; //获取清单库中的工作内容和项目特征 initJobAndCharacter(+libID, callback); }, function () { $.bootstrapLoading.end(); }); } //初始化清单指引库 //@param {Array}libDats @return {void} function initLibs(libDatas,callback){ libSel.empty(); if(!libDatas){ return; } let selectedLib = sessionStorage.getItem('stdBillsGuidance'); for(let libData of libDatas){ let opt = $('