ソースを参照

bugs + 导入

zhangweicheng 6 年 前
コミット
e1c7de207b

+ 36 - 0
modules/pm/controllers/pm_controller.js

@@ -714,6 +714,42 @@ module.exports = {
             callback(req, res, 1, err, null);
         }
     },
+    exportProject:async function(req,res){
+        let result={
+            error:0
+        };
+        try {
+            let data = JSON.parse(req.body.data);
+            result.data = await pm_facade.exportProject(req.session.sessionUser.id, data);
+        }catch (err){
+            console.log(err);
+            result.error=1;
+            result.message = err.message;
+        }
+        res.json(result);
+
+    },
+    importProject:async function(req,res){
+        let form = new multiparty.Form({uploadDir: './tmp'});
+        let uploadFullName;
+        form.parse(req, async function (err, fields, files) {
+            try {
+                console.log(fields);
+                const file = typeof files.file !== 'undefined' ? files.file[0] : null;
+                if (err || !file) {
+                    throw '上传失败。';
+                };
+                let data = fs.readFileSync(file.path,'utf-8');
+                let result = await pm_facade.importProjects(data,req,fields);
+                fs.unlinkSync(file.path);
+                res.json(result);
+            }catch (e){
+                console.log(e);
+                res.json({error:1,msg:"导入失败请检查文件!"})
+            }
+
+        })
+    },
     getBasicInfo: async function(req, res) {
         try {
             let data = JSON.parse(req.body.data);

+ 84 - 1
modules/pm/facade/pm_facade.js

@@ -28,7 +28,9 @@ module.exports={
     getProjectFeature: getProjectFeature,
     getProjectByGranularity: getProjectByGranularity,
     importProject: importProject,
-    getProjectPlaceholder: getProjectPlaceholder
+    getProjectPlaceholder: getProjectPlaceholder,
+    exportProject:exportProject,
+    importProjects:importProjects//建筑这里重名了,这比养护加多了个s
 };
 
 
@@ -92,6 +94,8 @@ let calcProgramFacade = require('../../main/facade/calc_program_facade');
 let mainColLibModel = mongoose.model('std_main_col_lib');
 import EngineeringLibModel from "../../users/models/engineering_lib_model";
 let installationFacade = require('../../main/facade/installation_facade');
+let cipher = require('../../../public/cipher');
+
 
 //拷贝例题项目
 //@param {String}userID {Array}projIDs拷贝的例题项目ID(建设项目、文件夹)@return {Boolean}
@@ -1522,4 +1526,83 @@ async function setupStdData(tenderData) {
             ratio.type = stdGLJ.gljType;
         }
     });
+}
+
+async function exportProject(userID,data){//导出建设项目
+    if(data.type == 'main'){
+        return await exportMainData(userID,data.projectID);
+    }else {
+        return await  exportTenderData(data);
+    }
+}
+
+async function exportMainData(userID,projectID) {
+    let result = {userID:userID,projects:[],type:'Project'};//type 备用属性,表示导出的类型,目前导出的都是整个建设项目
+    let tenderIDs = [];
+    let project = await projectModel.findOne({ID:projectID});
+    if(!project) throw  new Error("没有找到该建设项目:"+projectID);
+    result['compilationID'] = project.compilation;
+    result.projects.push(project);
+    let subProjects = await  projectModel.find({"$or": [{'ParentID':projectID}, {"property.rootProjectID": projectID}]});
+    for(let s of subProjects){
+        if(!s.deleteInfo || !s.deleteInfo.deleted){
+            result.projects.push(s);
+            if(s.projType =="Tender") tenderIDs.push(s.ID);
+        }
+    }
+    let files = {unitFiles:await exportUnitFiles(projectID),feeRateFiles:await exportFeeRateFiles(projectID)};
+    result.files = files;
+    result = cipher.aesEncrypt(JSON.stringify(result));
+    result +="|----|" +JSON.stringify(tenderIDs);
+    return result;
+}
+
+async function exportUnitFiles(rootProjectID){
+    let unitFiles = [];
+    let files = await unitPriceFileModel.find({root_project_id:rootProjectID});
+    for(let f of  files){
+        if(f.deleteInfo && f.deleteInfo.deleted == true) continue;
+        let tem = {unitFile:f};
+        tem.unitPrices = await unitPriceModel.find({unit_price_file_id:f.id});
+        tem.mixRatios = await mixRatioModel.find({unit_price_file_id:f.id});
+        unitFiles.push(tem);
+    }
+    return unitFiles;
+}
+
+async function exportFeeRateFiles(rootProjectID) {
+    let feeRateFiles = [];
+    let files = await feeRateFileModel.find({rootProjectID:rootProjectID});
+    for(let f of files){
+        if(f.deleteInfo && f.deleteInfo.deleted == true) continue;
+        let tem = {feeRateFile:f};
+        tem.feeRate = await feeRateModel.findOne({ID:f.feeRateID});
+        feeRateFiles.push(tem);
+    }
+    return feeRateFiles;
+}
+
+
+
+async function exportTenderData(data){
+    let result = {};
+    let projectSetting =  await projectSettingModel.findOne({"projectID": data.projectID}, '-_id');
+    if(projectSetting) result['projSetting'] = projectSetting;
+    result.bills = await billsModel.find({"projectID": data.projectID});
+    result.rations = await rationModel.find({'$or': [{projectID: data.projectID, deleteInfo: null}, {projectID: data.projectID, 'deleteInfo.deleted': {$in: [null, false]}}]});
+    result.projectGLJs = await gljListModel.find({'project_id':data.projectID});
+    result.installationFees =  await installationFeeModel.find({projectID:data.projectID});
+    result.rationGLJs = await rationGLJModel.find({projectID:data.projectID});
+    result.rationCoes = await rationCoeModel.find({projectID:data.projectID});
+    result.quantityDetails = await quantityDetailModel.find({projectID:data.projectID});
+    result.rationInstallations = await rationInstallationModel.find({projectID:data.projectID});
+    result.rationTemplates = await rationTemplateModel.find({projectID:data.projectID});
+    result.calcProgramsFile = await calcProgramsModel.findOne({projectID:data.projectID});
+    result.labourCoes = await labourCoesModel.findOne({projectID:data.projectID});
+
+    return cipher.aesEncrypt(JSON.stringify(result));
+}
+
+async function importProjects(data,req,fields) {
+
 }

+ 2 - 0
modules/pm/routes/pm_route.js

@@ -61,6 +61,8 @@ module.exports = function (app) {
     pmRouter.post('/share', pmController.share);
     pmRouter.post('/receiveProjects', pmController.receiveProjects);
     pmRouter.post('/changeFile', pmController.changeFile);
+    pmRouter.post('/exportProject', pmController.exportProject);
+    pmRouter.post('/importProject', pmController.importProject);
     pmRouter.post('/getBasicInfo', pmController.getBasicInfo);
     pmRouter.post('/getProjectFeature', pmController.getProjectFeature);
     pmRouter.post('/getProjectByGranularity', pmController.getProjectByGranularity);

+ 23 - 0
public/cipher.js

@@ -0,0 +1,23 @@
+/**
+ * Created by zhang on 2019/5/10.
+ */
+let crypto = require('crypto');
+module.exports ={
+    aesEncrypt:aesEncrypt,
+    aesDecrypt:aesDecrypt
+};
+
+
+function aesEncrypt(data, key = 'SmartCost') {
+    const cipher = crypto.createCipher('aes192', key);
+    var crypted = cipher.update(data, 'utf8', 'hex');
+    crypted += cipher.final('hex');
+    return crypted;
+}
+
+function aesDecrypt(encrypted, key= 'SmartCost') {
+    const decipher = crypto.createDecipher('aes192', key);
+    var decrypted = decipher.update(encrypted, 'hex', 'utf8');
+    decrypted += decipher.final('utf8');
+    return decrypted;
+}

+ 42 - 0
public/web/PerfectLoad.js

@@ -83,6 +83,48 @@ jQuery.bootstrapLoading = {
     },
     end: function () {
         $("#loadingPage").remove();
+    },
+    progressStop:true,
+    progressStart:async function(title="导出文件",autoBar = false){
+        if($("#progressModal").length == 0){
+            let phtml =    `<div class="modal fade" id="progressModal" data-backdrop="static">
+                            <div class="modal-dialog" role="document">
+                                <div class="modal-content">
+                                    <div class="modal-header">
+                                         <h5 class="modal-title" id="progress_modal_title">${title}</h5>
+                                    </div>
+                                     <div class="modal-body">
+                                        <!--正在生成-->
+                                        <h5 class="my-3" id="progress_modal_body">正在${title}</h5>
+                                        <div class="progress mb-3">
+                                        <div id="progress_modal_bar" class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100" style="width: 10%"></div>
+                                        </div>
+                                     </div>
+                                   </div>
+                                </div>
+                            </div>`;
+            $("body").append(phtml);
+        }else {
+            $("#progress_modal_title").text(title);
+            $("#progress_modal_body").text(`正在${title}`);
+        }
+        $("#progress_modal_bar").css('width','0%');
+        $("#progressModal").modal('show');
+        if(autoBar == true){//假的进度条
+            $.bootstrapLoading.progressStop = false;
+            let width = 0;
+            while ($.bootstrapLoading.progressStop == false){
+                await  setTimeoutSync(null,1000);
+                width += 5;
+                if(width > 90) width -= 50;
+                $("#progress_modal_bar").css('width',`${width}%`);
+            }
+        }
+    },
+    progressEnd:function () {
+        $("#progress_modal_bar").css('width','100%');
+        $.bootstrapLoading.progressStop = true;
+        $("#progressModal").modal('hide');
     }
 }
 

+ 1 - 1
web/building_saas/glj/html/project_glj.html

@@ -177,7 +177,7 @@
     <div class="modal-dialog modal-lg" role="document">
         <div class="modal-content">
             <div class="modal-header">
-                <h5 class="modal-title">从人机汇总中选择</h5>
+                <h5 class="modal-title">从人机汇总中选择</h5>
                 <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                     <span aria-hidden="true">&times;</span>
                 </button>

+ 1 - 0
web/building_saas/pm/html/project-management.html

@@ -909,6 +909,7 @@
 </div>
 <!-- JS. -->
 <script src = "/lib/spreadjs/sheets/gc.spread.sheets.all.11.1.2.min.js"></script>
+<script src = "/lib/fileSaver/FileSaver.min.js"></script>
 <script>GC.Spread.Sheets.LicenseKey = '<%- LicenseKey %>';</script>
 <script src="/lib/x2js/xml2json.min.js"></script>
 <script type="text/javascript" src="/lib/jquery-ui/jquery-ui-datepickerCN.js"></script>

+ 89 - 1
web/building_saas/pm/js/pm_newMain.js

@@ -406,6 +406,47 @@ const projTreeObj = {
                 //获取当前节点的建设项目ID
                 projTreeObj.refreshProjectData();
             }
+        },
+        exportProject: {
+            name: "导出建设项目",
+            icon: 'fa-external-link',
+            disabled: function () {
+                let selectedItem = projTreeObj.tree.selected;
+                return !(selectedItem && selectedItem.data.projType === projectType.project);
+            },
+            /* visible:function () {
+             return false
+             },*/
+            callback: function (key, opt) {
+                //获取当前节点的建设项目ID
+                projTreeObj.exportProject(projTreeObj.tree.selected.data.ID,projTreeObj.tree.selected.data.name);
+            }
+        },
+        importProject:{
+            name: "导入建设项目",
+            icon: 'fa-external-link',
+            disabled: function () {
+                let selectedItem = projTreeObj.tree.selected;
+                if(selectedItem){
+                    if(selectedItem.data.projType === projectType.project) return false;//如果是建设项目,可用
+                    if(selectedItem.data.projType === projectType.folder){//如果是文件夹
+                        if(selectedItem.children){
+                            if(selectedItem.children.length == 0) return false;//如果文件夹没有子项,可用
+                            if(selectedItem.children[0] .projType === projectType.project ) return false;//如果文件夹有子项,并且是建设项目,可用
+                        }
+                    }
+                }
+                return true;
+            },
+            /*  visible:function () {
+             return false
+             },*/
+            callback: function (key, opt) {
+                //获取当前节点的建设项目ID
+                $("#import").modal('show');
+
+                // projTreeObj.exportProject(projTreeObj.tree.selected.data.ID);
+            }
         }
     },
     //全部-开始(新建)按钮弹出菜单(新建单位工程)
@@ -437,7 +478,9 @@ const projTreeObj = {
                 "importInterface": me.contextMenuItems.importInterface,
                 "spr3": '--------',
                 "manageFiles": me.contextMenuItems.manageFiles,
-                "refreshSummary": me.contextMenuItems.refreshSummary
+                "refreshSummary": me.contextMenuItems.refreshSummary,
+                "exportProject":me.contextMenuItems.exportProject,
+                "importProject":me.contextMenuItems.importProject
             }
         });
     },
@@ -1554,6 +1597,51 @@ const projTreeObj = {
         //在一次的修改中,同一个建设下,单价文件、费率文件才有共用的情况,而refreshProjectData是传入单位工程ID,刷新整个建设项目,所以,只要传入修改的单位工程ID,刷新建设项目即可
         this.refreshProjectData(projectID);
     },
+    exportProject:async function(projectID,projectName){
+        $.bootstrapLoading.progressStart();
+        let spString = "|----|";
+        try {
+            let sumString = "";
+            $("#progress_modal_bar").css('width','5%');
+            let result = await getProjectInfo({projectID:projectID,type:"main",user_id: userID});
+            $("#progress_modal_bar").css('width','10%');
+            let result_arr = result.split(spString);
+            sumString = result_arr[0];
+            if(result_arr.length == 2){
+                let tenders = JSON.parse(result_arr[1]);
+                let each = 100;
+                let width = 10;
+                if(tenders.length > 0) each = 90/tenders.length;
+                for(let t of tenders){
+                    let tenderString = await getProjectInfo({projectID:t,rootProjectID:projectID,type:"sub",user_id: userID});
+                    width += each;
+                    $("#progress_modal_bar").css('width',width+'%');
+                    await  setTimeoutSync(null,500);//设置间隔
+                    sumString = sumString + spString +tenderString;
+                }
+
+            }
+            $.bootstrapLoading.progressEnd();
+            //  console.log(JSON.parse(sumString));
+
+            saveProjectFile(sumString);
+
+        }catch (e){
+            alert("导出失败!请查看log.");
+            console.log(e)
+        }
+
+
+        async function getProjectInfo(data) {
+            let result = await ajaxPost("/pm/api/exportProject",data);
+            return result;
+        }
+
+        function saveProjectFile(data) {
+            let blob = new Blob([data], {type: 'text/plain;charset=utf-8'});
+            saveAs(blob, projectName+'.ybp');
+        }
+    },
     //创建建设项目的时候,根据选中位置获取所要创建建设项目的父ID、上兄弟节点ID、后兄弟节点ID
     getRelProjectID: function (selected) {
         let parent, pre, next;

+ 3 - 2
web/over_write/js/chongqing_2018.js

@@ -330,7 +330,7 @@ if(typeof module !== 'undefined'){
 }
 
 function getCusCoeContent() {
-    return '人工×1,材料×1,施工机具×1,主材×1'
+    return '人工×1,材料×1,施工机具×1,主材×1,设备×1';//2019-07-08 bug 添加自定义系数添加设备
 }
 
 function getCustomerCoeData() {
@@ -339,6 +339,7 @@ function getCustomerCoeData() {
         { amount:1, operator:'*', gljCode:null, coeType:'人工'},
         { amount:1, operator:'*', gljCode:null, coeType:'材料'},
         { amount:1, operator:'*', gljCode:null, coeType:'施工机具'},
-        { amount:1, operator:'*', gljCode:null, coeType:'主材'}
+        { amount:1, operator:'*', gljCode:null, coeType:'主材'},
+        { amount:1, operator:'*', gljCode:null, coeType:'设备'}
     ]
 }