Browse Source

过滤新选项

TonyKang 3 years ago
parent
commit
2d5c3f1bb0

+ 9 - 0
modules/ration_repository/controllers/ration_controller.js

@@ -3,6 +3,7 @@
  */
 
 var rationItem = require('../models/ration_item');
+const fs = require("fs");
 import BaseController from "../../common/base/base_controller";
 var callback = function(req, res, err, message, data){
     res.json({error: err, message: message, data: data});
@@ -13,6 +14,14 @@ class RationController extends BaseController{
         try{
             let data = JSON.parse(req.body.data);
             let rationItems = await rationItem.getRationItemsByLib(data.rationLibId, data.showHint, data.returnFields);
+
+            /*
+            let testRationItems = await rationItem.getRationItemsByLib(211);
+            // console.log('testRationItems:');
+            fs.writeFile(`D:/GitHome/ConstructionOperation/tmp/testRationData_${(new Date()).getTime()}.js`, JSON.stringify(testRationItems), { 'flag': 'a' }, function(err){
+                if(err) throw err;
+            });
+            //*/
             callback(req, res, 0, '', rationItems);
         }
         catch(err){

+ 4 - 0
modules/ration_repository/controllers/ration_repository_controller.js

@@ -29,6 +29,10 @@ class RationRepositoryController extends baseController {
         try {
             const data = JSON.parse(req.body.data);
             const rst = await rationItem.prepareInitData(data.rationRepId);
+            // console.log(rst);
+            // fs.writeFile(`D:/GitHome/ConstructionOperation/tmp/testDataResult_${(new Date()).getTime()}.js`, JSON.stringify(rst.sectionTree), { 'flag': 'a' }, function(err){
+            //     if(err) throw err;
+            // });
             res.json({error: 0, message: 'success', data: rst});
         } catch (err) {
             console.log(err);

+ 321 - 0
modules/reports/controllers/adhoc_task_controller.js

@@ -0,0 +1,321 @@
+'use strict';
+
+/**
+ * Created by Tony on 2021/11/3.
+ */
+// const odbc = require('odbc');
+// const odbcdb = new odbc.Database();
+
+const ADODB = require('node-adodb');
+const connection = ADODB.open('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:/GitHome/公路养护支持文件/空白.mdb;');
+const rationItemDAO = require("../../ration_repository/models/ration_item");
+
+module.exports = {
+    createDesktopMdb: async function(req, res) {
+        // console.log('request createDesktopMdb!');
+        // console.log(req);
+        let params = JSON.parse(req.body.params);
+        let compilationId = params.compilationId,
+            rationLibId = params.rationLibId,
+            hasRationTree = params.hasRationTree,
+            hasRation = params.hasRation,
+            hasAssistRation = params.hasAssistRation,
+            hasGLJ = params.hasGLJ,
+            hasCOE = params.hasCOE
+        ;
+        // console.log(params);
+        // let rst = {};
+        if (hasRationTree || hasRation || hasGLJ || hasCOE) {
+            //const rst = await rationItem.prepareInitData(data.rationRepId);
+            let mixData = await rationItemDAO.prepareInitData(rationLibId);
+            let gljCache = {};
+            const prefix = '_'
+
+            if (hasRationTree) {
+                //mixData.sectionTree //定额树
+                // await _addTreeData(mixData.sectionTree);
+            }
+            if (hasRation || hasGLJ) {
+                for (let gljItem of mixData.gljList) {
+                    gljCache[prefix + gljItem.ID] = gljItem;
+                }
+                //mixData.gljList //总工料机
+                // await _addGLJData(mixData.gljList);
+            }
+            if (hasRation || hasCOE) {
+                let rationItems = await rationItemDAO.getRationItemsByLib(rationLibId); //定额
+                await _addRationData(rationItems);
+                // await _addRationGljData(rationItems, gljCache, prefix);
+            }
+        }
+        if (hasAssistRation) {
+            //
+        }
+        res.json({error: 0, message: 'success', data: ''});
+    }
+};
+
+const NODE_ID = "ID", P_ID = "ParentID", NEXT_ID = "NextSiblingID", ADHOC_PRE_ID="Previous_ID", CHILDREN_NODE = "items", SUB_ID = "sub_ids",
+    EMPTY_ID_VAL = -1, TREE_LEVEL = 'treeLevel', TOP_BILL_ID = "topBillID";
+
+let tree_Data_Helper = {
+    buildTreeNodeDirectly: function(data, addLevel) {
+        let topArr = [], rst = [], tmpNodes = {}, prefix = "id_";
+        let private_getStartNode = function (idArr) {
+            let tmpNodeRst = null;
+            for (let i = 0; i < idArr.length; i++) {
+                if (parseInt(tmpNodes[prefix + idArr[i]][ADHOC_PRE_ID]) === EMPTY_ID_VAL) {
+                    tmpNodeRst = tmpNodes[prefix + idArr[i]];
+                    break;
+                }
+            }
+            return tmpNodeRst;
+        };
+        let private_buildNodeData = function(parentItem, idArr, treeLevel, tbID) {
+            let iter = [], nextNode = private_getStartNode(idArr), pushedIds = [];
+            while (nextNode !== null && nextNode !== undefined ) {
+                if (parentItem) {
+                    parentItem[CHILDREN_NODE].push(nextNode);
+                } else {
+                    rst.push(nextNode);
+                }
+                iter.push(nextNode);
+                pushedIds.push(nextNode[NODE_ID]);
+                nextNode[TOP_BILL_ID] = tbID;
+                if (parentItem === null) {
+                    nextNode[TOP_BILL_ID] = nextNode[NODE_ID];
+                    if (nextNode.flags && nextNode.flags.length > 0) {
+                        for (let flag of nextNode.flags) {
+                            if (flag.fieldName === "fixed") {
+                                nextNode[TOP_BILL_ID] = flag.flag;
+                                break;
+                            }
+                        }
+                    }
+                }
+                if (addLevel) nextNode[TREE_LEVEL] = treeLevel;
+                nextNode = tmpNodes[prefix + nextNode[NEXT_ID]];
+                if (nextNode === null || nextNode === undefined) {
+                    //备注: 考虑到实际数据的健壮性,有些节点会掉链子,需要用 parentItem[SUB_ID] 比对已经加上的节点,如发现加上的节点数量不够,那就得在这里补充上去
+                    if (parentItem) {
+                        if (parentItem[SUB_ID].length > iter.length) {
+                            for (let subId of parentItem[SUB_ID]) {
+                                if (pushedIds.indexOf(subId) < 0) {
+                                    let restNode = tmpNodes[prefix + subId];
+                                    if (addLevel) restNode[TREE_LEVEL] = treeLevel;
+                                    restNode[TOP_BILL_ID] = tbID;
+                                    parentItem[CHILDREN_NODE].push(restNode);
+                                    iter.push(restNode);
+                                }
+                            }
+                        }
+                    } else {
+                        if (idArr.length > iter.length) {
+                            for (let topId of idArr) {
+                                if (pushedIds.indexOf(topId) < 0) {
+                                    let restNode = tmpNodes[prefix + topId];
+                                    if (addLevel) restNode[TREE_LEVEL] = treeLevel;
+                                    restNode[TOP_BILL_ID] = restNode[NODE_ID];
+                                    if (restNode.flags && restNode.flags.length > 0) {
+                                        for (let flag of restNode.flags) {
+                                            if (flag.fieldName === "fixed") {
+                                                restNode[TOP_BILL_ID] = flag.flag;
+                                                break;
+                                            }
+                                        }
+                                    }
+                                    rst.push(restNode);
+                                    iter.push(restNode);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            pushedIds = [];
+            for (let i = 0; i < iter.length; i++) {
+                let rtbID = tbID;
+                if (parentItem === null) {
+                    rtbID = iter[i][TOP_BILL_ID];
+                }
+                private_buildNodeData(iter[i], iter[i][SUB_ID], (treeLevel + 1), rtbID);
+            }
+        };
+        //1. 给每个节点设置key, 顺便找Top Node
+        for (let i = 0; i < data.length; i++) {
+            tmpNodes[prefix + data[i][NODE_ID]] = data[i];
+            data[i][ADHOC_PRE_ID] = EMPTY_ID_VAL;
+            data[i][SUB_ID] = [];
+            data[i][CHILDREN_NODE] = [];
+            if (parseInt(data[i][P_ID]) === EMPTY_ID_VAL) {
+                topArr.push(data[i][NODE_ID]);
+            }
+        }
+        //2. 通过key,设置好兄弟/父子关系
+        for (let i = 0; i < data.length; i++) {
+            if (parseInt(data[i][NEXT_ID]) !== EMPTY_ID_VAL) {
+                if (tmpNodes[prefix + data[i][NEXT_ID]] !== undefined){
+                    if (tmpNodes[prefix + data[i][NEXT_ID]][P_ID] === data[i][P_ID]) {
+                        tmpNodes[prefix + data[i][NEXT_ID]][ADHOC_PRE_ID] = data[i][NODE_ID];
+                    } else {
+                        tmpNodes[prefix + data[i][NEXT_ID]][ADHOC_PRE_ID] = EMPTY_ID_VAL;
+                        data[i][NEXT_ID] = EMPTY_ID_VAL;
+                    }
+                }
+            }
+            if (parseInt(data[i][P_ID]) !== EMPTY_ID_VAL) {
+                tmpNodes[prefix + data[i][P_ID]][SUB_ID].push(data[i][NODE_ID]);
+            }
+        }
+        //3. 开build
+        private_buildNodeData(null, topArr, 0, -1);
+        //try to release and return
+        tmpNodes = null;
+        topArr.length = 0;
+        return rst;
+    },
+
+    getFlatArray: function (srcArr, destArr) {
+        let private_put = function (parentItem) {
+            destArr.push(parentItem);
+            if (parentItem.items) {
+                for (let subItem of parentItem.items) {
+                    private_put(subItem);
+                }
+            }
+        }
+        for (let node of srcArr) {
+            private_put(node);
+        }
+        for (let item of destArr) {
+            delete item[CHILDREN_NODE];
+            delete item[SUB_ID];
+            delete item[ADHOC_PRE_ID];
+        }
+    }
+};
+
+async function _addRationGljData(rationItemArr, gljCache, prefix) {
+    console.log('start Ration GLJ!');
+    // console.log(`Ration GLJ total amount: ${rationGljArr.length}`);
+    for (let idx = 0; idx < rationItemArr.length; idx++) {
+        let rationItem = rationItemArr[idx];
+        for (let rgljItem of rationItem.rationGljList) {
+            if (parseFloat(rgljItem.consumeAmt) > 0) {
+                let fieldStr = 'RationID, GLJID, Amount, Proportion, Type';
+                let valueStr = `${rationItem.ID}, ${rgljItem.gljId}, ${rgljItem.consumeAmt}, ${(rgljItem.proportion !== undefined)?rgljItem.proportion:0}, ${gljCache[prefix + rgljItem.gljId].gljType}`;
+                let sqlStr = `INSERT INTO Ration_GLJ(${fieldStr}) VALUES (${valueStr})`;
+                try {
+                    // console.log(`executing SQL: ${sqlStr}`);
+                    await connection.execute(sqlStr);
+                } catch(ex) {
+                    console.log(`execute SQL with error: ${sqlStr}`);
+                }
+            }
+        }
+    }
+    console.log('end Ration GLJ!');
+}
+
+async function _addRationData(rationItemArr) {
+    console.log('start Ration!');
+    console.log(`Ration total amount: ${rationItemArr.length}`);
+    for (let idx = 0; idx < rationItemArr.length; idx++) {
+        let item = rationItemArr[idx];
+        let fieldStr = 'ID, IDCode, Code, Name, Unit, BasePrice, SectionID, Caption, FeeType, Name2, Unit2, UUID';
+        let valueStr = `${item.ID}, ${_getIDCode(item.code)}, '${item.code}', '${item.name}', '${item.unit}', ${item.basePrice}, ${item.sectionId}, '${item.caption}', ${item.feeType}, '', '', '' `;
+        let sqlStr = `INSERT INTO RationItems(${fieldStr}) VALUES (${valueStr})`;
+        try {
+            // console.log(`executing SQL: ${sqlStr}`);
+            await connection.execute(sqlStr);
+        } catch(ex) {
+            console.log(`execute SQL with error: ${sqlStr}`);
+        }
+    }
+    console.log('end Ration!');
+}
+
+async function _addGLJData(gljItemArr) {
+    console.log('start GLJ!');
+    console.log(`GLJ total amount: ${gljItemArr.length}`);
+    for (let idx = 0; idx < gljItemArr.length; idx++) {
+        let item = gljItemArr[idx];
+        let fieldStr = 'ID, Code, Name, Specs, Unit, BasePrice, Main, New, Type, DetailType, ShortName, Name2, Unit2, SortParam, CalculateType, UUID, 字段1, 字段2';
+        let valueStr = `${item.ID}, '${item.code}', '${item.name}', '${item.specs}', '${item.unit}', ${(item.basePrice !== undefined)?item.basePrice:0}, 0, 0, ${item.gljType}, ${item.gljClass}, '${item.shortName}', '', '', '', '', '', '', ''`;
+        let sqlStr = `INSERT INTO GLJList(${fieldStr}) VALUES (${valueStr})`;
+        try {
+            // console.log(`executing SQL: ${sqlStr}`);
+            await connection.execute(sqlStr);
+        } catch(ex) {
+            console.log(`execute SQL with error: ${sqlStr}`);
+        }
+    }
+    console.log('end GLJ!');
+}
+
+async function _addTreeData(treeDataArr) {
+    console.log('start tree!');
+    console.log(`GLJ total amount: ${treeDataArr.length}`);
+    let tmpTreeArr = tree_Data_Helper.buildTreeNodeDirectly(treeDataArr, true);
+    for (let idx = 0; idx < tmpTreeArr[0].items.length; idx++) {
+        _setChapterLevel(tmpTreeArr[0].items[idx], idx + 1);
+    }
+    let sectionTreeArr = [];
+    tree_Data_Helper.getFlatArray(tmpTreeArr, sectionTreeArr);
+    for (let sectionNode of sectionTreeArr) {
+        let fieldStr = 'ID, ParentID, NextSiblingID, Name, Code, FullCode, Name2';
+        let valueStr = `${sectionNode.ID},${sectionNode.ParentID},${sectionNode.NextSiblingID},'${sectionNode.name}',${sectionNode.chapterLv === undefined?-1:sectionNode.chapterLv},'',''`;
+        let sqlStr = `INSERT INTO RationTree(${fieldStr}) VALUES (${valueStr})`;
+        try {
+            // console.log(`executing SQL: ${sqlStr}`);
+            await connection.execute(sqlStr);
+        } catch(ex) {
+            console.log(`execute SQL with error: ${sqlStr}`);
+        }
+    }
+    console.log('end tree!');
+}
+
+function _setChapterLevel(chapterNode, cLv) {
+    chapterNode.chapterLv = cLv;
+    if (chapterNode.items && chapterNode.items.length > 0) {
+        for (let subNode of chapterNode.items) {
+            _setChapterLevel(subNode, cLv);
+        }
+    }
+}
+
+function _getIDCode(code) {
+    let rst = '';
+    if (code !== null && code !== undefined) {
+        let codes = code.split('-');
+        if (codes.length === 3) {
+            let suppls = ['', '', ''];
+
+            let regExp = new RegExp('D', "gm");
+            codes[0] = codes[0].replace(regExp, '');
+
+            if (codes[0].length < 2) {
+                for (let idx = codes[0].length; idx < 2; idx++) {
+                    suppls[0] = suppls[0] + '0';
+                }
+            }
+            if (codes[1].length < 2) {
+                for (let idx = codes[1].length; idx < 2; idx++) {
+                    suppls[1] = suppls[1] + '0';
+                }
+            }
+            if (codes[2].length < 3) {
+                for (let idx = codes[2].length; idx < 3; idx++) {
+                    suppls[2] = suppls[2] + '0';
+                }
+            }
+            for (let si = 0; si < codes.length; si++) {
+                rst += (suppls[si] + codes[si]);
+            }
+        } else {
+            //
+        }
+    }
+    return rst;
+}

+ 22 - 1
modules/reports/routes/report_router_operation.js

@@ -4,8 +4,11 @@
 
 import express from "express";
 let rptRouter = express.Router();
-import reportController from "../controllers/rpt_controller_operation";
+// import reportController from "../controllers/rpt_controller_operation";
+let adHocController = require("../controllers/adhoc_task_controller");
 
+// 完成历史任务,屏蔽
+/*
 module.exports =function (app) {
     app.get('/report',  function(req, res) {
         if (!req.session.managerData.username) {
@@ -32,3 +35,21 @@ module.exports =function (app) {
 
     app.use("/report_api", rptRouter);
 };
+//*/
+
+module.exports = function (app) {
+    app.get('/outputDataForDesktopVersion',  function(req, res) {
+        if (!req.session.managerData.username) {
+            res.redirect('/login');
+        }
+        else {
+            res.render('maintain/report/html/adhoc_task.html',
+                {userAccount: req.session.userAccount,
+                    userID: req.session.managerData.userID});
+        }
+    });
+
+    rptRouter.post('/createDesktopMdb', adHocController.createDesktopMdb);
+
+    app.use("/adHoc_report_api", rptRouter);
+};

+ 42 - 0
test/unit/exportData/exportGLJItem.js

@@ -0,0 +1,42 @@
+/**
+ * Created by Tony on 2021/10/6.
+ */
+
+let fs = require('fs');
+
+// let data = fs.readFileSync('D:/GitHome/ConstructionOperation/tmp/testGLJData.js');
+
+// let mixedData = fs.readFileSync('D:/GitHome/YangHuOperation/tmp/testDataResult_广西公路日常养护预算指标(2021).js');
+let mixedData = fs.readFileSync('D:/GitHome/YangHuOperation/tmp/testDataResult_广西公路养护预算定额(2021).js');
+let data = JSON.parse(mixedData);
+let gljItemArr = data.gljList;
+
+//----------------------------------------
+
+// let gljItemArr = JSON.parse(data);
+
+// console.log(gljItemArr);
+
+let newData = [];
+let firstStr = 'ID\tCode\tName\tSpecs\tUnit\tBasePrice\tMain\tNew\tType\tDetailType\tShortName\tName2\tUnit2\tSortParam\tCalculateType\tUUID\t字段1\t字段2';
+newData.push(firstStr);
+
+for (let item of gljItemArr) {
+
+    let str = `${item.ID}\t${item.code}\t${item.name}\t${item.specs}\t${item.unit}\t${(item.basePrice !== undefined)?item.basePrice:0}\t0\t0\t${item.gljType}\t${item.gljClass}\t${item.shortName}\t\t\t\t\t\t\t\t`;
+
+    newData.push(str);
+}
+
+let ttlStr = newData.join('\n');
+
+let regExp = new RegExp('"', "gm");
+ttlStr = ttlStr.replace(regExp, '');
+let regExp1 = new RegExp('null', "gm");
+ttlStr = ttlStr.replace(regExp1, '');
+
+fs.writeFile(`D:/GitHome/YangHuOperation/tmp/工料机临时Data文件_${(new Date()).getTime()}.txt`, ttlStr, { 'flag': 'a', 'encoding': 'utf-8' }, function(err){
+    if(err) throw err;
+});
+
+

+ 168 - 0
test/unit/exportData/exportRationCoe.js

@@ -0,0 +1,168 @@
+/**
+ * Created by Tony on 2021/10/8.
+ */
+
+let fs = require('fs');
+
+let data1 = fs.readFileSync('D:/GitHome/ConstructionOperation/tmp/testRationData_1633514079281.js');
+let data2 = fs.readFileSync('D:/GitHome/ConstructionOperation/tmp/testRationCoeData.js');
+let data3 = fs.readFileSync('D:/GitHome/ConstructionOperation/tmp/testGLJData.js');
+
+//----------------------------------------
+
+let rationItemArr = JSON.parse(data1);
+let coeItemArr = JSON.parse(data2);
+let gljItemArr = JSON.parse(data3);
+
+let gljCache = {};
+let coeCache = {};
+const prefix = '_'
+
+for (let gljItem of gljItemArr) {
+    gljCache[prefix + gljItem.code] = gljItem;
+}
+
+
+for (let gljItem of coeItemArr) {
+    coeCache[prefix + gljItem.ID] = gljItem;
+}
+
+let newData = [];
+
+// 先测量最多有多少coes
+let maxCoes = 0;
+let fixedCoes = [];
+for (let idx = 0; idx < coeItemArr.length; idx++) {
+    let item = coeItemArr[idx];
+    let dtlMax = 0;
+    let dtlFixedCoes = [];
+    for (let coe of item.coes) {
+        if (coe.coeType !== '人工' && coe.coeType !== '机械' && coe.coeType !== '材料' && coe.coeType !== '定额') {
+            dtlMax++;
+        } else {
+            dtlFixedCoes.push(coe);
+        }
+    }
+    fixedCoes.push(dtlFixedCoes);
+    maxCoes = Math.max(dtlMax, maxCoes);
+}
+
+let firstStr = 'ID|Name|Type|Content|G|L|J';
+//for (let idx = 0; idx < maxCoes - 1; idx++) {
+for (let idx = 1; idx <= 10; idx++) {
+    let str = '';
+    str = `|GLJ${idx}|Count${idx}|Type${idx}`;
+    firstStr += str;
+};
+newData.push(firstStr);
+
+function _getAmountByCoeType(coeObjs, coeItem) {
+    let rst = [];
+    let coeG = 0, coeL = 0, coeJ = 0;
+    for (let coeObj of coeObjs) {
+        switch (coeObj.coeType) {
+            case '定额':
+                coeG = coeObj.amount;
+                coeL = coeObj.amount;
+                coeJ = coeObj.amount;
+                break;
+            case '人工' :
+                coeG = coeObj.amount;
+                break;
+            case '单个工料机' :
+                let gcKey = prefix + coeObj.gljCode;
+                if (!gljCache.hasOwnProperty(gcKey)) {
+                    console.log('code1: ' + ' - ' + coeItem.ID + ' - ' + coeObj.coeType);
+                } else {
+                    if (gljCache[gcKey].gljType > 200 && gljCache[gcKey].gljType < 300) {
+                        coeL = coeObj.amount;
+                    } else if (gljCache[gcKey].gljType > 300 && gljCache[gcKey].gljType < 400) {
+                        coeJ = coeObj.amount;
+                    } else if (gljCache[gcKey].gljType <= 2) {
+                        coeG = coeObj.amount;
+                    } else {
+                        console.log('不明材料1: ' + ' - ' + gcKey + ' - ' + gljCache[gcKey].gljType);
+                    }
+                }
+                break;
+            case '机械' :
+                coeJ = coeObj.amount;
+                break;
+            case '材料' :
+                coeL = coeObj.amount;
+                break;
+            default :
+                console.log('不明coeType1: ' + ' - ' + coeObj.coeType);
+                break;
+        }
+    }
+    rst.push(coeG);
+    rst.push(coeL);
+    rst.push(coeJ);
+    return rst;
+}
+
+// 先输出coe list
+for (let idx = 0; idx < coeItemArr.length; idx++) {
+    let coeItem = coeItemArr[idx];
+    // coeCache[prefix + gljItem.ID] = gljItem;
+    let firstCoe = coeItem.coes[0];
+    let firstCoeType = firstCoe.operator;
+    let cRst =_getAmountByCoeType(fixedCoes[idx], coeItem);
+    let firstCoeG = cRst[0];
+    let firstCoeL = cRst[1];
+    let firstCoeJ = cRst[2];
+    let str = `${coeItem.ID}|${coeItem.name}|${firstCoeType}|${coeItem.content}|${firstCoeG}|${firstCoeL}|${firstCoeJ}`;
+
+    /*
+    for (let idx = 0; idx < maxCoes - 1; idx++) {
+        if (idx < coeItem.coes.length - 1) {
+            // 判断coeItem.coes[idx+1].gljCode,有一下几种情况:udefined, 空串, 其他正常值
+            let dtlRst =_getAmountByCoeType(coeItem.coes[idx+1], coeItem);
+            if (coeItem.coes[idx+1].gljCode === undefined || coeItem.coes[idx+1].gljCode === '') {
+                // str += `,${gljCache[gcKey].ID},${coeItem.coes[idx+1].amount},${coeItem.coes[idx+1].operator}`;
+                console.log('不明额外coeType2: ' + ' - ' + coeItem.ID + coeItem.coes[idx+1].coeType);
+                str += `,-1,${coeItem.coes[idx+1].amount},${coeItem.coes[idx+1].operator}`;
+            } else {
+                //正常值
+                let gcKey = prefix + coeItem.coes[idx+1].gljCode;
+                if (!gljCache.hasOwnProperty(gcKey)) {
+                    console.log('code2: ' + coeItem.ID + ' - ' + gcKey);
+                }
+                str += `,${gljCache[gcKey].ID},${coeItem.coes[idx+1].amount},${coeItem.coes[idx+1].operator}`;
+            }
+        } else {
+            str += ',,,';
+        }
+    }
+    */
+    for (let idx = 1; idx <= 10; idx++) {
+        str += '|||';
+    }
+    newData.push(str);
+}
+let ttlStr = newData.join('\n');
+
+let regExp = new RegExp('"', "gm");
+ttlStr = ttlStr.replace(regExp, '');
+// fs.writeFile(`D:/GitHome/ConstructionOperation/tmp/子目换算List文件_${(new Date()).getTime()}.txt`, ttlStr, { 'flag': 'a', 'encoding': 'utf-8' }, function(err){
+//     if(err) throw err;
+// });
+
+// 再输出ration - coe
+firstStr = 'SectionID|RationID|CoeID|Order|GroupIdx|Param';
+newData = [];
+newData.push(firstStr);
+for (let item of rationItemArr) {
+    for (let coeItem of item.rationCoeList) {
+        let str = `${item.sectionId}|${item.ID}|${coeItem.ID}|${coeItem.no}||`;
+        newData.push(str);
+    }
+}
+ttlStr = newData.join('\n');
+ttlStr = ttlStr.replace(regExp, '');
+
+fs.writeFile(`D:/GitHome/ConstructionOperation/tmp/定额_子目换算Data文件_${(new Date()).getTime()}.txt`, ttlStr, { 'flag': 'a', 'encoding': 'utf-8' }, function(err){
+    if(err) throw err;
+});
+

+ 62 - 0
test/unit/exportData/exportRationGLJ.js

@@ -0,0 +1,62 @@
+/**
+ * Created by Tony on 2021/10/8.
+ */
+
+let fs = require('fs');
+
+// let data1 = fs.readFileSync('D:/GitHome/ConstructionOperation/tmp/testRationData_1633514079281.js');
+// let data2 = fs.readFileSync('D:/GitHome/ConstructionOperation/tmp/testGLJData.js');
+
+// let mixedData = fs.readFileSync('D:/GitHome/YangHuOperation/tmp/testDataResult_广西公路日常养护预算指标(2021).js');
+let mixedData = fs.readFileSync('D:/GitHome/YangHuOperation/tmp/testDataResult_广西公路养护预算定额(2021).js');
+let data = JSON.parse(mixedData);
+let gljItemArr = data.gljList;
+
+// let data1 = fs.readFileSync('D:/GitHome/YangHuOperation/tmp/testRationData_广西公路日常养护预算指标(2021).js');
+let data1 = fs.readFileSync('D:/GitHome/YangHuOperation/tmp/testRationData_广西公路养护预算定额(2021).js');
+let rationItemArr = JSON.parse(data1);
+
+//----------------------------------------
+
+// let rationItemArr = JSON.parse(data1);
+// let gljItemArr = JSON.parse(data2);
+
+let gljCache = {};
+const prefix = '_'
+
+let pmKeysCache = {};
+
+for (let gljItem of gljItemArr) {
+    gljCache[prefix + gljItem.ID] = gljItem;
+}
+
+let newData = [];
+let firstStr = 'RationID|GLJID|Amount|Proportion|Type';
+newData.push(firstStr);
+
+for (let item of rationItemArr) {
+
+    for (let rgljItem of item.rationGljList) {
+        if (parseFloat(rgljItem.consumeAmt) > 0) {
+            let str = `${item.ID}|${rgljItem.gljId}|${rgljItem.consumeAmt}|${(rgljItem.proportion !== undefined)?rgljItem.proportion:0}|${gljCache[prefix + rgljItem.gljId].gljType}`;
+            // if (pmKeysCache.hasOwnProperty(item.ID + prefix + rgljItem.gljId)) {
+            //     pmKeysCache[item.ID + prefix + rgljItem.gljId]++;
+            //     console.log('dup key: ' + (item.ID + prefix + rgljItem.gljId));
+            // } else {
+            //     pmKeysCache[item.ID + prefix + rgljItem.gljId] = 1;
+            // }
+            newData.push(str);
+        }
+    }
+}
+
+let ttlStr = newData.join('\n');
+
+let regExp = new RegExp('"', "gm");
+ttlStr = ttlStr.replace(regExp, '');
+
+fs.writeFile(`D:/GitHome/YangHuOperation/tmp/定额工料机Data文件_${(new Date()).getTime()}.txt`, ttlStr, { 'flag': 'a', 'encoding': 'utf-8' }, function(err){
+    if(err) throw err;
+});
+
+

+ 80 - 0
test/unit/exportData/exportRationItems.js

@@ -0,0 +1,80 @@
+/**
+ * Created by Tony on 2021/10/6.
+ */
+
+// testRationData_1633422499669.js
+
+let fs = require('fs');
+
+// let data = fs.readFileSync('D:/GitHome/ConstructionOperation/tmp/testRationData_1633514079281.js');
+// let data = fs.readFileSync('D:/GitHome/YangHuOperation/tmp/testRationData_广西公路日常养护预算指标(2021).js');
+let data = fs.readFileSync('D:/GitHome/YangHuOperation/tmp/testRationData_广西公路养护预算定额(2021).js');
+
+//----------------------------------------
+
+let rationItemArr = JSON.parse(data);
+
+// console.log(rationItemArr);
+
+function _getIDCode(code) {
+    let rst = '';
+    if (code !== null && code !== undefined) {
+        let codes = code.split('-');
+        if (codes.length === 3) {
+            let suppls = ['', '', ''];
+
+            let regExp = new RegExp('D', "gm");
+            codes[0] = codes[0].replace(regExp, '');
+
+            if (codes[0].length < 2) {
+                for (let idx = codes[0].length; idx < 2; idx++) {
+                    suppls[0] = suppls[0] + '0';
+                }
+            }
+            if (codes[1].length < 2) {
+                for (let idx = codes[1].length; idx < 2; idx++) {
+                    suppls[1] = suppls[1] + '0';
+                }
+            }
+            if (codes[2].length < 3) {
+                for (let idx = codes[2].length; idx < 3; idx++) {
+                    suppls[2] = suppls[2] + '0';
+                }
+            }
+            for (let si = 0; si < codes.length; si++) {
+                rst += (suppls[si] + codes[si]);
+            }
+        } else {
+            //
+        }
+    }
+    return rst;
+}
+
+let newSectionData = [];
+let firstStr = 'ID|IDCode|Code|Name|Unit|BasePrice|SectionID|Caption|FeeType|Name2|Unit2|UUID,';
+newSectionData.push(firstStr);
+
+for (let item of rationItemArr) {
+
+    let str = `${item.ID}|${_getIDCode(item.code)}|${item.code}|${item.name}|${item.unit}|${item.basePrice}|${item.sectionId}|${item.caption}|${item.feeType}||||`;
+
+    newSectionData.push(str);
+}
+
+// let ttlSQL = JSON.stringify(newSectionData);
+// let ttlSQL = newSectionData.join('');
+let ttlSQL = newSectionData.join('\n');
+
+let regExp = new RegExp('"', "gm");
+ttlSQL = ttlSQL.replace(regExp, '');
+// ttlSQL.replace()
+
+//fs.writeFile(`D:/GitHome/ConstructionOperation/tmp/章节树临时Data文件_${(new Date()).getTime()}.js`, ttlSQL, { 'flag': 'a', 'encoding': 'utf-8' }, function(err){
+// fs.writeFile(`D:/GitHome/ConstructionOperation/tmp/定额临时Data文件_${(new Date()).getTime()}.txt`, ttlSQL, { 'flag': 'a', 'encoding': 'utf-8' }, function(err){
+fs.writeFile(`D:/GitHome/YangHuOperation/tmp/定额临时Data文件_${(new Date()).getTime()}.txt`, ttlSQL, { 'flag': 'a', 'encoding': 'utf-8' }, function(err){
+    if(err) throw err;
+});
+
+// */
+

+ 212 - 0
test/unit/exportData/exportRationSectionTree.js

@@ -0,0 +1,212 @@
+/**
+ * Created by Tony on 2021/10/6.
+ */
+
+let fs = require('fs');
+
+// let data = fs.readFileSync('D:/GitHome/ConstructionOperation/tmp/testDataResultSectionData_1633407022828.js');
+
+// let data = fs.readFileSync('D:/GitHome/YangHuOperation/tmp/testDataResult_SectionTree_广西公路日常养护预算指标(2021).js');
+let data = fs.readFileSync('D:/GitHome/YangHuOperation/tmp/testDataResult_SectionTree_广西公路养护预算定额(2021).js');
+
+//----------------------------------------
+
+const NODE_ID = "ID", P_ID = "ParentID", NEXT_ID = "NextSiblingID", ADHOC_PRE_ID="Previous_ID", CHILDREN_NODE = "items", SUB_ID = "sub_ids",
+    EMPTY_ID_VAL = -1, TREE_LEVEL = 'treeLevel', TOP_BILL_ID = "topBillID";
+
+let tree_Data_Helper = {
+    buildTreeNodeDirectly: function(data, addLevel) {
+        let topArr = [], rst = [], tmpNodes = {}, prefix = "id_";
+        let private_getStartNode = function (idArr) {
+            let tmpNodeRst = null;
+            for (let i = 0; i < idArr.length; i++) {
+                if (parseInt(tmpNodes[prefix + idArr[i]][ADHOC_PRE_ID]) === EMPTY_ID_VAL) {
+                    tmpNodeRst = tmpNodes[prefix + idArr[i]];
+                    break;
+                }
+            }
+            return tmpNodeRst;
+        };
+        let private_buildNodeData = function(parentItem, idArr, treeLevel, tbID) {
+            let iter = [], nextNode = private_getStartNode(idArr), pushedIds = [];
+            while (nextNode !== null && nextNode !== undefined ) {
+                if (parentItem) {
+                    parentItem[CHILDREN_NODE].push(nextNode);
+                } else {
+                    rst.push(nextNode);
+                }
+                iter.push(nextNode);
+                pushedIds.push(nextNode[NODE_ID]);
+                nextNode[TOP_BILL_ID] = tbID;
+                if (parentItem === null) {
+                    nextNode[TOP_BILL_ID] = nextNode[NODE_ID];
+                    if (nextNode.flags && nextNode.flags.length > 0) {
+                        for (let flag of nextNode.flags) {
+                            if (flag.fieldName === "fixed") {
+                                nextNode[TOP_BILL_ID] = flag.flag;
+                                break;
+                            }
+                        }
+                    }
+                }
+                if (addLevel) nextNode[TREE_LEVEL] = treeLevel;
+                nextNode = tmpNodes[prefix + nextNode[NEXT_ID]];
+                if (nextNode === null || nextNode === undefined) {
+                    //备注: 考虑到实际数据的健壮性,有些节点会掉链子,需要用 parentItem[SUB_ID] 比对已经加上的节点,如发现加上的节点数量不够,那就得在这里补充上去
+                    if (parentItem) {
+                        if (parentItem[SUB_ID].length > iter.length) {
+                            for (let subId of parentItem[SUB_ID]) {
+                                if (pushedIds.indexOf(subId) < 0) {
+                                    let restNode = tmpNodes[prefix + subId];
+                                    if (addLevel) restNode[TREE_LEVEL] = treeLevel;
+                                    restNode[TOP_BILL_ID] = tbID;
+                                    parentItem[CHILDREN_NODE].push(restNode);
+                                    iter.push(restNode);
+                                }
+                            }
+                        }
+                    } else {
+                        if (idArr.length > iter.length) {
+                            for (let topId of idArr) {
+                                if (pushedIds.indexOf(topId) < 0) {
+                                    let restNode = tmpNodes[prefix + topId];
+                                    if (addLevel) restNode[TREE_LEVEL] = treeLevel;
+                                    restNode[TOP_BILL_ID] = restNode[NODE_ID];
+                                    if (restNode.flags && restNode.flags.length > 0) {
+                                        for (let flag of restNode.flags) {
+                                            if (flag.fieldName === "fixed") {
+                                                restNode[TOP_BILL_ID] = flag.flag;
+                                                break;
+                                            }
+                                        }
+                                    }
+                                    rst.push(restNode);
+                                    iter.push(restNode);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            pushedIds = [];
+            for (let i = 0; i < iter.length; i++) {
+                let rtbID = tbID;
+                if (parentItem === null) {
+                    rtbID = iter[i][TOP_BILL_ID];
+                }
+                private_buildNodeData(iter[i], iter[i][SUB_ID], (treeLevel + 1), rtbID);
+            }
+        };
+        //1. 给每个节点设置key, 顺便找Top Node
+        for (let i = 0; i < data.length; i++) {
+            tmpNodes[prefix + data[i][NODE_ID]] = data[i];
+            data[i][ADHOC_PRE_ID] = EMPTY_ID_VAL;
+            data[i][SUB_ID] = [];
+            data[i][CHILDREN_NODE] = [];
+            if (parseInt(data[i][P_ID]) === EMPTY_ID_VAL) {
+                topArr.push(data[i][NODE_ID]);
+            }
+        }
+        //2. 通过key,设置好兄弟/父子关系
+        for (let i = 0; i < data.length; i++) {
+            if (parseInt(data[i][NEXT_ID]) !== EMPTY_ID_VAL) {
+                if (tmpNodes[prefix + data[i][NEXT_ID]] !== undefined){
+                    if (tmpNodes[prefix + data[i][NEXT_ID]][P_ID] === data[i][P_ID]) {
+                        tmpNodes[prefix + data[i][NEXT_ID]][ADHOC_PRE_ID] = data[i][NODE_ID];
+                    } else {
+                        tmpNodes[prefix + data[i][NEXT_ID]][ADHOC_PRE_ID] = EMPTY_ID_VAL;
+                        data[i][NEXT_ID] = EMPTY_ID_VAL;
+                    }
+                }
+            }
+            if (parseInt(data[i][P_ID]) !== EMPTY_ID_VAL) {
+                tmpNodes[prefix + data[i][P_ID]][SUB_ID].push(data[i][NODE_ID]);
+            }
+        }
+        //3. 开build
+        private_buildNodeData(null, topArr, 0, -1);
+        //try to release and return
+        tmpNodes = null;
+        topArr.length = 0;
+        return rst;
+    },
+
+    getFlatArray: function (srcArr, destArr) {
+        let private_put = function (parentItem) {
+            destArr.push(parentItem);
+            if (parentItem.items) {
+                for (let subItem of parentItem.items) {
+                    private_put(subItem);
+                }
+            }
+        }
+        for (let node of srcArr) {
+            private_put(node);
+        }
+        for (let item of destArr) {
+            delete item[CHILDREN_NODE];
+            delete item[SUB_ID];
+            delete item[ADHOC_PRE_ID];
+        }
+    }
+};
+
+
+let tmpTreeArr = tree_Data_Helper.buildTreeNodeDirectly(JSON.parse(data), true);
+
+function _setChapterLevel(chapterNode, cLv) {
+    chapterNode.chapterLv = cLv;
+    if (chapterNode.items && chapterNode.items.length > 0) {
+        for (let subNode of chapterNode.items) {
+            _setChapterLevel(subNode, cLv);
+        }
+    }
+}
+
+for (let idx = 0; idx < tmpTreeArr[0].items.length; idx++) {
+    _setChapterLevel(tmpTreeArr[0].items[idx], idx + 1);
+}
+// console.log(tmpTreeArr);
+
+let sectionTreeArr = [];
+tree_Data_Helper.getFlatArray(tmpTreeArr, sectionTreeArr);
+sectionTreeArr.splice(0,1);
+
+// console.log(sectionTreeArr);
+
+let newSectionData = [];
+let firstStr = 'ID,ParentID,NextSiblingID,Name,Code,FullCode,Name2';
+newSectionData.push(firstStr);
+for (let sectionNode of sectionTreeArr) {
+    // let node = [];
+    // node.push(sectionNode.ID);
+    // node.push(sectionNode.ParentID);
+    // node.push(sectionNode.NextSiblingID);
+    // node.push(sectionNode.name);
+    // node.push(sectionNode.chapterLv);
+    // node.push(''); //full code
+    // node.push(''); //name2
+
+    // let str = `INSERT INTO RationTree Values(${sectionNode.ID}, ${sectionNode.ParentID}, ${sectionNode.NextSiblingID}, '${sectionNode.name}', ${sectionNode.chapterLv === undefined?-1:sectionNode.chapterLv}, NULL, NULL );`
+    // let str = `${sectionNode.ID},${sectionNode.ParentID},${sectionNode.NextSiblingID},'${sectionNode.name}',${sectionNode.chapterLv === undefined?-1:sectionNode.chapterLv},'',''`
+    let str = `${sectionNode.ID},${sectionNode.ParentID},${sectionNode.NextSiblingID},${sectionNode.name},${sectionNode.chapterLv === undefined?-1:sectionNode.chapterLv},,,`
+
+    newSectionData.push(str);
+}
+
+// let ttlSQL = JSON.stringify(newSectionData);
+// let ttlSQL = newSectionData.join('');
+let ttlSQL = newSectionData.join('\n');
+
+let regExp = new RegExp('"', "gm");
+ttlSQL = ttlSQL.replace(regExp, '');
+// ttlSQL.replace()
+
+//fs.writeFile(`D:/GitHome/ConstructionOperation/tmp/章节树临时Data文件_${(new Date()).getTime()}.js`, ttlSQL, { 'flag': 'a', 'encoding': 'utf-8' }, function(err){
+// fs.writeFile(`D:/GitHome/ConstructionOperation/tmp/章节树临时Data文件_${(new Date()).getTime()}.txt`, ttlSQL, { 'flag': 'a', 'encoding': 'utf-8' }, function(err){
+fs.writeFile(`D:/GitHome/YangHuOperation/tmp/章节树临时Data文件_${(new Date()).getTime()}.txt`, ttlSQL, { 'flag': 'a', 'encoding': 'utf-8' }, function(err){
+    if(err) throw err;
+});
+
+// */
+

+ 1 - 0
web/maintain/ration_repository/js/coe.js

@@ -542,6 +542,7 @@ let coeOprObj = {
                 if(!result.error){
                     me.currentCoeList = result.data;
                     me.sortCoeList(me.currentCoeList);
+                    // console.log(me.currentCoeList);
                     me.currentMaxNo =  me.currentCoeList.length > 0 ? me.currentCoeList[me.currentCoeList.length - 1].serialNo : 0;
                     pageObj.showData(me.workSheet, me.setting, me.currentCoeList);
                     me.workSheet.clearSelection();

+ 124 - 0
web/maintain/report/html/adhoc_task.html

@@ -0,0 +1,124 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta http-equiv="x-ua-compatible" content="ie=edge">
+    <title>WEB导本地ACCESS库</title>
+    <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css">
+    <link rel="stylesheet" href="/web/maintain/report/css/main.css">
+    <link rel="stylesheet" href="/lib/font-awesome/font-awesome.min.css">
+    <link rel="stylesheet" href="/lib/font-zy/iconfont.css">
+    <script>
+        // 这里的变量供页面调用
+        let userAccount = '<%- userAccount %>';
+        let userID = '<%- userID %>';
+    </script>
+</head>
+
+<body>
+<div class="header">
+    <nav class="navbar navbar-toggleable-lg navbar-light bg-faded p-0 ">
+        <span class="header-logo px-2">Smartcost</span>
+        <div class="navbar-text"><a>额外导出</a> > <a id="rpt_tpl_display_label">...</a></div>
+    </nav>
+    <nav class="navbar navbar-toggleable-lg justify-content-between navbar-light p-0">
+        <div>
+            <ul class="nav nav-tabs" role="tablist">
+                <li class="nav-item">
+                    <a class="nav-link px-3" ><select class="form-control form-control-sm" id="compilations" onchange="adHocTaskObj.changeCompilation(this)"></select></a>
+                </li>
+                <li class="nav-item">
+                    <a class="nav-link px-3" ><select class="form-control form-control-sm" id="rations" onchange="adHocTaskObj.changeRationRepository(this)"></select></a>
+                </li>
+            </ul>
+        </div>
+        <!--
+        -->
+    </nav>
+</div>
+<div class="main">
+    <div class="content">
+        <div class="container-fluid">
+            <div class="row">
+                <div class="form-group col-md-12">
+                    <div class="form-check">
+                        <label class="form-check-label">
+                            <input type="checkbox" class="form-check-input" id="eleRationTree" checked>
+                            导出定额章节树
+                        </label>
+                    </div>
+                </div>
+                <div class="form-group col-md-12">
+                    <div class="form-check">
+                        <label class="form-check-label">
+                            <input type="checkbox" class="form-check-input" id="eleRationItems" checked>
+                            导出定额
+                        </label>
+                    </div>
+                </div>
+                <div class="form-group col-md-12">
+                    <div class="form-check">
+                        <label class="form-check-label">
+                            <input type="checkbox" class="form-check-input" id="eleAssistRationItems" checked>
+                            导出辅助定额
+                        </label>
+                    </div>
+                </div>
+                <div class="form-group col-md-12">
+                    <div class="form-check">
+                        <label class="form-check-label">
+                            <input type="checkbox" class="form-check-input" id="eleAllGLJ" checked>
+                            导出工料机
+                        </label>
+                    </div>
+                </div>
+                <div class="form-group col-md-12">
+                    <div class="form-check">
+                        <label class="form-check-label">
+                            <input type="checkbox" class="form-check-input" id="eleCOE" disabled>
+                            导出COE
+                        </label>
+                    </div>
+                </div>
+                <div class="tab-bar">
+                    <a onclick="adHocTaskObj.createDesktopMdb()" class="btn btn-secondary fa fa-plus-square">数据转换</a>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+<script src="/lib/jquery/jquery.min.js"></script>
+<script src="/lib/tether/tether.min.js"></script>
+<script src="/lib/bootstrap/bootstrap.min.js"></script>
+
+<script src="/web/maintain/report/js/global.js"></script>
+<script type="text/javascript" src="/public/web/common_ajax.js"></script>
+
+<script src="/web/maintain/report/js/adhoc_task.js"></script>
+
+
+<!-- JS.
+-->
+<!-- zTree
+<script type="text/javascript" src="/public/web/date_util.js"></script>
+<script type="text/javascript" src="/lib/ztree/jquery.ztree.core.js"></script>
+<script type="text/javascript" src="/lib/ztree/jquery.ztree.excheck.js"></script>
+<script type="text/javascript" src="/lib/ztree/jquery.ztree.exedit.js"></script>
+<script type="text/javascript" src="/public/web/storageUtil.js"></script>
+<script type="text/javascript" src="/public/web/rpt_tpl_def.js"></script>
+<script type="text/javascript" src="/public/web/treeDataHelper.js"></script>
+<script type="text/javascript" src="/public/web/ztree_common.js"></script>
+<script type="text/javascript" src="/public/web/rpt_value_define.js"></script>
+<script type="text/javascript" src="/public/web/string_util_light.js"></script>
+-->
+
+</body>
+<script type="text/javascript">
+    autoFlashHeight();
+    adHocTaskObj.iniPage();
+</script>
+
+</html>

+ 54 - 0
web/maintain/report/js/adhoc_task.js

@@ -0,0 +1,54 @@
+'use strict'
+
+/**
+ * Created by Tony on 2021/11/3.
+ */
+
+let adHocTaskObj = {
+    currentRationRepId: '',
+    currentRationLibId: '',
+    iniPage: function() {
+        this._getCompilationList();
+    },
+    _getCompilationList: function(){
+        let me = adHocTaskObj, params = {};
+        CommonAjax.postEx("report_tpl_api/getCompilationList", params, 20000, true, function(result){
+                for (let item of result) {
+                    $("#compilations").append("<option value='" + item._id + "'>" + item.name + "</option>");
+                }
+                me.changeCompilation($("#compilations").get(0));
+                me.currentRationRepId = $("#compilations").get(0).value;
+            }, null, null
+        );
+    },
+    changeCompilation: function(dom) {
+        $("#rations").empty();
+        ///rationRepository/api
+        let compilationId = dom.value;
+        CommonAjax.post('/rationRepository/api/getRationLibsByCompilation', {compilationId: compilationId}, function (rstData) {
+            $('#rations').empty();
+            for(let rationLib of rstData){
+                let opt = `<option value="${rationLib.ID}">${rationLib.dispName}</option>`;
+                $('#rations').append(opt);
+            }
+            adHocTaskObj.currentRationLibId = $("#rations").get(0).value;
+        });
+    },
+    changeRationRepository: function(dom) {
+        adHocTaskObj.currentRationLibId = dom.value;
+    },
+    createDesktopMdb: function() {
+        let params = {};
+        params.compilationId = adHocTaskObj.currentRationRepId;
+        params.rationLibId = adHocTaskObj.currentRationLibId;
+        params.hasRationTree = $("#eleRationTree").get(0).checked;
+        params.hasRation = $("#eleRationItems").get(0).checked;
+        params.hasAssistRation = $("#eleAssistRationItems").get(0).checked;
+        params.hasGLJ = $("#eleAllGLJ").get(0).checked;
+        params.hasCOE = $("#eleCOE").get(0).checked;
+        CommonAjax.postEx('/adHoc_report_api/createDesktopMdb', params, 10000, false, function (result) {
+            console.log(`result: `);
+            console.log(result);
+        });
+    }
+};

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

@@ -119,6 +119,7 @@ const exposed_ration_properties = [
 ];
 const exposed_ration_glj_properties = [
     {Name: "定额人材机_ID", Title: "", Key: "ID"}
+    ,{Name: "定额人材机_项目人材机映射ID", Title: "", Key: "projectGLJID", Order: "ascend"}
     ,{Name: "定额人材机_所属定额ID", Title: "", Key: "rationID", Order: "ascend"}
     ,{Name: "定额人材机_所属清单ID", Title: "", Key: "billsItemID", Order: "ascend"}
     ,{Name: "定额人材机_所属工程ID", Title: "", Key: "projectID", Order: "ascend"}
@@ -130,7 +131,7 @@ const exposed_ration_glj_properties = [
     ,{Name: "定额人材机_三材类别", Title: "", Key: "ref_join(projectGLJID,projectGLJ,id).materialType", Order: "ascend", individualType: fixed_material_types}
 ];
 const exposed_prj_glj_properties = [
-    {Name: "项目人材机_ID", Title: "", Key: "ID"}
+    {Name: "项目人材机_ID", Title: "", Key: "id"}
     ,{Name: "项目人材机_所属工程ID", Title: "", Key: "projectID", Order: "ascend"}
     ,{Name: "项目人材机_代码", Title: "", Key: "code", Order: "ascend"}
     ,{Name: "项目人材机_类型", Title: "", Key: "type", Order: "ascend", individualType: fixed_glj_types}