瀏覽代碼

Merge branch '1.0.0_online' of http://smartcost.f3322.net:3000/SmartCost/ConstructionCost into 1.0.0_online

chenshilong 6 年之前
父節點
當前提交
0db71f4b54
共有 35 個文件被更改,包括 672 次插入249 次删除
  1. 6 2
      config/gulpConfig.js
  2. 1 0
      modules/all_models/stdBills_bills.js
  3. 53 10
      modules/pm/controllers/pm_controller.js
  4. 35 1
      modules/pm/facade/pm_facade.js
  5. 1 0
      modules/pm/routes/pm_route.js
  6. 13 13
      modules/reports/controllers/rpt_controller.js
  7. 6 6
      modules/reports/rpt_component/jpc_ex.js
  8. 32 53
      modules/reports/rpt_component/jpc_flow_tab.js
  9. 1 1
      modules/users/controllers/boot_controller.js
  10. 5 0
      public/web/rpt_value_define.js
  11. 3 2
      public/web/sheet/sheet_common.js
  12. 83 0
      public/web/slideResize.js
  13. 13 6
      public/web/tree_sheet/tree_sheet_helper.js
  14. 0 1
      server.js
  15. 6 5
      test/unit/reports/test_rpt_test_template.js
  16. 11 5
      web/building_saas/complementary_glj_lib/html/tools-gongliaoji.html
  17. 37 0
      web/building_saas/complementary_glj_lib/js/glj.js
  18. 8 7
      web/building_saas/complementary_ration_lib/html/dinge.html
  19. 16 10
      web/building_saas/complementary_ration_lib/js/coe.js
  20. 38 35
      web/building_saas/complementary_ration_lib/js/ration.js
  21. 1 1
      web/building_saas/complementary_ration_lib/js/ration_assist.js
  22. 19 0
      web/building_saas/complementary_ration_lib/js/section_tree.js
  23. 2 1
      web/building_saas/css/custom.css
  24. 6 5
      web/building_saas/main/html/main.html
  25. 34 2
      web/building_saas/main/js/controllers/material_controller.js
  26. 2 2
      web/building_saas/main/js/views/glj_view.js
  27. 22 1
      web/building_saas/main/js/views/main_tree_col.js
  28. 4 8
      web/building_saas/main/js/views/project_view.js
  29. 8 0
      web/building_saas/main/js/views/sub_view.js
  30. 19 0
      web/building_saas/pm/html/project-management-share.html
  31. 1 0
      web/building_saas/pm/html/project-management.html
  32. 20 5
      web/building_saas/pm/js/pm_newMain.js
  33. 163 64
      web/building_saas/pm/js/pm_share.js
  34. 3 3
      web/building_saas/report/html/rpt_main.html
  35. 二進制
      web/dest/css/logo.png

+ 6 - 2
config/gulpConfig.js

@@ -35,6 +35,7 @@ module.exports = {
         'lib/jquery-contextmenu/jquery.contextMenu.css'
     ],
     pm_jspaths:[
+        'public/web/uuid.js',
         'public/web/date_util.js',
         'public/web/id_tree.js',
         'public/web/tree_sheet/tree_sheet_helper.js',
@@ -180,7 +181,8 @@ module.exports = {
         'public/web/ztree_common.js',
         'public/web/sheet/sheet_common.js',
         'web/building_saas/complementary_glj_lib/js/sheetOpr.js',
-        'public/web/storageUtil.js'
+        'public/web/storageUtil.js',
+        'public/web/slideResize.js'
     ],
     compleRation_ration_css: [
         'lib/ztree/css/zTreeStyle.css',
@@ -214,7 +216,9 @@ module.exports = {
         'web/building_saas/complementary_ration_lib/js/ration_glj.js',
         'web/building_saas/complementary_ration_lib/js/ration_coe.js',
         'web/building_saas/complementary_ration_lib/js/ration_assist.js',
-        'web/building_saas/complementary_ration_lib/js/ration_installation.js.js'
+        'web/building_saas/complementary_ration_lib/js/ration_installation.js.js',
+        'public/web/slideResize.js',
+        'web/building_saas/complementary_ration_lib/js/coe.js'
     ],
     compleRation_glj_css: [
     ],

+ 1 - 0
modules/all_models/stdBills_bills.js

@@ -14,6 +14,7 @@ const stdBills_bills = new Schema({
             ruleText: String,
             engineering: Number, //工程专业,填计算程序工程专业ID
             Expression: String,
+            comment: String, //备注,后台清单精灵录入
             jobs: [],
             items: [],
             recharge:String,

+ 53 - 10
modules/pm/controllers/pm_controller.js

@@ -47,21 +47,15 @@ module.exports = {
         }
     },
     checkProjectRight: function (userId, projectId, callback) {
-        ProjectsData.getProject(projectId).then(function (result) {
+        ProjectsData.getProject(projectId).then(async function (result) {
             /**
              * result._doc.userID(Number): MongoDB
              * userId(String): Session.userID
              */
-            //result._doc.userID == userId &&
             let isShare = false;
+            //判断是否是打开分享的项目
             if(userId !== result.userID){
-                //判断是否是打开分享的项目
-                for(let shareData of result.shareInfo){
-                    if(shareData.userID === userId){
-                        isShare = true;
-                        break;
-                    }
-                }
+                isShare = await pm_facade.isShare(userId, result);
             }
             if ((userId === result.userID || isShare) && result._doc.projType === projType.tender) {
                 callback(true);
@@ -521,8 +515,11 @@ module.exports = {
         try{
             let data = JSON.parse(req.body.data);
             //添加分享
-            let shareData = {userID: data.userID, allowCopy: data.allowCopy, shareDate: moment(Date.now()).format('YYYY-MM-DD HH:mm:ss')};
             if(data.type === 'create'){
+                let shareData = {userID: data.userID, allowCopy: data.allowCopy, shareDate: moment(Date.now()).format('YYYY-MM-DD HH:mm:ss')};
+                //覆盖
+                await projectModel.update({ID: data.projectID, $or: [{deleteInfo: null}, {'deleteInfo.deleted': false}]}, {$pull: {shareInfo: {userID: data.userID}}});
+                //新增
                 await projectModel.update({ID: data.projectID, $or: [{deleteInfo: null}, {'deleteInfo.deleted': false}]}, {$addToSet: {shareInfo: shareData}});
             }
             //取消分享
@@ -535,6 +532,52 @@ module.exports = {
             callback(req, res, 1, err, null);
         }
     },
+    //接收到的分享项目,返回未定义组、已定义组
+    receiveProjects: async function(req, res) {
+        try {
+            let rst = {grouped: [], ungrouped: []}
+            let userID = req.session.sessionUser.id;
+            let receiveProjects = await projectModel.find({
+                $or: [{deleteInfo: null}, {'deleteInfo.deleted': false}], compilation: req.session.sessionCompilation._id, 'shareInfo.userID': userID}, '-_id -property');
+            //设置原项目用户信息
+            if(receiveProjects.length > 0){
+                let orgUserIDs = [];
+                for(let proj of receiveProjects){
+                    orgUserIDs.push(proj.userID);
+                }
+                orgUserIDs = Array.from(new Set(orgUserIDs));
+                let userObjIDs = [];
+                for(let uID of orgUserIDs){
+                    userObjIDs.push(mongoose.Types.ObjectId(uID));
+                }
+                let orgUsersInfo = await userModel.find({_id: {$in : userObjIDs}});
+                for(let proj of receiveProjects){
+                    //获取分享项目子项
+                    if (proj.projType !== projType.tender) {
+                        proj._doc.children = await pm_facade.getPosterityProjects([proj.ID]);
+                    }
+                    //设置分组,单位工程及单项工程分到未分组那
+                    if (proj.projType === projType.tender || proj.projType === projType.engineering) {
+                        rst.ungrouped.push(proj);
+                    } else {
+                        rst.grouped.push(proj);
+                    }
+                    //设置项目类型为来自别人分享
+                    proj._doc.shareType = 'receive';
+                    for(let userData of orgUsersInfo){
+                        if(proj.userID == userData._id.toString()){
+                            let userInfo = {name: userData.real_name, mobile: userData.mobile, company: userData.company, email: userData.email};
+                            proj._doc.userInfo = userInfo;
+                        }
+                    }
+                }
+            }
+            callback(req, res, 0, 'success', rst);
+        }
+        catch (err){
+            callback(req, res, 1, err, null);
+        }
+    },
     getShareProjects: async function (req, res) {
         try {
             let userID = req.session.sessionUser.id;

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

@@ -46,7 +46,9 @@ module.exports={
     getConstructionProject: getConstructionProject,
     getFullPath: getFullPath,
     getProjectFeature:getProjectFeature,
-    projectType: projectType
+    projectType: projectType,
+    getPosterityProjects: getPosterityProjects,
+    isShare: isShare,
 };
 
 async function copyProject(userID, compilationID,data) {
@@ -722,4 +724,36 @@ async function getProjectFeature(libID,feeStandardName){
     }else {
         return [];
     }
+}
+
+//获取文件下所有子项目
+async function getPosterityProjects(projectIDs) {
+    let rst = [];
+    async function getProjects(IDs) {
+        if (IDs.length > 0) {
+            let newIDs = [];
+            let projs = await projectModel.find({ParentID: {$in: IDs}, $or: notDeleted}, '-_id -property');
+            for (let proj of projs) {
+                rst.push(proj);
+                newIDs.push(proj.ID);
+            }
+            await getProjects(newIDs);
+        }
+    }
+    await getProjects(projectIDs);
+    return rst;
+}
+
+//打开的单位工程是否是被分享的
+async function isShare(userId, project){
+    //判断是否是打开分享的项目,属于分享文件的子项也算
+    while (project) {
+        for(let shareData of project.shareInfo){
+            if(shareData.userID === userId){
+                return true;
+            }
+        }
+        project = await projectModel.findOne({ID: project.ParentID}, '-_id shareInfo ID ParentID');
+    }
+    return false;
 }

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

@@ -57,6 +57,7 @@ module.exports = function (app) {
     pmRouter.post('/getProjectShareInfo', pmController.projectShareInfo);
     pmRouter.post('/share', pmController.share);
     pmRouter.post('/getShareProjects', pmController.getShareProjects);
+    pmRouter.post('/receiveProjects', pmController.receiveProjects);
 
     app.use('/pm/api', pmRouter);
 };

+ 13 - 13
modules/reports/controllers/rpt_controller.js

@@ -57,7 +57,7 @@ function getAllPagesCommonOrg(rpt_id, pageSize, option, cb) {
                 let defProperties = rptUtil.getReportDefaultCache();
                 let dftOption = option||JV.PAGING_OPTION_NORMAL;
                 printCom.initialize(rptTpl);
-                printCom.analyzeData(rptTpl, tplData, defProperties, dftOption);
+                printCom.analyzeData(rptTpl, tplData, defProperties, dftOption, JV.OUTPUT_TYPE_NORMAL);
                 let maxPages = printCom.totalPages;
                 let pageRst = printCom.outputAsSimpleJSONPageArray(rptTpl, tplData, 1, maxPages, defProperties);
                 if (pageRst) {
@@ -223,7 +223,7 @@ function setupCustomizeCfg(customizeCfg, rptTpl, defProperties) {
         }
     }
 }
-function getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, customizeCfg, option, cb) {
+function getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, customizeCfg, option, outputType, cb) {
     let rptTpl = null;
     rptTplFacade.getRptTemplate(rpt_id).then(function(rst) {
         rptTpl = rst;
@@ -253,7 +253,7 @@ function getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, custo
                         if (customizeCfg) setupCustomizeCfg(customizeCfg, rptTpl, defProperties);
                         let dftOption = option||JV.PAGING_OPTION_NORMAL;
                         printCom.initialize(rptTpl);
-                        printCom.analyzeData(rptTpl, tplData, defProperties, dftOption);
+                        printCom.analyzeData(rptTpl, tplData, defProperties, dftOption, outputType);
                         let maxPages = printCom.totalPages;
                         let pageRst = printCom.outputAsSimpleJSONPageArray(rptTpl, tplData, 1, maxPages, defProperties, customizeCfg);
                         if (pageRst) {
@@ -298,7 +298,7 @@ function getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, custo
                     if (customizeCfg) setupCustomizeCfg(customizeCfg, rptTpl, defProperties);
                     let dftOption = option||JV.PAGING_OPTION_NORMAL;
                     printCom.initialize(rptTpl);
-                    printCom.analyzeData(rptTpl, tplData, defProperties, dftOption);
+                    printCom.analyzeData(rptTpl, tplData, defProperties, dftOption, outputType);
                     let maxPages = printCom.totalPages;
                     let pageRst = printCom.outputAsSimpleJSONPageArray(rptTpl, tplData, 1, maxPages, defProperties, customizeCfg);
                     if (pageRst) {
@@ -330,7 +330,7 @@ module.exports = {
         ;
         // req.session.sessionUser.ssoId
         let user_id = req.session.sessionUser.id;
-        getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, customizeCfg, null, function (err, pageRst) {
+        getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, customizeCfg, null, JV.OUTPUT_TYPE_NORMAL, function (err, pageRst) {
             callback(req, res, err, pageRst);
         });
     },
@@ -348,7 +348,7 @@ module.exports = {
         for (let id of rpt_ids) {
             parallelFunctions.push((function (rpt_id) {
                 return function (cb) {
-                    getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, customizeCfg, dftOption, function (err, pageRst) {
+                    getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, customizeCfg, dftOption, JV.OUTPUT_TYPE_NORMAL, function (err, pageRst) {
                         if(err){
                             cb(err);
                         }
@@ -377,7 +377,7 @@ module.exports = {
             customizeCfg = params.custCfg
         ;
         let user_id = req.session.sessionUser.id;
-        getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, customizeCfg, null, function (err, pageRst) {
+        getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, customizeCfg, null, JV.OUTPUT_TYPE_SVG, function (err, pageRst) {
             let svgRstStrArr = rpt_svg_util.exportSvgStr(pageRst, 0, 0);
             callback(req, res, err, svgRstStrArr);
         });
@@ -399,7 +399,7 @@ module.exports = {
             let r_id = rpt_ids[idx];
             parallelFunctions.push((function (rpt_id) {
                 return function (cb) {
-                    getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, customizeCfg, dftOption, function (err, pageRst) {
+                    getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, customizeCfg, dftOption, JV.OUTPUT_TYPE_EXCEL, function (err, pageRst) {
                         if(err){
                             cb(err);
                         }
@@ -440,7 +440,7 @@ module.exports = {
             let r_name = rpt_names[idx];
             parallelFunctions.push((function (rpt_id, rpt_name) {
                 return function (cb) {
-                    getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, customizeCfg, dftOption, function (err, pageRst) {
+                    getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, customizeCfg, dftOption, JV.OUTPUT_TYPE_EXCEL, function (err, pageRst) {
                         if(err){
                             cb(err);
                         } else {
@@ -495,7 +495,7 @@ module.exports = {
         let customizeCfg = null;
         let user_id = req.session.sessionUser.id;
         let dftOption = option||JV.PAGING_OPTION_NORMAL;
-        getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, customizeCfg, dftOption, function(err, pageRst){
+        getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, customizeCfg, dftOption, JV.OUTPUT_TYPE_EXCEL, function(err, pageRst){
             try {
                 rpt_xl_util.exportExcel(pageRst, pageSize, rptName, isOneSheet, null, null, function(uuidName){
                     res.setHeader('Content-Type', 'application/vnd.openxmlformats');
@@ -526,7 +526,7 @@ module.exports = {
         for (let id of rpt_ids) {
             parallelFunctions.push((function (rpt_id) {
                 return function (cb) {
-                    getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, null, null, dftOption, function (err, pageRst) {
+                    getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, null, null, dftOption, JV.OUTPUT_TYPE_EXCEL, function (err, pageRst) {
                         if(err){
                             cb(err);
                         }
@@ -573,7 +573,7 @@ module.exports = {
             let r_name = rpt_names[idx];
             parallelFunctions.push((function (rpt_id, rpt_name) {
                 return function (cb) {
-                    getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, customizeCfg, dftOption, function (err, pageRst) {
+                    getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, customizeCfg, dftOption, JV.OUTPUT_TYPE_PDF, function (err, pageRst) {
                         if(err){
                             cb(err);
                         }
@@ -604,7 +604,7 @@ module.exports = {
             rptName = req.params.rptName
         ;
         let user_id = req.session.sessionUser.id;
-        getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, null, JV.PAGING_OPTION_NORMAL, function(err, pageRst){
+        getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, null, JV.PAGING_OPTION_NORMAL, JV.OUTPUT_TYPE_PDF, function(err, pageRst){
             rpt_pdf_util.export_pdf_file(pageRst, pageSize, rptName,function (uuidName) {
                 res.setHeader('Content-Type', 'application/vnd.openxmlformats');
                 // res.setHeader("Content-Disposition", "attachment; filename=" + strUtil.getPinYinCamelChars(rptName) + ".pdf");

+ 6 - 6
modules/reports/rpt_component/jpc_ex.js

@@ -164,7 +164,7 @@ JpcExSrv.prototype.createNew = function(){
         me.formulas = JpcFunc.createNew(rptTpl);
     };
 
-    JpcResult.analyzeData = function(rptTpl, dataObj, defProperties, option) {
+    JpcResult.analyzeData = function(rptTpl, dataObj, defProperties, option, outputType) {
         let me = this, dftPagingOption = option||JV.PAGING_OPTION_NORMAL;
         //1. data object
         let dataHelper = JpcData.createNew();
@@ -189,20 +189,20 @@ JpcExSrv.prototype.createNew = function(){
         //3. formulas
         me.executeFormulas(JV.RUN_TYPE_BEFORE_PAGING, rptTpl, dataObj, me);
         //4. paging
-        me.paging(rptTpl, dataObj, defProperties, dftPagingOption);
+        me.paging(rptTpl, dataObj, defProperties, dftPagingOption, outputType);
         //alert('analyzeData was completed!');
         //for garbage collection:
         dataHelper = null;
     };
-    JpcResult.paging = function(rptTpl, dataObj, defProperties, option) {
+    JpcResult.paging = function(rptTpl, dataObj, defProperties, option, outputType) {
         let me = this, dftPagingOption = option||JV.PAGING_OPTION_NORMAL;
         if (me.flowTab) {
             if (me.isFollowMode) {
-                me.totalPages = me.flowTab.preSetupPages(rptTpl, dataObj, defProperties, dftPagingOption, me, me.flowTabEx);
+                me.totalPages = me.flowTab.preSetupPages(rptTpl, dataObj, defProperties, dftPagingOption, me, me.flowTabEx, outputType);
             } else {
-                me.totalPages = me.flowTab.preSetupPages(rptTpl, dataObj, defProperties, dftPagingOption, me, null);
+                me.totalPages = me.flowTab.preSetupPages(rptTpl, dataObj, defProperties, dftPagingOption, me, null, outputType);
                 if (me.flowTabEx) {
-                    me.exTotalPages = me.flowTabEx.preSetupPages(rptTpl, dataObj, defProperties, dftPagingOption, me, null);
+                    me.exTotalPages = me.flowTabEx.preSetupPages(rptTpl, dataObj, defProperties, dftPagingOption, me, null, outputType);
                     //console.log('ad-hoc flow pages: ' + me.exTotalPages);
                 }
                 me.totalPages += me.exTotalPages;

+ 32 - 53
modules/reports/rpt_component/jpc_flow_tab.js

@@ -153,7 +153,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
 
         me.auto_height_fields_idx = [];//那些被标记为判断自动行高的指标集合
         me.auto_height_info = [];
-        me.group_fields = [];
+        me.group_check_fields = [];
         me.group_sum_fields = [];
         me.group_sum_values = null;
         me.group_node_info = null; //记录在哪个seg及到哪条记录后有group sum信息
@@ -172,8 +172,17 @@ JpcFlowTabSrv.prototype.createNew = function(){
         if (rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_SEG_SUM]) JpcFieldHelper.findAndPutDataFieldIdx(rptTpl, rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_SEG_SUM][JV.PROP_SUM_FIELDS], me.seg_sum_tab_fields, me.seg_sum_fields_idx, me.isEx);
         if (rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_PAGE_SUM]) JpcFieldHelper.findAndPutDataFieldIdx(rptTpl, rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_PAGE_SUM][JV.PROP_SUM_FIELDS], me.page_sum_tab_fields, me.page_sum_fields_idx, me.isEx);
         if (rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_GROUP]) {
-            JpcFieldHelper.findAndPutDataFieldIdx(rptTpl, rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_GROUP][JV.PROP_GROUP_FIELDS], me.group_fields, null, me.isEx);
-            JpcFieldHelper.findAndPutDataFieldIdx(rptTpl, rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_GROUP][JV.PROP_SUM_FIELDS], me.group_sum_fields, null, me.isEx);
+            JpcFieldHelper.findAndPutDataFieldIdx(rptTpl, rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_GROUP][JV.PROP_GROUP_FIELDS], me.group_check_fields, null, me.isEx);
+            if (rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_GROUP][JV.PROP_GROUP_LINES]) {
+                for (let grpLine of rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_GROUP][JV.PROP_GROUP_LINES]) {
+                    if (grpLine[JV.PROP_GROUP_SUM_KEYS] && grpLine[JV.PROP_GROUP_SUM_KEYS].length > 0) {
+                        JpcFieldHelper.findAndPutDataFieldIdx(rptTpl, grpLine[JV.PROP_GROUP_SUM_KEYS], me.group_sum_fields, null, me.isEx);
+                    }
+                }
+            }
+            for (let grp_sum_f of me.group_sum_fields) {
+                grp_sum_f[JV.PROP_SUM_KEY] = `grp_sum_key_` + grp_sum_f[JV.PROP_FIELD_ID];
+            }
         }
         JpcFieldHelper.findAutoHeightFieldIdx(rptTpl, rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_CONTENT][JV.PROP_FLOW_FIELDS], me.auto_height_fields_idx, me.isEx);
         for (let si = 0; si < dataSeq.length; si++) {
@@ -187,7 +196,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
         let data_details = me.isEx?dataObj[JV.DATA_DETAIL_DATA_EX]:dataObj[JV.DATA_DETAIL_DATA],
             data_fields = [];
         for (let i = 0; i < me.seg_sum_fields_idx.length; i++) {
-            if (typeof(me.seg_sum_fields_idx[i])=="object") {
+            if (typeof(me.seg_sum_fields_idx[i]) === "object") {
                 let exField = JE.F(me.seg_sum_fields_idx[i][JV.PROP_ID], $CURRENT_RPT);
                 if (exField) {
                     data_fields.push(exField["data_field"]);
@@ -227,36 +236,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
             }
         }
     };
-    JpcFlowTabResult.getFlowFieldById = function (fieldKey, rptTpl) {
-        let rst = null;
-        if (rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_GROUP] && rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_GROUP][JV.PROP_GROUP_LINES] && rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_GROUP][JV.PROP_GROUP_LINES].length > 0) {
-            for (let grpLine of rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_GROUP][JV.PROP_GROUP_LINES]) {
-                if (grpLine[JV.PROP_GROUP_SUM_KEYS] && grpLine[JV.PROP_GROUP_SUM_KEYS].length > 0) {
-                    for (let sumKey of grpLine[JV.PROP_GROUP_SUM_KEYS]) {
-                        if (sumKey[JV.PROP_SUM_KEY] === fieldKey) {
-                            rst = sumKey;
-                            break;
-                        }
-                    }
-                }
-                if (rst) break;
-            }
-        }
-        if (!(rst) && rptTpl[JV.NODE_FLOW_INFO_EX] && rptTpl[JV.NODE_FLOW_INFO_EX][JV.NODE_FLOW_GROUP] && rptTpl[JV.NODE_FLOW_INFO_EX][JV.NODE_FLOW_GROUP][JV.PROP_GROUP_LINES] && rptTpl[JV.NODE_FLOW_INFO_EX][JV.NODE_FLOW_GROUP][JV.PROP_GROUP_LINES].length > 0) {
-            for (let grpLine of rptTpl[JV.NODE_FLOW_INFO_EX][JV.NODE_FLOW_GROUP][JV.PROP_GROUP_LINES]) {
-                if (grpLine[JV.PROP_GROUP_SUM_KEYS] && grpLine[JV.PROP_GROUP_SUM_KEYS].length > 0) {
-                    for (let sumKey of grpLine[JV.PROP_GROUP_SUM_KEYS]) {
-                        if (sumKey[JV.PROP_SUM_KEY] === fieldKey) {
-                            rst = sumKey;
-                            break;
-                        }
-                    }
-                }
-                if (rst) break;
-            }
-        }
-        return rst;
-    };
+
     JpcFlowTabResult.sumUpGrp = function (rptTpl, $CURRENT_RPT, dataObj, segIdx, preGrpIdx, nexGrpIdx) {
         let me = this, segDataIdx = me.segments[segIdx];
         for (let j = 0; j < me.group_sum_fields.length; j++) {
@@ -273,7 +253,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
                     if (sum_field[JV.PROP_PRECISION] && sum_field[JV.PROP_PRECISION].type === `fixed`) {
                         precisionAmt = sum_field[JV.PROP_FIXED_PRECISION_AMT];
                     } else {
-                        let flowF = me.getFlowFieldById(me.group_sum_fields[j][JV.PROP_SUM_KEY], rptTpl);
+                        let flowF = me.group_sum_fields[j]; //调整后,me.group_sum_fields[j]就是group lines下数组SumKey_S的元素值,无需再找
                         if (flowF && !strUtil.isEmptyString(flowF[JV.PROP_FORMAT])) {
                             let idx = flowF[JV.PROP_FORMAT].indexOf('.');
                             if (idx >= 0) {
@@ -292,7 +272,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
     };
     JpcFlowTabResult.setupGroupingData = function (rptTpl, dataObj, $CURRENT_RPT) {
         let me = this;
-        if (me.group_fields.length > 0 && me.group_sum_fields.length > 0) {
+        if (me.group_check_fields.length > 0 && me.group_sum_fields.length > 0) {
             me.group_sum_values = [];
             me.group_node_info = [];
             let CURRENT_FLOW_INFO = (me.isEx)?JV.NODE_FLOW_INFO_EX:JV.NODE_FLOW_INFO;
@@ -312,8 +292,8 @@ JpcFlowTabSrv.prototype.createNew = function(){
                 for (let di = 0; di < segDataIdx.length; di++) {
                     let hasDiff = false;
                     if (di > 1) {
-                        for (let i = 0; i < me.group_fields.length; i++) {
-                            let grp_field = JE.F(me.group_fields[i][JV.PROP_FIELD_ID], $CURRENT_RPT);
+                        for (let i = 0; i < me.group_check_fields.length; i++) {
+                            let grp_field = JE.F(me.group_check_fields[i][JV.PROP_FIELD_ID], $CURRENT_RPT);
                             if (grp_field) {
                                 let data_field = null;
                                 if (grp_field[JV.PROP_AD_HOC_DATA]) {
@@ -346,7 +326,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
             }
         }
     };
-    JpcFlowTabResult.setupAutoHeightData = function(bands, segIdx, rptTpl, dataObj, $CURRENT_RPT, defProperties) {
+    JpcFlowTabResult.setupAutoHeightData = function(bands, segIdx, rptTpl, dataObj, $CURRENT_RPT, defProperties, outputType) {
         let me = this;
         if (me.auto_height_fields_idx.length > 0) {
             let CURRENT_FLOW_INFO = (me.isEx)?JV.NODE_FLOW_INFO_EX:JV.NODE_FLOW_INFO;
@@ -415,7 +395,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
                             }
                         }
                         if (accAmt > rst) rst = accAmt;
-                        if (hasSplitStr) {
+                        if (hasSplitStr && outputType !== JV.OUTPUT_TYPE_EXCEL) {
                             let newValArr = [];
                             for (let i = 0; i < values.length; i++) {
                                 if (splitStrArr.indexOf(i) < 0) {
@@ -428,6 +408,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
                             splitStrArr = [];
                             newValArr = [];
                         }
+                        //备注: 如果outputType是excel类型,那么就只保留原始的分行符,无需介入分行,由excel本身去处理分行,只需要保留足够的空间即可。
                     }
                 }
                 return rst;
@@ -460,7 +441,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
         }
     };
 
-    JpcFlowTabResult.preSetupPages = function (rptTpl, dataObj, defProperties, option, $CURRENT_RPT, followTabEx) {
+    JpcFlowTabResult.preSetupPages = function (rptTpl, dataObj, defProperties, option, $CURRENT_RPT, followTabEx, outputType) {
         //换一种思路来整理流水式数据
         let me = this, rst = 1, counterRowRec = 0, counterRowRecEx = 0, maxRowRec = 1, pageIdx = 0, currentRecAmt = 0;
         me.paging_option = option||JV.PAGING_OPTION_NORMAL;
@@ -576,7 +557,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
                 grpPageInfo[JV.PROP_GRP_LINES] = me.group_lines_amt;
                 pageStatus[JV.STATUS_SEGMENT_START] = true;
                 private_resetBandArea();
-                me.setupAutoHeightData(bands, segIdx, rptTpl, dataObj, $CURRENT_RPT, defProperties);
+                me.setupAutoHeightData(bands, segIdx, rptTpl, dataObj, $CURRENT_RPT, defProperties, outputType);
                 let threshold = 0;
                 currentRecAmt = 0;
                 counterRowRec = 0;
@@ -983,14 +964,11 @@ JpcFlowTabSrv.prototype.createNew = function(){
                             if (contentValuesIdx[rowIdx][3] === grpIdx) {
                                 let grp_line = rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_GROUP][JV.PROP_GROUP_LINES][grpIdx];
                                 if (page === 1) {
-                                    let sumFields = rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_GROUP][JV.PROP_SUM_FIELDS];
-                                    for (let sumF of sumFields) {
-                                        if (grp_line[JV.PROP_GROUP_SUM_KEYS] && grp_line[JV.PROP_GROUP_SUM_KEYS].length > 0) {
-                                            for (let grp_sum_field of grp_line[JV.PROP_GROUP_SUM_KEYS]) {
-                                                if (grp_sum_field[JV.PROP_SUM_KEY] === sumF[JV.PROP_SUM_KEY]) {
-                                                    let map_field = JE.F(sumF[JV.PROP_FIELD_ID], $CURRENT_RPT);
-                                                    JpcFieldHelper.resetFormat(grp_sum_field, map_field, customizeCfg);
-                                                }
+                                    if (grp_line[JV.PROP_GROUP_SUM_KEYS] && grp_line[JV.PROP_GROUP_SUM_KEYS].length > 0) {
+                                        for (let grp_sum_field of grp_line[JV.PROP_GROUP_SUM_KEYS]) {
+                                            if (grp_sum_field[JV.PROP_FIELD_ID]) {
+                                                let map_field = JE.F(grp_sum_field[JV.PROP_FIELD_ID], $CURRENT_RPT);
+                                                JpcFieldHelper.resetFormat(grp_sum_field, map_field, customizeCfg);
                                             }
                                         }
                                     }
@@ -1146,7 +1124,8 @@ JpcFlowTabSrv.prototype.createNew = function(){
             let segIdx = JpcCommonHelper.getSegIdxByPageIdx(page, me.page_seg_map);
             let curSegGrpSum = me.group_sum_values[segIdx];
             for (let sumFieldNode of grp_line[JV.PROP_GROUP_SUM_KEYS]) {
-                let value = curSegGrpSum[sumFieldNode[JV.PROP_SUM_KEY]][grpValueIdx[2]];
+                // let value = curSegGrpSum[sumFieldNode[JV.PROP_SUM_KEY]][grpValueIdx[2]];
+                let value = curSegGrpSum[`grp_sum_key_` + sumFieldNode[JV.PROP_FIELD_ID]][grpValueIdx[2]];
                 let sumFldRst = JpcTextHelper.outputDirectValue(sumFieldNode, value,  band, unitFactor, rows, rowIdx, cols, colIdx, me.multiCols, multiColIdx);
                 rst.push(sumFldRst);
             }
@@ -1257,13 +1236,13 @@ function combineAutoHeightCells(prepareObj, page, controls) {
                         rst.push(sameColCells[i].cellIdx); //记下Cell的位置,在函数外消除
                         //如果到了最后一条数据,得判断firstMergeCell是否满格(即数据是满的,有可能有些格数据也有折行但不是自动行高判断指标)
                         //不满格的cell的Vertical强制设置为 'center'
-                        if (i === sameColCells.length - 1 && validValueAmt !== fullValidValueAmt) {
+                        if (i === sameColCells.length - 1 && validValueAmt !== fullValidValueAmt && (fullValidValueAmt / validValueAmt > 2.5) ) {
                             firstMergeCell[JV.PROP_CONTROL].VerticalForExcel = 'center';
                         }
                     } else {
                         //碰到新开始的自动行高行,判断原先的firstMergeCell是否满格(即数据是满的,有可能有些格数据也有折行但不是自动行高判断指标)
                         //不满格的cell的Vertical强制设置为 'center'
-                        if (validValueAmt !== fullValidValueAmt) {
+                        if (validValueAmt !== fullValidValueAmt && (fullValidValueAmt / validValueAmt > 2.5)) {
                             firstMergeCell[JV.PROP_CONTROL].VerticalForExcel = 'center';
                         }
                         firstMergeCell = sameColCells[i].cell;

+ 1 - 1
modules/users/controllers/boot_controller.js

@@ -49,7 +49,7 @@ class BootController extends BaseController {
             companyScaleList: userModel.companyScale,
             compilation: request.params.compilation,
             compilationName: request.session.sessionCompilation.name,
-            versionName: `纵横云计价(${req.session.compilationVersion})`,
+            versionName: `纵横云计价(${request.session.compilationVersion})`,
         };
         response.render('users/html/login-infoinput', renderData);
     }

+ 5 - 0
public/web/rpt_value_define.js

@@ -278,6 +278,11 @@ const JV = {
     PAGING_OPTION_NORMAL: 'normal',
     PAGING_OPTION_INFINITY: 'infinity',
 
+    OUTPUT_TYPE_NORMAL: 'normal',
+    OUTPUT_TYPE_SVG: 'svg',
+    OUTPUT_TYPE_PDF: 'pdf',
+    OUTPUT_TYPE_EXCEL: 'excel',
+
     DISPLAY_VAL_TYPE_NORMAL: 0,
     DISPLAY_VAL_TYPE_GROUP: 1,
     DISPLAY_VAL_TYPE_AUTO_HEIGHT: 2,

+ 3 - 2
public/web/sheet/sheet_common.js

@@ -539,7 +539,7 @@ var sheetCommonObj = {
         };
         return new ComboCellForActiveCell();
     },
-    getTipsCombo:function (forLocked,tips,setting) {
+    getTipsCombo:function (forLocked,tips,setting,node) {
         let getTipsCombo = function () {
             this.clickCom=false;
         };
@@ -550,7 +550,8 @@ var sheetCommonObj = {
                     this.clickCom = false;
                     return;
                 }
-                TREE_SHEET_HELPER.delayShowTips(hitinfo,setting,tips);
+                let text =  typeof tips == 'function'?tips(node):tips;
+                TREE_SHEET_HELPER.delayShowTips(hitinfo,setting,text);
             };
             getTipsCombo.prototype.processMouseLeave = function (hitinfo) {
                 TREE_SHEET_HELPER.hideTipsDiv();

+ 83 - 0
public/web/slideResize.js

@@ -0,0 +1,83 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Zhong
+ * @date 2018/11/7
+ * @version
+ */
+
+/*
+ * div之间的水平拖动,适应各种情况
+ * module: 所属模块,防止不同页面相同id导致localstorage数据被覆盖
+ * eleObj: resize, parent, left, right
+ * limit: min, max
+ * */
+
+const SlideResize = (function() {
+    let mouseMoveCount = 0;
+    function horizontalSlide(module, eleObj, limit, callback) {
+        const triggerCBSize = 5;
+        let drag = false,
+            startPoint = 0,
+            leftWidth = 0,
+            rightWidth = 0,
+            leftChange = 0,
+            rightChange = 0,
+            limitMax = 0;
+
+        eleObj.resize.mousedown(function (e) {
+            drag = true;
+            startPoint = e.clientX;
+            leftWidth = eleObj.left.width();
+            rightWidth = eleObj.right.width();
+            limitMax = eval(limit.max);
+        });
+        $('body').mousemove(function (e) {
+            if (drag) {
+                let moveSize = e.clientX - startPoint;
+                leftChange = leftWidth + moveSize;
+                leftChange = leftChange < limit.min ? limit.min : leftChange;
+                leftChange = leftChange > limitMax ? limitMax - 3 : leftChange;
+                rightChange = rightWidth - moveSize;
+                rightChange = rightChange < limit.min ? limit.min : rightChange;
+                rightChange = rightChange > limitMax ? limitMax - 3 : rightChange;
+                let leftPercentWidth = leftChange / eleObj.parent.width() * 100 + '%',
+                    rightPercentWidth = rightChange / eleObj.parent.width() * 100 + '%';
+                eleObj.left.css('width', leftPercentWidth);
+                eleObj.right.css('width', rightPercentWidth);
+                mouseMoveCount += Math.abs(moveSize);
+                if (mouseMoveCount > triggerCBSize && callback) {
+                    callback();
+                    mouseMoveCount = 0;
+                }
+            }
+        });
+        $('body').mouseup(function (e) {
+            if (drag) {
+                drag = false;
+                mouseMoveCount = 0;
+                //将宽度信息存储到localstorage
+                let leftWidthInfo = eleObj.left[0].style.width;
+                setLocalCache(`${module}${eleObj.left.attr('id')}Width`, leftWidthInfo);
+                let rightWidthInfo = eleObj.right[0].style.width;
+                setLocalCache(`${module}${eleObj.right.attr('id')}Width`, rightWidthInfo);
+            }
+        });
+    }
+
+    function loadHorizonWidth(module, eles, callback) {
+        for (let ele of eles) {
+            let cache = getLocalCache(`${module}${ele.attr('id')}Width`);
+            if (cache) {
+                ele.css('width', cache);
+            }
+        }
+        if (callback) {
+            callback();
+        }
+    }
+
+    return {horizontalSlide, loadHorizonWidth}
+})();

+ 13 - 6
public/web/tree_sheet/tree_sheet_helper.js

@@ -537,9 +537,9 @@ var TREE_SHEET_HELPER = {
                 $editor.css("background", 'white');
                 $editor.css("width", cellRect.width);
                 $editor.css("height", cellRect.height);
-                $editor.attr("gcUIElement", "gcEditingInput");//padding:0  //value="${context.sheet.getValue(context.row,context.col)}"
+                //$editor.attr("gcUIElement", "gcEditingInput");//padding:0  //value="${context.sheet.getValue(context.row,context.col)}"
                 $editor.html(` <div class="input-group input-group-sm">
-                                <input type="text" id="esInput" class="form-control" aria-label="Text input with dropdown button" autocomplete="off"   style=" background-color:${cellStyle.backColor}">
+                                <input type="text" id="esInput" class="form-control"  autocomplete="off"  style=" background-color:${cellStyle.backColor}">
                                 <div class="">                           
                                     <div class="triangle-border_dropdown tb-border_dropdown" id="esBtn" style="z-index:10; left: ${cellRect.width - 15+"px"};top:${cellRect.height/2-2+"px"}"></div>
                                 </div>
@@ -578,23 +578,30 @@ var TREE_SHEET_HELPER = {
                     },function(){
                         $(this).css("background-color","");
                     });
-
-
                     $("#esBtn").bind('click',function(e){
                         $(".es-list").toggle();
                     });
                     if( $('#esInput').val()) setCursor( $("#esInput")[0], $('#esInput').val().length)
                 });
+
+            };
+
+            TreeNodeCellType.prototype.processKeyDown = function (e, context){ //当用isReservedKey 不拦截编辑模式时的input框ctrl + c时,在非编辑模式的ctrl + c事件也需要自已处理,所以在这里再调用一下复制命令
+                //console.log(tree)
+                if(e.keyCode === GC.Spread.Commands.Key.c && e.ctrlKey)  context.sheet.getParent().commandManager().execute({cmd:"copy",sheetName:context.sheet.name()});
+            };
+            TreeNodeCellType.prototype.isReservedKey = function (e, context) {
+                return e.keyCode === GC.Spread.Commands.Key.c && e.ctrlKey && !e.shiftKey && !e.altKey;//不拦截ctrl + c事件。
             };
             TreeNodeCellType.prototype.setEditorValue = function (editor, value, context) {
 
                  $('#esInput').val(value);
             };
             TreeNodeCellType.prototype.getEditorValue = function (editor, context) {
-                this.isEscKey = false;
                 console.log($('#esInput').val());
                 return  $('#esInput').val()!==''? $('#esInput').val():null;
             };
+
         }
         return new TreeNodeCellType();
 
@@ -758,4 +765,4 @@ var TREE_SHEET_HELPER = {
         };
         return new QuestionCellType();
     }
-};
+};

+ 0 - 1
server.js

@@ -79,7 +79,6 @@ app.use(function (req, res, next) {
             req.session.lastPage = url;
             return res.redirect('/login');
         }
-
         next();
     }
 });

+ 6 - 5
test/unit/reports/test_rpt_test_template.js

@@ -32,7 +32,7 @@ let demoPrjId = - 1;
 // let demoRptId = 361; //封1
 // let demoRptId = 279; //表04
 // let demoRptId = 261; //封3
-// let demoRptId = 458; //09
+let demoRptId = 458; //09
 // let demoRptId = 451; //09-1
 // let demoRptId = 452; //04
 // let demoRptId = 612; //09-3
@@ -41,18 +41,19 @@ let demoPrjId = - 1;
 // let demoRptId = 389; //10
 // let demoRptId = 280; //11-1 暂列金
 // let demoRptId = 2260; //测试基本信息
-let demoRptId = 613; //09-4 2018
+// let demoRptId = 613; //09-4 2018
 let pagesize = "A4";
 //288: 11-2表(新)
 //279: 04
 
 // let userId_Leng = "59cdf14a0034a1000ba52b97"; //小冷User Id 换成_id了 QQ号
 // let userId_Leng = "5acac1e885bf55000bd055ba"; //小冷User Id2
+// let userId_me = "5b6a60b1c4ba33000dd417c0"; //我的
 let userId_HaiZhu = "5b5a66c4a3c23e000dccdd77"; //海珠user id
 // demoPrjId = 720; //QA: DW3
 //demoPrjId = 1626; //QA:
 // demoPrjId = 2260; //QA:
-demoPrjId = 4529; //QA:
+demoPrjId = 4568; //QA:
 //*/
 let userId_Dft = userId_HaiZhu;
 // let userId_Dft = "5a025c4c15074d134c2b9689";
@@ -93,12 +94,12 @@ test('测试 - 测试模板啦: ', function (t) {
                     let defProperties = rpt_cfg;
                     let dftOption = JV.PAGING_OPTION_NORMAL;
                     printCom.initialize(rptTpl);
-                    printCom.analyzeData(rptTpl, tplData, defProperties, dftOption);
+                    printCom.analyzeData(rptTpl, tplData, defProperties, dftOption, JV.OUTPUT_TYPE_EXCEL);
                     let maxPages = printCom.totalPages;
                     let customizeCfg = {"fillZero": true};
                     let pageRst = printCom.outputAsSimpleJSONPageArray(rptTpl, tplData, 1, maxPages, defProperties, customizeCfg);
                     if (pageRst) {
-                        // fsUtil.writeObjToFile(pageRst, "D:/GitHome/ConstructionCost/tmp/testBuiltPageResult_测试模板.jsp");
+                        fsUtil.writeObjToFile(pageRst, "D:/GitHome/ConstructionCost/tmp/testBuiltPageResult_测试模板.jsp");
                         // rpt_xl_util.exportExcel(pageRst, pagesize, "local_test_rpt_excel", true, null, null, function(uuidName){
                         //     console.log("excel uuid: " + uuidName);
                         // });

+ 11 - 5
web/building_saas/complementary_glj_lib/html/tools-gongliaoji.html

@@ -32,18 +32,23 @@
     <div class="main">
         <div class="content" style="margin-left: 0px;">
             <div class="container-fluid">
-                <div class="row">
-                    <div class="col-lg-3 p-0">
+                <div class="row" id="dataRow">
+                    <div id="leftContent" style="width: 25%;">
                         <div class="print-list">
                             <div class="form-list">
                                 <div id="gljClassSpread" style="height: 100%; width: 100%;"></div>
                             </div>
                         </div>
                     </div>
-                    <div id="GLJListSheet" class="col-lg-6 p-0">
-
+                    <div id="midContent" style="width: 50%">
+                        <div id="leftResize" style="width: 1%; height: 100%; resize:horizontal; cursor: w-resize; float: left; background: #F1F1F1"></div>
+                        <div id="GLJListSheet" class="p-0" style="height: 100%; width: 99%; float: left">
+                        </div>
                     </div>
-                    <div id="gljComponentSheet" class="col-lg-3 p-0">
+                    <div id="rightContent" style="width: 25%" >
+                        <div id="rightResize" style="width: 1%; height: 100%; resize:horizontal; cursor: w-resize; float: left; background: #F1F1F1"></div>
+                        <div id="gljComponentSheet" class="p-0" style="height: 100%; width: 99%; float: left">
+                        </div>
                     </div>
                 </div>
             </div>
@@ -169,6 +174,7 @@
     <script type="text/javascript" src="/public/web/sheet/sheet_common.js"></script>
     <script type="text/javascript" src="/web/building_saas/complementary_glj_lib/js/sheetOpr.js"></script>
     <script type="text/javascript" src="/public/web/storageUtil.js"></script>
+    <script src="/public/web/slideResize.js"></script>
     <!--endinject-->
     <script type="text/javascript" src="<%= overWriteUrl %>"></script>
     <SCRIPT type="text/javascript">

+ 37 - 0
web/building_saas/complementary_glj_lib/js/glj.js

@@ -1,6 +1,43 @@
 /**
  * Created by Zhong on 2017/8/14.
  */
+
+$(document).ready(function () {
+    let moduleName = 'compleGLj';
+    function refreshALlWorkBook() {
+        if (gljClassTreeObj.workBook) {
+            gljClassTreeObj.workBook.refresh();
+        }
+        if (repositoryGljObj.workBook) {
+            repositoryGljObj.workBook.refresh();
+        }
+        if (gljComponentOprObj.workBook) {
+            gljComponentOprObj.workBook.refresh();
+        }
+    }
+    SlideResize.loadHorizonWidth(moduleName, [$('#leftContent'), $('#midContent'), $('#rightContent')], function () {
+        refreshALlWorkBook();
+    });
+    //章节树与人材机表
+    let leftElesObj = {};
+    leftElesObj.resize = $('#leftResize');
+    leftElesObj.parent = $('#dataRow');
+    leftElesObj.left = $('#leftContent');
+    leftElesObj.right = $('#midContent');
+    SlideResize.horizontalSlide(moduleName, leftElesObj, {min: 200, max: `$('#dataRow').width() - $('#rightContent').width() - 200`}, function () {
+        refreshALlWorkBook();
+    });
+    //人材机表与人材机组成物表
+    let rightElesObj = {};
+    rightElesObj.resize = $('#rightResize');
+    rightElesObj.parent = $('#dataRow');
+    rightElesObj.left = $('#midContent');
+    rightElesObj.right = $('#rightContent');
+    SlideResize.horizontalSlide(moduleName, rightElesObj, {min: 200, max: `$('#dataRow').width() - $('#leftContent').width() - 200`}, function () {
+        refreshALlWorkBook();
+    });
+});
+
 let pageOprObj = {
     gljLibName : null,
     stdGljLibId: null,

+ 8 - 7
web/building_saas/complementary_ration_lib/html/dinge.html

@@ -60,9 +60,9 @@
             <!--<li class="nav-item">
                 <a class="nav-link px-3" id="fuzhu" href="<%= redirectCoe %>">子目换算</a>
             </li>-->
-            <li class="nav-item">
+            <!--<li class="nav-item">
                 <a class="nav-link px-3" id="anzhuang" href="<%= redirectInstallation %>">安装增加费</a>
-            </li>
+            </li>-->
         </ul>
         <ul class="nav nav-tabs" role="tablist">
             <li class="nav-item">
@@ -74,8 +74,8 @@
 <div class="main" style="overflow: hidden">
     <div class="content" style="margin-left: 0px">
         <div class="container-fluid">
-            <div class="row">
-                <div class="main-side p-0" style="width: 25%; height: 100%; overflow: hidden">
+            <div class="row" id="dataRow">
+                <div class="main-side p-0" style="width: 25%; height: 100%; overflow: hidden" id="leftContentg">
                     <div class="tab-bar">
                         <a href="javascript:void(0);" id="tree_Insert" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="插入"><i class="fa fa-plus" aria-hidden="true"></i></a>
                         <a href="javascript:void(0);" id="tree_remove" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="删除"><i class="fa fa-remove" aria-hidden="true"></i></a>
@@ -125,9 +125,9 @@
                                     <li class="nav-item">
                                         <a class="nav-link" id="linkFZTJ" data-toggle="tab" href="#rDetail" role="tab">子目换算调整</a>
                                     </li>
-                                    <li class="nav-item">
+                                    <!--<li class="nav-item">
                                         <a class="nav-link px-3" id="linkAZZJ" data-toggle="tab" href="#rDetail" role="tab">安装增加费</a>
-                                    </li>
+                                    </li>-->
                                 </ul>
                                 <!-- 内容 -->
                                 <div class="tab-content">
@@ -186,7 +186,7 @@
                     </div>
                 </div>
                 <div class="main-side p-0 main-side-right" id="zmhsContent" style="width: 25%; display: none">
-                    <div class="resize" id="sideResize" style="width: 1%; height: 100%; resize:horizontal; cursor: w-resize; float: left; background: #F1F1F1"></div>
+                    <div class="resize" id="rightResize" style="width: 1%; height: 100%; resize:horizontal; cursor: w-resize; float: left; background: #F1F1F1"></div>
                     <div style="width: 99%; float: left">
                         <div class="main-data-top-fluid" id="mainSpread">
                         </div>
@@ -590,6 +590,7 @@
 <script type="text/javascript" src="/web/building_saas/complementary_ration_lib/js/ration_coe.js"></script>
 <script type="text/javascript" src="/web/building_saas/complementary_ration_lib/js/ration_assist.js"></script>
 <script type="text/javascript" src="/web/building_saas/complementary_ration_lib/js/ration_installation.js"></script>
+<script src="/public/web/slideResize.js"></script>
 <script src="/web/building_saas/complementary_ration_lib/js/coe.js"></script>
 <!--endinject-->
 <script type="text/javascript">

+ 16 - 10
web/building_saas/complementary_ration_lib/js/coe.js

@@ -3,21 +3,27 @@
  */
 //modiyied by zhong on 2017/9/21
 
+let moduleName = 'compleRation';
+$(document).ready(function () {
+    //定额表与子目换算表
+    let rightElesObj = {};
+    rightElesObj.resize = $('#rightResize');
+    rightElesObj.parent = $('#dataRow');
+    rightElesObj.left = $('#mainContent');
+    rightElesObj.right = $('#zmhsContent');
+    SlideResize.horizontalSlide(moduleName, rightElesObj, {min: 200, max: `$('#dataRow').width() - $('#leftContent').width() - 200`}, function () {
+        pageOprObj.refreshAllBooks();
+    });
+});
+
 $('#zmhs').click(function () {
     if(!$(this).hasClass('active')){
         $(this).addClass('active');
         $('#mainContent').css('width', '50%');
         $('#zmhsContent').show();
-      /*  loadSize(sideResizeEles, 'width', function(){
-
-        });*/
-        if(!coeOprObj.workBook){
-            pageObj.initPage();
-        }
-        coeOprObj.workBook.refresh();
-        gljAdjOprObj.workBook.refresh();
-        rationOprObj.workBook.refresh();
-        rationGLJOprObj.sheet.getParent().refresh();
+        SlideResize.loadHorizonWidth(moduleName, [$('#mainContent'), $('#zmhsContent')], function () {
+            pageOprObj.refreshAllBooks();
+        });
     } else {
         $(this).removeClass('active');
         $('#mainContent').css('width', '75%')

+ 38 - 35
web/building_saas/complementary_ration_lib/js/ration.js

@@ -78,12 +78,12 @@ let rationOprObj = {
         let me = rationOprObj,
             sheetGLJ = rationGLJOprObj.sheet, settingGLJ = rationGLJOprObj.setting,
             sheetCoe = rationCoeOprObj.sheet, settingCoe = rationCoeOprObj.setting,
-            sheetAss = rationAssistOprObj.sheet, settingAss = rationAssistOprObj.setting,
-            sheetInst = rationInstObj.sheet, settingInst = rationInstObj.setting;
+            sheetAss = rationAssistOprObj.sheet, settingAss = rationAssistOprObj.setting;
+            //sheetInst = rationInstObj.sheet, settingInst = rationInstObj.setting;
         sheetCommonObj.cleanData(sheetGLJ, settingGLJ, -1);
         sheetCommonObj.cleanData(sheetCoe, settingCoe, -1);
         sheetCommonObj.cleanData(sheetAss, settingAss, -1);
-        sheetCommonObj.cleanData(sheetInst, settingInst, -1);
+        //sheetCommonObj.cleanData(sheetInst, settingInst, -1);
         let cacheSection = me.getCache();
         if (cacheSection && row < cacheSection.length) {
             rationGLJOprObj.getGljItems(cacheSection[row], function () {
@@ -101,13 +101,13 @@ let rationOprObj = {
                 }
             });
             rationAssistOprObj.getAssItems(cacheSection[row]);
-            rationInstObj.getInstItems(cacheSection[row], function () {
+            /*rationInstObj.getInstItems(cacheSection[row], function () {
                 if (focusOnSection){
                     sectionTreeObj.workBook.focus(true);
                 } else {
                     me.workBook.focus(true);
                 }
-            });
+            });*/
         }
         else {
             rationGLJOprObj.currentRationItem = null;
@@ -149,7 +149,7 @@ let rationOprObj = {
                         cacheSection[j]["rationGljList"] = rstData.ops[i]["rationGljList"];
                         cacheSection[j]["rationCoeList"] = rstData.ops[i]["rationCoeList"];
                         cacheSection[j]["rationAssList"] = rstData.ops[i]["rationAssList"];
-                        cacheSection[j]["rationInstList"] = rstData.ops[i]["rationInstList"];
+                        //cacheSection[j]["rationInstList"] = rstData.ops[i]["rationInstList"];
                     }
                 }
             }
@@ -164,7 +164,7 @@ let rationOprObj = {
                                 cacheSection[j]['rationGljList'] : [];
                         updateArr[i]['rationCoeList'] = cacheSection[j]['rationCoeList'] ? cacheSection[j]['rationCoeList'] : [];
                         updateArr[i]['rationAssList'] = cacheSection[j]['rationAssList'];
-                        updateArr[i]['rationInstList'] = cacheSection[j]['rationInstList'];
+                        //updateArr[i]['rationInstList'] = cacheSection[j]['rationInstList'];
                         cacheSection[j] = updateArr[i];
                     }
                 } else {
@@ -175,7 +175,7 @@ let rationOprObj = {
                                 cacheSection[j]['rationGljList'] : [];
                         updateArr[i]['rationCoeList'] = cacheSection[j]['rationCoeList'] ? cacheSection[j]['rationCoeList'] : [];
                         updateArr[i]['rationAssList'] = cacheSection[j]['rationAssList'];
-                        updateArr[i]['rationInstList'] = cacheSection[j]['rationInstList'];
+                        //updateArr[i]['rationInstList'] = cacheSection[j]['rationInstList'];
                         cacheSection[j] = updateArr[i];
                     }
                 }
@@ -664,8 +664,8 @@ let rationOprObj = {
         let me = rationOprObj,
             sheetGLJ = rationGLJOprObj.sheet, settingGLJ = rationGLJOprObj.setting,
             sheetCoe = rationCoeOprObj.sheet, settingCoe = rationCoeOprObj.setting,
-            sheetAss = rationAssistOprObj.sheet, settingAss = rationAssistOprObj.setting,
-            sheetInst = rationInstObj.sheet, settingInst = rationInstObj.setting;
+            sheetAss = rationAssistOprObj.sheet, settingAss = rationAssistOprObj.setting;
+            //sheetInst = rationInstObj.sheet, settingInst = rationInstObj.setting;
         if (me.workBook) {
             if (me.currentRations && me.currentRations["_SEC_ID_" + sectionID] && me.currentRations["_SEC_ID_" + sectionID].length > 0) {
                 let cacheSection = me.currentRations["_SEC_ID_" + sectionID];
@@ -680,18 +680,18 @@ let rationOprObj = {
                         sheetCommonObj.cleanData(sheetGLJ, settingGLJ, -1);
                         sheetCommonObj.cleanData(sheetCoe, settingCoe, -1);
                         sheetCommonObj.cleanData(sheetAss, settingAss, -1);
-                        sheetCommonObj.cleanData(sheetInst, settingInst, -1);
+                        //sheetCommonObj.cleanData(sheetInst, settingInst, -1);
                         rationGLJOprObj.getGljItems(cacheSection[row]);
                         rationCoeOprObj.getCoeItems(cacheSection[row]);
                         rationAssistOprObj.getAssItems(cacheSection[row]);
-                        rationInstObj.getInstItems(cacheSection[row]);
+                        //rationInstObj.getInstItems(cacheSection[row]);
                     }
                     else {
                         rationGLJOprObj.currentRationItem = null;
                         sheetCommonObj.cleanData(sheetGLJ, settingGLJ, -1);
                         sheetCommonObj.cleanData(sheetCoe, settingCoe, -1);
                         sheetCommonObj.cleanData(sheetAss, settingAss, -1);
-                        sheetCommonObj.cleanData(sheetInst, settingInst, -1);
+                        //sheetCommonObj.cleanData(sheetInst, settingInst, -1);
                         sheetCommonObj.setDynamicCombo(sheetAss, 0, 5, sheetAss.getRowCount(), rationAssistOprObj.setting.comboItems, false, false);
                     }
                 }
@@ -705,36 +705,39 @@ let rationOprObj = {
                 sheetCommonObj.cleanSheet(sheetGLJ, settingGLJ, -1);
                 sheetCommonObj.cleanSheet(sheetCoe, settingCoe, -1);
                 sheetCommonObj.cleanSheet(sheetAss, settingAss, -1);
-                sheetCommonObj.cleanSheet(sheetInst, settingInst, -1);
+                //sheetCommonObj.cleanSheet(sheetInst, settingInst, -1);
             }
             //--- me.workBook.focus(true);
         }
         sectionTreeObj.workBook.focus(true);
     },
     sortByCode: function(arr){
-        arr.sort(function (a, b) {
-            let rst = 0;
-            let splitA = a.code.split('-'),
-                splitB = b.code.split('-');
-            if(splitA[0] > splitB[0]){
-                rst = 1;
-            }
-            else if(splitA[0] < splitB[0]){
-                rst = -1;
-            }
-            else {
-                if(splitA[1] && splitB[1]){
-                    let floatA = parseFloat(splitA[1]),
-                        floatB = parseFloat(splitB[1]);
-                    if(floatA > floatB){
-                        rst = 1;
-                    }
-                    else if(floatA < floatB){
-                        rst = -1;
-                    }
+        function recurCompare(a, b, index){
+            if (a[index] && !b[index]) {
+                return 1;
+            } else if (!a[index] && b[index]) {
+                return -1;
+            } else if (a[index] && b[index]) {
+                let aV = a[index],
+                    bV = b[index];
+                if (!isNaN(aV) && !isNaN(bV)) {
+                    aV = parseFloat(a[index]);
+                    bV = parseFloat(b[index]);
+                }
+                if (aV > bV) {
+                    return 1;
+                } else if (aV < bV) {
+                    return -1;
+                } else {
+                    return recurCompare(a, b, index + 1);
                 }
             }
-            return rst;
+            return 0;
+        }
+        arr.sort(function (a, b) {
+            let aArr = a.code.split('-'),
+                bArr = b.code.split('-');
+            return recurCompare(aArr, bArr, 0);
         });
     },
     saveInString(datas){

+ 1 - 1
web/building_saas/complementary_ration_lib/js/ration_assist.js

@@ -7,7 +7,7 @@ var rationAssistOprObj = {
     setting: {
         header:[
             {headerName:"调整名称",headerWidth:200,dataCode:"name", dataType: "String", hAlign: "left"},
-            {headerName:"辅助定额号",headerWidth:120,dataCode:"assistCode", dataType: "String", hAlign: "center"},
+            {headerName:"辅助定额号",headerWidth:120,dataCode:"assistCode", dataType: "String", hAlign: "center", formatter: '@'},
             {headerName:"标准值",headerWidth:100,dataCode:"stdValue", dataType: "String", hAlign: "right"},
             {headerName:"步距",headerWidth:100,dataCode:"stepValue", dataType: "String", hAlign: "right"},
             {headerName:"精度",headerWidth:80,dataCode:"decimal",  dataType: "String", hAlign: "right"},

+ 19 - 0
web/building_saas/complementary_ration_lib/js/section_tree.js

@@ -2,6 +2,25 @@
  * Created by Zhong on 2017/12/18.
  */
 let pageOprObj = {
+    refreshAllBooks: function () {
+        if (sectionTreeObj.workBook) {
+            sectionTreeObj.workBook.refresh();
+        }
+        if (rationOprObj.workBook) {
+            rationOprObj.workBook.refresh();
+        }
+        if (coeOprObj.workBook) {
+            coeOprObj.workBook.refresh();
+        } else {
+            pageObj.initPage();
+        }
+        if (gljAdjOprObj.workBook) {
+            gljAdjOprObj.workBook.refresh();
+        }
+        if (rationGLJOprObj.sheet.getParent()) {
+            rationGLJOprObj.sheet.getParent().refresh();
+        }
+    },
     rationLibName : null,
     rationLibId : null,
     gljLibId: gljLibId,

+ 2 - 1
web/building_saas/css/custom.css

@@ -259,6 +259,7 @@ legend.legend{
 }
 
 .item_spread{
-    width: 30%;
+    width: 29.8%;
     float: left;
+    background: #F1F1F1
 }

+ 6 - 5
web/building_saas/main/html/main.html

@@ -142,7 +142,7 @@
                           <div class="resize"></div>
                           <div class="bottom-content">
                               <ul class="nav nav-tabs" role="tablist">
-                                  <li class="nav-item">
+                                  <li class="nav-item" id="GLJ_div">
                                       <a class="nav-link active" id="linkGLJ" data-toggle="tab" href="#subSpread" role="tab">人材机</a>
                                   </li>
                               <!--    <li class="nav-item">
@@ -151,7 +151,7 @@
                                   <li class="nav-item">
                                       <a class="nav-link" id="linkFZDE" data-toggle="tab" href="#subSpread" role="tab">辅助定额</a>
                                   </li>-->
-                                  <li class="nav-item">
+                                  <li class="nav-item" id = "ZMHS_div">
                                       <a class="nav-link" id="linkZMHS" data-toggle="tab" href="#subSpread" role="tab">子目换算</a>
                                   </li>
                                   <li class="nav-item" id="AZZJF_div" style="display: none">
@@ -163,10 +163,10 @@
                                   <li class="nav-item">
                                       <a class="nav-link" id="linkJSCX" data-toggle="tab" href="#subSpread" role="tab">计算程序</a>
                                   </li>
-                                  <li class="nav-item">
+                                 <!-- <li class="nav-item">   2018-11-08  新需求,隐藏说明信息
                                       <a class="nav-link" data-toggle="tab" href="#comments" role="tab" id="linkComments">说明信息</a>
-                                  </li>
-                                  <li class="nav-item">
+                                  </li>-->
+                                  <li class="nav-item" id = "TZJNR_div">
                                       <a class="nav-link" id="linkTZJNR" data-toggle="tab" href="#subSpread" role="tab">特征及内容</a>
                                   </li>
                               </ul>
@@ -174,6 +174,7 @@
                               <div class="tab-content" id="tabCon">
                                   <div class="tab-pane active" id="subItems" role="tabpanel">
                                       <div class="main-data-bottom ovf-hidden" id="subSpread" style="display: none" tabindex="0"></div>
+                                      <div class="main-data-bottom ovf-hidden" id="rgResize" style="width: 0.2%; height: 100%; resize:horizontal; cursor: w-resize; float: left; background: #F1F1F1"></div>
                                       <div class="main-data-bottom ovf-hidden item_spread" id="replaceM" style="display: none" ></div>
                                       <div class="main-data-bottom ovf-hidden" id="tabZMHS" style="display: none">
                                           <div class=" main-data-bottom ovf-hidden" style="width: 60%; float: left; margin: 0; padding:0;" id="coeSpread"></div>

+ 34 - 2
web/building_saas/main/js/controllers/material_controller.js

@@ -2,6 +2,7 @@
  * Created by zhang on 2018/9/12.
  */
 let MaterialController = {
+    subSpreadDivWidth:"",
     //规则相关映射
     rule1: function (node) {
         let itemText = node.data.itemCharacterText;
@@ -164,11 +165,15 @@ let MaterialController = {
     showReplaceDiv:function (node) {
         $("#subSpread").addClass("ration_glj_spread");
         $("#replaceM").show();
-        if(node) this.showReplaceSpread(node);//如果不是只刷新页面
+        $("#rgResize").show();// 拖动调整大小功能添加
+        // 2018-11-07 需求变更,这个项目特征替换表格暂时隐藏不删除,以后可能还要用,先把项目初始化这句注释掉
+       // if(node) this.showReplaceSpread(node);//如果不是只刷新页面
+        this.showItemCharacterText(node);//只显示文本
         refreshSubSpread();
     },
     hideReplaceDiv:function(){
         $("#subSpread").removeClass("ration_glj_spread");
+        $("#subSpread").css("width",""); //左右拖动调整表格大小的时候会设置css属性,所以隐藏这个div的时候也要把这个属性给去掉
         $("#replaceM").hide();
         refreshSubSpread();
     },
@@ -201,6 +206,22 @@ let MaterialController = {
         sheetCommonObj.showData(this.sheet, this.setting,this.datas);
         this.sheet.setRowCount(this.datas.length);
     },
+    showItemCharacterText:function (node) {
+        let text="";
+        let selected = node?node:projectObj.project.mainTree.selected;
+        let parent = selected.parent;
+        if(selected&&parent){
+            text = parent.data.itemCharacterText?parent.data.itemCharacterText.replace(/\n/g,"<br>"):"";
+        }
+        if(text == "") {//为空的时候不显示
+            $("#replaceM").hide();
+            $("#subSpread").removeClass("ration_glj_spread");
+            $('#subSpread').css('width','');
+            return;
+        }
+        $('#subSpread').css('width',MaterialController.subSpreadDivWidth);
+        $("#replaceM").html(text);
+    },
     getItems:function(characterText){
         if(!characterText) return;
         let strArray =  characterText.split(/\n/);
@@ -238,4 +259,15 @@ let MaterialController = {
             if(!_.isEmpty(doc)) this.postReplace([{glj:ration_glj,doc:doc}]);
         }
     }
-};
+};
+
+let rg_sideResizeEles = {};
+rg_sideResizeEles.id = 'tabRG';
+rg_sideResizeEles.resize = $('#rgResize');
+rg_sideResizeEles.nearElement = $('#subSpread');
+rg_sideResizeEles.farElement = $('#replaceM');
+rg_sideResizeEles.nav = null;
+slideResize(rg_sideResizeEles, {min: 100, max: $('#tabCon').width()-100}, 'width', function(){
+    MaterialController.subSpreadDivWidth = $('#subSpread').css('width');
+    refreshSubSpread();
+});

+ 2 - 2
web/building_saas/main/js/views/glj_view.js

@@ -568,8 +568,8 @@ var gljOprObj = {
         this.detailSheet.getRange(-1, 0, -1, this.detailSetting.header.length).locked(true);//锁住工程量明细的所有列
     },
     showRationGLJData: function (node) {
-        var gljList = [];
-        var ration_glj = projectObj.project.ration_glj;
+        let gljList = [];
+        let ration_glj = projectObj.project.ration_glj;
         node = node ? node : projectObj.project.mainTree.selected;
         if (node.sourceType == ModuleNames.ration) {
             if(node.data.type==rationType.gljRation){

+ 22 - 1
web/building_saas/main/js/views/main_tree_col.js

@@ -255,7 +255,11 @@ let MainTreeCol = {
              if(node.sourceType == ModuleNames.bills &&projectObj.ifItemCharHiden(setting)){//清单、并且项目特征列隐藏的时候悬浮提示
                 tips = node.data.itemCharacterText?node.data.itemCharacterText:'';
              }
-                    let dynamicCombo = sheetCommonObj.getTipsCombo(true,tips,setting);//sheetCommonObj.getDynamicCombo(true);
+            if(node.sourceType == ModuleNames.ration && node.data.type == rationType.ration){//定额类型时,显示人材机,工作内容等
+                //这里的人材机需要进行过滤,在初始化时组装会影响性能,应实时显示
+                tips = MainTreeCol.getRationUnitTips
+            }
+             let dynamicCombo = sheetCommonObj.getTipsCombo(true,tips,setting,node);//sheetCommonObj.getDynamicCombo(true);
             dynamicCombo.itemHeight(10).items(['m', 'm2', 'm3', 'km', 't', 'kg', '台班', '工日', '昼夜', '元', '项', '处', '个', '件',
                 '根', '组', '系统', '台', '套', '株', '丛', '缸', '支', '只', '块', '座', '对', '份', '樘', '攒', '榀']).editable(true);
             return dynamicCombo;
@@ -409,6 +413,23 @@ let MainTreeCol = {
             }
             ;
         }
+    },
+    getRationUnitTips:function (node) {
+        let tips="";
+        let ration_glj = projectObj.project.ration_glj;
+        let gljList = gljOprObj.filterGljByRation(node.data, ration_glj.datas);
+        for(let glj of gljList){
+            tips += `${glj.code} ${glj.name}${glj.specs ? '&nbsp;&nbsp;&nbsp;' + glj.specs : ''}&nbsp;&nbsp&nbsp;${glj.unit}&nbsp;&nbsp;&nbsp;${glj.quantity}<br>`;
+        }
+        if(node.data.content && node.data.content.toString().trim() !== ''){
+            tips += `工作内容:<br>`;
+            tips += `${node.data.content.replace(/\n/g,"<br>")}<br>`;
+        }
+        if(node.data.annotation && node.data.annotation.toString().trim() !== ''){
+            tips += `附注:<br>`;
+            tips += `${node.data.annotation.replace(/\n/g,"<br>")}<br>`;
+        }
+        return tips
     }
 };
 

+ 4 - 8
web/building_saas/main/js/views/project_view.js

@@ -1324,14 +1324,10 @@ var projectObj = {
                             }
                         }
                         getGLJData('insert');// ProjectController.addRation(project, controller, rationType.volumePrice);
-                    }/*,
-                    visible: function(key, opt){
-                        var selected = project.mainTree.selected;
-                        if(selected){
-                          return canInsertRationNode(selected);
-                        }
+                    },
+                    visible: function(key, opt){//2018-11-08  新需求,这个按钮先隐藏,有需要再放开
                         return false;
-                    }*/
+                    }
                 },
                 "spr2": '--------',
                 "calc_installation_fee": {
@@ -1466,7 +1462,7 @@ var projectObj = {
     // 计算node及node的所有父项
     converseCalculateBills: function (node) {
         projectObj.project.calcProgram.calcAndSave(node);
-},
+    },
 
     // 获取上次退出时的焦点位置
     loadFocusLocation: function() {

+ 8 - 0
web/building_saas/main/js/views/sub_view.js

@@ -57,6 +57,14 @@ let subObj = {
             disableSpread(contentOprObj.workBook);
             disableSpread(characterOprObj.workBook);
         }
+    },
+    initNavItem:function (node) {
+     /*   1、造价书选中行类别是“大项费用”、“分部”、“分项”、“清单”时,显示按钮“工程量明细”、“计算程序”、“特征及内容”,默认打开“计算程序”。
+          2、选中行类别是“定额”、“量价”、“人材机”时,显示按钮“人材机”、“子目换算”、“工程量明细”、“计算程序”,默认打开“人材机”。
+     */
+
+
+
     }
 };
 

+ 19 - 0
web/building_saas/pm/html/project-management-share.html

@@ -105,3 +105,22 @@
         </div>
     </div>
 </div>
+<!--取消分享-->
+<div class="modal fade" id="cancelShare" 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>
+            <div class="modal-footer">
+                <a href="javascript:void(0);" class="btn btn-primary" data-dismiss="modal" id="cancelShareConfirm">确定</a>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+            </div>
+        </div>
+    </div>
+</div>

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

@@ -676,6 +676,7 @@
 <script>GC.Spread.Sheets.LicenseKey = '<%- LicenseKey %>';</script>
 <!-- inject:js -->
 <script src="/web/building_saas/js/global.js"></script>
+<script src="/public/web/uuid.js"></script>
 <script src="/public/web/PerfectLoad.js"></script>
 <script src="/public/web/date_util.js"></script>
 <script src="/web/building_saas/pm/js/pm_tree.js"></script>

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

@@ -39,6 +39,18 @@ function isDef(v) {
     return typeof v !== 'undefined' && v !== null;
 }
 
+let keyupTime = 0,
+    delayTime = 500;
+function delayKeyup(callback) {
+    let nowTime = Date.now();
+    keyupTime = nowTime;
+    setTimeout(function () {
+        if (nowTime - keyupTime == 0) {
+            callback();
+        }
+    }, delayTime);
+}
+
 const projTreeObj = {
     tree: null,
     workBook: null,
@@ -289,15 +301,17 @@ const projTreeObj = {
                     icon: 'fa-share',
                     disabled: function () {
                         let selectedItem = projTreeObj.tree.selected;
-                        return !(selectedItem && selectedItem.data.projType === projectType.tender);
+                        return !selectedItem;
+                        //return !(selectedItem && selectedItem.data.projType === projectType.tender);
                     },
                     callback: function (key, opt) {
                         $('#sharePhone').val('');
                         $('#share-info').hide();
                         $('#share').find('.card').hide();
                         $('#share').modal('show');
-                        $('#allowCopy').prop('checked', false);
-                        $('#allowCopyHint').hide();
+                        //默认允许拷贝
+                        $('#allowCopy').prop('checked', true);
+                        $('#allowCopyHint').show();
                         setTimeout(function () {
                             $('#sharePhone').focus();
                         }, 200);
@@ -1697,7 +1711,6 @@ function init() {
                 data.feeStandardName = data.property.feeStandardName || '';
             }
         }
-        console.log(datas);
         CommonAjax.post('/options/getOptions', [], function (rstData) {
             projTreeObj.setting.style.selectedColor = rstData.COLOROPTS.SELECTED.backColor;
             projTreeObj.tree = pmTree.createNew(projTreeObj.setting, datas);
@@ -3349,7 +3362,9 @@ function shareTender(){
     });
 }
 $('#sharePhone').on('keyup',function () {
-    shareTender();
+    delayKeyup(function () {
+        shareTender();
+    });
 });
 //确认分享
 $('#share-confirm').click(function(){

+ 163 - 64
web/building_saas/pm/js/pm_share.js

@@ -13,6 +13,8 @@ const pmShare = (function () {
     let spreadObj = {workBook: null, sheet: null};
     //项目分享类型,由别人分享给自己的,和自己分享给别人的
     const shareType = {receive: 'receive', shareTo: 'shareTo'};
+    //操作类型
+    const oprType = {copy: 'copy', cancel: 'cancel'};
     let tree = null;
     const treeSetting = {
         tree: {
@@ -27,7 +29,8 @@ const pmShare = (function () {
         {name: '工程列表', dataCode: 'name', width: 0.55, rateWidth: 0.55, vAlign: 'center', hAlign: 'left'},
         {name: '由...分享', dataCode: 'from', width: 0.15, rateWidth: 0.15, vAlign: 'center', hAlign: 'left'},
         {name: '分享给...', dataCode: 'to', width: 0.15, rateWidth: 0.15, vAlign: 'center', hAlign: 'left'},
-        {name: '操作', dataCode: 'operation', width: 0.15, rateWidth: 0.15, vAlign: 'center', hAlign: 'left'},
+        {name: '拷贝工程', dataCode: 'copy', width: 0.075, rateWidth: 0.075, vAlign: 'center', hAlign: 'left'},
+        {name: '清除', dataCode: 'cancel', width: 0.075, rateWidth: 0.075, vAlign: 'center', hAlign: 'left'},
     ];
     const spreadOpts = {
         workBook: {
@@ -106,11 +109,20 @@ const pmShare = (function () {
             sheet.setRowHeight(0, 40, GC.Spread.Sheets.SheetArea.colHeader);
             let spreadWidth = getWorkBookWidth();
             for(let i = 0, len = headers.length; i < len; i++){
-                sheet.setValue(0, i, headers[i].name, GC.Spread.Sheets.SheetArea.colHeader);
                 sheet.setColumnWidth(i, spreadWidth * headers[i].width, GC.Spread.Sheets.SheetArea.colHeader);
                 if(headers[i].formatter){
                     sheet.setFormatter(-1, i, headers[i].formatter);
                 }
+                if(headers[i].dataCode === oprType.copy){
+                    //合并列
+                    sheet.addSpan(0, i, 1, 2, GC.Spread.Sheets.SheetArea.colHeader);
+                    sheet.setValue(0, i, '操作', GC.Spread.Sheets.SheetArea.colHeader);
+                    continue;
+                }
+                if(headers[i].dataCode === '' || headers[i].dataCode === 'feeRateFile_delete'){
+                    continue;
+                }
+                sheet.setValue(0, i, headers[i].name, GC.Spread.Sheets.SheetArea.colHeader);
                 sheet.getRange(-1, i, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[headers[i]['hAlign']]);
                 sheet.getRange(-1, i, -1, 1).vAlign(GC.Spread.Sheets.VerticalAlign[headers[i]['vAlign']]);
             }
@@ -315,8 +327,9 @@ const pmShare = (function () {
             //点击单位工程
             if(node.data.projType === projectType.tender && withingClickArea()){
                 let newTab = window.open('about:blank');
-                BeforeOpenProject(node.data.ID, {'fullFolder': GetFullFolder(node.parent)}, function () {
-                    let mainUrl = `/main?project=${node.data.ID}`;
+                //打开项目的实际ID
+                BeforeOpenProject(node.data.actualTreeInfo.ID, {'fullFolder': GetFullFolder(node.parent)}, function () {
+                    let mainUrl = `/main?project=${node.data.actualTreeInfo.ID}`;
                     CommonAjax.get(mainUrl, [], function () {
                         newTab.location.href = mainUrl;
                     });
@@ -374,8 +387,7 @@ const pmShare = (function () {
         }
         return new TreeNodeCellType();
     }
-    //
-    //
+    //互动单元格
     function getInteractionCell() {
         let InteractionCell = function () {
         };
@@ -421,8 +433,8 @@ const pmShare = (function () {
                     }
                 }
                 //操作
-                else if(dataCode === 'operation'){
-                    if(node.data.operation === '添加分享'){
+                else if(dataCode === oprType.copy){
+                   /* if(node.data.copy === '添加分享'){
                         $('#sharePhone').val('');
                         $('#share-info').hide();
                         $('#share').find('.card').hide();
@@ -430,32 +442,18 @@ const pmShare = (function () {
                         $('#allowCopy').prop('checked', false);
                         $('#allowCopyHint').hide();
                     }
-                    else if(node.data.operation === '拷贝工程'){
+                    else*/
+                    if(node.data.copy === '拷贝工程'){
                         $('#copyShare').modal('show');
                     }
-                    else {
-                        return;
-                    }
-                }
-                //清除
-                else if(dataCode === 'delete'){
-                    gcTreeObj.oprProj('#delPoj', node)
-                }
-                //恢复单价文件
-                else if(dataCode === 'unitPriceFile'){
-                    gcTreeObj.recoveryUnitPrc(node);
-                }
-                //清除单价文件
-                else if(dataCode === 'unitPriceFile_delete'){
-                    gcTreeObj.deleteUnitPrc(node);
                 }
-                //恢复费率文件
-                else if(dataCode === 'feeRateFile'){
-                    gcTreeObj.recoveryFeeRate(node);
-                }
-                //清除费率文件
-                else if(dataCode === 'feeRateFile_delete'){
-                    gcTreeObj.deleteFeeRate(node);
+                else if (dataCode === oprType.cancel) {
+                    if (node.data.cancel === '清除') {
+                        let $p = $('<p>').text(`点“确定”按钮,确认清除分享文件 “${node.data.name}”。`);
+                        $('#cancelShare').find('.modal-body').empty();
+                        $('#cancelShare').find('.modal-body').append($p);
+                        $('#cancelShare').modal('show');
+                    }
                 }
             }
         };
@@ -552,6 +550,7 @@ const pmShare = (function () {
         });
     }
     const foreColor = '#007bff';
+    const cancelForeColor = 'red';
     //显示树结构数据
     //@param {Array}nodes {Array}headers @return {void}
     function showTreeData(nodes, headers){
@@ -565,12 +564,18 @@ const pmShare = (function () {
                     sheet.getRange(-1, j, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[headers[j]['hAlign']]);
                     sheet.getRange(-1, j, -1, 1).vAlign(GC.Spread.Sheets.VerticalAlign[headers[j]['vAlign']]);
                     let dataCode = headers[j].dataCode;
-                    if(dataCode === 'operation'){
+                    if(dataCode === oprType.copy){
                         let style = new GC.Spread.Sheets.Style();
                         style.foreColor = foreColor;
                         sheet.setStyle(i, j, style);
                         sheet.getCell(i, j).cellType(getInteractionCell());
                     }
+                    else if (dataCode === oprType.cancel) {
+                        let style = new GC.Spread.Sheets.Style();
+                        style.foreColor = cancelForeColor;
+                        sheet.setStyle(i, j, style);
+                        sheet.getCell(i, j).cellType(getInteractionCell());
+                    }
                     else if(dataCode === 'from'){
                         if(nodes[i].data.shareType && nodes[i].data.shareType === shareType.receive){
                             let style = new GC.Spread.Sheets.Style();
@@ -587,51 +592,122 @@ const pmShare = (function () {
                             sheet.getCell(i, j).cellType(getInteractionCell());
                         }
                     }
-                   /* else if(dataCode === 'delete' || dataCode === 'unitPriceFile_delete' || dataCode === 'feeRateFile_delete'){
-                        let style = new GC.Spread.Sheets.Style();
-                        style.foreColor = me.setting.style.delForeColor;
-                        sheet.setStyle(-1, j, style);
-                    }*/
                     sheet.setValue(i, j, nodes[i].data[dataCode] ? nodes[i].data[dataCode] : '');
-                    //me.setCellValue({row: i, col: j}, nodes[i]);
                 }
             }
         };
         renderSheetFunc(sheet, fuc);
     }
-    //将数据转换为可成树的数据,因为获取的数据不来自同一棵树
+    //同一棵树,可能存在相同数据显示多条的问题(传入的datas中不存在相同数据),将真实树结构数据存在actualTreeInfo中,外部树结构数据用uuid重置。
     //@param {Array}datas
-    function buildTreeDatas(datas){
-        let IDMap = {};
-        for(let i = 0; i < datas.length; i++){
-            let data = datas[i];
-            let nextData = datas[i + 1];
+    function setTreeInfo(datas) {
+        let IDMapping = {};
+        for (let data of datas) {
+            IDMapping[data.ID] = uuid.v1();
+        }
+        for (let data of datas) {
+            data.actualTreeInfo = {ID: data.ID, ParentID: data.ParentID, NextSiblingID: data.NextSiblingID};
+            data.ID = IDMapping[data.ID];
+            data.NextSiblingID = IDMapping[data.NextSiblingID] ? IDMapping[data.NextSiblingID] : -1;
+            data.ParentID = IDMapping[data.ParentID] ? IDMapping[data.ParentID] : -1;
+        }
+    }
+    //整理同层数据的NextSiblingID,ParentID
+    //@param {Array}datas {Number || String}pid @return {void}
+    function sortSameDepthData(datas, pid) {
+        for (let i = 0; i < datas.length; i++) {
+            let data = datas[i],
+                nextData = datas[i + 1];
             data.NextSiblingID = nextData ? nextData.ID : -1;
-            data.ParentID = -1;
-            IDMap[data.ID] = data;
-            if(data.shareType === shareType.receive){
-                if(data.userInfo){
-                    data.from = `由 ${data.userInfo.name} 分享`;
-                    data.to = '分享给 我';
-                    data.operation = isAllowCopy(userID, data) ? '拷贝工程' : '';
+            data.ParentID = pid;
+        }
+    }
+    //给项目设置分享信息:由xx分享、分享给我、可进行的操作,含有userInfo信息的文件为他人直接分享的文件,他人分享父级文件,子文件不含有userInfo信息
+    //@param {Array}datas @return {void}
+    function setShareInfo(datas) {
+        for (let data of datas) {
+            if (data.userInfo) {
+                data.from = `由 ${data.userInfo.name} 分享`;
+                data.to = '分享给 我';
+                data.cancel = '清除'
+
+                //拷贝操作只允许到单位工程级
+                let tendersCanCopy = isAllowCopy(userID, data);
+                let tenders = data.projType === projectType.tender ? [data] : _.filter(data.children, {projType: projectType.tender});
+                for (let tender of tenders) {
+                    tender.copy = tendersCanCopy ? '拷贝工程' : '';
                 }
             }
-            else {
-                data.from = '由 我 分享';
-                data.to = '分享给...';
-                data.operation = '添加分享';
+        }
+    }
+    //获取可成树的数据
+    //@param {Array}datas @return {Array}
+    function getTreeDatas(groupedDatas, ungroupedDatas){
+        //设置新的树结构数据
+        for (let data of groupedDatas) {
+            setTreeInfo([data].concat(data.children));
+        }
+        let engs = _.filter(ungroupedDatas, {projType: projectType.engineering}),
+            tenders = _.filter(ungroupedDatas, {projType: projectType.tender});
+        for (let data of engs) {
+            setTreeInfo([data].concat(data.children));
+        }
+        setTreeInfo(tenders);
+        let rst = [];
+        //整理树结构
+        sortSameDepthData(groupedDatas, -1);
+        //新建未分类建设项目及单项工程
+        let ungroupedProj = {ID: uuid.v1(), ParentID: -1, NextSiblingID: -1, name: '未分类建设项目', projType: projectType.project};
+        let ungroupedEng = {ID: uuid.v1(), ParentID: ungroupedProj.ID, NextSiblingID: -1, name: '未分类单项工程', projType: projectType.engineering};
+        if (groupedDatas.length > 0) {
+            groupedDatas[groupedDatas.length - 1].NextSiblingID = ungroupedProj.ID;
+        }
+        //将未分类的数据归类
+        sortSameDepthData(engs, ungroupedProj.ID);
+        sortSameDepthData(tenders, ungroupedEng.ID);
+        //未分类单项工程处于同层第一个节点
+        ungroupedEng.NextSiblingID = engs[0] ? engs[0].ID : ungroupedEng.NextSiblingID;
+        let allDatas = groupedDatas.concat(ungroupedDatas);
+        //设置分享信息及操作信息
+        setShareInfo(allDatas);
+        for (let data of allDatas) {
+            rst.push(data);
+            if (data.children) {
+                rst = rst.concat(data.children);
             }
         }
+        rst.push(ungroupedProj);
+        rst.push(ungroupedEng);
+        return rst;
+    }
+    //按照时间排序
+    //@param {Array}datas @return {void}
+    function sortByDate(datas){
+        datas.sort(function (a, b) {
+            let shareInfoA = _.find(a.shareInfo, {userID}),
+                shareInfoB = _.find(b.shareInfo, {userID});
+            let aV = shareInfoA ? Date.parse(shareInfoA.shareDate) : 0,
+                bV = shareInfoB ? Date.parse(shareInfoB.shareDate) : 0;
+            //时间越晚越靠前
+            if (aV > bV) {
+                return -1;
+            } else if (aV < bV) {
+                return 1;
+            }
+            return 0;
+        });
     }
     //建立树
     //@return void
     function initShareTree(){
         $.bootstrapLoading.start();
         //获取分享数据
-        CommonAjax.post('/pm/api/getShareProjects', {user_id: userID}, function (rstData) {
-            let projDatas = rstData.receive.concat(rstData.share);
-            buildTreeDatas(projDatas);
-            tree = pmTree.createNew(treeSetting, projDatas);
+        CommonAjax.post('/pm/api/receiveProjects', {user_id: userID}, function (rstData) {
+            // 排序 --分享的文件按照时间先后顺序排序,分享文件下的子文件,按照原本树结构显示,不需要排序
+            sortByDate(rstData.grouped);
+            sortByDate(rstData.ungrouped);
+            let treeDatas = getTreeDatas(rstData.grouped, rstData.ungrouped);
+            tree = pmTree.createNew(treeSetting, treeDatas);
             console.log(tree);
             tree.selected = tree.items[0];
             showTreeData(tree.items, headers);
@@ -718,7 +794,7 @@ const pmShare = (function () {
             return;
         }
         let copyMap = {copy: null, update: null};
-        let newName = `${selected.data.name} (${selected.data.userInfo.name}分享拷贝)`;
+        let newName = getCopyName(selected);
         //获取单项工程的单位工程
         let tenderQuery = {$or: [{deleteInfo: null}, {'deleteInfo.deleted': false}], userID: userID, ParentID: engID};
         CommonAjax.post('/pm/api/getProjectsByQuery', {user_id: userID, query: tenderQuery, options: '-_id -property'}, function (rstData) {
@@ -740,7 +816,7 @@ const pmShare = (function () {
             //拷贝
             let copyData = {
                 userID: userID,
-                ID: selected.data.ID,
+                ID: selected.data.actualTreeInfo.ID,
                 NextSiblingID: -1,
                 ParentID: engID,
                 name: newName,
@@ -765,6 +841,18 @@ const pmShare = (function () {
         });
 
     }
+    //获取拷贝后的名称
+    //@param {Object}node @return {String}
+    function getCopyName(node) {
+        //当前单位工程可能没有分享的用户信息,可能他人分享的是父级文件,userInfo在父级文件中
+        let orgName = node.data.name,
+            userInfo = node.data.userInfo;
+        while (node && !userInfo) {
+            node = node.parent;
+            userInfo = node.data.userInfo;
+        }
+        return `${orgName} (${userInfo.name}分享拷贝)`;
+    }
     //事件监听器
     //@return void
     function eventListener(){
@@ -794,14 +882,14 @@ const pmShare = (function () {
         $('#copyShare').on('shown.bs.modal', function () {
             setCopyModal();
             //更改显示名称
-            let newName = `${shareSeleted.data.name} (${shareSeleted.data.userInfo.name}分享拷贝)`;
+            let newName = getCopyName(shareSeleted);
             $('#copyShare_name').html(`拷贝后,工程将重命名为 "<b>${newName}</b>"`);
             $('#copyShare_name').removeClass('text-danger');
         });
         //拷贝工程改变选择建设项目
         $('#copyShare_selectProj').change(function () {
             //更改显示名称
-            let newName = `${shareSeleted.data.name} (${shareSeleted.data.userInfo.name}分享拷贝)`;
+            let newName = getCopyName(shareSeleted);
             $('#copyShare_name').html(`拷贝后,工程将重命名为 "<b>${newName}</b>"`);
             $('#copyShare_name').removeClass('text-danger');
             $('#copyShareProj-info').hide();
@@ -812,7 +900,7 @@ const pmShare = (function () {
         //拷贝工程改变选择单项工程
         $('#copyShare_selectEng').change(function () {
             //更改显示名称
-            let newName = `${shareSeleted.data.name} (${shareSeleted.data.userInfo.name}分享拷贝)`;
+            let newName = getCopyName(shareSeleted);
             $('#copyShare_name').html(`拷贝后,工程将重命名为 "<b>${newName}</b>"`);
             $('#copyShare_name').removeClass('text-danger');
         });
@@ -834,6 +922,17 @@ const pmShare = (function () {
         $('#shareToConfirm').click(function () {
             updateShareInfo(tree.selected);
         });
+        //清除分享
+        $('#cancelShareConfirm').click(function () {
+            $.bootstrapLoading.start();
+            CommonAjax.post('/pm/api/share', {user_id: userID, type: oprType.cancel,  projectID: tree.selected.data.actualTreeInfo.ID, userID: userID}, function (rstData) {
+                $.bootstrapLoading.end();
+                tree.removeNode(tree.selected);
+                showTreeData(tree.items, headers);
+            }, function () {
+                $.bootstrapLoading.end();
+            });
+        });
     }
 
     return {spreadObj, headers, initView, eventListener}

+ 3 - 3
web/building_saas/report/html/rpt_main.html

@@ -3,12 +3,12 @@
     <div class="row">
         <div class="col-lg-3 p-0">
             <div class="print-list">
+                <!--
                 <div class="list-tools d-flex justify-content-center">
-                    <!--
-                        <button class="btn btn-outline-primary btn-sm" data-toggle="modal" data-target="#editForm"><i class="fa fa-cog"></i> 管理报表</button>
-                    -->
+                    <button class="btn btn-outline-primary btn-sm" data-toggle="modal" data-target="#editForm"><i class="fa fa-cog"></i> 管理报表</button>
                     <button class="btn btn-outline-primary btn-sm" onclick="zTreeOprObj.getReportTemplateTree()"><i class="fa fa-cog"></i> 刷新</button>
                 </div>
+                -->
                 <div class="form-list">
                     <ul id="rptTplTree" class="ztree"></ul>
                 </div>

二進制
web/dest/css/logo.png