Преглед изворни кода

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

zhangweicheng пре 1 година
родитељ
комит
2bd8478177

+ 46 - 44
modules/pm/controllers/pm_controller.js

@@ -79,7 +79,7 @@ module.exports = {
         });
     },
     getProjects: async function (req, res) {
-         await ProjectsData.getUserProjects(req.session.sessionUser.id, req.session.sessionCompilation._id, function(err, message, projects){
+        await ProjectsData.getUserProjects(req.session.sessionUser.id, req.session.sessionCompilation._id, function (err, message, projects) {
             if (projects) {
                 callback(req, res, err, message, projects);
             } else {
@@ -156,7 +156,7 @@ module.exports = {
                                 specialResult.newFeeLibID = engineering.tax_group[0].fee_lib.id;
                             }
                             specialResult.billLibs = engineering.bill_lib;
-                            
+
                         }
                     }
                 }
@@ -191,7 +191,7 @@ module.exports = {
         asyncTool.parallel(functions, function (err, result) {
             {
                 if (!err) {
-                    res.json({ error: 0, message: err, data: specialResult});
+                    res.json({ error: 0, message: err, data: specialResult });
                 } else {
                     res.json({ error: 1, message: err, data: null });
                 }
@@ -273,8 +273,8 @@ module.exports = {
                 projInfo.shareState = await pm_facade.getShareState(projectID, userID);
             }
             // 获取项目所属用户
-            projInfo.owner = await userModel.findOne({_id: mongoose.Types.ObjectId(project.userID)}, 'real_name mobile').lean();
-            projInfo.opener = await userModel.findOne({_id: mongoose.Types.ObjectId(userID)}, 'real_name mobile').lean();
+            projInfo.owner = await userModel.findOne({ _id: mongoose.Types.ObjectId(project.userID) }, 'real_name mobile').lean();
+            projInfo.opener = await userModel.findOne({ _id: mongoose.Types.ObjectId(userID) }, 'real_name mobile').lean();
             callback('', consts.projectConst.PROJECT_INFO, project);
         }, function (err) {
             callback(err, consts.projectConst.PROJECT_INFO, {});
@@ -303,7 +303,7 @@ module.exports = {
                 }
                 //读取建设项目的基本信息
                 let basicInfo = await ProjectsData.getBasicInfo(projectID);
-                if(basicInfo !== null){
+                if (basicInfo !== null) {
                     projInfo.property.basicInformation = basicInfo;
                 }
                 //获取单位工程完整目录结构
@@ -340,13 +340,14 @@ module.exports = {
         if (isFree && config[process.env.NODE_ENV].title !== '纵横公路云造价') {
             let renderData = {
                 userAccount: request.session.userAccount,
+                userMobile: request.session.sessionUser.mobile,
                 userID: request.session.sessionUser.id,
                 compilationName: sessionCompilation.name,
                 versionName: request.session.compilationVersion,
 
-                title:getTitle(request.headers.host) 
+                title: getTitle(request.headers.host)
             };
-    
+
             response.render('building_saas/pm/html/blank-project.html', renderData);
         } else {
             let compilationModel = new CompilationModel();
@@ -356,55 +357,56 @@ module.exports = {
             sessionCompilation = request.session.sessionCompilation;
             //更新用户的使用过的费用定额列表
             let isFirst = await pm_facade.isFirst(request.session.sessionUser.id, compilationData._id.toString());
-            
+
             let engineeringLibModel = new EngineeringLibModel();
-    
+
             // 建议估算
             let suggestionValuation = sessionCompilation.suggestion_valuation !== undefined ?
                 sessionCompilation.suggestion_valuation : [];
             suggestionValuation = await engineeringLibModel.getLib(suggestionValuation);
-    
+
             // 可行性估算
             let feasibilityValuation = sessionCompilation.feasibility_valuation !== undefined ?
                 sessionCompilation.feasibility_valuation : [];
             feasibilityValuation = await engineeringLibModel.getLib(feasibilityValuation);
-    
+
             // 估算
             let estimationValuation = sessionCompilation.estimation_valuation !== undefined ?
                 sessionCompilation.estimation_valuation : [];
-                estimationValuation = await engineeringLibModel.getLib(estimationValuation);
-    
+            estimationValuation = await engineeringLibModel.getLib(estimationValuation);
+
             // 概算
             let roughValuation = sessionCompilation.rough_valuation !== undefined ?
                 sessionCompilation.rough_valuation : [];
             roughValuation = await engineeringLibModel.getLib(roughValuation);
-            
+
             // 清单计价
             let billValuation = sessionCompilation.bill_valuation !== undefined ?
                 sessionCompilation.bill_valuation : [];
             billValuation = await engineeringLibModel.getLib(billValuation);
-    
+
             // 定额计价
             let rationValuation = sessionCompilation.ration_valuation !== undefined ?
                 sessionCompilation.ration_valuation : [];
             rationValuation = await engineeringLibModel.getLib(rationValuation);
-    
+
             if (sessionCompilation.name === '四川养护(2013)' || sessionCompilation.name === '部颁2018计价标准') {
                 billValuation = rationValuation;
             }
-    
+
             let absoluteUrl = compilationData.overWriteUrl ? request.app.locals.rootDir + compilationData.overWriteUrl : request.app.locals.rootDir;
             let overWriteUrl = fs.existsSync(absoluteUrl) && fs.statSync(absoluteUrl).isFile() ? compilationData.overWriteUrl : null;
             //欢迎页显示控制
-            let [isShow,context,showTime] = await pm_facade.getWelcomeInfo(sessionCompilation._id,request.session.sessionUser,request.session.compilationVersion.includes('学习'));
+            let [isShow, context, showTime] = await pm_facade.getWelcomeInfo(sessionCompilation._id, request.session.sessionUser, request.session.compilationVersion.includes('学习'));
             const unreadShareList = await pm_facade.getUnreadShareListByCompilation(request.session.sessionUser.id, sessionCompilation._id);
             let renderData = {
                 unreadShareList: JSON.stringify(unreadShareList),
                 isFirst: isFirst,
-                isShow:isShow,
-                context:context,
-                showTime:showTime,
+                isShow: isShow,
+                context: context,
+                showTime: showTime,
                 userAccount: request.session.userAccount,
+                userMobile: request.session.sessionUser.mobile,
                 userID: request.session.sessionUser.id,
                 isFree,
                 compilationData: JSON.stringify(sessionCompilation),
@@ -419,12 +421,12 @@ module.exports = {
                 adminLevelType: JSON.stringify(AdminLevelType),
                 compilationName: sessionCompilation.name,
                 versionName: request.session.compilationVersion,
-                socketPort:config[process.env.NODE_ENV].socketPort?config[process.env.NODE_ENV].socketPort:5500,
-                LicenseKey:config.getLicenseKey(process.env.NODE_ENV),
+                socketPort: config[process.env.NODE_ENV].socketPort ? config[process.env.NODE_ENV].socketPort : 5500,
+                LicenseKey: config.getLicenseKey(process.env.NODE_ENV),
                 cloudTitle: config.prod_sc.title,
-                title:getTitle(request.headers.host) 
+                title: getTitle(request.headers.host)
             };
-    
+
             response.render('building_saas/pm/html/project-management.html', renderData);
         }
     },
@@ -500,7 +502,7 @@ module.exports = {
         }
     },
 
-    getGC: async function(req, res) {
+    getGC: async function (req, res) {
         const userID = req.session.sessionUser.id;
         const compilationId = req.session.sessionCompilation._id;
         try {
@@ -574,14 +576,14 @@ module.exports = {
                 for (let i = 0, len = gc_tenderFiles.length; i < len; i++) {
                     let gc_t = gc_tenderFiles[i];
                     let theProj = _projs[prefix + gc_t.ParentID] || null;
-                    if(!theProj){
+                    if (!theProj) {
                         let tempProjs = await ProjectsData.getProjectsByIds(userID, compilatoinId, [gc_t.ParentID]);
-                        if(tempProjs.length > 0 && tempProjs[0].projType === projType.project){
+                        if (tempProjs.length > 0 && tempProjs[0].projType === projType.project) {
                             theProj = _projs[prefix + gc_t.ParentID] = tempProjs[0]._doc;
                             buildProj(theProj);
                         }
                     }
-                    if(theProj) {
+                    if (theProj) {
                         theProj.children.push(gc_t);
                     }
                 }
@@ -1022,7 +1024,7 @@ module.exports = {
         };
         try {
             data.session = req.session;
-            result = await redirectToImportServer(data,"importProject",req);
+            result = await redirectToImportServer(data, "importProject", req);
         } catch (err) {
             console.log(err);
             result.error = 1;
@@ -1031,19 +1033,19 @@ module.exports = {
         res.json(result);
     },
     copyConstructionProject: async function (req, res) {
-      let data = JSON.parse(req.body.data);
-      let result = {
-          error: 0
-      };
-      try {
-          data.session = req.session;
-          result.data = await redirectToImportServer(data, "copyConstructionProject", req);
-      } catch (err) {
-          console.log(err);
-          result.error = 1;
-          result.message = err.message;
-      }
-      res.json(result);
+        let data = JSON.parse(req.body.data);
+        let result = {
+            error: 0
+        };
+        try {
+            data.session = req.session;
+            result.data = await redirectToImportServer(data, "copyConstructionProject", req);
+        } catch (err) {
+            console.log(err);
+            result.error = 1;
+            result.message = err.message;
+        }
+        res.json(result);
     },
     importProcessChecking: async function (req, res) {
         let result = {

+ 1 - 1
modules/users/models/sms.js

@@ -36,7 +36,7 @@ class SMS {
         try {
             const formData = {
                 smsUser: this.smsUser,
-                templateId: 25595,
+                templateId: 14898,
                 msgType: 0,
                 phone: mobile,
                 vars: '{"%code%":'+ code +'}',

+ 6 - 3
public/web/headerOpr.js

@@ -53,15 +53,18 @@ const CommonHeader = (function () {
     }
     //绑定事件
     //@return {void}
-    function addEventListener(){
+    function addEventListener() {
         csDom.click(function () {
             getCategoryList(-1, '联系客服');
         });
+        $('#stop-create-contact').click(function () {
+            getCategoryList(-1, '联系客服');
+        });
     }
     //取消浏览器自带右键
     //@return {void}
     function banNavigatorContextMenu() {
-        document.oncontextmenu = function(event) {
+        document.oncontextmenu = function (event) {
             if (window.event) {
                 event = window.event;
             }
@@ -101,6 +104,6 @@ const CommonHeader = (function () {
 
 CommonHeader.banNavigatorContextMenu();
 
-$(document).ready(function(){
+$(document).ready(function () {
     CommonHeader.addEventListener();
 });

+ 1 - 1
web/building_saas/main/js/models/project.js

@@ -273,7 +273,7 @@ var PROJECT = {
                 })},
                 dataType: 'json',
                 cache: false,
-                timeout: 50000,
+                timeout: 1000 * 60 * 5,
                 success: function (result) {
                     if (!result.error) {
                         const isInit = true;

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

@@ -19,6 +19,7 @@
     <script>
         // 这里的变量供页面调用
         var userAccount = '<%- userAccount %>';
+        var userMobile = '<%- userMobile %>';
         var userID = '<%- userID %>';
         let isFirst = JSON.parse('<%- isFirst %>');
         let isShow = JSON.parse('<%- isShow %>');
@@ -475,6 +476,30 @@
         </div>
     </div>
 </div>
+<!-- 停止新建 -->
+<div class="modal fade" id="stop-create-dialog" 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">
+                <p style="margin-bottom: 0;">尊敬的用户:</p>
+                <p style="margin-bottom: 0; text-indent: 28px;">感谢您一直以来对纵横的信任和支持,为了更好地坚守初心,持续为您提供高质量的产品与服务,纵横公路养护云造价已升级为<a href="https://dsk.smartcost.com.cn/">大司空云计价</a>。</p>
+                <div style="text-indent: 28px;" style="margin-bottom: 0;">
+                    <!-- <p style="margin-bottom: 0;">请使用<a href="https://dsk.smartcost.com.cn/">大司空云计价</a>编制新项目,现版本已停止新建项目。</p> -->
+                    <p style="margin-bottom: 0;">请联系当地客服免费升级账号,使用<a href="https://dsk.smartcost.com.cn/">大司空云计价</a>编制新项目。</p>
+                    <p style="margin-bottom: 0;">当地服务热线:<a id="stop-create-contact" href="javascript:void(0);">联系</a>当地客服</p>
+                    <p style="margin-bottom: 0;">全国服务热线:0756-3850888,企业QQ:800003850</p>
+                    <p style="margin-bottom: 20px; color: red !important;">请点链接进入大司空云计价:<a style="color: red !important" href="https://dsk.smartcost.com.cn">https://dsk.smartcost.com.cn</a></p>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
 <!--弹出重命名-->
 <div class="modal fade" id="rename-dialog" data-backdrop="static">
     <div class="modal-dialog" role="document">

+ 149 - 119
web/building_saas/pm/js/pm_newMain.js

@@ -50,6 +50,14 @@ const {
 } = window.commonConstants;
 const { similarEqual, isDef } = window.commonUtil;
 
+function isStopCreate() {
+  if (userMobile === '15919278500') {
+    return false;
+  }
+  const names = ['重庆养护(2018)', '内蒙古养护(2019)', '甘肃养护(2021)', '内蒙古高速公路养护(2022)', '内蒙古高速公路养护(2022)'];
+  return !!(compilationData && names.includes(compilationData.name));
+}
+
 //操作状态
 const STATE = {
   addingTender: false,
@@ -321,7 +329,11 @@ const projTreeObj = {
         return projTreeObj.getAddBtnDisabled(projectType.project);
       },
       callback: function (key, opt) {
-        $("#add-project-dialog").modal("show");
+        if (isStopCreate()) {
+          $('#stop-create-dialog').modal('show');
+        } else {
+          $('#add-project-dialog').modal('show');
+        }
       },
     },
     addTender: {
@@ -331,6 +343,10 @@ const projTreeObj = {
         return projTreeObj.getAddBtnDisabled(projectType.tender);
       },
       callback: function (key, opt) {
+        if (isStopCreate()) {
+          $('#stop-create-dialog').modal('show');
+          return;
+        }
         //弹出新建单位工程之前,判断当前使用版本,且当前使用单位工程数是否已到最大值
         let selectedItem = projTreeObj.tree.selected;
         $("#add-tender-dialog").modal("show");
@@ -379,6 +395,10 @@ const projTreeObj = {
         return !(node && node.data.projType === projectType.tender);
       },
       callback: function (key, opt) {
+        if (isStopCreate()) {
+          $('#stop-create-dialog').modal('show');
+          return;
+        }
         let selectedItem = projTreeObj.tree.selected;
         try {
           let selectedType =
@@ -404,6 +424,10 @@ const projTreeObj = {
         return !(node && node.data.projType === projectType.tender);
       },
       callback: function (key, opt) {
+        if (isStopCreate()) {
+          $('#stop-create-dialog').modal('show');
+          return;
+        }
         $("#save-as-dialog").modal("show");
       },
     },
@@ -539,6 +563,10 @@ const projTreeObj = {
         return true;
       },
       callback: function (key, opt) {
+        if (isStopCreate()) {
+          $('#stop-create-dialog').modal('show');
+          return;
+        }
         $("#confirm-import").hide();
         $("#import").modal("show");
         projTreeObj.getUploadToken();
@@ -1188,8 +1216,8 @@ const projTreeObj = {
         data.engineeringCost = data.engineeringCost ? data.engineeringCost : 0;
         data.unitPriceFile =
           data.property &&
-          data.property.unitPriceFile &&
-          data.property.unitPriceFile.name
+            data.property.unitPriceFile &&
+            data.property.unitPriceFile.name
             ? data.property.unitPriceFile.name
             : "";
         data.feeRateFile =
@@ -1223,7 +1251,7 @@ const projTreeObj = {
       shareImgWidth = 13,
       shareImgHeight = 13;
     let defaultHeight = 18; // 单元格默认高度
-    let TreeNodeCellType = function () {};
+    let TreeNodeCellType = function () { };
     TreeNodeCellType.prototype = new GC.Spread.Sheets.CellTypes.Text();
     // 自动行高处理 此函数在每次调用autoFitRow后调用,返回的值作为新的单元格高度
     // 在单元格设置为自动行高后,单元格的内容有空格时,spreadjs会将空格认为是换行,会导致高度计算不正确,因此在setCellValue中处理空格
@@ -1240,9 +1268,9 @@ const projTreeObj = {
       const node = me.tree.items[context.row];
       const nodeIndent = node
         ? (node.depth() + 1) * indent +
-          node.depth() * levelIndent +
-          imgWidth +
-          5
+        node.depth() * levelIndent +
+        imgWidth +
+        5
         : 0;
       const cellWidth = context.sheet.getCell(-1, context.col).width();
       const textLength = this.getAutoFitWidth(...arguments);
@@ -1494,7 +1522,7 @@ const projTreeObj = {
         return (
           hitinfo.x > centerX + halfBoxLength &&
           hitinfo.x <
-            centerX + halfBoxLength + imgWidth + indent / 2 + 3 + textLength
+          centerX + halfBoxLength + imgWidth + indent / 2 + 3 + textLength
         );
       }
       if (hitinfo.sheet.name() === "projectSheet") {
@@ -1571,9 +1599,9 @@ const projTreeObj = {
       let node = me.tree.items[hitinfo.row];
       let nodeIndent = node
         ? (node.depth() + 1) * indent +
-          node.depth() * levelIndent +
-          imgWidth +
-          3
+        node.depth() * levelIndent +
+        imgWidth +
+        3
         : 0;
       let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {
         sheet: hitinfo.sheet,
@@ -1628,8 +1656,8 @@ const projTreeObj = {
       if (node.data.projType === projectType.tender) {
         value =
           node.data.property &&
-          node.data.property.unitPriceFile &&
-          node.data.property.unitPriceFile.name
+            node.data.property.unitPriceFile &&
+            node.data.property.unitPriceFile.name
             ? node.data.property.unitPriceFile.name
             : "";
       }
@@ -1637,8 +1665,8 @@ const projTreeObj = {
       if (node.data.projType === projectType.tender) {
         value =
           node.data.property &&
-          node.data.property.feeFile &&
-          node.data.property.feeFile.name
+            node.data.property.feeFile &&
+            node.data.property.feeFile.name
             ? node.data.property.feeFile.name
             : "";
       }
@@ -2013,8 +2041,7 @@ const projTreeObj = {
         );
       } else {
         alert(
-          `当前的建设项目中已经有相同名字的${
-            from == "feeRateFile" ? "费率" : "单价"
+          `当前的建设项目中已经有相同名字的${from == "feeRateFile" ? "费率" : "单价"
           }文件!`
         );
       }
@@ -2354,9 +2381,8 @@ function changeValuationType(type) {
     if (valuation === null) {
       continue;
     }
-    html += `<option ${i === targetData.length - 1 ? "selected" : ""} value="${
-      valuation.id
-    }">${valuation.name}</option>`;
+    html += `<option ${i === targetData.length - 1 ? "selected" : ""} value="${valuation.id
+      }">${valuation.name}</option>`;
   }
   $("#valuation").html(html);
   let engineeringList = getEngineeringList();
@@ -2578,6 +2604,10 @@ $(document).ready(function () {
 
   // 新建子菜单有效性刷新
   $("#addMenuBtn").click(function () {
+    if (isStopCreate()) {
+      $('#stop-create-dialog').modal('show');
+      return false;
+    }
     const menuDisplay = !$("#addMenu").is(":visible");
     if (!menuDisplay) {
       return;
@@ -3339,9 +3369,8 @@ function AddProject() {
 function _getOptionDivDomStr(value, rdName, labelName, id, isChecked) {
   return `
         <div class="custom-control custom-radio custom-control-inline">
-            <input type="radio" value="${value}" name="${rdName}" ${
-    isChecked ? "checked" : ""
-  } id="${id}" class="custom-control-input">
+            <input type="radio" value="${value}" name="${rdName}" ${isChecked ? "checked" : ""
+    } id="${id}" class="custom-control-input">
             <label class="custom-control-label" for="${id}">${labelName}</label>
         </div>
     `;
@@ -3352,108 +3381,103 @@ function initProjectOptSet($target) {
   const html = `<div class="form-group row">
                         <label for="staticEmail" class="col-auto col-form-label col-form-label-sm">项目类型</label>
                         <div class="col">
-                            ${
-                              COMPILATION_NAME.includes("公路造价")
-                                ? ` 
+                            ${COMPILATION_NAME.includes("公路造价")
+      ? ` 
                                 ${_getOptionDivDomStr(
-                                  SUGGESTION,
-                                  "valuation-type",
-                                  "建议估算",
-                                  "type-suggestion",
-                                  true
-                                )}
+        SUGGESTION,
+        "valuation-type",
+        "建议估算",
+        "type-suggestion",
+        true
+      )}
                                 ${_getOptionDivDomStr(
-                                  FEASIBILITY,
-                                  "valuation-type",
-                                  "可行性估算",
-                                  "type-feasibility",
-                                  false
-                                )}
+        FEASIBILITY,
+        "valuation-type",
+        "可行性估算",
+        "type-feasibility",
+        false
+      )}
                                 ${_getOptionDivDomStr(
-                                  ROUGH,
-                                  "valuation-type",
-                                  "概算",
-                                  "type-rough",
-                                  false
-                                )}
+        ROUGH,
+        "valuation-type",
+        "概算",
+        "type-rough",
+        false
+      )}
                             `
-                                : ""
-                            }
-                            ${
-                              COMPILATION_NAME.includes(
-                                "内蒙古高速公路日常养护估算(2021)"
-                              )
-                                ? `
+      : ""
+    }
+                            ${COMPILATION_NAME.includes(
+      "内蒙古高速公路日常养护估算(2021)"
+    )
+      ? `
                                 ${_getOptionDivDomStr(
-                                  ESTIMATION,
-                                  "valuation-type",
-                                  "估算",
-                                  "type-suggestion",
-                                  true
-                                )}
+        ESTIMATION,
+        "valuation-type",
+        "估算",
+        "type-suggestion",
+        true
+      )}
                                 `
-                                : ``
-                            }
-                            ${
-                              COMPILATION_NAME.includes("四川养护(2013)") ||
-                              COMPILATION_NAME.includes("部颁2018计价标准")
-                                ? `
+      : ``
+    }
+                            ${COMPILATION_NAME.includes("四川养护(2013)") ||
+      COMPILATION_NAME.includes("部颁2018计价标准")
+      ? `
                                 ${_getOptionDivDomStr(
-                                  BILL_BUDGET,
-                                  "valuation-type",
-                                  "清单预算",
-                                  "type-bill_budget",
-                                  true
-                                )}
+        BILL_BUDGET,
+        "valuation-type",
+        "清单预算",
+        "type-bill_budget",
+        true
+      )}
                                 `
-                                : ``
-                            }
-                            ${
-                              COMPILATION_NAME !==
-                                "内蒙古高速公路日常养护估算(2021)" &&
-                              COMPILATION_NAME !== "四川养护(2013)" &&
-                              COMPILATION_NAME !== "部颁2018计价标准"
-                                ? `
-                                ${
-                                  !COMPILATION_NAME.includes("部颁2018计价标准")
-                                    ? _getOptionDivDomStr(
-                                        BUDGET,
-                                        "valuation-type",
-                                        "预算",
-                                        "type-budget",
-                                        !COMPILATION_NAME.includes("公路造价")
-                                      )
-                                    : ""
-                                }
+      : ``
+    }
+                            ${COMPILATION_NAME !==
+      "内蒙古高速公路日常养护估算(2021)" &&
+      COMPILATION_NAME !== "四川养护(2013)" &&
+      COMPILATION_NAME !== "部颁2018计价标准"
+      ? `
+                                ${!COMPILATION_NAME.includes("部颁2018计价标准")
+        ? _getOptionDivDomStr(
+          BUDGET,
+          "valuation-type",
+          "预算",
+          "type-budget",
+          !COMPILATION_NAME.includes("公路造价")
+        )
+        : ""
+      }
                                 ${_getOptionDivDomStr(
-                                  BOQ,
-                                  "valuation-type",
-                                  "工程量清单",
-                                  "type-boq",
-                                  COMPILATION_NAME.includes("部颁2018计价标准")
-                                )}
+        BOQ,
+        "valuation-type",
+        "工程量清单",
+        "type-boq",
+        COMPILATION_NAME.includes("部颁2018计价标准")
+      )}
                                 `
-                                : ``
-                            }
+      : ``
+    }
                         </div>
                     </div>
                     <div class="form-group row hide-area" id="boq-type">
                         <label for="staticEmail" class="col-auto col-form-label col-form-label-sm">清单类型</label>
                         <div class="col">
                             ${_getOptionDivDomStr(
-                              BID_INVITATION,
-                              "boq-type-input",
-                              "招标",
-                              "boq-type-tender",
-                              false
-                            )}
+      BID_INVITATION,
+      "boq-type-input",
+      "招标",
+      "boq-type-tender",
+      false
+    )}
                             ${_getOptionDivDomStr(
-                              BID_SUBMISSION,
-                              "boq-type-input",
-                              "投标",
-                              "boq-type-bidder",
-                              true
-                            )}
+      BID_SUBMISSION,
+      "boq-type-input",
+      "投标",
+      "boq-type-bidder",
+      true
+    )}
                         </div>
                     </div>`;
   //const $children = $(html);
@@ -4242,6 +4266,13 @@ function AddTender() {
       .children("option:selected")
       .text();
     //let newTab = window.open('about:blank');
+    let tempProj = getNodeByName(projName, tempProjs);
+    if (!tempProj) {
+      if (isStopCreate()) {
+        $('#stop-create-dialog').modal('show');
+        return;
+      }
+    }
     $.bootstrapLoading.start();
     let callback = function (tenderNode) {
       $("#add-tender-dialog").modal("hide");
@@ -4722,9 +4753,8 @@ function getEngineeringHtml(engineeringList) {
     if (engLibNames.includes(tmp.lib.name)) {
       continue;
     }
-    result += `<option ${i === 0 ? "selected" : ""} value="${tmp.lib.name}">${
-      tmp.lib.name
-    }</option>`;
+    result += `<option ${i === 0 ? "selected" : ""} value="${tmp.lib.name}">${tmp.lib.name
+      }</option>`;
     engLibNames.push(tmp.lib.name);
   }
   return result;
@@ -4760,8 +4790,8 @@ function getProperty(projectInfo) {
     .removeAttr("checked", "checked");
   $(
     "input[name='tender_valuation_type'][value='" +
-      projectProperty.valuationType +
-      "']"
+    projectProperty.valuationType +
+    "']"
   )
     .attr("checked", "checked")
     .removeAttr("disabled", "disabled");
@@ -4787,7 +4817,7 @@ function getUnitFile(parentID, callback) {
     error: function () {
       alert("数据传输错误!");
     },
-    beforeSend: function () {},
+    beforeSend: function () { },
     success: function (response) {
       if (response.error === 1) {
         alert("获取失败!");
@@ -4820,7 +4850,7 @@ function getFeeRateFile(parentID, callback) {
     error: function () {
       alert("数据传输错误!");
     },
-    beforeSend: function () {},
+    beforeSend: function () { },
     success: function (response) {
       if (response.error === 1) {
         alert("获取失败!");
@@ -5060,8 +5090,8 @@ function set_file_table(target, poj_tenders, fileList, type) {
     let usedHtml =
       usedObj.usedCount > 0
         ? '<td class="text-center"><a href="javascript:void(0);">' +
-          usedObj.usedCount +
-          "</a></td>"
+        usedObj.usedCount +
+        "</a></td>"
         : '<td class="text-center">' + usedObj.usedCount + "</td>";
     let unitPriceEditHtml =
       type === fileType.unitPriceFile
@@ -5376,8 +5406,8 @@ function doAfterImport(projectDatas) {
     data.feeStandardName =
       (data.property && data.property.feeStandardName) || ""; //工程专业列显示用
     let parent = projTreeObj.tree.items.find(
-        (node) => node.data.ID === data.ParentID
-      ),
+      (node) => node.data.ID === data.ParentID
+    ),
       next = projTreeObj.tree.items.find(
         (node) => node.data.ID === data.NextSiblingID
       );

+ 8 - 0
web/building_saas/standard_interface/config.js

@@ -151,6 +151,14 @@ const INTERFACE_CONFIG = (() => {
         [CONTROL]: '.zjglzbkzj',
       },
     },
+    '浙江@杭州': {
+      scriptName: 'zhejiang_hangzhou.js',
+      fileSuffix: {
+        [BID_INVITATION]: '.zjglzb',
+        [BID_SUBMISSION]: '.zjgltb',
+        [CONTROL]: '.zjglzbkzj',
+      },
+    },
     '浙江@象山': {
       scriptName: 'zhejiang_xiangshan.js',
       fileSuffix: {

+ 136 - 128
web/building_saas/standard_interface/export/guangxi_common.js

@@ -237,6 +237,7 @@ INTERFACE_EXPORT = (() => {
         }
       }
     }
+    pass = true; // 新要求,不检查清单名称了 (这个检测随时变化)
     if (pass == false) fail = { hint: `清单:"${data.name ? data.name : ""}",名字不符合规范!`, type: projectName }
 
     return fail;
@@ -758,132 +759,132 @@ INTERFACE_EXPORT = (() => {
         //   if (orList.length > 0) this.children = orList;
         // }
 
-        function CostStructure(r) {
-          //待获取
-          this.name = "CostStructure";
-          this.attrs = [];
-          this.children = [];
-        }
-
-        function Consume(r, o) {
-          this.name = "Consume";
-          this.attrs = [{
-            name: "KeyId",
-            value: uuid.v1()
-          }];
-          this.children = [];
-          for (let g of o.ration_gljs) {
-            if (g.rationID == r.ID) {
-              let r_quantity = scMathUtil.roundForObj(r.quantity, tpdata.property.decimal.ration.quantity);
-              this.children.push(new ConsumeItem(g, r_quantity));
-            }
-          }
-        }
+        // function CostStructure(r) {
+        //   //待获取
+        //   this.name = "CostStructure";
+        //   this.attrs = [];
+        //   this.children = [];
+        // }
 
-        function ConsumeItem(g, ration_quantity) {
-          let costType = parseInt(g.type);
-          if (costType < 100) {
-            costType = 1;
-          } else if (costType >= 300) {
-            costType = 3;
-          } else {
-            //判断主材
-            for (let pglj of pgljData.gljList) {
-              if (pglj.glj_id === g.GLJID) {
-                if (pglj.is_main_material == 1) {
-                  costType = 3;
-                } else {
-                  costType = 2;
-                }
-                break;
-              }
-            }
-          }
-          const attrs = [{
-            name: "Code", //待获取
-            value: g.code,
-          },
-          {
-            name: "Consumption",
-            value: scMathUtil.roundForObj(ration_quantity * parseFloat(g.quantity), tpdata.property.decimal.glj.quantity),
-          },
-          {
-            name: "CostType",
-            value: costType,
-          },
-          {
-            name: "KeyId",
-            value: uuid.v1()
-          },
-          ];
-          Element.call(this, "ConsumeItem", attrs);
-        }
+        // function Consume(r, o) {
+        //   this.name = "Consume";
+        //   this.attrs = [{
+        //     name: "KeyId",
+        //     value: uuid.v1()
+        //   }];
+        //   this.children = [];
+        //   for (let g of o.ration_gljs) {
+        //     if (g.rationID == r.ID) {
+        //       let r_quantity = scMathUtil.roundForObj(r.quantity, tpdata.property.decimal.ration.quantity);
+        //       this.children.push(new ConsumeItem(g, r_quantity));
+        //     }
+        //   }
+        // }
 
-        function Norm(r, o) {
-          const attrs = [{
-            name: "NormLibNo", //待获取
-            value: "",
-          },
-          {
-            name: "DisplayCode",
-            value: r.code,
-          },
-          {
-            name: "Name",
-            value: r.name,
-          },
-          {
-            name: "Unit",
-            value: r.unit,
-          },
-          {
-            name: "Num",
-            value: r.quantity,
-          },
-          {
-            name: "CostTypeNo",
-            value: "", //待获取
-          },
-          {
-            name: "FabricationCost", //待获取
-            value: "",
-          },
-          {
-            name: "AdjustStatus",
-            value: "",
-          },
-          ];
-          Element.call(this, "Norm", attrs);
-          this.children.push(new CostStructure(r));
-          this.children.push(new Consume(r, o));
-        }
+        // function ConsumeItem(g, ration_quantity) {
+        //   let costType = parseInt(g.type);
+        //   if (costType < 100) {
+        //     costType = 1;
+        //   } else if (costType >= 300) {
+        //     costType = 3;
+        //   } else {
+        //     //判断主材
+        //     for (let pglj of pgljData.gljList) {
+        //       if (pglj.glj_id === g.GLJID) {
+        //         if (pglj.is_main_material == 1) {
+        //           costType = 3;
+        //         } else {
+        //           costType = 2;
+        //         }
+        //         break;
+        //       }
+        //     }
+        //   }
+        //   const attrs = [{
+        //     name: "Code", //待获取
+        //     value: g.code,
+        //   },
+        //   {
+        //     name: "Consumption",
+        //     value: scMathUtil.roundForObj(ration_quantity * parseFloat(g.quantity), tpdata.property.decimal.glj.quantity),
+        //   },
+        //   {
+        //     name: "CostType",
+        //     value: costType,
+        //   },
+        //   {
+        //     name: "KeyId",
+        //     value: uuid.v1()
+        //   },
+        //   ];
+        //   Element.call(this, "ConsumeItem", attrs);
+        // }
 
-        function SelfCollect(o) {
-          const attrs = [{
-            name: "OtherCost",
-            value: 0,
-          },];
-          Element.call(this, "SelfCollect", attrs);
-          for (let r of o.rations) {
-            this.children.push(new Norm(r, o));
-          }
-        }
+        // function Norm(r, o) {
+        //   const attrs = [{
+        //     name: "NormLibNo", //待获取
+        //     value: "",
+        //   },
+        //   {
+        //     name: "DisplayCode",
+        //     value: r.code,
+        //   },
+        //   {
+        //     name: "Name",
+        //     value: r.name,
+        //   },
+        //   {
+        //     name: "Unit",
+        //     value: r.unit,
+        //   },
+        //   {
+        //     name: "Num",
+        //     value: r.quantity || 0,
+        //   },
+        //   {
+        //     name: "CostTypeNo",
+        //     value: "", //待获取
+        //   },
+        //   {
+        //     name: "FabricationCost", //待获取
+        //     value: "",
+        //   },
+        //   {
+        //     name: "AdjustStatus",
+        //     value: "",
+        //   },
+        //   ];
+        //   Element.call(this, "Norm", attrs);
+        //   this.children.push(new CostStructure(r));
+        //   this.children.push(new Consume(r, o));
+        // }
 
-        function OrgPrices(o) {
-          const attrs = [{
-            name: "OrgPricevalue",
-            value: o.supplyPrice,
-          },
-          {
-            name: "Ratio",
-            value: o.coe,
-          },
-          ];
+        // function SelfCollect(o) {
+        //   const attrs = [{
+        //     name: "OtherCost",
+        //     value: 0,
+        //   },];
+        //   Element.call(this, "SelfCollect", attrs);
+        //   for (let r of o.rations) {
+        //     this.children.push(new Norm(r, o));
+        //   }
+        // }
 
-          Element.call(this, "OrgPrices", attrs);
-          if (!o.rations) return;
-          this.children.push(new SelfCollect(o));
-        }
+        // function OrgPrices(o) {
+        //   const attrs = [{
+        //     name: "OrgPricevalue",
+        //     value: o.supplyPrice,
+        //   },
+        //   {
+        //     name: "Ratio",
+        //     value: o.coe,
+        //   },
+        //   ];
+
+        //   Element.call(this, "OrgPrices", attrs);
+        //   if (!o.rations) return;
+        //   this.children.push(new SelfCollect(o));
+        // }
       }
 
       function Mech(g, gljKeyMap) {
@@ -1329,7 +1330,7 @@ INTERFACE_EXPORT = (() => {
           return rst;
         }
 
-        function _getDayworkMapStrByBillType(billData) {
+        function _getMapStrByBillFlag(billData) {
           let rst = ['', ''];
           if (billData && billData.flags && billData.flags.length > 0) {
             for (let idx = 0; idx < billData.flags.length; idx++) {
@@ -1344,6 +1345,12 @@ INTERFACE_EXPORT = (() => {
                   case 25:
                     rst = ["10.3", "D3"]; // 机械
                     break;
+                  case 19:
+                    rst = ["1", "A"]; // 第100章至700章清单
+                    break;
+                  case 26:
+                    rst = ["11", "E"]; // 暂列金额 fixedFlag.PROVISIONAL
+                    break;
                   default:
                     break;
                 }
@@ -1387,10 +1394,11 @@ INTERFACE_EXPORT = (() => {
           if (ListCodeMap[data.name]) ListCode = ListCodeMap[data.name][0];
           if (data.code && data.code != "") ListCode = data.code;
           let formulaCode = "";
+          // ListCodeFlagMap
           if (ListCodeMap[data.name]) {
             formulaCode = ListCodeMap[data.name][1];
           } else {
-            formulaCode = _getDayworkMapStrByBillType(data)[1];
+            formulaCode = _getMapStrByBillFlag(data)[1];
           }
           let perKeyId = '';
           if (data.ParentID != -1) {
@@ -1415,7 +1423,7 @@ INTERFACE_EXPORT = (() => {
           },
           {
             name: "Num",
-            value: data.quantity,
+            value: data.quantity || 0,
             type: TYPE.DECIMAL,
             toFix: _getDecimal(data.unit)
           },
@@ -1586,7 +1594,7 @@ INTERFACE_EXPORT = (() => {
               Costs.push(new Cost(bNode.data));
               for (let idx = 0; idx < Costs[Costs.length - 1].attrs.length; idx++) {
                 if (Costs[Costs.length - 1].attrs[idx].name === 'Num') {
-                  Costs[Costs.length - 1].attrs[idx].value = '' + bNode.data.quantity;
+                  Costs[Costs.length - 1].attrs[idx].value = '' + (bNode.data.quantity || 0);
                 } else if (Costs[Costs.length - 1].attrs[idx].name === 'BasePrice') {
                   Costs[Costs.length - 1].attrs[idx].value = '' + _getFee(bNode, 'common', 'tenderUnitFee');
                 }
@@ -1669,7 +1677,7 @@ INTERFACE_EXPORT = (() => {
                 value: item.unit
               }, {
                 name: 'Num',
-                value: item.tenderQuantity
+                value: item.tenderQuantity || ''
               }, {
                 name: 'BasePrice',
                 value: BasePrice
@@ -1731,7 +1739,7 @@ INTERFACE_EXPORT = (() => {
                 value: ration.unit
               }, {
                 name: 'Num',
-                value: ration.tenderQuantity
+                value: ration.tenderQuantity || 0
               },
               {
                 name: 'CostTypeNo',
@@ -1781,7 +1789,7 @@ INTERFACE_EXPORT = (() => {
                 value: rg.code,
               }, {
                 name: "Consumption",
-                value: rg.tenderQuantity
+                value: rg.tenderQuantity || 0
               }, {
                 name: "KeyId",
                 value: uuid.v1()

+ 71 - 16
web/building_saas/standard_interface/export/shandong_common.js

@@ -161,6 +161,13 @@ INTERFACE_EXPORT = (() => {
     , regRt1 = new RegExp('\n\r', 'g'), regRt2 = new RegExp('\r\n', 'g')
     ;
 
+  function getXMLTransitCharacters(orgStr) {
+    if ( typeof orgStr === 'string') {
+      return orgStr.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/'/g, '&apos;');
+    }
+    return orgStr;
+  }
+
   function getBasePrice(projectGLJID, tenderProject) {
     let glj = _.find(tenderProject.projectGLJ.datas.gljList, {
       id: projectGLJID
@@ -224,7 +231,8 @@ INTERFACE_EXPORT = (() => {
       let flag = data.flagsIndex.fixed.flag;
       switch (flag) {
         case fixedFlag.ONE_SEVEN_BILLS:
-          pass = data.name == "第100章至700章清单" || data.name == "第100章至700章清单合计";
+          // pass = data.name == "第100章至700章清单" || data.name == "第100章至700章清单合计";
+          pass = typeof data.name === 'string' && data.name.includes('第100章至'); 
           break;
         case fixedFlag.PROVISIONAL_TOTAL:
           pass = data.name == "已包含在清单合计中的材料、工程设备、专业工程暂估价合计";
@@ -287,9 +295,9 @@ INTERFACE_EXPORT = (() => {
       Element
     } = INTERFACE_EXPORT_BASE;
 
-    const { 
+    const {
       isGLYun
-    } = window.commonUtil;    
+    } = window.commonUtil;
 
     const {
       EXPORT_KIND: {
@@ -1073,9 +1081,10 @@ INTERFACE_EXPORT = (() => {
       // 1.4 计日工合计 标记:22
       // 1.5 暂列金额(不含计日工总额) 标记:26
       // 1.6 投标报价 标记:9
-      let topNode100To700, nodeZXZDJ, nodeQDKCZXZDJ, nodeJRG, nodeZLJE, nodeTBBJ;
+      let topNode100To700, nodeZXZDJ, nodeQDKCZXZDJ, nodeJRG, nodeZLJE, nodeTBBJ, newAddedBill;
       let chapterNodes = [];
       let fixedSum = _getFixedSum(tenderProject); //山东有固定费用,此费用不参与到此项中去
+      let nextBillID = '';
       tenderProject.Bills.datas.forEach((bill) => {
         if (bill.flags && bill.flags.length > 0) {
           for (let flag of bill.flags) {
@@ -1094,16 +1103,25 @@ INTERFACE_EXPORT = (() => {
                 break;
               case 26:
                 nodeZLJE = bill;
+                nextBillID = bill.NextSiblingID
                 break;
               case 9:
                 nodeTBBJ = bill;
                 break;
+              case 44:
+                newAddedBill = bill;
+                break;
               default:
                 break;
             }
           }
         }
       });
+      tenderProject.Bills.datas.forEach((bill) => {
+        if (bill.type === 1 && bill.ID === nextBillID && nodeTBBJ && nodeTBBJ.ID !== nextBillID) {
+          newAddedBill = bill;
+        }
+      });
 
       //2. 然后获取topNode100To700下的所有次一级清单(100章...700章)
       if (topNode100To700) {
@@ -1125,11 +1143,22 @@ INTERFACE_EXPORT = (() => {
         let order = 1;
         //读取投标报价汇总表信息。1.ItemNo 序号。2.ChapterNo 章次。 3.Name 科目名称。 4.Sum 金额。
         chapterNodes.forEach((cnode) => {
-          let chapterIdx = cnode.data.name.indexOf("00章");
-          nodeAttrs.push({ ItemNo: order, ChapterNo: cnode.data.name.substr(chapterIdx - 1, 3), Name: cnode.data.name, Sum: _getFee(cnode) });
-          order++;
+          if (_chkIfValid100(cnode)) {
+            let chapterIdx = cnode.data.name.indexOf("00章");
+            let chpNoStr = '';
+            const ch = cnode.data.name.substr(chapterIdx - 2, 2);
+            if (isNaN(parseFloat(ch))) {
+              chpNoStr = cnode.data.name.substr(chapterIdx - 1, 3);
+            } else {
+              chpNoStr = cnode.data.name.substr(chapterIdx - 2, 4);
+            }
+            // nodeAttrs.push({ ItemNo: order, ChapterNo: cnode.data.name.substr(chapterIdx - 1, 3), Name: cnode.data.name, Sum: _getFee(cnode) });
+            nodeAttrs.push({ ItemNo: order, ChapterNo: chpNoStr, Name: cnode.data.name, Sum: _getFee(cnode) });
+            order++;
+          }
         });
-        nodeAttrs.push({ ItemNo: order, ChapterNo: '', Name: '第100章至700章清单合计', Sum: _getFee(topNode100To700) });
+        // nodeAttrs.push({ ItemNo: order, ChapterNo: '', Name: '第100章至700章清单合计', Sum: _getFee(topNode100To700) });
+        nodeAttrs.push({ ItemNo: order, ChapterNo: '', Name: topNode100To700.name, Sum: _getFee(topNode100To700) });
         order++;
         if (nodeZXZDJ) {
           // nodeAttrs.push({ItemNo: order, ChapterNo: '', Name: '已包含在清单合计中的材料、工程设备、专业工程暂估价合计', Sum: _getFee(nodeZXZDJ) - fixedSum});
@@ -1148,8 +1177,16 @@ INTERFACE_EXPORT = (() => {
           nodeAttrs.push({ ItemNo: order, ChapterNo: '', Name: `暂列金额(不含计日工总额)`, Sum: _getFee(nodeZLJE) });
           order++;
         }
+        if (newAddedBill) {
+          nodeAttrs.push({ ItemNo: order, ChapterNo: '', Name: newAddedBill.name, Sum: _getFee(newAddedBill) });
+          order++;
+        }
         if (nodeTBBJ) {
-          nodeAttrs.push({ ItemNo: order, ChapterNo: '', Name: `投标报价(${chapterNodes.length + 1} + ${order - 2}+${order - 1})=${order}`, Sum: _getFee(nodeTBBJ) });
+          let nameStr = `投标报价(${chapterNodes.length + 1}+${order - 2}+${order - 1})=${order}`;
+          if (newAddedBill && nodeTBBJ.calcBase && nodeTBBJ.calcBase.includes(newAddedBill.ID)) {
+            nameStr = `投标报价(${chapterNodes.length + 1}+${order - 3}+${order - 2}+${order - 1})=${order}`;
+          }
+          nodeAttrs.push({ ItemNo: order, ChapterNo: '', Name: nameStr, Sum: _getFee(nodeTBBJ) });
           order++;
         }
       }
@@ -1614,7 +1651,7 @@ INTERFACE_EXPORT = (() => {
           let leafBillAttrs = [
             { name: 'ItemNo', value: sno },
             { name: 'Code', value: cacheObj[billIdKey].code },
-            { name: 'Name', value: cacheObj[billIdKey].name },
+            { name: 'Name', value: getXMLTransitCharacters(cacheObj[billIdKey].name) },
             { name: 'LaborWorkDays', value: _getNumValueByExportKind(scMathUtil.roundForObj(cacheObj[billIdKey].labourConsume / bQtn, decimalObj.glj.quantity)) },
             { name: 'LaborUnitPrice', value: _getNumValueByExportKind(scMathUtil.roundForObj(cacheObj[billIdKey].labourUnitPrice, decimalObj.glj.unitPrice)) },
             { name: 'LaborUnitTotal', value: _getNumValueByExportKind(scMathUtil.roundForObj(cacheObj[billIdKey].labourTotalPrice / bQtn, decimalObj.glj.unitPrice)) },
@@ -1672,6 +1709,9 @@ INTERFACE_EXPORT = (() => {
         }
       };
       const _getAllGlj = function (parentBill) {
+        if (parentBill.data.name === '挖除水泥混凝土路面(平面交叉)') {
+          debugger;
+        }
         if (parentBill.children.length > 0) {
           parentBill.children.forEach((subBill) => {
             _getAllGlj(subBill);
@@ -1685,11 +1725,15 @@ INTERFACE_EXPORT = (() => {
           }
           tenderProject.ration_glj.datas.forEach((rglj) => {
             if (rglj.billsItemID === parentBill.data.ID) {
-              let gljQty = parseFloat(rglj.quantity);
-              if (isNaN(gljQty)) gljQty = 0;
               let ration = _getRation(rglj.rationID);
+              if (ration) {
+                // 计算消耗量,否则定额人材机消耗量取值会不正确
+                gljOprObj.getTotalQuantity(rglj, ration);
+              }
+              let gljQty = parseFloat(rglj.tenderQuantity || rglj.quantity);
+              if (isNaN(gljQty)) gljQty = 0;
               let gljRationQty = 0;
-              if (ration) gljRationQty = parseFloat(ration.quantity);
+              if (ration) gljRationQty = parseFloat(ration.tenderQuantity || ration.quantity);
               if (isNaN(gljRationQty)) gljRationQty = 0;
               let gljCns = gljQty * gljRationQty;
               let prjGlj = _getPrjGLJ(rglj.projectGLJID);
@@ -1851,12 +1895,19 @@ INTERFACE_EXPORT = (() => {
 
     }
 
+    function _chkIfValid100(node) {
+      let rst = true;
+      if (node.data.name.indexOf('第100章') >= 0 && node.data.name.indexOf('总则') >= 0) {
+        let bVal = _getFee(node);
+        rst = node.children.length > 0 || bVal !== 0;
+      }
+      return rst;
+    }
 
     function getBillsItems(tenderProject, cacheForFormula) {
       let items = new emptyElement("Items");
       let rootNodes = tenderProject.mainTree.roots;
       for (let r of rootNodes) {
-
         setItem(r, -1, items.children);
       }
       return items;
@@ -1868,6 +1919,10 @@ INTERFACE_EXPORT = (() => {
         if (isBidInvitation && (bNode.data.specialProvisional == "材料暂估" || bNode.data.specialProvisional == "工程设备")) {
           return;
         }
+        // 判断: 100章下无子清单,且金额为0时,return
+        if (!_chkIfValid100(bNode)) {
+          return;
+        }
         let item = new bill(bNode, level, dftListCodeSeq);
         if (bNode.children && bNode.children.length > 0) {
           level += 1;
@@ -1909,7 +1964,7 @@ INTERFACE_EXPORT = (() => {
             const bNodeName = _billStrFilter(node.data.name);
             if (bNodeName.indexOf('清单第') >= 0 && bNodeName.indexOf('00章') > 0) {
               return 0;
-            } else if (isFlag(node.data) && specialChkBillFlag.includes(node.data.flagsIndex.fixed.flag)){
+            } else if (isFlag(node.data) && specialChkBillFlag.includes(node.data.flagsIndex.fixed.flag)) {
               return 0;
             }
             return 1 //叶子清单输出1
@@ -2714,7 +2769,7 @@ INTERFACE_EXPORT = (() => {
           }
         }
         // if (_billStrFilter(bill.name).includes('第100章至700章清单')) {
-          if (_billStrFilter(bill.name).includes('第100章至') && _billStrFilter(bill.name).includes('00章清单')) {
+        if (_billStrFilter(bill.name).includes('第100章至') && _billStrFilter(bill.name).includes('00章清单')) {
           cacheObj['_{各章清单合计}'] = {};
           cacheObj['_{各章清单合计}'].formulaCode = `{F${cnt - 1}}`;
         } else if (!_billStrFilter(bill.name).includes('清单第100章')) {

Разлика између датотеке није приказан због своје велике величине
+ 1154 - 0
web/building_saas/standard_interface/export/zhejiang_hangzhou.js


+ 23 - 5
web/building_saas/standard_interface/import/base.js

@@ -243,6 +243,14 @@ const INTERFACE_EXPORT_BASE = (() => {
     6: fixedFlag.TOTAL_COST,
   };
 
+  function chkIfDayworkBill(billName) {
+    let rst = false;
+    if (typeof billName === 'string') {
+      rst = /计日工/.test(billName) && billName.indexOf('计日工') === 0;
+    }
+    return rst;
+  }
+
   /**
    * 将提取出来的清单合并进清单模板
    * @param {Array} source - 从xml提取出来的清单
@@ -261,13 +269,13 @@ const INTERFACE_EXPORT_BASE = (() => {
       const titleType = bills.titleType || "0";
       let matched;
       if (!parent) {
-        if (titleTypeToFlag[titleType] === fixedFlag.ONE_SEVEN_BILLS || /100章.*章|100章.*700章|100章.*900章/.test(simpleName)) {
+        if ((titleTypeToFlag[titleType] === fixedFlag.ONE_SEVEN_BILLS || /100章.*章|100章.*700章|100章.*900章/.test(simpleName)) && simpleName.indexOf('第100章') === 0) {
           matched = target.find((bills) => getFlag(bills) === fixedFlag.ONE_SEVEN_BILLS);
         } else if (titleTypeToFlag[titleType] === fixedFlag.PROVISIONAL_TOTAL || /包含在清单合计中的材料、工程设备、专业工程暂估/.test(simpleName)) {
           matched = target.find((bills) => getFlag(bills) === fixedFlag.PROVISIONAL_TOTAL);
         } else if (titleTypeToFlag[titleType] === fixedFlag.BILLS_TOTAL_WT_PROV || /清单合计减去材料、工程设备、专业工程暂估价/.test(simpleName)) {
           matched = target.find((bills) => getFlag(bills) === fixedFlag.BILLS_TOTAL_WT_PROV);
-        } else if (titleTypeToFlag[titleType] === fixedFlag.DAYWORK_LABOR || /计日工合计/.test(simpleName)) {
+        } else if (titleTypeToFlag[titleType] === fixedFlag.DAYWORK_LABOR || chkIfDayworkBill(simpleName)) {
           matched = target.find((bills) => getFlag(bills) === fixedFlag.DAYWORK_LABOR);
         } else if (titleTypeToFlag[titleType] === fixedFlag.PROVISIONAL || /暂列金额[((]不含/.test(simpleName)) {
           matched = target.find((bills) => getFlag(bills) === fixedFlag.PROVISIONAL);
@@ -278,11 +286,11 @@ const INTERFACE_EXPORT_BASE = (() => {
         const parentSimpleName = parent.name ? parent.name.replace(/\s/g, "") : "";
         if (/100章.*章|100章.*700章|100章.*900章/.test(parentSimpleName) && /100章总则/.test(simpleName)) {
           matched = target.find((bills) => getFlag(bills) === fixedFlag.ONE_HUNDRED_BILLS);
-        } else if (/计日工合计/.test(parentSimpleName) && /劳务/.test(simpleName)) {
+        } else if (chkIfDayworkBill(parentSimpleName) && /劳务/.test(simpleName)) {
           matched = target.find((bills) => getFlag(bills) === fixedFlag.LABOUR_SERVICE);
-        } else if (/计日工合计/.test(parentSimpleName) && /材料/.test(simpleName)) {
+        } else if (chkIfDayworkBill(parentSimpleName) && /材料/.test(simpleName)) {
           matched = target.find((bills) => getFlag(bills) === fixedFlag.MATERIAL);
-        } else if (/计日工合计/.test(parentSimpleName) && /机械/.test(simpleName)) {
+        } else if (chkIfDayworkBill(parentSimpleName) && /机械/.test(simpleName)) {
           matched = target.find((bills) => getFlag(bills) === fixedFlag.CONSTRUCTION_MACHINE);
         }
       }
@@ -545,9 +553,19 @@ const INTERFACE_EXPORT_BASE = (() => {
       boqType: commonConstants.BOQType.BID_SUBMISSION, // 导入后必为投标
       basicInformation: mergeInfo(importData.info, templateData.basicInfo), // 将提取的基本信息数据与标准基本信息数据进行合并(目前只赋值,没有匹配到的不追加)
     };
+    const adhocInfo = importData.info.find(item => item.key === 'adhocInfoIsTotalChapterFirst');
+    let bkAdHocInfo = null;
+    if (adhocInfo) {
+      bkAdHocInfo = { key: adhocInfo.key, value: adhocInfo.value };
+    }
     delete importData.info;
     // 处理单位工程数据
     handleTenderData(importData.tenders, templateData, rationValuationData, engineeringLib, areaKey, onlyImportMatchBills);
+    if (bkAdHocInfo) {
+      importData.tenders.forEach(tender => {
+        tender.property[bkAdHocInfo.key] = bkAdHocInfo.value;
+      });
+    }
     console.log(importData);
   }
 

+ 59 - 5
web/building_saas/standard_interface/import/shandong_common.js

@@ -115,8 +115,22 @@ INTERFACE_IMPORT = (() => {
           { key: 'laneLength', value: getValue(Params, ['_LaneLength']) },// --todo
         ]
         const items = arrayValue(EprjInfo, ['Items', 'Item']);
+        let hasOneHundredChapter = false;
+        const _chkIfHasOneHundred = function(pBill) {
+          let rst = false;
+          if (pBill.name.indexOf('第100章') >= 0 && pBill.name.indexOf('总则') >= 0) {
+            rst = true;
+          } else {
+            for (let idx = 0; idx < pBill.children.length; idx++) {
+              rst = _chkIfHasOneHundred(pBill.children[idx]);
+              if (rst) break;
+            }
+          }
+          return rst;
+        };
         for (let i of items) {
           let bill = setupBills(i);
+          if (_chkIfHasOneHundred(bill)) hasOneHundredChapter = true;
           if (bill.name == "暂列金额(不含计日工总额)") { 
             bill.fees = [{ fieldName: "common",tenderTotalFee:ProvisionalSums, tenderUnitFee: "0", totalFee: ProvisionalSums, unitFee: "0" }];
             if (bill.calcBase === undefined || bill.calcBase === null || bill.calcBase === '') {
@@ -125,8 +139,16 @@ INTERFACE_IMPORT = (() => {
             }
             bill.calcFlag = 1;
           }
+          let formula = getValue(i, ['CostComposition', 'Formula', '_Formulas']);
+          if (formula !== undefined && formula !== null && formula !== '') {
+            bill.exCalcStr = formula; // 不仅仅'投标报价'有,其他的也要
+          }
+          // if (bill.name == '投标报价') {
+          //   bill.exCalcStr = formula || '';
+          // }
           tender.bills.push(bill);
         }
+        tender.hasOneHundredChapter = hasOneHundredChapter;
         // 山东的 formula 还得调整
         // setupFormula(tender.bills);
 
@@ -138,6 +160,19 @@ INTERFACE_IMPORT = (() => {
         return tender;
       }
 
+      function handleBillPrice(bill, formula, totalFee, quantity) {
+        if (formula) {
+          bill.calcFlag = 1;
+          bill.exCalcStr = formula;
+        } else if (!formula && !quantity && totalFee) {
+          // 没有基数、没有工程量时,有金额时,金额作为基数
+          bill.exCalcStr = String(totalFee);
+          bill.calcFlag = 1;
+        } else {
+          bill.calcFlag = 2;
+        }
+      }
+
       function setupBills(item, needClac = false) { 
         const regBlank = new RegExp(' ', 'g');
         let bill = {
@@ -152,6 +187,7 @@ INTERFACE_IMPORT = (() => {
           qtyFormula: item._QtyFormula,
           children: []
         }
+        const formula = getValue(item, ['CostComposition', 'Formula', '_Formulas']);
         // if ((needClac || bill.name == "暂列金额(不含计日工总额)") && bill.qtyFormula && bill.qtyFormula !== '') {
         if ((needClac || bill.name == "暂列金额(不含计日工总额)") && bill.hasOwnProperty('qtyFormula')) {
           let formula = getValue(item, ['CostComposition', 'Formula', '_Formulas']);
@@ -172,16 +208,20 @@ INTERFACE_IMPORT = (() => {
         if (item._ProvisionalType == '3') bill.specialProvisional = '固定费用';
         if (item._ProvisionalType == '2') {
           let sumVal = getValue(item, ['_Sum']);
-          bill.fees = [{ fieldName: "common",tenderTotalFee:sumVal, tenderUnitFee: "0", totalFee: sumVal, unitFee: "0" }];
-          bill.calcBase = sumVal;
-          bill.calcFlag = 1;
+          let priceVal = getValue(item, ['_Price']);
+          bill.fees = [{ fieldName: "common",tenderTotalFee:sumVal, tenderUnitFee: priceVal, totalFee: sumVal, unitFee: priceVal }];
+          // bill.calcBase = sumVal;
+          // bill.calcFlag = 2;
+          handleBillPrice(bill, formula, +sumVal, +bill.quantity);
         }
         if (item._ProvisionalType == '3') {
           let sumVal = getValue(item, ['_Sum']);
           let priceVal = getValue(item, ['_Price']);
+          // if ((+sumVal) < (+priceVal)) sumVal = priceVal;
           bill.fees = [{ fieldName: "common",tenderTotalFee:sumVal, tenderUnitFee: priceVal, totalFee: sumVal, unitFee: priceVal }];
-          bill.calcBase = sumVal;
-          bill.calcFlag = 1;
+          // bill.calcBase = sumVal;
+          // bill.calcFlag = 2;
+          handleBillPrice(bill, formula, +sumVal, +bill.quantity);
         }
 
         let subItems = arrayValue(item, ['Item']);
@@ -256,6 +296,10 @@ INTERFACE_IMPORT = (() => {
             cacheObj[bill.formulaCode] = bill;
           }
           if (typeof bill.calcBase === 'string' && bill.calcBase.length > 0) {
+            if (bill.exCalcStr) bill.calcBase = bill.exCalcStr;
+            calcBills.push(bill);
+          } else if (bill.exCalcStr) {
+            bill.calcBase = bill.exCalcStr;
             calcBills.push(bill);
           }
         }
@@ -266,6 +310,16 @@ INTERFACE_IMPORT = (() => {
       }  
       importData.tenders.forEach((tender, index) => {
         setupFormula(tender.bills);
+        if (!tender.hasOneHundredChapter) {
+          for (let idx = tender.bills.length - 1; idx >= 0; idx--) {
+            const bName = tender.bills[idx].name || '';
+            if (bName.indexOf('第100章') >= 0 && bName.indexOf('总则') > 0) {
+              tender.bills.splice(idx, 1);
+              break;
+            }
+          }
+        }
+        delete tender.hasOneHundredChapter;
       });
     }
   

+ 3 - 1
web/building_saas/standard_interface/import/view.js

@@ -34,6 +34,7 @@ const IMPORT_VIEW = (() => {
   // 导入相关事件监听器
   let importData = null;
   let areaKey = '';
+  const onlyImportMatchBillsCompilations = ['广东@中山', '浙江@杭州'];
   function importListener() {
     // 文件选择变更
     $('#interface-import-file').change(function () {
@@ -65,7 +66,8 @@ const IMPORT_VIEW = (() => {
         if (!(importData && areaKey && areaKey === curAreaKey)) {
           areaKey = curAreaKey;
           await STD_INTERFACE.loadScriptByArea(areaKey, STD_INTERFACE.ScriptType.IMPORT);
-          const onlyImportMatchBills = areaKey === '广东@中山';
+          // const onlyImportMatchBills = areaKey === '广东@中山';
+          const onlyImportMatchBills = onlyImportMatchBillsCompilations.includes(areaKey);
           importData = await INTERFACE_EXPORT_BASE.extractImportData(INTERFACE_IMPORT.entry, file, areaKey, false, onlyImportMatchBills, INTERFACE_IMPORT.handleAfterImport);
         }
         const constructionName = $('#import-rename').is(':visible') ? $('#import-rename-input').val() : importData.name;

+ 212 - 0
web/building_saas/standard_interface/import/zhejiang_hangzhou.js

@@ -0,0 +1,212 @@
+// 浙江杭州导入接口(copy from 宁海)
+// INTERFACE_EXPORT =,必须这么写,这样才能在导入时动态加载脚本后,覆盖前端代码
+INTERFACE_IMPORT = (() => {
+    'use strict';
+    /**
+     * 
+     * @param {String} areaKey - 地区标识,如:'安徽@马鞍山',有些地区的接口只是取值上有不同,共有一个接口脚本, 需要通过地区标识确定一些特殊处理
+     * @param {Object} xmlObj - xml经过x2js转换后的xml对象
+     * @return {Object} - 返回的格式需要统一,具体参考函数内返回的内容。返回的内容会经过一系列的统一处理形成可入库的数据。
+     */
+    async function entry(areaKey, xmlObj) {
+      const {
+        UTIL: {
+          getValue,
+          arrayValue,
+          extractItemsRecur,
+        }
+      } = INTERFACE_EXPORT_BASE;
+  
+      const subArea = areaKey.split('@')[1];
+  
+      const natureConstructionMap = {
+        '1': '施工',
+        '2': '养护',
+      };
+      const roadGradeMap = {
+        '1': '高速公路',
+        '2': '一级公路',
+        '3': '二级公路',
+        '4': '三级公路',
+        '5': '四级公路',
+        '6': '桥梁工程',
+        '7': '隧道工程',
+        '8': '其他工程',
+      };
+      const taxModeMap = {
+        '1': '一般计税',
+        '2': '简易计税',
+      };
+  
+      // 工程专业
+      let engineeringName = '小修保养、大中修';
+      // 费用标准
+      let feeName = '高速公路';
+  
+      // 提取基本信息,xml中提取出来的基本信息,最终会与模板基本信息进行合并处理。(接口内不需要处理合并)
+      function setupInformation(projectSrc) {
+        const gcxx = getValue(projectSrc, ['工程信息']);
+        const ztbxx = getValue(projectSrc, ['招投标信息', '招标控制价']) || getValue(projectSrc, ['招投标信息', '投标信息']) || getValue(projectSrc, ['招投标信息', '招标信息']);
+        // key:基本信息模板中的key,作为合并时的匹配字段
+        const natureConstruction = natureConstructionMap[getValue(gcxx, ['_项目类型'])] || '';
+        if (natureConstruction === '养护(年度经费)') {
+          engineeringName = '小修保养年度经费';
+        }
+        const roadGrade = roadGradeMap[getValue(gcxx, ['_专业划分'])] || '';
+        feeName = roadGrade;
+        const info = [
+          { key: 'projNum', value: getValue(gcxx, ['_项目编号']) },
+          { key: 'constructingUnits', value: getValue(gcxx, ['_建设单位']) },
+          { key: 'startChainages', value: getValue(gcxx, ['_起始桩号']) },
+          { key: 'endChainages', value: getValue(gcxx, ['_终点桩号']) },
+          { key: 'constructionAddress', value: getValue(gcxx, ['_建设地址']) },
+          { key: 'projOverview', value: getValue(gcxx, ['_项目概况']) },
+          { key: 'natureConstruction', value: natureConstruction },
+          { key: 'roadGrade', value: roadGrade },
+          { key: 'roadDistance', value: getValue(gcxx, ['_道路里程-公里']) },
+          { key: 'designUnit', value: getValue(gcxx, ['_设计单位']) },
+          { key: 'taxMode', value: taxModeMap[getValue(gcxx, ['_计税方式'])] },
+          { key: 'tendereeName', value: getValue(ztbxx, ['_招标人']) },
+          { key: 'tenderAuthorizer', value: getValue(ztbxx, ['_招标法定代表人或其授权人']) },
+          { key: 'compileApprover', value: getValue(ztbxx, ['_编制人']) },
+          { key: 'compileCertNo', value: getValue(ztbxx, ['_编制人资格证号']) },
+          { key: 'compileDate', value: getValue(ztbxx, ['_编制日期']) },
+          { key: 'proxy', value: getValue(ztbxx, ['_招标代理机构']) },
+          { key: 'scopeofBidding', value: getValue(ztbxx, ['_招标范围']) },
+          { key: 'timeLimit', value: getValue(ztbxx, ['_总工期日历天']) },
+          { key: 'compileDate', value: getValue(ztbxx, ['_编制日期']) },
+          { key: 'preparationDescription', value: getValue(ztbxx, ['_编制说明']) },
+          { key: 'reviewApprover', value: getValue(ztbxx, ['_复核人']) },
+          { key: 'reviewCertNo', value: getValue(ztbxx, ['_复核人资格证号']) },
+          { key: 'reviewDate', value: getValue(ztbxx, ['_复核日期']) },
+          { key: 'examineApprover', value: getValue(ztbxx, ['_审核人']) },
+          { key: 'examineCertNo', value: getValue(ztbxx, ['_审核人资格证号']) },
+          { key: 'examineDate', value: getValue(ztbxx, ['_审核日期']) },
+          { key: 'bidderName', value: getValue(ztbxx, ['_投标人']) },
+          { key: 'bidderAuthorizer', value: getValue(ztbxx, ['_投标人法人或其授权人']) },
+          { key: 'bidderCertNo', value: getValue(ztbxx, ['_投标人资质证号']) },
+          { key: 'downwardFloatingRateOfBid', value: getValue(ztbxx, ['_投标下浮率']) },
+          { key: 'descriptionOfTenderOffer', value: getValue(ztbxx, ['_投标报价说明']) },
+          { key: 'qualityCommitment', value: getValue(ztbxx, ['_质量承诺']) },
+          { key: 'bidBond', value: getValue(ztbxx, ['_投标保证金']) },
+          { key: 'projectManagers', value: getValue(ztbxx, ['_项目经理或项目负责人']) },
+          { key: 'projectmanagersCertNo', value: getValue(ztbxx, ['_项目经理或项目负责人资格证号']) },
+          { key: 'adhocInfoIsTotalChapterFirst', value: getIsTotalFirst(projectSrc) },
+        ];
+        return info;
+      }
+  
+      // 提取清单数据
+      function setupBills(rootSrc, oneSevenSrc, dayWorkSrc) {
+        // 章次为空的造价汇总表数据,为大项费用数据
+        const roots = arrayValue(rootSrc, ['造价汇总明细'])
+          .filter(item => !getValue(item, ['_章次']))
+          .map(item => ({
+            name: getValue(item, ['_名称']),
+            remark: getValue(item, ['_备注']),
+            titleType: getValue(item, ['_类别'])
+          }));
+        let oneSevenBills;
+        let dayWorkBills;
+        roots.forEach(item => {
+          // const simpleName = item.name ? item.name.replace(/\s/g, '') : '';
+          const simpleName = item.name ? item.name : ''; // 根据需求,保留所有类型的空格(空格、换行、tab缩进)
+          if (item.titleType === '1' || /100章至第700章|100章至700章/.test(simpleName)) {
+            oneSevenBills = item;
+          } else if (item.titleType === '4' || (/计日工合计|计日工/.test(simpleName) && !(/不含计日工/.test(simpleName)))) {
+            dayWorkBills = item;
+          }
+        });
+        // 第100-700章的数据
+        if (oneSevenBills) {
+          oneSevenBills.children = extractItemsRecur(oneSevenSrc, [['工程量清单明细']], (src) => ({
+            GUID: getValue(src, ['_GUID']),
+            sectionCode: getValue(src, ['_清单章节号']),
+            code: getValue(src, ['_子目号']),
+            name: getValue(src, ['_子目名称']),
+            unit: getValue(src, ['_单位']),
+            quantity: getValue(src, ['_数量']),
+            remark: getValue(src, ['_备注']),
+            appraisalBills: +getValue(src, ['_评审清单']),
+            specialProvisional: getValue(src, ['_数据类型']) === '21' ? '专业工程' : ''
+          }));
+        }
+        // 计日工数据
+        if (dayWorkBills) {
+          const title = '计日工信息标题';
+          const detail = '计日工信息明细';
+          let jrgBillExName = '计日工合计';
+          dayWorkBills.children = extractItemsRecur(dayWorkSrc, [[title], [detail]], (src, curField) => {
+            const name = getValue(src, ['_名称']);
+            const dataType = getValue(src, ['_数据类型']);
+            // const simpleName = name ? name.replace(/\s/g, '') : ''
+            const simpleName = name ? name : ''; // 根据需求,保留所有类型的空格(空格、换行、tab缩进)
+            if (curField === title && (dataType === '0' || /计日工合计|计日工/.test(simpleName))) { // 计日工标题在根节点中已经提取了,不重复提取
+              jrgBillExName = simpleName;
+              return null;
+            }
+            const item = { name };
+            if (curField === detail) {
+              item.code = getValue(src, ['_编号']);
+              item.unit = getValue(src, ['_单位']);
+              item.quantity = getValue(src, ['_暂定数量']);
+            }
+            const remark = getValue(src, ['_备注']) || '';
+            if (remark !== '') {
+              item.remark = remark;
+            }
+            return item;
+          });
+          const jrgBill = roots.find(rBill => rBill.titleType === '4' || rBill.titleType === '7');
+          if (jrgBill) {
+            // jrgBill.specialName = jrgBillExName;
+            jrgBill.name = jrgBillExName;
+          }
+        }
+        return roots;
+      }
+  
+      // 提取单位工程数据
+      function setupTender(tenderSrc) {
+        const oneSevenSrc = getValue(tenderSrc, ['工程量清单表']);
+        const dayWorkSrc = getValue(tenderSrc, ['计日工信息表']);
+        const rootSrc = getValue(tenderSrc, ['造价汇总表']);
+        return {
+          name: getValue(tenderSrc, ['_标段名称']),
+          GUID: getValue(tenderSrc, ['_唯一标识-Guid']),
+          bills: setupBills(rootSrc, oneSevenSrc, dayWorkSrc)
+        };
+      }
+
+      function getIsTotalFirst(projectSrc) {
+        // 因业务需要,要记录导入的招标文件中'造价汇总表'的 '第100章至X00章清单合计'的顺序(在前(品茗的)或在后(同望的))
+        let rst = false;
+        const tenders = arrayValue(projectSrc, ['公路工程数据', '公路标段工程'])
+        const rootSrc = arrayValue(tenders[0], ['造价汇总表', '造价汇总明细']);
+        // const roots = arrayValue(rootSrc, ['造价汇总明细'])
+        const nameStr = `${getValue(rootSrc[0], ['_名称']) || ''}`;
+        rst = (nameStr.includes('00章至') && nameStr.includes('章清单合计'))
+        return rst;
+      }
+  
+      // 从xml对象提取需要的数据
+      function setupProject(projectSrc) {
+        const tenders = arrayValue(projectSrc, ['公路工程数据', '公路标段工程'])
+          .map(tenderSrc => setupTender(tenderSrc));
+        return {
+          name: getValue(projectSrc, ['工程信息', '_项目名称']),
+          GUID: getValue(projectSrc, ['工程信息', '_GUID']),
+          info: setupInformation(projectSrc),
+          tenders,
+          engineeringName,
+          feeName,
+        };
+      }
+      return setupProject(getValue(xmlObj, ['浙江交通建设工程']));
+    }
+  
+    return {
+      entry
+    };
+  
+  })();

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

@@ -17,6 +17,7 @@
     <script>
         // 这里的变量供页面调用
         var userAccount = '<%- userAccount %>';
+        var userMobile = '<%- userMobile %>';
         var userID = '<%- userID %>';
     </script>
     <style type="text/css">