ledger.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. /**
  2. * 台账相关js
  3. *
  4. * @author Mai
  5. * @date 2018/02/05
  6. * @version
  7. */
  8. $(document).ready(function() {
  9. autoFlashHeight();
  10. const ledgerSpread = SpreadJsObj.createNewSpread($('#ledger-spread')[0]);
  11. SpreadJsObj.addDeleteBind(ledgerSpread);
  12. const ledgerTree = createNewPathTree({
  13. id: 'ledger_id',
  14. pid: 'ledger_pid',
  15. order: 'order',
  16. level: 'level',
  17. rootId: -1,
  18. keys: ['id', 'tender_id', 'ledger_id']
  19. });
  20. ledgerTree.loadDatas(ledger);
  21. SpreadJsObj.initSheet(ledgerSpread.getActiveSheet(), {
  22. cols: [
  23. {title: '项目节编号', field: 'code', width: 150, cellType: 'tree'},
  24. {title: '清单编号', field: 'b_code', width: 80},
  25. {title: '名称', field: 'name', width: 230},
  26. {title: '单位', field: 'unit', width: 50},
  27. {title: '单价', field: 'price', width: 60},
  28. {title: '数量', field: 'quantity', width: 60},
  29. {title: '金额', field: 'totalPrice', width: 60},
  30. {title: '施工图原设计', field: 'design', width: 60},
  31. {title: '图(册)号', field: 'drawingCode', width: 80},
  32. {title: '备注', field: 'memo', width: 100}
  33. ],
  34. treeCol: 0,
  35. emptyRows: 3
  36. });
  37. SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), 'tree', ledgerTree);
  38. const treeOperationObj = {
  39. /**
  40. * 刷新顶部按钮是否可用
  41. * @param sheet
  42. * @param selections
  43. */
  44. refreshOperationValid: function (sheet, selections) {
  45. const setObjEnable = function (obj, enable) {
  46. if (enable) {
  47. obj.removeClass('disabled');
  48. } else {
  49. obj.addClass('disabled');
  50. }
  51. };
  52. const row = selections[0].row;
  53. const tree = sheet.zh_tree;
  54. if (!tree) { return; }
  55. const node = sheet.zh_tree.nodes[row];
  56. setObjEnable($('#delete'), node);
  57. setObjEnable($('#up-move'), node && node.order > 1);
  58. setObjEnable($('#down-move'), node && !tree.isLastSibling(node));
  59. setObjEnable($('#up-level'), tree.getParent(node));
  60. setObjEnable($('#down-level'), node && node.order > 1);
  61. },
  62. /**
  63. * 新增节点
  64. * @param spread
  65. */
  66. addNode: function (spread) {
  67. const self = this;
  68. const sheet = spread.getActiveSheet();
  69. const row = sheet.getSelections()[0].row;
  70. const tree = sheet.zh_tree;
  71. if (!tree) { return; }
  72. const node = sheet.zh_tree.nodes[row];
  73. if (!node) { return; }
  74. SpreadJsObj.massOperationSheet(sheet, function () {
  75. tree.baseOperation('base-operation', node, 'add', function (result) {
  76. const newNodes = result.create;
  77. if (newNodes) {
  78. newNodes.sort(function (a, b) {
  79. const aIndex = tree.nodes.indexOf(a);
  80. const bIndex = tree.nodes.indexOf(b);
  81. return aIndex - bIndex;
  82. });
  83. for (const node of newNodes) {
  84. const index = tree.nodes.indexOf(node);
  85. sheet.addRows(index, 1);
  86. }
  87. }
  88. self.refreshOperationValid(sheet, sheet.getSelections());
  89. });
  90. });
  91. },
  92. /**
  93. * 删除选中节点
  94. * @param spread
  95. */
  96. deleteNode: function (spread) {
  97. const self = this;
  98. const sheet = spread.getActiveSheet();
  99. const row = sheet.getSelections()[0].row;
  100. const tree = sheet.zh_tree;
  101. if (!tree) { return; }
  102. const node = sheet.zh_tree.nodes[row];
  103. if (!node) { return; }
  104. const count = ledgerTree.getPosterity(node).length;
  105. tree.baseOperation('base-operation', node, 'delete', function (result) {
  106. sheet.deleteRows(row, count + 1);
  107. self.refreshOperationValid(sheet, sheet.getSelections());
  108. });
  109. },
  110. /**
  111. * 上移选中节点
  112. * @param spread
  113. */
  114. upMove: function (spread) {
  115. const self = this;
  116. const sheet = spread.getActiveSheet();
  117. const sel = sheet.getSelections()[0];
  118. const row = sel.row;
  119. const tree = sheet.zh_tree;
  120. if (!tree) { return; }
  121. const node = tree.nodes[row];
  122. if (!node) { return; }
  123. tree.baseOperation('base-operation', node, 'up-move', function (result) {
  124. for (const data of result.update) {
  125. SpreadJsObj.reLoadRowData(sheet, tree.nodes.indexOf(data), tree.getPosterity(data).length + 1);
  126. }
  127. sheet.setSelection(tree.nodes.indexOf(node), sel.col, sel.rowCount, sel.colCount);
  128. self.refreshOperationValid(sheet, sheet.getSelections());
  129. //sheet.moveTo(row, -1, tree.nodes.indexOf(node), -1, tree.getPosterity(node).length + 1, -1, GC.Spread.Sheets.CopyToOptions.value);
  130. });
  131. },
  132. /**
  133. * 下移选中节点
  134. * @param spread
  135. */
  136. downMove: function (spread) {
  137. const self = this;
  138. const sheet = spread.getActiveSheet();
  139. const sel = sheet.getSelections()[0];
  140. const row = sel.row;
  141. const tree = sheet.zh_tree;
  142. if (!tree) { return; }
  143. const node = tree.nodes[row];
  144. if (!node) { return; }
  145. tree.baseOperation('base-operation', node, 'down-move', function (result) {
  146. for (const data of result.update) {
  147. SpreadJsObj.reLoadRowData(sheet, tree.nodes.indexOf(data), tree.getPosterity(data).length + 1);
  148. }
  149. sheet.setSelection(tree.nodes.indexOf(node), sel.col, sel.rowCount, sel.colCount);
  150. self.refreshOperationValid(sheet, sheet.getSelections());
  151. });
  152. },
  153. /**
  154. * 升级选中节点
  155. * @param spread
  156. */
  157. upLevel: function (spread) {
  158. const self = this;
  159. const sheet = spread.getActiveSheet();
  160. const row = sheet.getSelections()[0].row;
  161. const tree = sheet.zh_tree;
  162. if (!tree) { return; }
  163. const node = tree.nodes[row];
  164. if (!node) { return; }
  165. tree.baseOperation('base-operation', node, 'up-level', function (result) {
  166. sheet.repaint();
  167. self.refreshOperationValid(sheet, sheet.getSelections());
  168. });
  169. },
  170. /**
  171. * 降级选中节点
  172. * @param spread
  173. */
  174. downLevel: function (spread) {
  175. const self = this;
  176. const sheet = spread.getActiveSheet();
  177. const row = sheet.getSelections()[0].row;
  178. const tree = sheet.zh_tree;
  179. if (!tree) { return; }
  180. const node = tree.nodes[row];
  181. if (!node) { return; }
  182. tree.baseOperation('base-operation', node, 'down-level', function (result) {
  183. sheet.repaint();
  184. self.refreshOperationValid(sheet, sheet.getSelections());
  185. });
  186. },
  187. /**
  188. * 编辑单元格响应事件
  189. * @param {Object} e
  190. * @param {Object} info
  191. */
  192. editEnded: function (e, info) {
  193. if (info.sheet.zh_setting) {
  194. const col = info.sheet.zh_setting.cols[info.col];
  195. const sortData = info.sheet.zh_dataType === 'tree' ? info.sheet.zh_tree.nodes : info.sheet.zh_data;
  196. const node = sortData[info.row];
  197. const data = {
  198. id: node.id,
  199. tender_id: node.tender_id,
  200. ledger_id: node.ledger_id
  201. };
  202. data[col.field] = info.editingText;
  203. info.sheet.zh_tree.updateInfo('update-info', [data], function (result) {
  204. const rows = [];
  205. for (const data of result) {
  206. rows.push(sortData.indexOf(data));
  207. }
  208. SpreadJsObj.reLoadRowsData(info.sheet, rows);
  209. });
  210. }
  211. },
  212. /**
  213. * 粘贴单元格响应事件
  214. * @param e
  215. * @param info
  216. */
  217. clipboardPasted: function (e, info) {
  218. if (info.sheet.zh_setting && info.sheet.zh_dataType === 'tree') {
  219. const sortData = info.sheet.zh_tree.nodes;
  220. const datas = [], nodes = [];
  221. for (let iRow = 0; iRow < info.cellRange.rowCount; iRow ++) {
  222. const curRow = info.cellRange.row + iRow;
  223. const node = sortData[curRow];
  224. if (node) {
  225. const data = info.sheet.zh_tree.getNodeKeyData(node);
  226. for (let iCol = 0; iCol < info.cellRange.colCount; iCol++) {
  227. const curCol = info.cellRange.col + iCol;
  228. const colSetting = info.sheet.zh_setting.cols[curCol];
  229. data[colSetting.field] = info.sheet.getText(curRow, curCol);
  230. }
  231. datas.push(data);
  232. nodes.push(node);
  233. }
  234. }
  235. info.sheet.zh_tree.updateInfo('update-info', datas, function (result) {
  236. const rows = [];
  237. for (const data of result) {
  238. rows.push(sortData.indexOf(data));
  239. }
  240. SpreadJsObj.reLoadRowsData(info.sheet, rows);
  241. });
  242. }
  243. },
  244. deletePress: function (sheet) {
  245. if (sheet.zh_setting && sheet.zh_dataType === 'tree') {
  246. const sortData = sheet.zh_tree.nodes;
  247. const datas = [], nodes = [];
  248. const sel = sheet.getSelections()[0];
  249. for (let iRow = sel.row; iRow < sel.row + sel.rowCount; iRow++) {
  250. const node = sortData[iRow];
  251. if (node) {
  252. const data = sheet.zh_tree.getNodeKeyData(node);
  253. for (let iCol = sel.col; iCol < sel.col + sel.colCount; iCol++) {
  254. const colSetting = sheet.zh_setting.cols[iCol];
  255. data[colSetting.field] = null;
  256. }
  257. datas.push(data);
  258. nodes.push(node);
  259. }
  260. }
  261. sheet.zh_tree.updateInfo('update-info', datas, function (result) {
  262. const rows = [];
  263. for (const data of result) {
  264. rows.push(sortData.indexOf(data));
  265. }
  266. SpreadJsObj.reLoadRowsData(sheet, rows);
  267. });
  268. }
  269. },
  270. pasteBlock: function (spread, block) {
  271. const self = this;
  272. const sheet = spread.getActiveSheet();
  273. const row = sheet.getSelections()[0].row;
  274. const tree = sheet.zh_tree;
  275. if (!tree) { return; }
  276. const node = tree.nodes[row];
  277. if (!node) { return; }
  278. tree.pasteBlock('paste-block', node, block, function (result) {
  279. SpreadJsObj.massOperationSheet(sheet, function () {
  280. const newNodes = result.create;
  281. if (newNodes) {
  282. newNodes.sort(function (a, b) {
  283. const aIndex = tree.nodes.indexOf(a);
  284. const bIndex = tree.nodes.indexOf(b);
  285. return aIndex - bIndex;
  286. });
  287. for (const node of newNodes) {
  288. const index = tree.nodes.indexOf(node);
  289. sheet.addRows(index, 1);
  290. SpreadJsObj.reLoadRowData(sheet, index, 1);
  291. }
  292. }
  293. self.refreshOperationValid(sheet, sheet.getSelections());
  294. });
  295. });
  296. }
  297. };
  298. ledgerSpread.bind(GC.Spread.Sheets.Events.SelectionChanged, function (e, info) {
  299. treeOperationObj.refreshOperationValid(info.sheet, info.newSelections);
  300. });
  301. ledgerSpread.bind(GC.Spread.Sheets.Events.EditEnded, treeOperationObj.editEnded);
  302. ledgerSpread.bind(GC.Spread.Sheets.Events.ClipboardPasted, treeOperationObj.clipboardPasted);
  303. SpreadJsObj.addDeleteBind(ledgerSpread, treeOperationObj.deletePress);
  304. // 绑定 删除等 顶部按钮
  305. $('#delete').click(function () {
  306. treeOperationObj.deleteNode(ledgerSpread);
  307. });
  308. $('#up-move').click(function () {
  309. treeOperationObj.upMove(ledgerSpread);
  310. });
  311. $('#down-move').click(function () {
  312. treeOperationObj.downMove(ledgerSpread);
  313. });
  314. $('#up-level').click(function () {
  315. treeOperationObj.upLevel(ledgerSpread);
  316. });
  317. $('#down-level').click(function () {
  318. treeOperationObj.downLevel(ledgerSpread);
  319. });
  320. treeOperationObj.refreshOperationValid(ledgerSpread.getActiveSheet(), ledgerSpread.getActiveSheet().getSelections());
  321. // 右键菜单
  322. $.contextMenu({
  323. selector: '#ledger-spread',
  324. build: function ($trigger, e) {
  325. const target = SpreadJsObj.safeRightClickSelection($trigger, e, ledgerSpread);
  326. return target.hitTestType === GC.Spread.Sheets.SheetArea.viewport || target.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
  327. },
  328. items: {
  329. 'create': {
  330. name: '新增',
  331. icon: 'fa-sign-in',
  332. callback: function (key, opt) {
  333. treeOperationObj.addNode(ledgerSpread);
  334. },
  335. visible: function(key, opt){
  336. const sheet = ledgerSpread.getActiveSheet();
  337. const selection = sheet.getSelections();
  338. const row = selection[0].row;
  339. const select = ledgerTree.nodes[row];
  340. return select;
  341. }
  342. },
  343. 'delete': {
  344. name: '删除',
  345. icon: 'fa-remove',
  346. callback: function (key, opt) {
  347. treeOperationObj.deleteNode(ledgerSpread);
  348. },
  349. visible: function (key, opt) {
  350. const sheet = ledgerSpread.getActiveSheet();
  351. const selection = sheet.getSelections();
  352. const row = selection[0].row;
  353. const select = ledgerTree.nodes[row];
  354. return select;
  355. }
  356. },
  357. 'copyBlock': {
  358. name: '复制整块',
  359. icon: 'fa-files-o',
  360. callback: function (key, opt) {
  361. /*ledgerSpread.commandManager().execute({
  362. cmd:"copy",
  363. sheetName:ledgerSpread.getActiveSheet().name()
  364. });*/
  365. treeOperationObj.block = [];
  366. const copyBlockList = [];
  367. const sheet = ledgerSpread.getActiveSheet();
  368. const sel = sheet.getSelections()[0];
  369. let iRow = sel.row;
  370. const pid = sheet.zh_tree.nodes[iRow].ledger_pid;
  371. while (iRow < sel.row + sel.rowCount) {
  372. const node = sheet.zh_tree.nodes[iRow];
  373. if (node.ledger_pid !== pid) {
  374. toast('error: 仅可同时选中同层节点', 'error', 'exclamation-circle');
  375. return;
  376. }
  377. copyBlockList.push(node.ledger_id);
  378. iRow += sheet.zh_tree.getPosterity(node).length + 1;
  379. }
  380. treeOperationObj.block = copyBlockList;
  381. },
  382. visible: function (key, opt) {
  383. const sheet = ledgerSpread.getActiveSheet();
  384. const selection = sheet.getSelections();
  385. const row = selection[0].row;
  386. const select = ledgerTree.nodes[row];
  387. return select;
  388. }
  389. },
  390. 'pasteBlock': {
  391. name: '粘贴',
  392. icon: 'fa-clipboard',
  393. disabled: function (key, opt) {
  394. const block = treeOperationObj.block || [];
  395. return block.length <= 0;
  396. },
  397. callback: function (key, opt) {
  398. const block = treeOperationObj.block || [];
  399. if (block.length > 0) {
  400. treeOperationObj.pasteBlock(ledgerSpread, block);
  401. }/* else {
  402. ledgerSpread.commandManager().execute({
  403. cmd:"paste",
  404. sheetName:ledgerSpread.getActiveSheet().name()
  405. });
  406. }*/
  407. }
  408. }
  409. }
  410. });
  411. });