'use strict'; /** * * * @author Zhong * @date 2019/5/15 * @version */ //操作接口为eventListen const importView = (() => { let importXML = null; let xmlObj = null; //导入xml转化后的对象 let tbcObj = null; //待确认对象 //显示、隐藏提示上传文件窗口相关提示信息 function showUploadAlert(success, msg) { if (!success) { $('#uploadAlert').removeClass('alert-success'); $('#uploadAlert').addClass('alert-danger'); } else { $('#uploadAlert').removeClass('alert-danger'); $('#uploadAlert').addClass('alert-success'); } $('#uploadAlert').text(msg); $('#uploadAlert').show(); } /* * 获取单位工程数据(将所有单项工程里的单位工程放到一起,含有单项工程的一些信息) * @param {Object} xmlObj @return {Array} * */ function getTenderDatas(xmlObj) { if (!xmlObj || !xmlObj.engs) { return []; } let rst = []; for (let eng of xmlObj.engs) { if (Array.isArray(eng.tenders)) { for (let tender of eng.tenders) { tender.temp = {}; //暂时存放的信息(不是从导入文件中获取的,记录当前工程已阅、选择的费用标准、计算程序) tender.engName = eng.name; } rst.push(...eng.tenders); } } return rst; } //确认界面提示信息隐藏 function hideTBCInfo() { $('#tbc-engName-info').hide(); $('#tbc-tenderName-info').hide(); $('#tbc-engineering-info').hide(); $('#tbc-calcProgram-info').hide(); } //待确认界面相关 class TBC { constructor(xmlObj, fileKind, valuation, taxType) { this.datas = getTenderDatas(xmlObj); this.fileKind = fileKind; //文件类型 this.valuationType = 'bill'; //计价方式 暂时默认为清单计价 this.valuation = valuation; //计价规则数据 this.taxType = taxType; //计税方法 this.engineeringList = valuation ? valuation.engineering_list : []; //工程专业库数据 this.curIdx = 0; //当前单位工程数据索引 this.init(); } //初始化 init() { this.next(this.curIdx); $('#importInterface .modal-content:eq(1) p:eq(0)').text(`该文件共有${this.datas.length}个单位工程待导入`); //信息统计信息 } checkConfirmed() { //检查数据是否都确认过了 let allConfirmed = this.datas.every(data => data.temp.confirmed); if (allConfirmed) { $('#import-confirm').prop('disabled', false); } } //检测当前待确认工程是否有效,有效才可确认 checkValid() { let engName = $('#tbc-engName').val(); if (!engName) { return $('#tbc-engName-info').show(); } else { $('#tbc-engName-info').hide(); } let tenderName = $('#tbc-tenderName').val(); if (!tenderName) { return $('#tbc-tenderName-info').show(); } else { $('#tbc-tenderName-info').hide(); } let engineering = $('#tbc-engineering').val(); if (!engineering) { return $('#tbc-engineering-info').show(); } else { $('#tbc-engineering-info').hide(); } let feeStandard = $('#tbc-feeStandard').val(); if (!feeStandard) { return $('#tbc-feeStandard-info').show(); } else { $('#tbc-feeStandard-info').hide(); } let calcProgram = $('#tbc-calcProgram').val(); if (!calcProgram) { return $('#tbc-calcProgram-info').show(); } else { $('#tbc-calcProgram-info').hide(); } return null; } //下一工程 next(idx = null) { this.curIdx = idx !== null ? idx : this.curIdx + 1; if (this.curIdx && this.checkValid()) { this.curIdx--; return; } let curData = this.datas[this.curIdx]; //显示这个工程的相关信息 $('#tbc-engName').val(curData.engName || ''); $('#tbc-tenderName').val(curData.name || ''); $('#tbc-engineering').val(curData.engineering || ''); curData.temp.confirmed = true; //增加确认信息(已读) if (this.curIdx === this.datas.length - 1) { //到最后一个数据了,无法点击下一工程 $('#tbc-next').prop('disabled', true); } else { $('#tbc-next').prop('disabled', false); } if (this.curIdx !== 0) { //不为第一个数据,可以点击上一工程 $('#tbc-prev').prop('disabled', false); } else { $('#tbc-prev').prop('disabled', true); } //更新x/x信息 $('#tbc-info').text(`${this.curIdx + 1}/${this.datas.length} 已确认`); //更新选项信息 this.initFeeOpts(curData); this.checkConfirmed(); } //上一工程 prev(idx = null) { this.curIdx = idx !== null ? idx : this.curIdx - 1; let curData = this.datas[this.curIdx]; $('#tbc-engName').val(curData.engName || ''); $('#tbc-tenderName').val(curData.name || ''); $('#tbc-engineering').val(curData.engineering || ''); if (this.curIdx === 0) { //到第一个数据了,无法点击上一工程 $('#tbc-prev').prop('disabled', true); } else { $('#tbc-prev').prop('disabled', false); } if (this.curIdx !== this.datas.length - 1) { //不为最后一个数据了,可以点击下一工程 $('#tbc-next').prop('disabled', false); } else { $('#tbc-next').prop('disabled', true); } //更新x/x信息 $('#tbc-info').text(`${this.curIdx + 1}/${this.datas.length} 已确认`); //更新选项信息 this.initFeeOpts(curData); this.checkConfirmed(); } /* * 初始化工程的费用选项等相关信息(专业工程、费用标准、计算程序等) * 根据导入文件提取的专业工程等数据确定,需要我们软件有对应的工程专业数据,否则下拉选择为空 * @param {Object}tenderData(当前确认单位工程数据) {Array}engineeringList(当前计价规则下的工程专业数据) * @return {void} * */ initFeeOpts(tenderData) { $('#tbc-engineering').empty(); //清空工程专业选项 $('#tbc-feeStandard').empty(); //清空费用标准选项 $('#tbc-calcProgram').empty(); //清空计算程序选项 let engineerings = []; if (tenderData.temp.engineering) { engineerings = this.engineeringList.filter(data => data.lib.name === tenderData.temp.engineering); } else { engineerings = this.engineeringList.filter(data => data.lib.name === tenderData.engineering); tenderData.temp.engineering = tenderData.engineering; } //文件里的工程专业跟软件里的对应不上,取第一个 if (!engineerings.length) { let firstEngineering = this.engineeringList[0]; engineerings = this.engineeringList.filter(data => data.lib.name === firstEngineering.lib.name); tenderData.temp.engineering = engineerings[0] ? engineerings[0].lib.name : tenderData.engineering; } if (!engineerings.length) { return; } //工程专业名称去重 let engineeringNames = [...new Set(this.engineeringList.map(data => data.lib.name))]; let engineeringHtml = engineeringNames.map(name => ``); $('#tbc-engineering').html(engineeringHtml); //$('#tbc-engineering').html(``); //费用标准,若当前工程有费用标准数据(该数据本身没有费用标准数据,选择过了,就会记录),则选中该费用标准 let feeOptsHtml = engineerings.map(data => ``).join(''); $('#tbc-feeStandard').html(feeOptsHtml); //记录选中的费用标准 tenderData.temp.feeStandard = $('#tbc-feeStandard').val(); //根据工程专业及费用标准确定的当前选中的工程专业库 let curEngineering = engineerings.find(data => data.lib.feeName === tenderData.temp.feeStandard) || engineerings[0]; //根据计税方法过滤出来的计税组合 let taxDatas = curEngineering.lib.tax_group.filter(data => data.taxType == this.taxType); //计算程序,若当前工程有计算程序(该数据本身没有计算程序数据,选择过了,就会记录),则选中该计算程序 let calcOptsHtml = taxDatas.map(data => ``); $('#tbc-calcProgram').html(calcOptsHtml); tenderData.temp.calcProgram = $('#tbc-calcProgram').val(); } } /* * 根据条件获取计税组合数据 * @param {Object}query ({engineeringName, feeName, taxType, calcProgram}) {Array}engineeringList(当前计价规则下的所有工程专业数据) * @return {Object} * */ function getTaxData(query, engineeringList) { //工程专业名称 + 费用标准名称 确定一个工程专业数据 let engineering = engineeringList.find(data => query.engineeringName === data.lib.name && query.feeStandard === data.lib.feeName); if (!engineering || !Array.isArray(engineering.lib.tax_group)) { return null; } return engineering.lib.tax_group.find(data => query.taxType == data.taxType && query.calcProgram === data.program_lib.name); } //获取单位工程项目属性的一些数据(新建单位工程需要,前端能获取到的一些数据,还有一些数据需要后端获取: rootProjectID, projectFeature..) /* * @param {Object}tbcObj(TBC实例) {Object}curData(单位工程数据) * @return {Object} * */ function getProperty(tbcObj, curData) { if (!tbcObj) { throw '存在无效数据,无法生成项目。'; } //计税数据 let query = { engineeringName: curData.temp.engineering || curData.engineering, feeStandard: curData.temp.feeStandard, taxType: tbcObj.taxType, //取导入时选择的计税方法,不读取文件中的计税方法 calcProgram: curData.temp.calcProgram }; let taxData = getTaxData(query, tbcObj.engineeringList); if (!taxData) { throw '无效计税数据,无法生成项目。'; } //当前工程专业数据 let curEngineering = tbcObj.engineeringList.find(data => query.engineeringName === data.lib.name && query.feeStandard === data.lib.feeName); return { region: '全省', //地区 valuationType: tbcObj.valuationType, //计价方式 valuation: tbcObj.valuation.id, //计价规则 valuationName: tbcObj.valuation.name, engineering_id: curEngineering.engineering_id, //工程专业 engineeringName: curEngineering.lib.name, taxType: parseInt(tbcObj.taxType), //计税方法 isInstall: !!curEngineering.lib.isInstall, //是安装工程? isItemIncrease: !!curEngineering.lib.isItemIncrease, //是否子目增加费? isAreaIncrease: !!curEngineering.lib.isAreaIncrease, //是否子目增加费? feeStandardName: curEngineering.lib.feeName, //费用标准 engineering: curEngineering.lib.engineering, //定额取费专业 projectEngineering: curEngineering.lib.projectEngineering, //单位工程取费专业 featureLibID: curEngineering.lib.feature_lib[0] ? curEngineering.lib.feature_lib[0].id : '', //工程特征 indexName: curEngineering.lib.indexName, // 指标名称 engineerInfoLibID: curEngineering.lib.engineer_info_lib[0] ? curEngineering.lib.engineer_info_lib[0].id : '', // 工程信息指标 engineerFeatureLibID: curEngineering.lib.engineer_feature_lib[0] ? curEngineering.lib.engineer_feature_lib[0].id : '', //工程特征指标 economicLibID: curEngineering.lib.economic_lib[0] ? curEngineering.lib.economic_lib[0].id : '', // 主要经济指标 mainQuantityLibID: curEngineering.lib.main_quantity_lib[0] ? curEngineering.lib.main_quantity_lib[0].id : '', // 主要工程量指标 materialLibID: curEngineering.lib.material_lib[0] ? curEngineering.lib.material_lib[0].id : '', // 主要工料指标 calcProgram: { name: taxData.program_lib.name, id: taxData.program_lib.id }, //计算程序 colLibID: taxData.col_lib.id, //列设置 templateLibID: taxData.template_lib.id, //清单模板 unitPriceFile: { name: curData.name, id: '' }, //新建单价文件 feeFile: { name: curData.name, id: `newFeeRate@@${taxData.fee_lib.id}` } //新建费率文件 }; } function eventListen() { //选择文件 $('#customFile').change(async function () { let file = $(this)[0].files[0]; $('#import-confirm').prop('disabled', true); //确认导入无效 $('.custom-file-label').text(`${file ? file.name : ''}`); //设置选择框文本 $('#uploadAlert').hide(); $('.selFile').hide(); hideTBCInfo(); if (file) { let reg = /(xml|XML|qtf|QTF)$/; if (file.name && !reg.test(file.name)) { $('.selFile').hide(); showUploadAlert(false, '请选择xml或qtf文件。'); return; } $.bootstrapLoading.start(); $('#loadingPage').css('z-index', '2000'); //转换数据 importXML = new ImportXML(); try { xmlObj = await importXML.extractData(file, false); $('.selFile input:eq(0)').val(xmlObj && xmlObj.name ? xmlObj.name : ''); $('.selFile input[name="fileKind-import"]:eq(0)').prop('checked', true); //文件类型恢复成投标 $('#import-taxType').val('1'); //计税方法显示回默认的一般计税法 $('.selFile').show(); //显示建设项目、计价规则 } catch (err) { console.log(err); showUploadAlert(false, err); $(this).val(''); } $.bootstrapLoading.end(); } }); //下一步 $('#import-next').click(function () { let file = $('#customFile')[0].files[0]; if (!file) { showUploadAlert(false, '请选择导入文件。'); return; } if (!xmlObj) { showUploadAlert(false, '不存在有效数据。'); return; } let projectName = $('.selFile input:eq(0)').val(); if (!projectName) { showUploadAlert(false, '不存在有效建设项目。'); return; } //文件类型 let fileKind = $('.selFile input[name="fileKind-import"]:checked').val(); if (!fileKind) { showUploadAlert(false, '不存在有效文件类型。'); } //计价规则 let valuation = $('#import-valuation').val(); if (!valuation) { showUploadAlert(false, '不存在有效计价规则。'); return; } //计税方法 let taxType = $('#import-taxType').val(); if (!taxType) { showUploadAlert(false, '不存在有效计税方法。'); return; } if (!xmlObj.engs.length) { showUploadAlert(false, '不存在单项工程数据。'); return; } if (!getTenderDatas(xmlObj).length) { showUploadAlert(false, '不存在单位工程数据。'); return; } $('#importInterface .modal-content:eq(0)').hide(); //隐藏第一步内容 $('#importInterface .modal-content:eq(1)').show(); //显示第二步内容 //console.log(getTenderDatas(xmlObj)); //console.log(xmlObj); let selValuation = billValuation.find(data => data.id === valuation); tbcObj = new TBC(xmlObj, fileKind, selValuation, taxType); }); //上一步 $('#import-prev').click(function () { $('#importInterface .modal-content:eq(0)').show(); //显示第一步内容 $('#importInterface .modal-content:eq(1)').hide(); //隐藏第二步内容 hideTBCInfo(); $('#import-confirm').prop('disabled', true); //确认导入无效 //清空确认字段 if (tbcObj) { for (let data of tbcObj.datas) { delete data.temp.confirmed; } } }); //变换专业工程 $('#tbc-engineering').change(function () { let curData = tbcObj ? tbcObj.datas[tbcObj.curIdx] : null; if (!curData) { return; } curData.temp.engineering = $(this).val(); tbcObj.initFeeOpts(curData); }); //变换费用标准 $('#tbc-feeStandard').change(function () { let curData = tbcObj ? tbcObj.datas[tbcObj.curIdx] : null; if (!curData) { return; } curData.temp.feeStandard = $(this).val(); tbcObj.initFeeOpts(curData); }); //变换计算程序 $('#tbc-calcProgram').change(function () { let curData = tbcObj ? tbcObj.datas[tbcObj.curIdx] : null; if (!curData) { return; } curData.temp.calcProgram = $(this).val(); tbcObj.initFeeOpts(curData); }); //待确认-下一工程 $('#tbc-next').click(function () { tbcObj.next(); }); //待确认-上一工程 $('#tbc-prev').click(function () { tbcObj.prev(); hideTBCInfo(); }); //确认导入 $('#import-confirm').click(async function () { if (STATE.importing) { return; } STATE.importing = true; if (tbcObj && tbcObj.checkValid()) { return; } let pr = new SCComponent.InitProgressBar(); try { //建设项目设置选择的文件类型和选择的计税方法 xmlObj.property.fileKind = tbcObj.fileKind; xmlObj.property.taxType = tbcObj.taxType; //确定使用的计税组合 tbcObj.datas.map(data => { data.property = getProperty(tbcObj, data); //默认定额库 let curEngineering = tbcObj.engineeringList.find(enData => data.temp.engineering === enData.lib.name && data.temp.feeStandard === enData.lib.feeName); let defaultLib = curEngineering.lib.ration_lib.find(data => data.isDefault) || curEngineering.lib.ration_lib[0]; data.defaultRationLib = parseInt(defaultLib.id); //此费用定额下可用的定额库id,人材机库id data.rationLibIDs = curEngineering.lib.ration_lib.map(data => parseInt(data.id)); data.gljLibIDs = curEngineering.lib.glj_lib.map(data => parseInt(data.id)); }); //确定生成建设项目的父、前、后节点ID let { parentProjectID, preProjectID, nextProjectID } = projTreeObj.getRelProjectID(projTreeObj.tree.selected); xmlObj.ParentID = parentProjectID; xmlObj.preID = preProjectID; xmlObj.NextSiblingID = nextProjectID; //确定建设项目的名称(不允许重复) let sameDepthProjs = getProjs(projTreeObj.tree.selected); if (sameDepthProjs.find(node => node.data.name === xmlObj.name)) { xmlObj.name += `(${moment(Date.now()).format('YYYY-MM-DD HH:mm:ss')})`; } $('#importInterface').modal('hide'); pr.start('导入文件', '正在生成文件,请稍候……'); let importData = await importXML.transformData(xmlObj); let blob = new Blob([JSON.stringify(importData)], { type: 'text/plain;charset=utf-8' }); // 转换成File实例 const key = `${uuid.v1()}.json`; const file = new File([blob], key); // 上传文件 console.time(); await projTreeObj.getUploadToken(); await UPLOAD_CDN.uploadSync(file, key, projTreeObj.uptoken); // 下载并处理文件 const rstData = await ajaxPost('/pm/import/importInterface', { key }); console.timeEnd(); if (Array.isArray(rstData)) { doAfterImport(rstData); } } catch (err) { console.log(err); alert(err); } finally { projTreeObj.uptoken = null; setTimeout(function () { STATE.importing = false; }, 500); pr.end(); } }); // 导入窗口激活 $('#importInterface').on('show.bs.modal', function () { // 恢复计价规则下拉 setValuationSels($('#import-valuation'), billValuation); }); //导入窗口消失后 $('#importInterface').on('hidden.bs.modal', function () { importXML = null; xmlObj = null; //重置数据 tbcObj = null; $('#importInterface .modal-content:eq(0)').show(); //显示第一步内容 $('#importInterface .modal-content:eq(1)').hide(); //隐藏第二步内容 $('#customFile').val(''); //清除选择 $('.custom-file-label').text(''); //设置选择框文本 $('#uploadAlert').hide(); //隐藏提示 $('.selFile').hide(); //隐藏建设项目及计价规则 $('#import-confirm').prop('disabled', true); //确认导入无效 $('.selFile input[name="fileKind-import"]:eq(0)').prop('checked', true); //文件类型恢复成投标 $('#import-taxType').val('1'); //显示回一般计税 hideTBCInfo(); }); } //projectDatas在后端已经按照顺序排过了: project eng1 tender1-1 tender1-2 eng2 tender2-1 tender2-2 function doAfterImport(projectDatas) { //插入节点 let lastNode; for (let data of projectDatas) { data.feeStandardName = data.property && data.property.feeStandardName || ''; //工程专业列显示用 let parent = projTreeObj.tree.items.find(node => node.data.ID === data.ParentID), next = projTreeObj.tree.items.find(node => node.data.ID === data.NextSiblingID); lastNode = projTreeObj.insert(data, parent, next); } if (lastNode) { projTreeObj.workBook.getSheet(0).showRow(lastNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center); } } return { eventListen }; })();