Przeglądaj źródła

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

TonyKang 5 lat temu
rodzic
commit
69fb59feab
39 zmienionych plików z 11457 dodań i 8415 usunięć
  1. 25 0
      modules/all_models/basic_info_lib.js
  2. 22 16
      modules/fee_rates/facade/fee_rates_facade.js
  3. 1 0
      modules/main/facade/project_facade.js
  4. 1 1
      modules/main/models/project.js
  5. 2 2
      modules/pm/controllers/pm_controller.js
  6. 66 5
      modules/pm/facade/pm_facade.js
  7. 7 1
      modules/pm/models/project_model.js
  8. 1 1
      modules/pm/models/project_property_template.js
  9. 665 604
      public/web/gljUtil.js
  10. 8 4
      public/web/sheet/sheet_common.js
  11. 2 0
      public/web/socket/connection.js
  12. 278 268
      web/building_saas/css/custom.css
  13. 3 3
      web/building_saas/main/html/tender_price.html
  14. 373 343
      web/building_saas/main/js/controllers/project_controller.js
  15. 1388 1370
      web/building_saas/main/js/models/calc_base.js
  16. 2609 2541
      web/building_saas/main/js/models/calc_program.js
  17. 14 14
      web/building_saas/main/js/views/config_material_view.js
  18. 401 262
      web/building_saas/main/js/views/electrovalence_view.js
  19. 1 1
      web/building_saas/main/js/views/main_tree_col.js
  20. 111 63
      web/building_saas/main/js/views/project_property_basicInfo.js
  21. 8 0
      web/building_saas/main/js/views/tender_price_view.js
  22. 25 4
      web/building_saas/pm/js/pm_newMain.js
  23. 2 2
      web/building_saas/pm/js/pm_share.js
  24. 567 495
      web/building_saas/pm/js/pm_tree.js
  25. 16 0
      web/building_saas/standard_interface/config.js
  26. 762 0
      web/building_saas/standard_interface/export/anhui_chizhou.js
  27. 720 701
      web/building_saas/standard_interface/export/anhui_maanshan.js
  28. 846 783
      web/building_saas/standard_interface/export/base.js
  29. 1254 172
      web/building_saas/standard_interface/export/guangdong_zhongshan.js
  30. 76 75
      web/building_saas/standard_interface/export/view.js
  31. 91 91
      web/building_saas/standard_interface/index.js
  32. 509 309
      web/building_saas/unit_price_file/index.js
  33. 4 0
      web/common/html/header.html
  34. 2 16
      web/over_write/js/anhui_2019.js
  35. 2 16
      web/over_write/js/hunan_2020.js
  36. 2 16
      web/over_write/js/neimeng_2019.js
  37. 394 81
      web/over_write/js/quanguo_2018.js
  38. 197 139
      web/over_write/js/shandong_2016.js
  39. 2 16
      web/over_write/js/zhejiang_2005.js

+ 25 - 0
modules/all_models/basic_info_lib.js

@@ -0,0 +1,25 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Zhong
+ * @date 2019/3/5
+ * @version
+ */
+//建设项目基本信息库
+const mongoose = require('mongoose');
+const Schema = mongoose.Schema;
+const oprSchema = require('../all_schemas/opr_schema');
+const basicInfoLib = new Schema({
+    ID: {type: String, index: true},
+    name: String,
+    creator: String,
+    createDate: Number,
+    recentOpr: [oprSchema],
+    info: {
+        type: Schema.Types.Mixed,
+        default: []
+    }
+});
+mongoose.model('std_basic_info_lib', basicInfoLib, 'std_basic_info_lib');

+ 22 - 16
modules/fee_rates/facade/fee_rates_facade.js

@@ -232,23 +232,29 @@ function commonCallback(callback,result,err) {
         callback(null,result);
     }
 }
-
 async function getFeeRateStandardsByProjectID(projectID) {
-    logger.info("get feeRate standard, projectID:"+projectID)
-    let feeRateStandards=[];
-    let project =  await projectsModel.findOne({ID:projectID});
-    let temFee = await feeRateFileModel.findOne({ID:project.property.feeFile.id});
-    feeRateStandards.push({ID:temFee.libID,libName:temFee.libName});
-   /* let engineeringLibModel = new EngineeringLibModel();
-    let engineeringInfo = project !== null && project.property.engineering_id !== undefined ?
-        await engineeringLibModel.getEngineering(project.property.engineering_id) : null;
-    if(engineeringInfo!=null){
-        let fee_lib = engineeringInfo.fee_lib;
-        for(let lib of fee_lib){
-            feeRateStandards.push({ID:lib.id,libName:lib.name});
-        }
-    }*/
-    return feeRateStandards;
+  logger.info("get feeRate standard, projectID:" + projectID)
+  let feeRateStandards = [];
+  let project = await projectsModel.findOne({
+    ID: projectID
+  });
+  //let temFee = await feeRateFileModel.findOne({ID:project.property.feeFile.id});
+  //feeRateStandards.push({ID:temFee.libID,libName:temFee.libName});
+  let engineeringLibModel = new EngineeringLibModel();
+  let engineeringInfo = project !== null && project.property.engineering_id !== undefined ?
+    await engineeringLibModel.getEngineering(project.property.engineering_id) : null;
+  if (engineeringInfo != null) {
+    for (let tax of engineeringInfo.tax_group) {
+      if (tax.taxType == project.property.taxType) {
+        let lib = tax.fee_lib;
+        feeRateStandards.push({
+          ID: lib.id,
+          libName: lib.name
+        });
+      }
+    }
+  }
+  return feeRateStandards;
 }
 
 async function changeFeeRateStandard(jdata){

+ 1 - 0
modules/main/facade/project_facade.js

@@ -3,6 +3,7 @@
  */
 
 module.exports = {
+  sortChildren,
   markUpdateProject: markUpdateProject,
   removeProjectMark: removeProjectMark,
   updateNodes: updateNodes,

+ 1 - 1
modules/main/models/project.js

@@ -139,7 +139,7 @@ Project.prototype.getDataSync = function(projectID){
                         const endTime = +new Date();
                         console.log(moduleName+'---------------'+(endTime - startTime));
                         cb(err, {moduleName: moduleName, data: data})
-                    }, true); // true 返回调价后的数据
+                    }, false);
                 }
             })(itemName))
         }

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

@@ -617,7 +617,7 @@ module.exports = {
         try {
             const { count, projectID } = JSON.parse(req.body.data);
             // 分享建设项目,仅提供给专业版用户
-            const proShareProjType = [projType.folder, projType.project];
+            /* const proShareProjType = [projType.folder, projType.project];
             const project = await projectModel.findOne({ ID: projectID }, 'projType');
             if (project && proShareProjType.indexOf(project.projType) >= 0) {
                 const isFree = userModelObj.isFreeFromSession(req.session.compilationVersion);
@@ -625,7 +625,7 @@ module.exports = {
                     callback(req, res, 0, 'success', { isFree });
                     return;
                 }
-            }
+            } */
             const userID = req.session.sessionUser.id;
             // 最近分享
             const recentUsers = await pm_facade.getRecentShareList(userID, count);

+ 66 - 5
modules/pm/facade/pm_facade.js

@@ -9,6 +9,7 @@
     };
 //先导出后require可以解决循环引用问题
 module.exports={
+    getBasicInfo,
     getProjectByGranularity,
     prepareShareList,
     getShareList,
@@ -106,11 +107,14 @@ const {
     fixedFlag,
     SharePermissionChangeType,
     GRANULARITY,
+    BOQType
 } = require('../../../public/common_constants');
 const notDeleted = [{deleteInfo: null}, {'deleteInfo.deleted': false}];
 let cipher = require('../../../public/cipher');
 let index = require("../../system_setting/model/index");
 const compilationModel = mongoose.model('compilation');
+const engineeringModel = mongoose.model('engineering_lib');
+const basicInfoModel = mongoose.model('std_basic_info_lib');
 let qiniu = require("qiniu");
 let fs = require("fs");
 let path = require("path");
@@ -1099,15 +1103,19 @@ function isDef(v){
 }
 
 function getTotalFee(bills, feeName) {
-    if(!isDef(bills)){
+    if (!isDef(bills)) {
         return 0;
     }
-    if(!isDef(bills.fees) || bills.fees.length <= 0){
+    if (!isDef(bills.fees) || bills.fees.length <= 0) {
         return 0;
     }
-    for(let fee of bills.fees){
-        if(isDef(fee.fieldName) && fee.fieldName === feeName){
-            return isDef(fee.totalFee) ? fee.totalFee : 0;
+    for (let fee of bills.fees) {
+        if (isDef(fee.fieldName) && fee.fieldName === feeName) {
+            return isDef(fee.tenderTotalFee)
+                ? fee.tenderTotalFee
+                : isDef(fee.totalFee)
+                    ? fee.totalFee
+                    : 0;
         }
     }
     return 0;
@@ -1590,6 +1598,15 @@ async function exportMainData(userID,projectID) {
             if(s.projType =="Tender") tenderIDs.push(s.ID);
         }
     }
+    const tenders = result.projects.filter(item => item.projType === projectType.tender);
+    // 标段兄弟之间树结构兼容性处理(防止导入的ybp源文件树结构是错的)
+    const sortedTenders = project_facade.sortChildren(tenders);
+    // 根据排好的顺序,重设NextSiblingID
+    for (let i = 0; i < sortedTenders.length; i++) {
+        const curTender = sortedTenders[i];
+        const nextTender = sortedTenders[i + 1];
+        curTender.NextSiblingID = nextTender && nextTender.ID || -1;
+    }
     let files = {unitFiles:await exportUnitFiles(projectID),feeRateFiles:await exportFeeRateFiles(projectID)};
     result.files = files;
     result = cipher.aesEncrypt(JSON.stringify(result));
@@ -1795,6 +1812,14 @@ async function importProject(data,req,updateData) {
                 result.msg = `您创建的项目个数超限,请联系我们的客服人员,或者导出建设项目保存到本地备份,删除云上数据。`;
                 return result;
             }
+            // 标段兄弟之间树结构兼容性处理(防止导入的ybp源文件树结构是错的)
+            const sortedTenders = project_facade.sortChildren(tenders);
+            // 根据排好的顺序,重设NextSiblingID
+            for (let i = 0; i < sortedTenders.length; i++) {
+                const curTender = sortedTenders[i];
+                const nextTender = sortedTenders[i + 1];
+                curTender.NextSiblingID = nextTender && nextTender.ID || -1;
+            }
             let [constructionProjectID,projectIDMap,labourCoeFileIDMap,calcProgramFileIDMap] = await handleMainProjectDatas(mainData,updateData,req.session.sessionUser.id);
             result.constructionProjectID = constructionProjectID;
             if(datas.length > 1 ){//生成后统一次插入 2020-05-29
@@ -2256,3 +2281,39 @@ async function getProjectByGranularity(tenderID, granularity, requestForSummaryI
     constructionProject.softInfo = `${company};${versionName};${version};${userID}`;
     return constructionProject;
 }
+
+//获取费用定额绑定的基本信息库数据
+async function getBasicInfo(compilationID, fileKind = null) {
+    const compilation = await compilationModel.findOne({_id: mongoose.Types.ObjectId(compilationID)});
+    if (!compilation) {
+        return null;
+    }
+    const billValuation = compilation.bill_valuation.find(function (data) {
+        return data.enable;
+    });
+    if (!billValuation) {
+        return null;
+    }
+    const engineerings = await engineeringModel.find({valuationID: billValuation.id}).lean();
+    const engineering = engineerings.find(function (data) {
+        return data.info_lib && data.info_lib.length > 0;
+    });
+    if (!engineering || !engineering.info_lib || !engineering.info_lib[0]) {
+        return null;
+    }
+    const infoLib = await basicInfoModel.findOne({ID: engineering.info_lib[0].id});
+    //提取文件类型中需要的数据 (投标项目可能不需要招标的一些信息)
+    if (fileKind && infoLib && infoLib.info && infoLib.info.length) {
+        const strMap = {
+            [BOQType.BID_SUBMISSION]: '投标',
+            [BOQType.BID_INVITATION]: '招标',
+        };
+        const needfulData = infoLib.info.filter(data => !data.fileKind || data.fileKind === strMap[fileKind]);
+        needfulData.forEach(nData => {
+            let needfulSub = nData.items.filter(sData => !sData.fileKind || sData.fileKind === strMap[fileKind]);
+            nData.items = needfulSub;
+        });
+        infoLib.info = needfulData;
+    }
+    return infoLib;
+}

+ 7 - 1
modules/pm/models/project_model.js

@@ -146,7 +146,13 @@ ProjectsDAO.prototype.updateUserProjects = async function (userId, compilationId
                 data.updateData['fileVer'] = await index.getVersion();
                 if(data.updateData.projType === projectType.project){
                     //设置建设项目基本信息,多个单位工程共用
-                    data.updateData.property.basicInformation = basicInformation;
+                    const fileKind = data.updateData.property.boqType;
+                    if (fileKind) {
+                        const infoLib = await pmFacade.getBasicInfo(compilationId, fileKind);
+                        data.updateData.property.basicInformation = infoLib && infoLib.info || basicInformation;
+                    } else {
+                        data.updateData.property.basicInformation = [];
+                    }
                 }
                 // 如果没有选中单价文件则新增单价文件
                 if (data.updateData.projType === projectType.tender && data.updateData.property !== null &&

+ 1 - 1
modules/pm/models/project_property_template.js

@@ -22,7 +22,7 @@ const displaySetting = {
 
 const tenderSetting = {
     gljPriceTenderCoe:1, //工料机单价调整系数
-    calcPriceOption:'coeBase'//根据调整系数计算报价
+    calcPriceOption:'priceBase_RCJ'//根据调整系数计算报价
 };
 
 const calcOptions={

Plik diff jest za duży
+ 665 - 604
public/web/gljUtil.js


+ 8 - 4
public/web/sheet/sheet_common.js

@@ -23,7 +23,7 @@ var sheetCommonObj = {
         var me = this;
         var spreadNS = GC.Spread.Sheets;
         if(setting.headRows == 2){
-            return me.buildSpanHeader(sheet, setting, rowCount);//初始化合并表格列头
+            return me.buildSpanHeader(sheet, setting);//初始化合并表格列头
         }
         sheet.suspendPaint();
         sheet.suspendEvent();
@@ -50,6 +50,7 @@ var sheetCommonObj = {
         sheet.showRowOutline(false);
         sheet.options.allowCellOverflow = false;
         me.buildHeader(sheet, setting);
+        sheet.setRowCount(rowCount, spreadNS.SheetArea.viewport);
         sheet.resumeEvent();
         sheet.resumePaint();
     },
@@ -63,7 +64,7 @@ var sheetCommonObj = {
         return spreadBook;
     },
 
-    buildSpanHeader:function (sheet, setting, rowCount) {
+    buildSpanHeader:function (sheet, setting) {
         let temSetting = {
             "emptyRows":0,
             "headRows":2,
@@ -73,7 +74,7 @@ var sheetCommonObj = {
             "cols":[]
         };
         let spanSetting =   sheetCommonObj.transferToTreeSetting(setting,temSetting);
-        TREE_SHEET_HELPER.loadSheetHeader(spanSetting,sheet,rowCount);
+        TREE_SHEET_HELPER.loadSheetHeader(spanSetting, sheet);
 
     },
 
@@ -788,7 +789,7 @@ var sheetCommonObj = {
         }
         return new getTipsCombo();
     },
-    getTreeNodeCellType: function (datas, row, parentMap,treeCol) {// 2018-09-26  不用spreadjs默认的树结构,自定义控件
+    getTreeNodeCellType: function (datas, row, parentMap,treeCol, paintFunc) {// 2018-09-26  不用spreadjs默认的树结构,自定义控件
         var ns = GC.Spread.Sheets;
         let rectW = 10;
         let rectH = 10;
@@ -801,6 +802,9 @@ var sheetCommonObj = {
         }
         TreeNodeCellType.prototype = new ns.CellTypes.Text();
         TreeNodeCellType.prototype.paint = function (ctx, value, x, y, w, h, style, options) {
+            if (paintFunc) {
+                paintFunc(ctx, value, x, y, w, h, style, { rectW, rectH, margin }, datas[row]);
+            }
             let offset = 0;
             let step = 7;
             let level = getTreeLevel(datas[row], datas);//从0开始,取当前节点是第几级的

+ 2 - 0
public/web/socket/connection.js

@@ -100,6 +100,8 @@ socketObject = {
             if (isActive) {
                 $("#message").html(`树结构发生变化,请<a href="javascript:void(0);" id="load-data">点击刷新列表</a>`);
                 $('#load-data').on('click', () => projTreeObj.handleNotifyClick(expandState, selection));
+                $('#notify > button').hide();
+                $('#empty-modal').modal('show');
                 $("#notify").show();
             }
         });

+ 278 - 268
web/building_saas/css/custom.css

@@ -1,36 +1,36 @@
 .text-green {
-    color: #172a30
+  color: #172a30
 }
 
 label.title {
-    display: inline-block;
-    width: 100px;
+  display: inline-block;
+  width: 100px;
 }
 
 .modal-feeRate {
-    max-width: 550px
+  max-width: 550px
 }
 
 div.resize {
-    height: 10px;
-    background: #efefef;
-    width: 100%;
-    cursor: s-resize;
+  height: 10px;
+  background: #efefef;
+  width: 100%;
+  cursor: s-resize;
 }
 
 div.resize-y {
-    height: 5px;
-    background: #efefef;
-    width: 100%;
-    cursor: s-resize;
+  height: 5px;
+  background: #efefef;
+  width: 100%;
+  cursor: s-resize;
 }
 
 div.resize-x {
-    width: 4px;
-    height: 100%;
-    background: #efefef;
-    cursor: w-resize;
-    float: left;
+  width: 4px;
+  height: 100%;
+  background: #efefef;
+  cursor: w-resize;
+  float: left;
 }
 
 /*.zlfb-check{
@@ -38,130 +38,131 @@ div.resize-x {
 }*/
 
 legend.legend {
-    display: block;
-    width: auto;
-    font-size: 0.9rem;
-    top: -15px;
-    background: white;
+  display: block;
+  width: auto;
+  font-size: 0.9rem;
+  top: -15px;
+  background: white;
 }
 
 .toolsbar_feeRate {
-    border-bottom: 1px solid #ccc
+  border-bottom: 1px solid #ccc
 }
 
 .li_sub {
-    margin-left: 14px;
+  margin-left: 14px;
 }
 
 .filterType {
-    width: 98px;
-    float: left;
+  width: 98px;
+  float: left;
 }
 
 .left {
-    float: left
+  float: left
 }
 
 .full-h {
-    height: 100%;
+  height: 100%;
 }
 
 .half-h {
-    height: 50%;
+  height: 50%;
 }
 
 .a_color {
-    color: #007bff;
+  color: #007bff;
 }
 
 .filterType a {
-    padding: 1px;
-    padding-top: 7px;
-    padding-bottom: 7px;
+  padding: 1px;
+  padding-top: 7px;
+  padding-bottom: 7px;
 }
 
-#gljPriceTenderCoe::-webkit-outer-spin-button, #gljPriceTenderCoe::-webkit-inner-spin-button {
-    -webkit-appearance: none;
+#gljPriceTenderCoe::-webkit-outer-spin-button,
+#gljPriceTenderCoe::-webkit-inner-spin-button {
+  -webkit-appearance: none;
 }
 
 #gljPriceTenderCoe {
-    -moz-appearance: textfield;
+  -moz-appearance: textfield;
 }
 
 .modal-quantity-edit-height {
-    height: 200px;
-    overflow-y: auto;
+  height: 200px;
+  overflow-y: auto;
 }
 
 .message-box {
-    position: absolute;
-    background: #000;
-    padding: 8px 10px;
-    line-height: 18px;
-    border-radius: 4px;
-    text-align: left;
-    font: 0.9rem Calibri;
-    box-shadow: 2px 2px 6px #ccc;
-    color: #fff;
+  position: absolute;
+  background: #000;
+  padding: 8px 10px;
+  line-height: 18px;
+  border-radius: 4px;
+  text-align: left;
+  font: 0.9rem Calibri;
+  box-shadow: 2px 2px 6px #ccc;
+  color: #fff;
 }
 
 .triangle-border {
-    position: absolute;
-    left: 10px;
-    overflow: hidden;
-    width: 0;
-    height: 0;
-    border-width: 6px;
-    border-style: solid dashed dashed dashed;
+  position: absolute;
+  left: 10px;
+  overflow: hidden;
+  width: 0;
+  height: 0;
+  border-width: 6px;
+  border-style: solid dashed dashed dashed;
 }
 
 .triangle-border_dropdown {
-    position: absolute;
-    left: 0px;
-    overflow: hidden;
-    width: 0;
-    height: 0;
-    border-width: 4px;
-    z-index: 10;
-    border-style: solid dashed dashed dashed;
+  position: absolute;
+  left: 0px;
+  overflow: hidden;
+  width: 0;
+  height: 0;
+  border-width: 4px;
+  z-index: 10;
+  border-style: solid dashed dashed dashed;
 }
 
 .tb-border_dropdown {
-    top: 7px;
-    border-color: #000 transparent transparent transparent;
+  top: 7px;
+  border-color: #000 transparent transparent transparent;
 }
 
 .tb-background_dropdown {
-    bottom: -11px;
-    border-color: #000 transparent transparent transparent;
+  bottom: -11px;
+  border-color: #000 transparent transparent transparent;
 }
 
 .tb-border {
-    bottom: -12px;
-    border-color: #000 transparent transparent transparent;
+  bottom: -12px;
+  border-color: #000 transparent transparent transparent;
 }
 
 .tb-background {
-    bottom: -11px;
-    border-color: #000 transparent transparent transparent;
+  bottom: -11px;
+  border-color: #000 transparent transparent transparent;
 }
 
 .tb-border_up {
-    top: -12px;
-    border-color: transparent transparent #000 transparent;
+  top: -12px;
+  border-color: transparent transparent #000 transparent;
 }
 
 .tb-background_up {
-    top: -11px;
-    border-color: transparent transparent #000 transparent;
+  top: -11px;
+  border-color: transparent transparent #000 transparent;
 }
 
 .elf-options:hover {
-    background-color: #CCCCCC;
+  background-color: #CCCCCC;
 }
 
 .inline-div {
-    display: inline;
+  display: inline;
 }
 
 /*快捷切换单位工程*/
@@ -172,95 +173,98 @@ legend.legend {
 }*/
 
 .menu ul ul {
-    visibility: hidden;
-    position: absolute;
-    top: -1px;
-    left: 100px;
+  visibility: hidden;
+  position: absolute;
+  top: -1px;
+  left: 100px;
 }
 
-.menu ul li:hover ul, .menu ul a:hover ul {
-    visibility: visible;
+.menu ul li:hover ul,
+.menu ul a:hover ul {
+  visibility: visible;
 }
 
 .menu ul :hover ul ul {
-    visibility: hidden;
+  visibility: hidden;
 }
 
 .menu ul :hover ul :hover ul {
-    visibility: visible;
+  visibility: visible;
 }
 
-.ui-datepicker-next, .ui-datepicker-next:hover {
-    background-image: url("/lib/jquery-ui/images/ui-icons_444444_256x240.png");
-    background-repeat: no-repeat;
-    background-position: -28px -12px;
+.ui-datepicker-next,
+.ui-datepicker-next:hover {
+  background-image: url("/lib/jquery-ui/images/ui-icons_444444_256x240.png");
+  background-repeat: no-repeat;
+  background-position: -28px -12px;
 }
 
-.ui-datepicker-prev, .ui-datepicker-prev:hover {
-    background-image: url("/lib/jquery-ui/images/ui-icons_444444_256x240.png");
-    background-repeat: no-repeat;
-    background-position: -90px -12px;
+.ui-datepicker-prev,
+.ui-datepicker-prev:hover {
+  background-image: url("/lib/jquery-ui/images/ui-icons_444444_256x240.png");
+  background-repeat: no-repeat;
+  background-position: -90px -12px;
 }
 
 .feerateInput {
-    padding: 0;
+  padding: 0;
 }
 
 #toolToastWrap {
-    display: -webkit-box;
-    display: -ms-flexbox;
-    display: flex;
-    -webkit-box-pack: center;
-    -ms-flex-pack: center;
-    justify-content: center;
-    pointer-events: none;
+  display: -webkit-box;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-box-pack: center;
+  -ms-flex-pack: center;
+  justify-content: center;
+  pointer-events: none;
 }
 
 #toolToast {
-    padding: 11px 20px;
-    line-height: 18px;
-    font-size: 14px;
-    position: relative;
-    word-wrap: break-word;
-    color: #fff;
-    text-align: center;
-    background: rgba(0, 0, 0, .75);
-    background-size: cover;
-    -webkit-user-select: none;
-    -moz-user-select: none;
-    -ms-user-select: none;
-    user-select: none;
-    display: -webkit-box;
-    display: -ms-flexbox;
-    display: flex;
-    -webkit-box-align: center;
-    -ms-flex-align: center;
-    align-items: center;
-    max-width: 686px;
-    box-sizing: border-box;
-    box-shadow: 0 0 0 0 rgba(0, 0, 0, .15), 0 2px 5px 0 rgba(0, 0, 0, .25);
-    pointer-events: auto;
-    border-radius: 2px
+  padding: 11px 20px;
+  line-height: 18px;
+  font-size: 14px;
+  position: relative;
+  word-wrap: break-word;
+  color: #fff;
+  text-align: center;
+  background: rgba(0, 0, 0, .75);
+  background-size: cover;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  display: -webkit-box;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-box-align: center;
+  -ms-flex-align: center;
+  align-items: center;
+  max-width: 686px;
+  box-sizing: border-box;
+  box-shadow: 0 0 0 0 rgba(0, 0, 0, .15), 0 2px 5px 0 rgba(0, 0, 0, .25);
+  pointer-events: auto;
+  border-radius: 2px
 }
 
 #toolToastBtn {
-    color: #0188fb;
-    margin: 0 2px;
-    white-space: nowrap;
-    cursor: pointer;
-    font-weight: 700
+  color: #0188fb;
+  margin: 0 2px;
+  white-space: nowrap;
+  cursor: pointer;
+  font-weight: 700
 }
 
 #toolToastBtn:hover {
-    color: #4060c9
+  color: #4060c9
 }
 
 #toolToastBtn:active {
-    color: #354ea1
+  color: #354ea1
 }
 
 .select_input {
-    border: none;
+  border: none;
 }
 
 /*.es-list>li:hover{
@@ -268,15 +272,15 @@ legend.legend {
 }*/
 
 .es-list-selected {
-    background: lightgrey;
+  background: lightgrey;
 }
 
 .es-list>li {
-    font-size: 13px;
+  font-size: 13px;
 }
 
 .es-list {
-    white-space: nowrap;
+  white-space: nowrap;
 }
 
 /*.dropdown-toggle::after{
@@ -284,245 +288,247 @@ legend.legend {
 }*/
 
 #esInput {
-    font-size: 13px;
-    color: black;
-    height: 100%;
+  font-size: 13px;
+  color: black;
+  height: 100%;
 }
 
 .ration_glj_spread {
-    width: 83%;
-    float: left;
+  width: 83%;
+  float: left;
 }
 
 .item_spread {
-    width: 29.8%;
-    float: left;
-    background: #F1F1F1;
-    word-wrap: break-word
+  width: 29.8%;
+  float: left;
+  background: #F1F1F1;
+  word-wrap: break-word
 }
 
 input.text-right {
-    text-align: right;
+  text-align: right;
 }
 
 .cus-width {
-    width: 100px;
-    margin-left: 10px;
+  width: 100px;
+  margin-left: 10px;
 }
 
 .more {
-    padding-left: .25rem!important
+  padding-left: .25rem !important
 }
 
 .bottom-tznrTools {
-    height: 30px;
-    line-height: 30px;
-    background: #efefef;
-    bottom: 30px;
-    left: 0px;
-    z-index: 999
+  height: 30px;
+  line-height: 30px;
+  background: #efefef;
+  bottom: 30px;
+  left: 0px;
+  z-index: 999
 }
 
 .zmhs-link {
-    padding: 0.4em 0.4em !important;
+  padding: 0.4em 0.4em !important;
 }
 
 /*修改tooltip默认最大宽度 */
 
 .tooltip-inner {
-    max-width: 400px !important;
+  max-width: 400px !important;
 }
 
 .applySuccess {
-    display: none;
-    color: #43CD80;
-    margin-left: 8px
+  display: none;
+  color: #43CD80;
+  margin-left: 8px
 }
 
 /*占位底色*/
 
 .occupied {
-    background: #f1f1f1;
+  background: #f1f1f1;
 }
 
 .material-ration-left {
-    float: left;
-    width: 90%;
+  float: left;
+  width: 90%;
 }
 
 .material-ass {
-    width: 10%;
-    background: #f7f7f9
+  width: 10%;
+  background: #f7f7f9
 }
 
 /*书签批注*/
 
 .annotate-color-1::before {
-    color: #E2F2C5 !important;
-    -webkit-text-stroke: .5px #ced4da;
+  color: #E2F2C5 !important;
+  -webkit-text-stroke: .5px #ced4da;
 }
 
 .annotate-color-2::before {
-    color: #F9E2CF !important;
-    -webkit-text-stroke: .5px #ced4da;
+  color: #F9E2CF !important;
+  -webkit-text-stroke: .5px #ced4da;
 }
 
 .annotate-color-3::before {
-    color: #F2EFD9 !important;
-    -webkit-text-stroke: .5px #ced4da;
+  color: #F2EFD9 !important;
+  -webkit-text-stroke: .5px #ced4da;
 }
 
 .annotate-color-4::before {
-    color: #F5D1DA !important;
-    -webkit-text-stroke: .5px #ced4da;
+  color: #F5D1DA !important;
+  -webkit-text-stroke: .5px #ced4da;
 }
 
 .annotate-color-5::before {
-    color: #E3E3E3 !important;
-    -webkit-text-stroke: .5px #ced4da;
+  color: #E3E3E3 !important;
+  -webkit-text-stroke: .5px #ced4da;
 }
 
 .annotate-color-6::before {
-    color: #B6F3F2 !important;
-    -webkit-text-stroke: .5px #ced4da;
+  color: #B6F3F2 !important;
+  -webkit-text-stroke: .5px #ced4da;
 }
 
 .annotate-color-7::before {
-    color: #ECE0F5 !important;
-    -webkit-text-stroke: .5px #ced4da;
+  color: #ECE0F5 !important;
+  -webkit-text-stroke: .5px #ced4da;
 }
 
 /*书签批注*/
 
 .annotate-color-1::before {
-    color: #E2F2C5 !important;
-    -webkit-text-stroke: .5px #ced4da;
+  color: #E2F2C5 !important;
+  -webkit-text-stroke: .5px #ced4da;
 }
 
 .annotate-color-2::before {
-    color: #F9E2CF !important;
-    -webkit-text-stroke: .5px #ced4da;
+  color: #F9E2CF !important;
+  -webkit-text-stroke: .5px #ced4da;
 }
 
 .annotate-color-3::before {
-    color: #F2EFD9 !important;
-    -webkit-text-stroke: .5px #ced4da;
+  color: #F2EFD9 !important;
+  -webkit-text-stroke: .5px #ced4da;
 }
 
 .annotate-color-4::before {
-    color: #F5D1DA !important;
-    -webkit-text-stroke: .5px #ced4da;
+  color: #F5D1DA !important;
+  -webkit-text-stroke: .5px #ced4da;
 }
 
 .annotate-color-5::before {
-    color: #E3E3E3 !important;
-    -webkit-text-stroke: .5px #ced4da;
+  color: #E3E3E3 !important;
+  -webkit-text-stroke: .5px #ced4da;
 }
 
 .annotate-color-6::before {
-    color: #B6F3F2 !important;
-    -webkit-text-stroke: .5px #ced4da;
+  color: #B6F3F2 !important;
+  -webkit-text-stroke: .5px #ced4da;
 }
 
 .annotate-color-7::before {
-    color: #ECE0F5 !important;
-    -webkit-text-stroke: .5px #ced4da;
+  color: #ECE0F5 !important;
+  -webkit-text-stroke: .5px #ced4da;
 }
 
 .z-index-3000 {
-    z-index: 3000;
+  z-index: 3000;
 }
 
 .text-ellipsis {
-    overflow: hidden;
-    white-space: nowrap;
-    text-overflow: ellipsis;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
 }
 
 .border-radius {
-    border-radius: .2rem !important;
+  border-radius: .2rem !important;
 }
 
 .pm-i {
-    width: 18px;
+  width: 18px;
 }
 
 .calcbase-btn {
-    width: 24px;
-    padding-left: 0;
-    padding-right: 0;
+  width: 24px;
+  padding-left: 0;
+  padding-right: 0;
 }
 
 .hide-area {
-    display: none;
+  display: none;
 }
 
 .middle-modal-width {
-    max-width: 650px;
+  max-width: 650px;
 }
 
 .middle-modal-height {
-    height: 500px;
+  height: 500px;
 }
 
-@media screen and (max-width: 1366px), (max-height: 768px) {
-    .middle-modal-width {
-        max-width: 500px;
-    }
-    .middle-modal-height {
-        height: 350px;
-    }
+@media screen and (max-width: 1366px),
+(max-height: 768px) {
+  .middle-modal-width {
+    max-width: 500px;
+  }
+
+  .middle-modal-height {
+    height: 350px;
+  }
 }
 
 /* 初始样式,防止projspread初始化完后背景从白突然变灰 */
 
 .poj-list {
-    height: 1000px;
-    background: #f7f7f9;
+  height: 1000px;
+  background: #f7f7f9;
 }
 
 .form-control-inline {
-    display: inline-block !important;
-    width: 80% !important;
+  display: inline-block !important;
+  width: 80% !important;
 }
 
 .unit_price_header {
-    padding-top: 6px;
-    margin-left: 50px;
-    margin-right: 100px !important;
+  padding-top: 6px;
+  margin-left: 50px;
+  margin-right: 100px !important;
 }
 
 .default-cursor {
-    cursor: default !important;
+  cursor: default !important;
 }
 
 .material_link.active {
-    border: 2px solid #ff6501 !important;
-    border-right: 1px solid #fff !important;
+  border: 2px solid #ff6501 !important;
+  border-right: 1px solid #fff !important;
 }
 
 .table-sc th {
-    font-weight: normal;
+  font-weight: normal;
 }
 
 .compilation-content {
-    left: 50% !important;
-    transform: translateX(-50%) !important;
-    width: 123% !important;
+  left: 50% !important;
+  transform: translateX(-50%) !important;
+  width: 123% !important;
 }
 
 /* 右键菜单input */
 
 .menu-input {
-    width: 2.5rem;
-    border: 1px solid rgb(221, 221, 221);
-    border-radius: 2px;
-    height: 1.3rem;
-    text-align: center;
+  width: 2.5rem;
+  border: 1px solid rgb(221, 221, 221);
+  border-radius: 2px;
+  height: 1.3rem;
+  text-align: center;
 }
 
 .menu-input:focus {
-    outline: none;
+  outline: none;
 }
 
 /* .menu-input::selection {
@@ -532,56 +538,60 @@ input.text-right {
 /* 进度条动画 */
 
 .progress-bar {
-    position: relative;
-    width: 100%;
+  position: relative;
+  width: 100%;
 }
 
 .progress-move {
-    position: absolute;
-    left: 0;
-    top: 0;
-    z-index: 999;
-    width: 200%;
-    height: 100%;
-    border-radius: .25rem;
-    animation: progressMove 20s linear infinite;
+  position: absolute;
+  left: 0;
+  top: 0;
+  z-index: 999;
+  width: 200%;
+  height: 100%;
+  border-radius: .25rem;
+  animation: progressMove 20s linear infinite;
 }
 
 @keyframes progressMove {
-    from {
-        transform: translateX(0);
-    }
-    to {
-        transform: translateX(-280px);
-    }
+  from {
+    transform: translateX(0);
+  }
+
+  to {
+    transform: translateX(-280px);
+  }
 }
 
 .progress-cover {
-    position: absolute;
-    left: 0;
-    top: 0;
-    z-index: 1000;
-    width: 100%;
-    height: 100%;
-    background-color: #e9ecef;
+  position: absolute;
+  left: 0;
+  top: 0;
+  z-index: 1000;
+  width: 100%;
+  height: 100%;
+  background-color: #e9ecef;
 }
 
 .progress-cover-move {
-    animation: progressCoverMove 40s linear;
-    animation-fill-mode: forwards;
+  animation: progressCoverMove 40s linear;
+  animation-fill-mode: forwards;
 }
 
 @keyframes progressCoverMove {
-    0% {
-        transform: translateX(0);
-    }
-    20% {
-        transform: translateX(330px);
-    }
-    40% {
-        transform: translateX(380px);
-    }
-    100% {
-        transform: translateX(420px);
-    }
+  0% {
+    transform: translateX(0);
+  }
+
+  20% {
+    transform: translateX(330px);
+  }
+
+  40% {
+    transform: translateX(380px);
+  }
+
+  100% {
+    transform: translateX(420px);
+  }
 }

+ 3 - 3
web/building_saas/main/html/tender_price.html

@@ -3,15 +3,15 @@
     <div class="btn-toolbar py-1">
         <div class="input-group input-group-sm mr-2">
             <select class="form-control form-control-sm" style="width: auto; font-size: .875rem" id="calcPriceOption">
+                <option value="priceBase_RCJ" >按目标价调整工料机消耗</option>
                 <option value="coeBase">按调价系数计算</option>
-                <option value="priceBase_RCJ" >按目标价调整人材机消耗</option>
                 <option value="priceBase_ZM" >按目标价调整子目工程量</option>
             </select>
         </div>
 
         <div class="input-group input-group-sm mr-2" style="width:230px">
             <div class="input-group-prepend">
-                <span class="input-group-text" id="inputGroup-sizing-sm">人材机单价调整系数</span>
+                <span class="input-group-text" id="inputGroup-sizing-sm">工料机单价调整系数</span>
             </div>
             <input id = 'gljPriceTenderCoe' type="number" step="0.1" class="form-control" placeholder="请输入系数" value="1">
         </div>
@@ -22,7 +22,7 @@
         <div class="form-check" style="margin-left:40px; margin-top:4px;">
             <label class="form-check-label">
                 <input class="form-check-input" name="cbShowTenderFields" id="cbShowTenderFields" value="true" type="checkbox">
-                <span data-toggle="tooltip" data-original-title="造价书界面定额人材机的调价、人材机汇总界面的调价">显示调价后数据</span>
+                <span data-toggle="tooltip" data-original-title="造价书界面定额工料机的调价、工料机汇总界面的调价">显示调价后数据</span>
             </label>
         </div>
     </div>

+ 373 - 343
web/building_saas/main/js/controllers/project_controller.js

@@ -3,371 +3,401 @@
  */
 
 ProjectController = {
-    /* sc: tree_sheet_controller */
-    syncDisplayNewNode: function (sc, newNode,callback) {
-        TREE_SHEET_HELPER.massOperationSheet(sc.sheet, function () {
-            var sels = sc.sheet.getSelections();
-            sc.sheet.addRows(newNode.serialNo(), 1);
-            TREE_SHEET_HELPER.refreshTreeNodeData(sc.setting, sc.sheet, [newNode], false);
-            sc.setTreeSelected(newNode);
-            sc.sheet.setSelection(newNode.serialNo(), sels[0].col, 1, 1);
-            //不显示到中间
-            //sc.sheet.showRow(newNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
-            cbTools.refreshFormulaNodes();
-            if(callback) callback();
-        });
-    },
-    syncDisplayNewNodes: function (sc, newNodes,withOutSelect=false,callback) {//withOutSelect 不需要自动选中,外面自已处理
-        TREE_SHEET_HELPER.massOperationSheet(sc.sheet, function () {
-            var sels = sc.sheet.getSelections();
-            newNodes.sort(function (a, b) {
-                let rst = 0;
-                if(a.serialNo() > b.serialNo()){
-                    rst = 1;
-                }
-                else {
-                    rst = -1;
-                }
-                return rst;
-            });
-            let lastNode = null;
-            for(let newNode of newNodes){
-                sc.sheet.addRows(newNode.serialNo(), 1);
-                TREE_SHEET_HELPER.refreshTreeNodeData(sc.setting, sc.sheet, [newNode], false);
-                lastNode = newNode
-               // sc.sheet.showRow(newNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
-            }
-            if(withOutSelect==false&& lastNode){
-                sc.setTreeSelected(lastNode);
-                sc.sheet.setSelection(lastNode.serialNo(), sels[0].col, 1, 1);
-            }
-
-            cbTools.refreshFormulaNodes();
-            if(callback) callback();
-        });
-    },
-    syncDisplayNewRationGljNode:function (sc,newNode) {
-        TREE_SHEET_HELPER.massOperationSheet(sc.sheet, function () {
-            sc.sheet.addRows(newNode.serialNo(), 1);
-            TREE_SHEET_HELPER.refreshTreeNodeData(sc.setting, sc.sheet, [newNode], false);
-           // sc.sheet.showRow(newNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
-            cbTools.refreshFormulaNodes();
-        });
-    },
-    /* addBillsByData: async function (postData, insertFunc) {
-        await ajaxPost('/bills/insertBills', { postData });
-        // 插入
-        const insertData = postData.filter(item => item.updateType === 'create');
-        const treeData = insertData.map(item => item.updateData);
-        // 插入清单节点
-        if (!insertFunc) {
-            insertFunc = projectObj.project.Bills.tree.insertByDatas;
-        }
-        projectObj.project.Bills.tree.insertByDatas(treeData);
-        projectObj.project.Bills.datas = projectObj.project.Bills.datas.concat(treeData);
-        // 插入主树节点
-        const newNodes = projectObj.project.mainTree.insertByDatas(treeData);
-        for (const node of newNodes) {
-            node.source = projectObj.project.Bills.tree.nodes[projectObj.project.Bills.tree.prefix + node.getID()];
-            node.data = node.source.data;
-            node.sourceType = projectObj.project.Bills.getSourceType();
-        }
-        ProjectController.syncDisplayNewNodes(projectObj.mainController, newNodes, true);
-        return newNodes;
-    }, */
-    addBillsByData: async function (postData, isSameDepth = false) {
-        await ajaxPost('/bills/insertBills', { postData });
-        // 插入
-        const insertData = postData.filter(item => item.updateType === 'create');
-        const treeData = insertData.map(item => item.updateData);
-        // 插入清单节点和主树节点
-        projectObj.project.Bills.datas = projectObj.project.Bills.datas.concat(treeData);
-        let newNodes;
-        if (isSameDepth) {
-            const pre = postData.find(item => item.updateType === 'update');
-            const preID = pre && pre.updateData.ID || null;
-            projectObj.project.Bills.tree.multiInsert(treeData, preID);
-            newNodes = projectObj.project.mainTree.multiInsert(treeData, preID);
+  /* sc: tree_sheet_controller */
+  syncDisplayNewNode: function (sc, newNode, callback) {
+    TREE_SHEET_HELPER.massOperationSheet(sc.sheet, function () {
+      var sels = sc.sheet.getSelections();
+      sc.sheet.addRows(newNode.serialNo(), 1);
+      TREE_SHEET_HELPER.refreshTreeNodeData(sc.setting, sc.sheet, [newNode], false);
+      sc.setTreeSelected(newNode);
+      sc.sheet.setSelection(newNode.serialNo(), sels[0].col, 1, 1);
+      //不显示到中间
+      //sc.sheet.showRow(newNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
+      cbTools.refreshFormulaNodes();
+      if (callback) callback();
+    });
+  },
+  syncDisplayNewNodes: function (sc, newNodes, withOutSelect = false, callback) { //withOutSelect 不需要自动选中,外面自已处理
+    TREE_SHEET_HELPER.massOperationSheet(sc.sheet, function () {
+      var sels = sc.sheet.getSelections();
+      newNodes.sort(function (a, b) {
+        let rst = 0;
+        if (a.serialNo() > b.serialNo()) {
+          rst = 1;
         } else {
-            projectObj.project.Bills.tree.insertByDatas(treeData);
-            newNodes = projectObj.project.mainTree.insertByDatas(treeData);
-        }
-        for (const node of newNodes) {
-            node.source = projectObj.project.Bills.tree.nodes[projectObj.project.Bills.tree.prefix + node.getID()];
-            node.data = node.source.data;
-            node.sourceType = projectObj.project.Bills.getSourceType();
+          rst = -1;
         }
-        ProjectController.syncDisplayNewNodes(projectObj.mainController, newNodes, true);
-        return newNodes;
-    },
-    getBillsPostData: function (number) {
-        const project = projectObj.project;
-        const target = project.getParentTarget(project.mainTree.selected, 'sourceType', project.Bills.getSourceType());
-        const baseParentID = target.depth() === 0 ? target.source.getID() : target.source.getParentID();
-        const baseNextID = target.depth() === 0 ? -1 : target.source.getNextSiblingID();
-        const updateNode = target.depth() === 0 ? target.source.children[target.source.children.length - 1] : target;
-        const insertData = [];
-        for (let i = 0; i < number; i++) {
-            const data = {
-                type: billType.BILL,
-                projectID: project.ID(),
-                ID: uuid.v1(),
-                ParentID: baseParentID,
-            };
-            const pre = insertData[i - 1];
-            if (pre) {
-                pre.NextSiblingID = data.ID;
-            }
-            if (i === number - 1) {
-                data.NextSiblingID = baseNextID;
-            }
-            insertData.push(data);
-        }
-        const postData = insertData.map(item => ({
-            updateType: 'create',
-            updateData: item
-        }));
-        if (updateNode) {
-            postData.push({ updateType: 'update', updateData: { ID: updateNode.getID(), NextSiblingID: insertData[0].ID } });
-        }
-        return postData;
-    },
-    addBills: function (project, sheetController, std) {
-        if (!project || !sheetController) { return null; }
-        let target = project.getParentTarget(project.mainTree.selected, 'sourceType', project.Bills.getSourceType());
-        let newSource = null, newNode = null, parentID, nextSiblingID, nodeParentID, nodeNextSiblingID;
-        if (target) {
-            if(target.depth() === 0){
-                parentID = target.source.getID();
-                nextSiblingID = project.Bills.tree.setting.rootId;
-                nodeParentID = target.getID();
-                nodeNextSiblingID = project.mainTree.rootID();
-            } else{
-                parentID = target.source.getParentID();
-                nextSiblingID = target.source.getNextSiblingID();
-                nodeParentID = target.getParentID();
-                nodeNextSiblingID = target.getNextSiblingID();
-            }
-            parentID = target.depth() === 0 ? target.source.getID() : target.source.getParentID();
-            nextSiblingID = target.depth() === 0 ? project.Bills.tree.setting.rootId : target.source.getNextSiblingID();
+        return rst;
+      });
+      let lastNode = null;
+      for (let newNode of newNodes) {
+        sc.sheet.addRows(newNode.serialNo(), 1);
+        TREE_SHEET_HELPER.refreshTreeNodeData(sc.setting, sc.sheet, [newNode], false);
+        lastNode = newNode
+        // sc.sheet.showRow(newNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
+      }
+      if (withOutSelect == false && lastNode) {
+        sc.setTreeSelected(lastNode);
+        sc.sheet.setSelection(lastNode.serialNo(), sels[0].col, 1, 1);
+      }
 
-            if (std) {
-                let fixedNode = getRootFixedNode(target);
-                if(!isFlag(fixedNode.data) || (fixedNode.data.flagsIndex.fixed.flag !== fixedFlag.SUB_ENGINERRING && fixedNode.data.flagsIndex.fixed.flag !== fixedFlag.MEASURE)){
-                    return false;
-                }
-                //焦点行属于分部分项
-                if(fixedNode.data.flagsIndex.fixed.flag === fixedFlag.SUB_ENGINERRING){
-                    std.type = billType.FX;
-                    //焦点行是分部分项
-                    let subType = getSubType(target);
-                    if(target.sourceType === project.Bills.getSourceType() && target.data.type === billType.DXFY && subType === billType.FB){
-                        return false;
-                    } else if(target.sourceType === project.Bills.getSourceType() && target.data.type === billType.FB){//焦点行是分部
-                        if(!subType || subType === billType.FX){
-                            parentID = target.source.getID();
-                            nextSiblingID = project.Bills.tree.setting.rootId;
-                            nodeParentID = target.getID();
-                            nodeNextSiblingID = project.mainTree.rootID();
-                        } else{
-                            return false;
-                        }
-                    }
-                } else {
-                    std.type = billType.BILL;
-                }
+      cbTools.refreshFormulaNodes();
+      if (callback) callback();
+    });
+  },
+  syncDisplayNewRationGljNode: function (sc, newNode) {
+    TREE_SHEET_HELPER.massOperationSheet(sc.sheet, function () {
+      sc.sheet.addRows(newNode.serialNo(), 1);
+      TREE_SHEET_HELPER.refreshTreeNodeData(sc.setting, sc.sheet, [newNode], false);
+      // sc.sheet.showRow(newNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
+      cbTools.refreshFormulaNodes();
+    });
+  },
+  /* addBillsByData: async function (postData, insertFunc) {
+      await ajaxPost('/bills/insertBills', { postData });
+      // 插入
+      const insertData = postData.filter(item => item.updateType === 'create');
+      const treeData = insertData.map(item => item.updateData);
+      // 插入清单节点
+      if (!insertFunc) {
+          insertFunc = projectObj.project.Bills.tree.insertByDatas;
+      }
+      projectObj.project.Bills.tree.insertByDatas(treeData);
+      projectObj.project.Bills.datas = projectObj.project.Bills.datas.concat(treeData);
+      // 插入主树节点
+      const newNodes = projectObj.project.mainTree.insertByDatas(treeData);
+      for (const node of newNodes) {
+          node.source = projectObj.project.Bills.tree.nodes[projectObj.project.Bills.tree.prefix + node.getID()];
+          node.data = node.source.data;
+          node.sourceType = projectObj.project.Bills.getSourceType();
+      }
+      ProjectController.syncDisplayNewNodes(projectObj.mainController, newNodes, true);
+      return newNodes;
+  }, */
+  addBillsByData: async function (postData, isSameDepth = false) {
+    await ajaxPost('/bills/insertBills', {
+      postData
+    });
+    // 插入
+    const insertData = postData.filter(item => item.updateType === 'create');
+    const treeData = insertData.map(item => item.updateData);
+    // 插入清单节点和主树节点
+    projectObj.project.Bills.datas = projectObj.project.Bills.datas.concat(treeData);
+    let newNodes;
+    if (isSameDepth) {
+      const pre = postData.find(item => item.updateType === 'update');
+      const preID = pre && pre.updateData.ID || null;
+      projectObj.project.Bills.tree.multiInsert(treeData, preID);
+      newNodes = projectObj.project.mainTree.multiInsert(treeData, preID);
+    } else {
+      projectObj.project.Bills.tree.insertByDatas(treeData);
+      newNodes = projectObj.project.mainTree.insertByDatas(treeData);
+    }
+    for (const node of newNodes) {
+      node.source = projectObj.project.Bills.tree.nodes[projectObj.project.Bills.tree.prefix + node.getID()];
+      node.data = node.source.data;
+      node.sourceType = projectObj.project.Bills.getSourceType();
+    }
+    ProjectController.syncDisplayNewNodes(projectObj.mainController, newNodes, true);
+    return newNodes;
+  },
+  getBillsPostData: function (number) {
+    const project = projectObj.project;
+    const target = project.getParentTarget(project.mainTree.selected, 'sourceType', project.Bills.getSourceType());
+    const baseParentID = target.depth() === 0 ? target.source.getID() : target.source.getParentID();
+    const baseNextID = target.depth() === 0 ? -1 : target.source.getNextSiblingID();
+    const updateNode = target.depth() === 0 ? target.source.children[target.source.children.length - 1] : target;
+    const insertData = [];
+    for (let i = 0; i < number; i++) {
+      const data = {
+        type: billType.BILL,
+        unitPriceAnalysis: 1,
+        projectID: project.ID(),
+        ID: uuid.v1(),
+        ParentID: baseParentID,
+      };
+      const pre = insertData[i - 1];
+      if (pre) {
+        pre.NextSiblingID = data.ID;
+      }
+      if (i === number - 1) {
+        data.NextSiblingID = baseNextID;
+      }
+      insertData.push(data);
+    }
+    const postData = insertData.map(item => ({
+      updateType: 'create',
+      updateData: item
+    }));
+    if (updateNode) {
+      postData.push({
+        updateType: 'update',
+        updateData: {
+          ID: updateNode.getID(),
+          NextSiblingID: insertData[0].ID
+        }
+      });
+    }
+    return postData;
+  },
+  addBills: function (project, sheetController, std) {
+    if (!project || !sheetController) {
+      return null;
+    }
+    let target = project.getParentTarget(project.mainTree.selected, 'sourceType', project.Bills.getSourceType());
+    let newSource = null,
+      newNode = null,
+      parentID, nextSiblingID, nodeParentID, nodeNextSiblingID;
+    if (target) {
+      if (target.depth() === 0) {
+        parentID = target.source.getID();
+        nextSiblingID = project.Bills.tree.setting.rootId;
+        nodeParentID = target.getID();
+        nodeNextSiblingID = project.mainTree.rootID();
+      } else {
+        parentID = target.source.getParentID();
+        nextSiblingID = target.source.getNextSiblingID();
+        nodeParentID = target.getParentID();
+        nodeNextSiblingID = target.getNextSiblingID();
+      }
+      parentID = target.depth() === 0 ? target.source.getID() : target.source.getParentID();
+      nextSiblingID = target.depth() === 0 ? project.Bills.tree.setting.rootId : target.source.getNextSiblingID();
 
-                let newCode = project.Bills.newFormatCode(std.code);
-                newSource = project.Bills.insertStdBills(parentID, nextSiblingID, std, newCode);
+      if (std) {
+        let fixedNode = getRootFixedNode(target);
+        if (!isFlag(fixedNode.data) || (fixedNode.data.flagsIndex.fixed.flag !== fixedFlag.SUB_ENGINERRING && fixedNode.data.flagsIndex.fixed.flag !== fixedFlag.MEASURE)) {
+          return false;
+        }
+        //焦点行属于分部分项
+        if (fixedNode.data.flagsIndex.fixed.flag === fixedFlag.SUB_ENGINERRING) {
+          std.type = billType.FX;
+          //焦点行是分部分项
+          let subType = getSubType(target);
+          if (target.sourceType === project.Bills.getSourceType() && target.data.type === billType.DXFY && subType === billType.FB) {
+            return false;
+          } else if (target.sourceType === project.Bills.getSourceType() && target.data.type === billType.FB) { //焦点行是分部
+            if (!subType || subType === billType.FX) {
+              parentID = target.source.getID();
+              nextSiblingID = project.Bills.tree.setting.rootId;
+              nodeParentID = target.getID();
+              nodeNextSiblingID = project.mainTree.rootID();
             } else {
-                newSource = project.Bills.insertBills(parentID, nextSiblingID);
+              return false;
             }
-            newNode = project.mainTree.insert(nodeParentID, nodeNextSiblingID, newSource.data.ID);
+          }
         } else {
-            alert('不可添加清单');
+          std.type = billType.BILL;
         }
 
-        if (newNode) {
-            newNode.source = newSource;
-            newNode.sourceType = project.Bills.getSourceType();
-            newNode.data = newSource.data;
+        let newCode = project.Bills.newFormatCode(std.code);
+        newSource = project.Bills.insertStdBills(parentID, nextSiblingID, std, newCode);
+      } else {
+        newSource = project.Bills.insertBills(parentID, nextSiblingID);
+      }
+      newNode = project.mainTree.insert(nodeParentID, nodeNextSiblingID, newSource.data.ID);
+    } else {
+      alert('不可添加清单');
+    }
 
-            this.syncDisplayNewNode(sheetController, newNode);
-            return newNode;
-        }
-        function getSubType(node){
-            for(let sub of node.children){
-                if(sub.sourceType === project.Bills.getSourceType() && sub.data.type === billType.FB){
-                    return billType.FB;
-                }
-                else if(sub.sourceType === project.Bills.getSourceType() && sub.data.type === billType.FX){
-                    return billType.FX;
-                }
-            }
-            return null;
-        }
-    },
-    addRootBill:function (project, sheetController) {//添加大项费用
-        if (!project || !sheetController) { return null; }
-        this.addSpecialBill(project, sheetController,null, project.mainTree.selected.nextSibling,true,billType.DXFY);
-    },
-    addFB:function(project, sheetController) {//添加分部
-        if (!project || !sheetController) { return null; }
-        let selected = project.mainTree.selected;
-        if(selected.parent==null&&isFlag(selected.data)&&selected.data.flagsIndex.fixed.flag==fixedFlag.SUB_ENGINERRING){//选中的是分部分项,则插入做为最后一个子项
-            return this.addSpecialBill(project, sheetController,selected, null,true,billType.FB);
-        }
-        if(selected.parent){
-            return this.addSpecialBill(project, sheetController,selected.parent, selected.nextSibling,true,billType.FB);
-        }
+    if (newNode) {
+      newNode.source = newSource;
+      newNode.sourceType = project.Bills.getSourceType();
+      newNode.data = newSource.data;
 
-    },
-    addFX:function(project, sheetController) {//添加分项
-        if (!project || !sheetController) { return null; }
-        let selected = project.mainTree.selected;
-        console.log(selected);
-        if(selected.data.type==billType.FB||(selected.parent==null&&isFlag(selected.data)&&selected.data.flagsIndex.fixed.flag==fixedFlag.SUB_ENGINERRING)){//选中的是分部或者是分部分项工程,则插入做为最后一个子项
-            return this.addSpecialBill(project, sheetController,selected, null,true,billType.FX);
-        }
-        if(selected.parent){
-            if(selected.data.type==billType.FX||selected.data.type==billType.BX){
-                return this.addSpecialBill(project, sheetController,selected.parent, selected.nextSibling,true,billType.FX);
-            }
-        }
-    },
-    addSpecialBill(project,sheetController,parent,nextSibling,isUserAdd,type){
-        let newNode = null;
-        let b_nexID = nextSibling==null?-1:nextSibling.source.getID();//主树和清单树,对应的树节点ID不一样
-        let m_nexID = nextSibling==null?-1:nextSibling.getID();
-        let b_parent = parent==null?-1:parent.source.getID();
-        let m_parent = parent==null?-1:parent.getID();
+      this.syncDisplayNewNode(sheetController, newNode);
+      return newNode;
+    }
 
-        let newSource = project.Bills.insertSpecialBill(b_parent, b_nexID,isUserAdd,type);
-        newNode = project.mainTree.insert(m_parent,m_nexID, newSource.data.ID);
-        if (newNode) {
-            newNode.source = newSource;
-            newNode.sourceType = project.Bills.getSourceType();
-            newNode.data = newSource.data;
-            this.syncDisplayNewNode(sheetController, newNode);
-            return newNode;
+    function getSubType(node) {
+      for (let sub of node.children) {
+        if (sub.sourceType === project.Bills.getSourceType() && sub.data.type === billType.FB) {
+          return billType.FB;
+        } else if (sub.sourceType === project.Bills.getSourceType() && sub.data.type === billType.FX) {
+          return billType.FX;
         }
-    },
+      }
+      return null;
+    }
+  },
+  addRootBill: function (project, sheetController) { //添加大项费用
+    if (!project || !sheetController) {
+      return null;
+    }
+    this.addSpecialBill(project, sheetController, null, project.mainTree.selected.nextSibling, true, billType.DXFY);
+  },
+  addFB: function (project, sheetController) { //添加分部
+    if (!project || !sheetController) {
+      return null;
+    }
+    let selected = project.mainTree.selected;
+    if (selected.parent == null && isFlag(selected.data) && selected.data.flagsIndex.fixed.flag == fixedFlag.SUB_ENGINERRING) { //选中的是分部分项,则插入做为最后一个子项
+      return this.addSpecialBill(project, sheetController, selected, null, true, billType.FB);
+    }
+    if (selected.parent) {
+      return this.addSpecialBill(project, sheetController, selected.parent, selected.nextSibling, true, billType.FB);
+    }
 
-    addRation: function (project, sheetController, rationType, std) {
-        if (!project || !sheetController) { return; }
+  },
+  addFX: function (project, sheetController) { //添加分项
+    if (!project || !sheetController) {
+      return null;
+    }
+    let selected = project.mainTree.selected;
+    console.log(selected);
+    if (selected.data.type == billType.FB || (selected.parent == null && isFlag(selected.data) && selected.data.flagsIndex.fixed.flag == fixedFlag.SUB_ENGINERRING)) { //选中的是分部或者是分部分项工程,则插入做为最后一个子项
+      return this.addSpecialBill(project, sheetController, selected, null, true, billType.FX);
+    }
+    if (selected.parent) {
+      if (selected.data.type == billType.FX || selected.data.type == billType.BX) {
+        return this.addSpecialBill(project, sheetController, selected.parent, selected.nextSibling, true, billType.FX);
+      }
+    }
+  },
+  addSpecialBill(project, sheetController, parent, nextSibling, isUserAdd, type) {
+    let newNode = null;
+    let b_nexID = nextSibling == null ? -1 : nextSibling.source.getID(); //主树和清单树,对应的树节点ID不一样
+    let m_nexID = nextSibling == null ? -1 : nextSibling.getID();
+    let b_parent = parent == null ? -1 : parent.source.getID();
+    let m_parent = parent == null ? -1 : parent.getID();
 
-        let selected = project.mainTree.selected, newSource = null, newNode = null;
-        if (selected === null) { return; }
+    let newSource = project.Bills.insertSpecialBill(b_parent, b_nexID, isUserAdd, type);
+    newNode = project.mainTree.insert(m_parent, m_nexID, newSource.data.ID);
+    if (newNode) {
+      newNode.source = newSource;
+      newNode.sourceType = project.Bills.getSourceType();
+      newNode.data = newSource.data;
+      this.syncDisplayNewNode(sheetController, newNode);
+      return newNode;
+    }
+  },
 
-        if (selected.sourceType === project.Bills.getSourceType() && selected.depth() > 0) {
-            if (selected.source.children.length > 0) {
-                alert('当前清单已有清单子项,不能套用定额。');
-            } else if (selected.data.calcBase&&selected.data.calcBase!="") {
-                alert('当前有基数计算,不能插入定额/量价/人材机。');
-            } else {
-                if(selected.data.type === billType.FB){
-                    return;
-                }
-                if (std) {
-                    newSource = project.Ration.insertStdRation(selected.source.getID(), null, std);
-                    project.ration_glj.addRationGLJ(newSource,std);
-                } else {
-                    newSource = project.Ration.insertRation(selected.source.getID(),null, rationType);
-                }
-                newNode = project.mainTree.insert(selected.getID(), selected.tree.rootID(), newSource.ID);
-            }
-        } else if (selected.sourceType === project.Ration.getSourceType()) {
-            if (std) {
-                newSource = project.Ration.insertStdRation(selected.source[project.masterField.ration], selected.source, std);
-                project.ration_glj.addRationGLJ(newSource,std);
-            } else {
-                newSource = project.Ration.insertRation(selected.source[project.masterField.ration], selected.source, rationType);
-            }
-            newNode = project.mainTree.insert(selected.getParentID(), selected.getNextSiblingID(), newSource.ID);
-        };
-        if (newNode) {
-            newNode.source = newSource;
-            newNode.sourceType = project.Ration.getSourceType();
-            newNode.data = newSource;
+  addRation: function (project, sheetController, rationType, std) {
+    if (!project || !sheetController) {
+      return;
+    }
 
-            this.syncDisplayNewNode(sheetController, newNode);
+    let selected = project.mainTree.selected,
+      newSource = null,
+      newNode = null;
+    if (selected === null) {
+      return;
+    }
 
+    if (selected.sourceType === project.Bills.getSourceType() && selected.depth() > 0) {
+      if (selected.source.children.length > 0) {
+        alert('当前清单已有清单子项,不能套用定额。');
+      } else if (selected.data.calcBase && selected.data.calcBase != "") {
+        alert('当前有基数计算,不能插入定额/量价/人材机。');
+      } else {
+        if (selected.data.type === billType.FB) {
+          return;
         }
-    },
-    replaceRation: function (project, sheetController, std) {
-        if (!project || !sheetController) { return; }
-
-        let selected = project.mainTree.selected, newSource = null, newNode = null;
-        if (selected === null) { return; }
-
-        if (  selected.sourceType === project.Ration.getSourceType()) {
-            project.Ration.replaceRation(selected.source, std);
-            project.ration_glj.addRationGLJ(selected.source, std);
-            sheetController.refreshTreeNode([selected], false);
+        if (std) {
+          newSource = project.Ration.insertStdRation(selected.source.getID(), null, std);
+          project.ration_glj.addRationGLJ(newSource, std);
         } else {
-            alert('当前焦点行不是定额,无法替换。');
+          newSource = project.Ration.insertRation(selected.source.getID(), null, rationType);
         }
-    },
-    addNewNodes:function (updateData){
-        let controller = projectObj.mainController;
-        let Bill = projectObj.project.Bills;
-        let newAddNode = [];
-        let newRationNodes = [];
-        for(let nb of updateData.bills.add){
-            let newSource = Bill.tree.insertByData(nb, nb.ParentID, -1, true);//按顺序插入的情况下,nextID为-1,树节点
-            let newNode = projectObj.project.mainTree.insert(nb.ParentID, -1, newSource.data.ID);
-            newNode.source = newSource;
-            newNode.sourceType = Bill.getSourceType();
-            newNode.data = newSource.data;
-            controller.sheet.addRows(newNode.serialNo(), 1);
-           // controller.sheet.showRow(newNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
-            newAddNode.push(newNode);
-            Bill.datas.push(nb);
-        }
-        for(let nr of updateData.ration.add){
-            let newNode = projectObj.project.mainTree.insert(nr.billsItemID, -1, nr.ID);
-            newNode.source = nr;
-            newNode.sourceType = projectObj.project.Ration.getSourceType();
-            newNode.data = nr;
-            controller.sheet.addRows(newNode.serialNo(), 1);
-           // controller.sheet.showRow(newNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
-            newAddNode.push(newNode);
-            newRationNodes.push(newNode);
-            projectObj.project.Ration.datas.push(nr);
-        }
-        TREE_SHEET_HELPER.refreshTreeNodeData(controller.setting, controller.sheet, newAddNode, false);
-        return newRationNodes;
+        newNode = project.mainTree.insert(selected.getID(), selected.tree.rootID(), newSource.ID);
+      }
+    } else if (selected.sourceType === project.Ration.getSourceType()) {
+      if (std) {
+        newSource = project.Ration.insertStdRation(selected.source[project.masterField.ration], selected.source, std);
+        project.ration_glj.addRationGLJ(newSource, std);
+      } else {
+        newSource = project.Ration.insertRation(selected.source[project.masterField.ration], selected.source, rationType);
+      }
+      newNode = project.mainTree.insert(selected.getParentID(), selected.getNextSiblingID(), newSource.ID);
+    };
+    if (newNode) {
+      newNode.source = newSource;
+      newNode.sourceType = project.Ration.getSourceType();
+      newNode.data = newSource;
+
+      this.syncDisplayNewNode(sheetController, newNode);
+
+    }
+  },
+  replaceRation: function (project, sheetController, std) {
+    if (!project || !sheetController) {
+      return;
     }
-/*    addVolumePrice: function (project, sheetController) {
-        if (!project || !sheetController) { return null; }
 
-        var selected = project.mainTree.selected;
-        var newSource = null, newNode = null;
-        if(selected === null) {
-            return;
-        }
+    let selected = project.mainTree.selected,
+      newSource = null,
+      newNode = null;
+    if (selected === null) {
+      return;
+    }
 
-        if (selected.sourceType === project.Bills.getSourceType() && selected.source.children.length === 0) {
-            newSource = project.VolumePrice.insertVolumePrice(selected.source.getID());
-            newNode = project.mainTree.insert(selected.getID(), selected.tree.rootID());
-        } else if (selected.sourceType === project.Ration.getSourceType() || selected.sourceType === project.VolumePrice.getSourceType()) {
-            newSource = project.VolumePrice.insertVolumePrice(selected.source[project.masterField.volumePrice], selected.source);
-            newNode = project.mainTree.insert(selected.getParentID(), selected.getNextSiblingID());
-        }
-        if (newNode) {
-            newNode.source = newSource;
-            newNode.sourceType = project.VolumePrice.getSourceType();
-            newNode.data = newSource;
+    if (selected.sourceType === project.Ration.getSourceType()) {
+      project.Ration.replaceRation(selected.source, std);
+      project.ration_glj.addRationGLJ(selected.source, std);
+      sheetController.refreshTreeNode([selected], false);
+    } else {
+      alert('当前焦点行不是定额,无法替换。');
+    }
+  },
+  addNewNodes: function (updateData) {
+    let controller = projectObj.mainController;
+    let Bill = projectObj.project.Bills;
+    let newAddNode = [];
+    let newRationNodes = [];
+    for (let nb of updateData.bills.add) {
+      let newSource = Bill.tree.insertByData(nb, nb.ParentID, -1, true); //按顺序插入的情况下,nextID为-1,树节点
+      let newNode = projectObj.project.mainTree.insert(nb.ParentID, -1, newSource.data.ID);
+      newNode.source = newSource;
+      newNode.sourceType = Bill.getSourceType();
+      newNode.data = newSource.data;
+      controller.sheet.addRows(newNode.serialNo(), 1);
+      // controller.sheet.showRow(newNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
+      newAddNode.push(newNode);
+      Bill.datas.push(nb);
+    }
+    for (let nr of updateData.ration.add) {
+      let newNode = projectObj.project.mainTree.insert(nr.billsItemID, -1, nr.ID);
+      newNode.source = nr;
+      newNode.sourceType = projectObj.project.Ration.getSourceType();
+      newNode.data = nr;
+      controller.sheet.addRows(newNode.serialNo(), 1);
+      // controller.sheet.showRow(newNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
+      newAddNode.push(newNode);
+      newRationNodes.push(newNode);
+      projectObj.project.Ration.datas.push(nr);
+    }
+    TREE_SHEET_HELPER.refreshTreeNodeData(controller.setting, controller.sheet, newAddNode, false);
+    return newRationNodes;
+  }
+  /*    addVolumePrice: function (project, sheetController) {
+          if (!project || !sheetController) { return null; }
 
-            this.syncDisplayNewNode(sheetController, newNode);
-        }
-    },*/
-/*    calculateAll: function (project, sheetController, CalcType) {
-        this.project.setCalcFlag(CalcType);
-        let calc = new BillsCalcHelper(project);
-        calc.calcAll();
-        sheetController.showTreeData();
-        project.Bills.updateAll();
-        calc = null;
-    }*/
-}
+          var selected = project.mainTree.selected;
+          var newSource = null, newNode = null;
+          if(selected === null) {
+              return;
+          }
+
+          if (selected.sourceType === project.Bills.getSourceType() && selected.source.children.length === 0) {
+              newSource = project.VolumePrice.insertVolumePrice(selected.source.getID());
+              newNode = project.mainTree.insert(selected.getID(), selected.tree.rootID());
+          } else if (selected.sourceType === project.Ration.getSourceType() || selected.sourceType === project.VolumePrice.getSourceType()) {
+              newSource = project.VolumePrice.insertVolumePrice(selected.source[project.masterField.volumePrice], selected.source);
+              newNode = project.mainTree.insert(selected.getParentID(), selected.getNextSiblingID());
+          }
+          if (newNode) {
+              newNode.source = newSource;
+              newNode.sourceType = project.VolumePrice.getSourceType();
+              newNode.data = newSource;
+
+              this.syncDisplayNewNode(sheetController, newNode);
+          }
+      },*/
+  /*    calculateAll: function (project, sheetController, CalcType) {
+          this.project.setCalcFlag(CalcType);
+          let calc = new BillsCalcHelper(project);
+          calc.calcAll();
+          sheetController.showTreeData();
+          project.Bills.updateAll();
+          calc = null;
+      }*/
+}

Plik diff jest za duży
+ 1388 - 1370
web/building_saas/main/js/models/calc_base.js


Plik diff jest za duży
+ 2609 - 2541
web/building_saas/main/js/models/calc_program.js


+ 14 - 14
web/building_saas/main/js/views/config_material_view.js

@@ -1218,20 +1218,20 @@ let pgljSelObj = {
         dataType: "String",
         cellType: 'checkBox'
       },
-      {
-        headerName: "产地",
-        headerWidth: 80,
-        dataCode: "originPlace",
-        hAlign: "left",
-        dataType: "String"
-      },
-      {
-        headerName: "厂家",
-        headerWidth: 80,
-        dataCode: "vender",
-        hAlign: "left",
-        dataType: "String"
-      },
+      /*  {
+         headerName: "产地",
+         headerWidth: 80,
+         dataCode: "originPlace",
+         hAlign: "left",
+         dataType: "String"
+       },
+       {
+         headerName: "厂家",
+         headerWidth: 80,
+         dataCode: "vender",
+         hAlign: "left",
+         dataType: "String"
+       }, */
       {
         headerName: "备注",
         headerWidth: 100,

+ 401 - 262
web/building_saas/main/js/views/electrovalence_view.js

@@ -2,297 +2,436 @@
  * Created by zhang on 2019/12/12.
  */
 let electrovalenceObj = {
-    setting:{
-        header:[
-            {headerName: "代号", headerWidth: 70, dataCode: "code", dataType: "String"},
-            {headerName: "名称", headerWidth: 150, dataCode: "displayName",dataType: "String"},
-            {headerName: "规格", headerWidth: 70, dataCode: "specs", dataType: "Number",validator:"number"},
-            {headerName: "预算价", headerWidth: 75, dataCode: "electPrice", hAlign: "right", dataType: "Number",validator:"number"},
-            {headerName: "加权系数", headerWidth: 80, dataCode: "coe", hAlign: "right", dataType: "Number",validator:"number"}
-        ],
-        view: {
-            lockColumns: ["code","specs"],
-            rowHeaderWidth:25,
-            colHeaderHeight:36
-        }
-    },
-    spread:null,
-    sheet:null,
-    datas:[],
-    total:0,
-    options:[
-        {code:"3005003",name:"电网电",specs:"",unit:"kW·h",type:"201"},
-        {code:"8017001",name:"5kW以内柴油发电机组",specs:"5GF1",unit:"台班",type:"301"},
-        {code:"8017002",name:"15kW以内柴油发电机组",specs:"12GF1",unit:"台班",type:"301"},
-        {code:"8017003",name:"30kW以内柴油发电机组",specs:"30GFY-2",unit:"台班",type:"301"},
-        {code:"8017004",name:"50kW以内柴油发电机组",specs:"50GFY-2",unit:"台班",type:"301"},
-        {code:"8017005",name:"75kW以内柴油发电机组",specs:"75GFY-4",unit:"台班",type:"301"},
-        {code:"8017006",name:"100kW以内柴油发电机组",specs:"90GFZ",unit:"台班",type:"301"},
-        {code:"8017007",name:"120kW以内柴油发电机组",specs:"120GFY-4",unit:"台班",type:"301"},
-        {code:"8017008",name:"160kW以内柴油发电机组",specs:"160GF",unit:"台班",type:"301"},
-        {code:"8017009",name:"200kW以内柴油发电机组",specs:"200GF",unit:"台班",type:"301"},
-        {code:"8017010",name:"250kW以内柴油发电机组",specs:"250GF4-4",unit:"台班",type:"301"},
-        {code:"8017011",name:"320kW以内柴油发电机组",specs:"320GF-2",unit:"台班",type:"301"}
+  setting: {
+    header: [{
+        headerName: "代号",
+        headerWidth: 70,
+        dataCode: "code",
+        dataType: "String"
+      },
+      {
+        headerName: "名称",
+        headerWidth: 150,
+        dataCode: "displayName",
+        dataType: "String"
+      },
+      {
+        headerName: "规格",
+        headerWidth: 70,
+        dataCode: "specs",
+        dataType: "Number",
+        validator: "number"
+      },
+      {
+        headerName: "预算价",
+        headerWidth: 75,
+        dataCode: "electPrice",
+        hAlign: "right",
+        dataType: "Number",
+        validator: "number"
+      },
+      {
+        headerName: "加权系数",
+        headerWidth: 80,
+        dataCode: "coe",
+        hAlign: "right",
+        dataType: "Number",
+        validator: "number"
+      }
     ],
-    initSpread:function () {
-        if(this.spread) return this.spread.refresh();
-        this.spread = SheetDataHelper.createNewSpread($("#electrovalence_sheet")[0]);
-        sheetCommonObj.spreadDefaultStyle(this.spread);
-        this.sheet = this.spread.getSheet(0);
-        sheetCommonObj.initSheet(this.sheet, this.setting, 30);
-        this.sheet.bind(GC.Spread.Sheets.Events.SelectionChanged,this.onElectrovalenceSelectionChange);
-        this.sheet.bind(GC.Spread.Sheets.Events.ValueChanged, this.onElectrovalenceValueChange);
-        this.sheet.bind(GC.Spread.Sheets.Events.EditStarting,this.onElectrovalenceEditStarting);
-        this.sheet.name('electrovalence_sheet');
-        if(projectReadOnly){
-            disableSpread(this.spread);
-        }
+    view: {
+      lockColumns: ["code", "specs"],
+      rowHeaderWidth: 25,
+      colHeaderHeight: 36
+    }
+  },
+  spread: null,
+  sheet: null,
+  datas: [],
+  total: 0,
+  options: [{
+      code: "3005003",
+      name: "电网电",
+      specs: "",
+      unit: "kW·h",
+      type: "201"
     },
-    showDatas:function (datas) {
-        let sel = this.sheet.getSelections()[0];
-        let oldData = sel.row<this.datas.length?this.datas[sel.row]:"";
-        this.sheet.setRowCount(0);
-        this.datas = datas?datas:this.getElectrovalenceDatas();
-        this.calcPertElectrovalenceMarketPrice(this.datas);
-        sheetCommonObj.showData(this.sheet, this.setting,this.datas);
-        this.sheet.setRowCount(this.datas.length+1);
-        let nameCol = _.findIndex(this.setting.header,{'dataCode':'displayName'});
-        let nameOptions = this.getElectrovalenceOptions();
-        sheetCommonObj.setComboBox(-1,nameCol,this.sheet,nameOptions,false,false,5);
-        sel.row =  oldData?_.findIndex(this.datas,{'ID':oldData.ID}):sel.row ;
-        this.sheet.setSelection(sel.row==-1?0:sel.row,sel.col,sel.rowCount,sel.colCount);
+    {
+      code: "8017001",
+      name: "5kW以内柴油发电机组",
+      specs: "5GF1",
+      unit: "台班",
+      type: "301"
     },
-    getElectrovalenceDatas:function (ext) {
-        let datas = [];
-        let pgljMap = {};
-        let com_electrovalence = projectObj.project.projectGLJ.datas.com_electrovalence;
-        for(let pg of projectObj.project.projectGLJ.datas.gljList){
-            pgljMap[gljUtil.getIndex(pg)] = pg;
-        }
-        if(com_electrovalence && com_electrovalence.gljList){
-            for (let g of com_electrovalence.gljList){
-                let t = this.createNewElectrovalenceData(g);
-                let tg = pgljMap[gljUtil.getIndex(g)];
-                if(tg) gljOprObj.setGLJPrice(t,tg,false,ext);
-                datas.push(t);
-            }
-        }
-        return datas;
+    {
+      code: "8017002",
+      name: "15kW以内柴油发电机组",
+      specs: "12GF1",
+      unit: "台班",
+      type: "301"
     },
-    createNewElectrovalenceData:function (g) {//只是拷贝一份
-        let t = {
-            ID:g.ID,
-            GLJID:g.GLJID,
-            projectGLJID:g.projectGLJID,
-            name:g.name,
-            displayName:g.displayName,
-            code:g.code,
-            specs:g.specs,
-            unit:g.unit,
-            type:g.type,
-            coe: g.coe,
-            from:g.from
-        };
-        return t;
+    {
+      code: "8017003",
+      name: "30kW以内柴油发电机组",
+      specs: "30GFY-2",
+      unit: "台班",
+      type: "301"
     },
-
-    calcPertElectrovalenceMarketPrice:function (datas,ext) {
-        let total = 0;
-        for(let d of datas){
-            if(ext && ext[d.projectGLJID] && gljUtil.isDef(ext[d.projectGLJID].marketPrice)) d.marketPrice = ext[d.projectGLJID].marketPrice;
-            if(d.name == "电网电"){
-                d.electPrice = d.marketPrice;
-            }else {
-                let w = parseInt(d.name);
-                if(!w) continue;
-                let t = scMathUtil.roundForObj(d.marketPrice/w,getDecimal("process"));
-                d.electPrice = scMathUtil.roundForObj(t * gljUtil.getElecCoe(),getDecimal("glj.unitPriceHasMix"));
-            }
-            let et = scMathUtil.roundForObj(d.electPrice * d.coe,getDecimal("process"));
-            total = scMathUtil.roundForObj(et + total,getDecimal("process"));
-        }
-        this.total = scMathUtil.roundForObj(total,getDecimal("glj.unitPriceHasMix"));
-        $("#electrovalenceLabel").text(`综合电价:${this.total}`);
-        return this.total;
+    {
+      code: "8017004",
+      name: "50kW以内柴油发电机组",
+      specs: "50GFY-2",
+      unit: "台班",
+      type: "301"
     },
-    clacNewElecPrice:function (ext) {
-        for(let g of projectObj.project.projectGLJ.datas.gljList){
-            if(g.code == gljUtil.getElecCode() && g.name == "电" && g.unit == "kW·h"){//更新电价
-                let datas  = this.getElectrovalenceDatas(ext);
-                if(datas.length > 0){
-                    let marketPrice = this.calcPertElectrovalenceMarketPrice(datas,ext);
-                    if(marketPrice && g.unit_price.market_price != marketPrice+'') return {projectGLJID:g.id,id:g.unit_price.id,'unit_price_file_id':g.unit_price.unit_price_file_id,doc:{'market_price':marketPrice+''}}
-                }
-            }
-        }
-        return null;
+    {
+      code: "8017005",
+      name: "75kW以内柴油发电机组",
+      specs: "75GFY-4",
+      unit: "台班",
+      type: "301"
     },
-    getElectrovalenceOptions:function () {
-        return _.map(this.options,"name")
+    {
+      code: "8017006",
+      name: "100kW以内柴油发电机组",
+      specs: "90GFZ",
+      unit: "台班",
+      type: "301"
     },
-    onElectrovalenceSelectionChange:function (sender,args) {
-        args.sheet.repaint();
+    {
+      code: "8017007",
+      name: "120kW以内柴油发电机组",
+      specs: "120GFY-4",
+      unit: "台班",
+      type: "301"
     },
-    onElectrovalenceEditStarting:function (sender,args) {
-        let me = electrovalenceObj;
-        let dataCode = me.setting.header[args.col].dataCode;
-        if(dataCode == "electPrice" ){//除电网电外,不可修改
-            let cancel = true;
-            if(me.datas[args.row] && me.datas[args.row].name == "电网电") cancel  = false;
-            args.cancel = cancel;
-        }
+    {
+      code: "8017008",
+      name: "160kW以内柴油发电机组",
+      specs: "160GF",
+      unit: "台班",
+      type: "301"
     },
-
-
-    onElectrovalenceValueChange:function (sender,args) {
-        let me = electrovalenceObj;
-        let dataCode = me.setting.header[args.col].dataCode;
-        let value = args.newValue;
-        if(dataCode == "displayName" && args.row >= me.datas.length) {//新增
-             me.addElectrovalence(value);
-        }else { //修改
-            let tem = me.datas[args.row];
-            if (value&&!sheetCommonObj.checkData(args.col,me.setting,value)) {
-                alert('输入的数据类型不对,请重新输入!');
-                return  me.showDatas(me.datas);
-            }
-            if(dataCode == 'coe' || dataCode == 'electPrice'){
-                let dec = dataCode == 'coe' ?getDecimal("process"):getDecimal("glj.unitPrice");
-                if(value){
-                    value = scMathUtil.roundForObj(value,dec);
-                }
-                tem[dataCode] = value;
-                if(dataCode == 'electPrice') tem.marketPrice = value;
-            }else if(dataCode == 'displayName'){//下拉替换
-                me.editElectrovalence(value,args.row,"replace");
-            }
-            me.showDatas(me.datas);
-        }
+    {
+      code: "8017009",
+      name: "200kW以内柴油发电机组",
+      specs: "200GF",
+      unit: "台班",
+      type: "301"
     },
-    addElectrovalence:async function (name) {
-        this.editElectrovalence(name);
+    {
+      code: "8017010",
+      name: "250kW以内柴油发电机组",
+      specs: "250GF4-4",
+      unit: "台班",
+      type: "301"
     },
-    editElectrovalence:async function (name,row,type="add") {
-        //新建项目的时候,电已经默认生成了,所以不用考考虑电没有的情况
-        try {
-            let glj = _.find(this.options,{name:name});
-            if(glj){
-                let tem = {displayName:glj.name,code:glj.code,specs:glj.specs,unit:glj.unit,type:glj.type,projectID : projectObj.project.ID()};
-                tem.ID = uuid.v1();
-                $.bootstrapLoading.start();
-                let result =  await ajaxPost('/glj/insertElectrovalence',tem);
-                //插入项目工料机列表
-                if(type == "add" && (!result.projetcGLJData || result.projetcGLJData.length == 0)){
-                   alert("没有找到该工料机,请检查工料机库");
-                   return  this.showDatas(this.datas);
-                }
-                let newProjectPGJ = projectObj.project.projectGLJ.loadNewProjectGLJToCache(result.projetcGLJData);
-                //加入综合电价显示列表缓存
-                tem.GLJID = result.projetcGLJData.glj_id;
-                tem.projectGLJID = result.projetcGLJData.id;
-                tem.name =  result.projetcGLJData.name;
-                tem.coe = 0;
-                tem.from = "std";
-                gljOprObj.setGLJPrice(tem,newProjectPGJ);
+    {
+      code: "8017011",
+      name: "320kW以内柴油发电机组",
+      specs: "320GF-2",
+      unit: "台班",
+      type: "301"
+    }
+  ],
+  initSpread: function () {
+    if (this.spread) return this.spread.refresh();
+    this.spread = SheetDataHelper.createNewSpread($("#electrovalence_sheet")[0]);
+    sheetCommonObj.spreadDefaultStyle(this.spread);
+    this.sheet = this.spread.getSheet(0);
+    sheetCommonObj.initSheet(this.sheet, this.setting, 30);
+    this.sheet.bind(GC.Spread.Sheets.Events.SelectionChanged, this.onElectrovalenceSelectionChange);
+    this.sheet.bind(GC.Spread.Sheets.Events.ValueChanged, this.onElectrovalenceValueChange);
+    this.sheet.bind(GC.Spread.Sheets.Events.EditStarting, this.onElectrovalenceEditStarting);
+    this.sheet.name('electrovalence_sheet');
+    if (projectReadOnly) {
+      disableSpread(this.spread);
+    }
+  },
+  showDatas: function (datas) {
+    let sel = this.sheet.getSelections()[0];
+    let oldData = sel.row < this.datas.length ? this.datas[sel.row] : "";
+    this.sheet.setRowCount(0);
+    this.datas = datas ? datas : this.getElectrovalenceDatas();
+    this.calcPertElectrovalenceMarketPrice(this.datas);
+    sheetCommonObj.showData(this.sheet, this.setting, this.datas);
+    this.sheet.setRowCount(this.datas.length + 1);
+    let nameCol = _.findIndex(this.setting.header, {
+      'dataCode': 'displayName'
+    });
+    let nameOptions = this.getElectrovalenceOptions();
+    sheetCommonObj.setComboBox(-1, nameCol, this.sheet, nameOptions, false, false, 5);
+    sel.row = oldData ? _.findIndex(this.datas, {
+      'ID': oldData.ID
+    }) : sel.row;
+    this.sheet.setSelection(sel.row == -1 ? 0 : sel.row, sel.col, sel.rowCount, sel.colCount);
+  },
+  getElectrovalenceDatas: function (ext, tcom_electrovalence, tgljList) {
+    let datas = [];
+    let pgljMap = {};
+    let com_electrovalence = tcom_electrovalence ? tcom_electrovalence : projectObj.project.projectGLJ.datas.com_electrovalence;
+    let gljList = tgljList ? tgljList : projectObj.project.projectGLJ.datas.gljList;
+    for (let pg of gljList) {
+      pgljMap[gljUtil.getIndex(pg)] = pg;
+    }
+    if (com_electrovalence && com_electrovalence.gljList) {
+      for (let g of com_electrovalence.gljList) {
+        let t = this.createNewElectrovalenceData(g);
+        let tg = pgljMap[gljUtil.getIndex(g)];
+        if (tg) gljOprObj.setGLJPrice(t, tg, false, ext);
+        datas.push(t);
+      }
+    }
+    return datas;
+  },
+  createNewElectrovalenceData: function (g) { //只是拷贝一份
+    let t = {
+      ID: g.ID,
+      GLJID: g.GLJID,
+      projectGLJID: g.projectGLJID,
+      name: g.name,
+      displayName: g.displayName,
+      code: g.code,
+      specs: g.specs,
+      unit: g.unit,
+      type: g.type,
+      coe: g.coe,
+      from: g.from
+    };
+    return t;
+  },
 
-                if(type == "add"){
-                    this.datas.push(tem);
-                }else { //除了添加的就是替换
-                    if(this.datas[row])this.datas[row]=tem;
-                }
-                this.showDatas(this.datas);
+  calcPertElectrovalenceMarketPrice: function (datas, ext) {
+    let total = 0;
+    for (let d of datas) {
+      if (ext && ext[d.projectGLJID] && gljUtil.isDef(ext[d.projectGLJID].marketPrice)) d.marketPrice = ext[d.projectGLJID].marketPrice;
+      if (d.name == "电网电") {
+        d.electPrice = d.marketPrice;
+      } else {
+        let w = parseInt(d.name);
+        if (!w) continue;
+        let t = scMathUtil.roundForObj(d.marketPrice / w, getDecimal("process"));
+        d.electPrice = scMathUtil.roundForObj(t * gljUtil.getElecCoe(), getDecimal("glj.unitPriceHasMix"));
+      }
+      let et = scMathUtil.roundForObj(d.electPrice * d.coe, getDecimal("process"));
+      total = scMathUtil.roundForObj(et + total, getDecimal("process"));
+    }
+    this.total = scMathUtil.roundForObj(total, getDecimal("glj.unitPriceHasMix"));
+    $("#electrovalenceLabel").text(`综合电价:${this.total}`);
+    return this.total;
+  },
+  clacNewElecPrice: function (ext) {
+    for (let g of projectObj.project.projectGLJ.datas.gljList) {
+      if (g.code == gljUtil.getElecCode() && g.name == "电" && g.unit == "kW·h") { //更新电价
+        let datas = this.getElectrovalenceDatas(ext);
+        if (datas.length > 0) {
+          let marketPrice = this.calcPertElectrovalenceMarketPrice(datas, ext);
+          if (marketPrice && g.unit_price.market_price != marketPrice + '') return {
+            projectGLJID: g.id,
+            id: g.unit_price.id,
+            'unit_price_file_id': g.unit_price.unit_price_file_id,
+            doc: {
+              'market_price': marketPrice + ''
             }
-        }catch (e){
-            console.log(e)
-        }finally {
-            //materialCalcObj.showDatas();
-            $.bootstrapLoading.end();
+          }
         }
-    },
-    getGljListFromDatas:function (datas) {
-        let gljList = [];
-        for(let d of datas){
-            gljList.push(this.createNewElectrovalenceData(d));
+      }
+    }
+    return null;
+  },
+  getElectrovalenceOptions: function () {
+    return _.map(this.options, "name")
+  },
+  onElectrovalenceSelectionChange: function (sender, args) {
+    args.sheet.repaint();
+  },
+  onElectrovalenceEditStarting: function (sender, args) {
+    let me = electrovalenceObj;
+    let dataCode = me.setting.header[args.col].dataCode;
+    if (dataCode == "electPrice") { //除电网电外,不可修改
+      let cancel = true;
+      if (me.datas[args.row] && me.datas[args.row].name == "电网电") cancel = false;
+      args.cancel = cancel;
+    }
+  },
+
+
+  onElectrovalenceValueChange: function (sender, args) {
+    let me = electrovalenceObj;
+    let dataCode = me.setting.header[args.col].dataCode;
+    let value = args.newValue;
+    if (dataCode == "displayName" && args.row >= me.datas.length) { //新增
+      me.addElectrovalence(value);
+    } else { //修改
+      let tem = me.datas[args.row];
+      if (value && !sheetCommonObj.checkData(args.col, me.setting, value)) {
+        alert('输入的数据类型不对,请重新输入!');
+        return me.showDatas(me.datas);
+      }
+      if (dataCode == 'coe' || dataCode == 'electPrice') {
+        let dec = dataCode == 'coe' ? getDecimal("process") : getDecimal("glj.unitPrice");
+        if (value) {
+          value = scMathUtil.roundForObj(value, dec);
         }
-        return gljList;
-    },
-    updateElectrovalence:function () {
-        let updateMap = {};
-        let dwd = null;//电网电
-        let com_electrovalence = projectObj.project.projectGLJ.datas.com_electrovalence;
-        if(com_electrovalence){//存在则是更新
-            updateMap['electrovalence'] = {
-                actionType:'update',
-                ID:com_electrovalence.ID,
-                doc:{gljList:this.getGljListFromDatas(this.datas)}
-            };
-        }else { //不存在则是新增
-            updateMap['electrovalence'] = {
-                actionType:'add',
-                doc:{
-                    unit_price_file_id:projectObj.project.property.unitPriceFile.id,
-                    gljList:this.getGljListFromDatas(this.datas)
-                }
-            };
-            updateMap['electrovalence']['doc'].ID = uuid.v1();
+        tem[dataCode] = value;
+        if (dataCode == 'electPrice') tem.marketPrice = value;
+      } else if (dataCode == 'displayName') { //下拉替换
+        me.editElectrovalence(value, args.row, "replace");
+      }
+      me.showDatas(me.datas);
+    }
+  },
+  addElectrovalence: async function (name) {
+    this.editElectrovalence(name);
+  },
+  editElectrovalence: async function (name, row, type = "add") {
+    //新建项目的时候,电已经默认生成了,所以不用考考虑电没有的情况
+    try {
+      let glj = _.find(this.options, {
+        name: name
+      });
+      if (glj) {
+        let tem = {
+          displayName: glj.name,
+          code: glj.code,
+          specs: glj.specs,
+          unit: glj.unit,
+          type: glj.type,
+          projectID: projectObj.project.ID()
+        };
+        tem.ID = uuid.v1();
+        $.bootstrapLoading.start();
+        let result = await ajaxPost('/glj/insertElectrovalence', tem);
+        //插入项目工料机列表
+        if (type == "add" && (!result.projetcGLJData || result.projetcGLJData.length == 0)) {
+          alert("没有找到该工料机,请检查工料机库");
+          return this.showDatas(this.datas);
         }
-        for(let t of this.datas){
-            if(t.name == '电网电'){
-                dwd = t;
-            }
+        let newProjectPGJ = projectObj.project.projectGLJ.loadNewProjectGLJToCache(result.projetcGLJData);
+        //加入综合电价显示列表缓存
+        tem.GLJID = result.projetcGLJData.glj_id;
+        tem.projectGLJID = result.projetcGLJData.id;
+        tem.name = result.projetcGLJData.name;
+        tem.coe = 0;
+        tem.from = "std";
+        gljOprObj.setGLJPrice(tem, newProjectPGJ);
+
+        if (type == "add") {
+          this.datas.push(tem);
+        } else { //除了添加的就是替换
+          if (this.datas[row]) this.datas[row] = tem;
         }
-        let unitPrices = [];
-        for(let g of projectObj.project.projectGLJ.datas.gljList){
-            if(dwd && g.id == dwd.projectGLJID){
-                if(g.unit_price.market_price != dwd.electPrice+''){
-                  let  t_unitPrice = {projectGLJID:g.id,id:g.unit_price.id,'unit_price_file_id':g.unit_price.unit_price_file_id,doc:{'market_price':dwd.electPrice+""}};
-                    unitPrices.push(t_unitPrice);
-                }
-            }
-            if(g.code == gljUtil.getElecCode() && g.name == "电" && g.unit == "kW·h"){//更新电价
-                if(g.unit_price.market_price != this.total+''){
-                    let  d_unitPrice = {projectGLJID:g.id,id:g.unit_price.id,'unit_price_file_id':g.unit_price.unit_price_file_id,doc:{'market_price':this.total+''}};
-                    unitPrices.push(d_unitPrice);
-                }
+        this.showDatas(this.datas);
+      }
+    } catch (e) {
+      console.log(e)
+    } finally {
+      //materialCalcObj.showDatas();
+      $.bootstrapLoading.end();
+    }
+  },
+  getGljListFromDatas: function (datas) {
+    let gljList = [];
+    for (let d of datas) {
+      gljList.push(this.createNewElectrovalenceData(d));
+    }
+    return gljList;
+  },
+  updateElectrovalence: function () {
+    let updateMap = {};
+    let dwd = null; //电网电
+    let com_electrovalence = projectObj.project.projectGLJ.datas.com_electrovalence;
+    if (com_electrovalence) { //存在则是更新
+      updateMap['electrovalence'] = {
+        actionType: 'update',
+        ID: com_electrovalence.ID,
+        doc: {
+          gljList: this.getGljListFromDatas(this.datas)
+        }
+      };
+    } else { //不存在则是新增
+      updateMap['electrovalence'] = {
+        actionType: 'add',
+        doc: {
+          unit_price_file_id: projectObj.project.property.unitPriceFile.id,
+          gljList: this.getGljListFromDatas(this.datas)
+        }
+      };
+      updateMap['electrovalence']['doc'].ID = uuid.v1();
+    }
+    for (let t of this.datas) {
+      if (t.name == '电网电') {
+        dwd = t;
+      }
+    }
+    let unitPrices = [];
+    for (let g of projectObj.project.projectGLJ.datas.gljList) {
+      if (dwd && g.id == dwd.projectGLJID) {
+        if (g.unit_price.market_price != dwd.electPrice + '') {
+          let t_unitPrice = {
+            projectGLJID: g.id,
+            id: g.unit_price.id,
+            'unit_price_file_id': g.unit_price.unit_price_file_id,
+            doc: {
+              'market_price': dwd.electPrice + ""
             }
+          };
+          unitPrices.push(t_unitPrice);
         }
-        if(unitPrices.length > 0)updateMap["unitPrice"] =  unitPrices;
-        this.submitElectrovalenceChange(updateMap)
-    },
-    submitElectrovalenceChange:async function (updateMap) {
-        try {
-            if(!_.isEmpty(updateMap)){
-                $.bootstrapLoading.start();
-                let result =  await ajaxPost('/glj/updateElectrovalence',updateMap);
-                projectObj.project.projectGLJ.refreshEctrovalenceCache(updateMap);
+      }
+      if (g.code == gljUtil.getElecCode() && g.name == "电" && g.unit == "kW·h") { //更新电价
+        if (g.unit_price.market_price != this.total + '') {
+          let d_unitPrice = {
+            projectGLJID: g.id,
+            id: g.unit_price.id,
+            'unit_price_file_id': g.unit_price.unit_price_file_id,
+            doc: {
+              'market_price': this.total + ''
             }
-        }catch (e){
-            console.log(e)
-        }finally {
-            $.bootstrapLoading.end();
+          };
+          unitPrices.push(d_unitPrice);
         }
-
+      }
     }
+    if (unitPrices.length > 0) updateMap["unitPrice"] = unitPrices;
+    this.submitElectrovalenceChange(updateMap)
+  },
+  submitElectrovalenceChange: async function (updateMap) {
+    try {
+      if (!_.isEmpty(updateMap)) {
+        $.bootstrapLoading.start();
+        let result = await ajaxPost('/glj/updateElectrovalence', updateMap);
+        projectObj.project.projectGLJ.refreshEctrovalenceCache(updateMap);
+      }
+    } catch (e) {
+      console.log(e)
+    } finally {
+      $.bootstrapLoading.end();
+    }
+
+  }
 
 
 };
 
 $(function () {
 
-    $("#electrovalenceDiv").on('shown.bs.modal', function () {
-        electrovalenceObj.initSpread();
-        electrovalenceObj.showDatas();
-    });
+  $("#electrovalenceDiv").on('shown.bs.modal', function () {
+    electrovalenceObj.initSpread();
+    electrovalenceObj.showDatas();
+  });
 
-    $("#removeElectrovalencec").click(function(){
-        let record = sheetCommonObj.getSelectedRecode(electrovalenceObj.sheet,electrovalenceObj.datas);
-        if(record){
-            _.remove(electrovalenceObj.datas,{'ID':record.ID});
-            electrovalenceObj.showDatas(electrovalenceObj.datas);
-        }
-    });
+  $("#removeElectrovalencec").click(function () {
+    let record = sheetCommonObj.getSelectedRecode(electrovalenceObj.sheet, electrovalenceObj.datas);
+    if (record) {
+      _.remove(electrovalenceObj.datas, {
+        'ID': record.ID
+      });
+      electrovalenceObj.showDatas(electrovalenceObj.datas);
+    }
+  });
 
-    $("#electrovalencecConfirm").click(function () {
-        electrovalenceObj.updateElectrovalence();
-    })
+  $("#electrovalencecConfirm").click(function () {
+    electrovalenceObj.updateElectrovalence();
+  })
 });

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

@@ -369,7 +369,7 @@ let MainTreeCol = {
         specialProvisional: function (node) {
             if(!MainTreeCol.readOnly.specialProvisional(node)){
                 let dynamicCombo = sheetCommonObj.getDynamicCombo();
-                dynamicCombo.items(["材料","工程设备","专业工程",""]);
+                dynamicCombo.items(["专业工程",""]);
                 return dynamicCombo;
             }
 

+ 111 - 63
web/building_saas/main/js/views/project_property_basicInfo.js

@@ -19,10 +19,10 @@ let basicInfoView = {
             allowUserDragFill: false,
             scrollbarMaxAlign : true
         },
-        dateRows: [5, 18],
-        numRows: [7],
+        dateRows: [],
+        numRows: [],
         locked: {
-            rows: [0, 19, 23, 27],
+            rows: [],
             cols: [0]
         }
     },
@@ -70,6 +70,8 @@ let basicInfoView = {
             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, headers[i].width, 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']]);
             }
         };
         me.renderSheetFuc(sheet, fuc);
@@ -91,6 +93,7 @@ let basicInfoView = {
         let sheet = workBook.getActiveSheet();
         sheet.bind(_events.EditStarting, this.onEditStarting);
         sheet.bind(_events.EditEnded, this.onEditEnded);
+        sheet.bind(_events.EnterCell, this.onEnterCell);
         sheet.bind(_events.ClipboardPasting, this.onClipboardPasting);
         sheet.bind(_events.ClipboardPasted, this.onClipboardPasted);
     },
@@ -102,15 +105,28 @@ let basicInfoView = {
         let fuc = function () {
             sheet.setRowCount(datas.length);
             me.initTree(sheet, true, datas);
-            me.setDatePicker(sheet, me.setting.dateRows);
             sheet.setFormatter(-1, 1, '@');
-            for(let col = 0, cLen = cols.length; col < cLen; col++){
-                sheet.getRange(-1, col, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[cols[col]['hAlign']]);
-                sheet.getRange(-1, col, -1, 1).vAlign(GC.Spread.Sheets.VerticalAlign[cols[col]['vAlign']]);
-                for(let row = 0, rLen = datas.length; row < rLen; row++){
+            //兼容旧数据,旧数据可能没有设置cellType
+            let compatNumKeys = ['grossArea'],
+                compatDateKeys = ['constructionDate', 'establishDate'];
+            for(let row = 0;row < datas.length ; row ++){
+                if(datas[row].cellType == 'number' || compatNumKeys.includes(datas[row].key)){
+                    me.setting.numRows.push(row);
+                } else if (datas[row].cellType === 'date' || compatDateKeys.includes(datas[row].key)) {
+                    me.setting.dateRows.push(row);
+                } else if(datas[row].cellType === 'comboBox'){
+                    let options = datas[row].options ? datas[row].options.split("@") : [];
+                    projFeatureView.setCombo(sheet, row, options);
+                }
+                let readOnly = typeof datas[row].readOnly === 'string' ? JSON.parse(datas[row].readOnly) : datas[row].readOnly;
+                if (readOnly || datas[row].items) {
+                    me.setting.locked.rows.push(row);
+                }
+                for(let col = 0;col < cols.length;col++){
                     sheet.setValue(row, col, datas[row][cols[col]['dataCode']]);
                 }
             }
+            me.setDatePicker(sheet, me.setting.dateRows);
         };
         this.renderSheetFuc(sheet, fuc);
     },
@@ -120,8 +136,7 @@ let basicInfoView = {
         if(args.col === 0){
             args.cancel = true;
         }
-        //工程专业
-        if(args.col === 1 && me.setting.locked.rows.indexOf(args.row) !== -1){
+        if(me.setting.locked.rows.indexOf(args.row) !== -1){
             args.cancel = true;
         }
     },
@@ -130,8 +145,12 @@ let basicInfoView = {
         let me = basicInfoView;
         let v =  args.editingText ? args.editingText.toString().trim() : '';
         if(args.row < me.datas.length){
+            let required = typeof me.datas[args.row].required === 'string' ? JSON.parse(me.datas[args.row].required) : me.datas[args.row].required;
             //date
-            if(me.setting.dateRows.indexOf(args.row) !== -1){
+            if (required && !v) {
+                v = me.datas[args.row].value;
+                args.sheet.setValue(args.row, args.col, v);
+            } else if(me.setting.dateRows.indexOf(args.row) !== -1){
                 if(v.length > 0){
                     v = formatDate(new Date(v), 'yyyy-MM-dd');
                     v = me.filtDate(v);
@@ -141,8 +160,7 @@ let basicInfoView = {
                         return;
                     }
                 }
-            }
-            else if(me.setting.numRows.indexOf(args.row) !== -1){//控制数值
+            } else if(me.setting.numRows.indexOf(args.row) !== -1){//控制数值
                 if(!me.isNum(v)){
                     alert('只能输入数值');
                     v = me.datas[args.row].value && me.isNum(me.datas[args.row].value) ? me.datas[args.row].value : '';
@@ -153,6 +171,10 @@ let basicInfoView = {
         }
     },
 
+    onEnterCell: function (sender, args) {
+        args.sheet.repaint();
+    },
+
     onClipboardPasting: function (sender, args) {
         let me = basicInfoView;
         if(args.cellRange.col === 0){
@@ -166,23 +188,25 @@ let basicInfoView = {
         let recRows = [];
         for(let i = 0, len = items.length; i < len; i++){
             let row = i + args.cellRange.row;
+            let comboItems = projFeatureView.getComboItemsByRow.call(me, row);
+            let required = typeof me.datas[row].required === 'string' ? JSON.parse(me.datas[row].required) : me.datas[row].required;
             if(me.setting.locked.rows.indexOf(row) !== -1){
                 recRows.push(row);
-            }
-            else if(me.setting.dateRows.indexOf(row) !== -1){
+            } else if(comboItems && !comboItems.includes(items[i].value)){//粘贴下拉框数据过滤
+                recRows.push(row);
+            } else if(me.setting.dateRows.indexOf(row) !== -1){
                 items[i].value = me.filtDate(items[i].value);
                 if(!me.isDef(items[i].value)){
                     recRows.push(row);
-                }
-                else {
+                } else {
                     me.datas[row].value = items[i].value;
                 }
-            }
-            else if(me.setting.numRows.indexOf(row) !== -1 && !me.isNum(items[i].value)){
+            } else if(me.setting.numRows.indexOf(row) !== -1 && !me.isNum(items[i].value)){
                 recRows.push(row);
-            }
-            else {
-                me.datas[row].value = items[i].value;
+            } else if (required && !items[i].value) {
+                recRows.push(row);
+            } else
+                {me.datas[row].value = items[i].value;
             }
         }
         if(recRows.length > 0){
@@ -191,7 +215,7 @@ let basicInfoView = {
                     let staticV = me.datas[recRows[i]].value || '';
                     args.sheet.setValue(recRows[i], args.cellRange.col, staticV);
                 }
-            })
+            });
         }
     },
 
@@ -219,44 +243,47 @@ let basicInfoView = {
     },
 
     initDatas: function (datas) {
-        this.datas = [];
-        for(let i = 0, len = datas.length; i < len; i++){
-            this.datas.push(this.copyObj(datas[i]));
-        }
+        this.datas = _.cloneDeep(datas);
     },
 
     //数据库读到的数据转换为展示的结构
     toViewDatas: function (datas) {
-        let rst = [];
-        for(let i = 0, len = datas.length; i < len; i++){
-            let items = datas[i].items || null;
-            if(items){
-                rst.push(datas[i]);
-                for(let j = 0, jLen = items.length; j < jLen; j++){
-                    rst.push(items[j]);
+        // 将数据打平(原数据一些子项数据会嵌套在items数组中)
+        let curID = 1;
+        return extractDataFromItems(datas);
+        // 为了与sheet_common.js -> getTreeNodeCellType共用树结构功能
+        // 需要设置数据的ID、ParentID
+
+        function extractDataFromItems(items, parentID) {
+            const rst = [];
+            items.forEach(item => {
+                // 为了与sheet_common.js -> getTreeNodeCellType共用树结构功能
+                // 需要设置数据的ID、ParentID
+                item.ID = curID++;
+                item.ParentID = parentID || null;
+                rst.push(item);
+                if (item.items && item.items.length) {
+                    rst.push(...extractDataFromItems(item.items, item.ID));
                 }
-            }
+            });
+            return rst;
         }
-        return rst;
     },
 
     //展示的结构转换为入库的结构
     toSaveDatas: function (datas) {
-        let rst = [];
-        let index = -1;
-        for(let i = 0, len = datas.length; i < len; i++){
-            let items = datas[i].items || null;
-            if(items){
-                delete datas[i].collapsed;
-                datas[i].items = [];
-                rst.push(datas[i]);
-                index++;
-            }
-            else {
-                rst[index]['items'].push(datas[i]);
-            }
+        const saveData = datas.filter(item => item.ParentID === null);
+        clearJunkAttrs(saveData);
+
+        function clearJunkAttrs(items) {
+            items.forEach(item => {
+                delete item.ID && delete item.ParentID && delete item.collapsed;
+                if (item.items && item.items.length) {
+                    clearJunkAttrs(item.items);
+                }
+            })
         }
-        return rst;
+        return saveData;
     },
 
     toUpdate: function (orgDatas, newDatas) {
@@ -288,19 +315,36 @@ let basicInfoView = {
         });
     },
 
-    initTree:function (sheet, init, datas) {
-        sheet.getRange(-1, 0, -1, 1).cellType(this.getTreeNodeCellType(datas));
-        for(let i =0, len = datas.length; i < len; i++){
-            if(datas[i].hasOwnProperty('items')){
+    initTree: function (sheet, init, datas) {
+        //sheet.getRange(-1, 0, -1, 1).cellType(this.getTreeNodeCellType(datas));
+        const parentType = _.groupBy(datas, 'ParentID');
+        const paint = (ctx, value, x, y, w, h, style, rectInfo, data) => {
+            const required = typeof data.required === 'string' ? JSON.parse(data.required) : data.required;
+            const readOnly = typeof data.readOnly === 'string' ? JSON.parse(data.readOnly) : data.readOnly;
+            if (required && !readOnly) {
+                const { rectW, margin } = rectInfo;
+                ctx.save();
+                ctx.fillStyle = 'red';
+                const paddingLeft = 8;
+                const paintX = x + margin + paddingLeft; // 第一层盒子处[+] / [-]
+                const paintY = y + Math.round(h / 2) + paddingLeft;
+                ctx.font = "14px Calibri"
+                ctx.fillText('*', paintX, paintY);
+                ctx.restore();
+            }
+            
+        };
+        for (let i = 0, len = datas.length; i < len; i++) {
+            if (datas[i].hasOwnProperty('items')) {
                 let collapsed = false;
-                if(init){
-                    datas[i].collapsed=false;
+                if (init) {
+                    datas[i].collapsed = false;
                     collapsed = true;
-                }else {
+                } else {
                     collapsed = datas[i].collapsed == undefined ? true : datas[i].collapsed;
                 }
-                //sheet.getRange(i+1, -1, datas[i].items.length, -1).visible(!collapsed);
             }
+            sheet.getCell(i, 0).cellType(sheetCommonObj.getTreeNodeCellType(datas, i, parentType, 0, paint))
         }
     },
 
@@ -406,7 +450,7 @@ let basicInfoView = {
             if(recode&&recode.hasOwnProperty('items')){
                 //方框外1像素内都有效
                 const boxLengh = 10;
-                if (hitinfo.x >= centerX - halfBoxLength - 2 && hitinfo.x <= centerX + halfBoxLength + 1 &&
+                if (hitinfo.x >= centerX - halfBoxLength - 1 && hitinfo.x <= centerX + halfBoxLength + 1 &&
                     hitinfo.y >= centerY - halfBoxLength - 1 && hitinfo.y <= centerY + halfBoxLength + 1) {
                     var collapsed = recode.collapsed==undefined?true:recode.collapsed;
                     collapsed = !collapsed
@@ -473,8 +517,7 @@ let basicInfoView = {
 };
 
 $(document).ready(function () {
-    //暂时隐藏
-   $('#poj-set').on('shown.bs.modal', function (e) {
+    $('#poj-set').on('shown.bs.modal', function (e) {
         //init Spread
         basicInfoView.initDatas(basicInfoView.orgDatas);
         basicInfoView.buildSheet();
@@ -494,10 +537,15 @@ $(document).ready(function () {
     });
 
     $('#tab_poj-settings-basicInfo').on('shown.bs.tab', function () {
-        basicInfoView.workBook.refresh();
+        sheetCommonObj.refreshWorkbookDelDefer(basicInfoView.workBook, 100);
     });
     $('#openProjSet').click(function () {
         $('[data-toggle="tooltip"]').tooltip('hide');
         $('#poj-set').modal('show');
-    });
+    })
+   /* $('#property_ok').bind('click', function () {
+        if(basicInfoView.toUpdate(basicInfoView.orgDatas, basicInfoView.datas)){
+            basicInfoView.a_updateInfo(basicInfoView.toSaveDatas(basicInfoView.datas));
+        }
+    });*/
 });

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

@@ -60,6 +60,14 @@ let tender_obj={
                 newNode.source = mainNode.source;
                 newNode.sourceType = mainNode.sourceType;
                 newNode.mainNode = mainNode;
+
+                // 只显示到叶子清单层
+                if (calcTools.isLeafBill(newNode))
+                    newNode.expanded = false;
+
+                if (calcTools.isRationCategory(newNode))
+                    newNode.visible = false;
+
                 if (mainNode.children.length > 0) {
                     for (let c of mainNode.children) {
                         createTenderNode(c, newNode, null);

+ 25 - 4
web/building_saas/pm/js/pm_newMain.js

@@ -50,7 +50,8 @@ const STATE = {
     addingProject: false,
     addingFolder: false,
     deleting: false,
-    importing: false
+    importing: false,
+    moving: false,
 };
 const projTreeObj = {
     tree: null,
@@ -508,11 +509,16 @@ const projTreeObj = {
             }
             projTreeObj.moveTo(selected, null, parent, next, null, action);
             $.bootstrapLoading.end();
+            STATE.moving = false;
             projTreeObj.emitTreeChange();
         });
     },
     //升级后选中节点的后兄弟节点不成为其子节点,因为有层级类型限制(相当于选中节点移动到父项后成为其后兄弟)
     upLevel: function () {
+        if (STATE.moving) {
+            return;
+        }
+        STATE.moving = true;
         let selected = projTreeObj.tree.selected,
             parent = selected.parent.parent,
             next = selected.parent.nextSibling,
@@ -529,6 +535,10 @@ const projTreeObj = {
         this.doAfterTreeOpr({selected, parent, next, projectMap});
     },
     downLevel: function () {
+        if (STATE.moving) {
+            return;
+        }
+        STATE.moving = true;
         let selected = projTreeObj.tree.selected,
             parent = null,
             next = null,
@@ -551,10 +561,15 @@ const projTreeObj = {
         this.doAfterTreeOpr({selected, parent, next, projectMap}, 'downLevel');
     },
     upMove: function () {
+        if (STATE.moving) {
+            return;
+        }
+        STATE.moving = true;
         let selected = projTreeObj.tree.selected,
             parent = selected.parent,
             next = selected.preSibling(),
             projectMap = {};
+        //$('#upMove').addClass('disabled');
         //更新前前兄弟
         let prepre = selected.preSibling().preSibling();
         if (prepre) {
@@ -568,10 +583,15 @@ const projTreeObj = {
         this.doAfterTreeOpr({selected, parent, next, projectMap});
     },
     downMove: function () {
+        if (STATE.moving) {
+            return;
+        }
+        STATE.moving = true;
         let selected = projTreeObj.tree.selected,
             parent = selected.parent,
             next = selected.nextSibling.nextSibling,
             projectMap = {};
+        //$('#downMove').addClass('disabled');
         //更新前兄弟
         let pre = selected.preSibling();
         if (pre) {
@@ -1648,6 +1668,7 @@ const projTreeObj = {
         init(refresh, callback, expandCallback);
     },
     handleNotifyClick: function (expandState, selection) {
+        $('#empty-modal').modal('hide');
         $('#notify').hide();
         const callback = () => {
             const sheet = this.workBook.getSheet(0);
@@ -2497,12 +2518,12 @@ function initProjectOptSet($target) {
                         <label for="staticEmail" class="col-auto col-form-label col-form-label-sm">清单类型</label>
                         <div class="col">
                             <div class="custom-control custom-radio custom-control-inline">
-                                <input type="radio" value="${BID_INVITATION}" name="boq-type-input" checked id="boq-type-tender" class="custom-control-input">
+                                <input type="radio" value="${BID_INVITATION}" name="boq-type-input" id="boq-type-tender" class="custom-control-input">
                                 <label class="custom-control-label" for="boq-type-tender">招标</label>
                             </div>
                             <div class="custom-control custom-radio custom-control-inline">
-                                <input type="radio" value="${BID_SUBMISSION}" name="boq-type-input" id="boq-type-bidder" class="custom-control-input">
-                                <label class="custom-control-label" checked for="boq-type-bidder">投标</label>
+                                <input type="radio" value="${BID_SUBMISSION}" name="boq-type-input" id="boq-type-bidder" class="custom-control-input" checked>
+                                <label class="custom-control-label" for="boq-type-bidder">投标</label>
                             </div>
                         </div>
                     </div>`;

+ 2 - 2
web/building_saas/pm/js/pm_share.js

@@ -797,10 +797,10 @@ const pmShare = (function () {
                       return !(selected && selected.data.allowCopy && selected.data.projType === projectType.project);
                   },
                   callback: function (key, opt) {
-                      if($(".p-title").text().includes('学习')){
+                      /* if($(".p-title").text().includes('学习')){
                         hintBox.versionBox('此功能仅在专业版中提供,学习版可选择单个分段进行拷贝。');
                         return;
-                      }
+                      } */
                       copyContructionProject(tree.selected);
                   }
                 },

Plik diff jest za duży
+ 567 - 495
web/building_saas/pm/js/pm_tree.js


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

@@ -31,6 +31,14 @@ const INTERFACE_CONFIG = (() => {
         [CONTROL]: '.HBGLKZJ',
       },
     },
+    '安徽@铜陵': {
+      scriptName: 'anhui_maanshan.js',
+      fileSuffix: {
+        [BID_INVITATION]: '.TLGLZB',
+        [BID_SUBMISSION]: '.TLGLTB',
+        [CONTROL]: '.TLGLKZJ',
+      },
+    },
     '安徽@芜湖': {
       scriptName: 'anhui_maanshan.js',
       fileSuffix: {
@@ -55,6 +63,14 @@ const INTERFACE_CONFIG = (() => {
         [CONTROL]: '.XCGLKZJ',
       },
     },
+    '安徽@池州': {
+      scriptName: 'anhui_chizhou.js',
+      fileSuffix: {
+        [BID_INVITATION]: '.CZGLZB',
+        [BID_SUBMISSION]: '.CZLTB',
+        [CONTROL]: '.CZGLZBKZJ',
+      }
+    },
     '广东@中山': {
       scriptName: 'guangdong_zhongshan.js',
       fileSuffix: {

+ 762 - 0
web/building_saas/standard_interface/export/anhui_chizhou.js

@@ -0,0 +1,762 @@
+
+INTERFACE_EXPORT = (() => {
+    'use strict';
+
+    /**
+     * 
+     * @param {String} areaKey - 地区标识,如:'安徽@马鞍山',有些地区的接口只是取值上有不同,共有一个接口脚本, 需要通过地区标识确定一些特殊处理
+     * @param {Number} exportKind - 导出类型,招标、投标、控制价
+     * @param {Object} projectData - 项目表数据:{ 建设项目Data, children: [单位工程...] }
+     * @param {Object} tenderDetailMap - 单位工程ID与getData接口数据(projectObj.project的结构)的映射。
+     * @return {Promise<Array>} - 返回的数据结构必须按照规定:[{ data, exportKind, fileName }],参考web\building_saas\standard_interface\index.js中的注释说明
+     */
+    async function entry(areaKey, exportKind, projectData, tenderDetailMap) {
+        const {
+            CONFIG: { 
+                TYPE, 
+                WHITE_SPACE
+            },
+            UTIL: {
+                getValueByKey,
+                getHan,
+                getFee,
+                generateHardwareId,
+            },
+            Element,
+        } = INTERFACE_EXPORT_BASE;
+
+        const {
+            EXPORT_KIND: { BID_INVITATION, BID_SUBMISSION, CONTROL },
+            fixedFlag,
+            RationType,
+        } = window.commonConstants
+
+        const GljType = gljUtil.gljType;
+
+        const { isEmptyVal, isDef } = window.commonUtil;
+
+        const isBidInvitation = exportKind === BID_INVITATION; // 是否是招标
+        const isBidSubmission = exportKind === BID_SUBMISSION; // 是否是投标
+        const isControl = exportKind === CONTROL; // 是否是控制价
+
+        // 节点定义--------------------------------
+        const subArea = areaKey.split('@')[1];
+
+        function ChiZGLGC() {
+            Element.call(this, '池州公路工程');
+        }
+
+        function GongCXX(information) {
+            const attrs = [
+                { name: '项目编号', value: getValueByKey(information, 'tendereeName') }, // 招标人
+                { name: '项目名称', value: getValueByKey(information, 'costConsultant') }, // 造价咨询人
+                { name: '建设单位', value: getValueByKey(information, 'tenderAuthorizer') }, // 招标人法定代表人或其授权人
+                { name: '起始桩号', value: getValueByKey(information, 'consultantAuthorizer') }, // 造价咨询人法定代表人或其授权人
+                { name: '终点桩号', value: getValueByKey(information, 'tenderCompiler') }, // 编制人
+                { name: '建设地址', value: getValueByKey(information, 'tenderExaminer') }, // 复核人
+                { name: '项目概况', value: getValueByKey(information, 'compilationTime'), type: TYPE.DATE }, // 编制时间
+                { name: '建设性质', value: getValueByKey(information, 'reviewTime'), type: TYPE.DATE }, // 复核时间
+                { name: '专业划分', value: getValueByKey(information, 'reviewTime'), type: TYPE.DATE }, // 复核时间
+                { name: '道路里程', value: getValueByKey(information, 'reviewTime'), type: TYPE.DATE }, // 复核时间
+                { name: '设计单位', value: getValueByKey(information, 'reviewTime'), type: TYPE.DATE }, // 复核时间
+                { name: '计税方式', value: getValueByKey(information, 'reviewTime'), type: TYPE.DATE }, // 复核时间
+                { name: '文件类型', value: getValueByKey(information, 'reviewTime'), type: TYPE.DATE }, // 复核时间
+                { name: '标准版本号', value: getValueByKey(information, 'reviewTime'), type: TYPE.DATE }, // 复核时间
+                { name: 'GUID', value: getValueByKey(information, 'reviewTime'), type: TYPE.DATE }, // 复核时间
+            ];
+            Element.call(this, '工程信息', attrs);
+        }
+
+        function ZhaoTBXX(){
+            Element.call(this, '招投标信息');
+        }
+
+        function GongLGCSJ(){
+            Element.call(this, '公路工程数据');
+        }
+
+        function ZhaoBiaoXx(information) {
+            const attrs = [
+                { name: '招标人', value: getValueByKey(information, 'tendereeName') }, // 招标人
+                { name: 'Zxr', value: getValueByKey(information, 'costConsultant') }, // 造价咨询人
+                { name: 'ZbrDb', value: getValueByKey(information, 'tenderAuthorizer') }, // 招标人法定代表人或其授权人
+                { name: 'ZxrDb', value: getValueByKey(information, 'consultantAuthorizer') }, // 造价咨询人法定代表人或其授权人
+                { name: 'Bzr', value: getValueByKey(information, 'tenderCompiler') }, // 编制人
+                { name: 'Fhr', value: getValueByKey(information, 'tenderExaminer') }, // 复核人
+                { name: 'BzTime', value: getValueByKey(information, 'compilationTime'), type: TYPE.DATE }, // 编制时间
+                { name: 'FhTime', value: getValueByKey(information, 'reviewTime'), type: TYPE.DATE }, // 复核时间
+            ];
+            // 额外字段
+            const extraMap = {
+                '淮北': [
+                    { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
+                    { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
+                    { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
+                    { name: 'ZxrNssbh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
+                ]
+            };
+            if (extraMap[subArea]) {
+                attrs.push(...extraMap[subArea]);
+            }
+            Element.call(this, '招标信息', attrs);
+        }
+
+        function ZhaoBiaoKzXx(information, totalCost) {
+            const attrs = [
+                { name: 'Zbr', value: getValueByKey(information, 'tendereeName') }, // 招标人
+                { name: 'Zxr', value: getValueByKey(information, 'costConsultant') }, // 造价咨询人
+                { name: 'ZbrDb', value: getValueByKey(information, 'tenderAuthorizer') }, // 招标人法定代表人或其授权人
+                { name: 'ZxrDb', value: getValueByKey(information, 'consultantAuthorizer') }, // 造价咨询人法定代表人或其授权人
+                { name: 'Bzr', value: getValueByKey(information, 'tenderCompiler') }, // 编制人
+                { name: 'Fhr', value: getValueByKey(information, 'tenderExaminer') }, // 复核人
+                { name: 'BzTime', value: getValueByKey(information, 'compilationTime'), type: TYPE.DATE }, // 编制时间
+                { name: 'FhTime', value: getValueByKey(information, 'reviewTime'), type: TYPE.DATE }, // 复核时间
+                { name: 'Zbkzj', value: totalCost, type: TYPE.DECIMAL }, // 控制价总价(元),取“投标报价”的金额。
+            ];
+            // 额外字段
+            const extraMap = {
+                '淮北': [
+                    { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
+                    { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
+                    { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
+                    { name: 'ZxrNssbh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
+                ]
+            };
+            if (extraMap[subArea]) {
+                attrs.push(...extraMap[subArea]);
+            }
+            Element.call(this, '招标控制价', attrs);
+        }
+
+        function TouBiaoXx(information, totalCost) {
+            const attrs = [
+                { name: 'Zbr', value: getValueByKey(information, 'tendereeName') }, // 招标人
+                { name: 'Tbr', value: getValueByKey(information, 'bidder') }, // 投标人
+                { name: 'TbrDb', value: getValueByKey(information, 'bidderAuthorizer') }, // 投标人法定代表或其授权
+                { name: 'Bzr', value: getValueByKey(information, 'tenderCompiler') }, // 编制人
+                { name: 'BzTime', value: getValueByKey(information, 'compilationTime'), type: TYPE.DATE }, // 编制时间
+                { name: 'Tbzj', value: totalCost, type: TYPE.DECIMAL }, // 控制价总价(元),取“投标报价”的金额。
+            ];
+            // 额外字段
+            const extraMap = {
+                '淮北': [
+                    { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
+                    { name: 'TbrNssbh', value: getValueByKey(information, 'bidderTaxpayerIdentificationNo') }, // 投标人纳税识别号
+                    { name: 'TbrDbsfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 投标人法定代表或其授权人身份证号
+                ]
+            };
+            if (extraMap[subArea]) {
+                attrs.push(...extraMap[subArea]);
+            }
+            Element.call(this, '投标信息', attrs);
+        }
+
+        // 单项工程信息,因项目管理中无“单项工程”这一层,从单位工程的工程特征信息中拼凑出来
+        function Dxgcxx(code, name) {
+            const attrs = [
+                { name: 'Dxgcbh', value: code, minLen: 1, whiteSpace: WHITE_SPACE.COLLAPSE }, // 单项工程编号
+                { name: 'Dxgcmc', value: name }, // 单项工程名称
+            ];
+            Element.call(this, 'Dxgcxx', attrs);
+        }
+
+        // 单位工程信息
+        function Dwgcxx(tenderName, feature) {
+            const attrs = [
+                { name: 'Dwgcbh', value: getValueByKey(feature, 'unitProjNo'), minLen: 1, whiteSpace: WHITE_SPACE.COLLAPSE }, // 单位工程编号
+                { name: 'Dwgcmc', value: tenderName }, // 单位工程名称
+            ];
+            Element.call(this, 'Dwgcxx', attrs);
+        }
+
+        // 取费信息(费率信息)
+        function Qfxx() {
+            Element.call(this, 'Qfxx');
+        }
+
+        // 计价费率表
+        function JjFlb() {
+            Element.call(this, 'JjFlb');
+        }
+
+        // 计价费率表明细,造价书费率页面左侧最底层数据
+        function JjFlbMx(rootItem, item) {
+            // 费率明细名称-编码映射表
+            const FeeRateCodeMap = {
+                '冬季施工增加费': 'DJF',
+                '雨季施工增加费': 'YJF',
+                '夜间施工增加费': 'YEF',
+                '工地转移费': 'ZYF',
+                '高原地区施工增加费': 'GYF',
+                '风沙地区施工增加费': 'FSF',
+                '沿海地区施工增加费': 'YHF',
+                '行车干扰施工增加费': 'XCF',
+                '施工辅助费': 'SFF',
+                '养老保险费': 'YLF',
+                '失业保险费': 'SYF',
+                '医疗保险费': 'YBF',
+                '住房公积金': 'ZFF',
+                '工伤保险费': 'GSF',
+                '基本费用': 'JBF',
+                '主副食运费补贴': 'YFF',
+                '职工探亲补贴': 'TQF',
+                '职工取暖补贴': 'QNF',
+                '财务费用': 'CWF',
+                '利润': 'LR',
+                '税金': 'SJ',
+            };
+            // 费率工程名称-取费类别映射表
+            const FeeRateTypeMap = {
+                '土方': 1,
+                '石方': 3,
+                '运输': 2,
+                '路面': 4,
+                '隧道': 11,
+                '构造物Ⅰ': 5,
+                '构造物Ⅰ(不计冬)': 16,
+                '构造物Ⅱ': 6,
+                '构造物Ⅲ(桥梁)': 9,
+                '构造物Ⅲ(除桥以外不计雨夜)': 8,
+                '技术复杂大桥': 10,
+                '钢材及钢结构(桥梁)': 12,
+                '钢材及钢结构(除桥以外不计夜)': 13,
+                '费率为0': 17,
+                '路面(不计雨)': 4,
+                '构造物Ⅰ(不计雨)': 16,
+                '构造物Ⅲ(除桥以外)': 8,
+                '钢材及钢结构(除桥以外)': 13,
+                '设备': 15,
+                '量价': 14,
+            };
+            const rate = isEmptyVal(item.rate) ? '100' : item.rate; // 为空时输出=100,为0时输出=0
+            /* if (!FeeRateTypeMap[rootItem.name]) {
+                debugger;
+            } */
+            const attrs = [
+                { name: 'Bm', value: FeeRateCodeMap[item.name] }, // 编码
+                { name: 'Name', value: item.name }, // 名称
+                { name: 'Fl', value: rate, type: TYPE.DECIMAL }, // 费率
+                { name: 'Qflb', value: FeeRateTypeMap[rootItem.name], type: TYPE.INT }, // 取费类别
+            ];
+            Element.call(this, 'JjFlbMx', attrs);
+        }
+
+        // 计价费率项
+        function JjFlx() {
+            Element.call(this, 'JjFlx');
+        }
+
+        // 计价费率项明细,造价书费率页面右侧最顶层数据
+        function JjFlxMx(item) {
+            // 编码取名称拼音首字母
+            const allHanName = getHan(item.name || '');
+            const code = pinyinUtil.getFirstLetter(allHanName).toLowerCase();
+            let value;
+            if (isDef(item.value)) {
+                value = item.value;
+            } else {
+                const selected = item.optionList.find(item => item.selected);
+                value = selected.name;
+            }
+            const attrs = [
+                { name: 'Bm', value: code }, // 编码
+                { name: 'Mc', value: item.name }, // 名称
+                { name: 'ShuZhi', value: value }, // 数值
+            ];
+            Element.call(this, 'JjFlxMx', attrs);
+        }
+
+        // 清单项目
+        function QdXm() {
+            Element.call(this, 'QdXm');
+        }
+        // 标题类别:1=100~700清单合计,2=暂估价合计,3=清单不包含暂估价合计,4=计日工,5=暂列金额(不含计日工总额)),6=投标报价,0=其他
+        const BillsTitleType = {
+            [fixedFlag.ONE_SEVEN_BILLS]: '1',
+            [fixedFlag.PROVISIONAL_TOTAL]: '2',
+            [fixedFlag.BILLS_TOTAL_WT_PROV]: '3',
+            [fixedFlag.DAYWORK_LABOR]: '4',
+            [fixedFlag.PROVISIONAL]: '5',
+            [fixedFlag.TOTAL_COST]: '6',
+        };
+        // 清单标题 造价书的第一层数据。
+        function QdBt(node) {
+            const row = node.row();
+            const fee = isBidInvitation ? '0' : getFee(node.data.fees, 'common.tenderTotalFee')
+            const attrs = [
+                { name: 'Xh', value: row, type: TYPE.INT }, // 序号
+                { name: 'Bm', value: node.data.code }, // 编码
+                { name: 'Name', value: node.data.name }, // 名称
+                { name: 'Je', value: fee, type: TYPE.DECIMAL }, // 金额
+                { name: 'Code', value: `F${row}` }, // 行引用
+                { name: 'Jsgs', value: node.data.calcBase }, // 计算基数
+                { name: 'Lb', value: BillsTitleType[node.getFlag()], type: TYPE.INT }, // 类别
+                { name: 'Bz', value: node.data.remark }, // 备注
+            ];
+            Element.call(this, 'QdBt', attrs);
+        }
+
+        // 清单明细 (只有100-700章清单标题输出)
+        function QdMx(node) {
+            const row = node.row();
+            const attrs = [
+                { name: 'Xh', value: row, type: TYPE.INT }, // 序号
+                { name: 'Qdbm', value: node.data.code, minLen: 1 }, // 编码
+                { name: 'Name', value: node.data.name }, // 名称
+                { name: 'Dw', value: node.data.unit }, // 单位
+                { name: 'Sl', value: node.data.quantity, type: TYPE.DECIMAL }, // 工程量
+                { name: 'Sl2', value: '0', type: TYPE.DECIMAL }, // 工程量2
+                { name: 'Rgf', value: isBidInvitation ? '0' : getFee(node.data.fees, 'marketLabour.tenderTotalFee'), type: TYPE.DECIMAL }, // 人工费
+                { name: 'Clf', value: isBidInvitation ? '0' : getFee(node.data.fees, 'marketMaterial.tenderTotalFee'), type: TYPE.DECIMAL }, // 材料费
+                { name: 'Jxf', value: isBidInvitation ? '0' : getFee(node.data.fees, 'marketMachine.tenderTotalFee'), type: TYPE.DECIMAL }, // 机械费
+                { name: 'Sbf', value: isBidInvitation ? '0' : getFee(node.data.fees, 'marketEquipment.tenderTotalFee'), type: TYPE.DECIMAL }, // 设备费
+                { name: 'Csf', value: isBidInvitation ? '0' : getFee(node.data.fees, 'measure.tenderTotalFee'), type: TYPE.DECIMAL }, // 措施费
+                { name: 'Glf', value: isBidInvitation ? '0' : getFee(node.data.fees, 'manage.tenderTotalFee'), type: TYPE.DECIMAL }, // 企业管理费
+                { name: 'Gf', value: isBidInvitation ? '0' : getFee(node.data.fees, 'force.tenderTotalFee'), type: TYPE.DECIMAL }, // 规费
+                { name: 'Lr', value: isBidInvitation ? '0' : getFee(node.data.fees, 'profit.tenderTotalFee'), type: TYPE.DECIMAL }, // 利润
+                { name: 'Sj', value: isBidInvitation ? '0' : getFee(node.data.fees, 'tax.tenderTotalFee'), type: TYPE.DECIMAL }, // 税金
+                { name: 'Zhdj', value: isBidInvitation ? '0' : getFee(node.data.fees, 'common.tenderUnitFee'), type: TYPE.DECIMAL }, // 单价
+                { name: 'Zhhj', value: isBidInvitation ? '0' : getFee(node.data.fees, 'common.tenderTotalFee'), type: TYPE.DECIMAL }, // 合价
+                { name: 'Zgj', value: isBidInvitation ? '0' : getFee(node.data.fees, 'estimate.tenderTotalFee'), type: TYPE.DECIMAL }, // 暂估价
+                { name: 'Iszg', value: node.data.specialProvisional === '专业工程', type: TYPE.BOOL }, // 是否暂定 如果专项暂定列选择了“专业工程”,则输出true,否则是false。
+                { name: 'Djfx', value: !!node.data.unitPriceAnalysis, type: TYPE.BOOL }, // 单价分析
+                { name: 'Jsgs', value: node.data.calcBase }, // 计算基数
+                { name: 'Bl', value: '' }, // 变量
+                { name: 'Bz', value: node.data.remark }, // 备注
+            ];
+            Element.call(this, 'QdMx', attrs);
+        }
+
+        // 定额组价
+        function Qdxdezj() {
+            Element.call(this, 'Qdxdezj');
+        }
+
+        // 定额租价明细 招标文件不输出
+        function QdxdezjMx(ration) {
+            const typeMap = {
+                [RationType.RATION]: '1',
+                [RationType.VOLUME_PRICE + GljType.LABOUR]: '2',
+                [RationType.VOLUME_PRICE + GljType.GENERAL_MATERIAL]: '3',
+                [RationType.VOLUME_PRICE + GljType.GENERAL_MACHINE]: '4',
+                [RationType.VOLUME_PRICE + GljType.EQUIPMENT]: '2',
+            };
+            const typeKey = (ration.type || '') + (ration.subType || '');
+            const type = typeMap[typeKey];
+            const attrs = [
+                { name: 'Debm', value: ration.code }, // 编码
+                { name: 'Mc', value: ration.name }, // 名称
+                { name: 'Dw', value: ration.unit }, // 单位
+                { name: 'Sl', value: ration.tenderQuantity }, // 工程量
+                { name: 'Dj', value: getFee(ration.fees, 'common.tenderUnitFee'), type: TYPE.DECIMAL }, // 单价
+                { name: 'Hj', value: getFee(ration.fees, 'common.tenderTotalFee'), type: TYPE.DECIMAL }, // 合价
+                { name: 'Rgf', value: getFee(ration.fees, 'marketLabour.tenderTotalFee'), type: TYPE.DECIMAL }, // 人工费
+                { name: 'Clf', value: getFee(ration.fees, 'marketMaterial.tenderTotalFee'), type: TYPE.DECIMAL }, // 材料费
+                { name: 'Jxf', value: getFee(ration.fees, 'marketMachine.tenderTotalFee'), type: TYPE.DECIMAL }, // 机械费
+                { name: 'Sbf', value: getFee(ration.fees, 'marketEquipment.tenderTotalFee'), type: TYPE.DECIMAL }, // 设备费
+                { name: 'Csf', value: getFee(ration.fees, 'measure.tenderTotalFee'), type: TYPE.DECIMAL }, // 措施费
+                { name: 'Glf', value: getFee(ration.fees, 'manage.tenderTotalFee'), type: TYPE.DECIMAL }, // 企业管理费
+                { name: 'Gf', value: getFee(ration.fees, 'force.tenderTotalFee'), type: TYPE.DECIMAL }, // 规费
+                { name: 'Lr', value: getFee(ration.fees, 'profit.tenderTotalFee'), type: TYPE.DECIMAL }, // 利润
+                { name: 'Sj', value: getFee(ration.fees, 'tax.tenderTotalFee'), type: TYPE.DECIMAL }, // 税金
+                { name: 'Delb', value: type, type: TYPE.INT }, // 取定额/量价/设备的类别。(1=普通定额,2=人工,3=材料,4=机械,5=设备)
+                { name: 'Iszd', value: 'false', type: TYPE.BOOL }, // 暂时,全部取fals
+            ];
+            Element.call(this, 'QdxdezjMx', attrs);
+        }
+
+        // 定额人材机含量
+        function Qdxdercjhl() {
+            Element.call(this, 'Qdxdercjhl');
+        }
+
+        // 定额人材机含量明细
+        function QdxdercjhlMx(rcjID, quantity) {
+            const attrs = [
+                { name: 'RcjId', value: rcjID }, // 人材机资源ID
+                { name: 'Sl', value: quantity, type: TYPE.DECIMAL }, // 消耗量
+            ]
+            Element.call(this, 'QdxdercjhlMx', attrs);
+        }
+
+        // 清单人材机含量
+        function Qdxrcjhl() {
+            Element.call(this, 'Qdxrcjhl');
+        }
+
+        // 清单人材机含量明细
+        function QdxrcjhlMx(item) {
+            const attrs = [
+                { name: 'RcjId', value: item.rcjID }, // 人材机资源ID
+                { name: 'Rcjhl', value: item.contain, type: TYPE.DECIMAL }, // 含量:取叶子清单下所有的人材机的含量,=各定额下的人材机总消耗量之和,再除以清单工程量
+                { name: 'Rcjhj', value: item.totalPrice, type: TYPE.DECIMAL }, // 合价:人材机含量*人材机预算价
+                { name: 'Zgjbz', value: item.isEvaluate, type: TYPE.BOOL }, // 是否暂估,根据资源ID,读取工料机汇总界面对应的“是否暂估”
+                { name: 'Zcbz', value: 'false', type: TYPE.BOOL }, // 主材标记,公路上无此概念,默认输出=fales
+                { name: 'Zyclbz', value: item.isMainMaterial, type: TYPE.BOOL }, // 根据资源ID,读取工料机汇总界面对应的“主要材料”
+            ]
+            Element.call(this, 'QdxrcjhlMx', attrs);
+        }
+
+        // 计日工
+        function Jrg() {
+            Element.call(this, 'Jrg');
+        }
+
+        // 计日工标题
+        function JrgBt(node) {
+            const typeMap = {
+                [fixedFlag.LABOUR_SERVICE]: '1',
+                [fixedFlag.MATERIAL]: '2',
+                [fixedFlag.CONSTRUCTION_MACHINE]: '3',
+            };
+            const attrs = [
+                { name: 'Name', value: node.data.name }, // 名称
+                { name: 'Je', value: isBidInvitation ? '0' : getFee(node.data.fees, 'common.tenderTotalFee'), type: TYPE.DECIMAL }, // 金额
+                { name: 'Lb', value: typeMap[node.getFlag()], type: TYPE.INT }, // 类别:1=劳务;2=材料;3=施工机械
+                { name: 'Bz', value: node.data.remark }, // 备注
+            ];
+            Element.call(this, 'JrgBt', attrs);
+        }
+
+        // 计日工明细
+        function JrgMx(node) {
+            const attrs = [
+                { name: 'Bh', value: node.data.code }, // 编码
+                { name: 'Name', value: node.data.name }, // 名称
+                { name: 'Dw', value: node.data.unit }, // 单位
+                { name: 'Sl', value: node.data.quantity }, // 工程量
+                { name: 'Dj', value: isBidInvitation ? '0' : getFee(node.data.fees, 'common.tenderTotalFee'), type: TYPE.DECIMAL }, // 单价
+                { name: 'Hj', value: isBidInvitation ? '0' : getFee(node.data.fees, 'common.tenderUnitFee'), type: TYPE.DECIMAL }, // 合价
+            ];
+            Element.call(this, 'JrgMx', attrs);
+        }
+
+        // 暂估材料表、评标材料表
+        function gljRefRoot(eleName) {
+            Element.call(this, eleName);
+        }
+
+        // 暂估材料表、评标材料表明细
+        function gljRefElement(eleName, glj) {
+            const attrs = [
+                { name: 'Xh', value: glj.seq }, // 序号
+                { name: 'RcjId', value: projectGLJIDToRcjID[glj.projectGLJID] }, // 资源ID
+                { name: 'Bm', value: glj.code }, // 编码
+                { name: 'Mc', value: glj.name }, // 名称
+                { name: 'Ggxh', value: glj.specs }, // 规格型号
+                { name: 'Dw', value: glj.unit }, // 单位
+                { name: 'Sl', value: BID_INVITATION ? '0' : glj.quantity, type: TYPE.DECIMAL }, // 工程量
+                { name: 'Dj', value: glj.marketPrice, type: TYPE.DECIMAL }, // 暂定价、单价
+                { name: 'Hj', value: BID_INVITATION ? '0' : glj.totalPrice, type: TYPE.DECIMAL }, // 合价
+                { name: 'Bz', value: glj.remark }, // 备注
+            ];
+            Element.call(this, eleName, attrs);
+        }
+
+        // 人材机汇总
+        function Rcjhz() {
+            Element.call(this, 'Rcjhz');
+        }
+
+        // 人材机汇总明细
+        function RcjhzMx(glj) {
+            const rootTypeReg = /\d/;
+            let rootType = rootTypeReg.exec(glj.type)[0];
+            if (!['1', '2', '3'].includes(rootType)) {
+                rootType = '2'; 
+            }
+            const attrs = [
+                { name: 'RcjId', value: projectGLJIDToRcjID[glj.id] }, // 资源ID
+                { name: 'RcjBm', value: glj.code }, // 编码
+                { name: 'Name', value: glj.name }, // 名称
+                { name: 'Ggxh', value: glj.specs }, // 规格型号
+                { name: 'Dw', value: glj.unit }, // 单位
+                { name: 'Dj', value: glj.priceInfo.tenderPrice, type: TYPE.DECIMAL }, // 预算价,调后
+                { name: 'Sl', value: glj.tenderQuantity, type: TYPE.DECIMAL }, // 总消耗量
+                { name: 'Hj', value: glj.totalPrice, type: TYPE.DECIMAL }, // 合价,人材料总消耗量*预算价
+                { name: 'Cd', value: '' }, // 产地
+                { name: 'Gycs', value: '' }, // 厂商
+                { name: 'Rcjlb', value: rootType, type: TYPE.INT }, // 人材机类型 1=人工;2=材料;3=机械
+                { name: 'Jgbz', value: 'false', type: TYPE.BOOL }, // 供材方
+                { name: 'Zyclbz', value: !!glj.is_main_material, type: TYPE.BOOL }, // 主要材料
+                { name: 'Zgjbz', value: !!glj.is_evaluate, type: TYPE.BOOL }, // 是否暂估
+                { name: 'Zcbz', value: 'false', type: TYPE.BOOL }, // 主材标记
+            ];
+            Element.call(this, 'RcjhzMx', attrs);
+        }
+
+        // 配比组成
+        function PbZc() {
+            Element.call(this, 'PbZc');
+        }
+
+        // 配比明细
+        function PbZcMx(ratio) {
+            const attrs = [
+                { name: 'RcjId', value: projectGLJIDToRcjID[ratio.projectGLJID] }, // 组成物对应人材机汇总的资源ID
+                { name: 'Sl', value: ratio.consumption, type: TYPE.DECIMAL }, // 组成物消耗量
+            ];
+            Element.call(this, 'PbZcMx', attrs);
+        }
+        
+        // 校验信息
+        function Jyxx(cpuID, diskID, macID, toMD5Value) {
+            const attrs = [
+                { name: 'SoftName', value: '纵横创新软件有限公司' }, // 公司名
+                { name: 'SoftNum', value: md5(toMD5Value) }, // 校验数据
+                { name: 'MacAdress', value: macID }, // mac地址
+                { name: 'DogNum', value: userID }, // 加密锁号,取用户ID
+                { name: 'ComputerName', value: USER_NAME }, // 计算机名,取用户名称
+                { name: 'HDDSerial', value: diskID }, // 硬盘序列号
+                { name: 'CPUSerial', value: cpuID }, // CPU序列号
+            ];
+            Element.call(this, 'Jyxx', attrs);
+        }
+
+        // 组装数据 --------------------------------------
+
+        // 组装建设项目数据
+        function setupConstruction(constructionData) {
+            const information = constructionData.property && constructionData.property.basicInformation || [];
+            const summaryInfo = constructionData.summaryInfo[constructionData.ID];
+
+            const chiZGLGC = new ChiZGLGC(constructionData.name, information);
+            chiZGLGC.children.push(new GongCXX(information));
+
+            const zhaoTBXX = new ZhaoTBXX();
+            chiZGLGC.children.push(zhaoTBXX);
+            if (isBidInvitation) {
+                zhaoTBXX.children.push(new ZhaoBiaoXx(information));
+            } else if (isControl) {
+                zhaoTBXX.children.push(new ZhaoBiaoKzXx(information, summaryInfo.totalCost));
+            } else {
+                zhaoTBXX.children.push(new TouBiaoXx(information, summaryInfo.totalCost));
+            }
+
+            const gongLGCSJ = new GongLGCSJ(constructionData.name, information);
+            chiZGLGC.children.push(gongLGCSJ);
+
+            // 将单位工程工程特征中,单项工程编号、名称相同的,插入到建设项目和分段(单位工程)的中间层。
+            const midLayerMap = {}; // 单项工程key(code@name)与单项工程节点映射
+            for (const tenderData of constructionData.children) {
+                const feature = tenderData.property && tenderData.property.projectFeature || [];
+                const midLayerCode = getValueByKey(feature, 'singleProjNo');
+                const midLayerName = getValueByKey(feature, 'singleProjName');
+                // const midLayerKey = `${midLayerCode}@${midLayerName}`;
+                // if (!midLayerMap[midLayerKey]) {
+                //     chiZGLGC.children.push(midLayerMap[midLayerKey] = new Dxgcxx(midLayerCode, midLayerName));
+                // }
+                // midLayerMap[midLayerKey].children.push(setupTender(tenderData, feature));
+            }
+            // 校验信息
+            const [cpuID, diskID, macID] = generateHardwareId().split(';');
+            const suffix = INTERFACE_CONFIG[areaKey]['fileSuffix'][exportKind];
+            // 需要md5的值:MD5(“WHGLZTB”+项目名称+机器码+加密锁锁号)机器码取mac地址,加密锁锁号取用户账号id
+            const toMD5Suffix = suffix.split('.')[1];
+            const toMD5Value = `${toMD5Suffix}${constructionData.name}${macID}${userID}`;
+            // chiZGLGC.children.push(new Jyxx(cpuID, diskID, macID, suffix, toMD5Value));
+            return [{
+                data: chiZGLGC,
+                exportKind,
+                fileName: `${constructionData.name}${suffix}`
+            }];
+        }
+
+        // getData接口数据
+        let curDetail;
+
+        // 需要先设置项目人材机的关联ID(从1开始),因为定额人材机等一些节点需要用到这个关联ID
+        const projectGLJIDToRcjID = {}; // 项目人材机ID与新生成的整形ID映射
+        const projectGLJMap = {}; // 项目人材机与项目人材机数据映射
+
+        // 组装单位工程数据
+        function setupTender(tenderData, feature) {
+            curDetail = tenderDetailMap[tenderData.ID];
+            curDetail.projectGLJ.datas.gljList.forEach((glj, index) => {
+                projectGLJIDToRcjID[glj.id] = index + 1;
+                projectGLJMap[glj.id] = glj;
+            });
+            const dwgcxx = new Dwgcxx(tenderData.name, feature);
+            dwgcxx.children.push(
+                setupFeeRate(curDetail.FeeRate),
+                setupBills(curDetail.mainTree),
+                ...setupGLJList(curDetail)
+            );
+            return dwgcxx;
+        }
+
+        // 组装费率数据
+        function setupFeeRate(feeRateDetail) {
+            const qfxx = new Qfxx();
+            const jjflb = new JjFlb();
+            // 费率界面左侧底层数据
+            let curRootItem;
+            feeRateDetail.datas.rates.forEach(item => {
+                if (!item.ParentID) {
+                    curRootItem = item;
+                } else if (!item.sum) { // 最底层
+                    jjflb.children.push(new JjFlbMx(curRootItem, item));
+                }
+            });
+            // 费率界面右侧顶层数据
+            const jjflx = new JjFlx();
+            const flxmxData = feeRateDetail
+                .getAllSubRates()
+                .filter(item => !item.isSub)
+                .map(item => new JjFlxMx(item));
+            jjflx.children.push(...flxmxData);
+
+            qfxx.children.push(jjflb, jjflx);
+            return qfxx;
+        }
+
+        // 组装清单数据
+        function setupBills(mainTree) {
+            const qdxm = new QdXm();
+            const qdbtData = mainTree.roots.map(node => new QdBt(node));
+            qdxm.children.push(...qdbtData);
+
+            mainTree.roots.forEach(node => {
+                const flag = node.getFlag();
+                const qdbt = new QdBt(node);
+                if (flag === fixedFlag.ONE_SEVEN_BILLS) { // 100章到700章清单需要输出详细数据
+                    qdbt.children.push(...setupSubBills(node.children));
+                } else if (flag === fixedFlag.DAYWORK_LABOR) {
+                    qdbt.children.push(setupDaywork(node.children));
+                }
+                qdxm.children.push(qdbt);
+            });
+
+            function setupSubBills(nodes) {
+                const rst = [];
+                nodes.forEach(node => {
+                    const qdmx = new QdMx(node);
+                    rst.push(qdmx);
+                    const subIsRations = node.children.length && !node.source.children.length;
+                    if (subIsRations) {
+                        qdmx.children.push(...setupRations(node.children));
+                        qdmx.children.push(...setupBillsContain(node.data));
+                    } else {
+                        qdmx.children.push(...setupSubBills(node.children));
+                    }
+                });
+                return rst;
+            }
+
+            function setupDaywork(nodes) {
+                const dayworkRoot = new Jrg();
+                const dayworkBT = nodes.map(node => {
+                    const bt = new JrgBt(node);
+                    const dayworkMX = node.children.map(child => new JrgMx(child));
+                    bt.children.push(...dayworkMX);
+                    return bt;
+                });
+                dayworkRoot.children.push(...dayworkBT);
+                return dayworkRoot;
+            }
+
+            return qdxm;
+        }
+
+        // 组装定额、定额人材机数据
+        function setupRations(rationNodes) {
+            // 招标文件不输出
+            if (isBidInvitation) {
+                return [];
+            }
+            const rationRoot = new Qdxdezj();
+            const rationEles = rationNodes.map(node => {
+                const rationEle = new QdxdezjMx(node.data);
+                /* // 定额人材机
+                let rationGLJList = curDetail.ration_glj.datas.filter(glj => glj.rationID === node.data.ID);
+                rationGLJList = gljUtil.sortRationGLJ(rationGLJList); */
+                const rationGLJRoot = new Qdxdercjhl();
+                const rationGLJEles = node.data.rationGLJList.map(glj => new QdxdercjhlMx(projectGLJIDToRcjID[glj.projectGLJID], glj.tenderQuantity));
+                rationGLJRoot.children.push(...rationGLJEles);
+                rationEle.children.push(rationGLJRoot);
+                return rationEle;
+            });
+            rationRoot.children.push(...rationEles);
+            return [rationRoot];
+        }
+
+        // 组装清单人材机含量数据
+        function setupBillsContain(bills) {
+            if (isBidInvitation) {
+                return [];
+            }
+            // 读取清单下的人材机,先将各定额下的人材机汇总,相同的合并(相同的项目人材机ID)
+            const gljList = curDetail.ration_glj.datas.filter(glj => glj.billsItemID === bills.ID);
+            if (!gljList) {
+                return [];
+            }
+            const map = {};
+            gljList.forEach(glj => {
+                if (!map[glj.projectGLJID]) {
+                    const projectGLJ = projectGLJMap[glj.projectGLJID];
+                    map[glj.projectGLJID] = {
+                        rcjID: projectGLJIDToRcjID[glj.projectGLJID],
+                        totalQuantity: glj.tenderQuantity,
+                        price: glj.tenderPrice,
+                        isEvaluate: !!projectGLJ.is_evaluate,
+                        isMainMaterial: !!projectGLJ.is_main_material
+                    };
+                } else {
+                    map[glj.projectGLJID].totalQuantity = scMathUtil.roundTo(map[glj.projectGLJID].totalQuantity + glj.tenderQuantity, -6);
+                }
+            });
+            const containItems = Object
+                .values(map)
+                .map(glj => {
+                    const contain = glj.totalQuantity / (bills.quantity || 1);
+                    return {
+                        rcjID: glj.rcjID,
+                        contain: scMathUtil.roundTo(contain, -6), // 固定取6位
+                        totalPrice: scMathUtil.roundTo(contain * glj.price, -2), // 固定取2位
+                        isEvaluate: glj.isEvaluate,
+                        isMainMaterial: glj.isMainMaterial
+                    };
+                });
+            const root = new Qdxrcjhl();
+            root.children.push(...containItems.map(item => new QdxrcjhlMx(item)));
+            return [root]
+        }
+
+        // 组装人材机汇总相关表数据
+        function setupGLJList(tenderDetail) {
+            // 暂估材料
+            const zgcl = new gljRefRoot('ZgCl');
+            zgcl.children = tenderDetail.evaluateMaterialData.map(glj => new gljRefElement('ZgClMx', glj));
+
+            // 评标材料
+            const jpcl = new gljRefRoot('JpCl');
+            jpcl.children = tenderDetail.bidMaterialData.map(glj => new gljRefElement('JpClMx', glj));
+            if (isBidInvitation) {
+                return [zgcl, jpcl];
+            }
+            // 人材机汇总 (招标不导出)
+            const rcjhz = new Rcjhz();
+            rcjhz.children = tenderDetail.projectGLJ.datas.gljList.map(pGLJ => {
+                const gljElement = new RcjhzMx(pGLJ);
+                // 组成物
+                const connectKey = gljUtil.getIndex(pGLJ, gljKeyArray);
+                const ratioData = tenderDetail.projectGLJ.datas.mixRatioMap[connectKey];
+                if (ratioData && ratioData.length) {
+                    const pbzc = new PbZc();
+                    pbzc.children = ratioData.map(ratio => new PbZcMx(ratio));
+                    gljElement.children.push(pbzc);
+                }
+                return gljElement;
+            });
+            return [zgcl, jpcl, rcjhz];
+        }
+
+        return setupConstruction(projectData);
+
+
+    }
+
+    return {
+        entry
+    };
+})();

Plik diff jest za duży
+ 720 - 701
web/building_saas/standard_interface/export/anhui_maanshan.js


Plik diff jest za duży
+ 846 - 783
web/building_saas/standard_interface/export/base.js


Plik diff jest za duży
+ 1254 - 172
web/building_saas/standard_interface/export/guangdong_zhongshan.js


+ 76 - 75
web/building_saas/standard_interface/export/view.js

@@ -7,83 +7,84 @@
  */
 //导出接口相关
 const EXPORT_VIEW = (() => {
-    'use strict';
+  'use strict';
 
-    const _base = INTERFACE_EXPORT_BASE;
-    const _cache = _base.CACHE;
-    // 导出数据缓存,为了自检完后,再导出的时候不需要重新运行相关提取程序。(暂时取消了自检,但还是留着这个缓存机制)
-    let _exportCache = [];
-    // 操作状态
-    const STATE = {
-        checking: false, // 自检
-        exporting: false, // 导出
-    };
-    // 回到初始状态,需要清空cache中的数据
-    function resetState() {
-        _exportCache = [];
-        _cache.clear();
-    }
-    //事件监听
-    function exportListener() {
-        // 导出接口
-        $('#interface-export-confirm').click(async function () {
-            const pr = new SCComponent.InitProgressBar();
-            try {
-                const checkedDatas = $('#interface-export-modal input[type="checkbox"]:checked');
-                if (!checkedDatas.length) {
-                    throw '请勾选导出文件。';
-                }
-                const parentArea = $('#export-parent-area').val();
-                const subArea = $('#export-sub-area').val();
-                if (!parentArea || !subArea) {
-                    throw '请选择有效地区。';
-                }
-                // 按照地区动态加载导出脚本
-                const areaKey = `${parentArea}@${subArea}`;
-                await STD_INTERFACE.loadScriptByArea(areaKey, STD_INTERFACE.ScriptType.EXPORT);
-                if (STATE.exporting) {
-                    return;
-                }
-                STATE.exporting = true;
-                if (!_exportCache || !_exportCache.length) {
-                    pr.start('导出数据接口', '正在导出文件,请稍候……');
-                    for (const checkedData of checkedDatas) {
-                        const boqType = parseInt($(checkedData).val());
-                        const requestForSummaryInfo = INTERFACE_EXPORT.requestForSummaryInfo || {};
-                        const projectID = projectObj.project.ID();
-                        const exportData = await _base.extractExportData(INTERFACE_EXPORT.entry, requestForSummaryInfo, boqType, areaKey, projectID, userID);
-                        _exportCache.push(...exportData);
-                    }
-                }
-                if (_exportCache && _exportCache.length) {
-                    // 导出文件
-                    await _base.exportFile(_exportCache, INTERFACE_EXPORT.saveAsFile || INTERFACE_EXPORT_BASE.defaultSaveAs);
-                }
-            } catch (err) {
-                console.log(err);
-                alert(err);
-            } finally {
-                pr.end();
-                setTimeout(() => {
-                    STATE.exporting = false;
-                }, 300);
-            }
-        });
-        //导出窗口--------
-        $('#interface-export-modal').on('hide.bs.modal', function () {
-            resetState();
-            STATE.checking = false;
-            STATE.exporting = false;
-            $('#interface-export-modal input[type="checkbox"]:eq(0)').prop('checked', true);
-        });
-        $('#interface-export-modal input[type="checkbox"]').click(function () {
-            resetState();
-        });
-    }
-    return { exportListener, resetState }
+  const _base = INTERFACE_EXPORT_BASE;
+  const _cache = _base.CACHE;
+  // 导出数据缓存,为了自检完后,再导出的时候不需要重新运行相关提取程序。(暂时取消了自检,但还是留着这个缓存机制)
+  let _exportCache = [];
+  // 操作状态
+  const STATE = {
+    checking: false, // 自检
+    exporting: false, // 导出
+  };
+  // 回到初始状态,需要清空cache中的数据
+  function resetState() {
+    _exportCache = [];
+    _cache.clear();
+  }
+  //事件监听
+  function exportListener() {
+    // 导出接口
+    $('#interface-export-confirm').click(async function () {
+      const pr = new SCComponent.InitProgressBar();
+      try {
+        const checkedDatas = $('#interface-export-modal input[type="checkbox"]:checked');
+        if (!checkedDatas.length) {
+          throw '请勾选导出文件。';
+        }
+        const parentArea = $('#export-parent-area').val();
+        const subArea = $('#export-sub-area').val();
+        if (!parentArea || !subArea) {
+          throw '请选择有效地区。';
+        }
+        // 按照地区动态加载导出脚本
+        const areaKey = `${parentArea}@${subArea}`;
+        await STD_INTERFACE.loadScriptByArea(areaKey, STD_INTERFACE.ScriptType.EXPORT);
+        if (STATE.exporting) {
+          return;
+        }
+        STATE.exporting = true;
+        if (!_exportCache || !_exportCache.length) {
+          pr.start('导出数据接口', '正在导出文件,请稍候……');
+          for (const checkedData of checkedDatas) {
+            const boqType = parseInt($(checkedData).val());
+            const requestForSummaryInfo = INTERFACE_EXPORT.requestForSummaryInfo || null;
+            const projectID = projectObj.project.ID();
+            const exportData = await _base.extractExportData(INTERFACE_EXPORT.entry, requestForSummaryInfo, boqType, areaKey, projectID, userID);
+            _exportCache.push(...exportData);
+          }
+        }
+        if (_exportCache && _exportCache.length) {
+          // 导出文件
+          await _base.exportFile(_exportCache, INTERFACE_EXPORT.saveAsFile || INTERFACE_EXPORT_BASE.defaultSaveAs);
+        }
+        $('#interface-export-modal').modal('hide');
+      } catch (err) {
+        console.log(err);
+        alert(err);
+      } finally {
+        pr.end();
+        setTimeout(() => {
+          STATE.exporting = false;
+        }, 300);
+      }
+    });
+    //导出窗口--------
+    $('#interface-export-modal').on('hide.bs.modal', function () {
+      resetState();
+      STATE.checking = false;
+      STATE.exporting = false;
+      $('#interface-export-modal input[type="checkbox"]:eq(0)').prop('checked', true);
+    });
+    $('#interface-export-modal input[type="checkbox"]').click(function () {
+      resetState();
+    });
+  }
+  return { exportListener, resetState }
 })();
 
 $(document).ready(() => {
-    $('#interface-export-modal').on('show.bs.modal', () => STD_INTERFACE.initExportAreas($('#export-parent-area'), $('#export-sub-area')));
-    EXPORT_VIEW.exportListener();
+  $('#interface-export-modal').on('show.bs.modal', () => STD_INTERFACE.initExportAreas($('#export-parent-area'), $('#export-sub-area')));
+  EXPORT_VIEW.exportListener();
 })

+ 91 - 91
web/building_saas/standard_interface/index.js

@@ -33,102 +33,102 @@ let INTERFACE_EXPORT = {};
 let INTERFACE_IMPORT = {};
 
 const STD_INTERFACE = (() => {
-    'use strict';
+  'use strict';
 
-    // 根据地区配置,初始化地区选项
-    function initExportAreas($parentAreas, $subAreas) {
-        const connectedAreas = Object.keys(INTERFACE_CONFIG);
-        const parentMap = {};
-        connectedAreas.forEach(connectedArea => {
-            const areas = connectedArea.split('@');
-            (parentMap[areas[0]] || (parentMap[areas[0]] = [])).push(areas[1]);
-        });
-        const parentAreasHtml = Object
-            .keys(parentMap)
-            .reduce((acc, area) => acc += `<option value="${area}">${area}</option>`, '');
-        $parentAreas.html(parentAreasHtml);
-        const subAreasHtml = parentMap[Object.keys(parentMap)[0]].reduce((acc, area) => acc += `<option value="${area}">${area}</option>`, '');
-        $subAreas.html(subAreasHtml);
-        // 父级地区变更,子地区选项更新
-        $parentAreas.change(function () {
-            EXPORT_VIEW.resetState(); // 清空接口缓存
-            const curArea = $(this).val();
-            const subAreasHtml = parentMap[curArea].reduce((acc, area) => acc += `<option value="${area}">${area}</option>`, '');
-            $subAreas.html(subAreasHtml);
-        });
-        $subAreas.change(function() {
-            EXPORT_VIEW.resetState();
-        })
-    }
+  // 根据地区配置,初始化地区选项
+  function initExportAreas($parentAreas, $subAreas) {
+    const connectedAreas = Object.keys(INTERFACE_CONFIG);
+    const parentMap = {};
+    connectedAreas.forEach(connectedArea => {
+      const areas = connectedArea.split('@');
+      (parentMap[areas[0]] || (parentMap[areas[0]] = [])).push(areas[1]);
+    });
+    const parentAreasHtml = Object
+      .keys(parentMap)
+      .reduce((acc, area) => acc += `<option value="${area}">${area}</option>`, '');
+    $parentAreas.html(parentAreasHtml);
+    const subAreasHtml = parentMap[Object.keys(parentMap)[0]].reduce((acc, area) => acc += `<option value="${area}">${area}</option>`, '');
+    $subAreas.html(subAreasHtml);
+    // 父级地区变更,子地区选项更新
+    $parentAreas.change(function () {
+      EXPORT_VIEW.resetState(); // 清空接口缓存
+      const curArea = $(this).val();
+      const subAreasHtml = parentMap[curArea].reduce((acc, area) => acc += `<option value="${area}">${area}</option>`, '');
+      $subAreas.html(subAreasHtml);
+    });
+    $subAreas.change(function () {
+      EXPORT_VIEW.resetState();
+    })
+  }
 
-    /**
-     * 动态加载script
-     * 由于后续的接口可能会非常多,一次性加载所有的接口文件完全没必要,而且不可控,很容易导致初次加载速度变慢。
-     * 在选定相关地区后,再根据地区对应的script路径,动态加载script
-     * 不需要缓存,缓存可能会影响正常操作的性能。而且导入导出时动态获取接口文件的需要的时间,客户是不可感知的。
-     * @param {String} path - 需要加载的scipt路径
-     * @return {Promise}
-     */
-    function loadScript(path) {
-        return new Promise((resolve, reject) => {
-            const scriptID = 'interface-script';
-            const body = document.getElementsByTagName('body')[0];
-            // 移除原来的
-            const orgScript = document.getElementById(scriptID);
-            if (orgScript) {
-                body.removeChild(orgScript);
-            }
-            // 增加新的
-            const script = document.createElement('script');
-            script.src = path;
-            script.type = 'text/javascript';
-            script.id = scriptID;
-            body.appendChild(script);
-            script.onload = script.onreadystatechange = function () { // ie、ff触发事件不同,都写上
-                if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
-                    script.onload = script.onreadystatechange = null;
-                    resolve();
-                }
-            };
-            script.onerror = function () {
-                reject('script加载失败。');
-            };
-        });
-    }
+  /**
+   * 动态加载script
+   * 由于后续的接口可能会非常多,一次性加载所有的接口文件完全没必要,而且不可控,很容易导致初次加载速度变慢。
+   * 在选定相关地区后,再根据地区对应的script路径,动态加载script
+   * 不需要缓存,缓存可能会影响正常操作的性能。而且导入导出时动态获取接口文件的需要的时间,客户是不可感知的。
+   * @param {String} path - 需要加载的scipt路径
+   * @return {Promise}
+   */
+  function loadScript(path) {
+    return new Promise((resolve, reject) => {
+      const scriptID = 'interface-script';
+      const body = document.getElementsByTagName('body')[0];
+      // 移除原来的
+      const orgScript = document.getElementById(scriptID);
+      if (orgScript) {
+        body.removeChild(orgScript);
+      }
+      // 增加新的
+      const script = document.createElement('script');
+      script.src = path;
+      script.type = 'text/javascript';
+      script.id = scriptID;
+      body.appendChild(script);
+      script.onload = script.onreadystatechange = function () { // ie、ff触发事件不同,都写上
+        if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
+          script.onload = script.onreadystatechange = null;
+          resolve();
+        }
+      };
+      script.onerror = function () {
+        reject('script加载失败。');
+      };
+    });
+  }
 
-    const ScriptType = {
-        EXPORT: 'export',
-        IMPORT: 'import',
-    };
+  const ScriptType = {
+    EXPORT: 'export',
+    IMPORT: 'import',
+  };
 
-    let curArea = '';
-    /**
-     * 根据地区和脚本类型加载脚本
-     * @param {String} area - 地区选项 eg: '安徽省@马鞍山'
-     * @param {Number} scriptType - 脚本类型
-     * @return {Void}
-     */
-    async function loadScriptByArea(area, scriptType) {
-        if (area === curArea) {
-            return;
-        }
-        curArea = area;
-        const configItem = INTERFACE_CONFIG[area];
-        if (!configItem) {
-            throw new Error(`[${area}]不存在有效配置。`);
-        }
-        const scriptName = configItem.scriptName;
-        if (!scriptName) {
-            throw new Error(`[${area}]不存在有效脚本。`);
-        }
-        const fullPath = `/web/building_saas/standard_interface/${scriptType}/${scriptName}`;
-        await loadScript(fullPath);
+  let curArea = '';
+  /**
+   * 根据地区和脚本类型加载脚本
+   * @param {String} area - 地区选项 eg: '安徽省@马鞍山'
+   * @param {Number} scriptType - 脚本类型
+   * @return {Void}
+   */
+  async function loadScriptByArea(area, scriptType) {
+    if (area === curArea) {
+      return;
+    }
+    curArea = area;
+    const configItem = INTERFACE_CONFIG[area];
+    if (!configItem) {
+      throw new Error(`[${area}]不存在有效配置。`);
+    }
+    const scriptName = configItem.scriptName;
+    if (!scriptName) {
+      throw new Error(`[${area}]不存在有效脚本。`);
     }
+    const fullPath = `/web/building_saas/standard_interface/${scriptType}/${scriptName}`;
+    await loadScript(fullPath);
+  }
 
-    return {
-        initExportAreas,
-        ScriptType,
-        loadScriptByArea,
-    };
+  return {
+    initExportAreas,
+    ScriptType,
+    loadScriptByArea,
+  };
 
 })();

Plik diff jest za duży
+ 509 - 309
web/building_saas/unit_price_file/index.js


+ 4 - 0
web/common/html/header.html

@@ -194,6 +194,10 @@
         </div>
     </div>
 </div>
+<div class="modal fade" id="empty-modal" data-backdrop="static" style="display: none;" aria-hidden="true">
+    <div class="modal-dialog" role="document">
+    </div>
+</div>
 <!--激活产品 & 售后服务 & 联系客服-->
 <!--办事处客服列表-->
 <div class="modal fade z-index-3000" id="activ" data-backdrop="static" style="display: none; overflow: auto;" aria-hidden="true">

+ 2 - 16
web/over_write/js/anhui_2019.js

@@ -341,23 +341,9 @@ if (typeof baseFigureTemplate !== 'undefined') {
             return cbTools.getBaseFee(calcBase.fixedFlag.ONE_SEVEN_BILLS, tender, 'common');
         },
         //{专项暂定合计}
-        // 汇总专项暂定列有值的清单的金额
+        // 第100章至700章清单行的暂估合价
         'ZXZDHJ': function (tender) {
-            let rst = 0,
-                feeField = 'common',
-                subFeeField = tender ? 'tenderTotalFee' : 'totalFee';
-            let billsData = calcBase.project.Bills.datas,
-                filterData = billsData.filter(function (data) {
-                    return data.specialProvisional;
-                });
-            for (let data of filterData) {
-                if (cbTools.isUnDef(data.feesIndex) || _.isEmpty(data.feesIndex) ||
-                    cbTools.isUnDef(data.feesIndex[feeField]) || cbTools.isUnDef(data.feesIndex[feeField][subFeeField])) {
-                    continue;
-                }
-                rst += data.feesIndex[feeField][subFeeField];
-            }
-            return rst.toDecimal(decimalObj.bills.totalPrice);
+            return cbTools.getBaseFee(calcBase.fixedFlag.ONE_SEVEN_BILLS, tender, 'estimate');
         },
         //{100章以外清单合计}
         // 取清单固定清单[第100章至700章清单]的金额,但扣除清单100章下的金额。

+ 2 - 16
web/over_write/js/hunan_2020.js

@@ -358,23 +358,9 @@ if (typeof baseFigureTemplate !== 'undefined') {
             return cbTools.getBaseFee(calcBase.fixedFlag.ONE_SEVEN_BILLS, tender, 'common');
         },
         //{专项暂定合计}
-        // 汇总专项暂定列有值的清单的金额
+        // 第100章至700章清单行的暂估合价
         'ZXZDHJ': function (tender) {
-            let rst = 0,
-                feeField = 'common',
-                subFeeField = tender ? 'tenderTotalFee' : 'totalFee';
-            let billsData = calcBase.project.Bills.datas,
-                filterData = billsData.filter(function (data) {
-                    return data.specialProvisional;
-                });
-            for (let data of filterData) {
-                if (cbTools.isUnDef(data.feesIndex) || _.isEmpty(data.feesIndex) ||
-                    cbTools.isUnDef(data.feesIndex[feeField]) || cbTools.isUnDef(data.feesIndex[feeField][subFeeField])) {
-                    continue;
-                }
-                rst += data.feesIndex[feeField][subFeeField];
-            }
-            return rst.toDecimal(decimalObj.bills.totalPrice);
+            return cbTools.getBaseFee(calcBase.fixedFlag.ONE_SEVEN_BILLS, tender, 'estimate');
         },
         //{100章以外清单合计}
         // 取清单固定清单[第100章至700章清单]的金额,但扣除清单100章下的金额。

+ 2 - 16
web/over_write/js/neimeng_2019.js

@@ -296,23 +296,9 @@ if (typeof baseFigureTemplate !== 'undefined') {
             return cbTools.getBaseFee(calcBase.fixedFlag.ONE_SEVEN_BILLS, tender, 'common');
         },
         //{专项暂定合计}
-        // 汇总专项暂定列有值的清单的金额
+        // 第100章至700章清单行的暂估合价
         'ZXZDHJ': function (tender) {
-            let rst = 0,
-                feeField = 'common',
-                subFeeField = tender ? 'tenderTotalFee' : 'totalFee';
-            let billsData = calcBase.project.Bills.datas,
-                filterData = billsData.filter(function (data) {
-                    return data.specialProvisional;
-                });
-            for (let data of filterData) {
-                if (cbTools.isUnDef(data.feesIndex) || _.isEmpty(data.feesIndex) ||
-                    cbTools.isUnDef(data.feesIndex[feeField]) || cbTools.isUnDef(data.feesIndex[feeField][subFeeField])) {
-                    continue;
-                }
-                rst += data.feesIndex[feeField][subFeeField];
-            }
-            return rst.toDecimal(decimalObj.bills.totalPrice);
+            return cbTools.getBaseFee(calcBase.fixedFlag.ONE_SEVEN_BILLS, tender, 'estimate');
         },
         //{100章以外清单合计}
         // 取清单固定清单[第100章至700章清单]的金额,但扣除清单100章下的金额。

+ 394 - 81
web/over_write/js/quanguo_2018.js

@@ -1,13 +1,3 @@
-const progression = [];
-const deficiency = {};
-if (typeof module !== 'undefined' && !module.nodeType) {
-  module.exports = {
-    progression,
-    deficiency
-  };
-}
-
-
 let isQG2018 = true;
 
 function overwriteRationCalcBases() {
@@ -56,79 +46,79 @@ function overwriteRationCalcBases() {
 (function overwriteFeeTypes() {
   if (typeof cpFeeTypes == 'undefined') return;
   cpFeeTypes = [{
-      type: 'marketLabour',
-      name: '人工费'
-    },
-    {
-      type: 'marketMaterial',
-      name: '材料费'
-    },
-    {
-      type: 'marketMachine',
-      name: '施工机械使用费'
-    },
-    {
-      type: 'marketMachineLabour',
-      name: '施工机械人工费'
-    },
-    {
-      type: 'marketEquipment',
-      name: '设备购置费'
-    },
-    {
-      type: 'marketDirect',
-      name: '直接费'
-    },
+    type: 'marketLabour',
+    name: '人工费'
+  },
+  {
+    type: 'marketMaterial',
+    name: '材料费'
+  },
+  {
+    type: 'marketMachine',
+    name: '施工机械使用费'
+  },
+  {
+    type: 'marketMachineLabour',
+    name: '施工机械人工费'
+  },
+  {
+    type: 'marketEquipment',
+    name: '设备购置费'
+  },
+  {
+    type: 'marketDirect',
+    name: '直接费'
+  },
 
-    {
-      type: 'labour',
-      name: '定额人工费'
-    },
-    {
-      type: 'material',
-      name: '定额材料费'
-    },
-    {
-      type: 'machine',
-      name: '定额施工机械使用费'
-    },
-    {
-      type: 'equipment',
-      name: '定额设备费'
-    },
-    {
-      type: 'direct',
-      name: '定额直接费'
-    },
+  {
+    type: 'labour',
+    name: '定额人工费'
+  },
+  {
+    type: 'material',
+    name: '定额材料费'
+  },
+  {
+    type: 'machine',
+    name: '定额施工机械使用费'
+  },
+  {
+    type: 'equipment',
+    name: '定额设备费'
+  },
+  {
+    type: 'direct',
+    name: '定额直接费'
+  },
 
-    {
-      type: 'measure',
-      name: '措施费'
-    },
-    {
-      type: 'manage',
-      name: '企业管理费'
-    },
-    {
-      type: 'force',
-      name: '规费'
-    },
-    {
-      type: 'profit',
-      name: '利润'
-    },
-    {
-      type: 'tax',
-      name: '税金'
-    },
-    {
-      type: 'common',
-      name: '建安费'
-    },
-    {
-      type: 'rationCommon',
-      name: '定额建安费'
-    }
+  {
+    type: 'measure',
+    name: '措施费'
+  },
+  {
+    type: 'manage',
+    name: '企业管理费'
+  },
+  {
+    type: 'force',
+    name: '规费'
+  },
+  {
+    type: 'profit',
+    name: '利润'
+  },
+  {
+    type: 'tax',
+    name: '税金'
+  },
+  {
+    type: 'common',
+    name: '建安费'
+  },
+  {
+    type: 'rationCommon',
+    name: '定额建安费'
+  }
   ];
 })();
 
@@ -155,4 +145,327 @@ if (typeof feeRateObject !== 'undefined') {
     }
     return result;
   }
+}
+
+// 清单基数
+const progression = ['施工场地建设费', '建设单位(业主)管理费', '建设项目信息化费', '工程监理费', '设计文件审查费', '前期工作费'];
+const deficiency = {};
+if (typeof baseFigureMap !== 'undefined') {
+  const { fixedFlag } = commonConstants;
+  const budgetMap = {
+    // 显示:除清单固定类别是“建筑安装工程费”部分可显示
+    '建筑安装工程费': {
+      base: 'JZAZGCF',
+      fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
+      filter: [fixedFlag.CONSTRUCTION_INSTALL_FEE],
+      pick: false,
+    },
+    // 显示:除清单固定类别是“建筑安装工程费”部分可显示
+    '定额建筑安装工程费': {
+      base: 'DEJZAZGCF',
+      fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
+      filter: [fixedFlag.CONSTRUCTION_INSTALL_FEE],
+      pick: false
+    },
+    // 显示:仅清单固定类别是“工程建设其他费”部分可显示
+    '建筑安装工程费(不含设备费)': {
+      base: 'JZAZGCFBHSB',
+      fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
+      filter: [fixedFlag.MAINTENANCE_EXPENSES],
+      pick: true
+    },
+    // 显示:仅清单固定类别是“工程建设其他费”部分可显示
+    '定额建筑安装工程费(含定额设备购置费*40%)': {
+      base: 'DEJZAZGCFSBSS',
+      fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
+      filter: [fixedFlag.MAINTENANCE_EXPENSES],
+      pick: true
+    },
+    // 显示:仅清单固定类别是“工程建设其他费”、“专项费用”部分可显示
+    '定额建筑安装工程费(不含定额设备购置费、专项费用)': {
+      base: 'DEJZAZGCFBHSBZX',
+      fixedFlag: null,
+      filter: [fixedFlag.MAINTENANCE_EXPENSES, fixedFlag.SPECIAL_COST],
+      pick: true,
+    },
+    // 显示:仅清单固定类别是“施工场地建设费”的可显示
+    '施工场地建设费': {
+      isProgressive: true,
+      base: 'SGCDJSF',
+      fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
+      filter: [fixedFlag.CONSTRUCTION_PLANT_COST],
+      pick: true,
+    },
+    // 显示:仅清单固定类别是“工程建设其他费”部分可显示
+    '建设单位(业主)管理费': {
+      isProgressive: true,
+      base: 'JSDWYZGLF',
+      fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
+      filter: [fixedFlag.MAINTENANCE_EXPENSES],
+      pick: true,
+    },
+    // 显示:仅清单固定类别是“工程建设其他费”部分可显示
+    '建设项目信息化费': {
+      isProgressive: true,
+      base: 'JSXMXXHF',
+      fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
+      filter: [fixedFlag.MAINTENANCE_EXPENSES],
+      pick: true,
+    },
+    // 显示:仅清单固定类别是“工程建设其他费”部分可显示
+    '工程监理费': {
+      isProgressive: true,
+      base: 'GCJLF',
+      fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
+      filter: [fixedFlag.MAINTENANCE_EXPENSES],
+      pick: true,
+    },
+    // 显示:仅清单固定类别是“工程建设其他费”部分可显示
+    '设计文件审查费': {
+      isProgressive: true,
+      base: 'SJWJSCF',
+      fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
+      filter: [fixedFlag.MAINTENANCE_EXPENSES],
+      pick: true,
+    },
+    // 显示:仅清单固定类别是“工程建设其他费”部分可显示
+    '前期工作费': {
+      isProgressive: true,
+      base: 'QQGZF',
+      fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
+      filter: [fixedFlag.MAINTENANCE_EXPENSES],
+      pick: true,
+    },
+    // 显示:仅“价差预备费”可显示
+    '价差预备费': {
+      base: 'JCYBF',
+      fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
+      filter: [fixedFlag.SPREAD_BUDGET_FEE],
+      pick: true,
+    },
+  };
+  const boqMap = {
+    // 仅允许用于固定类别是“第100章至700章清单”以外的清单
+    '各章清单合计': {
+      base: 'GZQDHJ',
+      fixedFlag: fixedFlag.ONE_SEVEN_BILLS,
+      filter: [fixedFlag.ONE_SEVEN_BILLS],
+      pick: false
+    },
+    // 仅允许用于固定类别是“第100章至700章清单”以外的清单
+    '专项暂定合计': {
+      base: 'ZXZDHJ',
+      fixedFlag: null,
+      filter: [fixedFlag.ONE_SEVEN_BILLS],
+      pick: false
+    },
+    /*
+    *  清单固定行[第100章至700章清单]下的[第100章清单]需要允许清单可使用基数{100章以外合计}
+    *  因此{100章以外合计}不设置关联的清单固定行
+    * */
+    // 仅允许用于固定类别为“100章清单”引用
+    '100章以外清单合计': {
+      base: 'YBZYHQDHJ',
+      fixedFlag: null,
+      filter: [fixedFlag.ONE_HUNDRED_BILLS],
+      pick: true
+    }
+  };
+  baseFigureMap.budget = budgetMap;
+  baseFigureMap.boq = boqMap;
+}
+
+if (typeof baseFigureTemplate !== 'undefined') {
+  const { fixedFlag } = commonConstants;
+  baseFigureTemplate.budget = {
+    // 建设安装工程费 算法:取“建筑安装工程费”的金额
+    JZAZGCF(tender) {
+      return cbTools.getBaseFee(fixedFlag.CONSTRUCTION_INSTALL_FEE, tender, 'common');
+    },
+    // 定额建设安装工程费 算法:取“定额建筑安装工程费”的金额
+    DEJZAZGCF(tender) {
+      return cbTools.getBaseFee(fixedFlag.CONSTRUCTION_INSTALL_FEE, tender, 'rationCommon');
+    },
+    // 建设安装工程费(不含设备费) 算法:取固定类别是“建筑安装工程费”的金额。扣除设备的金额。(全国造价云版中,没有固定的设备购置行,需要扣除所有类别是“设备”的金额,仅指设备行,不包括定额工料机的设备)
+    JZAZGCFBHSB(tender) {
+      let baseFee = this['JZAZGCF'](tender);
+      const fixedNode = projectObj.project.mainTree.roots.find(node => node.getFlag() === fixedFlag.CONSTRUCTION_INSTALL_FEE);
+      const allSubNodes = [];
+      projectObj.project.mainTree.getAllSubNode(fixedNode, allSubNodes);
+      const equipmentNodes = allSubNodes.filter(node => node.data.type === rationType.gljRation && node.data.subType === gljType.EQUIPMENT);
+      const feeField = 'common';
+      const subFeeField = tender ? 'tenderTotalFee' : 'totalFee';
+      let totalEquipmentFee = 0;
+      for (const node of equipmentNodes) {
+        const data = node.data;
+        if (cbTools.isUnDef(data.feesIndex) || _.isEmpty(data.feesIndex) ||
+          cbTools.isUnDef(data.feesIndex[feeField]) || cbTools.isUnDef(data.feesIndex[feeField][subFeeField])) {
+          continue;
+        }
+        totalEquipmentFee = (totalEquipmentFee + data.feesIndex[feeField][subFeeField]).toDecimal(decimalObj.process);
+      }
+      baseFee = (baseFee - totalEquipmentFee).toDecimal(decimalObj.process);
+      return baseFee.toDecimal(decimalObj.bills.totalPrice);
+    },
+    // 定额建筑安装工程费(含定额设备购置费*40%) 取固定类别是“建筑安装工程费”的金额,扣除定额设备购置费*60%的金额。
+    DEJZAZGCFSBSS(tender) {
+      let baseFee = this['JZAZGCF'](tender);
+      const fixedNode = projectObj.project.mainTree.roots.find(node => node.getFlag() === fixedFlag.CONSTRUCTION_INSTALL_FEE);
+      const allSubNodes = [];
+      projectObj.project.mainTree.getAllSubNode(fixedNode, allSubNodes);
+      const equipmentNodes = allSubNodes.filter(node => node.data.type === rationType.gljRation && node.data.subType === gljType.EQUIPMENT);
+      const feeField = 'common';
+      const subFeeField = tender ? 'tenderTotalFee' : 'totalFee';
+      let totalEquipmentFee = 0;
+      for (const node of equipmentNodes) {
+        const data = node.data;
+        if (cbTools.isUnDef(data.feesIndex) || _.isEmpty(data.feesIndex) ||
+          cbTools.isUnDef(data.feesIndex[feeField]) || cbTools.isUnDef(data.feesIndex[feeField][subFeeField])) {
+          continue;
+        }
+        totalEquipmentFee = (totalEquipmentFee + data.feesIndex[feeField][subFeeField]).toDecimal(decimalObj.process);
+      }
+      baseFee = (baseFee - totalEquipmentFee * 0.6).toDecimal(decimalObj.process);
+      return baseFee.toDecimal(decimalObj.bills.totalPrice);
+    },
+    // 定额建筑安装工程费(不含定额设备购置费、专项费用) 算法:取固定类别是“建筑安装工程费”的金额,扣除定额设备购置费和专项费用的金额
+    DEJZAZGCFBHSBZX(tender) {
+      let baseFee = this['JZAZGCF'](tender);
+      const fixedNode = projectObj.project.mainTree.roots.find(node => node.getFlag() === fixedFlag.CONSTRUCTION_INSTALL_FEE);
+      const allSubNodes = [];
+      projectObj.project.mainTree.getAllSubNode(fixedNode, allSubNodes);
+      const equipmentNodes = allSubNodes.filter(node => node.data.type === rationType.gljRation && node.data.subType === gljType.EQUIPMENT);
+      const feeField = 'common';
+      const subFeeField = tender ? 'tenderTotalFee' : 'totalFee';
+      let diffFee = 0;
+      for (const node of equipmentNodes) {
+        const data = node.data;
+        if (cbTools.isUnDef(data.feesIndex) || _.isEmpty(data.feesIndex) ||
+          cbTools.isUnDef(data.feesIndex[feeField]) || cbTools.isUnDef(data.feesIndex[feeField][subFeeField])) {
+          continue;
+        }
+        diffFee = (diffFee + data.feesIndex[feeField][subFeeField]).toDecimal(decimalObj.process);
+      }
+      const specialFee = cbTools.getBaseFee(fixedFlag.SPECIAL_COST, tender, 'common');
+      diffFee = (diffFee + specialFee).toDecimal(decimalObj.process);
+      baseFee = (baseFee - diffFee).toDecimal(decimalObj.process);
+      return baseFee.toDecimal(decimalObj.bills.totalPrice);
+    },
+    // 施工场地建设费 算法:按“定额建筑安装工程费”扣除专项费为基数,以累进办法计算
+    SGCDJSF(tender) {
+      let baseFee = this['DEJZAZGCF'](tender);
+      const specialFee = cbTools.getBaseFee(fixedFlag.SPECIAL_COST, tender, 'common');
+      baseFee = (baseFee - specialFee).toDecimal(decimalObj.process);
+      if (!tender) {
+        calcBase.baseProgressiveFee = baseFee;
+      }
+      return calculateUtil.getProgressiveFee(baseFee, '施工场地建设费', projectObj.project.property.progressiveInterval, decimalObj.bills.totalPrice, deficiency);
+    },
+    // 建设单位(业主)管理费 算法:按“定额建筑安装工程费”总和为基数,以累进办法计算
+    JSDWYZGLF(tender) {
+      const baseFee = this['DEJZAZGCF'](tender);
+      if (!tender) {
+        calcBase.baseProgressiveFee = baseFee;
+      }
+      return calculateUtil.getProgressiveFee(baseFee, '建设单位(业主)管理费', projectObj.project.property.progressiveInterval, decimalObj.bills.totalPrice, deficiency);
+    },
+    // 建设项目信息化费 算法:按“定额建筑安装工程费”总和为基数,以累进办法计算
+    JSXMXXHF(tender) {
+      const baseFee = this['DEJZAZGCF'](tender);
+      if (!tender) {
+        calcBase.baseProgressiveFee = baseFee;
+      }
+      return calculateUtil.getProgressiveFee(baseFee, '建设项目信息化费', projectObj.project.property.progressiveInterval, decimalObj.bills.totalPrice, deficiency);
+    },
+    // 工程监理费 算法:按“定额建筑安装工程费”总和为基数,以累进办法计算
+    GCJLF(tender) {
+      const baseFee = this['DEJZAZGCF'](tender);
+      if (!tender) {
+        calcBase.baseProgressiveFee = baseFee;
+      }
+      return calculateUtil.getProgressiveFee(baseFee, '工程监理费', projectObj.project.property.progressiveInterval, decimalObj.bills.totalPrice, deficiency);
+    },
+    // 设计文件审查费 算法:按“定额建筑安装工程费”总和为基数,以累进办法计算
+    SJWJSCF(tender) {
+      const baseFee = this['DEJZAZGCF'](tender);
+      if (!tender) {
+        calcBase.baseProgressiveFee = baseFee;
+      }
+      return calculateUtil.getProgressiveFee(baseFee, '设计文件审查费', projectObj.project.property.progressiveInterval, decimalObj.bills.totalPrice, deficiency);
+    },
+    // 前期工作费 算法:按“定额建筑安装工程费”总和为基数,以累进办法计算
+    QQGZF(tender) {
+      const baseFee = this['DEJZAZGCF'](tender);
+      if (!tender) {
+        calcBase.baseProgressiveFee = baseFee;
+      }
+      return calculateUtil.getProgressiveFee(baseFee, '前期工作费', projectObj.project.property.progressiveInterval, decimalObj.bills.totalPrice, deficiency);
+    },
+    /*  价差预备费 算法:价差预备费以“建筑安装工程费”总额为基数,按设计文件编制年始至工程竣工年终的年数和年工程造价增涨费率计算
+        价差预备费 P * [(1+i)^(n-1) -1]
+        P——建筑安装工程费总额(元);
+        i——年工程造价增涨率(%);
+        n——设计文件编制年至养护项目开工年+养护项目建设期限(年)。
+    */
+    JCYBF(tender) {
+      // 建筑安装工程费作为基数
+      const installFee = this['JZAZGCF'](tender);
+      // 年造价增涨
+      const costGrowthRate = calcBase.project.property.costGrowthRate
+        ? calcBase.project.property.costGrowthRate
+        : 0;
+      // 增涨计费年限
+      const growthPeriod = projectObj.project.property.growthPeriod
+        ? calcBase.project.property.growthPeriod
+        : 0;
+      // = P * [(1+i)^(n-1) -1]
+      return (installFee * (Math.pow(1 + costGrowthRate, growthPeriod - 1) - 1)).toDecimal(decimalObj.bills.totalPrice);
+    }
+
+  };
+
+  baseFigureTemplate.boq = {
+    //{各章清单合计}
+    // 取清单固定类别是“第100章至700章清单”的金额
+    'GZQDHJ': function (tender) {
+      return cbTools.getBaseFee(calcBase.fixedFlag.ONE_SEVEN_BILLS, tender, 'common');
+    },
+    //{专项暂定合计}
+    // 第100章至700章清单行的暂估合价
+    'ZXZDHJ': function (tender) {
+      return cbTools.getBaseFee(calcBase.fixedFlag.ONE_SEVEN_BILLS, tender, 'estimate');
+    },
+    //{100章以外清单合计}
+    // 取清单固定清单[第100章至700章清单]的金额,但扣除清单100章下的金额。
+    // 如果是固定清单[第100章至700章清单]下100章以外清单引用此基数,要排除自身(目前只允许100章的清单使用,所以暂时不需要此判断)
+    'YBZYHQDHJ': function (tender) {
+      let oneToSeven = cbTools.findNodeByFlag(fixedFlag.ONE_SEVEN_BILLS);
+      if (!oneToSeven) {
+        return 0;
+      }
+      //100-700章固定节点的所有子节点
+      let allChildren = [];
+      function getChildren(nodes) {
+        allChildren = allChildren.concat(nodes);
+        for (let node of nodes) {
+          if (node.children.length > 0) {
+            getChildren(node.children);
+          }
+        }
+      }
+      getChildren(oneToSeven.children);
+      //扣除的节点:100章的节点[100-200)
+      let deductNodes = allChildren.filter(cbTools.withingOneHundred);
+      //计算金额
+      let fullFeeField = tender ? 'common.tenderTotalFee' : 'common.totalFee';
+      return projectObj.project.calcProgram.getTotalFee([oneToSeven], deductNodes, fullFeeField).toDecimal(decimalObj.bills.totalPrice);
+    }
+  };
+}
+
+if (typeof module !== 'undefined' && !module.nodeType) {
+  module.exports = {
+    progression,
+    deficiency
+  };
 }

+ 197 - 139
web/over_write/js/shandong_2016.js

@@ -1,141 +1,120 @@
 let isSD2016 = true;
 
 function overwriteRationCalcBases() {
-  if (typeof rationCalcBases == 'undefined') return;
+  if (typeof rationCalcBases == "undefined") return;
   for (let key in rationCalcBases) delete rationCalcBases[key];
 
-  rationCalcBases['人工费'] = function (node, isTender) {
+  rationCalcBases["人工费"] = function (node, isTender) {
     return calcTools.rationBaseFee(node, [gljType.LABOUR], priceTypes.ptMarketPrice, isTender);
   };
-  rationCalcBases['材料费'] = function (node, isTender) {
+  rationCalcBases["材料费"] = function (node, isTender) {
     return calcTools.rationBaseFee(node, baseMaterialTypes, priceTypes.ptMarketPrice, isTender);
   };
-  rationCalcBases['施工机械使用费'] = function (node, isTender) {
+  rationCalcBases["施工机械使用费"] = function (node, isTender) {
     return calcTools.rationBaseFee(node, baseMachineTypes, priceTypes.ptMarketPrice, isTender);
   };
-  rationCalcBases['商品砼费'] = function (node, isTender) {
+  rationCalcBases["商品砼费"] = function (node, isTender) {
     return calcTools.rationBaseFee(node, [gljType.COMMERCIAL_CONCRETE, gljType.COMMERCIAL_MORTAR], priceTypes.ptMarketPrice, isTender);
   };
-  rationCalcBases['外购砼构件费'] = function (node, isTender) {
+  rationCalcBases["外购砼构件费"] = function (node, isTender) {
     return calcTools.rationBaseFee(node, [gljType.PURCHASE_COMPONENT], priceTypes.ptMarketPrice, isTender);
   };
-};
+}
 
 (function overwriteFeeTypes() {
-  if (typeof cpFeeTypes == 'undefined') return;
-  cpFeeTypes = [{
-      type: 'marketDirect',
-      name: '直接费'
+  if (typeof cpFeeTypes == "undefined") return;
+  cpFeeTypes = [
+    {
+      type: "marketDirect",
+      name: "直接费",
     },
     {
-      type: 'marketDirectWork',
-      name: '直接工程费'
-    }, {
-      type: 'marketLabour',
-      name: '人工费'
+      type: "marketDirectWork",
+      name: "直接工程费",
     },
     {
-      type: 'marketMaterial',
-      name: '材料费'
+      type: "marketLabour",
+      name: "人工费",
     },
     {
-      type: 'marketMachine',
-      name: '施工机械使用费'
+      type: "marketMaterial",
+      name: "材料费",
     },
     {
-      type: 'otherFee',
-      name: '其他工程费'
+      type: "marketMachine",
+      name: "施工机械使用费",
     },
     {
-      type: 'otherFee1',
-      name: '其他工程费I'
+      type: "otherFee",
+      name: "其他工程费",
     },
     {
-      type: 'otherFee2',
-      name: '其他工程费II'
+      type: "otherFee1",
+      name: "其他工程费I",
     },
     {
-      type: 'indirectFee',
-      name: '间接费'
+      type: "otherFee2",
+      name: "其他工程费II",
     },
     {
-      type: 'manage',
-      name: '企业管理费'
+      type: "indirectFee",
+      name: "间接费",
     },
     {
-      type: 'force',
-      name: '规费'
+      type: "manage",
+      name: "企业管理费",
     },
     {
-      type: 'profit',
-      name: '利润'
+      type: "force",
+      name: "规费",
     },
     {
-      type: 'tax',
-      name: '税金'
+      type: "profit",
+      name: "利润",
     },
     {
-      type: 'common',
-      name: '建安费'
-    }
-  ]
+      type: "tax",
+      name: "税金",
+    },
+    {
+      type: "common",
+      name: "建安费",
+    },
+  ];
 })();
 
 // 清单基数
-const progression = ['养护工程管理费', '养护工程设计费'];
+const progression = ["养护工程管理费", "养护工程设计费"];
 const deficiency = {};
-if (typeof baseFigureMap !== 'undefined') {
-  const {
-    fixedFlag
-  } = commonConstants;
+if (typeof baseFigureMap !== "undefined") {
+  const { fixedFlag } = commonConstants;
   const budgetMap = {
     // 显示:除清单固定类别是“建筑安装工程费”的以外部分可显示。
-    '建筑安装工程费': {
-      base: 'JZAZGCF',
+    建筑安装工程费: {
+      base: "JZAZGCF",
       fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
       filter: [fixedFlag.CONSTRUCTION_INSTALL_FEE],
       pick: false,
     },
-    // 显示:仅清单固定类别是“安全生产费”的可显示。
-    '建筑安装工程费(不含设备费)': {
-      base: 'JZAZGCFBHSB',
-      fixedFlag: null,
-      filter: [fixedFlag.SAFE_COST],
-      pick: true
-    },
-    // 显示:除清单固定类别是“建筑安装工程费”、“土地使用及拆迁补偿费”的以外部分可显示。
-    '土地使用及拆迁补偿费': {
-      base: 'TDSYJCQBCF',
-      fixedFlag: fixedFlag.LAND_USED_DEMOLITION,
-      filter: [fixedFlag.CONSTRUCTION_INSTALL_FEE, fixedFlag.LAND_USED_DEMOLITION],
-      pick: false,
-    },
-    // 显示:除清单固定类别是“建筑安装工程费”、“土地使用及拆迁补偿费”、“工程建设其他费用”的以外部分可显示。
-    '工程建设其他费用': {
-      base: 'GCJSQTFY',
-      fixedFlag: fixedFlag.MAINTENANCE_EXPENSES,
-      filter: [fixedFlag.CONSTRUCTION_INSTALL_FEE, fixedFlag.LAND_USED_DEMOLITION, fixedFlag.MAINTENANCE_EXPENSES],
-      pick: false,
-    },
     // 显示:仅清单固定类别是“养护工程其他费用”部分可显示。
-    '养护工程管理费': {
+    养护工程管理费: {
       isProgressive: true,
-      base: 'YHGCGLF',
+      base: "YHGCGLF",
       fixedFlag: null,
       filter: [fixedFlag.MAINTENANCE_EXPENSES],
       pick: true,
     },
     // 显示:仅清单固定类别是“养护工程其他费用”部分可显示。
-    '养护工程设计费': {
+    养护工程设计费: {
       isProgressive: true,
-      base: 'YHGCSJF',
+      base: "YHGCSJF",
       fixedFlag: null,
       filter: [fixedFlag.MAINTENANCE_EXPENSES],
       pick: true,
     },
     // 显示:仅“价差预备费”可显示
-    '价差预备费': {
-      base: 'JCYBF',
+    价差预备费: {
+      base: "JCYBF",
       fixedFlag: null,
       filter: [fixedFlag.SPREAD_BUDGET_FEE],
       pick: true,
@@ -143,68 +122,58 @@ if (typeof baseFigureMap !== 'undefined') {
   };
   const boqMap = {
     //仅允许用于固定类别是“第100章至700章清单”以外的清单
-    '各章清单合计': {
-      base: 'GZQDHJ',
+    各章清单合计: {
+      base: "GZQDHJ",
       fixedFlag: fixedFlag.ONE_SEVEN_BILLS,
       filter: [fixedFlag.ONE_SEVEN_BILLS],
-      pick: false
+      pick: false,
     },
     //仅允许用于固定类别是“第100章至700章清单”以外的清单
-    '专项暂定合计': {
-      base: 'ZXZDHJ',
+    专项暂定合计: {
+      base: "ZXZDHJ",
       fixedFlag: null,
       filter: [fixedFlag.ONE_SEVEN_BILLS],
-      pick: false
+      pick: false,
     },
     /*
      *  清单固定行[第100章至700章清单]下的[第100章清单]需要允许清单可使用基数{100章以外合计}
      *  因此{100章以外合计}不设置关联的清单固定行
      * */
     //仅允许用于固定类别为“100章清单”引用
-    '100章以外清单合计': {
-      base: 'YBZYHQDHJ',
+    "100章以外清单合计": {
+      base: "YBZYHQDHJ",
       fixedFlag: null,
       filter: [fixedFlag.ONE_HUNDRED_BILLS],
-      pick: true
-    }
+      pick: true,
+    },
   };
   baseFigureMap.budget = budgetMap;
   baseFigureMap.boq = boqMap;
 }
 
-if (typeof baseFigureTemplate !== 'undefined') {
-  const {
-    fixedFlag
-  } = commonConstants;
+if (typeof baseFigureTemplate !== "undefined") {
+  const { fixedFlag } = commonConstants;
   baseFigureTemplate.budget = {
     // 建筑安装工程费 算法:取清单固定类别是“建筑安装工程费”的金额。
     JZAZGCF(tender) {
-      return cbTools.getBaseFee(fixedFlag.CONSTRUCTION_INSTALL_FEE, tender, 'common');
-    },
-    // 土地使用及拆迁补偿费 算法:取清单固定类别是“土地使用及拆迁补偿费”的金额。
-    TDSYJCQBCF(tender) {
-      return cbTools.getBaseFee(fixedFlag.LAND_USED_DEMOLITION, tender, 'common');
-    },
-    // 工程建设其他费用 算法:取清单固定类别是“养护工程其他费用”的金额。
-    GCJSQTFY(tender) {
-      return cbTools.getBaseFee(fixedFlag.MAINTENANCE_EXPENSES, tender, 'common');
+      return cbTools.getBaseFee(fixedFlag.CONSTRUCTION_INSTALL_FEE, tender, "common");
     },
     // 养护工程管理费 算法:以{建筑安装工程费}为基数,采用累进办法计算
     YHGCGLF(tender) {
-      const baseFee = this['JZAZGCF'](tender);
+      const baseFee = this["JZAZGCF"](tender);
       if (!tender) {
         calcBase.baseProgressiveFee = baseFee;
       }
-      return calculateUtil.getProgressiveFee(baseFee, '养护工程管理费', projectObj.project.property.progressiveInterval, decimalObj.bills.totalPrice, deficiency);
+      return calculateUtil.getProgressiveFee(baseFee, "养护工程管理费", projectObj.project.property.progressiveInterval, decimalObj.bills.totalPrice, deficiency);
     },
 
     // 养护工程设计费 算法:以{建筑安装工程费}为基数,采用累进办法计算。
     YHGCSJF(tender) {
-      const baseFee = this['JZAZGCF'](tender);
+      const baseFee = this["JZAZGCF"](tender);
       if (!tender) {
         calcBase.baseProgressiveFee = baseFee;
       }
-      return calculateUtil.getProgressiveFee(baseFee, '养护工程设计费', projectObj.project.property.progressiveInterval, decimalObj.bills.totalPrice, deficiency);
+      return calculateUtil.getProgressiveFee(baseFee, "养护工程设计费", projectObj.project.property.progressiveInterval, decimalObj.bills.totalPrice, deficiency);
     },
     /*  价差预备费 算法:以建筑安装工程费为基数,按设计文件编制年始至养护项目工程竣工年终的年数和年工程造价增涨率计算。
         价差预备费 P * [(1+i)^(n-1) -1]
@@ -214,50 +183,31 @@ if (typeof baseFigureTemplate !== 'undefined') {
     */
     JCYBF(tender) {
       //建筑安装工程费作为基数
-      const installFee = this['JZAZGCF'](tender);
+      const installFee = this["JZAZGCF"](tender);
       //年造价增涨
-      const costGrowthRate = calcBase.project.property.costGrowthRate ?
-        calcBase.project.property.costGrowthRate :
-        0;
+      const costGrowthRate = calcBase.project.property.costGrowthRate ? calcBase.project.property.costGrowthRate : 0;
       //增涨计费年限
-      const growthPeriod = projectObj.project.property.growthPeriod ?
-        calcBase.project.property.growthPeriod :
-        0;
+      const growthPeriod = projectObj.project.property.growthPeriod ? calcBase.project.property.growthPeriod : 0;
       //= P * [(1+i)^(n-1) -1]
       return (installFee * (Math.pow(1 + costGrowthRate, growthPeriod - 1) - 1)).toDecimal(decimalObj.bills.totalPrice);
-    }
-
+    },
   };
 
   baseFigureTemplate.boq = {
     //{各章清单合计}
     // 取清单固定类别是“第100章至700章清单”的金额
-    'GZQDHJ': function (tender) {
-      return cbTools.getBaseFee(calcBase.fixedFlag.ONE_SEVEN_BILLS, tender, 'common');
+    GZQDHJ: function (tender) {
+      return cbTools.getBaseFee(calcBase.fixedFlag.ONE_SEVEN_BILLS, tender, "common");
     },
     //{专项暂定合计}
-    // 汇总专项暂定列有值的清单的金额
-    'ZXZDHJ': function (tender) {
-      let rst = 0,
-        feeField = 'common',
-        subFeeField = tender ? 'tenderTotalFee' : 'totalFee';
-      let billsData = calcBase.project.Bills.datas,
-        filterData = billsData.filter(function (data) {
-          return data.specialProvisional;
-        });
-      for (let data of filterData) {
-        if (cbTools.isUnDef(data.feesIndex) || _.isEmpty(data.feesIndex) ||
-          cbTools.isUnDef(data.feesIndex[feeField]) || cbTools.isUnDef(data.feesIndex[feeField][subFeeField])) {
-          continue;
-        }
-        rst += data.feesIndex[feeField][subFeeField];
-      }
-      return rst.toDecimal(decimalObj.bills.totalPrice);
+    // 第100章至700章清单行的暂估合价
+    ZXZDHJ: function (tender) {
+      return cbTools.getBaseFee(calcBase.fixedFlag.ONE_SEVEN_BILLS, tender, 'estimate');
     },
     //{100章以外清单合计}
     // 取清单固定清单[第100章至700章清单]的金额,但扣除清单100章下的金额。
     // 如果是固定清单[第100章至700章清单]下100章以外清单引用此基数,要排除自身(目前只允许100章的清单使用,所以暂时不需要此判断)
-    'YBZYHQDHJ': function (tender) {
+    YBZYHQDHJ: function (tender) {
       let oneToSeven = cbTools.findNodeByFlag(fixedFlag.ONE_SEVEN_BILLS);
       if (!oneToSeven) {
         return 0;
@@ -277,30 +227,138 @@ if (typeof baseFigureTemplate !== 'undefined') {
       //扣除的节点:100章的节点[100-200)
       let deductNodes = allChildren.filter(cbTools.withingOneHundred);
       //计算金额
-      let fullFeeField = tender ? 'common.tenderTotalFee' : 'common.totalFee';
+      let fullFeeField = tender ? "common.tenderTotalFee" : "common.totalFee";
       return projectObj.project.calcProgram.getTotalFee([oneToSeven], deductNodes, fullFeeField).toDecimal(decimalObj.bills.totalPrice);
-    }
+    },
+  };
+}
+
+//工料机类型排序:人工、机上人工、混凝土、砂浆、配合比、普通材料、商品混凝土、商品砂浆、外购砼构件、绿化苗木、机械台班、机械组成物、设备。
+
+function o_sortRationGLJ(list, std, tm) {
+  let lo_sh = typeof _ !== "undefined" ? _ : require("lodash");
+  const field = std ? "gljType" : "type";
+  let TypeMap = {
+    1: 1,
+    303: 2,
+    202: 3,
+    203: 4,
+    204: 5,
+    201: 6,
+    205: 7,
+    206: 8,
+    208: 9,
+    209: 10,
+    301: 11,
+    302: 12,
+    5: 13,
+  };
+  if (tm) TypeMap = tm;
+  list = lo_sh.sortByAll(list, [
+    function (item) {
+      return TypeMap[item[field]];
+    },
+    function (item) {
+      let arr = item.code.split("-");
+      return arr[0];
+    },
+    "code",
+  ]);
+  return list;
+}
+
+if (typeof gljUtil !== "undefined") {
+  gljUtil.sortRationGLJ = o_sortRationGLJ;
+
+  gljUtil.sortProjectGLJ = function (list) {
+    //人工、机上人工、普通材料、商品混凝土、商品砂浆、外购砼构件、绿化苗木、机械台班、机械组成物、设备、混凝土、砂浆、配合比
+    const TypeMap = {
+      1: 1,
+      303: 2,
+      201: 3,
+      205: 4,
+      206: 5,
+      208: 6,
+      209: 7,
+      301: 8,
+      302: 9,
+      5: 10,
+      202: 11,
+      203: 12,
+      204: 13,
+    };
+    return o_sortRationGLJ(list, false, TypeMap);
   };
 }
 
 //山东工地转移费率值修改特殊处理
-if (typeof feeRateObject !== 'undefined') {
+if (typeof feeRateObject !== "undefined") {
   feeRateObject.feeRateSpecialHandle = function (subRate, value) {
     let result = {};
-    if (subRate.name == "工地转移(km)" && value && value < 50) { //工地转移50km以内按50km算
+    if (subRate.name == "工地转移(km)" && value && value < 50) {
+      //工地转移50km以内按50km算
       result.valueKey = "50";
       result.value = scMathUtil.roundForObj(value, getDecimal("feeRate")); //设置显示的节点值
     }
     return result;
-  }
+  };
 }
 
-if (typeof module !== 'undefined' && !module.nodeType) {
+if (typeof gljOprObj !== 'undefined') {
+    // 添加、替换工料机界面工料机排序
+    gljOprObj.sortSelectViewGLJ = function (data) {
+        // 工料机编码:按“-”前的数值排序
+        const reg = /[^-]+/;
+        data.sort((a, b) => {
+            const orgCodeA = a.code;
+            const orgCodeB = b.code;
+            const regCodeA = orgCodeA.match(reg);
+            const regCodeB = orgCodeB.match(reg);
+            const compareCodeA = regCodeA
+                ? +regCodeA[0]
+                    ? +regCodeA[0]
+                    : regCodeA[0]
+                : orgCodeA;
+            const compareCodeB = regCodeB
+                ? +regCodeB[0]
+                    ? +regCodeB[0]
+                    : regCodeB
+                : orgCodeB;
+            return isNaN(compareCodeA) && isNaN(compareCodeB)
+                ? compareCodeA.localeCompare(compareCodeB)
+                : compareCodeA - compareCodeB;
+        });
+        // 工料机类型排序:人工、机上人工、混凝土、砂浆、配合比、普通材料、商品混凝土、商品砂浆、外购砼构件、绿化苗木、机械台班、机械组成物、设备。
+        const TypeMap = {
+            1: 1,
+            303: 2,
+            202: 3,
+            203: 4,
+            204: 5,
+            201: 6,
+            205: 7,
+            206: 8,
+            208: 9,
+            209: 10,
+            301: 11,
+            302: 12,
+            5: 13,
+        };
+        data.sort((a, b) => {
+            const typeA = TypeMap[a.gljType];
+            const typeB = TypeMap[b.gljType];
+            return typeA - typeB;
+        });
+    }
+}
+
+if (typeof module !== "undefined" && !module.nodeType) {
   module.exports = {
     progression,
     deficiency,
+    sortRationGLJ: o_sortRationGLJ,
     getDefalutAssistProductionFeeRate: function () {
-      return 5
-    }
+      return 5;
+    },
   };
-}
+}

+ 2 - 16
web/over_write/js/zhejiang_2005.js

@@ -173,23 +173,9 @@ if (typeof baseFigureTemplate !== 'undefined') {
             return cbTools.getBaseFee(calcBase.fixedFlag.ONE_SEVEN_BILLS, tender, 'common');
         },
         //{专项暂定合计}
-        // 汇总专项暂定列有值的清单的金额
+        // 第100章至700章清单行的暂估合价
         'ZXZDHJ': function (tender) {
-            let rst = 0,
-                feeField = 'common',
-                subFeeField = tender ? 'tenderTotalFee' : 'totalFee';
-            let billsData = calcBase.project.Bills.datas,
-                filterData = billsData.filter(function (data) {
-                    return data.specialProvisional;
-                });
-            for (let data of filterData) {
-                if (cbTools.isUnDef(data.feesIndex) || _.isEmpty(data.feesIndex) ||
-                    cbTools.isUnDef(data.feesIndex[feeField]) || cbTools.isUnDef(data.feesIndex[feeField][subFeeField])) {
-                    continue;
-                }
-                rst += data.feesIndex[feeField][subFeeField];
-            }
-            return rst.toDecimal(decimalObj.bills.totalPrice);
+            return cbTools.getBaseFee(calcBase.fixedFlag.ONE_SEVEN_BILLS, tender, 'estimate');
         },
         //{100章以外清单合计}
         // 取清单固定清单[第100章至700章清单]的金额,但扣除清单100章下的金额。