batch_import.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. const BatchImportStageGcl = function (setting) {
  2. const biObj = {
  3. setting,
  4. spread: null,
  5. sheet: null,
  6. tenderSourceTree: null,
  7. history: [],
  8. batchTree: null,
  9. rebuildStageSelect: function () {
  10. const getItems = function (data) {
  11. const items = [];
  12. if (data) {
  13. for (let i = 1; i <= data.stageCount; i++) {
  14. items.push({value: i, text: `第${i}期`});
  15. }
  16. }
  17. return items;
  18. };
  19. for (let i = 0; i < biObj.sheet.getRowCount(); i++) {
  20. const data = biObj.batchTree.nodes[i];
  21. if (!data.tid) continue;
  22. const items = getItems(data);
  23. const cellType = new spreadNS.CellTypes.ComboBox().itemHeight(10).editorValueType(spreadNS.CellTypes.EditorValueType.value).items(items);
  24. biObj.sheet.getCell(i, 3).cellType(cellType);
  25. }
  26. },
  27. EditEnded: function (e, info) {
  28. const data = SpreadJsObj.getSelectObject(info.sheet);
  29. const col = info.sheet.zh_setting.cols[info.col];
  30. data[col.field] = info.sheet.getValue(info.row, info.col);
  31. },
  32. ButtonClicked: function (e, info) {
  33. if (!info.sheet.zh_setting) return;
  34. const col = info.sheet.zh_setting.cols[info.col];
  35. if (col.field !== 'selected') return;
  36. const node = SpreadJsObj.getSelectObject(info.sheet);
  37. const newValue = !node.selected;
  38. const parent = node.lid ? node : info.sheet.zh_tree.getParent(node);
  39. parent.selected = newValue;
  40. if (parent.children && parent.children.length > 0) {
  41. for (const child of parent.children) {
  42. child.selected = newValue;
  43. }
  44. }
  45. SpreadJsObj.reLoadRowData(info.sheet, info.sheet.zh_tree.getNodeIndex(parent), parent.children.length + 1);
  46. },
  47. reloadBatchTree() {
  48. this.batchTree.clearDatas();
  49. for (const h of this.history) {
  50. if (!h.ledger_node) continue;
  51. const ledgerData = { lid: h.lid, ledger_id: h.ledger_node.ledger_id, code: h.ledger_node.code, name: h.ledger_node.name, ledger_node: h.ledger_node, selected: h.tenders.length > 0 };
  52. const batchNode = this.batchTree.addNode(ledgerData, null);
  53. for (const t of h.tenders) {
  54. const tenderData = JSON.parse(JSON.stringify(t));
  55. tenderData.selected = true;
  56. const tender = this.tenderSourceTree.nodes.find(y => { return y.tid === t.tid });
  57. tenderData.stageCount = tender.stageCount;
  58. this.batchTree.addNode(tenderData, batchNode);
  59. }
  60. }
  61. this.batchTree.sortTreeNode(true);
  62. },
  63. loadHistory: function () {
  64. if (biObj.batching) return;
  65. biObj.tender_id = biObj.setting.stageTree.nodes[0].tender_id;
  66. postData(`/sp/${spid}/list/load`, {type: 'stageBatch', tid: biObj.tender_id}, data => {
  67. biObj.history = data.history || [];
  68. // 屏蔽自己
  69. const curIndex = data.tenders.findIndex(x => { return x.id === biObj.tender_id });
  70. if (curIndex >= 0) data.tenders.splice(curIndex, 1);
  71. biObj.tenderSourceTree = Tender2Tree.convert(data.category, data.tenders, data.ledgerAuditConst, data.stageAuditConst);
  72. for (const h of biObj.history) {
  73. h.ledger_order = biObj.setting.stageTree.nodes.findIndex(x => { return x.id === h.lid; });
  74. h.ledger_node = h.ledger_order >= 0 ? biObj.setting.stageTree.nodes[h.ledger_order] : null;
  75. if (h.tenders) h.tenders = h.tenders.filter(x => { return biObj.tenderSourceTree.nodes.find(y => { return x.tid === y.tid; })});
  76. }
  77. biObj.history.sort((x, y) => { return x.ledger_order - y.ledger_order; });
  78. biObj.reloadBatchTree();
  79. SpreadJsObj.loadSheetData(biObj.sheet, SpreadJsObj.DataType.Tree, biObj.batchTree);
  80. biObj.rebuildStageSelect();
  81. });
  82. },
  83. initBatchImport: function () {
  84. if (this.spread) return;
  85. this.spread = SpreadJsObj.createNewSpread($('#bi-spread')[0]);
  86. this.sheet = this.spread.getActiveSheet();
  87. SpreadJsObj.initSheet(this.sheet, {
  88. cols: [
  89. {title: '选择', field: 'selected', hAlign: 1, width: 40, formatter: '@', cellType: 'checkbox'},
  90. {title: '编号', field: 'code', hAlign: 0, width: 180, formatter: '@', cellType: 'tree', readOnly: true },
  91. {title: '名称/引用标段', field: 'name', hAlign: 0, width: 180, formatter: '@', readOnly: true },
  92. {title: '可选期', field: 'stage', hAlign: 1, width: 60, formatter: '@'},
  93. {title: '指定项目节', field: 'match_code', hAlign: 1, width: 70, formatter: '@', readOnly: true},
  94. {title: '状态', field: 'status', hAlign: 1, width: 60, formatter: '@', readOnly: true},
  95. {title: '错误信息', field: 'error', hAlign: 1, width: 60, formatter: '@', readOnly: true},
  96. ],
  97. emptyRows: 0,
  98. headRows: 1,
  99. headRowHeight: [32],
  100. defaultRowHeight: 21,
  101. headerFont: '12px 微软雅黑',
  102. font: '12px 微软雅黑',
  103. selectedBackColor: '#fffacd',
  104. });
  105. this.spread.bind(spreadNS.Events.EditEnded, biObj.EditEnded);
  106. this.spread.bind(spreadNS.Events.ButtonClicked, biObj.ButtonClicked);
  107. this.batchTree = createNewPathTree('gather', {
  108. id: 'id',
  109. pid: 'pid',
  110. order: 'order',
  111. level: 'level',
  112. rootId: -1,
  113. fullPath: 'full_path',
  114. });
  115. this.loadHistory();
  116. },
  117. checkErrors: function () {
  118. const hasError = this.batchTree.children.findIndex(x => { return x.error > 0; }) >= 0;
  119. if (hasError) {
  120. $('#bi-download-error').show();
  121. } else {
  122. $('#bi-download-error').hide();
  123. }
  124. },
  125. importStageGcl: async function (node, cover, ignore, change) {
  126. const updateData = { lid: node.lid, type: 'stage', cover, ignore, change, tenders: [] };
  127. for (const tender of node.children) {
  128. updateData.tenders.push({ tid: tender.tid, name: tender.name, stageCount: tender.stageCount, stage: tender.stage, match_code: tender.match_code });
  129. }
  130. const result = await postDataAsync(window.location.pathname + '/sumLoad', updateData);
  131. biObj.setting.afterLoad(result, node.ledger_node);
  132. node.errors = result.sumLoadHis.errors;
  133. node.error = node.errors ? node.errors.length : 0;
  134. },
  135. beforeBatchImport: function () {
  136. this.batchTree.children.forEach(x => {
  137. x.status = x.selected ? '等待中' : '';
  138. x.error = 0;
  139. x.errors = [];
  140. });
  141. SpreadJsObj.reloadColData(this.sheet, 4, 2);
  142. },
  143. batchImport: async function () {
  144. $('#bi-start')[0].disabled = true;
  145. biObj.batching = true;
  146. this.beforeBatchImport();
  147. const cover = $('#bi-cover')[0].checked;
  148. const ignore = $('#bi-ignore')[0].checked;
  149. const change = $('#bi-change')[0].checked;
  150. for (const node of this.batchTree.children) {
  151. if (!node.selected) continue;
  152. const row = this.batchTree.getNodeIndex(node);
  153. if (!node.children || node.children.length === 0) {
  154. node.status = '无数据';
  155. } else {
  156. try {
  157. node.status = '开始导入';
  158. SpreadJsObj.reLoadRowData(biObj.sheet, row);
  159. await biObj.importStageGcl(node, cover, ignore, change);
  160. node.status = '导入完成';
  161. } catch(err) {
  162. console.log(err);
  163. node.status = '导入失败';
  164. }
  165. }
  166. SpreadJsObj.reLoadRowData(biObj.sheet, row);
  167. }
  168. biObj.batching = false;
  169. $('#bi-start')[0].disabled = false;
  170. biObj.checkErrors();
  171. },
  172. downloadErrors: function () {
  173. const errorType = {
  174. less: '数量变少',
  175. miss: '找不到清单',
  176. 'qc-conflict': '变更冲突(已调用变更令)'
  177. };
  178. // const setting = {
  179. // header: ['清单编号', '清单名称','单位', '合同数量', '变更数量', '错误类型'],
  180. // width: [80, 200, 60, 80, 80, 180],
  181. // hAlign: ['left', 'left', 'center', 'right', 'right', 'left'],
  182. // };
  183. // const sheets = [];
  184. // for (const node of this.batchTree.children) {
  185. // if (node.error > 0) {
  186. // sheets.push({ name: node.code, setting, data: node.errors.map(x => {
  187. // return [x.b_code, x.name, x.unit, x.qty, x.qc_qty, errorType[x.type]]; })
  188. // });
  189. // }
  190. // }
  191. // XLSXObj.exportXlsxSheets(sheets, '批量导入错误.xlsx');
  192. const setting = {
  193. cols: [
  194. {title: '清单编号', field: 'b_code', hAlign: 0, width: 80, formatter: '@'},
  195. {title: '清单名称', field: 'name', hAlign: 0, width: 180, formatter: '@'},
  196. {title: '单位', field: 'unit', hAlign: 1, width: 60, formatter: '@'},
  197. {title: '合同数量', field: 'qty', hAlign: 2, width: 80, formatter: '@'},
  198. {title: '变更数量', field: 'qc_qty', hAlign: 2, width: 80, formatter: '@'},
  199. {title: '错误类型', field: 'type', hAlign: 0, width: 150, formatter: '@', getValue(data) { return errorType[data.type]; }},
  200. ],
  201. emptyRows: 0,
  202. headRows: 1,
  203. headRowHeight: [32],
  204. defaultRowHeight: 21,
  205. headerFont: '12px 微软雅黑',
  206. font: '12px 微软雅黑',
  207. };
  208. const sheets = [];
  209. for (const node of this.batchTree.children) {
  210. if (node.error > 0) {
  211. sheets.push({ name: node.code || node.name, setting, data: node.errors });
  212. }
  213. }
  214. SpreadExcelObj.exportSimpleXlsxSheets(sheets, '批量导入错误.xlsx');
  215. }
  216. };
  217. $('#batch-import').on('shown.bs.modal', () => {
  218. biObj.initBatchImport();
  219. // biObj.loadHistory();
  220. });
  221. $('#bi-start').click(function () {
  222. biObj.batchImport();
  223. });
  224. $('#bi-download-error').click(function () {
  225. biObj.downloadErrors();
  226. });
  227. const show = function () {
  228. $('#batch-import').modal('show');
  229. };
  230. return { show }
  231. };