block_lib.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. /**
  2. * 块模板库管理。
  3. * Created by CSL on 2018-09-19.
  4. */
  5. var blockLibObj = {
  6. // libs: [],
  7. activeLib: null,
  8. mainSpread: null,
  9. mainSheet: null,
  10. mainTree: null,
  11. mainTreeController: null,
  12. mainSetting: {
  13. "emptyRowHeader": true,
  14. "rowHeaderWidth": 15,
  15. "emptyRows":0,
  16. "headRows":1,
  17. "headRowHeight":[30],
  18. "defaultRowHeight": 21,
  19. "treeCol": 9,
  20. "cols":[{
  21. "width":400,
  22. "readOnly": true,
  23. "head":{
  24. "titleNames":["名称"],
  25. "spanCols":[1],
  26. "spanRows":[1],
  27. "vAlign":[1],
  28. "hAlign":[1],
  29. "font":["Arial"]
  30. },
  31. "data":{
  32. "field":"nodeName",
  33. "vAlign":1,
  34. "hAlign":0,
  35. "font":"Arial"
  36. }
  37. }]
  38. },
  39. mainDatas: [],
  40. billSpread: null,
  41. billSheet: null,
  42. billSetting: {
  43. header: [
  44. {headerName: "项目编码", headerWidth: 90, dataCode: "code", dataType: "String", hAlign: "center"},
  45. {headerName: "项目名称", headerWidth: 100, dataCode: "name", dataType: "String"},
  46. {headerName: "单位", headerWidth: 40, dataCode: "unit", dataType: "String", hAlign: "center"},
  47. {headerName: "综合单价", headerWidth: 70, dataCode: "unitFee", dataType: "Number"},
  48. {headerName: "项目特征", headerWidth: 160, dataCode: "itemCharacterText", dataType: "String"}
  49. ],
  50. view: {
  51. lockColumns: [0, 1, 2, 3, 4]
  52. }
  53. },
  54. rationSpread: null,
  55. rationSheet: null,
  56. rationSetting: {
  57. header: [
  58. {headerName: "编码", headerWidth: 50, dataCode: "code", dataType: "String", hAlign: "center"},
  59. {headerName: "名称", headerWidth: 200, dataCode: "name", dataType: "String"},
  60. {headerName: "单位", headerWidth: 70, dataCode: "unit", dataType: "String", hAlign: "center"},
  61. /* {headerName: "含量", headerWidth: 40, dataCode: "contain", dataType: "Number"},
  62. {headerName: "取费专业", headerWidth: 70, dataCode: "programName", dataType: "String", hAlign: "center"}, */
  63. {headerName: "综合单价", headerWidth: 70, dataCode: "unitFee", dataType: "Number"},
  64. //{headerName: "子目换算状态", headerWidth: 90, dataCode: "adjustState", dataType: "String"}
  65. ],
  66. view: {
  67. lockColumns: [0, 1, 2, 3, 4, 5, 6]
  68. }
  69. },
  70. cloneType: null,
  71. initialShareTip: '',
  72. buildSheet: async function () {
  73. $.bootstrapLoading.start();
  74. let me = this;
  75. let namesAndLib = await ajaxPost('/blockLib/getLibNamesAndFirstLib',
  76. {userID: userID, compilationID: projectObj.project.projectInfo.compilation});
  77. function getLibNamesHtml(libsArr) {
  78. let result = '';
  79. for (let lib of libsArr) {
  80. result += '<option value="' + lib.libID + '">' + lib.libName + '</option>';
  81. };
  82. return result;
  83. };
  84. let html = getLibNamesHtml(namesAndLib.libNames);
  85. $("#select_block_lib_names").html(html);
  86. this.initialShareTip = namesAndLib.shareList && namesAndLib.shareList.length
  87. ? namesAndLib.shareList.reduce((acc, user) => acc += ` ${user.real_name}`, '已分享给')
  88. : '';
  89. $('#btn_block_share').attr('data-original-title', this.initialShareTip);
  90. await me.loadLib(namesAndLib.firstLib);
  91. $.bootstrapLoading.end();
  92. },
  93. loadLib: async function (lib){
  94. let me = this;
  95. if (me.mainSpread) {
  96. me.mainSpread.destroy();
  97. me.mainSpread = null;
  98. };
  99. if (me.billSpread) {
  100. me.billSpread.destroy();
  101. me.billSpread = null;
  102. };
  103. if (me.rationSpread) {
  104. me.rationSpread.destroy();
  105. me.rationSpread = null;
  106. };
  107. me.mainDatas = lib.datas;
  108. me.activeLib = lib;
  109. me.mainSpread = SheetDataHelper.createNewSpread($('#div_block_tree')[0]);
  110. me.mainSheet = me.mainSpread.getSheet(0);
  111. me.mainSheet.name('blockLibSheet');
  112. sheetCommonObj.spreadDefaultStyle(me.mainSpread);
  113. function showBlockTree(datas) {
  114. me.mainTree = idTree.createNew({id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1, autoUpdate: false});
  115. me.mainTreeController = TREE_SHEET_CONTROLLER.createNew(me.mainTree, me.mainSheet, me.mainSetting);
  116. me.mainTree.loadDatas(datas);
  117. me.mainTreeController.showTreeData();
  118. me.mainSheet.getRange(-1, 0, -1, 1).cellType(me.getTreeCell(me.mainTree));
  119. me.mainTree.selected = me.mainTree.items[0];
  120. me.mainTreeController.bind(TREE_SHEET_CONTROLLER.eventName.treeSelectedChanged, function (node) {
  121. blockLibObj.loadDetailDatas(node);
  122. });
  123. };
  124. showBlockTree(me.mainDatas);
  125. /* me.billSpread = sheetCommonObj.buildSheet($('#div_block_bill')[0], me.billSetting, 1);
  126. me.billSheet = me.billSpread.getSheet(0);
  127. sheetCommonObj.spreadDefaultStyle(me.billSpread);
  128. me.billSheet.setColumnWidth(0, 20, GC.Spread.Sheets.SheetArea.rowHeader); */
  129. me.rationSpread = sheetCommonObj.buildSheet($('#div_block_ration')[0], me.rationSetting, 1);
  130. me.rationSheet = me.rationSpread.getSheet(0);
  131. sheetCommonObj.spreadDefaultStyle(me.rationSpread);
  132. me.rationSheet.setColumnWidth(0, 20, GC.Spread.Sheets.SheetArea.rowHeader);
  133. me.loadTreeContextMenu();
  134. me.mainSpread.bind(GC.Spread.Sheets.Events.EnterCell, me.onEnterCell);
  135. me.mainSpread.bind(GC.Spread.Sheets.Events.CellDoubleClick, this.onCellDoubleClick);
  136. },
  137. loadDetailDatas: function (node){
  138. let me = this;
  139. if (!node) return;
  140. if (node.data.type == 2){
  141. let bill = node.data;
  142. let rations = bill.children;
  143. //sheetCommonObj.showData(me.billSheet, me.billSetting, [bill]);
  144. let rCount = (rations.length > 0) ? rations.length : 1;
  145. me.rationSheet.setRowCount(rCount, GC.Spread.Sheets.SheetArea.viewport);
  146. sheetCommonObj.showData(me.rationSheet, me.rationSetting, rations);
  147. }
  148. else{
  149. //sheetCommonObj.cleanSheet(me.billSheet, me.billSetting, 1);
  150. sheetCommonObj.cleanSheet(me.rationSheet, me.rationSetting, 1);
  151. }
  152. },
  153. getTreeCell: function (tree) {
  154. let me = this;
  155. let indent = 20, levelIndent = -5, halfBoxLength = 5, halfExpandLength = 3, imgWidth = 14, imgHeight = 14;
  156. let TreeCell = function () {};
  157. TreeCell.prototype = new GC.Spread.Sheets.CellTypes.Text();
  158. TreeCell.prototype.paint = function (ctx, value, x, y, w, h, style, options) {
  159. if (style.backColor) {
  160. ctx.save();
  161. ctx.fillStyle = style.backColor;
  162. ctx.fillRect(x, y, w, h);
  163. ctx.restore();
  164. } else {
  165. ctx.clearRect(x, y, w, h);
  166. };
  167. let drawLine = function (canvas, x1, y1, x2, y2, color) {
  168. ctx.save();
  169. ctx.translate(0.5, 0.5);
  170. ctx.beginPath();
  171. ctx.moveTo(x1, y1);
  172. ctx.lineTo(x2, y2);
  173. ctx.strokeStyle = color;
  174. ctx.stroke();
  175. ctx.restore();
  176. };
  177. let drawExpandBox = function (ctx, x, y, w, h, centerX, centerY, expanded) {
  178. let rect = {}, h1, h2, offset = 1;
  179. rect.top = centerY - halfBoxLength;
  180. rect.bottom = centerY + halfBoxLength;
  181. rect.left = centerX - halfBoxLength;
  182. rect.right = centerX + halfBoxLength;
  183. if (rect.left < x + w) {
  184. rect.right = Math.min(rect.right, x + w);
  185. ctx.save();
  186. ctx.translate(0.5, 0.5);
  187. ctx.strokeStyle = 'black';
  188. ctx.beginPath();
  189. ctx.moveTo(rect.left, rect.top);
  190. ctx.lineTo(rect.left, rect.bottom);
  191. ctx.lineTo(rect.right, rect.bottom);
  192. ctx.lineTo(rect.right, rect.top);
  193. ctx.lineTo(rect.left, rect.top);
  194. ctx.stroke();
  195. ctx.fillStyle = 'white';
  196. ctx.fill();
  197. ctx.restore();
  198. // Draw Horizontal Line
  199. h1 = centerX - halfExpandLength;
  200. h2 = Math.min(centerX + halfExpandLength, x + w);
  201. if (h2 > h1) {
  202. drawLine(ctx, h1, centerY, h2, centerY, 'black');
  203. }
  204. // Draw Vertical Line
  205. if (!expanded && (centerX < x + w)) {
  206. drawLine(ctx, centerX, centerY - halfExpandLength, centerX, centerY + halfExpandLength, 'black');
  207. }
  208. }
  209. };
  210. let node = tree.items[options.row];
  211. if (!node) return;
  212. let showTreeLine = true;
  213. let centerX = Math.floor(x) + node.depth() * indent + node.depth() * levelIndent + indent / 2;
  214. let x1 = centerX + indent / 2;
  215. let centerY = Math.floor((y + (y + h)) / 2);
  216. let y1;
  217. const lineColor = '#ababab';
  218. // Draw Horizontal Line、Image、sibling Vertical Line
  219. if (centerX < x + w) {
  220. // Draw Horizontal Line
  221. drawLine(ctx, centerX, centerY, Math.min(x1, x + w), centerY, lineColor);
  222. // Draw Image
  223. let imgId;
  224. if (node.data.type === 0) imgId = 'blockLib_pic'
  225. else if (node.data.type === 1) imgId = 'folder_pic'
  226. else if (node.data.type === 2) {
  227. imgId = 'block_pic';
  228. };
  229. let img = document.getElementById(imgId);
  230. ctx.drawImage(img, centerX+indent/2+3, centerY - 7, imgWidth, imgHeight);
  231. // Draw Vertical Line
  232. y1 = node.isLast() ? centerY : y + h;
  233. if (node.isFirst() && !node.parent/*.parent*/) {
  234. drawLine(ctx, centerX, centerY, centerX, y1, lineColor);
  235. } else {
  236. drawLine(ctx, centerX, y, centerX, y1, lineColor);
  237. }
  238. }
  239. // Draw Expand Box
  240. if (node.children.length > 0) {
  241. drawExpandBox(ctx, x, y, w, h, centerX, centerY, node.expanded);
  242. }
  243. // Draw Parent Line
  244. var curNode = node.parent, parentCenterX = centerX - indent - levelIndent;
  245. while (curNode) {
  246. if (!curNode.isLast()) {
  247. if (parentCenterX < x + w) {
  248. drawLine(ctx, parentCenterX, y, parentCenterX, y + h, lineColor);
  249. }
  250. }
  251. curNode = curNode.parent;
  252. parentCenterX -= (indent + levelIndent);
  253. }
  254. // Draw Text
  255. x = x + (node.depth() + 1) * indent + node.depth() * levelIndent + imgWidth + 3;
  256. w = w - (node.depth() + 1) * indent - node.depth() * levelIndent - imgWidth - 3;
  257. GC.Spread.Sheets.CellTypes.Text.prototype.paint.apply(this, arguments);
  258. };
  259. TreeCell.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {
  260. let info = {x: x, y: y, row: context.row, col: context.col, cellStyle: cellStyle, cellRect: cellRect, sheetArea: context.sheetArea};
  261. let node = tree.items[info.row];
  262. let offset = -1;
  263. let centerX = info.cellRect.x + offset + node.depth() * indent + node.depth() * levelIndent + indent / 2;
  264. let text = context.sheet.getText(info.row, info.col);
  265. let value = context.sheet.getValue(info.row, info.col);
  266. let acStyle = context.sheet.getActualStyle(info.row, info.col),
  267. zoom = context.sheet.zoom();
  268. let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: context.sheet, row: info.row, col: info.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
  269. if(info.x > centerX + halfBoxLength && info.x < centerX + halfBoxLength + imgWidth + indent/2+3 + textLength){
  270. info.isReservedLocation = true;
  271. }
  272. return info;
  273. };
  274. TreeCell.prototype.processMouseDown = function (hitinfo) {
  275. let offset = -1;
  276. let node = tree.items[hitinfo.row];
  277. let centerX = hitinfo.cellRect.x + offset + node.depth() * indent + node.depth() * levelIndent + indent / 2;
  278. let centerY = (hitinfo.cellRect.y + offset + (hitinfo.cellRect.y + offset + hitinfo.cellRect.height)) / 2;
  279. let text = hitinfo.sheet.getText(hitinfo.row, hitinfo.col);
  280. let value = hitinfo.sheet.getValue(hitinfo.row, hitinfo.col);
  281. let acStyle = hitinfo.sheet.getActualStyle(hitinfo.row, hitinfo.col),
  282. zoom = hitinfo.sheet.zoom();
  283. let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: hitinfo.sheet, row: hitinfo.row, col: hitinfo.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
  284. //(图标+名字)区域
  285. function withingClickArea(){
  286. return hitinfo.x > centerX + halfBoxLength && hitinfo.x < centerX + halfBoxLength + imgWidth + indent/2+3 + textLength;
  287. }
  288. //方框外1像素内都有效
  289. if (hitinfo.x >= centerX - halfBoxLength - 2 && hitinfo.x <= centerX + halfBoxLength + 2 &&
  290. hitinfo.y >= centerY - halfBoxLength - 2 && hitinfo.y <= centerY + halfBoxLength + 2) {
  291. node.setExpanded(!node.expanded);
  292. TREE_SHEET_HELPER.massOperationSheet(hitinfo.sheet, function () {
  293. let iCount = node.posterityCount(), i, child;
  294. for (i = 0; i < iCount; i++) {
  295. child = tree.items[hitinfo.row + i + 1];
  296. hitinfo.sheet.setRowVisible(hitinfo.row + i + 1, child.visible, hitinfo.sheetArea);
  297. }
  298. hitinfo.sheet.invalidateLayout();
  299. });
  300. hitinfo.sheet.repaint();
  301. }
  302. };
  303. TreeCell.prototype.processMouseMove = function (hitInfo) {
  304. let sheet = hitInfo.sheet;
  305. let div = sheet.getParent().getHost();
  306. let canvasId = div.id + "vp_vp";
  307. /* let canvas = $(`#${canvasId}`)[0];
  308. //改变鼠标图案
  309. if (sheet && hitInfo.isReservedLocation) {
  310. canvas.style.cursor='pointer';
  311. return true;
  312. }else{
  313. canvas.style.cursor='default';
  314. }*/
  315. return false;
  316. };
  317. TreeCell.prototype.processMouseEnter = function (hitinfo) {
  318. let text = hitinfo.sheet.getText(hitinfo.row, hitinfo.col);
  319. let value = hitinfo.sheet.getValue(hitinfo.row, hitinfo.col);
  320. let tag = hitinfo.sheet.getTag(hitinfo.row, hitinfo.col);
  321. let acStyle = hitinfo.sheet.getActualStyle(hitinfo.row, hitinfo.col),
  322. zoom = hitinfo.sheet.zoom();
  323. let node = me.mainTree.items[hitinfo.row];
  324. let nodeIndent = node ? (node.depth() + 1) * indent + node.depth() * levelIndent + imgWidth + 3 : 0;
  325. let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: hitinfo.sheet, row: hitinfo.row, col: hitinfo.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
  326. let cellWidth = hitinfo.sheet.getCell(-1, hitinfo.col).width();
  327. if(textLength > cellWidth - nodeIndent){
  328. TREE_SHEET_HELPER.showTipsDiv(text,{pos: {}},hitinfo);
  329. }
  330. };
  331. TreeCell.prototype.processMouseLeave = function (hitinfo) {
  332. let me = this;
  333. TREE_SHEET_HELPER.tipDiv = 'hide';
  334. if (TREE_SHEET_HELPER._toolTipElement) {
  335. $(TREE_SHEET_HELPER._toolTipElement).hide();
  336. TREE_SHEET_HELPER._toolTipElement = null;
  337. };
  338. TREE_SHEET_HELPER.tipDivCheck();//延时检查:当tips正在show的时候,就调用了hide方法,会导致tips一直存在,所以设置一个超时处理
  339. };
  340. return new TreeCell();
  341. },
  342. newNode: async function (nodeType, nodeName, categoryID, source){ // 1 分类(只用前两个参数) 2 块文件
  343. if (nodeName == '') return;
  344. let tree = blockLibObj.mainTree;
  345. let ID = uuid.v1();
  346. let pID = (nodeType == 2) ? categoryID : -1;
  347. let nID = -1;
  348. // 先生成临时结点数据用于提交入库,成功后才生成树结点,并在UI上刷新显示。
  349. let temp = {};
  350. temp.data = {
  351. ID: ID,
  352. ParentID: pID,
  353. NextSiblingID: nID,
  354. libID: blockLibObj.activeLib.libID,
  355. type: nodeType,
  356. nodeName: nodeName
  357. };
  358. if (nodeType == 2)
  359. blockLibObj.assignData(temp, source);
  360. try {
  361. let obj = {
  362. libID: blockLibObj.activeLib.libID,
  363. nodeID: temp.data.ID,
  364. create: temp.data
  365. };
  366. await ajaxPost('/blockLib/saveBlock', obj);
  367. let newN = tree.insertByID(ID, pID, nID);
  368. newN.data = temp.data;
  369. tree.selected = newN;
  370. let sheet = blockLibObj.mainSheet;
  371. sheet.suspendPaint();
  372. sheet.suspendEvent();
  373. let idx = tree.items.indexOf(newN);
  374. sheet.addRows(idx, 1);
  375. sheet.getRange(idx, 0, 1, 1).locked(true);
  376. sheet.setValue(idx, 0, newN.data.nodeName);
  377. sheet.setSelection(idx, 0, 1, 1);
  378. sheet.resumeEvent();
  379. sheet.resumePaint();
  380. }
  381. catch (err) {
  382. console.log(err.message);
  383. return;
  384. };
  385. },
  386. assignData: function (block, source){
  387. block.data.compilationID = source.compilationID;
  388. block.data.copyTime = source.copyTime;
  389. block.data.firstNodeType = source.firstNodeType;
  390. block.data.isFBFX = source.isFBFX;
  391. let bill = source.datas[0];
  392. block.data.code = bill.code;
  393. block.data.name = bill.name;
  394. block.data.unit = bill.unit;
  395. block.data.itemCharacterText = bill.itemCharacterText;
  396. block.data.unitFee = (bill.feesIndex && bill.feesIndex.common) ? bill.feesIndex.common.unitFee : 0;
  397. block.data.children = bill.children;
  398. for (let r of bill.children){
  399. r.unitFee = (r.feesIndex && r.feesIndex.common) ? r.feesIndex.common.unitFee : 0;
  400. if (r.programID)
  401. r.programName = projectObj.project.calcProgram.compiledTemplateMaps[r.programID];
  402. // delete r.ID; // 这个不能删!
  403. delete r.billsItemID;
  404. delete r.fees;
  405. delete r.feesIndex;
  406. };
  407. },
  408. reName: async function (node, newName){
  409. if (newName == '') return;
  410. let obj = {
  411. libID: blockLibObj.activeLib.libID,
  412. nodeID: node.data.ID,
  413. update: {nodeName: newName}
  414. };
  415. await ajaxPost('/blockLib/saveBlock', obj);
  416. node.data.nodeName = newName;
  417. let idx = blockLibObj.mainTree.items.indexOf(node);
  418. blockLibObj.mainSheet.setValue(idx, 0, newName);
  419. },
  420. moveBlock: function (parentID) {
  421. // this.mainTreeController.moveTo(parentID);
  422. },
  423. delete: async function () {
  424. let node = blockLibObj.mainTree.selected;
  425. let obj = {
  426. libID: blockLibObj.activeLib.libID,
  427. nodeID: node.data.ID,
  428. delete: {nodeType: node.data.type}
  429. };
  430. await ajaxPost('/blockLib/saveBlock', obj);
  431. this.mainTreeController.delete();
  432. },
  433. getCategories: function () {
  434. let nodes = [], node = blockLibObj.mainTree.items[0];
  435. nodes.push(node);
  436. while (node.nextSibling != null){
  437. node = node.nextSibling;
  438. nodes.push(node);
  439. };
  440. return nodes;
  441. },
  442. curIsBlock: function () {
  443. return this.mainTree.selected.data.type == 2;
  444. },
  445. curIsCategory: function () {
  446. return this.mainTree.selected.data.type == 1;
  447. },
  448. getSameNameNode: function(name){
  449. let rst = null;
  450. let nodes = blockLibObj.mainTree.items;
  451. for (let i = 0; i < nodes.length; i++) {
  452. let node = nodes[i];
  453. if (node.data.nodeName == name){
  454. rst = node;
  455. break;
  456. }
  457. }
  458. return rst;
  459. },
  460. refreshSpread: function (){
  461. if (this.mainSpread)
  462. this.mainSpread.refresh();
  463. if (this.billSpread)
  464. this.billSpread.refresh();
  465. if (this.rationSpread)
  466. this.rationSpread.refresh();
  467. },
  468. loadTreeContextMenu: function (){
  469. let me = this;
  470. $.contextMenu({
  471. selector: '#div_block_tree',
  472. build: function ($trigger, e) {
  473. SheetDataHelper.safeRightClickSelection($trigger, e, me.mainSpread);
  474. me.onEnterCell();
  475. },
  476. items: {
  477. "oneToOneClone": {
  478. name: '一对一克隆',
  479. icon: "fa-stop",
  480. disabled: function () {
  481. let ok = me.curIsBlock() && calcTools.isLeafBill(projectObj.project.mainTree.selected);
  482. return !ok;
  483. },
  484. visible: function(key, opt){
  485. return true;
  486. },
  487. callback: function (key, opt) {
  488. blockLibObj.cloneType = 1;
  489. $("#div_cloneOptions").modal({show: true});
  490. }
  491. },
  492. "oneToMoreClone": {
  493. name: '一对多克隆',
  494. icon: "fa-th-list",
  495. disabled: function () {
  496. let ok = me.curIsBlock() && calcTools.isParentBill(projectObj.project.mainTree.selected);
  497. return !ok;
  498. },
  499. visible: function(key, opt){
  500. return true;
  501. },
  502. callback: function (key, opt) {
  503. blockLibObj.cloneType = 2;
  504. $("#div_cloneOptions").modal({show: true});
  505. }
  506. },
  507. "moreToMoreClone": {
  508. name: '多对多克隆',
  509. icon: "fa-th",
  510. disabled: function () {
  511. let ok = me.curIsCategory() && calcTools.isParentBill(projectObj.project.mainTree.selected);
  512. return !ok;
  513. },
  514. visible: function(key, opt){
  515. return true;
  516. },
  517. callback: function (key, opt) {
  518. blockLibObj.cloneType = 3;
  519. $("#div_cloneOptions").modal({show: true});
  520. }
  521. },
  522. "delete": {
  523. name: '删除',
  524. icon: "delete",
  525. disabled: function () {
  526. return $("#select_block_lib_names option:selected").prop("index") !== 0;
  527. },
  528. visible: function(key, opt){
  529. return true;
  530. },
  531. callback: function (key, opt) {
  532. let name = hintBox.fontRed(me.mainTree.selected.data.nodeName);
  533. hintBox.infoBox('操作确认', `确定要删除"${name}"吗?`, 2, function () {
  534. me.delete();
  535. });
  536. }
  537. },
  538. "moveBlock": {
  539. name: '移动模板',
  540. icon: "cut",
  541. disabled: function () {
  542. return true;
  543. },
  544. visible: function(key, opt){
  545. // return me.curIsBlock();
  546. return false;
  547. },
  548. callback: function (key, opt) {
  549. }
  550. }
  551. }
  552. });
  553. },
  554. onEnterCell: function (sender, args) {
  555. let me = blockLibObj;
  556. me.mainTree.selected = me.mainTree.items[me.mainSheet.getActiveRowIndex()];
  557. },
  558. onCellDoubleClick: function (sender, args) {
  559. if (blockLibObj.curIsCategory()) {
  560. hintBox.infoBox('系统提示', `双击是“一对一克隆”,不支持分类操作,请在块文件上双击!`, 1);
  561. return;
  562. }
  563. let projectNode = projectObj.project.mainTree.selected;
  564. if (!calcTools.isLeafBill(projectNode)) {
  565. hintBox.infoBox('系统提示', `双击是“一对一克隆”,请在造价书界面选择最底层的分项/补项/清单进行操作!`, 1);
  566. return;
  567. }
  568. blockLibObj.cloneType = 1;
  569. $("#div_cloneOptions").modal({show: true});
  570. },
  571. oneToOneClone: function (projectNode, block, options) {
  572. return new Promise(function (resolve, reject) {
  573. let canClone = true;
  574. if (options.checkCode)
  575. canClone = canClone && (projectNode.data.code.substr(0, 9) == block.data.code.substr(0, 9));
  576. if (options.checkName)
  577. canClone = canClone && (projectNode.data.name == block.data.name);
  578. if (options.checkUnit)
  579. canClone = canClone && (projectNode.data.unit == block.data.unit);
  580. if (!canClone) return resolve([[], []]);
  581. if (options.overwriteRations)
  582. projectObj.project.Bills.deleteChildren(projectNode);
  583. /* 这里封装成伟城的块文件格式,可直接使用伟城的“粘贴块”接口。
  584. 但这里结构要作出调整:忽略叶子清单层,直接从定额开始(跟粘贴块有区别),始终强制在叶子清单下插入定额。
  585. 该操作前提:当前块文件的全部数据已从后台取到前台。 */
  586. let vBlock_WC = {
  587. compilationID: block.data.compilationID,
  588. copyTime: block.data.copyTime,
  589. firstNodeType: 1, // 强制改成1 (因为是从清单下的定额开始。清单自身的还是保留,暂不使用使用)。
  590. isFBFX: block.data.isFBFX,
  591. zeroQuantity: options.zeroQuantity,
  592. datas: block.data.children // rations
  593. };
  594. vBlock_WC = JSON.parse(JSON.stringify(vBlock_WC));
  595. BlockController.confirmPaste(vBlock_WC, projectNode, 'sub',function(r, c){
  596. resolve([r, c])
  597. });
  598. })
  599. },
  600. checkShow: async function () { // 这里需要处理异步:模板库装载完再弹出位置选择窗。
  601. if (!$("#kmbk").is(":visible")){ // 如果还没显示
  602. if (!blockLibObj.mainSpread){
  603. await blockLibObj.buildSheet();
  604. };
  605. $('#blockLibTab').click(); // 强制显示
  606. };
  607. $("#div_createBlocks").modal({show: true});
  608. }
  609. };
  610. $(document).ready(function(){ // 这里不需要处理异步:因为不需要弹出位置选择窗。
  611. $('#blockLibTab').on('click', function (){
  612. if ($("#kmbk").is(":visible")){ // 显示状态下
  613. if (!blockLibObj.mainSpread){
  614. blockLibObj.buildSheet();
  615. };
  616. }
  617. });
  618. $('#btn_block_newFolder').on('click', function (){
  619. $('#input_block_newFolder').val('');
  620. });
  621. $('#btn_block_newFolder_add').on('click', function (){
  622. let name = $('#input_block_newFolder').val();
  623. blockLibObj.newNode(1, name);
  624. });
  625. $('#btn_block_reName').on('click', function (){
  626. let select = blockLibObj.mainTree.selected;
  627. $('#input_block_reName').val(select.data.nodeName);
  628. });
  629. $('#btn_block_reName_OK').on('click', function (){
  630. let select = blockLibObj.mainTree.selected;
  631. let oldName = select.data.nodeName;
  632. let newName = $('#input_block_reName').val();
  633. if (oldName != newName) blockLibObj.reName(select, newName);
  634. });
  635. $("#select_block_lib_names").change(function() {
  636. const index = $("#select_block_lib_names option:selected").prop("index");
  637. if (index !== 0) {
  638. // 只读
  639. $('#btn_block_newFolder').hide();
  640. $('#btn_block_reName').hide();
  641. $('#btn_block_share').prop('disabled', true);
  642. } else {
  643. $('#btn_block_newFolder').show();
  644. $('#btn_block_reName').show();
  645. $('#btn_block_share').prop('disabled', false);
  646. }
  647. async function getLib(){
  648. let libID = $("#select_block_lib_names").val();
  649. let lib = await ajaxPost('/blockLib/getLib', {libID: libID});
  650. blockLibObj.loadLib(lib);
  651. if (userID === lib.userID) {
  652. $('#btn_block_share').attr('data-original-title', blockLibObj.initialShareTip);
  653. }
  654. };
  655. $.bootstrapLoading.start();
  656. getLib();
  657. $.bootstrapLoading.end();
  658. });
  659. $('#btn_block_share').click(function () {
  660. SHARE_TO.initModal(SHARE_TO.Mode.BLOCK_LIB);
  661. })
  662. });