Browse Source

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

zhangweicheng 1 year ago
parent
commit
10e4ea28f6

+ 1 - 1
Dockerfile

@@ -6,7 +6,7 @@ WORKDIR /ConstructionOperation
 COPY package.json /ConstructionOperation
 
 RUN mkdir tmp \
-    && cnpm install
+    && cnpm install --registry=https://registry.npmmirror.com/
 
 FROM base-alpine:latest
 

+ 3 - 1
modules/all_models/stdBills_bills.js

@@ -19,7 +19,7 @@ const stdBills_bills = new Schema({
     name: String,
     unit: String,
     ruleText: String,
-    engineerContent:String,//工程内容
+    engineerContent: String,//工程内容
     engineering: Number, //工程专业,填计算程序工程专业ID
     fixedFlag: Number,  //固定ID
     Expression: String,
@@ -32,6 +32,8 @@ const stdBills_bills = new Schema({
     sectionInfo: Schema.Types.Mixed,
     deleted: Boolean,
     kind: Number, // 前台里(重构、微前端)BRType: 1: 大项费用、 8:XMJ 4:清单
+    erratumRecord: String, // 勘误记录
+    unitPrice: Number, // 单价
 },
     { versionKey: false }
 );

+ 51 - 102
modules/price_info_lib/facade/index.js

@@ -16,7 +16,7 @@ const { getWordArray, alias } = require('../../../public/cut_word/segmentit');
 
 
 async function getLibs(query) {
-    return await priceInfoLibModel.find(query).lean();
+    return await priceInfoLibModel.find(query).sort({ period: 1 }).lean();
 }
 
 async function createLib(name, period, compilationID) {
@@ -323,107 +323,6 @@ async function importKeyData(libID, mainData, subData) {
     }
 }
 
-/* async function importExcelData(libID, sheetData) {
-    const libs = await getLibs({ ID: libID });
-    const compilationID = libs[0].compilationID;
-    // 建立区映射表:名称-ID映射、ID-名称映射
-    const areaList = await getAreas(compilationID);
-    const areaMap = {};
-    areaList.forEach(({ ID, name }) => {
-        areaMap[name] = ID;
-        areaMap[ID] = name;
-    });
-    // 建立分类映射表:地区名称@分类名称:ID映射
-    const classMap = {};
-    const classList = await getClassData(libID);
-    classList.forEach(({ ID, areaID, name }) => {
-        const areaName = areaMap[areaID] || '';
-        classMap[`${areaName}@${name}`] = ID;
-    });
-    // 第一行获取行映射
-    const colMap = {};
-    for (let col = 0; col < sheetData[0].length; col++) {
-        const cellText = sheetData[0][col];
-        switch (cellText) {
-            case '地区':
-                colMap.area = col;
-                break;
-            case '分类':
-                colMap.class = col;
-                break;
-            case '编码':
-                colMap.code = col;
-                break;
-            case '名称':
-                colMap.name = col;
-                break;
-            case '规格型号':
-                colMap.specs = col;
-                break;
-            case '单位':
-                colMap.unit = col;
-                break;
-            case '不含税价':
-                colMap.noTaxPrice = col;
-                break;
-            case '含税价':
-                colMap.taxPrice = col;
-                break;
-        }
-    }
-    // 提取数据
-    const data = [];
-    let curAreaName;
-    let curClassName;
-    for (let row = 1; row < sheetData.length; row++) {
-        const areaName = sheetData[row][colMap.area] || '';
-        const className = sheetData[row][colMap.class] || '';
-        const code = sheetData[row][colMap.code] || '';
-        const name = sheetData[row][colMap.name] || '';
-        const specs = sheetData[row][colMap.specs] || '';
-        const unit = sheetData[row][colMap.unit] || '';
-        const noTaxPrice = sheetData[row][colMap.noTaxPrice] || '';
-        const taxPrice = sheetData[row][colMap.taxPrice] || '';
-        if (!code && !name && !specs && !noTaxPrice && !taxPrice) { // 认为是空数据
-            continue;
-        }
-        if (areaName && areaName !== curAreaName) {
-            curAreaName = areaName;
-        }
-        if (className && className !== curClassName) {
-            curClassName = className;
-        }
-        const areaID = areaMap[curAreaName];
-        if (!areaID) {
-            continue;
-        }
-        const classID = classMap[`${curAreaName}@${curClassName}`];
-        if (!classID) {
-            continue;
-        }
-        data.push({
-            ID: uuidV1(),
-            compilationID,
-            libID,
-            areaID,
-            classID,
-            period: libs[0].period,
-            code,
-            name,
-            specs,
-            unit,
-            noTaxPrice,
-            taxPrice
-        });
-    }
-    if (data.length) {
-        await priceInfoItemModel.remove({ libID });
-        await priceInfoItemModel.insertMany(data);
-    } else {
-        throw 'excel没有有效数据。'
-    }
-} */
-
 // 获取费用定额的地区数据
 async function getAreas(compilationID) {
     return await priceInfoAreaModel.find({ compilationID }, '-_id ID name serialNo').lean();
@@ -765,6 +664,55 @@ const getRecommendPriceSummaryData = async (keyword) => {
     return items;
 }
 
+// 处理价格¥符号
+/* const handlePriceText = async () => {
+    const libs = await priceInfoLibModel.find({}).lean();
+    for (const lib of libs) {
+        const libID = lib.ID;
+        const bulks = [];
+        const items = await priceInfoItemModel.find({ libID }, '-_id ID noTaxPrice areaID period').lean();
+        items.forEach(item => {
+            if (item.noTaxPrice && /¥/.test(item.noTaxPrice)) {
+                const noTaxPrice = item.noTaxPrice.replace('¥', '').replace(',', '');
+                bulks.push({ updateOne: { filter: { ID: item.ID, areaID: item.areaID, period: item.period }, update: { $set: { noTaxPrice } } } });
+                // bulks.push({ deleteOne: { filter: { ID: item.ID, areaID: item.areaID, period: item.period } } });
+            }
+        });
+        if (bulks.length) {
+            const chunks = _.chunk(bulks, Math.floor(bulks.length / 500) + 1);
+            for (const chunk of chunks) {
+
+                if (chunk.length) {
+                    await priceInfoItemModel.bulkWrite(chunk);
+                }
+            }
+        }
+    }
+} */
+
+// 删除价格为空的
+const handlePriceText = async () => {
+    const libs = await priceInfoLibModel.find({}).lean();
+    for (const lib of libs) {
+        const libID = lib.ID;
+        const bulks = [];
+        const items = await priceInfoItemModel.find({ libID }, '-_id ID noTaxPrice areaID period').lean();
+        items.forEach(item => {
+            if (!item.noTaxPrice) {
+                bulks.push({ deleteOne: { filter: { ID: item.ID, areaID: item.areaID, period: item.period } } });
+            }
+        });
+        if (bulks.length) {
+            const chunks = _.chunk(bulks, Math.floor(bulks.length / 500) + 1);
+            for (const chunk of chunks) {
+                if (chunk.length) {
+                    await priceInfoItemModel.bulkWrite(chunk);
+                }
+            }
+        }
+    }
+}
+
 module.exports = {
     getLibs,
     createLib,
@@ -786,4 +734,5 @@ module.exports = {
     matchSummary,
     getPriceEmptyData,
     getRecommendPriceSummaryData,
+    handlePriceText,
 }

+ 5 - 1
package.json

@@ -48,7 +48,11 @@
     "uat_server": "SET NODE_ENV=uat&& D:/GitHome/ConstructionOperation/node_modules/.bin/babel-node operation.js",
     "uat_sc_server": "SET NODE_ENV=pp_sc&& D:/GitHome/ConstructionOperation/node_modules/.bin/babel-node operation.js",
     "prod_server": "SET NODE_ENV=prod_s&& D:/GitHome/ConstructionOperation/node_modules/.bin/babel-node operation.js",
+    "prod_server2": "SET NODE_ENV=prod_s2&& D:/GitHome/ConstructionOperation/node_modules/.bin/babel-node operation.js",
     "prod_sc_server": "SET NODE_ENV=prod_sc&& babel-node operation.js",
-    "local2prod_hw_server": "SET NODE_ENV=local2prod_hw&& babel-node operation.js"
+    "local2prod_hw_server": "SET NODE_ENV=local2prod_hw&& babel-node operation.js",
+    "qa_hw_server": "SET NODE_ENV=qa_hw&& babel-node operation.js",
+    "uat_hw_server": "SET NODE_ENV=uat_hw&& babel-node operation.js",
+    "prod_hw_server": "SET NODE_ENV=prod_hw&& babel-node operation.js"
   }
 }

+ 21 - 17
public/web/rpt_value_define.js

@@ -24,14 +24,14 @@ const JV = {
     NODE_EVENTS: "事件_集合",
     NODE_DISCRETE_INFO: "离散信息",
     NODE_BILL_INFO: "账单式表_信息",
-    NODE_BILL_CONTENT : "账单式表_数据",
+    NODE_BILL_CONTENT: "账单式表_数据",
     NODE_FLOW_INFO: "流水式表_信息",
     NODE_FLOW_INFO_EX: "流水式表_拓展信息",
     NODE_FLOW_GROUP: "流水式表_分组信息",
     NODE_FLOW_SEG_SUM: "流水式表_段统计信息",
     NODE_FLOW_PAGE_SUM: "流水式表_页统计信息",
-    NODE_FLOW_COLUMN : "流水式表_列",
-    NODE_FLOW_CONTENT : "流水式表_数据",
+    NODE_FLOW_COLUMN: "流水式表_列",
+    NODE_FLOW_CONTENT: "流水式表_数据",
     PROP_MULTI_COLUMN: "多列显示数量",
     PROP_FLOW_EX_DISPLAY_MODE: "流水拓展显示模式",
     DISPLAY_MODE_INDEPENDENT: "单独模式",
@@ -72,6 +72,9 @@ const JV = {
     PROP_HANDLE_TYPE_COMPONENT_MOVE: "组成物数据转移",
     PROP_HANDLE_TYPE_COMPONENT_REPLACEMENT: "组成物替换",
     PROP_HANDLE_TYPE_PRECISION: "合计精度",
+    PROP_HANDLE_TYPE_CHANGE_QUANTITIES_BILLS: "转化工程量清单",
+    PROP_HANDLE_TYPE_CHANGE_QUANTITIES_BILLS_SORT_TYPE: "工程量清单排序类型",
+    PROP_HANDLE_TYPE_CHANGE_QUANTITIES_BILLS_DATA_TYPE: "工程量清单数据类型",
 
     PROP_ADJUST_COLLECTION: "数据调整集",
     PROP_ADJUST_ACTION: "action",
@@ -93,6 +96,7 @@ const JV = {
     PROP_FIELD_EXP_FIXED_MAP: "fixedMapExpression",
     PROP_FIELD_EXP_FLEXIBLE_MAP: "flexibleMapExpression",
     PROP_FLEXIBLE_REF_FILED_ID: "flexibleRefFieldID",
+    PROP_QUANTITIES_BILLS_LEVEL: "工程量清单输出类型",
 
     NODE_FONT_COLLECTION: "font_collection",
     NODE_STYLE_COLLECTION: "style_collection",
@@ -176,9 +180,9 @@ const JV = {
     BAND_PROP_SUB_BANDS: "band_s",
 
     MEASUREMENT: {
-        PIXEL:["像素点", "象素点", "PIXEL"],
+        PIXEL: ["像素点", "象素点", "PIXEL"],
         CM: ["厘米", "CM"],
-        INCH: ["英寸","INCH"]
+        INCH: ["英寸", "INCH"]
     },
 
     PROP_IS_ID: "isID",
@@ -212,7 +216,7 @@ const JV = {
 
     RUN_TYPE_BEFORE_GROUP_TEXT_OUT: "before_group_text_output",
 
-    PAGE_STATUS: ["EveryPage","FirstPage", "LastPage", "SegmentStart", "SegmentEnd", "Group", "CrossRowEnd", "CrossColEnd"],
+    PAGE_STATUS: ["EveryPage", "FirstPage", "LastPage", "SegmentStart", "SegmentEnd", "Group", "CrossRowEnd", "CrossColEnd"],
 
     CONTROL_PROPS: ["Shrink", "ShowZero", "Horizon", "Vertical", "Wrap", "VerticalForExcel", "ShrinkFirst", "CloseOutput"],
     CONTROL_PROP_IDX_SHRINK: 0,
@@ -246,7 +250,7 @@ const JV = {
     STATUS_CROSS_ROW_END: 6,
     STATUS_CROSS_COL_END: 7,
 
-    LAYOUT: ["Top","Bottom", "Left", "Right", "Fulfill"],
+    LAYOUT: ["Top", "Bottom", "Left", "Right", "Fulfill"],
     LAYOUT_TOP: 0,
     LAYOUT_BOTTOM: 1,
     LAYOUT_LEFT: 2,
@@ -257,14 +261,14 @@ const JV = {
         H: ["left", "center", "right"],
         V: ["top", "center", "bottom"]
     },
-    H_ALIGN_IDX_LEFT : 0,
-    H_ALIGN_IDX_CENTER : 1,
-    H_ALIGN_IDX_RIGHT : 2,
-    V_ALIGN_IDX_TOP : 0,
-    V_ALIGN_IDX_CENTER : 1,
-    V_ALIGN_IDX_BOTTOM : 2,
-
-    CAL_TYPE:["percentage","abstract"],
+    H_ALIGN_IDX_LEFT: 0,
+    H_ALIGN_IDX_CENTER: 1,
+    H_ALIGN_IDX_RIGHT: 2,
+    V_ALIGN_IDX_TOP: 0,
+    V_ALIGN_IDX_CENTER: 1,
+    V_ALIGN_IDX_BOTTOM: 2,
+
+    CAL_TYPE: ["percentage", "abstract"],
     CAL_TYPE_PERCENTAGE: 0,
     CAL_TYPE_ABSTRACT: 1,
 
@@ -288,7 +292,7 @@ const JV = {
     SIZE_16K: [7.75, 10.75],
     SIZE_EXECUTIVE: [7.25, 10.5],
 
-    OUTPUT_OFFSET: [2,2,1,3],
+    OUTPUT_OFFSET: [2, 2, 1, 3],
     OFFSET_IDX_LEFT: 0,
     OFFSET_IDX_RIGHT: 1,
     OFFSET_IDX_TOP: 2,
@@ -319,7 +323,7 @@ const JV = {
     PAGES_SIZE_IDX: [8, 9, 11, 13, 1, 5, 7, 93],
     PAGES_SIZE: [[11.69, 16.54], [8.27, 11.69], [5.83, 8.27], [6.93, 9.84], [8.5, 11.0], [8.5, 14.0], [7.25, 10.5], [7.25, 10.5]],
 
-    HUNDRED_PERCENT : 100.0,
+    HUNDRED_PERCENT: 100.0,
 
     VERTICAL_ANGLE: "90",
     ANTI_VERTICAL_ANGLE: "-90",

+ 40 - 2
web/maintain/bills_lib/html/qingdan.html

@@ -95,6 +95,10 @@
                       <a trigger="billsRecharge" class="pull-right mr-3 uploadImgTrigger lock-btn-control" href="javacript:void(0);" data-toggle="modal" data-target="#uploadimg" ><i class="fa fa-image"></i>上传图片</a>
                       <label for="exampleTextarea">补注:</label>
                       <textarea class="form-control" id="exampleTextarea" rows="8"></textarea>
+                      <div>
+                        <label for="erratumRecordText">勘误记录:</label>
+                        <textarea class="form-control lock-btn-control" id="erratumRecordText" rows="8" style="height: calc(100% - 38px);"></textarea>
+                    </div>
                   </div>
                <!-- <div class="row">
                   <div class="col ovf-hidden" style="width:50%; height: 100%; float: left;">
@@ -372,7 +376,14 @@
         theme:"material",
         readOnly: locked
     });
-    codeEditor.setSize('auto','350px');
+    codeEditor.setSize('auto', '350px');
+    const erratumRecordEditor = CodeMirror.fromTextArea(document.getElementById("erratumRecordText"), {
+        mode: "text/html",
+        lineNumbers: true,
+        theme:"material",
+        readOnly: locked
+    });
+    erratumRecordEditor.setSize('auto','350px');
     autoFlashHeight();
     let BillsFixedFlagList = JSON.parse('<%- BillsFixedFlagList %>');
     let userAccount = '<%= userAccount %>';
@@ -546,6 +557,8 @@
         bindBillsRangeChanged(controller, billsSpread.getActiveSheet(), setting);
         //补注内容改变
         rechargeChange(controller);//
+        // 勘误错误改变
+        erratumRecordChange(controller)
         //焦点控制
         switchFcs(controller, controller.sheet, billsSpread, jobsSheet, designsSheet, itemsSheet);
         //jobs
@@ -775,6 +788,26 @@
         });*/
     }
 
+    // 勘误记录
+    function erratumRecordChange(controller){
+        erratumRecordEditor.on('change', async function () {
+            console.log('1111');
+            const node = controller.tree.selected;
+            const erratumRecord = erratumRecordEditor.getValue();
+            if (!node || erratumRecord === node.data.erratumRecord) {
+                return;
+            }
+            try {
+                const updateId = node.getID();
+                await ajaxPost('/stdBillsEditor/updateBills', { billsLibId, updateId, field: 'erratumRecord', data: erratumRecord });
+                node.data.erratumRecord = erratumRecord;
+            } catch(error) {
+                alert(error.message);
+                erratumRecordEditor.setValue(node.data.erratumRecord || '');
+            }
+        });
+    }
+
     function jobOperation(controller, jobsSheet, callback){
         mainAjax.getMaxNumber(billsLibId, 'jobs', function(result){
             if(result.length === 0){
@@ -864,6 +897,8 @@
                 codeEditor.setValue('');
                 //$('#exampleTextarea').val('');
             }
+            const erratumRecord = controller.tree.selected.data.erratumRecord || '';
+            erratumRecordEditor.setValue(erratumRecord);
         }
     }
 
@@ -876,6 +911,8 @@
                 //rechargeArea
                 const recharge = controller.tree.selected.data.recharge || '';
                 codeEditor.setValue(recharge);
+                const erratumRecord = controller.tree.selected.data.erratumRecord || '';
+                erratumRecordEditor.setValue(erratumRecord);
                 //$('#exampleTextarea').val(controller.tree.selected.data.recharge);
                 if(field === 'jobs'){
                     tools.clearData(sheet);
@@ -955,7 +992,8 @@
                     sheet.setValue(i, 3, sheetBillsDatas.datasIdx['rowIdx'+ i].unit);
                     sheet.setValue(i, 4, sheetBillsDatas.datasIdx['rowIdx'+ i].ruleText);
                     sheet.setValue(i, 5, sheetBillsDatas.datasIdx['rowIdx'+ i].engineerContent);
-                    sheet.setValue(i, 6, sheetBillsDatas.datasIdx['rowIdx'+ i].engineering);
+                    sheet.setValue(i, 6, sheetBillsDatas.datasIdx['rowIdx'+ i].unitPrice);
+                    //sheet.setValue(i, 7, sheetBillsDatas.datasIdx['rowIdx'+ i].engineering);
                     sheet.setValue(i, 7, sheetBillsDatas.datasIdx['rowIdx'+ i].fixedFlag);
                 }
                 else {

+ 18 - 1
web/maintain/bills_lib/scripts/bills_lib_setting.js

@@ -107,6 +107,23 @@ var billsLibSetting = {
         },
         {
             head: {
+                titleNames: ['单价'],
+                spanCols: [1],
+                spanRows: [2],
+                vAlign: [1, 1],
+                hAlign: [1, 1],
+                font: 'Arial'
+            },
+            data: {
+                field: 'unitPrice',
+                vAlign: 1,
+                hAlign: 2,
+                font: 'Arial'
+            },
+            width: 80
+        },
+        /* {
+            head: {
                 titleNames: ['工程专业'],
                 spanCols: [1],
                 spanRows: [2],
@@ -121,7 +138,7 @@ var billsLibSetting = {
                 font: 'Arial'
             },
             width: 80
-        },
+        }, */
         {
             head: {
                 titleNames: ['固定ID'],

+ 14 - 3
web/maintain/bills_lib/scripts/db_controller.js

@@ -373,12 +373,18 @@ var dbController = {
         if (node) {
             updateId = node.getID();
             field = billsLibSetting.cols[args.col].data.field;
-            if (field === 'engineering') {
+            /* if (field === 'engineering') {
                 if (isNaN(args.editingText) || args.editingText % 1 !== 0) {
                     args.sheet.setValue(args.row, args.col, dbController.currentEditData ? dbController.currentEditData : '');
                     alert('工程专业只能输入整数!');
                     return;
                 }
+            } else  */if (field === 'unitPrice') {
+                if (isNaN(args.editingText)) {
+                    args.sheet.setValue(args.row, args.col, dbController.currentEditData ? dbController.currentEditData : '');
+                    alert('单价只能输入数值!');
+                    return;
+                }
             }
             node.data[field] = args.editingText;
             sheetBillsDatas.datasIdx['rowIdx' + args.row][field] = args.editingText;
@@ -802,6 +808,10 @@ var tools = {
                         if (!isNaN(value) && value % 1 === 0) {
                             validData[setting.cols[j].data.field] = value;
                         }
+                    } else if (setting.cols[j].data.field === 'unitPrice') {
+                        if (!isNaN(value)) {
+                            validData[setting.cols[j].data.field] = value;
+                        }
                     } else if (setting.cols[j].data.field === 'fixedFlag') {
                         let findData = BillsFixedFlagList.find((x) => x.name === value);
                         if (findData) {
@@ -1133,9 +1143,10 @@ var tools = {
                 let kind = sheet.getValue(i, 0), code = sheet.getValue(i, 1), name = sheet.getValue(i, 2),
                     unit = sheet.getValue(i, 3), ruleText = sheet.getValue(i, 4),
                     engineerContent = sheet.getValue(i, 5),
-                    engineering = sheet.getValue(i, 6),
+                    unitPrice = sheet.getValue(i, 6),
+                    // engineering = sheet.getValue(i, 7),
                     fixedFlag = sheet.getValue(i, 7);
-                let data = { kind: kind, code: code, name: name, unit: unit, ruleText: ruleText, engineerContent, engineering: engineering, fixedFlag: fixedFlag, rowIdx: i };
+                let data = { kind: kind, code: code, name: name, unit: unit, ruleText: ruleText, engineerContent, unitPrice, /* engineering: engineering, */ fixedFlag: fixedFlag, rowIdx: i };
                 sheetDatas.datas.push(data);
                 sheetDatas.datasIdx['rowIdx' + i] = data;
             }

+ 3 - 1
web/maintain/report/css/main.css

@@ -358,7 +358,9 @@ body {
   left: 105px;
   top: 38px;
   border: 1px solid #d9d9d9;
-  display: none;
+  display: none;    
+  z-index: 999;
+  background-color: #fff;
 }
 .mutiSelector {
   width: 130px;

+ 9 - 1
web/maintain/report/html/rpt_tpl_dtl_info.html

@@ -83,7 +83,15 @@
                 </div>
                 <div class="input-group col-2">
                     <div class="input-group-addon">项目汇总级别</div>
-                    <select class="form-control input-sm" id="element_sumLv_flags" onchange="zTreeOprObj.onChangeFlag('sumLevelType', this)"><option value ="NA">N/A</option><option value ="construct">建设项目级别</option><option value ="Single">单项工程级别</option><option value ="custom">用户自选工程</option></select>
+                    <select class="form-control input-sm" id="element_sumLv_flags" onchange="zTreeOprObj.onChangeFlag('sumLevelType', this)">
+                        <option value ="NA">N/A</option>
+                        <option value ="construct">建设项目级别</option>
+                        <option value ="Single">单项工程级别</option>
+                        <option value ="custom">用户自选工程</option>
+                        <option value="complexUnit">跨项目自选工程(3个建设项目)</option>
+                        <option value="stageContrast">阶段对比</option>
+                        <option value="unitPriceContrast">单价偏差对比</option>
+                    </select>
                 </div>
             </div>
                

+ 2 - 0
web/maintain/report/html/rpt_tpl_dtl_pre_hdl.html

@@ -33,6 +33,8 @@
             <%include ./rpt_tpl_dtl_pre_hdl_adjust.html %>
             <!--dummy数据处理-->
             <%include ./rpt_tpl_dtl_pre_hdl_addDummy.html %>
+            <!--工程量清单数据处理-->
+            <%include ./rpt_tpl_dtl_pre_hdl_change_quantities_bills.html %>
         </div>
     </div>
 </div>

+ 28 - 0
web/maintain/report/html/rpt_tpl_dtl_pre_hdl_change_quantities_bills.html

@@ -0,0 +1,28 @@
+<div id="div_quantities_bills_sort_bar">
+<div class="form-group row" id="div_quantities_bills_sort_type">
+    <div class="input-group col-5">
+        <div class="input-group-addon">排序方式</div>
+        <select class="form-control input-sm" id="select_quantities_bills_sort_types"
+            onchange="preHandleQuantitiesBillsSortObj.onQuantitiesBillsSortTypeChange(this)">
+            <option value="onlyBill">清单排序合并</option>
+            <option value="all">同项目节下排序合并</option>
+            <option value="onlyChapt">只有章节汇总数据</option>
+            <option value="auditComparison">审核对比合并排序</option>
+        </select>
+    </div>
+</div>
+<div class="form-group row" id="div_quantities_bills_type">
+    <div class="input-group col-5">
+        <div class="input-group-addon">处理对象</div>
+        <select class="form-control input-sm" id="select_quantities_bills_types"
+            onchange="preHandleQuantitiesBillsSortObj.onQuantitiesBillsTypesChange(this)">
+            <option value="normal">普通</option>
+            <option value="cross">交叉数据</option>
+            <option value="flow">流水数据</option>
+           
+        </select>
+    </div>
+</div>
+</div>
+
+

+ 35 - 34
web/maintain/report/js/rpt_tpl_field_location.js

@@ -10,7 +10,7 @@ let fieldLocationOprObj = {
     iniSpreadJs: function (columnParentNode, contentParentNode) {
         let me = this;
         if (me.columnWorkBook === null) {
-            me.columnWorkBook = new GC.Spread.Sheets.Workbook($('#rptTplColumnWorkbook')[0], {sheetCount: 1});
+            me.columnWorkBook = new GC.Spread.Sheets.Workbook($('#rptTplColumnWorkbook')[0], { sheetCount: 1 });
             // me.columnWorkBook.setHei
             me.columnWorkBook.options.tabStripVisible = false;
             // me.columnWorkBook.options.scrollbarMaxAlign = true;
@@ -30,7 +30,7 @@ let fieldLocationOprObj = {
     },
     restoreColumn: function () {
         let me = this;
-        let rptTpl = (zTreeOprObj.currentNode)?zTreeOprObj.currentNode.rptTpl:null;
+        let rptTpl = (zTreeOprObj.currentNode) ? zTreeOprObj.currentNode.rptTpl : null;
         me.setupColumn(rptTpl, me.columnParentNode, me.contentParentNode);
     },
     setupColumn: function (rptTpl, columnParentNode, contentParentNode) {
@@ -42,9 +42,8 @@ let fieldLocationOprObj = {
             sheet.suspendPaint();
             sheet.clearSelection();
             sheet.setRowCount(0);
-            let spans =sheet.getSpans();
-            for(let i = 0; i < spans.length; i++)
-            {
+            let spans = sheet.getSpans();
+            for (let i = 0; i < spans.length; i++) {
                 sheet.removeSpan(spans[i].row, spans[i].col, GC.Spread.Sheets.SheetArea.viewport);
             }
             // sheet.setRowCount(1);
@@ -53,10 +52,10 @@ let fieldLocationOprObj = {
             let bandW = 700;
             let pIdx = JV.PAGES_SIZE_STR.indexOf(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_PAGE_SIZE]);
             if (pIdx >= 0) {
-                bandW = Math.round(JV.PAGES_SIZE[pIdx][0] * 96 - (parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_LEFT]) + parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_RIGHT])) /2.54*96 );
+                bandW = Math.round(JV.PAGES_SIZE[pIdx][0] * 96 - (parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_LEFT]) + parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_RIGHT])) / 2.54 * 96);
                 if (rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_ORIENTATION] === JV.ORIENTATION_LANDSCAPE ||
                     rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_ORIENTATION] === JV.ORIENTATION_LANDSCAPE_CHN) {
-                    bandW = Math.round(JV.PAGES_SIZE[pIdx][1] * 96 - (parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_LEFT]) + parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_RIGHT])) /2.54*96 );
+                    bandW = Math.round(JV.PAGES_SIZE[pIdx][1] * 96 - (parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_LEFT]) + parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_RIGHT])) / 2.54 * 96);
                 }
             }
             if (columnParentNode.items && columnParentNode.items.length > 0) {
@@ -84,10 +83,10 @@ let fieldLocationOprObj = {
                 for (let jCol = 0; jCol < sheet.getColumnCount(); jCol++) {
                     sheet.getCell(iSelectedRow, jCol).cellType(cellType);
                 }
-                xPos.sort(function(x1, x2){
+                xPos.sort(function (x1, x2) {
                     return (x1 - x2);
                 });
-                yPos.sort(function(y1, y2){
+                yPos.sort(function (y1, y2) {
                     return (y1 - y2);
                 });
                 for (let contentItemNode of contentParentNode.items) {
@@ -151,7 +150,7 @@ let fieldLocationOprObj = {
         let me = fieldLocationOprObj,
             sheet = me.columnWorkBook.getActiveSheet(),
             selectedRanges = sheet.getSelections()
-        ;
+            ;
         let rc = sheet.getRowCount();
         if (rc > 2) {
             if (selectedRanges.length > 0) {
@@ -184,7 +183,7 @@ let fieldLocationOprObj = {
         let me = fieldLocationOprObj,
             sheet = me.columnWorkBook.getActiveSheet(),
             selectedRanges = sheet.getSelections()
-        ;
+            ;
         let cc = sheet.getColumnCount();
         if (cc > 1) {
             if (selectedRanges.length > 0) {
@@ -215,8 +214,7 @@ let fieldLocationOprObj = {
         let spans = sheet.getSpans();
         if (selectedRanges.length > 0 && spans.length > 0) {
             let selectedSpans = [];
-            for(let i = 0; i < spans.length; i++)
-            {
+            for (let i = 0; i < spans.length; i++) {
                 for (let j = 0; j < selectedRanges.length; j++) {
                     if (spans[i].row >= selectedRanges[j].row && spans[i].col >= selectedRanges[j].col &&
                         spans[i].row < selectedRanges[j].row + selectedRanges[j].rowCount && spans[i].col < selectedRanges[j].col + selectedRanges[j].colCount) {
@@ -230,14 +228,14 @@ let fieldLocationOprObj = {
         }
     },
     fitTheWidth: function (factor) {
-        let me = this, rptTpl = (zTreeOprObj.currentNode)?zTreeOprObj.currentNode.rptTpl:null;
+        let me = this, rptTpl = (zTreeOprObj.currentNode) ? zTreeOprObj.currentNode.rptTpl : null;
         let pIdx = JV.PAGES_SIZE_STR.indexOf(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_PAGE_SIZE]);
         let bandW = 700;
         if (pIdx >= 0) {
-            bandW = Math.round(JV.PAGES_SIZE[pIdx][0] * 96 - (parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_LEFT]) + parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_RIGHT])) /2.54*96 );
+            bandW = Math.round(JV.PAGES_SIZE[pIdx][0] * 96 - (parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_LEFT]) + parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_RIGHT])) / 2.54 * 96);
             if (rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_ORIENTATION] === JV.ORIENTATION_LANDSCAPE ||
                 rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_ORIENTATION] === JV.ORIENTATION_LANDSCAPE_CHN) {
-                bandW = Math.round(JV.PAGES_SIZE[pIdx][1] * 96 - (parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_LEFT]) + parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_RIGHT])) /2.54*96 );
+                bandW = Math.round(JV.PAGES_SIZE[pIdx][1] * 96 - (parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_LEFT]) + parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_RIGHT])) / 2.54 * 96);
             }
         }
         bandW *= factor;
@@ -255,10 +253,10 @@ let fieldLocationOprObj = {
         let me = fieldLocationOprObj,
             sheet = me.columnWorkBook.getActiveSheet(),
             fieldRowIdx = sheet.getRowCount() - 1
-        ;
+            ;
         //sheet.getSelectio
         let selectedRanges = sheet.getSelections();
-        for(let i = 0; i < selectedRanges.length; i++){
+        for (let i = 0; i < selectedRanges.length; i++) {
             if (selectedRanges[i].row === fieldRowIdx) {
                 let ctrl = me.columnFieldCtrls[selectedRanges[i].col]
                 ctrl[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_SHRINK]] = 'F';
@@ -352,7 +350,7 @@ let fieldLocationOprObj = {
         }
     },
     private_create_dft_ctrl: function () {
-        return {"Shrink" : "T", "ShowZero" : "T", "Horizon": "left", "Vertical": "bottom", "Wrap": "F", "isNarrow": false, "isAutoHeight": false };
+        return { "Shrink": "T", "ShowZero": "T", "Horizon": "left", "Vertical": "bottom", "Wrap": "F", "isNarrow": false, "isAutoHeight": false };
     },
     private_merge_ctrl: function (rptTpl, srcIdx, fieldNode, directCtrl) {
         let me = this, ctrl = null;
@@ -405,23 +403,24 @@ let fieldLocationOprObj = {
             $("#eleIsAutoHeightEx")[0].removeAttribute("disabled");
         } else {
             $("#fieldControlDiv")[0].style.cursor = "not-allowed";
-            $("#hOptionLeft")[0].disabled = "disabled" ;
-            $("#hOptionCenter")[0].disabled = "disabled" ;
-            $("#hOptionRight")[0].disabled = "disabled" ;
-            $("#vOptionUp")[0].disabled = "disabled" ;
-            $("#vOptionCenter")[0].disabled = "disabled" ;
-            $("#vOptionDown")[0].disabled = "disabled" ;
-            $("#eleShrinkEx")[0].disabled = "disabled" ;
-            $("#eleShowZeroEx")[0].disabled = "disabled" ;
-            $("#eleAutoWrapEx")[0].disabled = "disabled" ;
-            $("#eleIsNarrowEx")[0].disabled = "disabled" ;
-            $("#eleIsAutoHeightEx")[0].disabled = "disabled" ;
+            $("#hOptionLeft")[0].disabled = "disabled";
+            $("#hOptionCenter")[0].disabled = "disabled";
+            $("#hOptionRight")[0].disabled = "disabled";
+            $("#vOptionUp")[0].disabled = "disabled";
+            $("#vOptionCenter")[0].disabled = "disabled";
+            $("#vOptionDown")[0].disabled = "disabled";
+            $("#eleShrinkEx")[0].disabled = "disabled";
+            $("#eleShowZeroEx")[0].disabled = "disabled";
+            $("#eleAutoWrapEx")[0].disabled = "disabled";
+            $("#eleIsNarrowEx")[0].disabled = "disabled";
+            $("#eleIsAutoHeightEx")[0].disabled = "disabled";
         }
     },
     private_create_content_node: function (colWidthArr, cellValue, colIdx, rptTpl) {
         let me = this;
-        let rst = {"Name": cellValue, "Title": '', "FieldID": -1, "font": "Content", "control": "Column", "style" : "Default_Normal", "isAutoHeight" : false,
-            "area" : {"Left" : 0, "Right" : 100, "Top" : 0, "Bottom" : 100, "H_CalculationType" : "percentage", "V_CalculationType" : "percentage"}
+        let rst = {
+            "Name": cellValue, "Title": '', "FieldID": -1, "font": "Content", "control": "Column", "style": "Default_Normal", "isAutoHeight": false,
+            "area": { "Left": 0, "Right": 100, "Top": 0, "Bottom": 100, "H_CalculationType": "percentage", "V_CalculationType": "percentage" }
         };
         //1. 设置FieldID
         let hasChkField = false;
@@ -429,6 +428,7 @@ let fieldLocationOprObj = {
             for (let field of rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS]) {
                 if (field[JV.PROP_NAME] === cellValue) {
                     rst.FieldID = field[JV.PROP_ID];
+                    // rst.Name = field.Name + "(" + field[JV.PROP_ID] + ")";
                     rst["Title"] = "ID: " + field[JV.PROP_ID];
                     hasChkField = true;
                     break;
@@ -439,6 +439,7 @@ let fieldLocationOprObj = {
             for (let field of rptTpl[JV.NODE_NO_MAPPING_FIELDS]) {
                 if (field[JV.PROP_NAME] === cellValue) {
                     rst.FieldID = field[JV.PROP_ID];
+                    // rst.Name = field.Name + "(" + field[JV.PROP_ID] + ")";
                     rst["Title"] = "ID: " + field[JV.PROP_ID];
                     hasChkField = true;
                     break;
@@ -490,7 +491,7 @@ let fieldLocationOprObj = {
 
     applyColumnBack: function () {
         let me = this;
-        let rptTpl = (zTreeOprObj.currentNode)?zTreeOprObj.currentNode.rptTpl:null;
+        let rptTpl = (zTreeOprObj.currentNode) ? zTreeOprObj.currentNode.rptTpl : null;
         if (rptTpl && me.columnParentNode && me.contentParentNode && confirm(`请确认提交应用!`)) {
             let sheet = me.columnWorkBook.getActiveSheet();
             if (sheet.getRowCount() > 1 && sheet.getColumnCount() > 0) {
@@ -513,7 +514,7 @@ let fieldLocationOprObj = {
                 //1. 重新生成节点
                 let contentNodes = [];
                 let contenRowIdx = sheet.getRowCount() - 1;
-                let rptTpl = (zTreeOprObj.currentNode)?zTreeOprObj.currentNode.rptTpl:null;
+                let rptTpl = (zTreeOprObj.currentNode) ? zTreeOprObj.currentNode.rptTpl : null;
                 for (let iCol = 0; iCol < sheet.getColumnCount(); iCol++) {
                     let cellValue = sheet.getValue(contenRowIdx, iCol);
                     if (!(stringUtil.isEmptyString(cellValue))) {

+ 62 - 49
web/maintain/report/js/rpt_tpl_field_map.js

@@ -7,10 +7,10 @@
 'use strict'
 
 let fieldMapTreeOprObj = {
-    treeObj : null,
+    treeObj: null,
     currentNode: null,
     dataTypeDef: ['string', 'int32', 'int64', 'double', 'currency', 'date', 'image', 'object'],
-    iniTree: function(rptTpl) {
+    iniTree: function (rptTpl) {
         var me = this;
         let fieldMapList = me.buildTreeData(rptTpl);
         me.treeObj = $.fn.zTree.init($("#field_map_tree_reversed"), fieldMapSetting, fieldMapList);
@@ -27,21 +27,22 @@ let fieldMapTreeOprObj = {
                 if (field[JV.PROP_IS_ID]) {
                     field.checked = true;
                 }
+                // field.Name = field.Name + "(" + field[JV.PROP_ID] + ")";
                 field.Title = "ID: " + field[JV.PROP_ID];
                 parent.items.push(field);
             }
         }
 
         if (rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DISCRETE_FIELDS]) {
-            rst.push({Name: JV.NODE_DISCRETE_FIELDS, items: [], isParent: true});
+            rst.push({ Name: JV.NODE_DISCRETE_FIELDS, items: [], isParent: true });
             private_setSubFields(rst[rst.length - 1], rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DISCRETE_FIELDS])
         }
         if (rptTpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS]) {
-            rst.push({Name: JV.NODE_MASTER_FIELDS, items: [], isParent: true});
+            rst.push({ Name: JV.NODE_MASTER_FIELDS, items: [], isParent: true });
             private_setSubFields(rst[rst.length - 1], rptTpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS])
         }
         if (rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS]) {
-            rst.push({Name: JV.NODE_DETAIL_FIELDS, items: [], isParent: true});
+            rst.push({ Name: JV.NODE_DETAIL_FIELDS, items: [], isParent: true });
             private_setSubFields(rst[rst.length - 1], rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS])
         }
 
@@ -52,7 +53,7 @@ let fieldMapTreeOprObj = {
         if (me.treeObj) {
             let nodes = me.treeObj.getNodes();
             for (let node of nodes) {
-                let item = {Name: node.Name, items: [], isParent: true, Title: ""};
+                let item = { Name: node.Name, items: [], isParent: true, Title: "" };
                 if (node.items) {
                     for (let subNode of node.items) {
                         let subItem = me.createMapFieldByNode(subNode);
@@ -64,7 +65,7 @@ let fieldMapTreeOprObj = {
         }
         return rst;
     },
-    onClick: function (event,treeId,treeNode) {
+    onClick: function (event, treeId, treeNode) {
         let me = fieldMapTreeOprObj;
         me.currentNode = treeNode;
         //then refresh the field map tab properties
@@ -91,13 +92,13 @@ let fieldMapTreeOprObj = {
         // }
         //映射指标
     },
-    onBeforeRemove: function(treeId, treeNode){
+    onBeforeRemove: function (treeId, treeNode) {
         if (treeNode.level === 0) {
             return false;
         }
         return true;
     },
-    beforeRename: function(treeId, treeNode, newName, isCancel) {
+    beforeRename: function (treeId, treeNode, newName, isCancel) {
         if (isCancel) {
             return true;
         }
@@ -106,7 +107,7 @@ let fieldMapTreeOprObj = {
         }
         return true;
     },
-    onBeforeDrop: function(treeId, treeNodes, targetNode, moveType){
+    onBeforeDrop: function (treeId, treeNodes, targetNode, moveType) {
         let rst = true;
         if (treeId === 'selectable_field_tree_reversed' || targetNode.level === 0 || moveType === 'inner') {
             rst = false;
@@ -188,28 +189,40 @@ let fieldMapTreeOprObj = {
     }
 };
 
+// const setNodeFieldID = (data) => {
+//     if (data.items && data.items.length > 0) {
+//         data.items.forEach(i => {
+//             setNodeFieldID(i);
+//         })
+
+//     } else {
+//         data.Name = data.Name + "(" + data.ID + ")";
+//     }
+// }
+
 let selectableFiledTreeOprObj = {
-    treeObj : null,
+    treeObj: null,
     currentNode: null,
-    iniTree: function() {
+    iniTree: function () {
         let me = this, params = {};
         params.userId = userID;
-        CommonAjax.postEx("report_tpl_api/getMappingFields", params, 20000, true, function(result){
-                let showRst = [];
-                for (let item of result) {
-                    me.decorateMappingFieldList(item);
-                    if (item.items.length > 0) {
-                        showRst.push(item);
-                    }
+        CommonAjax.postEx("report_tpl_api/getMappingFields", params, 20000, true, function (result) {
+            let showRst = [];
+            for (let item of result) {
+                me.decorateMappingFieldList(item);
+                if (item.items.length > 0) {
+                    // setNodeFieldID(item);
+                    showRst.push(item);
                 }
-                me.treeObj = $.fn.zTree.init($("#selectable_field_tree_reversed"), selectableFieldSetting, showRst);
-                let nodes = me.treeObj.getNodes();
-                for (let node of nodes) {
-                    me.treeObj.expandNode(node, true, false);
-                }
-                // me.treeObj.expandAll(true);
-                showRst = null;
-            }, null, null
+            }
+            me.treeObj = $.fn.zTree.init($("#selectable_field_tree_reversed"), selectableFieldSetting, showRst);
+            let nodes = me.treeObj.getNodes();
+            for (let node of nodes) {
+                me.treeObj.expandNode(node, true, false);
+            }
+            // me.treeObj.expandAll(true);
+            showRst = null;
+        }, null, null
         );
     },
     decorateMappingFieldList: function (rawMappingField) {
@@ -222,7 +235,7 @@ let selectableFiledTreeOprObj = {
             rawMappingField.Title = "ID: " + rawMappingField[JV.PROP_ID];
         }
     },
-    onClick: function (event,treeId,treeNode) {
+    onClick: function (event, treeId, treeNode) {
         let me = fieldMapTreeOprObj;
         me.currentNode = treeNode;
     },
@@ -236,10 +249,10 @@ let selectableFiledTreeOprObj = {
         }
         return rst;
     },
-    onBeforeDrop: function(treeId, treeNodes, targetNode, moveType){
+    onBeforeDrop: function (treeId, treeNodes, targetNode, moveType) {
         let rst = true;
         if (treeId === 'field_map_tree_reversed') {
-            if ( (targetNode.level === 0 && moveType !== 'inner') || (targetNode.level > 0 && moveType === 'inner')) {
+            if ((targetNode.level === 0 && moveType !== 'inner') || (targetNode.level > 0 && moveType === 'inner')) {
                 rst = false;
             }
         } else {
@@ -250,29 +263,29 @@ let selectableFiledTreeOprObj = {
     addDiyDom: function (treeId, treeNode) {
         if (treeNode.level > 0) {
             let aObj = $("#" + treeNode.tId + "_a");
-            if ($("#diyBtn_"+treeNode.ID).length>0) return;
+            if ($("#diyBtn_" + treeNode.ID).length > 0) return;
             let editStr = "<span>&nbsp(" + treeNode.DataType + ")</span>";
             aObj.append(editStr);
-            let btn = $("#diyBtn_"+treeNode.ID);
-            if (btn) btn.bind("click", function(){alert("diy Button for " + treeNode.name);});
+            let btn = $("#diyBtn_" + treeNode.ID);
+            if (btn) btn.bind("click", function () { alert("diy Button for " + treeNode.name); });
         }
     }
 };
 
 let discreteFieldParamTreeOprObj = {
-    treeObj : null,
+    treeObj: null,
     currentNode: null,
-    local_idx : 12000,
-    iniTree: function(rptTpl) {
+    local_idx: 12000,
+    iniTree: function (rptTpl) {
         var me = this;
         let fieldMapList = me.buildTreeData(rptTpl);
         me.treeObj = $.fn.zTree.init($("#tpl_discrete_fields_params_reversed"), discreteFieldParamSetting, fieldMapList);
         me.treeObj.expandAll(true);
     },
-    buildTreeData: function(rptTpl){
+    buildTreeData: function (rptTpl) {
         let me = this, rst = [];
-        let disFieldNode = {Name: JV.NODE_NO_MAPPING_FIELDS, items: [], isParent: true, Title: ""};
-        let disParamNode = {Name: JV.NODE_DISCRETE_PARAMS, items: [], isParent: true, Title: ""};
+        let disFieldNode = { Name: JV.NODE_NO_MAPPING_FIELDS, items: [], isParent: true, Title: "" };
+        let disParamNode = { Name: JV.NODE_DISCRETE_PARAMS, items: [], isParent: true, Title: "" };
         rst.push(disFieldNode);
         rst.push(disParamNode);
         if (rptTpl[JV.NODE_NO_MAPPING_FIELDS] && rptTpl[JV.NODE_NO_MAPPING_FIELDS].length > 0) {
@@ -302,18 +315,18 @@ let discreteFieldParamTreeOprObj = {
         }
         return rst;
     },
-    getAndModifyLocalIdx: function() {
+    getAndModifyLocalIdx: function () {
         let me = discreteFieldParamTreeOprObj, rst = me.local_idx;
         me.local_idx++;
         return rst;
     },
-    addHoverDom: function(treeId, treeNode) {
+    addHoverDom: function (treeId, treeNode) {
         let me = discreteFieldParamTreeOprObj, sObj = $("#" + treeNode.tId + "_span");
-        if (treeNode.level > 0 || $("#addBtn_"+treeNode.tId).length > 0) return;
+        if (treeNode.level > 0 || $("#addBtn_" + treeNode.tId).length > 0) return;
         let addStr = "<span class='button add' id='addBtn_" + treeNode.tId + "' title='新增子节点' onfocus='this.blur();'></span>";
         sObj.after(addStr);
-        let btn = $("#addBtn_"+treeNode.tId);
-        if (btn) btn.bind("click", function(){
+        let btn = $("#addBtn_" + treeNode.tId);
+        if (btn) btn.bind("click", function () {
             if (treeNode[JV.PROP_NAME] === JV.NODE_NO_MAPPING_FIELDS) {
                 let field = me.private_setup_dummy_discrete_field_node();
                 let newNodes = [field];
@@ -343,17 +356,17 @@ let discreteFieldParamTreeOprObj = {
         rst.Title = "ID: " + rst[JV.PROP_ID];
         return rst;
     },
-    removeHoverDom: function(treeId, treeNode) {
-        $("#addBtn_"+treeNode.tId).unbind().remove();
+    removeHoverDom: function (treeId, treeNode) {
+        $("#addBtn_" + treeNode.tId).unbind().remove();
     },
-    onBeforeRemove: function(treeId, treeNode){
+    onBeforeRemove: function (treeId, treeNode) {
         let rst = true;
         if (treeNode.isParent) {
             rst = false;
         }
         return rst;
     },
-    beforeRename: function(treeId, treeNode, newName, isCancel) {
+    beforeRename: function (treeId, treeNode, newName, isCancel) {
         let rst = true;
         if (treeNode.isParent && !isCancel) {
             rst = false;
@@ -370,7 +383,7 @@ let discreteFieldParamTreeOprObj = {
         }
         return rst;
     },
-    onBeforeDrop: function(treeId, treeNodes, targetNode, moveType){
+    onBeforeDrop: function (treeId, treeNodes, targetNode, moveType) {
         // let rst = false;
         // if (targetNode.tId && targetNode.tId.indexOf("tpl_data_info_reversed") >= 0 && (!(targetNode.isParent && moveType !== 'inner')) ) {
         //     if (targetNode.level === 0) {

+ 3 - 0
web/maintain/report/js/rpt_tpl_main.js

@@ -953,6 +953,9 @@ let zTreeOprObj = {
                             if (sumLvType === 'construct') $("#element_sumLv_flags")[0].selectedIndex = 1
                             else if (sumLvType === 'Single') $("#element_sumLv_flags")[0].selectedIndex = 2
                             else if (sumLvType === 'custom') $("#element_sumLv_flags")[0].selectedIndex = 3
+                            else if (sumLvType === 'complexUnit') $("#element_sumLv_flags")[0].selectedIndex = 4
+                            else if (sumLvType === 'stageContrast') $("#element_sumLv_flags")[0].selectedIndex = 5
+                            else if (sumLvType === 'unitPriceContrast') $("#element_sumLv_flags")[0].selectedIndex = 6
                             else $("#element_sumLv_flags")[0].selectedIndex = 0;
                         } else {
                             $("#element_sumLv_flags")[0].selectedIndex = 0;

+ 54 - 1
web/maintain/report/js/rpt_tpl_pre_handle.js

@@ -286,9 +286,12 @@ let preHandleObj = {
         types.push({ Name: JV.PROP_HANDLE_TYPE_SUM, Title: "" });
         types.push({ Name: JV.PROP_HANDLE_TYPE_ADJUST, Title: "" });
         types.push({ Name: JV.PROP_HANDLE_TYPE_ADD_DUMMY, Title: "" });
+        types.push({
+            Name: JV.PROP_HANDLE_TYPE_CHANGE_QUANTITIES_BILLS, Title: ''
+        });
         // types.push({Name: "纯手工填写", Title: ""});
         me.typeTreeObj = $.fn.zTree.init($("#pre_handle_type_reversed"), preHandleTypeSetting, types);
-        me.setDisabledBandSelect([0, 1, 2, 3, 4, 5, 6]);
+        me.setDisabledBandSelect([0, 1, 2, 3, 4, 5, 6, 7]);
         me.build_handle_data_selection();
     },
     setDisabledBandSelect: function (disabledIdxArr) {
@@ -331,6 +334,9 @@ let preHandleObj = {
             case JV.PROP_HANDLE_TYPE_ADD_DUMMY:
                 rst = { Name: "预处理环节", Title: "", "映射数据对象": "bills", "预处理类型": preHandleType, "Dummy数据集": [] };
                 break;
+            case JV.PROP_HANDLE_TYPE_CHANGE_QUANTITIES_BILLS:
+                rst = { Name: "预处理环节", Title: "", "映射数据对象": "bills", "预处理类型": preHandleType };
+                break;
             default:
                 rst = { Name: "预处理环节", Title: "", "映射数据对象": "bills", "预处理类型": "排序", "排序方式": "normal", "排序键值集": [] };
                 break;
@@ -370,6 +376,10 @@ let preHandleObj = {
             case JV.PROP_HANDLE_TYPE_ADD_DUMMY:
                 item[JV.PROP_DUMMY_COLLECTION] = [];
                 break;
+            case JV.PROP_HANDLE_TYPE_CHANGE_QUANTITIES_BILLS:
+                item[JV.PROP_HANDLE_TYPE_CHANGE_QUANTITIES_BILLS_SORT_TYPE] = "all";// 工程量清单排序
+                item[JV.PROP_HANDLE_TYPE_CHANGE_QUANTITIES_BILLS_DATA_TYPE] = 'bills'; // 工程量清单输出级别
+                break;
             default:
                 item[JV.PROP_HANDLE_TYPE] = JV.PROP_HANDLE_TYPE_SORT;
                 item[JV.PROP_SORT_TYPE] = "normal";
@@ -393,6 +403,8 @@ let preHandleObj = {
             preHandleAdjustObj.copyNode(src, dest);
         } else if (src[JV.PROP_HANDLE_TYPE] === JV.PROP_HANDLE_TYPE_ADD_DUMMY) {
             preHandleAddDummyObj.copyNode(src, dest);
+        } else if (src[JV.PROP_HANDLE_TYPE] === JV.PROP_HANDLE_TYPE_CHANGE_QUANTITIES_BILLS) {
+            preHandleQuantitiesBillsSortObj.copyNode(src, dest);
         }
     },
     private_set_title: function (node) {
@@ -435,6 +447,8 @@ let preHandleObj = {
                     preHandleAdjustObj.refresh_node();
                 } else if (typeNode[JV.PROP_NAME] === "增加Dummy数据") {
                     preHandleAddDummyObj.refresh_node();
+                } else if (typeNode[JV.PROP_NAME] === "转化工程量清单") {
+                    preHandleQuantitiesBillsSortObj.refresh_node();
                 }
             }
         }
@@ -451,6 +465,7 @@ let preHandleObj = {
         $("#div_sort_type_parent_data")[0].style.display = "none";
         $("#div_sort_tree")[0].style.display = "none";
         $("#div_sort_self_define")[0].style.display = "none";
+        $("#div_quantities_bills_sort_bar")[0].style.display = "none";
     },
     onPreHandleClick: function (event, treeId, treeNode) {
         //点击预处理环节 节点
@@ -577,6 +592,9 @@ let preHandleObj = {
                     case JV.PROP_HANDLE_TYPE_COMPONENT_MOVE:
                         rst.push(preHandleBillDataMoveObj.extractTabFields(handleObj));
                         break;
+                    case JV.PROP_HANDLE_TYPE_CHANGE_QUANTITIES_BILLS:
+                        rst.push(preHandleQuantitiesBillsSortObj.extractTabFields(handleObj));
+                        break;
                     default:
                         break;
                 }
@@ -1252,3 +1270,38 @@ let preHandleAddDummyObj = {
         return rst;
     }
 };
+let preHandleQuantitiesBillsSortObj = {
+    copyNode: function (src, dest) {
+        dest[JV.PROP_HANDLE_TYPE_CHANGE_QUANTITIES_BILLS_SORT_TYPE] = src.billSortType;
+        dest[JV.PROP_HANDLE_TYPE_CHANGE_QUANTITIES_BILLS_DATA_TYPE] = src.billSortData;
+    },
+    refresh_node: function () {
+        $("#div_quantities_bills_sort_bar")[0].style.display = "";
+        if (preHandleObj.currentNode) {
+            $("#select_quantities_bills_sort_types")[0].value = preHandleObj.currentNode[JV.PROP_HANDLE_TYPE_CHANGE_QUANTITIES_BILLS_SORT_TYPE] || 'all';
+            $("#select_quantities_bills_types")[0].value = preHandleObj.currentNode[JV.PROP_HANDLE_TYPE_CHANGE_QUANTITIES_BILLS_DATA_TYPE] || 'bills';
+        }
+    },
+    extractTabFields: function (handleObj) {
+        let me = preHandleQuantitiesBillsSortObj, rst = {};
+        me.copyNode(handleObj, rst);
+        rst = {
+            "预处理类型": "转化工程量清单",
+            "映射数据对象": "bills",
+            'billSortType': handleObj[JV.PROP_HANDLE_TYPE_CHANGE_QUANTITIES_BILLS_SORT_TYPE],
+            'billSortData': handleObj[JV.PROP_HANDLE_TYPE_CHANGE_QUANTITIES_BILLS_DATA_TYPE],
+        }
+        return rst;
+    },
+    onQuantitiesBillsSortTypeChange: function (dom) {
+        // 工程量清单排序类型
+        let me = preHandleObj;
+        me.currentNode[JV.PROP_HANDLE_TYPE_CHANGE_QUANTITIES_BILLS_SORT_TYPE] = dom.value;
+
+    },
+    onQuantitiesBillsTypesChange: function (dom) {
+        // 工程量清单排序对象类型
+        let me = preHandleObj;
+        me.currentNode[JV.PROP_HANDLE_TYPE_CHANGE_QUANTITIES_BILLS_DATA_TYPE] = dom.value;
+    },
+}

+ 27 - 25
web/maintain/report/js/rpt_tpl_vis_sum.js

@@ -11,7 +11,7 @@ let virtualSummaryOprObj = {
             me.summaryWorkBook.destroy();
             me.summaryWorkBook = null;
         }
-        me.summaryWorkBook = new GC.Spread.Sheets.Workbook($('#rptTplSummaryWorkbook')[0], {sheetCount: 1});
+        me.summaryWorkBook = new GC.Spread.Sheets.Workbook($('#rptTplSummaryWorkbook')[0], { sheetCount: 1 });
         me.summaryWorkBook.options.tabStripVisible = false;
         me.summaryWorkBook.options.allowCopyPasteExcelStyle = false;
         me.summaryWorkBook.options.allowUserDragDrop = false;
@@ -24,7 +24,7 @@ let virtualSummaryOprObj = {
     },
     restoreSummary: function () {
         let me = this;
-        let rptTpl = (zTreeOprObj.currentNode)?zTreeOprObj.currentNode.rptTpl:null;
+        let rptTpl = (zTreeOprObj.currentNode) ? zTreeOprObj.currentNode.rptTpl : null;
         me.private_setup_control_options(false);
         me.setupSummary(rptTpl, me.summaryParentNode);
     },
@@ -46,17 +46,17 @@ let virtualSummaryOprObj = {
             if (columnParentNode) {
                 let yColumnPos = [], xPos = [], ySummaryPos = [0]
                     // , xSummaryPos = [0]
-                ;
+                    ;
                 let sheet = me.summaryWorkBook.getActiveSheet();
                 let columnBand = visualCommonOprObj.getBandEx(columnParentNode[JV.PROP_BAND_NAME], rptTpl);
                 let bandH = Math.round(parseFloat(columnBand[JV.BAND_PROP_HEIGHT]) / 2.54 * 96);
                 let bandW = 700;
                 let pIdx = JV.PAGES_SIZE_STR.indexOf(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_PAGE_SIZE]);
                 if (pIdx >= 0) {
-                    bandW = Math.round(JV.PAGES_SIZE[pIdx][0] * 96 - (parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_LEFT]) + parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_RIGHT])) /2.54*96 );
+                    bandW = Math.round(JV.PAGES_SIZE[pIdx][0] * 96 - (parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_LEFT]) + parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_RIGHT])) / 2.54 * 96);
                     if (rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_ORIENTATION] === JV.ORIENTATION_LANDSCAPE ||
                         rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_ORIENTATION] === JV.ORIENTATION_LANDSCAPE_CHN) {
-                        bandW = Math.round(JV.PAGES_SIZE[pIdx][1] * 96 - (parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_LEFT]) + parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_RIGHT])) /2.54*96 );
+                        bandW = Math.round(JV.PAGES_SIZE[pIdx][1] * 96 - (parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_LEFT]) + parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_RIGHT])) / 2.54 * 96);
                     }
                 }
                 //1. 设置column位置(让用户知道位置,后期无需用户再调)
@@ -72,10 +72,10 @@ let virtualSummaryOprObj = {
                 sheet.setColumnCount(xPos.length - 1, GC.Spread.Sheets.SheetArea.viewport);
                 // sheet.clear();
 
-                xPos.sort(function(x1, x2){
+                xPos.sort(function (x1, x2) {
                     return (x1 - x2);
                 });
-                yColumnPos.sort(function(y1, y2){
+                yColumnPos.sort(function (y1, y2) {
                     return (y1 - y2);
                 });
                 for (let idx = 1; idx < xPos.length; idx++) {
@@ -127,7 +127,7 @@ let virtualSummaryOprObj = {
         let me = this,
             sheet = me.summaryWorkBook.getActiveSheet(),
             selectedRanges = sheet.getSelections()
-        ;
+            ;
         sheet.suspendPaint();
         if (selectedRanges.length > 0) {
             sheet.deleteRows(selectedRanges[0].row, 1);
@@ -207,8 +207,7 @@ let virtualSummaryOprObj = {
         if (selectedRanges.length > 0 && spans.length > 0) {
             sheet.suspendPaint();
             let selectedSpans = [];
-            for(let i = 0; i < spans.length; i++)
-            {
+            for (let i = 0; i < spans.length; i++) {
                 for (let j = 0; j < selectedRanges.length; j++) {
                     if (spans[i].row >= selectedRanges[j].row && spans[i].col >= selectedRanges[j].col &&
                         spans[i].row <= selectedRanges[j].row + selectedRanges[j].rowCount && spans[i].col <= selectedRanges[j].col + selectedRanges[j].colCount) {
@@ -243,8 +242,8 @@ let virtualSummaryOprObj = {
             let hA = GC.Spread.Sheets.HorizontalAlign.left, vA = GC.Spread.Sheets.VerticalAlign.top;
             if ($(`#hOptionCenterSum`)[0].checked) hA = GC.Spread.Sheets.HorizontalAlign.center;
             if ($(`#hOptionRightSum`)[0].checked) hA = GC.Spread.Sheets.HorizontalAlign.right;
-            if ($(`#vOptionCenterSum`)[0].checked ) vA = GC.Spread.Sheets.VerticalAlign.center;
-            if ($(`#vOptionDownSum`)[0].checked ) vA = GC.Spread.Sheets.VerticalAlign.bottom;
+            if ($(`#vOptionCenterSum`)[0].checked) vA = GC.Spread.Sheets.VerticalAlign.center;
+            if ($(`#vOptionDownSum`)[0].checked) vA = GC.Spread.Sheets.VerticalAlign.bottom;
             cell.hAlign(hA);
             cell.vAlign(vA);
             if ($(`#eleIsNarrowSumEx`)[0].checked) {
@@ -258,9 +257,9 @@ let virtualSummaryOprObj = {
     changeCtrl: function (dom) {
         let me = virtualSummaryOprObj,
             sheet = me.summaryWorkBook.getActiveSheet()
-        ;
+            ;
         let selectedRanges = sheet.getSelections();
-        for(let i = 0; i < selectedRanges.length; i++){
+        for (let i = 0; i < selectedRanges.length; i++) {
             //         let ctrl = me.columnFieldCtrls[selectedRanges[i].col]
             //         ctrl[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_SHRINK]] = 'F';
             //         ctrl[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_SHOW_ZERO]] = 'F';
@@ -314,21 +313,22 @@ let virtualSummaryOprObj = {
             $("#eleIsNarrowSumEx")[0].removeAttribute("disabled");
         } else {
             $("#sumFieldControlDiv")[0].style.cursor = "not-allowed";
-            $("#hOptionLeftSum")[0].disabled = "disabled" ;
-            $("#hOptionCenterSum")[0].disabled = "disabled" ;
-            $("#hOptionRightSum")[0].disabled = "disabled" ;
-            $("#vOptionUpSum")[0].disabled = "disabled" ;
-            $("#vOptionCenterSum")[0].disabled = "disabled" ;
-            $("#vOptionDownSum")[0].disabled = "disabled" ;
-            $("#rdIsText")[0].disabled = "disabled" ;
-            $("#rdIsField")[0].disabled = "disabled" ;
+            $("#hOptionLeftSum")[0].disabled = "disabled";
+            $("#hOptionCenterSum")[0].disabled = "disabled";
+            $("#hOptionRightSum")[0].disabled = "disabled";
+            $("#vOptionUpSum")[0].disabled = "disabled";
+            $("#vOptionCenterSum")[0].disabled = "disabled";
+            $("#vOptionDownSum")[0].disabled = "disabled";
+            $("#rdIsText")[0].disabled = "disabled";
+            $("#rdIsField")[0].disabled = "disabled";
             $("#eleIsNarrowSumEx")[0].disabled = "disabled";
         }
     },
     private_create_field_node: function (sheet, colWidthArr, rowHeightArr, text, rptTpl) {
         let cellValue = text[`text`].toString().slice(1, -1);
-        let rst = {"Name": cellValue, "Title": '', "FieldID": -1, "font": "GrandTotal", "control": "Column_Right", "style" : "Default_Normal", "isAutoHeight" : false,
-            "area" : {"Left" : 0, "Right" : 100, "Top" : 0, "Bottom" : 100, "H_CalculationType" : "percentage", "V_CalculationType" : "percentage"}
+        let rst = {
+            "Name": cellValue, "Title": '', "FieldID": -1, "font": "GrandTotal", "control": "Column_Right", "style": "Default_Normal", "isAutoHeight": false,
+            "area": { "Left": 0, "Right": 100, "Top": 0, "Bottom": 100, "H_CalculationType": "percentage", "V_CalculationType": "percentage" }
         };
         //1. 设置FieldID
         let hasChkField = false;
@@ -336,6 +336,7 @@ let virtualSummaryOprObj = {
             for (let field of rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS]) {
                 if (field[JV.PROP_NAME] === cellValue) {
                     rst.FieldID = field[JV.PROP_ID];
+                    // field.Name = field.Name + "(" + field[JV.PROP_ID] + ")";
                     rst["Title"] = "ID: " + field[JV.PROP_ID];
                     hasChkField = true;
                     break;
@@ -346,6 +347,7 @@ let virtualSummaryOprObj = {
             for (let field of rptTpl[JV.NODE_NO_MAPPING_FIELDS]) {
                 if (field[JV.PROP_NAME] === cellValue) {
                     rst.FieldID = field[JV.PROP_ID];
+                    // field.Name = field.Name + "(" + field[JV.PROP_ID] + ")";
                     rst["Title"] = "ID: " + field[JV.PROP_ID];
                     hasChkField = true;
                     break;
@@ -364,7 +366,7 @@ let virtualSummaryOprObj = {
 
     applySummaryBack: function () {
         let me = this;
-        let rptTpl = (zTreeOprObj.currentNode)?zTreeOprObj.currentNode.rptTpl:null;
+        let rptTpl = (zTreeOprObj.currentNode) ? zTreeOprObj.currentNode.rptTpl : null;
         if (rptTpl && me.summaryParentNode) {
             let sheet = me.summaryWorkBook.getActiveSheet();
             let rAmt = sheet.getRowCount(), pixH = [0];