zhangweicheng před 5 roky
rodič
revize
69b9e19cbb

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 2 - 0
lib/qiniu/qiniu.min.js


+ 20 - 0
modules/all_models/import_logs.js

@@ -0,0 +1,20 @@
+/**
+ * Created by zhang on 2019/12/27.
+ */
+import mongoose from "mongoose";
+
+let Schema = mongoose.Schema;
+let collectionName = 'import_logs';
+
+let modelSchema = {
+    // 日志类型
+    key: {type: String, index: true},
+    // 日志内容
+    userID: String,
+    // 关联用户id
+    status:String,
+    // 创建时间
+    create_time: Number,
+    errorMsg:""
+};
+mongoose.model(collectionName, new Schema(modelSchema, {versionKey: false, collection: collectionName}));

+ 2 - 4
modules/import/controllers/import_controller.js

@@ -8,10 +8,8 @@ let logger = require("../../../logs/log_helper").logger;
 let pm_facade = require('../../pm/facade/pm_facade');
 let controller = {
     importProject:async function (req){
-        let data = req.body.data;
-        let sessionInfo = {session:req.body.session};
-        let fields = req.body.fields;
-        return await pm_facade.importProjects(data,sessionInfo,fields);
+        let data = req.body;
+        return await pm_facade.downLoadProjectFile(data);
     },
     exportProject:async function(req){
         let result={

+ 40 - 22
modules/pm/controllers/pm_controller.js

@@ -732,28 +732,46 @@ module.exports = {
 
     },
     importProject:async function(req,res){
-        let form = new multiparty.Form({uploadDir: './tmp'});
-        let path = "";
-        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 '上传失败。';
-                };
-                path = file.path;
-                let data = fs.readFileSync(file.path,'utf-8');
-                let body = {data: data, fields:fields, session:req.session};
-                let result = await redirectToImportServer(body,"importProject",req);
-                res.json(result);
-            }catch (e){
-                console.log(e);
-                res.json({error:1,msg:"导入失败请检查文件!"})
-            }finally {
-                fs.unlinkSync(path);
-            }
-
-        })
+        let data = JSON.parse(req.body.data);
+        let result={
+            error:0
+        };
+        try {
+            data.session = req.session;
+            result = await redirectToImportServer(data,"importProject",req);
+        }catch (err){
+            console.log(err);
+            result.error=1;
+            result.message = err.message;
+        }
+        res.json(result);
+    },
+    importProcessChecking:async function (req,res) {
+        let result={
+            error:0
+        };
+        try{
+            let data = JSON.parse(req.body.data);
+            result.data = await pm_facade.importProcessChecking(data);
+        } catch (err){
+            console.log(err);
+            result.error=1;
+            result.message = err.message;
+        }
+        res.json(result);
+    },
+    getUploadToken:function (req,res) {
+        let result={
+            error:0
+        };
+        try {
+            result =pm_facade.uploadToken();
+        }catch (err){
+            console.log(err);
+            result.error=1;
+            result.message = err.message;
+        }
+        res.json(result);
     },
     getBasicInfo: async function(req, res) {
         try {

+ 98 - 4
modules/pm/facade/pm_facade.js

@@ -32,7 +32,10 @@ module.exports={
     getProjectPlaceholder: getProjectPlaceholder,
     exportProject:exportProject,
     importProjects:importProjects,//建筑这里重名了,这比养护加多了个s
-    initOverHeightItems: initOverHeightItems
+    initOverHeightItems: initOverHeightItems,
+    uploadToken:uploadToken,
+    downLoadProjectFile:downLoadProjectFile,
+    importProcessChecking:importProcessChecking
 };
 
 
@@ -77,6 +80,7 @@ let evaluateListModel = mongoose.model("evaluate_list");
 let bidListModel = mongoose.model("bid_evaluation_list");
 let contractorListModel = mongoose.model("contractor_list");
 let featureLibModel =  mongoose.model("std_project_feature_lib");
+let importLogsModel = mongoose.model("import_logs");
 const overHeightLibModel = mongoose.model('std_over_height_lib');
 let scMathUtil = require('../../../public/scMathUtil').getUtil();
 let counter = require('../../../public/counter/counter');
@@ -100,7 +104,18 @@ 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');
-
+let qiniu = require("qiniu");
+let fs = require("fs");
+let path = require("path");
+let request = require("request");
+
+let qiniu_config = {
+    "AccessKey": "_gR1ed4vi1vT2G2YITGSf4_H0fJu_nRS9Tzk3T4z",
+    "SecretKey": "ty4zd0FHqgEDaiVzSLC8DfHlai99aS7bspLkw6s6",
+    "Bucket": "yun-update",
+    "Domain": "https://serverupdate.smartcost.com.cn"
+};
+let mac = new qiniu.auth.digest.Mac(qiniu_config.AccessKey, qiniu_config.SecretKey);
 
 //拷贝例题项目
 //@param {String}userID {Array}projIDs拷贝的例题项目ID(建设项目、文件夹)@return {Boolean}
@@ -1736,7 +1751,70 @@ async function exportTenderData(data){
     return cipher.aesEncrypt(JSON.stringify(result));
 }
 
-async function importProjects(data,req,fields) {
+async function downLoadProjectFile(info) {
+    let result = {error:0};
+    let bucketManager2 = new qiniu.rs.BucketManager(mac, null);
+    let publicBucketDomain = qiniu_config.Domain;// "http://serverupdate.smartcost.com.cn";//这里不支持https
+    let deadline = parseInt(Date.now() / 1000) + 3600; // 1小时过期
+    let privateDownloadUrl = bucketManager2.privateDownloadUrl(publicBucketDomain, info.key, deadline);
+
+    let data = {
+        key:info.key,
+        userID:info.session.sessionUser.id,
+        status:"start",
+        create_time:+new Date()
+    };
+    await importLogsModel.create(data);
+    doDownLoadAndImport(privateDownloadUrl,info);
+    return result;
+}
+
+async function doDownLoadAndImport(privateDownloadUrl,info) {
+    let stream = fs.createWriteStream(path.join(__dirname, "../../../tmp/"+info.key));//
+    request(privateDownloadUrl).pipe(stream).on("close", async function (err) {
+        console.log("文件[" + info.key + "]下载完毕");
+        let doc = {status:"finish"};
+        try {
+            let data = fs.readFileSync(stream.path,'utf-8');
+            let result = await importProjects(data,{session:info.session},info.updateData);
+            if(result.error == 1){
+                doc.errorMsg = result.msg;
+                doc.status = "error";
+            }
+        }catch (error){
+            console.log(error);
+            doc.errorMsg = "导入失败,请检查文件!";
+            doc.status = "error";
+        }finally {
+            await importLogsModel.update({key:info.key},doc);
+            fs.unlinkSync(stream.path);
+        }
+    });
+}
+
+async function importProcessChecking(data){
+    let result = {error:0};
+    let log = await importLogsModel.findOne({key:data.key});
+    if(log){
+        if(log.status == "finish"){
+            result.status = "complete";
+            await importLogsModel.remove({key:data.key});
+        }else if(log.status == "start"){
+            result.status = "processing";
+        }else if(log.status == "error"){
+            result.error = 1;
+            result.msg = log.errorMsg;
+            await importLogsModel.remove({key:data.key});
+        }
+    }else {
+        result.error = 1;
+        result.msg = `导入过程中发生错误!`;
+    }
+    return result;
+
+}
+
+async function importProjects(data,req,updateData) {
     let result = {error:0};
     let stringArr = data.split("|----|");
     let datas = [];
@@ -1755,7 +1833,7 @@ async function importProjects(data,req,fields) {
             result.error = 1;
             result.msg = `导入失败:您要导入的文件是由“${fileCompilationName}”导出,当前软件是“${curCompilationName}”,请选择正确的费用定额再进行操作!`;
         }else {
-            let [projectIDMap,labourCoeFileIDMap,calcProgramFileIDMap] = await handleMainProjectDatas(mainData,JSON.parse(fields.updateData[0]),req.session.sessionUser.id);
+            let [projectIDMap,labourCoeFileIDMap,calcProgramFileIDMap] = await handleMainProjectDatas(mainData,updateData,req.session.sessionUser.id);
             if(datas.length > 1 ){
                 for(let i = 1;i<datas.length;i++){
                     await handleEachProject(datas[i],projectIDMap,labourCoeFileIDMap,calcProgramFileIDMap)
@@ -2010,3 +2088,19 @@ async function initOverHeightItems(engineeringID) {
     const overHeightLib = await overHeightLibModel.findOne({ID: overHeightLibID});
     return overHeightLib ? overHeightLib.list : defaultData;
 }
+
+function uploadToken() {
+    let options = {
+        scope: qiniu_config.Bucket,
+        deleteAfterDays: 1,
+        returnBody:
+            '{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)","name":"$(x:name)"}'
+    };
+    let putPolicy = new qiniu.rs.PutPolicy(options);
+    let token = putPolicy.uploadToken(mac);
+    let result = {
+        uptoken: token,
+        domain: qiniu_config.Domain
+    }
+    return result
+}

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

@@ -12,7 +12,7 @@ module.exports = function (app) {
     app.get('/pm', baseController.init, pmController.index);
 
     let pmRouter = express.Router();
-
+    pmRouter.get('/getUploadToken', pmController.getUploadToken);
     pmRouter.use(function (req, res, next) {
         if (/\/getNewProjectID/.test(req.originalUrl) ||/\/importProject/.test(req.originalUrl)|| pmController.checkRight(req, res)) {
             next();
@@ -63,6 +63,7 @@ module.exports = function (app) {
     pmRouter.post('/changeFile', pmController.changeFile);
     pmRouter.post('/exportProject', pmController.exportProject);
     pmRouter.post('/importProject', pmController.importProject);
+    pmRouter.post('/importProcessChecking', pmController.importProcessChecking);
     pmRouter.post('/getBasicInfo', pmController.getBasicInfo);
     pmRouter.post('/getProjectFeature', pmController.getProjectFeature);
     pmRouter.post('/getProjectByGranularity', pmController.getProjectByGranularity);

+ 2 - 1
package.json

@@ -56,7 +56,8 @@
     "socket.io": "2.0.3",
     "ua-parser-js": "^0.7.14",
     "uuid": "^3.1.0",
-    "wiredep": "^2.2.2"
+    "wiredep": "^2.2.2",
+    "qiniu": "^7.1.1"
   },
   "scripts": {
     "start": "C:\\Users\\mai\\AppData\\Roaming\\npm\\babel-node.cmd server.js",

+ 13 - 0
public/web/common_ajax.js

@@ -190,6 +190,19 @@ async function ajaxPost(url, data, isPlainData = false) {
 }
 
 
+async function ajaxGet(url,data){
+    return new Promise(function (resolve, reject) {
+        $.get(url,data,function (result,status) {
+            if(status == 'success'){
+                resolve(result);
+            }else {
+                reject(result);
+            }
+        },"json")
+    })
+
+}
+
 /**
  * 在页面中任何嵌套层次的窗口中获取顶层窗口
  * @return 当前页面的顶层窗口对象

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

@@ -934,6 +934,7 @@
 <!-- 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 src="/lib/qiniu/qiniu.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>

+ 74 - 49
web/building_saas/pm/js/pm_newMain.js

@@ -471,10 +471,10 @@ const projTreeObj = {
              return false
              },*/
             callback: function (key, opt) {
-                //获取当前节点的建设项目ID
-                $("#import").modal('show');
 
-                // projTreeObj.exportProject(projTreeObj.tree.selected.data.ID);
+                $("#confirm-import").hide();
+                $("#import").modal('show');
+                projTreeObj.getUploadToken();
             }
         }
     },
@@ -1671,8 +1671,14 @@ const projTreeObj = {
         return {parentProjectID: parent && parent.data ? parent.data.ID : -1,
                 preProjectID: pre && pre.data ? pre.data.ID : -1,
                 nextProjectID: next && next.data ? next.data.ID : -1};
+    },
+    getUploadToken:async function () {
+        let result =await ajaxGet("/pm/api/getUploadToken");
+        $("#confirm-import").show();
+        projTreeObj.uptoken=result.uptoken;
     }
 
+
 };
 // 新建项目必填项提示框设置“ 比如:注:为响应重庆地区指标采集标准数据要求,以上工程信息及特征必填项为必填项,请正确填写。”
 function setupRequiredWarn(compilation) {
@@ -4673,56 +4679,75 @@ $("#confirm-import").click(function() {
         return;
     }
     STATE.importing = true;
-    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);
-        formData.append("updateData",JSON.stringify(projTreeObj.getImportProjectDate()));
-        $('#import').modal("hide");
-        $.bootstrapLoading.progressStart("导入建设项目",true);
-        $.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){
-                STATE.importing = false;
-                self.text('确定导入');
-                $.bootstrapLoading.progressEnd();
-                if(response.error == 1){
-                    alert(response.msg);
-                    setTimeout(function () {
-                        $.bootstrapLoading.progressEnd();//不做这个的话太快,页面不会自动关闭
-                    },500)
-                }else {
-                    refreshAllPage();
-                }
 
+    let input = $("input[name='import_project_data']")[0];
+    if (input.files.length <= 0) {
+        throw '请选择文件!';
+    }
+    let token = projTreeObj.uptoken;
+    $('#import').modal("hide");
+    $.bootstrapLoading.progressStart("上传文件中",true);
+    let file = input.files[0];
+    let key = uuid.v1() + ".ybp"; //file.name;
+    if (file) {
+        let config = {
+            useCdnDomain: true,
+            disableStatisticsReport: false,
+            retryCount: 6,
+            region: qiniu.region.z2
+        };
+        let putExtra = {
+            fname: "",
+            params: {"x:name":key.split(".")[0]},
+            mimeType: null
+        };
+        // 添加上传dom面板
+        let observable = qiniu.upload(file, key, token, putExtra, config);
+        observable.subscribe({
+            next:function (reponse) {
+                console.log(reponse);
             },
-            error:  function(response){
-                STATE.importing = false;
-                setTimeout(function () {
-                    self.text('确定导入');
-                    $.bootstrapLoading.progressEnd();
-                    alert("导入失败,请检查文件!");
-                },1000)
+            error:function (err) {
+                console.log(err);
+            },
+            complete:function(res){
+                console.log("complete")
+                $("#progress_modal_body").text("正在导入建设项目");
+                startImportProject(key);
+                projTreeObj.uptoken = null;
             }
         });
-    } catch(error) {
-        STATE.importing = false;
-        alert(error);
-        $.bootstrapLoading.end();
+    }
+
+    async function  startImportProject(key) {
+        try {
+            console.log("start Import");
+            let result = await ajaxPost("/pm/api/importProject",{key:key,updateData:projTreeObj.getImportProjectDate()});
+            setTimeout(importProcessChecking,2000);
+        }catch (error){
+            alert(error);
+            $.bootstrapLoading.end();
+        }finally {
+            STATE.importing = false;
+        }
+    }
+
+    async function importProcessChecking() {
+        let result = await ajaxPost("/pm/api/importProcessChecking",{key:key,user_id:userID});
+        if(result.error == 1){
+            let message = result.msg?result.msg:result.message;
+            setTimeout(function () {
+                $.bootstrapLoading.progressEnd();//不做这个的话太快,页面不会自动关闭
+            },500);
+            alert(message)
+        }else if(result.error == 0){
+            if(result.status == "processing"){
+                setTimeout(importProcessChecking,2000);
+            }else if(result.status == "complete"){
+                $.bootstrapLoading.progressEnd();
+                refreshAllPage();
+            }
+        }
     }
 });