| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429 |
- 'use strict';
- /**
- *
- *
- * @author Zhong
- * @date 2018/6/11
- * @version
- */
- //清单指引/精灵获取完清单数据后的回调函数
- let doAfterLoadGuidance = null;
- const billsGuidance = (function () {
- //更新类型
- const updateType = {update: 'update', create: 'create'};
- //库类型
- const libType = {'guidance': 1, 'elf': 2}; //清单指引、清单精灵
- const libSel = $('#stdBillsGuidanceLibSelect');
- //工作内容
- let stdBillsJobData = [];
- //项目特征
- let stdBillsFeatureData = [];
- //正在插入
- let isInserting = false;
- const bills = {
- dom: $('#billsGuidance_bills'),
- workBook: null,
- cache: [],
- tree: null,
- controller: null,
- treeSetting: {
- emptyRowHeader: true,
- rowHeaderWidth: 15,
- treeCol: 1,
- emptyRows: 0,
- headRows: 1,
- headRowHeight: [40],
- defaultRowHeight: 21,
- cols: [
- {
- width: 35,
- readOnly: false,
- showHint: false,
- head: {
- titleNames: ["选用"],
- spanCols: [1],
- spanRows: [1],
- vAlign: [1],
- hAlign: [1],
- font: ["Arial"]
- },
- data: {
- field: "select",
- vAlign: 1,
- hAlign: 1,
- font: "Arial"
- }
- },
- {
- width: 105,
- 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: 60,
- 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: 'select', width: 35, vAlign: 'center', hAlign: 'center', formatter: '@'},
- {name: '项目编码', dataCode: 'code', width: 105, vAlign: 'center', hAlign: 'left', formatter: '@'},
- {name: '项目名称', dataCode: 'name', width: 190, vAlign: 'center', hAlign: 'left', formatter: '@'},
- {name: '单位', dataCode: 'unit', width: 60, vAlign: 'center', hAlign: 'center', formatter: '@'},
- ],
- rowHeaderWidth:1,
- events: {
- ButtonClicked: function (sender, args) {
- if(args.sheet.isEditing()){
- args.sheet.endEdit(true);
- }
- if (args.col !== 0) {
- return;
- }
- const selectedNode = bills.tree.items[args.row];
- const curValue = args.sheet.getValue(args.row, args.col);
- let count = selectedNode.posterityCount();
- if (count) {
- renderSheetFunc(args.sheet, () => {
- let row = args.row;
- while (count--) {
- row++;
- args.sheet.setValue(row, args.col, curValue);
- }
- });
- }
- },
- CellDoubleClick: function (sender, args) {
- if (args.col === 0) {
- return;
- }
- if(!bills.tree){
- return;
- }
- let node = bills.tree.items[args.row];
- if(!node){
- return;
- }
- //展开收起(非最底层节点且双击的是第一列)
- if (args.col === 1 && 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 && !isInserting && !projectObj.project.isBillsLocked() && (![1].includes(args.col) || node.children.length === 0)) {
- //选中部分的最底层(只是选中部分的最底)
- let lowestNodes = [bills.tree.items[args.row]];
- insertBills(lowestNodes);
- }
- }
- }
- };
- // 获取对比树片段数据的方法,此方法可能会被覆盖,方法存在一个对象中,使得外部可以覆盖相关方法
- // 在农村公路2020中,主树对比片段与这里的逻辑是不相同的
- const overwrite = {
- getFragment() {
- return { parent: null, mainTreeFragment: projectObj.project.Bills.tree.roots }
- }
- };
- // 反转插入顺序
- // 正常顺序插入时,next数据可能还没插入,会造成错误,需要反过来插入
- // insertData为正向排好序的数据
- function reverseInsertData(insertData) {
- const reverseData = [];
- const parentMap = {};
- const IDMap = {};
- insertData.forEach(item => {
- IDMap[item.data.ID] = item;
- (parentMap[item.data.ParentID] || (parentMap[item.data.ParentID] = [])).push(item);
- });
- // 找到顶层数据: 数据中没有找不到对应parent的数据
- const topLevelData = insertData
- .filter(item => !IDMap[item.data.ParentID])
- .reverse();
- function getReverseData(items) {
- items.forEach(item => {
- reverseData.push(item);
- const children = parentMap[item.data.ID];
- if (children && children.length) {
- getReverseData(children.reverse());
- }
- })
- }
- getReverseData(topLevelData);
- return reverseData;
- }
- //插入清单
- async function insertBills(lowestNodes) {
- try {
- let selTree = getSelTree(lowestNodes);
- const { errMsg, parent, mainTreeFragment } = overwrite.getFragment();
- if (errMsg) {
- alert(errMsg);
- return;
- }
- let compareData = compareTree(parent, mainTreeFragment, selTree.roots);
- _chkBillsUnitPrice(compareData.postData); //设置指标基价(默认单价)
- let sheet = projectObj.mainSpread.getActiveSheet(),
- row = sheet.getActiveColumnIndex(),
- col = sheet.getActiveColumnIndex();
- if (compareData.postData.length > 0) {
- //如果插入的是固定清单,则需要判断该固定清单在造价书中是否已存在,造价书中不可存在相同的固定清单
- let fixedDatas = compareData.postData.filter((data) =>
- data.updateType === updateType.create && Array.isArray(data.updateData.flags));
- if (fixedDatas.length > 0) {
- //提示已存在此固定清单并且定位
- let firstFixed = fixedDatas[0].updateData;
- let existNode = projectObj.project.mainTree.items.find((node) =>
- node.data && node.data.flagsIndex && node.data.flagsIndex.fixed && node.data.flagsIndex.fixed.flag === firstFixed.flags[0].flag);
- if (existNode) {
- alert(`固定清单<strong>“${firstFixed.name}”</strong>已被第${existNode.serialNo() + 1}行清单占用。`);
- locateAtSpread(sheet, existNode.serialNo(), col);
- return;
- }
- }
- isInserting = true;
- await ajaxPost('/bills/insertBills', { postData: compareData.postData });
- // 更新前端树
- const toReverseData = [];
- const cacheData = [];
- compareData.postData.forEach(item => {
- const cacheItem = {
- type: ModuleNames.bills,
- action: item.updateType === updateType.create ? 'add' : 'update',
- data: item.updateData,
- }
- if (item.updateType === updateType.create) {
- toReverseData.push(cacheItem);
- } else {
- cacheData.push(cacheItem);
- }
- });
- cacheData.push(...reverseInsertData(toReverseData));
- console.log(cacheData);
- const nodes = projectObj.project.updateNodesCache(cacheData, false);
- projectObj.mainController.refreshTreeNode(nodes);
- row = nodes[nodes.length - 1].serialNo();
- //有新的节点插入,也有可能定位至旧节点(批量选用的情况下)
- if (compareData.locateNode) {
- //该清单节点在主树的位置
- row = projectObj.project.mainTree.nodes[projectObj.project.mainTree.prefix + compareData.locateNode.data.ID].serialNo();
- }
- locateAtSpread(sheet, row, col);
- } else if (compareData.locateNode) {
- //该清单节点在主树的位置
- row = projectObj.project.mainTree.nodes[projectObj.project.mainTree.prefix + compareData.locateNode.data.ID].serialNo();
- locateAtSpread(sheet, row, col);
- }
- } catch (err) {
- console.log(err);
- if (!$('hintBox_form').is(':visible')) {
- alert(err);
- }
- } finally {
- isInserting = false;
- $.bootstrapLoading.end();
- }
- }
- function locateAtSpread(sheet, row, col) {
- sheet.setSelection(row, col, 1, 1);
- projectObj.mainController.setTreeSelected(projectObj.mainController.tree.items[row]);//触发树节点选中事件
- sheet.showRow(row, GC.Spread.Sheets.VerticalPosition.center);
- }
- /*
- *
- * 1.选中的树结构(清单规则选中的节点及其所有父项)与主树对比(主树中节点“编码-名称-单位”与选中树~组合相同视为同一节点),
- * 将主树中不含有的选中节点全部插入
- * 2.插入位置由1对比得出,主树有与选中树结构相同层次结构的片段,这个相同片段为插入位置
- * 3.选中树结构除去相同片段,为需要插入的节点,插入时,遇到同层节点,根据编码的字符编码值确定顺序
- * a.code <= b.code,则a节点在b节点前
- * */
- //获取选中的树(将选中的节点及其所有父项,组合成一棵树,没有重复节点)
- //@param {Array}lowestNodes(选中的最底层节点) @return {Array}
- function getSelTree(lowestNodes) {
- let allNodes = [];
- //获取树上所有的节点
- for (let node of lowestNodes) {
- while (node && !allNodes.includes(node)) {
- allNodes.push(node);
- node = node.parent;
- }
- }
- // 根据原节点serialNo排序,排序后,后一项节点只可能前节点的后兄弟项,或子项
- allNodes.sort(function (a, b) {
- let aV = a.serialNo(),
- bV = b.serialNo();
- if (aV > bV) {
- return 1;
- } else if (aV < bV) {
- return -1;
- }
- return 0;
- });
- //生成树数据
- let treeData = [];
- //旧ID与新ID映射
- let IDMapping = {};
- const ParentIDMap = {};
- for (let i = 0; i < allNodes.length; i++) {
- //原节点
- let thisN = allNodes[i];
- let newNodeData = { code: thisN.data.code, name: thisN.data.name, ID: uuid.v1(), NextSiblingID: -1, ParentID: -1, orgID: thisN.data.ID };
- IDMapping[newNodeData.orgID] = newNodeData.ID;
- (ParentIDMap[thisN.data.ParentID] || (ParentIDMap[thisN.data.ParentID] = [])).push(newNodeData); // 兄弟节点已经拍好序(serialNo排序)
- treeData.push(newNodeData);
- }
- // 重新设置ParentID、NextSiblingID
- for (const orgParentID in ParentIDMap) {
- const newNodeDatas = ParentIDMap[orgParentID];
- const newParentID = orgParentID == -1 ? -1 : IDMapping[orgParentID];
- newNodeDatas.forEach((newNodeData, index) => {
- newNodeData.ParentID = newParentID;
- const preNewNodeData = newNodeDatas[index - 1];
- if (preNewNodeData) {
- preNewNodeData.NextSiblingID = newNodeData.ID;
- }
- });
- }
- let selTree = idTree.createNew({id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1, autoUpdate: true});
- selTree.loadDatas(treeData);
- return selTree;
- }
- /*
- * 选中树与清单主树进行对比,(自上而下,从roots开始)获取插入、更新数据
- * 找到的清单树中清单子项含有非清单项或输入了计算基数,则中止该清单的对比,不可插入数据
- * */
- const firstBillsSymbol = Symbol('第一行固定清单');
- //获取节点的匹配数据:编码-名称-单位
- //@param {Object}node @return {String}
- function getMatchContent(node) {
- // 标准清单第一个根节点与项目清单第一个根节点写死能对应匹配上
- const firstStdNode = bills.tree.roots[0];
- const firstProjectNode = projectObj.project.Bills.tree.roots[0];
- if (node === firstStdNode || node === firstProjectNode) {
- return firstBillsSymbol;
- }
- return `${node.data.code ? node.data.code : '*'}-${node.data.name ? node.data.name : '*'}-${node.data.unit ? node.data.unit : '*'}`;
- }
- //**对比清单主树节点片段与选中树节点片段,获取需要更新和插入的数据**
- //@param {Object}parent - 主树片段的父节点 {Array}mainTreeFragment {Array}stdTreeFragment
- function compareTree(parent, mainTreeFragment, stdTreeFragment) {
- //需要插入、更新的数据
- let postData = [],
- //跟树结构自动定位至的清单节点(最近匹配到的节点)
- locateNode = null;
- if (!mainTreeFragment || !stdTreeFragment) {
- return postData;
- }
- comparePeer(parent, mainTreeFragment, stdTreeFragment);
- return {postData, locateNode};
- /*
- * 该清单节点是否可以继续往下递归匹配,即该节点是否还可插入子项(在该层匹配到的时候判断)
- * 1.该底层节点不能含有非清单子项
- * 2.该节点不能含有计算基数
- * todo 3.数量单价等相关概念,等有了补上
- * @param {Object}billsNode(清单树中的某节点) @return {Boolean}
- * */
- function canRecursive(billsNode) {
- //主树节点含有子节点,清单节点不含子节点,说明该节点含有非清单子项
- //这里需要去mainTree查,不能在清单树查,因为清单树的节点children里只会有清单,就算实际上有定额,这个children里也不含该定额
- let mainTreeNode = projectObj.project.mainTree.getNodeByID(billsNode.data.ID);
- if (!mainTreeNode) {
- return false;
- }
- if (mainTreeNode && mainTreeNode.children.length > 0 && billsNode.children.length === 0) {
- return false;
- } else if (billsNode.data.calcBase) {
- return false;
- }
- return true;
- }
- //获取某选中节点要往清单主树同层插入的位置
- function insertPos(peerNodes, node) {
- //node选中树中没有记录原清单的数据,只记录了原清单ID,需要node的数据,则要找回原清单
- let orgNode = bills.tree.nodes[`${bills.tree.prefix}${node.data.orgID}`];
- if (!orgNode) {
- return -1;
- }
- let insertCode = orgNode.data.code ? orgNode.data.code : '';
- //插入最顶层节点或者无编码,对比选中节点后兄弟节点和同层主树节点的名称,插在的匹配的节点前面
- function mathNext(selNode, compareNodes) {
- let selNext = selNode.nextSibling;
- while (selNext) {
- for (let i = 0; i < compareNodes.length; i++) {
- if (compareNodes[i].data.name === selNext.data.name) {
- return i;
- }
- }
- selNext = selNext.nextSibling;
- }
- return compareNodes.length;
- }
- if (orgNode.depth() === 0 || insertCode === '') {
- return mathNext(orgNode, peerNodes);
- //return peerNodes.length;
- }
- // 比较编码大小,可能需要对比xx-xx xx-xx-xx ....
- function compareCode(codeA, codeB) {
- const codeASplits = codeA.split('-');
- const codeBSplits = codeB.split('-');
- const count = Math.max(codeASplits.length, codeBSplits.length);
- for (let i = 0; i < count; i++) {
- const perA = codeASplits[i];
- const perB = codeBSplits[i];
- if (perA && !perB) {
- return 1;
- } else if (!perA && perB) {
- return -1;
- } else if (perA && perB) {
- const numberCompare = !isNaN(perA) && !isNaN(perB);
- const compareRst = numberCompare ? +perA - +perB : perA.localeCompare(perB);
- if (compareRst === 0) {
- continue;
- } else {
- return compareRst;
- }
- }
- }
- }
- for (let i = 0; i < peerNodes.length; i++) {
- let thisNode = peerNodes[i];
- let thisCode = thisNode.data.code ? thisNode.data.code : '';
- //确定同层节点的顺序,编码小于等于在前,大于在后
- const compareRst = compareCode(insertCode, thisCode);
- if (compareRst <= 0) {
- return i;
- } else {
- continue;
- }
- }
- /* for (let i = 0; i < peerNodes.length; i++) {
- let thisNode = peerNodes[i];
- let thisCode = thisNode.data.code ? thisNode.data.code : '';
- //确定同层节点的顺序,编码小于等于在前,大于在后
- if (insertCode <= thisCode) {
- return i;
- } else if (insertCode > thisCode) {
- continue;
- }
- } */
- return peerNodes.length;
- }
- //获取插入清单数据
- function getInsertData(insertObj) {
- let stdNode = bills.tree.nodes[`${bills.tree.prefix}${insertObj.orgID}`];
- if (!stdNode) {
- return null;
- }
- let stdData = {};
- stdData.projectID = projectObj.project.projectInfo.ID;
- stdData.isAdd = 1;
- stdData.ID = insertObj.ID;
- stdData.ParentID = insertObj.ParentID;
- stdData.NextSiblingID = insertObj.NextSiblingID;
- //顶层节点是大项费用
- stdData.type = stdNode.parent ? billType.BILL : billType.DXFY;
- stdData.code = stdNode.data.code;
- stdData.name = stdNode.data.name;
- stdData.unit = stdNode.data.unit;
- stdData.ruleText = stdNode.data.ruleText;
- stdData.comments = stdNode.data.comments;
- stdData.programID = stdNode.data.engineering;
- stdData.billsLibId = stdNode.data.billsLibId;
- if (stdNode.data.fixedFlag) {
- stdData.flags = [{flag : stdNode.data.fixedFlag, fieldName : 'fixed'}];
- stdData.flagsIndex = {fixed: {fieldName: 'fixed', flag: stdNode.data.fixedFlag}}; //前端用
- }
- if (projectObj.project.property.valuationType === commonConstants.ValuationType.BOQ) {
- stdData.unitPriceAnalysis = 1;
- }
- return stdData;
- }
- //从同层节点中获取更新数据
- //@param {Object}parentNode(同层节点挂载的父节点,清单主树中) {Array}peerNodes(同层节点,含有清单树和选中树节点)
- // {Array}billsNodes(该层清单树节点) {Array}selNodes(该层选中树节点) @return {Array}
- function getUpdateDataFromPeer(parentNode, peerNodes, billsNodes, selNodes) {
- let rst = [];
- //向下获取插入数据直到最底层
- function getDataTillDeepest(node) {
- if (node) {
- let insertData = getInsertData(node.data);
- if (insertData) {
- rst.push({updateType: updateType.create, updateData: insertData});
- }
- for (let child of node.children) {
- getDataTillDeepest(child);
- }
- }
- }
- for (let i = 0; i < peerNodes.length; i++) {
- let thisNode = peerNodes[i],
- nextNode = peerNodes[i + 1];
- //更新原清单节点NextSiblingID
- if (billsNodes.includes(thisNode) && selNodes.includes(nextNode)) {
- rst.push({updateType: updateType.update, updateData: {ID: thisNode.data.ID, NextSiblingID: nextNode.data.ID}});
- } else if (selNodes.includes(thisNode) && billsNodes.includes(nextNode)) { //变更选中节点的NextSiblingID
- thisNode.data.NextSiblingID = nextNode.data.ID;
- }
- //所有选中的同层节点设为清单树父节点的子项,获取插入数据(插入该同层节点及其所有子节点)
- if (selNodes.includes(thisNode)) {
- thisNode.data.ParentID = parentNode ? parentNode.data.ID : -1;
- getDataTillDeepest(thisNode);
- }
- }
- return rst;
- }
- //同层节点之间比较,匹配到的则继续往下匹配,匹配不到的节点则按照规定的顺序进行排序,插入更新(更新清单树节点中NextSiblingID改变的节点)
- function comparePeer(parentNode, billsNodes, selNodes) {
- let peerNodes = [].concat(billsNodes); //同层节点
- let matchNode = null; //匹配到的清单主树节点
- for (let selNode of selNodes) {
- let stdNode = bills.tree.nodes[`${bills.tree.prefix}${selNode.data.orgID}`],
- selMatch = getMatchContent(stdNode),
- isMatched = false;
- for( let billsNode of billsNodes) {
- let billsMatch = getMatchContent(billsNode);
- if (selMatch === billsMatch) {//只进行一次成功匹配
- // 特殊处理:如果匹配成功,但是清单名称不同,将造价书清单的名称设成清单库中的清单名称
- const stdName = selNode.data.name || '';
- const billsName = billsNode.data.name || '';
- if (billsName !== stdName) {
- postData.push({updateType: updateType.update, updateData: {ID: billsNode.data.ID, name: stdName}});
- }
- matchNode = billsNode;
- isMatched = true;
- if (selNode.children.length === 0) {//成功匹配且为选中的最底节点,则为自动定位节点
- locateNode = matchNode;
- }
- break;
- }
- }
- if (isMatched && canRecursive(matchNode)) {//匹配成功,且该匹配到的节点可插入子项,递归匹配子项
- comparePeer(matchNode, matchNode.children, selNode.children);
- } else if (!isMatched) { //匹配不成功,其节点与该层清单节点同层,根据编码插入同层数组中
- let pos = insertPos(peerNodes, selNode);
- if (pos >= 0) {
- peerNodes.splice(pos, 0, selNode);
- }
- }
- }
- //同层节点比清单树节点多了,说明在该层有选中节点插入清单树中
- if (peerNodes.length > billsNodes.length) {
- let updateData = getUpdateDataFromPeer(parentNode, peerNodes, billsNodes, selNodes);
- postData = postData.concat(updateData);
- }
- }
- }
- function _chkBillsUnitPrice(billsNodes) {
- if (billsUnitPriceFeature !== null) {
- for (const node of billsNodes) {
- if (node.updateType === 'create') {
- //只有创建的才设置初始化单价
- const _chkKeys = function(keys) {
- let rst = false;
- for (const subKey of keys) {
- let isPrjFeatureMatch = false;
- for (let prjF of projectObj.project.projectInfo.property.projectFeature) {
- if (prjF.key === bmsK.key) {
- if (prjF.value === bmsK.value) {
- isPrjFeatureMatch = true;
- // isKeyMatch = true;
- break;
- } else {
- //key相同而value不同,则无需再循环,直接退出
- break;
- }
- }
- }
- if (isPrjFeatureMatch) {
- rst = true;
- break;
- }
- }
- return rst;
- };
- let isMatch = true;
- // 1. 基本数量
- // 先判断此bills是否有配置
- for (const bm of billsUnitPriceFeature.feature.basicMappings) {
- if (bm.parentBasicKeys.length === billsUnitPriceFeature.feature.basicKeyOptions.length) {
- for (let kIdx = 0; kIdx < bm.parentBasicKeys.length; kIdx++) {
- if (bm.parentBasicKeys[kIdx] !== 'ALL' && node[billsUnitPriceFeature.feature.basicKeyOptions[kIdx]] !== bm.parentBasicKeys[kIdx]) {
- isMatch = false;
- break;
- }
- }
- } else {
- isMatch = false;
- break;
- }
- }
- let basicValue = 0;
- if (isMatch) {
- //再根据相关项目属性指定基数
- for (const bms of billsUnitPriceFeature.feature.basicMappings.subs) {
- if (_chkKeys(bms.keys)) {
- basicValue = bms.basicValue;
- break;
- }
- }
- }
- // 2. 相关系数(允许多个)
- let factors = [];
- isMatch = true;
- for (const fm of billsUnitPriceFeature.feature.factorMappings) {
- if (fm.basicFactorKeys.length === billsUnitPriceFeature.feature.basicKeyOptions.length) {
- for (let kIdx = 0; kIdx < fm.basicFactorKeys.length; kIdx++) {
- if (fm.basicFactorKeys[kIdx] !== 'ALL' && node[billsUnitPriceFeature.feature.basicKeyOptions[kIdx]] !== fm.basicFactorKeys[kIdx]) {
- isMatch = false;
- break;
- }
- }
- } else {
- isMatch = false;
- break;
- }
- }
- if (isMatch) {
- for (const fms of billsUnitPriceFeature.feature.factorMappings.subs) {
- if (_chkKeys(fms.keys)) {
- factors.push(fms.basicValue); // 允许多个
- }
- }
- }
- //3. 装配(指标基价 即 默认的清单单价)
- let unitFeeVal = basicValue;
- for (const factor of factors) {
- unitFeeVal = unitFeeVal * parseFloat(factor);
- }
- // 暂时未设小数位数 scMathUtil.roundTo(unitFeeVal,2);
- node.calcFlag = 2; //当用户输入单价
- if (!node.hasOwnProperty('fees')) {
- node.fees = [];
- }
- node.fees.push({fieldName: 'common', unitFee: unitFeeVal, totalFee: 0, tenderUnitFee: unitFeeVal, tenderTotalFee: 0});
- }
- }
- }
- }
- //项目指引类型
- const itemType = {
- job: 0,
- ration: 1
- };
- const guideItem = {
- dom: $('#billsGuidance_items'),
- workBook: null,
- tree: null,
- controller: null,
- treeSetting: {
- treeCol: 1,
- emptyRows: 0,
- headRows: 1,
- headRowHeight: [40],
- defaultRowHeight: 21,
- cols: [
- {
- width: 35,
- readOnly: false,
- head: {
- titleNames: ["选择"],
- spanCols: [1],
- spanRows: [1],
- vAlign: [1],
- hAlign: [1],
- font: ["Arial"]
- },
- data: {
- field: "select",
- vAlign: 1,
- hAlign: 1,
- font: "Arial"
- }
- },
- {
- width: 420,
- readOnly: false,
- head: {
- titleNames: ["项目指引"],
- spanCols: [1],
- spanRows: [1],
- vAlign: [1],
- hAlign: [1],
- font: ["Arial"]
- },
- data: {
- field: "name",
- vAlign: 1,
- hAlign: 0,
- font: "Arial"
- }
- }
- ]
- },
- headers: [
- {name: '选择', dataCode: 'select', width: 35, vAlign: 'center', hAlign: 'center', formatter: '@'},
- {name: '项目指引', dataCode: 'name', width: 300, vAlign: 'center', hAlign: 'left', formatter: '@'},
- ],
- rowHeaderWidth:25,
- events: {
- EditStarting: function (sender, args) {
- if(!bills.tree || guideItem.headers[args.col]['dataCode'] === 'name'){
- args.cancel = true;
- }
- },
- ButtonClicked: function (sender, args) {
- if(args.sheet.isEditing()){
- args.sheet.endEdit(true);
- }
- refreshInsertRation();
- },
- CellDoubleClick: function (sender, args) {
- if(!bills.tree || !bills.tree.selected){
- return;
- }
- let node = bills.tree.selected.guidance.tree.selected;
- if(!node){
- return;
- }
- if(node.children.length === 0){
- if(guideItem.headers[args.col]['dataCode'] === 'name'){
- insertRations(getInsertRationData([args.row]));
- }
- }
- else {
- node.setExpanded(!node.expanded);
- renderSheetFunc(args.sheet, function () {
- let iCount = node.posterityCount(), i, child;
- for (i = 0; i < iCount; i++) {
- child = bills.tree.selected.guidance.tree.items[args.row + i + 1];
- args.sheet.setRowVisible(args.row + i + 1, child.visible, args.sheetArea);
- }
- args.sheet.invalidateLayout();
- });
- args.sheet.repaint();
- }
- }
- }
- };
- const elfItem = {
- dom: $('#billsGuidance_items'),
- workBook: null,
- tree: null,
- controller: null,
- treeSetting: {
- treeCol: 0,
- emptyRows: 0,
- headRows: 1,
- headRowHeight: [40],
- defaultRowHeight: 21,
- cols: [
- {
- width: 250,
- readOnly: true,
- head: {
- titleNames: ["施工工序"],
- spanCols: [1],
- spanRows: [1],
- vAlign: [1],
- hAlign: [1],
- font: ["Arial"]
- },
- data: {
- field: "name",
- vAlign: 1,
- hAlign: 0,
- font: "Arial"
- }
- },
- {
- width: 250,
- readOnly: false,
- head: {
- titleNames: ["选项"],
- spanCols: [1],
- spanRows: [1],
- vAlign: [1],
- hAlign: [1],
- font: ["Arial"]
- },
- data: {
- field: "options",
- vAlign: 1,
- hAlign: 0,
- font: "Arial"
- }
- }
- ]
- },
- headers: [
- {name: '施工工序', dataCode: 'name', width: 250, rateWidth: 0.5, vAlign: 'center', hAlign: 'center', formatter: '@'},
- {name: '选项', dataCode: 'options', width: 250, rateWidth: 0.5, vAlign: 'center', hAlign: 'left', formatter: '@'},
- ],
- rowHeaderWidth:25,
- events: {
- CellClick: function (sender, args) {
- if(elfItem.headers[args.col]['dataCode'] === 'options' && args.sheetArea === 3){
- if(!args.sheet.getCell(args.row, args.col).locked() && !args.sheet.isEditing()){
- args.sheet.startEdit();
- }
- }
- },
- ClipboardPasting: function (sender, info) {
- info.cancel = true;
- }
- }
- };
- 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);
- //sheet.setColumnWidth(0, sheet.getParent() === bills.workBook ? 15 : 25, GC.Spread.Sheets.SheetArea.rowHeader);
- if(sheet.getParent() === elfItem.workBook || sheet.getParent() === guideItem.workBook){
- sheet.setRowHeight(0, 20, 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}workBook {Number}workBookWidth {Array}headers @return {void}
- function setColumnWidthByRate(workBook, workBookWidth, headers) {
- if(workBook){
- workBookWidth -= 48;
- const sheet = workBook.getActiveSheet();
- sheet.suspendEvent();
- sheet.suspendPaint();
- for(let col = 0; col < headers.length; col++){
- if(headers[col]['rateWidth'] !== undefined && headers[col]['rateWidth'] !== null && headers[col]['rateWidth'] !== ''){
- let width = workBookWidth * headers[col]['rateWidth'];
- if(headers[col]['dataCode'] === 'options'){
- width = width;
- }
- sheet.setColumnWidth(col, width, GC.Spread.Sheets.SheetArea.colHeader)
- }
- else {
- if(headers[col]['headerWidth'] !== undefined && headers[col]['headerWidth'] !== null && headers[col]['headerWidth'] !== ''){
- sheet.setColumnWidth(col, headers[col]['headerWidth'], GC.Spread.Sheets.SheetArea.colHeader)
- }
- }
- }
- sheet.resumeEvent();
- sheet.resumePaint();
- }
- }
- //建表
- //@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 === guideItem){
- sheet.options.isProtected = true;
- sheet.getRange(-1, 0, -1, 1).locked(false);
- sheet.getRange(-1, 1, -1, 1).locked(true);
- }
- if(module === elfItem){
- sheet.options.isProtected = true;
- sheet.getRange(-1, 0, -1, 1).locked(true);
- sheet.getRange(-1, 1, -1, 1).locked(false);
- }
- if(module.rowHeaderWidth) {
- sheet.setColumnWidth(0, module.rowHeaderWidth, GC.Spread.Sheets.SheetArea.rowHeader);
- }
- setOptions(module.workBook, options);
- buildHeader(module.workBook.getActiveSheet(), module.headers);
- if(module === elfItem){
- setColumnWidthByRate(elfItem.workBook, $('#zy').width(), elfItem.headers)
- }
- bindEvent(module.workBook, module.events);
- }
- }
- //清空表数据
- //@param {Object}sheet {Array}headers {Number}rowCount @return {void}
- function cleanData(sheet, headers, rowCount){
- renderSheetFunc(sheet, function () {
- sheet.clear(-1, 0, -1, headers.length, GC.Spread.Sheets.SheetArea.viewport, GC.Spread.Sheets.StorageType.data);
- if (rowCount > 0) {
- sheet.setRowCount(rowCount);
- }
- });
- }
- //初始化各工作表
- //@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('补注');
- $('#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 () {
- const checkBoxType = new GC.Spread.Sheets.CellTypes.CheckBox();
- for (let i = 0; i < bills.tree.items.length; i++) {
- sheet.setCellType(i, 0, checkBoxType);
- sheet.setCellType(i, 2, TREE_SHEET_HELPER.getQuestionCellType(initRechargeModal, hasRechargeRuleText));
- }
- });
- }
- }
- //项目指引表焦点控制
- //@param {Number}row @return {void}
- function guideItemInitSel(row){
- let billsNode = bills.tree.selected;
- let node = null;
- if(billsNode && billsNode.guidance.tree){
- node = billsNode.guidance.tree.items[row];
- if(node){
- billsNode.guidance.tree.selected = node;
- }
- }
- }
- //清单精灵表焦点控制
- //@param {Number}row @return {void}
- function elfItemInitSel(row){
- let billsNode = bills.tree.selected;
- let node = null;
- if(billsNode && billsNode.elf.tree){
- node = billsNode.elf.tree.items[row];
- if(node){
- billsNode.elf.tree.selected = node;
- }
- }
- }
- //根据项目指引的类型设置单元格类型,定额类型的项目指引为复选框
- //@param {Array}nodes @return {void}
- function setItemCellType(nodes){
- //设置单元格类型
- const base = new GC.Spread.Sheets.CellTypes.Base();
- const checkBox = new GC.Spread.Sheets.CellTypes.CheckBox();
- const sheet = guideItem.workBook.getActiveSheet();
- renderSheetFunc(sheet, function(){
- for(let node of nodes){
- sheet.setCellType(node.serialNo(), 0, node.data.type === itemType.ration ? checkBox : base);
- }
- });
- }
- //初始化清单的工作内容和项目特征
- //@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);
- // 默认展开第一个节点到第二层
- bills.tree.roots[0].setExpanded(true);
- }
- }
- //设置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(billsNode.data.ruleText && billsNode.data.ruleText !== ''){
- hintArr.push('工程量计算规则:');
- hintArr.push(billsNode.data.ruleText);
- }
- if(billsNode.data.recharge && billsNode.data.recharge !== ''){
- hintArr.push('补注:');
- hintArr.push(billsNode.data.recharge);
- }*/
- 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){
- //获取清单
- $.bootstrapLoading.start();
- CommonAjax.post('/billsGuidance/api/getLibWithBills', {libID: libID, isGuidanceLib: false}, function(rstData){
- if(guideItem.workBook){
- guideItem.workBook.destroy();
- guideItem.workBook = null;
- }
- if(elfItem.workBook){
- elfItem.workBook.destroy();
- elfItem.workBook = null;
- }
- initViews();
- let callback = function () {
- initTree(bills, bills.workBook.getActiveSheet(), bills.treeSetting, rstData.bills);
- if(doAfterLoadGuidance){
- doAfterLoadGuidance();
- }
- $.bootstrapLoading.end();
- };
- //获取清单库中的工作内容和项目特征
- initJobAndCharacter(libID, callback);
- }, function () {
- $.bootstrapLoading.end();
- });
- }
- //初始化清单指引库
- //@param {Array}libDats @return {void}
- function initLibs(libDatas){
- libSel.empty();
- if(!libDatas){
- return;
- }
- let selectedLib = sessionStorage.getItem('stdBillsGuidance');
- for(let libData of libDatas){
- let opt = $('<option>').val(libData.id).text(libData.name);
- if(selectedLib && libData.id == selectedLib){
- opt.attr('selected', 'selected');
- }
- libSel.append(opt);
- }
- //初始默认选择
- libInitSel(libSel.select().val());
- }
- //初始化视图
- //@param {void} @return {void}
- function initViews(){
- //赋初始高度
- if($('#billsGuidance_bills').height() === 0 || $('#billsGuidance_items').height() === 0){
- let height = $(window).height()-$(".header").height()-$(".toolsbar").height()-$(".tools-bar-height-z").height();
- $('#billsGuidance_bills').height(height / 2);
- $('#billsGuidance_items').height(height / 2);
- }
- let modules = [bills];
- modules.push(elfItem);
- initWorkBooks(modules);
- }
- //展开至搜索出来点的节点
- //@param {Array}nodes @return {void}
- function expandSearchNodes(nodes){
- let that = this;
- let billsSheet = bills.workBook.getActiveSheet();
- renderSheetFunc(billsSheet, function () {
- function expParentNode(node){
- if(node.parent){
- if (!node.parent.expanded) {
- node.parent.setExpanded(true);
- }
- expParentNode(node.parent);
- }
- }
- for(let node of nodes){
- expParentNode(node);
- }
- TREE_SHEET_HELPER.refreshTreeNodeData(bills.treeSetting, billsSheet, bills.tree.roots, true);
- TREE_SHEET_HELPER.refreshNodesVisible(bills.tree.roots, billsSheet, true);
- });
- }
- //各按钮监听事件
- //@return {void}
- function bindBtn(){
- //打开清单指引库
- $('#stdBillsGuidanceTab').click(function () {
- if(libSel.children().length === 0 && !$(this).hasClass('disabled')){
- initLibs(projectObj.project.projectInfo.engineeringInfo.bill_lib);
- }
- });
- //更改清单指引库
- $('#stdBillsGuidanceLibSelect').change(function () {
- //关闭搜索窗口
- $('#billsGuidanceSearchResult').hide();
- billsLibObj.clearHighLight(bills.workBook);
- libInitSel($(this).select().val());
- //记住选项
- sessionStorage.setItem('stdBillsGuidance', $(this).select().val());
- //清除展开收起状态sessionStorage
- sessionStorage.removeItem('stdBillsGuidanceExpState');
- });
- //搜索
- $('#stdBillsGuidanceSearch>div>button').click(function () {
- if(!bills.tree){
- return;
- }
- let billsSheet = bills.workBook.getActiveSheet();
- billsLibObj.clearHighLight(bills.workBook);
- let keyword = $('#stdBillsGuidanceSearch>input').val();
- if (!keyword || keyword === '') {
- $('#billsGuidanceSearchResult').hide();
- return;
- }
- let result = bills.tree.items.filter(function (item) {
- let codeIs = item.data.code ? item.data.code.indexOf(keyword) !== -1 : false;
- let nameIs = item.data.name ? item.data.name.indexOf(keyword) !== -1 : false;
- return codeIs || nameIs;
- });
- result.sort(function (x, y) {
- return x.serialNo() - y.serialNo();
- });
- if (result.length !== 0) {
- //展开搜索出来的节点
- expandSearchNodes(result);
- //设置记住展开
- sessionStorage.setItem('stdBillsGuidanceExpState', bills.tree.getExpState(bills.tree.items));
- let sel = billsSheet.getSelections();
- renderSheetFunc(billsSheet, function () {
- bills.controller.setTreeSelected(result[0]);
- billsSheet.setSelection(result[0].serialNo(), sel[0].col, 1, 1);
- for (let node of result) {
- billsSheet.getRange(node.serialNo(), -1, 1, -1).backColor('lemonChiffon');
- }
- });
- //搜索初始定位
- billsSheet.showRow(result[0].serialNo(), GC.Spread.Sheets.VerticalPosition.center);
- //查找下一条
- $('#nextBillsGuidance').show();
- $('#nextBillsGuidance').unbind('click');
- $('#nextBillsGuidance').bind('click', function () {
- let cur = bills.tree.selected, resultIndex = result.indexOf(cur), sel = billsSheet.getSelections();
- if (resultIndex === result.length - 1) {
- bills.controller.setTreeSelected(result[0]);
- billsSheet.setSelection(result[0].serialNo(), sel[0].col, 1, 1);
- billsSheet.showRow(result[0].serialNo(), GC.Spread.Sheets.VerticalPosition.center);
- } else {
- bills.controller.setTreeSelected(result[resultIndex + 1]);
- billsSheet.setSelection(result[resultIndex + 1].serialNo(), sel[0].col, 1, 1);
- billsSheet.showRow(result[resultIndex + 1].serialNo(), GC.Spread.Sheets.VerticalPosition.center);
- }
- });
- //查找上一条
- $('#preBillsGuidance').show();
- $('#preBillsGuidance').unbind('click');
- $('#preBillsGuidance').bind('click', function () {
- let cur = bills.tree.selected, resultIndex = result.indexOf(cur), sel = billsSheet.getSelections();
- if (resultIndex === 0) {
- bills.controller.setTreeSelected(result[result.length - 1]);
- billsSheet.setSelection(result[result.length - 1].serialNo(), sel[0].col, 1, 1);
- billsSheet.showRow(result[result.length - 1].serialNo(), GC.Spread.Sheets.VerticalPosition.center);
- } else {
- bills.controller.setTreeSelected(result[resultIndex - 1]);
- billsSheet.setSelection(result[resultIndex - 1].serialNo(), sel[0].col, 1, 1);
- billsSheet.showRow(result[resultIndex - 1].serialNo(), GC.Spread.Sheets.VerticalPosition.center);
- }
- });
- } else {
- billsLibObj.clearHighLight(bills.workBook);
- $('#nextBillsGuidance').hide();
- $('#preBillsGuidance').hide();
- }
- $('#billsGuidanceSearchResultCount').text('搜索结果:' + result.length);
- $('#billsGuidanceSearchResult').show();
- autoFlashHeight();
- refreshWorkBook();
- });
- //搜索框回车
- $('#stdBillsGuidanceSearch>input').bind('keypress', function (event) {
- if(event.keyCode === 13){
- $(this).blur();
- $('#stdBillsGuidanceSearch>div>button').click();
- }
- });
- // 关闭搜索结果
- $('#closeSearchBillsGuidance').click(function () {
- $('#billsGuidanceSearchResult').hide();
- billsLibObj.clearHighLight(bills.workBook);
- autoFlashHeight();
- refreshWorkBook();
- });
- // 添加选用
- $('#add-select-bills').click(function() {
- if (isInserting) {
- return;
- }
- const sheet = bills.controller.sheet;
- const lowestNodes = [];
- for (let i = 0; i < bills.tree.items.length; i++) {
- const checked = sheet.getValue(i, 0);
- const node = bills.tree.items[i];
- if (checked && !node.children.length) {
- lowestNodes.push(node);
- }
- }
- if (lowestNodes.length) {
- $.bootstrapLoading.start();
- insertBills(lowestNodes);
- }
- });
- }
- //刷新表
- //@return {void}
- function refreshWorkBook(){
- if(bills.workBook){
- bills.workBook.refresh();
- }
- if(guideItem.workBook){
- guideItem.workBook.refresh();
- }
- if(elfItem.workBook){
- elfItem.workBook.refresh();
- }
- }
- return {initViews, initLibs, bindBtn, refreshWorkBook, setColumnWidthByRate, locateAtBills, bills, elfItem, overwrite};
- })();
- $(document).ready(function(){
- billsGuidance.bindBtn();
- });
|