pm_import.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. 'use strict';
  2. /**
  3. *
  4. *
  5. * @author Zhong
  6. * @date 2019/5/15
  7. * @version
  8. */
  9. //操作接口为eventListen
  10. const importView = (() => {
  11. let xmlObj = null; //导入xml转化后的对象
  12. let tbcObj = null; //待确认对象
  13. //显示、隐藏提示上传文件窗口相关提示信息
  14. function showUploadAlert(success, msg) {
  15. if (!success) {
  16. $('#uploadAlert').removeClass('alert-success');
  17. $('#uploadAlert').addClass('alert-danger');
  18. } else {
  19. $('#uploadAlert').removeClass('alert-danger');
  20. $('#uploadAlert').addClass('alert-success');
  21. }
  22. $('#uploadAlert').text(msg);
  23. $('#uploadAlert').show();
  24. }
  25. /*
  26. * 获取单位工程数据(将所有单项工程里的单位工程放到一起,含有单项工程的一些信息)
  27. * @param {Object} xmlObj @return {Array}
  28. * */
  29. function getTenderDatas(xmlObj) {
  30. if (!xmlObj || !xmlObj.engs) {
  31. return [];
  32. }
  33. let rst = [];
  34. for (let eng of xmlObj.engs) {
  35. if (Array.isArray(eng.tenders)) {
  36. for (let tender of eng.tenders) {
  37. tender.temp = {}; //暂时存放的信息(不是从导入文件中获取的,记录当前工程已阅、选择的费用标准、计算程序)
  38. tender.engName = eng.name;
  39. }
  40. rst.push(...eng.tenders);
  41. }
  42. }
  43. return rst;
  44. }
  45. //确认界面提示信息隐藏
  46. function hideTBCInfo() {
  47. $('#tbc-engName-info').hide();
  48. $('#tbc-tenderName-info').hide();
  49. $('#tbc-engineering-info').hide();
  50. $('#tbc-calcProgram-info').hide();
  51. }
  52. //待确认界面相关
  53. class TBC {
  54. constructor(xmlObj, fileKind, valuation, taxType) {
  55. this.datas = getTenderDatas(xmlObj);
  56. this.fileKind = fileKind; //文件类型
  57. this.valuationType = 'bill'; //计价方式 暂时默认为清单计价
  58. this.valuation = valuation; //计价规则数据
  59. this.taxType = taxType; //计税方法
  60. this.engineeringList = valuation ? valuation.engineering_list : []; //工程专业库数据
  61. this.curIdx = 0; //当前单位工程数据索引
  62. this.init();
  63. }
  64. //初始化
  65. init() {
  66. this.next(this.curIdx);
  67. $('#importInterface .modal-content:eq(1) p:eq(0)').text(`该文件共有${this.datas.length}个单位工程待导入`); //信息统计信息
  68. }
  69. checkConfirmed() {
  70. //检查数据是否都确认过了
  71. let allConfirmed = this.datas.every(data => data.temp.confirmed);
  72. if (allConfirmed) {
  73. $('#import-confirm').prop('disabled', false);
  74. }
  75. }
  76. //检测当前待确认工程是否有效,有效才可确认
  77. checkValid() {
  78. let engName = $('#tbc-engName').val();
  79. if (!engName) {
  80. return $('#tbc-engName-info').show();
  81. } else {
  82. $('#tbc-engName-info').hide();
  83. }
  84. let tenderName = $('#tbc-tenderName').val();
  85. if (!tenderName) {
  86. return $('#tbc-tenderName-info').show();
  87. } else {
  88. $('#tbc-tenderName-info').hide();
  89. }
  90. let engineering = $('#tbc-engineering').val();
  91. if (!engineering) {
  92. return $('#tbc-engineering-info').show();
  93. } else {
  94. $('#tbc-engineering-info').hide();
  95. }
  96. let feeStandard = $('#tbc-feeStandard').val();
  97. if (!feeStandard) {
  98. return $('#tbc-feeStandard-info').show();
  99. } else {
  100. $('#tbc-feeStandard-info').hide();
  101. }
  102. let calcProgram = $('#tbc-calcProgram').val();
  103. if (!calcProgram) {
  104. return $('#tbc-calcProgram-info').show();
  105. } else {
  106. $('#tbc-calcProgram-info').hide();
  107. }
  108. return null;
  109. }
  110. //下一工程
  111. next(idx = null) {
  112. this.curIdx = idx !== null ? idx : this.curIdx + 1;
  113. if (this.curIdx && this.checkValid()) {
  114. this.curIdx--;
  115. return;
  116. }
  117. let curData = this.datas[this.curIdx];
  118. //显示这个工程的相关信息
  119. $('#tbc-engName').val(curData.engName || '');
  120. $('#tbc-tenderName').val(curData.name || '');
  121. $('#tbc-engineering').val(curData.engineering || '');
  122. curData.temp.confirmed = true; //增加确认信息(已读)
  123. if (this.curIdx === this.datas.length - 1) { //到最后一个数据了,无法点击下一工程
  124. $('#tbc-next').prop('disabled', true);
  125. } else {
  126. $('#tbc-next').prop('disabled', false);
  127. }
  128. if (this.curIdx !== 0) { //不为第一个数据,可以点击上一工程
  129. $('#tbc-prev').prop('disabled', false);
  130. } else {
  131. $('#tbc-prev').prop('disabled', true);
  132. }
  133. //更新x/x信息
  134. $('#tbc-info').text(`${this.curIdx + 1}/${this.datas.length} 已确认`);
  135. //更新选项信息
  136. this.initFeeOpts(curData);
  137. this.checkConfirmed();
  138. }
  139. //上一工程
  140. prev(idx = null) {
  141. this.curIdx = idx !== null ? idx : this.curIdx - 1;
  142. let curData = this.datas[this.curIdx];
  143. $('#tbc-engName').val(curData.engName || '');
  144. $('#tbc-tenderName').val(curData.name || '');
  145. $('#tbc-engineering').val(curData.engineering || '');
  146. if (this.curIdx === 0) { //到第一个数据了,无法点击上一工程
  147. $('#tbc-prev').prop('disabled', true);
  148. } else {
  149. $('#tbc-prev').prop('disabled', false);
  150. }
  151. if (this.curIdx !== this.datas.length - 1) { //不为最后一个数据了,可以点击下一工程
  152. $('#tbc-next').prop('disabled', false);
  153. } else {
  154. $('#tbc-next').prop('disabled', true);
  155. }
  156. //更新x/x信息
  157. $('#tbc-info').text(`${this.curIdx + 1}/${this.datas.length} 已确认`);
  158. //更新选项信息
  159. this.initFeeOpts(curData);
  160. this.checkConfirmed();
  161. }
  162. /*
  163. * 初始化工程的费用选项等相关信息(专业工程、费用标准、计算程序等)
  164. * 根据导入文件提取的专业工程等数据确定,需要我们软件有对应的工程专业数据,否则下拉选择为空
  165. * @param {Object}tenderData(当前确认单位工程数据) {Array}engineeringList(当前计价规则下的工程专业数据)
  166. * @return {void}
  167. * */
  168. initFeeOpts(tenderData) {
  169. $('#tbc-engineering').empty(); //清空工程专业选项
  170. $('#tbc-feeStandard').empty(); //清空费用标准选项
  171. $('#tbc-calcProgram').empty(); //清空计算程序选项
  172. let engineerings = [];
  173. if (tenderData.temp.engineering) {
  174. engineerings = this.engineeringList.filter(data => data.lib.name === tenderData.temp.engineering);
  175. } else {
  176. engineerings = this.engineeringList.filter(data => data.lib.name === tenderData.engineering);
  177. tenderData.temp.engineering = tenderData.engineering;
  178. }
  179. //文件里的工程专业跟软件里的对应不上,取第一个
  180. if (!engineerings.length) {
  181. let firstEngineering = this.engineeringList[0];
  182. engineerings = this.engineeringList.filter(data => data.lib.name === firstEngineering.lib.name);
  183. tenderData.temp.engineering = engineerings[0] ? engineerings[0].lib.name : tenderData.engineering;
  184. }
  185. if (!engineerings.length) {
  186. return;
  187. }
  188. //工程专业名称去重
  189. let engineeringNames = [...new Set(this.engineeringList.map(data => data.lib.name))];
  190. let engineeringHtml = engineeringNames.map(name =>
  191. `<option ${tenderData.temp.engineering === name ? 'selected' : ''} value="${name}">${name}</option>`);
  192. $('#tbc-engineering').html(engineeringHtml);
  193. //$('#tbc-engineering').html(`<option selected value="${tenderData.engineering}">${tenderData.engineering}</option>`);
  194. //费用标准,若当前工程有费用标准数据(该数据本身没有费用标准数据,选择过了,就会记录),则选中该费用标准
  195. let feeOptsHtml = engineerings.map(data =>
  196. `<option ${tenderData.temp.feeStandard === data.lib.feeName ? 'selected' : ''} value="${data.lib.feeName}">${data.lib.feeName}</option>`).join('');
  197. $('#tbc-feeStandard').html(feeOptsHtml);
  198. //记录选中的费用标准
  199. tenderData.temp.feeStandard = $('#tbc-feeStandard').val();
  200. //根据工程专业及费用标准确定的当前选中的工程专业库
  201. let curEngineering = engineerings.find(data => data.lib.feeName === tenderData.temp.feeStandard) || engineerings[0];
  202. //根据计税方法过滤出来的计税组合
  203. let taxDatas = curEngineering.lib.tax_group.filter(data => data.taxType == this.taxType);
  204. //计算程序,若当前工程有计算程序(该数据本身没有计算程序数据,选择过了,就会记录),则选中该计算程序
  205. let calcOptsHtml = taxDatas.map(data =>
  206. `<option ${tenderData.temp.calcProgram === data.program_lib.name ? 'selected' : ''} value="${data.program_lib.name}">${data.program_lib.name}</option>`);
  207. $('#tbc-calcProgram').html(calcOptsHtml);
  208. tenderData.temp.calcProgram = $('#tbc-calcProgram').val();
  209. }
  210. }
  211. /*
  212. * 根据条件获取计税组合数据
  213. * @param {Object}query ({engineeringName, feeName, taxType, calcProgram}) {Array}engineeringList(当前计价规则下的所有工程专业数据)
  214. * @return {Object}
  215. * */
  216. function getTaxData(query, engineeringList) {
  217. //工程专业名称 + 费用标准名称 确定一个工程专业数据
  218. let engineering = engineeringList.find(data => query.engineeringName === data.lib.name &&
  219. query.feeStandard === data.lib.feeName);
  220. if (!engineering || !Array.isArray(engineering.lib.tax_group)) {
  221. return null;
  222. }
  223. return engineering.lib.tax_group.find(data => query.taxType == data.taxType &&
  224. query.calcProgram === data.program_lib.name);
  225. }
  226. //获取单位工程项目属性的一些数据(新建单位工程需要,前端能获取到的一些数据,还有一些数据需要后端获取: rootProjectID, projectFeature..)
  227. /*
  228. * @param {Object}tbcObj(TBC实例) {Object}curData(单位工程数据)
  229. * @return {Object}
  230. * */
  231. function getProperty(tbcObj, curData) {
  232. if (!tbcObj) {
  233. throw '存在无效数据,无法生成项目。';
  234. }
  235. //计税数据
  236. let query = {
  237. engineeringName: curData.temp.engineering || curData.engineering,
  238. feeStandard: curData.temp.feeStandard,
  239. taxType: tbcObj.taxType, //取导入时选择的计税方法,不读取文件中的计税方法
  240. calcProgram: curData.temp.calcProgram
  241. };
  242. let taxData = getTaxData(query, tbcObj.engineeringList);
  243. if (!taxData) {
  244. throw '无效计税数据,无法生成项目。';
  245. }
  246. //当前工程专业数据
  247. let curEngineering = tbcObj.engineeringList.find(data => query.engineeringName === data.lib.name &&
  248. query.feeStandard === data.lib.feeName);
  249. return {
  250. region: '全省', //地区
  251. valuationType: tbcObj.valuationType, //计价方式
  252. valuation: tbcObj.valuation.id, //计价规则
  253. valuationName: tbcObj.valuation.name,
  254. engineering_id: curEngineering.engineering_id, //工程专业
  255. engineeringName: curEngineering.lib.name,
  256. taxType: parseInt(tbcObj.taxType), //计税方法
  257. isInstall: !!curEngineering.lib.isInstall, //是安装工程?
  258. isItemIncrease: !!curEngineering.lib.isItemIncrease, //是否子目增加费?
  259. isAreaIncrease: !!curEngineering.lib.isAreaIncrease, //是否子目增加费?
  260. feeStandardName: curEngineering.lib.feeName, //费用标准
  261. engineering: curEngineering.lib.engineering, //定额取费专业
  262. projectEngineering: curEngineering.lib.projectEngineering, //单位工程取费专业
  263. featureLibID: curEngineering.lib.feature_lib[0] ? curEngineering.lib.feature_lib[0].id : '', //工程特征
  264. indexName: curEngineering.lib.indexName, // 指标名称
  265. engineerInfoLibID: curEngineering.lib.engineer_info_lib[0] ? curEngineering.lib.engineer_info_lib[0].id : '', // 工程信息指标
  266. engineerFeatureLibID: curEngineering.lib.engineer_feature_lib[0] ? curEngineering.lib.engineer_feature_lib[0].id : '', //工程特征指标
  267. economicLibID: curEngineering.lib.economic_lib[0] ? curEngineering.lib.economic_lib[0].id : '', // 主要经济指标
  268. mainQuantityLibID: curEngineering.lib.main_quantity_lib[0] ? curEngineering.lib.main_quantity_lib[0].id : '', // 主要工程量指标
  269. materialLibID: curEngineering.lib.material_lib[0] ? curEngineering.lib.material_lib[0].id : '', // 主要工料指标
  270. calcProgram: { name: taxData.program_lib.name, id: taxData.program_lib.id }, //计算程序
  271. colLibID: taxData.col_lib.id, //列设置
  272. templateLibID: taxData.template_lib.id, //清单模板
  273. unitPriceFile: { name: curData.name, id: '' }, //新建单价文件
  274. feeFile: { name: curData.name, id: `newFeeRate@@${taxData.fee_lib.id}` } //新建费率文件
  275. };
  276. }
  277. function eventListen() {
  278. //选择文件
  279. $('#customFile').change(async function () {
  280. let file = $(this)[0].files[0];
  281. $('#import-confirm').prop('disabled', true); //确认导入无效
  282. $('.custom-file-label').text(`${file ? file.name : ''}`); //设置选择框文本
  283. $('#uploadAlert').hide();
  284. $('.selFile').hide();
  285. hideTBCInfo();
  286. if (file) {
  287. const reg = importXMLBase.getAcceptReg(importXML.accept);
  288. if (file.name && !reg.test(file.name)) {
  289. $('.selFile').hide();
  290. const acceptAlert = importXML.accept.join('、');
  291. showUploadAlert(false, `请选择${acceptAlert}文件。`);
  292. return;
  293. }
  294. $.bootstrapLoading.start();
  295. $('#loadingPage').css('z-index', '2000');
  296. try {
  297. //转换数据
  298. xmlObj = await importXML.extractData(file, false);
  299. console.log(xmlObj);
  300. debugger;
  301. $('.selFile input:eq(0)').val(xmlObj && xmlObj.name ? xmlObj.name : '');
  302. $('.selFile input[name="fileKind-import"]:eq(0)').prop('checked', true); //文件类型恢复成投标
  303. $('#import-taxType').val('1'); //计税方法显示回默认的一般计税法
  304. $('.selFile').show(); //显示建设项目、计价规则
  305. } catch (err) {
  306. console.log(err);
  307. showUploadAlert(false, err);
  308. $(this).val('');
  309. }
  310. $.bootstrapLoading.end();
  311. }
  312. });
  313. //下一步
  314. $('#import-next').click(function () {
  315. debugger;
  316. let file = $('#customFile')[0].files[0];
  317. if (!file) {
  318. showUploadAlert(false, '请选择导入文件。');
  319. return;
  320. }
  321. if (!xmlObj) {
  322. showUploadAlert(false, '不存在有效数据。');
  323. return;
  324. }
  325. let projectName = $('.selFile input:eq(0)').val();
  326. if (!projectName) {
  327. showUploadAlert(false, '不存在有效建设项目。');
  328. return;
  329. }
  330. //文件类型
  331. let fileKind = $('.selFile input[name="fileKind-import"]:checked').val();
  332. if (!fileKind) {
  333. showUploadAlert(false, '不存在有效文件类型。');
  334. }
  335. //计价规则
  336. let valuation = $('#import-valuation').val();
  337. if (!valuation) {
  338. showUploadAlert(false, '不存在有效计价规则。');
  339. return;
  340. }
  341. //计税方法
  342. let taxType = $('#import-taxType').val();
  343. if (!taxType) {
  344. showUploadAlert(false, '不存在有效计税方法。');
  345. return;
  346. }
  347. if (!xmlObj.engs.length) {
  348. showUploadAlert(false, '不存在单项工程数据。');
  349. return;
  350. }
  351. if (!getTenderDatas(xmlObj).length) {
  352. showUploadAlert(false, '不存在单位工程数据。');
  353. return;
  354. }
  355. $('#importInterface .modal-content:eq(0)').hide(); //隐藏第一步内容
  356. $('#importInterface .modal-content:eq(1)').show(); //显示第二步内容
  357. //console.log(getTenderDatas(xmlObj));
  358. //console.log(xmlObj);
  359. let selValuation = billValuation.find(data => data.id === valuation);
  360. tbcObj = new TBC(xmlObj, fileKind, selValuation, taxType);
  361. });
  362. //上一步
  363. $('#import-prev').click(function () {
  364. $('#importInterface .modal-content:eq(0)').show(); //显示第一步内容
  365. $('#importInterface .modal-content:eq(1)').hide(); //隐藏第二步内容
  366. hideTBCInfo();
  367. $('#import-confirm').prop('disabled', true); //确认导入无效
  368. //清空确认字段
  369. if (tbcObj) {
  370. for (let data of tbcObj.datas) {
  371. delete data.temp.confirmed;
  372. }
  373. }
  374. });
  375. //变换专业工程
  376. $('#tbc-engineering').change(function () {
  377. let curData = tbcObj ? tbcObj.datas[tbcObj.curIdx] : null;
  378. if (!curData) {
  379. return;
  380. }
  381. curData.temp.engineering = $(this).val();
  382. tbcObj.initFeeOpts(curData);
  383. });
  384. //变换费用标准
  385. $('#tbc-feeStandard').change(function () {
  386. let curData = tbcObj ? tbcObj.datas[tbcObj.curIdx] : null;
  387. if (!curData) {
  388. return;
  389. }
  390. curData.temp.feeStandard = $(this).val();
  391. tbcObj.initFeeOpts(curData);
  392. });
  393. //变换计算程序
  394. $('#tbc-calcProgram').change(function () {
  395. let curData = tbcObj ? tbcObj.datas[tbcObj.curIdx] : null;
  396. if (!curData) {
  397. return;
  398. }
  399. curData.temp.calcProgram = $(this).val();
  400. tbcObj.initFeeOpts(curData);
  401. });
  402. //待确认-下一工程
  403. $('#tbc-next').click(function () {
  404. tbcObj.next();
  405. });
  406. //待确认-上一工程
  407. $('#tbc-prev').click(function () {
  408. tbcObj.prev();
  409. hideTBCInfo();
  410. });
  411. //确认导入
  412. $('#import-confirm').click(async function () {
  413. if (STATE.importing) {
  414. return;
  415. }
  416. STATE.importing = true;
  417. if (tbcObj && tbcObj.checkValid()) {
  418. return;
  419. }
  420. let pr = new SCComponent.InitProgressBar();
  421. try {
  422. //建设项目设置选择的文件类型和选择的计税方法
  423. xmlObj.property.fileKind = tbcObj.fileKind;
  424. xmlObj.property.taxType = tbcObj.taxType;
  425. //确定使用的计税组合
  426. tbcObj.datas.map(data => {
  427. data.property = getProperty(tbcObj, data);
  428. //默认定额库
  429. let curEngineering = tbcObj.engineeringList.find(enData => data.temp.engineering === enData.lib.name &&
  430. data.temp.feeStandard === enData.lib.feeName);
  431. let defaultLib = curEngineering.lib.ration_lib.find(data => data.isDefault) || curEngineering.lib.ration_lib[0];
  432. data.defaultRationLib = parseInt(defaultLib.id);
  433. //此费用定额下可用的定额库id,人材机库id
  434. data.rationLibIDs = curEngineering.lib.ration_lib.map(data => parseInt(data.id));
  435. data.gljLibIDs = curEngineering.lib.glj_lib.map(data => parseInt(data.id));
  436. });
  437. //确定生成建设项目的父、前、后节点ID
  438. let { parentProjectID, preProjectID, nextProjectID } = projTreeObj.getRelProjectID(projTreeObj.tree.selected);
  439. xmlObj.ParentID = parentProjectID;
  440. xmlObj.preID = preProjectID;
  441. xmlObj.NextSiblingID = nextProjectID;
  442. //确定建设项目的名称(不允许重复)
  443. let sameDepthProjs = getProjs(projTreeObj.tree.selected);
  444. if (sameDepthProjs.find(node => node.data.name === xmlObj.name)) {
  445. xmlObj.name += `(${moment(Date.now()).format('YYYY-MM-DD HH:mm:ss')})`;
  446. }
  447. $('#importInterface').modal('hide');
  448. pr.start('导入文件', '正在生成文件,请稍候……');
  449. let importData = await importXML.transformData(xmlObj);
  450. debugger;
  451. console.log(importData);
  452. let blob = new Blob([JSON.stringify(importData)], { type: 'text/plain;charset=utf-8' });
  453. // 转换成File实例
  454. const key = `${uuid.v1()}.json`;
  455. const file = new File([blob], key);
  456. // 上传文件
  457. console.time();
  458. await projTreeObj.getUploadToken();
  459. await UPLOAD_CDN.uploadSync(file, key, projTreeObj.uptoken);
  460. // 下载并处理文件
  461. const rstData = await ajaxPost('/pm/import/importInterface', { key });
  462. console.timeEnd();
  463. if (Array.isArray(rstData)) {
  464. doAfterImport(rstData);
  465. }
  466. } catch (err) {
  467. console.log(err);
  468. alert(err);
  469. } finally {
  470. projTreeObj.uptoken = null;
  471. setTimeout(function () {
  472. STATE.importing = false;
  473. }, 500);
  474. pr.end();
  475. }
  476. });
  477. // 导入窗口激活
  478. $('#importInterface').on('show.bs.modal', function () {
  479. // 设置上传文件输入框accept属性
  480. $('#customFile').attr('accept', importXML.accept.join(','));
  481. // 恢复计价规则下拉
  482. setValuationSels($('#import-valuation'), billValuation);
  483. });
  484. //导入窗口消失后
  485. $('#importInterface').on('hidden.bs.modal', function () {
  486. xmlObj = null; //重置数据
  487. tbcObj = null;
  488. $('#importInterface .modal-content:eq(0)').show(); //显示第一步内容
  489. $('#importInterface .modal-content:eq(1)').hide(); //隐藏第二步内容
  490. $('#customFile').val(''); //清除选择
  491. $('.custom-file-label').text(''); //设置选择框文本
  492. $('#uploadAlert').hide(); //隐藏提示
  493. $('.selFile').hide(); //隐藏建设项目及计价规则
  494. $('#import-confirm').prop('disabled', true); //确认导入无效
  495. $('.selFile input[name="fileKind-import"]:eq(0)').prop('checked', true); //文件类型恢复成投标
  496. $('#import-taxType').val('1'); //显示回一般计税
  497. hideTBCInfo();
  498. });
  499. }
  500. //projectDatas在后端已经按照顺序排过了: project eng1 tender1-1 tender1-2 eng2 tender2-1 tender2-2
  501. function doAfterImport(projectDatas) {
  502. //插入节点
  503. let lastNode;
  504. for (let data of projectDatas) {
  505. data.feeStandardName = data.property && data.property.feeStandardName || ''; //工程专业列显示用
  506. let parent = projTreeObj.tree.items.find(node => node.data.ID === data.ParentID),
  507. next = projTreeObj.tree.items.find(node => node.data.ID === data.NextSiblingID);
  508. lastNode = projTreeObj.insert(data, parent, next);
  509. }
  510. if (lastNode) {
  511. projTreeObj.workBook.getSheet(0).showRow(lastNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
  512. }
  513. }
  514. return { eventListen };
  515. })();