| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510 | 'use strict';/** * * * @author Zhong * @date 2019/5/15 * @version *///操作接口为eventListenconst 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 =>                `<option ${tenderData.temp.engineering === name ? 'selected' : ''} value="${name}">${name}</option>`);            $('#tbc-engineering').html(engineeringHtml);            //$('#tbc-engineering').html(`<option selected value="${tenderData.engineering}">${tenderData.engineering}</option>`);            //费用标准,若当前工程有费用标准数据(该数据本身没有费用标准数据,选择过了,就会记录),则选中该费用标准            let feeOptsHtml = engineerings.map(data =>                `<option ${tenderData.temp.feeStandard === data.lib.feeName ? 'selected' : ''} value="${data.lib.feeName}">${data.lib.feeName}</option>`).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 =>                `<option ${tenderData.temp.calcProgram === data.program_lib.name ? 'selected' : ''} value="${data.program_lib.name}">${data.program_lib.name}</option>`);            $('#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,  //是安装工程?            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 };})();
 |