瀏覽代碼

别人分享过来,只能查看的项目,可在打开的页面进行拷贝。 将信息价按钮移动至最左

zhangweicheng 4 年之前
父節點
當前提交
930132a938

+ 1 - 0
config/gulpConfig.js

@@ -189,6 +189,7 @@ module.exports = {
         'web/building_saas/main/js/views/calc_base_view.js',
         'web/building_saas/main/js/views/project_property_labour_coe_view.js',
         'web/building_saas/main/js/views/locate_view.js',
+        'web/building_saas/main/js/views/copyProject.js',
         'web/building_saas/complementary_ration_lib/js/main.js',
         'public/web/storageUtil.js'
     ],

+ 4 - 0
logs/online_logs.js

@@ -8,6 +8,7 @@ module.exports = {
 let mongoose = require("mongoose");
 const moment = require('moment');
 let logs_model = mongoose.model("online_logs");
+let user_model = mongoose.model("user");
 
 async function saveOnlineTime(req) {
     let online_times = 0;
@@ -26,14 +27,17 @@ async function saveOnlineTime(req) {
         if(!req.session.sessionUser||!req.session.sessionCompilation) return;
         let dataString = moment(end).format('YYYY-MM-DD');
         let condition = {userID:req.session.sessionUser.id,compilationID:req.session.sessionCompilation._id,dateString:dataString};
+        let userCondition = {_id: mongoose.Types.ObjectId(req.session.sessionUser.id)};
         let record = await logs_model.findOne(condition);
         if(record){ //如果找到,则累加
             await logs_model.update(condition,{$inc:{'online_times' : online_times }});
+            await user_model.update(userCondition,{$inc:{'online_times' : online_times }});
         }else {//如果没找到,则新增一条记录
             condition["online_times"] = online_times;
             let today = moment(dataString).toDate();
             condition["dateTime"] = +today;
             await logs_model.create(condition);
+            await user_model.update(userCondition,{'online_times' : online_times});
         }
     }catch (e){
         console.log("统计登录时间错误,online_times值:"+online_times);

+ 5 - 2
modules/all_models/user.js

@@ -120,7 +120,10 @@ let schema = {
         default: 0
     },
     welcomeShowTime:String,
-    token: String
-
+    token: String,
+    online_times: {
+        type: Number,
+        default: 0
+    } //最近一天的登录时长累计
 };
 mongoose.model(collectionName, new Schema(schema, {versionKey: false}));

+ 2 - 1
modules/main/routes/main_route.js

@@ -19,7 +19,7 @@ module.exports =function (app) {
     app.get('/main', baseController.init, function(req, res) {
         let pm = require('../../pm/controllers/pm_controller');
         const projectID = +req.query.project;
-        pm.checkProjectRight(req.session.sessionUser.id, projectID, async function (hasRight, projectData, isOpenShareProject, allowCooperate) {
+        pm.checkProjectRight(req.session.sessionUser.id, projectID, async function (hasRight, projectData, isOpenShareProject, allowCooperate,allowCopy) {
             if (hasRight) {
                 //分享的项目,只读、协作(允许编辑)
                 let projectReadOnly = false,
@@ -52,6 +52,7 @@ module.exports =function (app) {
                         versionName: req.session.compilationVersion,
                         projectReadOnly: projectReadOnly,
                         projectCooperate: projectCooperate,
+                        allowCopy: allowCopy||false,
                         LicenseKey:config.getLicenseKey(process.env.NODE_ENV),
                         overWriteUrl:req.session.sessionCompilation.overWriteUrl,
                         fileKind: fileKind,

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

@@ -69,7 +69,8 @@ module.exports = {
             }
             if ((userId === result.userID || shareInfo) && result._doc.projType === projType.tender) {
                 const allowCooperate = (shareInfo || {}).allowCooperate;
-                callback(true, result, isOpenShareProject, allowCooperate);
+                const allowCopy = (shareInfo || {}).allowCopy;
+                callback(true, result, isOpenShareProject, allowCooperate,allowCopy);
             } else {
                 callback(false);
             }

+ 1 - 0
public/common_constants.js

@@ -105,6 +105,7 @@
     };
     //项目类型
     const projectType = {
+        Folder: 'Folder',
         Project: 'Project',
         Engineering: 'Engineering',
         Tender: 'Tender'

+ 7 - 8
web/building_saas/glj/html/project_glj.html

@@ -87,19 +87,18 @@
       <div class="resize-y" id="projectGljResize"></div>
       <div class="bottom-content" id="projectGljBottom">
         <ul class="nav nav-tabs" role="tablist">
+          <li class="nav-item" id="info-nav-li">
+            <a class="nav-link active show" id="info-nav" data-toggle="tab" data-name="info" href="#info_price_div"
+              role="tab">信息价</a>
+          </li>
           <li class="nav-item">
-            <a class="nav-link active show" id="mixRatio-nav" data-toggle="tab" href="#ph_div" role="tab"
+            <a class="nav-link" id="mixRatio-nav" data-toggle="tab" href="#ph_div" role="tab"
               aria-selected="false">组成物计算</a>
           </li>
           <li class="nav-item">
             <a class="nav-link " id="ration-nav" data-toggle="tab" href="#ph_div" role="tab"
               aria-selected="true">相关定额</a>
           </li>
-          <li class="nav-item" id="info-nav-li">
-            <a class="nav-link" id="info-nav" data-toggle="tab" data-name="info" href="#info_price_div"
-              role="tab">信息价</a>
-          </li>
-
           <!-- <li class="nav-item">
                         <a class="nav-link" data-toggle="tab" data-name="machine_sheet" id="machine_ratio_link" href="#ph_div" role="tab">机械单价</a>
                     </li>-->
@@ -111,11 +110,11 @@
                             相关定额
                         </div>
                     </div>-->
-          <div class="tab-pane active" id="ph_div" role="tabpanel">
+          <div class="tab-pane" id="ph_div" role="tabpanel">
             <div class="main-data-bottom" id="mix_ratio_sheet" style="overflow:hidden">
             </div>
           </div>
-          <div class="tab-pane" id="info_price_div" role="tabpanel">
+          <div class="tab-pane active" id="info_price_div" role="tabpanel">
             <div class="form-inline py-1 toolsbar_feeRate" id="infoToolDiv" style="background:#f7f7f9">
               <label class="mx-2" for="info_area">地区</label>
               <select class="form-control form-control-sm" style="font-size: .875rem; width:120px;" id="info_area">

+ 39 - 0
web/building_saas/main/html/main.html

@@ -41,6 +41,7 @@
     let userID = '<%- userID %>';
     let projectReadOnly = JSON.parse('<%- projectReadOnly %>');
     let projectCooperate = JSON.parse('<%- projectCooperate %>');
+    let allowCopy = JSON.parse('<%- allowCopy %>');
     let projectOptins = JSON.parse('<%- options %>');
     const overWriteUrl = '<%- overWriteUrl %>';
     console.log(projectCooperate);
@@ -2639,6 +2640,43 @@
       </div>
     </div>
   </div>
+
+  <!--弹出拷贝工程-->
+  <div class="modal fade" id="copyShare" 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">
+                <div class="form-group">
+                    <label>建设项目</label>
+                    <select id="copyShare_selectProj" class="form-control"><option>请选择建设项目</option></select>
+                    <span style="display: none" id="copyShareProj-info" class="form-text text-danger">建设项目不可为空</span>
+                </div>
+                <div class="form-group">
+                    <label>单项项目</label>
+                    <select id="copyShare_selectEng" class="form-control"><option>请选择单项工程</option></select>
+                    <span style="display: none" id="copyShareEng-info" class="form-text text-danger">单项工程不可为空</span>
+                </div>
+                <div class="form-group">
+                    <label>单位工程</label>
+                    <input id="copyShare_name" class="form-control"></input>
+                    <span style="display: none" id="copyShareTender-info" class="form-text text-danger">已存在同名单位工程</span>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <a id="copyShare_confirm" href="javascript:void(0);" class="btn btn-primary">确定拷贝</a>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+            </div>
+        </div>
+    </div>
+  </div>
+
+
   <%include ../../../common/components/share/index.html %>
 
   <img src="/web/dest/css/img/folder_open.png" id="folder_open_pic" style="display: none">
@@ -2808,6 +2846,7 @@
   <script type="text/javascript" src="/web/building_saas/main/js/views/calc_base_view.js"></script>
   <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_labour_coe_view.js"></script>
   <script type="text/javascript" src="/web/building_saas/main/js/views/locate_view.js"></script>
+  <script type="text/javascript" src="/web/building_saas/main/js/views/copyProject.js"></script>
   <script type="text/javascript" src="/web/building_saas/complementary_ration_lib/js/main.js"></script>
   <script type="text/javascript" src="/public/web/storageUtil.js"></script>
   <!-- endinject -->

+ 26 - 0
web/building_saas/main/js/controllers/block_controller.js

@@ -3,6 +3,32 @@
  */
 let BlockController = {
     datas:[],
+    disabelCopyRightClick:function(){
+        console.log("right clicked")
+        if (projectReadOnly) {
+            return true;
+        }
+        let selection = projectObj.mainSpread.getActiveSheet().getSelections()[0];
+        let firstNode = projectObj.project.mainTree.items[selection.row];//当多选的情况,用mainTree.selected判断不正确,要用第一个选中的节点
+        for(let i = 0;i< selection.rowCount;i++){ //多选的时候判断所有与第一个节点同级的节点
+            let temNode = projectObj.project.mainTree.items[selection.row + i];
+            if(firstNode.getParentID() == temNode.getParentID()){
+                if(BlockController.copyBtnDisable(temNode) == true){
+                    return true;
+                }
+            }
+        }
+        return false;
+    },
+    copyRightClickCallback:function(){
+        $.bootstrapLoading.start();
+        //let selected = project.mainTree.selected;
+        let selections = projectObj.mainSpread.getActiveSheet().getSelections();
+        setTimeout(function () {
+            BlockController.copyBlock(selections[0]);
+            $.bootstrapLoading.end();
+        },100)
+    },
     copyBtnDisable:function (selected) {
         if(this.isDXFYorMainEq(selected)){
             return true;

+ 207 - 0
web/building_saas/main/js/views/copyProject.js

@@ -0,0 +1,207 @@
+const copyProject = (function () {
+    const projectType = commonConstants.projectType;
+    let curCopySelTree = null;  //拷贝工程建设项目选项树
+    function setEng(projID){
+        let engQuery = {$or: [{deleteInfo: null}, {'deleteInfo.deleted': false}], projType: projectType.Engineering, userID: userID, ParentID: projID};
+        CommonAjax.post('/pm/api/getProjectsByQuery', {user_id: userID, query: engQuery, options: '-_id -property'}, function (rstData) {
+            $('#copyShare_selectEng').empty();
+            for(let eng of rstData){
+                let opt = $('<option>').val(eng.ID).text(eng.name);
+                $('#copyShare_selectEng').append(opt);
+            }
+        });
+    }
+
+    function getFileHierarchyInfo(treeData){
+        curCopySelTree = idTree.createNew({id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1});
+        curCopySelTree.loadDatas(treeData);
+        let items = curCopySelTree.items;
+        let rst = [];
+        function getFileHierarchyName(node){
+            let nodeName = node.data.name;
+            let name = [];
+            while (node.parent){
+                name.push(node.parent.data.name ? node.parent.data.name : '');
+                node = node.parent;
+            }
+            name = name.reverse();
+            name.push(nodeName);
+            return name.join('\\');
+        }
+        for(let node of items){
+            if(node.children.length === 0 ){//project
+                rst.push({ID: node.data.ID, fileHierarchyName: getFileHierarchyName(node)})
+            }
+        }
+        return rst;
+    }
+
+ //设置拷贝工程下拉选择
+    //@return {void}
+    function setCopyModal(){
+        //获取建设项目
+        let projQuery = {$or: [{deleteInfo: null}, {'deleteInfo.deleted': false}], projType: {$in: [projectType.Project, projectType.Folder]}, userID: userID};
+        CommonAjax.post('/pm/api/getProjectsByQuery', {user_id: userID, query: projQuery, options: '-_id'}, function (rstData) {
+            let fileHierarchyData = getFileHierarchyInfo(rstData);
+            $('#copyShare_selectProj').empty();
+            for(let proj of fileHierarchyData){
+                let opt = $('<option>').val(proj.ID).text(proj.fileHierarchyName);
+                $('#copyShare_selectProj').append(opt);
+            }
+            //初始选择
+            if(fileHierarchyData.length > 0){
+                setEng(fileHierarchyData[0].ID);
+            }
+        });
+    }
+
+//拷贝分享的工程
+    //@param {Object}selected {Number}parentID @return {void}
+    async function copyShareProject(projectInfo, projID, engID){
+        try {
+            if(!engID || !projectInfo){
+                return;
+            }
+            let copyMap = {copy: null, update: null};
+            let newName = $('#copyShare_name').val();
+            if (!newName) {
+                $('#copyShareTender-info').text('单位工程名称不可为空');
+                $('#copyShareTender-info').show();
+                return;
+            }
+            //获取单项工程的单位工程
+            let tenderQuery = {$or: [{deleteInfo: null}, {'deleteInfo.deleted': false}], userID: userID, ParentID: engID};
+            const rstData = await ajaxPost('/pm/api/getProjectsByQuery', {user_id: userID, query: tenderQuery, options: '-_id -property'}, false, 10000);
+            let updateTender = null;
+            for(let tender of rstData){
+                if(tender.name === newName){
+                    $('#copyShareTender-info').text('已存在同名单位工程');
+                    $('#copyShareTender-info').show();
+                    return;
+                }
+                if(tender.NextSiblingID == -1){
+                    updateTender = tender;
+                }
+            }
+            //更新前节点
+            if(updateTender){
+                copyMap.update = {query: {ID: updateTender.ID}};
+            }
+            //拷贝
+            let copyData = {
+                userID: userID,
+                ID: projectInfo.ID,
+                NextSiblingID: -1,
+                ParentID: engID,
+                name: newName,
+                shareInfo: [],
+                compilation: projectInfo.compilation,
+                createDateTime: projectInfo.createDateTime,
+                fileVer: projectInfo.fileVer ? projectInfo.fileVer : '',
+                projType: projectInfo.projType,
+                property: {},
+                recentDateTime: projectInfo.recentDateTime,
+                fullFolder: projectInfo.fullFolder
+            };
+            copyData.property.rootProjectID = projID;
+            copyMap.copy = {document: copyData};
+            $('#copyShare').modal('hide');
+            $.bootstrapLoading.progressStart('拷贝项目', true);
+            $("#progress_modal_body").text('正在拷贝项目,请稍候……');
+            await ajaxPost('/pm/api/copyProjects', {projectMap: copyMap, user_id: userID, tenderCount: 1});
+            const compilationID = projectInfo.compilation;
+            importProcessChecking(null, null, ()=> socket.emit('pmTreeChange', { userID, compilationID}));
+        } catch (err) {
+            alert(err);
+        }
+
+    }
+
+    async function importProcessChecking(key, processingFunc = null, completeFunc = null, immediately = false) {
+        let count = 0;
+        immediately ? checking() : setTimeout(checking, 2000);
+        async function checking() {
+            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);
+                if (completeFunc) {
+                    completeFunc(result.data);
+                }
+            } else if (result.error == 0) {
+                if (result.status == "processing") {
+                    // 只调用一次
+                    if (processingFunc && count === 0) {
+                        processingFunc(result);
+                    }
+                    count++;
+                    setTimeout(checking, 2000);
+                } else if (result.status == "complete") {
+                    if (completeFunc) {
+                        completeFunc(result.data);
+                    }
+                    $.bootstrapLoading.progressEnd();
+                    //refreshAllPage();
+                }
+            }
+        }
+    }
+
+    function eventListener(){
+           //关闭拷贝工程
+        $('#copyShare').on('hidden.bs.modal', function () {
+            $('#copyShareProj-info').hide();
+            $('#copyShareEng-info').hide();
+        });
+        //打开拷贝工程
+        $('#copyShare').on('shown.bs.modal', function () {
+            setCopyModal();
+            //更改显示名称
+            $('#copyShare_name').val(projectObj.project.projectInfo.name);
+        });
+         //拷贝工程改变选择建设项目
+         $('#copyShare_selectProj').change(function () {
+            $('#copyShareProj-info').hide();
+            $('#copyShareEng-info').hide();
+            $('#copyShareTender-info').hide();
+            let curSelID = $(this).select().val();
+            setEng(parseInt(curSelID));
+        });
+        //拷贝工程改变选择单项工程
+        $('#copyShare_selectEng').change(function () {
+            $('#copyShareTender-info').hide();
+        });
+
+
+         //确认拷贝
+         $('#copyShare_confirm').click(function () {
+            let selProj = $('#copyShare_selectProj').select().val();
+            if(!selProj){
+                $('#copyShareProj-info').show();
+                return;
+            }
+            //目标建设项目的计税方法与单位工程的一致时,才可拷贝
+            if (curCopySelTree) {
+                let projectNode = curCopySelTree.nodes[curCopySelTree.prefix + selProj];
+                if (!projectNode || !projectNode.data.property || projectNode.data.property.taxType != projectObj.project.property.taxType){
+                    alert('当前单位工程计税方法与目标建设项目不一致,不可复制。');
+                    return;
+                }
+            }
+            let selEng = $('#copyShare_selectEng').select().val();
+            if(!selEng){
+                $('#copyShareEng-info').show();
+                return;
+            }
+            copyShareProject(projectObj.project.projectInfo, parseInt(selProj), parseInt(selEng));
+        });
+    }
+    return{eventListener}
+})()
+$(document).ready(function () {
+    console.log("hehe")
+    copyProject.eventListener();
+});

+ 8 - 3
web/building_saas/main/js/views/project_info.js

@@ -26,10 +26,15 @@ var projectInfoObj = {
         }
         const action = projectCooperate ? '可编辑' : '只能查看';
         const ownerName = owner && owner.real_name || '';
+        const dropdownMenu = allowCopy?`
+         <div  class="dropdown-menu" style="left:auto;">
+        <a class="dropdown-item btn-sm"  href="#copyShare" data-toggle="modal">拷贝工程</a>
+      </div>`:"";
         return `
-            <span class="pl-2" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="来自 ${ownerName} 的分享">
-                <a href="javascript:;" class="btn btn-xs btn-primary default-cursor"><i class="fa fa-share-alt"></i> ${action}</a>
-            </span>`;
+            <span class="pl-2" data-toggle="tooltip" data-placement="left" title="" data-original-title="来自 ${ownerName} 的分享">
+                <a href="javascript:void(0);"  ${allowCopy?'data-toggle="dropdown"':''} class="btn btn-xs btn-primary default-cursor ${allowCopy?'dropdown-toggle':''} " ><i class="fa fa-share-alt"></i> ${action}</a>
+                ${dropdownMenu}
+                </span> `;
     },
     getShareButton: function (projectReadOnly, projectCooperate, shareTip) {
         if (projectReadOnly || projectCooperate) {

+ 16 - 2
web/building_saas/main/js/views/project_view.js

@@ -995,6 +995,7 @@ var projectObj = {
                 if(!projectReadOnly){
                     that.mainSpreadEscKey(that.mainSpread, that.mainSpreadEditStarting, that.mainSpreadEditEnded);
                     sheetCommonObj.bindEnterKey(that.mainSpread, that.mainSpreadEnterKey);
+                    that.bindPaseBlockKey(that.mainSpread);
                 }
                 setTimeout(function () {
                     that.mainSpread.getActiveSheet().startEdit();//这两句需要挺多时间,而又需要在editend 事件前触发,而这些又不影响计算,所以这里用异步的方法
@@ -1059,6 +1060,17 @@ var projectObj = {
         });
 
     },
+    //绑定复制整块,粘贴整块快捷键
+    bindPaseBlockKey:function(workBook){
+        workBook.commandManager().register('paseBlock', function () {
+            //  console.log("teest Z")
+            // BlockController.copyRightClickCallback();
+        })
+
+        workBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.z, true, false, false, false);
+        workBook.commandManager().setShortcutKey('paseBlock', GC.Spread.Commands.Key.z, true, false, false, false);
+    },
+
     //mainSpread有一些单元格进入编辑状态后,会动态改变值,公用的bindEscKey方法不适用
     mainSpreadEscKey: function (workBook, editStarting = null, editEnded = null) {
         workBook.commandManager().register('myEsc', function () {
@@ -1100,6 +1112,7 @@ var projectObj = {
         });
         workBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.esc, false, false, false, false);
         workBook.commandManager().setShortcutKey('myEsc', GC.Spread.Commands.Key.esc, false, false, false, false);
+
     },
     mainSpreadEnterKey: function () {
         let me = projectObj;
@@ -1746,7 +1759,7 @@ var projectObj = {
                     name: '复制整块',
                     icon: 'fa-copy',
                     disabled: function () {
-                        if (projectReadOnly) {
+                        /* if (projectReadOnly) {
                             return true;
                         }
                         let selection = projectObj.mainSpread.getActiveSheet().getSelections()[0];
@@ -1759,7 +1772,8 @@ var projectObj = {
                                 }
                             }
                         }
-                        return false;
+                        return false; */
+                        return BlockController.disabelCopyRightClick();
                     },
                     callback: function () {
                         $.bootstrapLoading.start();

+ 5 - 2
web/building_saas/pm/js/pm_newMain.js

@@ -3251,7 +3251,7 @@ function AddTenderItems(selected, projName, engName, tenderName, property, callb
                 let tenderNode = projTreeObj.insert(tenderData, engNode, null);
                 const rows = [pojNode.serialNo(), engNode.serialNo(), tenderNode.serialNo()];
                 sheetCommonObj.setRowsAutoFit(projTreeObj.workBook.getSheet(0), rows, 0, true)
-                callback();
+                callback();           
             }, errCB);
         }, errCB);
     }
@@ -3307,17 +3307,20 @@ function AddTenderItems(selected, projName, engName, tenderName, property, callb
                 updateDatas.push({updateType: 'update', updateData: {ID: pre.id(), NextSiblingID: tenderID}});
             }
             UpdateProjectData(updateDatas, function (datas) {
+                let tenderNode = null;
                 datas.forEach(function (data) {
                     if(data.updateType === 'new') {
                         data.updateData.shareInfo = [];
                         setInitSummaryData(data.updateData);
                         data.updateData.feeStandardName = data.updateData.property.feeStandardName || '';
-                        let tenderNode = projTreeObj.insert(data.updateData, tempEng, null);
+                        tenderNode = projTreeObj.insert(data.updateData, tempEng, null);
                         const rows = [tenderNode.serialNo()];
                         sheetCommonObj.setRowsAutoFit(projTreeObj.workBook.getSheet(0), rows, 0, true);
                     }
                 });
                 callback();
+                //自动打开新建的单位工程
+                //projTreeObj.openTender(tenderNode.data.ID, tenderNode.parent, 500);
             }, errCB);
         }, errCB);
     }