Explorar el Código

Merge branch 'master' of http://192.168.1.41:3000/SmartCost/YangHuCost

TonyKang hace 6 años
padre
commit
1ee93ee949

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 3 - 0
lib/fileSaver/FileSaver.min.js


+ 2 - 2
modules/main/facade/project_facade.js

@@ -376,11 +376,11 @@ function getReportData(nameList,items,prjTypeNames,compilationScopes,decimal) {
                 tem['技术经济指标'].push(scMathUtil.roundForObj(p/bills.quantityMap[n],2));
             }else {
                 tem.billsAmounts.push(0);
-                tem['技术经济指标'].push(0);
+                tem['技术经济指标'].push(scMathUtil.roundForObj(p,2));
             }
         }
         tem.billsTtlPrice = scMathUtil.roundForObj(total,decimal.bills.totalPrice);
-        tem['技术经济综合指标'] = (tem.billsTtlAmt && parseFloat(tem.billsTtlAmt) !== 0)?scMathUtil.roundForObj(tem.billsTtlPrice/tem.billsTtlAmt,2):0;
+        tem['技术经济综合指标'] = (tem.billsTtlAmt && parseFloat(tem.billsTtlAmt) !== 0)?scMathUtil.roundForObj(tem.billsTtlPrice/tem.billsTtlAmt,2):scMathUtil.roundForObj(tem.billsTtlPrice,2);
         if(bills.flag == fixedFlag.TOTAL_COST) totalItem = tem;
         return tem
     }

+ 49 - 1
modules/pm/controllers/pm_controller.js

@@ -28,7 +28,7 @@ const _ = require('lodash');
 import SectionTreeDao from '../../complementary_ration_lib/models/sectionTreeModel';
 let sectionTreeDao = new SectionTreeDao();
 let consts = require('../../main/models/project_consts');
-
+import multiparty from 'multiparty';
 //统一回调函数
 let callback = function(req, res, err, message, data){
     res.json({error: err, message: message, data: data});
@@ -666,5 +666,53 @@ module.exports = {
             console.log(err);
             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: './public'});
+        let uploadFullName;
+        form.parse(req, async function (err, fields, files) {
+            try {
+                const file = typeof files.file !== 'undefined' ? files.file[0] : null;
+                if (err || !file) {
+                    throw '上传失败。';
+                }
+                console.log(file);
+                let data = fs.readFileSync(file.path,'utf-8');
+                console.log(data);
+            }catch (e){
+
+            }
+            res.json({error:0})
+        })
+        /*let result={
+            error:0
+        };
+        try {
+            console.log(req.files[0]);
+           /!* 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);*/
+
+
     }
 };

+ 86 - 2
modules/pm/facade/pm_facade.js

@@ -27,6 +27,7 @@ module.exports={
     prepareInitialData: prepareInitialData,
     changeFile:changeFile,
     copyForSectionError: copyForSectionError,
+    exportProject:exportProject
 };
 
 
@@ -49,6 +50,8 @@ let feeRateModel = mongoose.model('fee_rates');
 let feeRateFileModel = mongoose.model('fee_rate_file');
 let unitPriceFileModel = mongoose.model("unit_price_file");
 let mixRatioModel = mongoose.model("mix_ratio");
+let freightModel = mongoose.model("freight_calc");
+let originalModel = mongoose.model("original_calc");
 let unitPriceModel = mongoose.model("unit_price");
 let installationFeeModel = mongoose.model("installation_fee");
 let rationGLJModel = mongoose.model('ration_glj');
@@ -70,6 +73,7 @@ import CounterModel from "../../glj/models/counter_model";
 import moment from 'moment';
 import billsFlags from '../../common/const/bills_fixed';
 const notDeleted = [{deleteInfo: null}, {'deleteInfo.deleted': false}];
+let cipher = require('../../../public/cipher');
 
 
 
@@ -362,6 +366,8 @@ async function copyUnitPriceFile(newProjectID,rootProjectID,userID,originaluUnit
     let taskList = [
         copyFile(newProjectID,rootProjectID,userID,originaluUnitPriceFileID,unitPriceFileID,newName),
         copySubList(originaluUnitPriceFileID,unitPriceFileID,mixRatioModel),
+        copySubList(originaluUnitPriceFileID,unitPriceFileID,freightModel,true),
+        copySubList(originaluUnitPriceFileID,unitPriceFileID,originalModel,true),
         copySubList(originaluUnitPriceFileID,unitPriceFileID,unitPriceModel)
     ];
 
@@ -379,12 +385,12 @@ async function copyUnitPriceFile(newProjectID,rootProjectID,userID,originaluUnit
         await unitPriceFileModel.create(unitPriceFile._doc);
     }
 
-    async function copySubList(srcFID,newFID,model) {
+    async function copySubList(srcFID,newFID,model,UUID=false) {
         let mList = await model.find({unit_price_file_id: srcFID}, '-_id');
         let rList = [];
         for(let m of mList){
             m._doc.unit_price_file_id = newFID;
-            m._doc.id = await getCounterID(model.modelName);
+            UUID == true?m._doc.ID = uuidV1():m._doc.id = await getCounterID(model.modelName);
             rList.push(m._doc);
         }
         await insertMany(rList,model)
@@ -970,4 +976,82 @@ async function changeFile(datas,userID,fileID,name,from,type){//from 费率或
     }
     await project_facade.markProjectsToChange(projectIDs,projectUpdateType)//项目标记为待刷新状态
 
+}
+
+async function exportProject(userID,data){//导出建设项目
+    console.log(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});
+         tem.freights = await freightModel.find({unit_price_file_id:f.id});
+         tem.originals = await originalModel.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));
 }

+ 3 - 1
modules/pm/routes/pm_route.js

@@ -14,7 +14,7 @@ module.exports = function (app) {
     let pmRouter = express.Router();
 
     pmRouter.use(function (req, res, next) {
-        if (/\/getNewProjectID/.test(req.originalUrl) || pmController.checkRight(req, res)) {
+        if (/\/getNewProjectID/.test(req.originalUrl)||/\/importProject/.test(req.originalUrl) || pmController.checkRight(req, res)) {
             next();
         } else {
             res.json({error: 1, message: '对不起,您无权限操作。', data: null});
@@ -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);
 
     app.use('/pm/api', pmRouter);
 };

+ 12 - 1
web/building_saas/js/global.js

@@ -145,4 +145,15 @@ function getFeeIndex(fees) {
 function replaceAll(FindText, RepText,str) {
     let regExp = new RegExp(FindText, "g");
     return str.replace(regExp, RepText);
-};
+};
+
+function setTimeoutSync(handle, time) {
+    return new Promise(function(resolve, reject) {
+        setTimeout(function () {
+            if (handle && typeof handle === 'function') {
+                handle();
+            }
+            resolve();
+        }, time);
+    });
+}

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

@@ -645,8 +645,58 @@
         </div>
     </div>
 </div>
+
+<!--弹出 导出-->
+<div class="modal fade" id="export" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">导出文件</h5>
+              <!--  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>-->
+            </div>
+            <div class="modal-body">
+                <!--正在生成-->
+                <h5 class="my-3">正在生成文件</h5>
+                <div class="progress mb-3">
+                    <div id="export_progress_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>
+
+<!--弹出 导出-->
+<div class="modal fade" id="import" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">导入建设项目</h5><button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                <span aria-hidden="true">&times;</span>
+            </button>
+            </div>
+            <div class="modal-body">
+                <form>
+                    <div class="form-group">
+                        <label>请选择ybp格式文件</label>
+                        <input class="form-control-file" type="file" accept=".ybp" name="import_project_data"/>
+                    </div>
+                </form>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-primary" id="confirm-import">确定导入</button>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+            </div>
+        </div>
+    </div>
+</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>
 <!-- inject:js -->
 <script src="/web/building_saas/js/global.js"></script>

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

@@ -338,6 +338,38 @@ 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);
+            }
+        },
+        improtProject:{
+            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
+                $("#import").modal('show');
+
+               // projTreeObj.exportProject(projTreeObj.tree.selected.data.ID);
+            }
         }
     },
     //全部-开始(新建)按钮弹出菜单(新建单位工程)
@@ -367,7 +399,9 @@ const projTreeObj = {
                 "share": me.contextMenuItems.share,
                 "spr3": '--------',
                 "manageFiles": me.contextMenuItems.manageFiles,
-                "refreshSummary": me.contextMenuItems.refreshSummary
+                "refreshSummary": me.contextMenuItems.refreshSummary,
+                "exportProject":me.contextMenuItems.exportProject,
+                "importProject":me.contextMenuItems.improtProject
             }
         });
     },
@@ -1438,6 +1472,62 @@ const projTreeObj = {
     refreshWhenFileDateChange:function(projectID){//当单价文件、费率文件被修改后,刷新页面,共用的项目提示刷新图标
         //在一次的修改中,同一个建设下,单价文件、费率文件才有共用的情况,而refreshProjectData是传入单位工程ID,刷新整个建设项目,所以,只要传入修改的单位工程ID,刷新建设项目即可
         this.refreshProjectData(projectID);
+    },
+     exportProject:async function(projectID,projectName){
+        $("#export_progress_bar").css('width','0%');
+        $("#export").modal('show');
+        let spString = "|----|";
+        try {
+            let sumString = "";
+            let result = await getProjectInfo({projectID:projectID,type:"main",user_id: userID});
+            $("#export_progress_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;
+                    $("#export_progress_bar").css('width',width+'%');
+                    await  setTimeoutSync(null,500);//设置间隔
+                    sumString = sumString + spString +tenderString;
+                    console.log(JSON.parse(tenderString));
+                }
+
+            }
+            $("#export_progress_bar").css('width','100%');
+            $("#export").modal('hide');
+          //  console.log(JSON.parse(sumString));
+
+            saveProjectFile(sumString);
+
+        }catch (e){
+            console.log(e)
+        }
+
+
+        async function getProjectInfo(data) {
+            let result = await ajaxPost("/pm/api/exportProject",data);
+            return result;
+           // let blob = new Blob([result], {type: 'text/plain;charset=utf-8'});
+           // saveAs(blob, 'textName.ybp');
+        }
+
+        function saveProjectFile(data) {
+            let blob = new Blob([data], {type: 'text/plain;charset=utf-8'});
+            saveAs(blob, projectName+'.ybp');
+        }
+
+       /* setTimeout(function(){
+            $("#progressbar").css('width','50%');
+            setTimeout(function(){
+                $("#export").modal('hide');
+            },1000)
+            //$("#export").modal('hide');
+        },1000)*/
     }
 };
 
@@ -3494,6 +3584,42 @@ $('#shareToConfirm').click(function () {
     updateShareInfo(selected);
 });
 
+
+$("#confirm-import").click(function() {
+    //$.bootstrapLoading.start();
+    const self = $(this);
+    try {
+        let formData = new FormData();
+        let file = $("input[name='import_project_data']")[0];
+        if (file.files.length <= 0) {
+            throw '请选择文件!';
+        }
+        formData.append('file', file.files[0]);
+        formData.append('userID', userID);
+        $.ajax({
+            url: '/pm/api/importProject',
+            type: 'POST',
+            data: formData,
+            cache: false,
+            contentType: false,
+            processData: false,
+            beforeSend: function() {
+                self.attr('disabled', 'disabled');
+                self.text('上传中...');
+            },
+            success: function(response){
+
+            },
+            error: function(){
+
+            }
+        });
+    } catch(error) {
+        alert(error);
+        $.bootstrapLoading.end();
+    }
+});
+
 //设置分享给界面数据
 //@param {Object}selected @return {void}
 function setShareToModal(selected){