Browse Source

Merge branch 'master' of http://smartcost.f3322.net:3000/SmartCost/ConstructionOperation

zhangweicheng 8 years ago
parent
commit
1350080f81
50 changed files with 3730 additions and 95 deletions
  1. 37 0
      modules/common/std/schemas/std_glj_lib_map.js
  2. 55 0
      modules/common/std/std_glj_lib_map_model.js
  3. 20 0
      modules/ration_repository/controllers/ration_repository_controller.js
  4. 0 1
      modules/ration_repository/controllers/repository_views_controller.js
  5. 3 2
      modules/ration_repository/models/repository_map.js
  6. 2 1
      modules/ration_repository/routes/ration_rep_routes.js
  7. 11 0
      modules/reports/controllers/rpt_controller.js
  8. 8 0
      modules/reports/facade/rpt_tpl_data_facade.js
  9. 8 1
      modules/reports/models/rpt_template.js
  10. 3 1
      modules/reports/models/rpt_tpl_data_demo.js
  11. 18 4
      modules/reports/rpt_component/helper/jpc_helper_band.js
  12. 15 0
      modules/reports/rpt_component/helper/jpc_helper_common.js
  13. 3 2
      modules/reports/rpt_component/helper/jpc_helper_field.js
  14. 6 0
      modules/reports/rpt_component/jpc_band.js
  15. 93 0
      modules/reports/rpt_component/jpc_data.js
  16. 20 2
      modules/reports/rpt_component/jpc_ex.js
  17. 13 1
      modules/reports/rpt_component/jpc_field.js
  18. 27 15
      modules/reports/rpt_component/jpc_flow_tab.js
  19. 4 0
      modules/reports/rpt_component/jpc_rte.js
  20. 18 0
      modules/reports/util/rpt_data_util.js
  21. 112 0
      modules/std_glj_lib/controllers/gljController.js
  22. 66 0
      modules/std_glj_lib/controllers/gljMapController.js
  23. 23 0
      modules/std_glj_lib/controllers/viewsController.js
  24. 150 0
      modules/std_glj_lib/models/gljMapModel.js
  25. 334 0
      modules/std_glj_lib/models/gljModel.js
  26. 65 0
      modules/std_glj_lib/models/schemas.js
  27. 41 0
      modules/std_glj_lib/routes/routes.js
  28. 7 1
      modules/users/controllers/compilation_controller.js
  29. 11 1
      modules/users/models/compilation_model.js
  30. 5 0
      modules/users/models/schemas/compilation.js
  31. 1 0
      public/counter/counter.js
  32. 8 0
      public/web/rpt_value_define.js
  33. 7 1
      public/web/sheet/sheet_common.js
  34. 22 1
      web/maintain/ration_repository/js/main.js
  35. 1 3
      web/maintain/ration_repository/js/ration.js
  36. 50 42
      web/maintain/ration_repository/js/ration_glj.js
  37. 3 3
      web/maintain/ration_repository/js/repository_glj.js
  38. 0 2
      web/maintain/ration_repository/js/section_tree.js
  39. 34 2
      web/maintain/ration_repository/main.html
  40. 1 0
      web/maintain/report/rpt_test.html
  41. 279 0
      web/maintain/std_glj_lib/css/main.css
  42. 265 0
      web/maintain/std_glj_lib/html/gongliao.html
  43. 144 0
      web/maintain/std_glj_lib/html/main.html
  44. 1069 0
      web/maintain/std_glj_lib/js/glj.js
  45. 370 0
      web/maintain/std_glj_lib/js/gljComponent.js
  46. 42 0
      web/maintain/std_glj_lib/js/global.js
  47. 191 0
      web/maintain/std_glj_lib/js/main.js
  48. 33 5
      web/users/js/compilation.js
  49. 22 4
      web/users/views/compilation/add.html
  50. 10 0
      web/users/views/compilation/modal.html

+ 37 - 0
modules/common/std/schemas/std_glj_lib_map.js

@@ -0,0 +1,37 @@
+/**
+ * 工料机库数据模型
+ *
+ * @author CaiAoLin
+ * @date 2017/8/16
+ * @version
+ */
+/*
+import mongoose from "mongoose";
+
+let Schema = mongoose.Schema;
+let collectionName = 'std_glj_lib_map';
+let modelSchema = {
+    // 显示名称
+    dispName: String,
+    // 类型
+    appType: String,
+    // 是否被删除标记
+    deleted: Boolean,
+    // 自增ID
+    ID: Number,
+    // 创建时间
+    createDate: String,
+    // 创建者
+    creator: String,
+    // 最近一次操作
+    recentOpr: Schema.Types.Mixed,
+    // 编办id
+    compilationId: String,
+    // 编办名称
+    compilationName: String,
+    // 定额库
+    rationLibs: Schema.Types.Mixed
+};
+
+let model = mongoose.model(collectionName, new Schema(modelSchema, {versionKey: false, collection: collectionName}));
+export {model as default, collectionName as collectionName};*/

+ 55 - 0
modules/common/std/std_glj_lib_map_model.js

@@ -0,0 +1,55 @@
+/**
+ * 工料机库业务逻辑
+ *
+ * @author CaiAoLin
+ * @date 2017/8/16
+ * @version
+ */
+import BaseModel from "../../common/base/base_model";
+import STDGLJLibMapSchema from "./schemas/std_glj_lib_map";
+
+class STDGLJLibMapModel extends BaseModel {
+
+    /**
+     * 构造函数
+     *
+     * @return {void}
+     */
+    constructor() {
+        let parent = super();
+        parent.model = STDGLJLibMapSchema;
+        parent.init();
+    }
+
+    /**
+     * 获取对应的工料机库
+     *
+     * @param {String} compilationId
+     * @return {Promise}
+     */
+    async getGLJLibList(compilationId) {
+        let result = [];
+        let gliLib = await this.findDataByCondition({deleted: false, compilationId: compilationId.toString()}, null, false);
+
+        if (gliLib.length <= 0) {
+            return result;
+        }
+
+        // 整理数据
+        let gljList = [];
+        for(let tmp of gliLib) {
+            let tmpRation = {id: tmp.ID, name: tmp.dispName};
+            if (gljList.length <= 0) {
+                gljList = [tmpRation];
+            } else {
+                gljList.push(tmpRation);
+            }
+        }
+
+        result = gljList;
+        return result;
+    }
+
+}
+
+export default STDGLJLibMapModel;

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

@@ -3,11 +3,31 @@
  */
 var rationRepository = require("../models/repository_map");
 import baseController from "../../common/base/base_controller";
+import CompilationModel from "../../users/models/compilation_model";
 var callback = function(req, res, err, message, data){
     res.json({error: err, message: message, data: data});
 };
 
 class RationRepositoryController extends baseController{
+   async getCompilationList(req, res){
+       try{
+           let compilationModel = new CompilationModel(), rst = [];
+           let compilationList = await compilationModel.getCompilationList();
+           if(compilationList.length <= 0){
+               throw '没有数据';
+           }
+           else{
+
+               compilationList.forEach(function (compilation) {
+                   rst.push({_id: compilation._id, name: compilation.name});
+               })
+               callback(req, res, false, '', rst);
+           }
+       }
+        catch(err) {
+            callback(req, res, err, '没有数据', null);
+        }
+    }
     addRationRepository(req,res){
         var rationObj = JSON.parse(req.body.rationRepObj);
         rationRepository.addRationRepository(rationObj,function(err,data){

+ 0 - 1
modules/ration_repository/controllers/repository_views_controller.js

@@ -2,7 +2,6 @@
  * Created by Zhong on 2017/8/3.
  */
 import BaseController from "../../common/base/base_controller";
-
 class ViewsController extends BaseController{
     redirectMain(req, res){
         res.render('maintain/ration_repository/main.html',

+ 3 - 2
modules/ration_repository/models/repository_map.js

@@ -13,13 +13,14 @@ var RepositoryMapSchema = new Schema({
     "ID": Number,
     "dispName" : String,
     "appType" : String, //如:"建筑" / "公路"
-    "localeType": Number, //如 各个省份 / 部颁
+    "compilationId": Number, //编办
+    "compilationName": String,
     "descr" : String,
     "creator": String,
     "createDate": String,
     "recentOpr" :[],
     "deleted": Boolean
-});
+},  {versionKey: false});
 var counter = require('../../../public/counter/counter');
 
 var rationRepository = rationLibdb.model("std_ration_lib_map", RepositoryMapSchema, "std_ration_lib_map");

+ 2 - 1
modules/ration_repository/routes/ration_rep_routes.js

@@ -34,9 +34,10 @@ module.exports =  function (app) {
     app.get('/rationRepository/main', viewsController.auth, viewsController.init, viewsController.redirectMain);
     app.get('/rationRepository/ration',viewsController.auth, viewsController.init, viewsController.redirectRation);
     app.get('/rationRepository/lmm', viewsController.auth, viewsController.init, viewsController.redirectGlj);
-
     app.get('/rationRepository/coeList', viewsController.auth, viewsController.init, viewsController.redirectCoeList);
 
+    apiRouter.post("/getCompilationList", rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.getCompilationList);
+
     apiRouter.post("/getRationDisplayNames",rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.getDisPlayRationLibs);
     apiRouter.post("/editRationLibs",rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.updateRationRepositoryName);
     apiRouter.post("/addRationRepository",rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.addRationRepository);

+ 11 - 0
modules/reports/controllers/rpt_controller.js

@@ -81,6 +81,17 @@ function getAllPagesCommon(req, res, rpt_id, pageSize, cb) {
                 if (rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS] && rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS].leng > 0) {
                     tplData[JV.DATA_DETAIL_DATA] = [];
                 }
+                //2. Ex主数据
+                if (rptTpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS_EX] && rptTpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS_EX].leng > 0) {
+                    tplData[JV.DATA_MASTER_DATA_EX] = [];
+                }
+                //3. Ex从数据
+                if (rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS_EX] && rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS_EX].leng > 0) {
+                    tplData[JV.DATA_DETAIL_DATA_EX] = [];
+                }
+                //4. 重点: 开始组装$PROJECT对象
+                let $PROJECT = {};
+                //let $PROJECT.COMMON = {};
                 //return demoTemplateData.getPromise(rptTpl.ID_KEY);
                 //return demoTemplateData.findOne({"Data_Key": rptTpl.ID_KEY}).exec();
 

+ 8 - 0
modules/reports/facade/rpt_tpl_data_facade.js

@@ -4,3 +4,11 @@
 
 let mongoose = require("mongoose");
 let rpt_tpl_mdl = mongoose.model("rpt_templates");
+
+module.exports = {
+
+}
+
+async function prepareProjectData(prjId, userId) {
+    //
+}

+ 8 - 1
modules/reports/models/rpt_template.js

@@ -8,9 +8,16 @@ let RptTemplateSchema = new Schema({
     "GROUP_KEY": String,
     "ID_KEY": String,
     "主信息": Schema.Types.Mixed,
-    "指标_数据_映射": Schema.Types.Mixed,
+    "指标_数据_映射": {
+        "离散指标_集合": Array,
+        "主数据指标_集合": Array,
+        "从数据指标_集合": Array,
+        "主数据指标_拓展集合": Array,
+        "从数据指标_拓展集合": Array
+    },
     "布局框_集合": Array,
     "流水式表_信息": Schema.Types.Mixed,
+    "流水式表_拓展信息": Schema.Types.Mixed,
     "账单式表_信息": Schema.Types.Mixed,
     "交叉表_信息": Schema.Types.Mixed,
     "无映射离散指标_集合": Schema.Types.Mixed,

+ 3 - 1
modules/reports/models/rpt_tpl_data_demo.js

@@ -9,7 +9,9 @@ let RptTemplateDataSchema = new Schema({
     "Data_Key": String,
     "discrete_data": Array,
     "master_data": Array,
-    "detail_data": Array
+    "detail_data": Array,
+    "master_data_ex": Array,
+    "detail_data_ex": Array
 });
 
 let TemplateData = mongoose.model("rpt_temp_tpl_data", RptTemplateDataSchema, "rpt_temp_tpl_data");

+ 18 - 4
modules/reports/rpt_component/helper/jpc_helper_band.js

@@ -7,18 +7,32 @@ let JpcBandHelper = {
         if (rst < 0) rst = JV.STATUS_NORMAL;
         return rst;
     },
-    setBandArea: function(bands, rptTpl, pageStatus) {
+    setBandArea: function(bands, rptTpl, pageStatus, isOnlyNormalStatus, isOnlyExStatus) {
         let me = this;
         if (rptTpl[JV.NODE_BAND_COLLECTION]) {
+            isOnlyNormalStatus = isOnlyNormalStatus||false;
+            isOnlyExStatus = isOnlyExStatus||false;
+
             let unitFactor = JpcCommonHelper.getUnitFactor(rptTpl);
             let orgArea = JpcCommonHelper.getReportArea(rptTpl, unitFactor);
             for (let i = 0; i < rptTpl[JV.NODE_BAND_COLLECTION].length; i++) {
-                me.setBandPos(bands, rptTpl[JV.NODE_BAND_COLLECTION][i], orgArea, unitFactor, pageStatus);
+                me.setBandPos(bands, rptTpl[JV.NODE_BAND_COLLECTION][i], orgArea, unitFactor, pageStatus, isOnlyNormalStatus, isOnlyExStatus);
             }
         }
     },
-    setBandPos: function(bands, bandNode, orgArea, unitFactor, pageStatus) {
+    setBandPos: function(bands, bandNode, orgArea, unitFactor, pageStatus, isOnlyNormalStatus, isOnlyExStatus) {
         let me = this, band = bands[bandNode[JV.BAND_PROP_NAME]];
+        //0. for multi flow purpose
+        if (isOnlyNormalStatus) {
+            if (bandNode.hasOwnProperty(JV.PROP_BAND_EX_ONLY) && JpcCommonHelper.getBoolean(bandNode[JV.PROP_BAND_EX_ONLY])) {
+                return;
+            }
+        }
+        if (isOnlyExStatus) {
+            if (bandNode.hasOwnProperty(JV.PROP_BAND_NORMAL_ONLY) && !(JpcCommonHelper.getBoolean(bandNode[JV.PROP_BAND_NORMAL_ONLY]))) {
+                return;
+            }
+        }
         //1. initialize
         band[JV.PROP_LEFT] = orgArea[JV.IDX_LEFT];
         band[JV.PROP_TOP] = orgArea[JV.IDX_TOP];
@@ -64,7 +78,7 @@ let JpcBandHelper = {
             if (bandNode[JV.BAND_PROP_SUB_BANDS]) {
                 let bandArea = [band.Left, band.Top, band.Right, band.Bottom];
                 for (let i = 0; i < bandNode[JV.BAND_PROP_SUB_BANDS].length; i++) {
-                    me.setBandPos(bands, bandNode[JV.BAND_PROP_SUB_BANDS][i], bandArea, unitFactor, pageStatus);
+                    me.setBandPos(bands, bandNode[JV.BAND_PROP_SUB_BANDS][i], bandArea, unitFactor, pageStatus, isOnlyNormalStatus, isOnlyExStatus);
                 }
             }
         }

+ 15 - 0
modules/reports/rpt_component/helper/jpc_helper_common.js

@@ -51,6 +51,21 @@ let JpcCommonHelper = {
         if (rst < 0) rst = JV.CAL_TYPE_ABSTRACT;
         return rst;
     },
+    getBoolean: function(bStr) {
+        let rst = false;
+        if (bStr !== null && bStr !== undefined) {
+            let valType = typeof(bStr);
+            if (valType === "boolean") {
+                rst = bStr;
+            } else if (valType === "string") {
+                let tS = bStr.toUpperCase();
+                rst = (tS === "T" || tS === "TRUE" || tS === "YES" || tS === "Y");
+            } else if (valType === "number") {
+                rst = (bStr === 1);
+            }
+        }
+        return rst;
+    },
     getScreenDPI: function() {
         let me = this, arrDPI = [];
         if (!me.commonConstant.resolution) {

+ 3 - 2
modules/reports/rpt_component/helper/jpc_helper_field.js

@@ -19,9 +19,10 @@ let JpcFieldHelper = {
             }
         }
     },
-    findAndPutDataFieldIdx: function (rptTpl, tab_fields, rstFields, rstFieldsIdx) {
+    findAndPutDataFieldIdx: function (rptTpl, tab_fields, rstFields, rstFieldsIdx, isEx) {
         if (tab_fields) {
-            let detail_fields = rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS];
+            let DTL_STR = isEx?JV.NODE_DETAIL_FIELDS_EX:JV.NODE_DETAIL_FIELDS;
+            let detail_fields = rptTpl[JV.NODE_FIELD_MAP][DTL_STR];
             for (let i = 0; i < tab_fields.length; i++) {
                 let isFounded = false;
                 for (let j = 0; j < detail_fields.length; j++) {

+ 6 - 0
modules/reports/rpt_component/jpc_band.js

@@ -32,6 +32,12 @@ let JpcBand = {
             item[JV.BAND_PROP_DISPLAY_TYPE] = JpcBandHelper.getBandTypeValByString(bandNode[JV.BAND_PROP_DISPLAY_TYPE]);
             item[JV.BAND_PROP_ALIGNMENT] = JpcCommonHelper.getLayoutAlignment(bandNode[JV.BAND_PROP_ALIGNMENT]);
             item[JV.PROP_CALCULATION] = JpcCommonHelper.getPosCalculationType(bandNode[JV.PROP_CALCULATION]);
+            if (bandNode.hasOwnProperty(JV.PROP_BAND_NORMAL_ONLY)) {
+                item[JV.PROP_BAND_NORMAL_ONLY] = JpcCommonHelper.getBoolean(bandNode[JV.PROP_BAND_NORMAL_ONLY]);
+            }
+            if (bandNode.hasOwnProperty(JV.PROP_BAND_EX_ONLY)) {
+                item[JV.PROP_BAND_EX_ONLY] = JpcCommonHelper.getBoolean(bandNode[JV.PROP_BAND_EX_ONLY]);
+            }
 
             if (bandNode[JV.BAND_PROP_MERGE_BORDER]) {
                 item[JV.BAND_PROP_MERGE_BORDER] = bandNode[JV.BAND_PROP_MERGE_BORDER];

+ 93 - 0
modules/reports/rpt_component/jpc_data.js

@@ -3,9 +3,101 @@ let JpcData = {
     createNew: function() {
         let JpcDataRst = {};
         JpcDataRst.dataSeq = [];
+        JpcDataRst.exDataSeq = [];
         JpcDataRst.analyzeData = function(rptTpl, dataObj) {
             let me = this;
+            let private_analyse = function(MASTER_FIELD_STR, DETAIL_FIELD_STR, MASTER_DATA_STR, DETAIL_DATA_STR, dataSeqArr) {
+                //1. get ID fields
+                let masterIDs = [];
+                for (let i = 0; i < rptTpl[JV.NODE_FIELD_MAP][MASTER_FIELD_STR].length; i++) {
+                    let mstFieldObj = rptTpl[JV.NODE_FIELD_MAP][MASTER_FIELD_STR][i];
+                    if ((mstFieldObj[JV.PROP_IS_ID]) && (mstFieldObj[JV.PROP_IS_ID] === 'T')) {
+                        masterIDs.push({"idx": i, "seq": mstFieldObj[JV.PROP_ID_SEQ]});
+                    }
+                }
+                let detailIDs = [];
+                for (let i = 0; i < rptTpl[JV.NODE_FIELD_MAP][DETAIL_FIELD_STR].length; i++) {
+                    let dtlFieldObj = rptTpl[JV.NODE_FIELD_MAP][DETAIL_FIELD_STR][i];
+                    if ((dtlFieldObj[JV.PROP_IS_ID]) && (dtlFieldObj[JV.PROP_IS_ID] === 'T')) {
+                        detailIDs.push({"idx": i, "seq": dtlFieldObj[JV.PROP_ID_SEQ]});
+                    }
+                }
+                //2. sort the ID fields
+                if (masterIDs.length > 1) {
+                    masterIDs.sort(function(a, b) {
+                        return 1*a["seq"] - 1*b["seq"];
+                    })
+                }
+                if (detailIDs.length > 1) {
+                    detailIDs.sort(function(a, b) {
+                        return 1*a["seq"] - 1*b["seq"];
+                    })
+                }
+                //3. prepare data sequence
+                if (masterIDs.length > 0) {
+                    let mst_dt_len = 0, dtl_dt_len = 0, mst_fields = [];
+                    for (let i = 0; i < masterIDs.length; i++) {
+                        mst_fields.push(dataObj[MASTER_DATA_STR][masterIDs[i]["idx"]]);
+                        mst_dt_len = dataObj[MASTER_DATA_STR][masterIDs[i]["idx"]].length;
+                    }
+                    let dtl_fields = [];
+                    for (let i = 0; i < detailIDs.length; i++) {
+                        dtl_fields.push(dataObj[DETAIL_DATA_STR][detailIDs[i]["idx"]]);
+                        dtl_dt_len = dataObj[DETAIL_DATA_STR][detailIDs[i]["idx"]].length;
+                    }
+                    let sIdx = 0;
+                    let isEqual = true;
+                    for (let i = 0; i < mst_dt_len; i++) {
+                        dataSeqArr.push([]);
+                        //then compare the master/detail ID-field value
+                        for (let j = sIdx; j < dtl_dt_len; j++) {
+                            isEqual = true;
+                            for (let k = 0; k < mst_fields.length; k++) {
+                                if (!(mst_fields[k][i] === dtl_fields[k][j])) {
+                                    isEqual = false;
+                                    break;
+                                }
+                            }
+                            if (isEqual) {
+                                dataSeqArr[i].push(j);
+                            } else {
+                                sIdx = j;
+                                //below logic is for the data robustness purpose, to avoid those strange record(detail level) which could not match even one of the master record!
+                                if (i < mst_dt_len - 1 && j < dtl_dt_len - 1) {
+                                    for (let j1 = j; j1 < dtl_dt_len; j1++) {
+                                        isEqual = true;
+                                        for (let k = 0; k < mst_fields.length; k++) {
+                                            if (!(mst_fields[k][i + 1] === dtl_fields[k][j1])) {
+                                                isEqual = false;
+                                                break;
+                                            }
+                                        }
+                                        if (isEqual) {
+                                            sIdx = j1;
+                                            break;
+                                        }
+                                    }
+                                }
+                                break;
+                            }
+                        }
+                    }
+                } else { //if no master data
+                    let field = dataObj[DETAIL_DATA_STR][0];
+                    //dataSeqArr = [[]];
+                    dataSeqArr.push([]);
+                    for (let i = 0; i < field.length; i++) {
+                        dataSeqArr[0].push(i);
+                    }
+                }
+            };
             if ((rptTpl) && (dataObj)) {
+                //*
+                private_analyse(JV.NODE_MASTER_FIELDS, JV.NODE_DETAIL_FIELDS, JV.DATA_MASTER_DATA, JV.DATA_DETAIL_DATA, me.dataSeq);
+                if (rptTpl[JV.NODE_FLOW_INFO_EX]) {
+                    private_analyse(JV.NODE_MASTER_FIELDS_EX, JV.NODE_DETAIL_FIELDS_EX, JV.DATA_MASTER_DATA_EX, JV.DATA_DETAIL_DATA_EX, me.exDataSeq);
+                }
+                /*/
                 //1. get ID fields
                 let masterIDs = [];
                 for (let i = 0; i < rptTpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS].length; i++) {
@@ -88,6 +180,7 @@ let JpcData = {
                         me.dataSeq[0].push(i);
                     }
                 }
+                //*/
             }
             //alert(3);
         };

+ 20 - 2
modules/reports/rpt_component/jpc_ex.js

@@ -86,7 +86,11 @@ JpcExSrv.prototype.createNew = function(){
         let me = this;
         if (rptTpl[JV.NODE_FLOW_INFO]) {
             me.flowTab = JpcFlowTab.createNew();
-            me.flowTab.initialize();
+            me.flowTab.initialize(false);
+        }
+        if (rptTpl[JV.NODE_FLOW_INFO_EX]) {
+            me.flowTabEx = JpcFlowTab.createNew();
+            me.flowTabEx.initialize(true);
         }
         if (rptTpl[JV.NODE_BILL_INFO]) {
             me.billTab = JpcBillTab.createNew();
@@ -98,6 +102,7 @@ JpcExSrv.prototype.createNew = function(){
             me.crossTab.initialize();
         }
         me.totalPages = 0;
+        me.exTotalPages = 0;
         me.runTimePageData = {};
         me.fields = JpcField.createNew(rptTpl);
         me.params = JpcParam.createNew(rptTpl);
@@ -114,6 +119,9 @@ JpcExSrv.prototype.createNew = function(){
         //let dt1 = new Date();
         if (me.flowTab) {
             me.flowTab.sorting(rptTpl, dataObj, dataHelper.dataSeq.slice(0));
+            if (me.flowTabEx) {
+                me.flowTabEx.sorting(rptTpl, dataObj, dataHelper.exDataSeq.slice(0));
+            }
         }
         if (me.crossTab) {
             me.crossTab.sorting(rptTpl, dataObj, dataHelper.dataSeq.slice(0));
@@ -132,6 +140,11 @@ JpcExSrv.prototype.createNew = function(){
         let me = this;
         if (me.flowTab) {
             me.totalPages = me.flowTab.preSetupPages(rptTpl, dataObj, defProperties);
+            if (me.flowTabEx) {
+                me.exTotalPages = me.flowTabEx.preSetupPages(rptTpl, dataObj, defProperties);
+                //console.log('ad-hoc flow pages: ' + me.exTotalPages);
+            }
+            me.totalPages += me.exTotalPages;
         } else if (me.crossTab) {
             me.totalPages = me.crossTab.preSetupPages(rptTpl, defProperties);
         } else if (me.billTab) {
@@ -187,7 +200,12 @@ JpcExSrv.prototype.createNew = function(){
             rst[JV.PROP_PAGE_SEQ] = page;
             //rst.cells = [];
             if (me.flowTab) {
-                rst.cells = me.flowTab.outputAsSimpleJSONPage(rptTpl, dataObj, page, bands, controls, me);
+                if (me.totalPages - me.exTotalPages >= page) {
+                    rst.cells = me.flowTab.outputAsSimpleJSONPage(rptTpl, dataObj, page, bands, controls, me);
+                } else {
+                    rst.cells = me.flowTabEx.outputAsSimpleJSONPage(rptTpl, dataObj, page - me.exTotalPages, bands, controls, me);
+                }
+                //rst.cells = me.flowTab.outputAsSimpleJSONPage(rptTpl, dataObj, page, bands, controls, me);
             } else if (me.crossTab) {
                 rst.cells = me.crossTab.outputAsSimpleJSONPage(rptTpl, dataObj, page, bands, controls, me);
             } else if (me.billTab) {

+ 13 - 1
modules/reports/rpt_component/jpc_field.js

@@ -27,7 +27,19 @@ let JpcField = {
                 me.createSingle(rptTpl[JV.NODE_NO_MAPPING_FIELDS][i], JpcFieldResult[JV.NODE_NO_MAPPING_FIELDS], rptTpl, "NA", JV.BLANK_FIELD_INDEX);
             }
         }
-        //
+        JpcFieldResult[JV.NODE_MASTER_FIELDS_EX] = {};
+        if (rptTpl[JV.NODE_FIELD_MAP] && rptTpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS_EX]) {
+            for (let i = 0; i < rptTpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS_EX].length; i++) {
+                me.createSingle(rptTpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS_EX][i], JpcFieldResult[JV.NODE_MASTER_FIELDS_EX], rptTpl, JV.DATA_MASTER_DATA_EX, i);
+            }
+        }
+        JpcFieldResult[JV.NODE_DETAIL_FIELDS_EX] = {};
+        if (rptTpl[JV.NODE_FIELD_MAP] && rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS_EX]) {
+            for (let i = 0; i < rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS_EX].length; i++) {
+                me.createSingle(rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS_EX][i], JpcFieldResult[JV.NODE_DETAIL_FIELDS_EX], rptTpl, JV.DATA_DETAIL_DATA_EX, i);
+            }
+        }
+        //NODE_MASTER_FIELDS_EX
         return JpcFieldResult;
     },
     createSingle: function(fieldNode, parentObj, rptTpl, dataNodeName, sequence) {

+ 27 - 15
modules/reports/rpt_component/jpc_flow_tab.js

@@ -25,8 +25,9 @@ JpcFlowTabSrv.prototype.createNew = function(){
         ValuedIdxLst.push(vIdx);
     }
     let JpcFlowTabResult = {};
-    JpcFlowTabResult.initialize = function() {
+    JpcFlowTabResult.initialize = function(isEx) {
         let me = this;
+        me.isEx = isEx;
         me.segments = [];
         me.dispValueIdxLst = [];
         me.page_seg_map = [];
@@ -39,17 +40,19 @@ JpcFlowTabSrv.prototype.createNew = function(){
         me.groupSumValLst = [];
         me.segSumValLst = [];
         me.multiCols = 1;
+        me.pagesAmt = 0;
     };
     JpcFlowTabResult.sorting = function(rptTpl, dataObj, dataSeq) {
         let me = this;
-        JpcFieldHelper.findAndPutDataFieldIdx(rptTpl, rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_SEG_SUM][JV.PROP_SUM_FIELDS], me.seg_sum_tab_fields, me.seg_sum_fields_idx);
-        JpcFieldHelper.findAndPutDataFieldIdx(rptTpl, rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_PAGE_SUM][JV.PROP_SUM_FIELDS], null, me.page_sum_fields_idx);
-        JpcFieldHelper.findAndPutDataFieldIdx(rptTpl, rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_GROUP][JV.PROP_GROUP_FIELDS], null, me.group_fields_idx);
+        let FLOW_NODE_STR = me.isEx?JV.NODE_FLOW_INFO_EX:JV.NODE_FLOW_INFO;
+        JpcFieldHelper.findAndPutDataFieldIdx(rptTpl, rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_SEG_SUM][JV.PROP_SUM_FIELDS], me.seg_sum_tab_fields, me.seg_sum_fields_idx, me.isEx);
+        JpcFieldHelper.findAndPutDataFieldIdx(rptTpl, rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_PAGE_SUM][JV.PROP_SUM_FIELDS], null, me.page_sum_fields_idx, me.isEx);
+        JpcFieldHelper.findAndPutDataFieldIdx(rptTpl, rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_GROUP][JV.PROP_GROUP_FIELDS], null, me.group_fields_idx, me.isEx);
         for (let si = 0; si < dataSeq.length; si++) {
             me.segments.push(dataSeq[si].slice(0));
         }
         //pre-sum the data(for seg sum display)
-        let data_details = dataObj[JV.DATA_DETAIL_DATA],
+        let data_details = me.isEx?dataObj[JV.DATA_DETAIL_DATA_EX]:dataObj[JV.DATA_DETAIL_DATA],
             data_fields = [];
         for (let i = 0; i < me.seg_sum_fields_idx.length; i++) {
             let data_field = data_details[me.seg_sum_fields_idx[i]];
@@ -72,14 +75,18 @@ JpcFlowTabSrv.prototype.createNew = function(){
     };
     JpcFlowTabResult.preSetupPages = function (rptTpl, dataOjb, defProperties) {
         let rst = 0, me = this, counterRowRec = 0, maxRowRec = 1, pageIdx = 0;
-        JpcFieldHelper.findAndPutDataFieldIdx(rptTpl, rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_CONTENT][JV.PROP_FLOW_FIELDS], null, me.disp_fields_idx);
+        let CURRENT_FLOW_INFO = (me.isEx)?JV.NODE_FLOW_INFO_EX:JV.NODE_FLOW_INFO;
+        JpcFieldHelper.findAndPutDataFieldIdx(rptTpl, rptTpl[CURRENT_FLOW_INFO][JV.NODE_FLOW_CONTENT][JV.PROP_FLOW_FIELDS], null, me.disp_fields_idx, me.isEx);
         let bands = JpcBand.createNew(rptTpl, defProperties);
         let pageStatus = [true, true, false, false, false, false, false, false];
-        if (rptTpl[JV.NODE_FLOW_INFO][JV.PROP_MULTI_COLUMN]) {
-            me.multiCols = 1 * rptTpl[JV.NODE_FLOW_INFO][JV.PROP_MULTI_COLUMN];
+        if (me.isEx) {
+            pageStatus[JV.STATUS_REPORT_START] = false;
+        }
+        if (rptTpl[CURRENT_FLOW_INFO][JV.PROP_MULTI_COLUMN]) {
+            me.multiCols = 1 * rptTpl[CURRENT_FLOW_INFO][JV.PROP_MULTI_COLUMN];
         }
         function private_resetBandArea() {
-            JpcBandHelper.setBandArea(bands, rptTpl, pageStatus);
+            JpcBandHelper.setBandArea(bands, rptTpl, pageStatus, !me.isEx, me.isEx);
             maxRowRec = JpcFlowTabHelper.getMaxRowsPerPage(bands, rptTpl);
         }
         for (let segIdx = 0; segIdx < me.segments.length; segIdx++) {
@@ -106,13 +113,15 @@ JpcFlowTabSrv.prototype.createNew = function(){
             pageStatus[JV.STATUS_REPORT_START] = false;
         }
         rst = Math.ceil(1.0 * pageIdx / me.multiCols);
+        me.pagesAmt = rst;
         return rst;
     };
     JpcFlowTabResult.outputAsSimpleJSONPage = function (rptTpl, dataObj, page, bands, controls, $CURRENT_RPT) {
         let me = this, rst = [], tabRstLst = [];
+        let FLOW_NODE_STR = me.isEx?JV.NODE_FLOW_INFO_EX:JV.NODE_FLOW_INFO;
         let segIdx = JpcCommonHelper.getSegIdxByPageIdx(page, me.page_seg_map);
         //1 calculate the band position
-        JpcBandHelper.setBandArea(bands, rptTpl, me.pageStatusLst[page - 1]);
+        JpcBandHelper.setBandArea(bands, rptTpl, me.pageStatusLst[page - 1], !me.isEx, me.isEx);
         //2. start to output detail-part
         let unitFactor = JpcCommonHelper.getUnitFactor(rptTpl);
         for (let pi = 0; pi < me.multiCols; pi++) {
@@ -126,7 +135,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
             //2.4 Sum Page
             //2.5 Discrete
             if (pi == 0) {
-                tabRstLst.push(JpcDiscreteHelper.outputDiscreteInfo(rptTpl[JV.NODE_FLOW_INFO][JV.NODE_DISCRETE_INFO], bands, dataObj, unitFactor, me.pageStatusLst[actualPage - 1], segIdx, 1, pi, $CURRENT_RPT));
+                tabRstLst.push(JpcDiscreteHelper.outputDiscreteInfo(rptTpl[FLOW_NODE_STR][JV.NODE_DISCRETE_INFO], bands, dataObj, unitFactor, me.pageStatusLst[actualPage - 1], segIdx, 1, pi, $CURRENT_RPT));
             }
         }
         for (let i = 0; i < tabRstLst.length; i++) {
@@ -137,13 +146,14 @@ JpcFlowTabSrv.prototype.createNew = function(){
     };
     JpcFlowTabResult.outputContent = function(rptTpl, dataObj, page, bands, unitFactor, controls, multiColIdx, $CURRENT_RPT) {
         let me = this, rst = [];
-        let tab = rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_CONTENT];
+        let FLOW_NODE_STR = me.isEx?JV.NODE_FLOW_INFO_EX:JV.NODE_FLOW_INFO;
+        let tab = rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_CONTENT];
         let band = bands[tab[JV.PROP_BAND_NAME]];
         if (band) {
             let pageStatus = me.pageStatusLst[page - 1];
             if (pageStatus[band[JV.BAND_PROP_DISPLAY_TYPE]] == true) {
                 let tab_fields = tab[JV.PROP_FLOW_FIELDS];
-                let data_details = dataObj[JV.DATA_DETAIL_DATA];
+                let data_details = me.isEx?dataObj[JV.DATA_DETAIL_DATA_EX]:dataObj[JV.DATA_DETAIL_DATA];
                 let contentValuesIdx = me.dispValueIdxLst[page - 1];
                 for (let i = 0; i < tab_fields.length; i++) {
                     let tab_field = tab_fields[i];
@@ -168,7 +178,8 @@ JpcFlowTabSrv.prototype.createNew = function(){
     };
     JpcFlowTabResult.outputColumn = function (rptTpl, dataObj, page, segIdx, bands, unitFactor, controls, multiColIdx) {
         let me = this, rst = [];
-        let tab = rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_COLUMN];
+        let FLOW_NODE_STR = me.isEx?JV.NODE_FLOW_INFO_EX:JV.NODE_FLOW_INFO;
+        let tab = rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_COLUMN];
         let band = bands[tab[JV.PROP_BAND_NAME]];
         if (band) {
             let pageStatus = me.pageStatusLst[page - 1];
@@ -190,7 +201,8 @@ JpcFlowTabSrv.prototype.createNew = function(){
     };
     JpcFlowTabResult.outputSegSum = function (rptTpl, dataObj, page, segIdx, bands, unitFactor, controls) {
         let me = this, rst = [];
-        let tab = rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_SEG_SUM];
+        let FLOW_NODE_STR = me.isEx?JV.NODE_FLOW_INFO_EX:JV.NODE_FLOW_INFO;
+        let tab = rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_SEG_SUM];
         let band = bands[tab[JV.PROP_BAND_NAME]];
         if (band) {
             let pageStatus = me.pageStatusLst[page - 1];

+ 4 - 0
modules/reports/rpt_component/jpc_rte.js

@@ -10,6 +10,10 @@ let JE = {
             rst = $CURRENT_RPT.fields[JV.NODE_DETAIL_FIELDS][JV.PROP_ID + "_" + fID];
         } else if ($CURRENT_RPT && ($CURRENT_RPT.fields[JV.NODE_MASTER_FIELDS][JV.PROP_ID + "_" + fID])) {
             rst = $CURRENT_RPT.fields[JV.NODE_MASTER_FIELDS][JV.PROP_ID + "_" + fID];
+        } else if ($CURRENT_RPT && ($CURRENT_RPT.fields[JV.NODE_MASTER_FIELDS_EX][JV.PROP_ID + "_" + fID])) {
+            rst = $CURRENT_RPT.fields[JV.NODE_MASTER_FIELDS_EX][JV.PROP_ID + "_" + fID];
+        } else if ($CURRENT_RPT && ($CURRENT_RPT.fields[JV.NODE_DETAIL_FIELDS_EX][JV.PROP_ID + "_" + fID])) {
+            rst = $CURRENT_RPT.fields[JV.NODE_DETAIL_FIELDS_EX][JV.PROP_ID + "_" + fID];
         } else if ($CURRENT_RPT && ($CURRENT_RPT.fields[JV.NODE_DISCRETE_FIELDS][JV.PROP_ID + "_" + fID])) {
             rst = $CURRENT_RPT.fields[JV.NODE_DISCRETE_FIELDS][JV.PROP_ID + "_" + fID];
         } else if ($CURRENT_RPT && ($CURRENT_RPT.fields[JV.NODE_NO_MAPPING_FIELDS][JV.PROP_ID + "_" + fID])) {

+ 18 - 0
modules/reports/util/rpt_data_util.js

@@ -2,13 +2,31 @@
  * Created by Tony on 2017/7/14.
  * 报表数据提取class,是协助报表模板里指标字段自主提取数据的工具类
  */
+let JV = require('../rpt_component/jpc_value_define');
+let $JE = require('../rpt_component/jpc_rte');
+
 class Rpt_Common{
     initialize(Projects) {
         this.Projects = Projects;
     };
+
+    getSerialNo(fieldId, $CURRENT_RPT, $CURRENT_DATA){
+        let itemSerialNoRec = $JE.F(fieldId, $CURRENT_RPT);
+        if (itemSerialNoRec) {
+            itemSerialNoRec[JV.PROP_AD_HOC_DATA] = [];
+            for (var innerFmlIdx = 0; innerFmlIdx < $CURRENT_DATA[JV.DATA_DETAIL_DATA][0].length; innerFmlIdx++) {
+                itemSerialNoRec[JV.PROP_AD_HOC_DATA][innerFmlIdx] = (innerFmlIdx + 1);
+            }
+            itemSerialNoRec = null;
+        }
+    };
 };
 
 class Rpt_Data_Extractor {
+    constructor () {
+        this.COMMON = new Rpt_Common();
+    };
+
     initialize(Projects) {
         this.Projects = Projects;
         //Projects对象应该从前端传送过来,无需在后端重复查询及构建

+ 112 - 0
modules/std_glj_lib/controllers/gljController.js

@@ -0,0 +1,112 @@
+/**
+ * Created by Zhong on 2017/8/11.
+ */
+
+import BaseController from "../../common/base/base_controller";
+import stdgljutil  from "../../../public/cache/std_glj_type_util";
+import GljDao from "../models/gljModel";
+
+let gljDao = new GljDao();
+let callback = function(req, res, err, message, data){
+    res.json({error: err, message: message, data: data});
+};
+
+class GljController extends BaseController{
+    getGljDistType (req, res) {
+        let gljDistTypeCache = stdgljutil.getStdGljTypeCacheObj().toArray();
+        if(gljDistTypeCache.length >0 ){
+            callback(req, res, null, '', gljDistTypeCache);
+        }
+        else {
+            callback(req, res, 1, 'Error', null);
+        }
+    }
+    getGljTree(req,res){
+        var gljLibId = req.body.gljLibId;
+        gljDao.getGljTypes(gljLibId,function(err,data){
+            callback(req,res,err, 'Get Tree', data)
+        });
+    }
+    createNewGljTypeNode(req, res) {
+        var repId = req.body.repositoryId;
+        var lastNodeId = req.body.lastNodeId;
+        let lastOpr = req.body.lastOpr;
+        var nodeData = JSON.parse(req.body.rawNodeData);
+        gljDao.createNewNode(repId, lastOpr, lastNodeId, nodeData, function(err, msg, data){
+            callback(req,res,err,msg, data)
+        });
+    }
+    updateGljNodes(req, res) {
+        var nodes = JSON.parse(req.body.nodes);
+        let repId = req.body.repId,
+            lastOpr = req.body.lastOpr;
+        gljDao.updateNodes(repId, lastOpr, nodes, function(err,results){
+            callback(req,res, err, results)
+        });
+    }
+    deleteGljNodes(req, res) {
+        var nodes = JSON.parse(req.body.nodes);
+        var preNodeId = req.body.preNodeId;
+        var preNodeNextId = req.body.preNodeNextId;
+        let repId = req.body.repId, lastOpr = req.body.lastOpr;
+        gljDao.removeNodes(repId, lastOpr, nodes, preNodeId, preNodeNextId, function(err,results){
+            callback(req,res, err, results)
+        });
+    }
+    getGljItems(req, res) {
+        var repId = req.body.repositoryId,
+            gljType = req.body.type,
+            gljCode = req.body.code;
+        if (gljCode) {
+            gljDao.getGljItem(repId, gljCode, function(err, data){
+                callback(req,res,err,'Get Items', data)
+            });
+        } else if (gljType) {
+            gljDao.getGljItemByType(repId, gljType, function(err, data){
+                callback(req,res,err,'Get Types', data)
+            });
+        } else {
+            gljDao.getGljItemsByRep(repId, function(err, data){
+                callback(req,res,err,'Get Items',data)
+            });
+        }
+    }
+    getGljItemsByIds(req, res) {
+        var gljIds = JSON.parse(req.body.gljIds);
+        gljDao.getGljItems(gljIds, function(err, data){
+            callback(req,res,err,'Get Items',data)
+        });
+    }
+    getGljItemsByCodes(req, res) {
+        var gljCodes = JSON.parse(req.body.gljCodes),
+            repId = req.body.repId;
+        gljDao.getGljItemsByCode(repId, gljCodes, function(err, data){
+            callback(req,res,err,'Get Items',data)
+        });
+    }
+    updateComponent(req, res){
+        let libId = req.body.libId,
+            updateArr = req.body.updateArr,
+            oprtor = req.body.oprtor;
+        gljDao.updateComponent(libId, oprtor, updateArr, function (err, message, rst) {
+            callback(req, res, err, message, rst);
+        })
+    }
+    mixUpdateGljItems(req, res){
+        var repId = req.body.repositoryId,
+            updateItems = JSON.parse(req.body.updateItems),
+            addItems = JSON.parse(req.body.addItems),
+            removeIds = JSON.parse(req.body.removeIds),
+            lastOpr = req.body.lastOpr;
+        gljDao.mixUpdateGljItems(repId, lastOpr, updateItems, addItems, removeIds, function(err, message, rst){
+            if (err) {
+                callback(req, res, err, message, null);
+            } else {
+                callback(req, res, err, message, rst);
+            }
+        });
+    }
+
+}
+
+export default GljController;

+ 66 - 0
modules/std_glj_lib/controllers/gljMapController.js

@@ -0,0 +1,66 @@
+/**
+ * Created by Zhong on 2017/8/11.
+ */
+
+import BaseController from "../../common/base/base_controller";
+import {GljMapDao} from "../models/gljMapModel";
+import CompilationModel from "../../users/models/compilation_model";
+let gljMapDao = new GljMapDao();
+
+let callback = function(req, res, err, message, data){
+    res.json({error: err, message: message, data: data});
+};
+class GljMapController extends BaseController{
+    async getCompilationList(req, res){
+        try{
+            let compilationModel = new CompilationModel(), rst = [];
+            let compilationList = await compilationModel.getCompilationList();
+            if(compilationList.length <= 0){
+                throw '没有数据';
+            }
+            else{
+
+                compilationList.forEach(function (compilation) {
+                    rst.push({_id: compilation._id, name: compilation.name});
+                })
+                callback(req, res, false, '', rst);
+            }
+        }
+        catch(err) {
+            callback(req, res, err, '没有数据', null);
+        }
+    }
+    getGljLib(req, res){
+        let libId = req.body.libId;
+        gljMapDao.getGljLib(libId, function (err, message, data) {
+            callback(req, res, err, message, data);
+        })
+    }
+    getAllGljLib(req, res){
+        gljMapDao.getAllGljLib(function (err, message, data) {
+            callback(req, res, err, message, data);
+        })
+    }
+    createGljLib(req, res){
+        let gljLibObj = JSON.parse(req.body.gljLibObj);
+        gljMapDao.createGljLib(gljLibObj, function (err, message, data) {
+            callback(req, res, err, message, data);
+        })
+    }
+    renameGljLib(req, res){
+        let oprtor = req.body.oprtor,
+            renameObj = JSON.parse(req.body.renameObj);
+        gljMapDao.renameGljLib(oprtor, renameObj, function (err, message) {
+            callback(req, res, err, message, null);
+        })
+    }
+    removeGljLib(req, res){
+        let oprtor = req.body.oprtor,
+            libId = req.body.libId;
+        gljMapDao.removeGljLib(oprtor, libId, function (err, message) {
+            callback(req, res, err, message, null);
+        });
+    }
+}
+
+export default GljMapController;

+ 23 - 0
modules/std_glj_lib/controllers/viewsController.js

@@ -0,0 +1,23 @@
+/**
+ * Created by Zhong on 2017/8/11.
+ * 标准工料机库页面控制器
+ */
+
+import BaseController from "../../common/base/base_controller";
+
+class ViewsController extends BaseController{
+    redirectMain(req, res){
+        res.render('maintain/std_glj_lib/html/main.html',
+        {
+            userAccount: req.session.managerData.username
+        });
+    }
+    redirectGlj(req, res){
+        res.render('maintain/std_glj_lib/html/gongliao.html',
+        {
+            userAccount: req.session.managerData.username
+        });
+    }
+}
+
+export default ViewsController;

+ 150 - 0
modules/std_glj_lib/models/gljMapModel.js

@@ -0,0 +1,150 @@
+/**
+ * Created by Zhong on 2017/8/11.
+ */
+import {gljMapModel} from "./schemas";
+import moment from "moment";
+import counter from "../../../public/counter/counter";
+import async from "async";
+
+class OprDao {
+    static updateOprArr(findSet, oprtor, date, cb){
+        let oprDate = moment(date).format('YYYY-MM-DD HH:mm:ss');
+        gljMapModel.find(findSet, function (err, result) {
+            if(err){
+                cb(err);
+            }
+            else{
+                if(result.length === 1){
+                    let recentOprArr = result[0].recentOpr;
+                    let isExist = false;
+                    for(let i =0 ; i<recentOprArr.length; i++){
+                        if(recentOprArr[i].operator === oprtor){
+                            recentOprArr[i].operateDate = oprDate;
+                            isExist = true;
+                        }
+                    }
+                    if(!isExist){
+                        if(recentOprArr.length < 5){
+                            recentOprArr.push({operator: oprtor, operateDate: oprDate});
+                        }
+                        else if(recentOprArr.length === 5){
+                            recentOprArr.sort(function (a, b) {
+                                if(a.operateDate > b.operateDate){
+                                    return -1;
+                                }else {
+                                    return 1;
+                                }
+                                return 0;
+                            });
+                            recentOprArr.splice(recentOprArr.length -1, 1);
+                            recentOprArr.splice(0, 1, {operator: oprtor, operateDate: oprDate});
+                        }
+                    }
+                    gljMapModel.update(findSet, {$set: {recentOpr: recentOprArr}}, function (err) {
+                        if(err){
+                            cb(err);
+                        }
+                        else{
+                            cb(null);
+                        }
+                    });
+                }
+                else{
+                    cb(err);
+                }
+            }
+        });
+    };
+}
+
+
+class GljMapDao extends OprDao{
+   static createNewLibModel(gljLibObj){
+        var rst = {};
+        rst.dispName = gljLibObj.dispName;
+        rst.appType = gljLibObj.appType?gljLibObj.appType:'construct';
+        rst.compilationId = gljLibObj.compilationId?gljLibObj.compilationId: -1;
+        rst.compilationName = gljLibObj.compilationName?gljLibObj.compilationName:'';
+        rst.creator = gljLibObj.creator;
+        rst.createDate = moment(Date.now()).format('YYYY-MM-DD HH:mm:ss');
+        rst.recentOpr = [{operator: gljLibObj.creator, operateDate: rst.createDate}];
+        rst.deleted = false;
+        return rst;
+    }
+
+    getGljLib(libId, callback){
+        gljMapModel.find({ID: libId}, function (err, result) {
+            if(err){
+                callback(err, '没有数据!', null);
+            }
+            else{
+                callback(null, '成功', result);
+            }
+        })
+    }
+    getAllGljLib(callback){
+        gljMapModel.find({deleted: false}, function (err, result) {
+            if(err){
+                callback(err, '没有定额库数据!', null);
+            }
+            else{
+                callback(null, '成功', result);
+            }
+        })
+    }
+    createGljLib(gljLibObj, callback){
+        counter.counterDAO.getIDAfterCount(counter.moduleName.stdGljLib, 1, function (err, result) {
+            if(err){
+                callback(err, '获取新ID失败!');
+            }
+            else{
+                let newGljLib = GljMapDao.createNewLibModel(gljLibObj);
+                newGljLib.ID = result.value.sequence_value;
+                gljMapModel.create(newGljLib, function (err, result) {
+                    if(err){
+                        callback(err, '创建新工料机库失败!', null);
+                    }
+                    else{
+                        callback(null, '创建成功!', result);
+                    }
+                });
+            }
+        })
+    }
+    renameGljLib(oprtor, renameObj, callback){
+        gljMapModel.update({ID: renameObj.ID, deleted: false}, {$set: {dispName: renameObj.newName}}, function (err) {
+            if(err){
+                callback(err, '重命名失败!');
+            }
+            else{
+                GljMapDao.updateOprArr({ID: renameObj.ID, deleted: false}, oprtor, Date.now(), function (err) {
+                    if(err){
+                        callback(err, '更新最近操作者失败!');
+                    }
+                    else{
+                        callback(null, '成功!');
+                    }
+                });
+            }
+        });
+    }
+    removeGljLib(oprtor, libId, callback){
+        GljMapDao.updateOprArr({ID: libId, deleted: false}, oprtor, Date.now(), function (err) {
+            if(err){
+                callback(err, '失败!')
+            }
+            else{
+                gljMapModel.update({ID: libId, deleted: false}, {$set: {deleted: true}}, function (err) {
+                    if(err){
+                        callback(err, '移除工料机库失败!');
+                    }
+                    else{
+                        callback(null, '成功!');
+                    }
+                });
+            }
+        });
+    }
+}
+
+export {OprDao, GljMapDao};

+ 334 - 0
modules/std_glj_lib/models/gljModel.js

@@ -0,0 +1,334 @@
+/**
+ * Created by Zhong on 2017/8/11.
+ */
+import {gljMapModel, gljModel, gljClassModel, gljClassTemplateModel} from "./schemas";
+import {OprDao} from  "./gljMapModel";
+import moment from "moment";
+import counter from "../../../public/counter/counter";
+import async from "async";
+
+class GljDao  extends OprDao{
+    getGljTypes (gljLibId, callback){
+        gljClassModel.find({"repositoryId": gljLibId, "$or": [{"isDeleted": null}, {"isDeleted": false} ]},function(err,data){
+            if(data.length) {
+                callback(false,data);
+            }
+            else  if(err) callback("获取工料机类型错误!",false)
+            else {
+                gljClassTemplateModel.find({'$or': [{isDeleted: null}, {isDeleted: false}]}, function (err, datas) {
+                    if(err){
+                        callback("获取工料机类型错误!", false);
+                    }
+                    else{
+                        let rst = [];
+                        async.each(datas, function (data, cb) {
+                            let newClassObj = {};
+                            newClassObj.ID = data.ID;
+                            newClassObj.ParentID = data.ParentID;
+                            newClassObj.NextSiblingID = data.NextSiblingID;
+                            newClassObj.Name = data.Name;
+                            newClassObj.repositoryId = gljLibId;
+                            gljClassModel.create(newClassObj, function(err){
+                                if(err)cb(err);
+                                else{
+                                    rst.push(newClassObj);
+                                    cb(null);
+                                }
+                            });
+                        }, function (err) {
+                            if(err) callback("新增工料机类型错误!", false);
+                            else callback(false, rst);
+                        });
+                    }
+                });
+            }
+        })
+    }
+
+    getGljItemsByRep(repositoryId,callback){
+        gljModel.find({"repositoryId": repositoryId},function(err,data){
+            if(err) callback(true, "")
+            else callback(false,data);
+        })
+    }
+
+    getGljItemByType (repositoryId, type, callback){
+        gljModel.find({"repositoryId": repositoryId, "gljType": type},function(err,data){
+            if(err) callback(true, "")
+            else callback(false, data);
+        })
+    };
+
+    getGljItem (repositoryId, code, callback){
+        gljModel.find({"repositoryId": repositoryId, "code": code},function(err,data){
+            if(err) callback(true, "")
+            else callback(false, data);
+        })
+    };
+
+    getGljItems (gljIds, callback){
+        gljModel.find({"ID": {"$in": gljIds}},function(err,data){
+            if(err) callback(true, "")
+            else callback(false, data);
+        })
+    };
+
+    getGljItemsByCode (repositoryId, codes, callback){
+        gljModel.find({"repositoryId": repositoryId,"code": {"$in": codes}},function(err,data){
+            if(err) callback(true, "")
+            else callback(false, data);
+        })
+    };
+
+    updateComponent(libId, oprtor, updateArr, callback){
+        let parallelFucs = [];
+        for(let i = 0; i < updateArr.length; i++){
+            parallelFucs.push((function(obj){
+                return function (cb) {
+                    if(typeof obj.component === 'undefined'){
+                        obj.component = [];
+                    }
+                    gljModel.update({repositoryId: libId, ID: obj.ID}, obj, function (err, result) {
+                        if(err){
+                            cb(err);
+                        }
+                        else{
+                            cb(null, obj);
+                        }
+                    })
+                }
+            })(updateArr[i]));
+        }
+        parallelFucs.push((function () {
+            return function (cb) {
+                GljDao.updateOprArr({ID: libId}, oprtor, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
+                    if(err){
+                        cb(err);
+                    }
+                    else{
+                        cb(null);
+                    }
+                })
+            }
+        })());
+        async.parallel(parallelFucs, function (err, result) {
+            if(err){
+                callback(err, '更新组成物错误!', null);
+            }
+            else{
+                console.log(result);
+                callback(null, '成功!', result);
+            }
+        });
+    }
+
+    mixUpdateGljItems (repId, lastOpr, updateItems, addItems, rIds, callback) {
+        var me = this;
+        if (updateItems.length == 0 && rIds.length == 0) {
+            me.addGljItems(repId, lastOpr, addItems, callback);
+        } else {
+            me.removeGljItems(repId, lastOpr, rIds, function(err, message, docs) {
+                me.updateGljItems(repId, lastOpr, updateItems, function(err, results){
+                    if (err) {
+                        callback(true, "Fail to update", false);
+                    } else {
+                        if (addItems && addItems.length > 0) {
+                            me.addGljItems(repId, lastOpr, addItems, callback);
+                        } else {
+                            callback(false, "Save successfully", results);
+                        }
+                    }
+                });
+            });
+        }
+    };
+
+    removeGljItems (repId, lastOpr, rIds, callback) {
+        if (rIds && rIds.length > 0) {
+            gljModel.collection.remove({ID: {$in: rIds}}, null, function(err, docs){
+                if (err) {
+                    callback(true, "Fail to remove", false);
+                } else {
+                    GljDao.updateOprArr({ID: repId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
+                        if(err){
+                            callback(true, "Fail to update operator", false);
+                        }
+                        else{
+                            callback(false, "Remove successfully", docs);
+                        }
+                    });
+                }
+            })
+        } else {
+            callback(false, "No records were deleted!", null);
+        }
+    }
+
+    addGljItems (repId, lastOpr, items, callback) {
+        if (items && items.length > 0) {
+            counter.counterDAO.getIDAfterCount(counter.moduleName.GLJ, items.length, function(err, result){
+                var maxId = result.value.sequence_value;
+                var arr = [];
+                for (var i = 0; i < items.length; i++) {
+                    var obj = new gljModel(items[i]);
+                    obj.ID = (maxId - (items.length - 1) + i);
+                    obj.repositoryId = repId;
+                    arr.push(obj);
+                }
+                gljModel.collection.insert(arr, null, function(err, docs){
+                    if (err) {
+                        callback(true, "Fail to add", false);
+                    } else {
+                        GljDao.updateOprArr({ID: repId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
+                            if(err){
+                                callback(true, "Fail to update Operator", false);
+                            }
+                            else{
+                                callback(false, "Add successfully", docs);
+                            }
+                        });
+                    }
+                })
+            });
+        } else {
+            callback(true, "No source", false);
+        }
+    }
+
+    updateGljItems(repId, lastOpr, items, callback) {
+        var functions = [];
+        for (var i=0; i < items.length; i++) {
+            functions.push((function(doc) {
+                return function(cb) {
+                    var filter = {};
+                    if (doc.ID) {
+                        filter.ID = doc.ID;
+                    } else {
+                        filter.repositoryId = repId;
+                        filter.code = doc.code;
+                    }
+                    gljModel.update(filter, doc, cb);
+                };
+            })(items[i]));
+        }
+        functions.push((function () {
+            return function (cb) {
+                GljDao.updateOprArr({ID: repId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
+                    if(err){
+                        cb(err);
+                    }
+                    else{
+                        cb(null);
+                    }
+                })
+            }
+        })());
+        async.parallel(functions, function(err, results) {
+            callback(err, results);
+        });
+    }
+
+    updateNodes (repId, lastOpr, nodes, callback) {
+        var functions = [];
+        for (var i=0; i < nodes.length; i++) {
+            functions.push((function(doc) {
+                return function(cb) {
+                    gljClassModel.update({ID: doc.ID}, doc, cb);
+                };
+            })(nodes[i]));
+        }
+        functions.push((function () {
+            return function (cb) {
+                GljDao.updateOprArr({ID: repId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
+                    if(err){
+                        cb(err);
+                    }
+                    else{
+                        cb(null);
+                    }
+                })
+            }
+        })());
+        async.parallel(functions, function(err, results) {
+            callback(err, results);
+        });
+    }
+    removeNodes (repId, lastOpr, nodeIds, preNodeId, preNodeNextId, callback){
+        var functions = [];
+        if (preNodeId != -1) {
+            functions.push((function(nodeId, nextId) {
+                return function(cb) {
+                    gljClassModel.update({ID: nodeId}, {"NextSiblingID": nextId}, cb);
+                };
+            })(preNodeId, preNodeNextId));
+        }
+        for (var i=0; i < nodeIds.length; i++) {
+            functions.push((function(nodeId) {
+                return function(cb) {
+                    gljClassModel.update({ID: nodeId}, {"isDeleted": true}, cb);
+                };
+            })(nodeIds[i]));
+        }
+        functions.push((function () {
+            return function (cb) {
+                GljDao.updateOprArr({ID: repId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
+                    if(err){
+                        cb(err);
+                    }
+                    else{
+                        cb(null);
+                    }
+                })
+            }
+        })());
+        async.parallel(functions, function(err, results) {
+            callback(err, results);
+        });
+    }
+
+    createNewNode(repId, lastOpr, lastNodeId, nodeData, callback) {
+        return counter.counterDAO.getIDAfterCount(counter.moduleName.GLJ, 1, function(err, result){
+            nodeData.repositoryId = repId;
+            nodeData.ID = result.value.sequence_value;
+            var node = new gljModel(nodeData);
+            async.parallel([
+                function (cb) {
+                    node.save(function (err, result) {
+                        if (err) {
+                            cb("章节树ID错误!", false);
+                        } else {
+                            if (lastNodeId > 0) {
+                                gljClassModel.update({ID: lastNodeId}, {"NextSiblingID": nodeData.ID}, function(err, rst){
+                                    if (err) {
+                                        cb("章节树ID错误!", false);
+                                    } else {
+                                        cb(false, result);
+                                    }
+                                });
+                            } else cb(false, result);
+                        }
+                    });
+                },
+                function (cb) {
+                    GljDao.updateOprArr({ID: repId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
+                        if(err){
+                            cb(err);
+                        }
+                        else{
+                            cb(null);
+                        }
+                    })
+                }
+            ], function (err, result) {
+                if(err){
+                    callback(true, "章节树错误!", false);
+                }
+                else{
+                    callback(false, '', result[0]);
+                }
+            })
+        });
+    }
+}
+
+export default GljDao;

+ 65 - 0
modules/std_glj_lib/models/schemas.js

@@ -0,0 +1,65 @@
+/**
+ * Created by Zhong on 2017/8/11.
+ */
+import mongoose from "mongoose";
+let Schema = mongoose.Schema;
+let gljMapSchema = new Schema({
+    deleted: false,
+    ID: Number,
+    dispName: String,
+    appType: String,
+    creator: String,
+    createDate: String,
+    recentOpr: [],
+    compilationId: String,
+    compilationName: String
+},
+    {versionKey: false});
+
+let gjlComponentSchema = mongoose.Schema(
+    {
+        ID: Number,
+        consumeAmt: Number
+    },
+    {_id: false},
+    {versionKey: false}
+);
+
+let gljSchema = new Schema({
+    deleted: false,
+    repositoryId: Number,
+    ID: Number,
+    code: String,
+    name: String,
+    specs: String,
+    basePrice: Number,
+    gljClass: Number,
+    gljType: Number,
+    shortName: String,
+    component: [gjlComponentSchema]
+},{versionKey: false});
+
+let gljClassSchema = mongoose.Schema({
+    repositoryId: Number,
+    ID: Number,
+    ParentID: Number,
+    NextSiblingID: Number,
+    Name: String,
+    isDeleted: Boolean
+}, {versionKey: false});
+
+let gljClassTemplate = mongoose.Schema({
+    ID: Number,
+    ParentID: Number,
+    NextSiblingID: Number,
+    Name: String,
+    isDeleted: Boolean
+}, {versionKey: false});
+
+
+let gljMapModel = mongoose.model('std_glj_lib_map', gljMapSchema, 'std_glj_lib_map');
+let gljModel = mongoose.model('std_glj_lib_gljList', gljSchema, 'std_glj_lib_gljList');
+let gljClassModel = mongoose.model('std_glj_lib_gljClass', gljClassSchema, 'std_glj_lib_gljClass');
+let gljClassTemplateModel = mongoose.model('std_glj_lib_gljClassTemplate', gljClassTemplate, 'std_glj_lib_gljClassTemplate');
+
+export {gljMapModel, gljModel, gljClassModel, gljClassTemplateModel};

+ 41 - 0
modules/std_glj_lib/routes/routes.js

@@ -0,0 +1,41 @@
+/**
+ * Created by Zhong on 2017/8/11.
+ * 标准工料机库路由
+ */
+
+import express from "express";
+import ViewsController from "../controllers/viewsController";
+import GljMapController from "../controllers/gljMapController";
+import GljController from "../controllers/gljController";
+
+let router = express.Router();
+let viewsController = new ViewsController(),
+    gljMapController = new GljMapController(),
+    gljController = new GljController();
+
+module.exports = function (app) {
+    app.get('/stdGljRepository/main', viewsController.auth, viewsController.init, viewsController.redirectMain);
+    app.get('/stdGljRepository/glj', viewsController.auth, viewsController.init, viewsController.redirectGlj);
+
+    router.post('/getCompilationList', gljMapController.auth, gljMapController.init, gljMapController.getCompilationList);
+    router.post('/getGljLib', gljMapController.auth, gljMapController.init, gljMapController.getGljLib);
+    router.post('/getAllGljLib', gljMapController.auth, gljMapController.init, gljMapController.getAllGljLib);
+    router.post('/createGljLib', gljMapController.auth, gljMapController.init, gljMapController.createGljLib);
+    router.post('/renameGljLib', gljMapController.auth, gljMapController.init, gljMapController.renameGljLib);
+    router.post('/removeGljLib', gljMapController.auth, gljMapController.init, gljMapController.removeGljLib);
+
+
+    router.post("/createNewGljTypeNode",gljController.auth, gljController.init, gljController.createNewGljTypeNode);
+    router.post("/updateGljNodes",gljController.auth, gljController.init, gljController.updateGljNodes);
+    router.post("/deleteGljNodes",gljController.auth, gljController.init, gljController.deleteGljNodes);
+    router.post("/getGljDistType",gljController.auth, gljController.init, gljController.getGljDistType);
+    router.post("/getGljTree",gljController.auth, gljController.init, gljController.getGljTree);
+    router.post("/getGljItems",gljController.auth, gljController.init, gljController.getGljItems);
+    router.post("/updateComponent",gljController.auth, gljController.init, gljController.updateComponent);
+    router.post("/mixUpdateGljItems",gljController.auth, gljController.init, gljController.mixUpdateGljItems);
+    router.post("/getGljItemsByIds",gljController.auth, gljController.init, gljController.getGljItemsByIds);
+    router.post("/getGljItemsByCodes",gljController.auth, gljController.init, gljController.getGljItemsByCodes);
+
+    app.use("/stdGljRepository/api", router);
+
+};

+ 7 - 1
modules/users/controllers/compilation_controller.js

@@ -9,6 +9,7 @@ import BaseController from "../../common/base/base_controller";
 import CompilationModel from "../models/compilation_model";
 import STDRationLibMapModel from "../../common/std/std_ration_lib_map_model";
 import STDBillLibListsModel from "../../common/std/std_bills_lib_lists_model";
+import STDGLJLibMapModel from "../../common/std/std_glj_lib_map_model";
 import {default as EngineeringConst, List as EngineeringList} from "../../common/const/engineering";
 
 class CompilationController extends BaseController {
@@ -114,6 +115,7 @@ class CompilationController extends BaseController {
         let compilationList = [];
         let valuationData = {};
         let valuationList = {};
+        let gljList = [];
         try {
             let compilationModel = new CompilationModel();
             compilationList = await compilationModel.getCompilationList();
@@ -126,6 +128,10 @@ class CompilationController extends BaseController {
             let stdRationLibMapModel = new STDRationLibMapModel();
             rationList = await stdRationLibMapModel.getRationLib(selectedCompilation._id);
 
+            // 获取工料机库
+            let stdGLJLibMapModel = new STDGLJLibMapModel();
+            gljList = await stdGLJLibMapModel.getGLJLibList(selectedCompilation._id);
+
             // 获取对应的计价规则数据
             [valuationData, valuationList] = await compilationModel.getValuation(selectedCompilation._id, valuationId, section);
             if (Object.keys(valuationData).length <= 0) {
@@ -140,7 +146,7 @@ class CompilationController extends BaseController {
             compilationList: compilationList,
             billList: JSON.stringify(billList),
             rationList: JSON.stringify(rationList),
-
+            gljList: JSON.stringify(gljList),
             mainTreeCol: JSON.stringify(valuationData.main_tree_col),
             engineeringList: EngineeringList,
             selectedCompilation: selectedCompilation,

+ 11 - 1
modules/users/models/compilation_model.js

@@ -122,6 +122,7 @@ class CompilationModel extends BaseModel {
         let updateData = {};
         updateData[sectionString + ".$.bill_lib"] = data.bill_lib;
         updateData[sectionString + ".$.ration_lib"] = data.ration_lib;
+        updateData[sectionString + ".$.glj_lib"] = data.glj_lib;
         updateData[sectionString + ".$.name"] = data.name;
         updateData[sectionString + ".$.engineering"] = data.engineering;
         updateData[sectionString + ".$.main_tree_col"] = JSON.parse(data.main_tree_col);
@@ -184,7 +185,7 @@ class CompilationModel extends BaseModel {
         for(let tmp in data.bill_lib) {
             data.bill_lib[tmp] = JSON.parse(data.bill_lib[tmp]);
         }
-        // 判断定额清单
+        // 判断定额
         if (data.ration_lib === undefined || data.ration_lib === '') {
             throw '判断标准清单不能为空';
         }
@@ -193,6 +194,15 @@ class CompilationModel extends BaseModel {
             data.ration_lib[tmp] = JSON.parse(data.ration_lib[tmp]);
         }
 
+        // 判断工料机库
+        if (data.glj_lib === undefined || data.glj_lib === '') {
+            throw '判断工料机库不能为空';
+        }
+        data.glj_lib = data.glj_lib instanceof Array ? data.glj_lib : [data.glj_lib];
+        for(let tmp in data.glj_lib) {
+            data.glj_lib[tmp] = JSON.parse(data.glj_lib[tmp]);
+        }
+
         return data;
     }
 

+ 5 - 0
modules/users/models/schemas/compilation.js

@@ -27,6 +27,11 @@ let childrenSchema = new Schema({
         type: Schema.Types.Mixed,
         default: []
     },
+    // 工料机库
+    glj_lib: {
+        type: Schema.Types.Mixed,
+        default: []
+    },
     // 是否启用
     enable: {
         type: Boolean,

+ 1 - 0
public/counter/counter.js

@@ -29,6 +29,7 @@ const COUNTER_MODULE_NAME = {
     unitPriceFile: 'unitPriceFile',
     unitPriceGLJ: 'unitPriceGLJ',
     template_bills: 'temp_bills',
+    stdGljLib: 'stdGljLib',
     billsLib: 'billsLib',
     billsLib_jobs: 'billsLib_jobs',
     billsLib_items: 'billsLib_items',

+ 8 - 0
public/web/rpt_value_define.js

@@ -15,13 +15,16 @@ let JV = {
     NODE_NO_MAPPING_FIELDS: "无映射离散指标_集合",
     NODE_DISCRETE_PARAMS: "离散参数_集合",
     NODE_MASTER_FIELDS: "主数据指标_集合",
+    NODE_MASTER_FIELDS_EX: "主数据指标_拓展集合",
     NODE_DETAIL_FIELDS: "从数据指标_集合",
+    NODE_DETAIL_FIELDS_EX: "从数据指标_拓展集合",
     NODE_BAND_COLLECTION: "布局框_集合",
     NODE_FORMULAS: "计算式_集合",
     NODE_DISCRETE_INFO: "离散信息",
     NODE_BILL_INFO: "账单式表_信息",
     NODE_BILL_CONTENT : "账单式表_数据",
     NODE_FLOW_INFO: "流水式表_信息",
+    NODE_FLOW_INFO_EX: "流水式表_拓展信息",
     NODE_FLOW_GROUP: "流水式表_分组信息",
     NODE_FLOW_SEG_SUM: "流水式表_段统计信息",
     NODE_FLOW_PAGE_SUM: "流水式表_页统计信息",
@@ -43,6 +46,9 @@ let JV = {
     PROP_CMN_HEIGHT: "CommonHeight",
     PROP_CMN_WIDTH: "CommonWidth",
     PROP_BAND_NAME: "BandName",
+    PROP_BAND_NORMAL_ONLY: "normalOnly",
+    PROP_BAND_EX_ONLY: "exOnly",
+
     PROP_UNITS: "单位",
     PROP_PAGE_SIZE: "页规格",
     PROP_ORIENTATION: "方向",
@@ -119,6 +125,8 @@ let JV = {
     DATA_DISCRETE_DATA: "discrete_data",
     DATA_MASTER_DATA: "master_data",
     DATA_DETAIL_DATA: "detail_data",
+    DATA_MASTER_DATA_EX: "master_data_ex",
+    DATA_DETAIL_DATA_EX: "detail_data_ex",
 
     BLANK_FIELD_INDEX: -10,
     BLANK_VALUE_INDEX: -100,

+ 7 - 1
public/web/sheet/sheet_common.js

@@ -94,7 +94,12 @@ var sheetCommonObj = {
         var me = this, ch = GC.Spread.Sheets.SheetArea.viewport;
         sheet.suspendPaint();
         sheet.suspendEvent();
-        sheet.setRowCount(typeof repositoryGljObj !== 'undefined' && repositoryGljObj.currentOprParent === 1 ? data.length : data.length + 5);
+        if(typeof setting.owner !== 'undefined' && setting.owner === 'gljComponent'){
+            sheet.setRowCount(data.length + 5);
+        }
+        else{
+            sheet.setRowCount(typeof repositoryGljObj !== 'undefined' && repositoryGljObj.currentOprParent === 1 ? data.length : data.length + 5);
+        }
         for (var col = 0; col < setting.header.length; col++) {
             var hAlign = "left", vAlign = "center";
             if (setting.header[col].hAlign) {
@@ -118,6 +123,7 @@ var sheetCommonObj = {
                 }
                 else {
                     sheet.setValue(row, col, data[row][setting.header[col].dataCode], ch);
+                    sheet.setTag(row, 0, data[row].ID, ch);
                 }
             }
         }

+ 22 - 1
web/maintain/ration_repository/js/main.js

@@ -2,6 +2,7 @@
  * Created by Syusuke on 2017/3/17.
  */
 $(function(){
+    getCompilationList();
     getRationLibs();
 })
 
@@ -62,6 +63,27 @@ $("#deleteLib").click(function(){
 
 
 });
+function getCompilationList(){
+    $.ajax({
+        type: 'post',
+        url: 'api/getCompilationList',
+        dataType: 'json',
+        success: function (result) {
+            //addoptions
+            for(let i = 0; i < result.data.length; i++){
+               let $option =  $("<option >"+ result.data[i].name +"</option>");
+                $option.val( result.data[i]._id);
+                $('#compilationSels').append($option);
+            }
+            $('#compilationSels').on("change", function () {
+
+               console.log(this.selectedOptions);
+               console.log(this.selectedOptions[0].text);
+               console.log(this.selectedOptions[0].value);
+            });
+        }
+    });
+}
 function getRationLibs(){
     $.ajax({
         type:"POST",
@@ -70,7 +92,6 @@ function getRationLibs(){
         cache:false,
         timeout:5000,
         success:function(result){
-            console.log(result);
             $("tbody tr").html("");
             for(var i=0;i<result.data.length;i++){
                 addLibTag(result.data[i].dispName, result.data[i].ID, result.data[i].createDate);

+ 1 - 3
web/maintain/ration_repository/js/ration.js

@@ -441,9 +441,7 @@ var rationOprObj = {
                         return rst;
                     });
                     me.showRationItems(me.currentSectionId);
-                   /* me.workBook.getSheet(0).setActiveCell(me.activeCell.row, me.activeCell.col);
-                    let spreadBook = new GC.Spread.Sheets.Workbook(rationOprObj.sheet, { sheetCount: 1 });
-                    spreadBook.focus(true);*/
+                    me.workBook.getSheet(0).setActiveCell(me.activeCell.row, me.activeCell.col);
                 }
             },
             error:function(){

+ 50 - 42
web/maintain/ration_repository/js/ration_glj.js

@@ -56,9 +56,7 @@ var rationGLJOprObj = {
                 distTypeTree.comboDatas.push({text: distTypeObj.data.fullName, value: distTypeObj.data.ID});
             }
         });
-        //me.distTypeTree = distTypeTree;
         return distTypeTree;
-        //return distTypeTree.comboDatas;
     },
     getGljDistType: function (callback) {
         let me = this;
@@ -69,8 +67,6 @@ var rationGLJOprObj = {
             success: function (result) {
                 if(!result.error && callback){
                     me.distTypeTree = me.getDistTypeTree(result.data);
-                    console.log(`me.distTypeTree`);
-                    console.log(me.distTypeTree);
                     callback();
                 }
             }
@@ -92,22 +88,17 @@ var rationGLJOprObj = {
     rationGljDelOpr: function () {
         let me = rationGLJOprObj, spreadBook = me.sheet.getParent();
         spreadBook.commandManager().register('rationGljDelete', function () {
-            console.log(me.cache["_GLJ_" + me.currentRationItem.ID]);
             let sels = me.sheet.getSelections(), updateArr = [], removeArr = [], lockCols = me.setting.view.lockColumns;
             let cacheSection = me.cache["_GLJ_" + me.currentRationItem.ID], isUpdate = false;
-            console.log(`sels`);
-            console.log(sels);
             if(sels.length > 0){
                 for(let sel = 0; sel < sels.length; sel++){
                     if(sels[sel].colCount === me.setting.header.length){
                         if(cacheSection){
                             for(let i = 0; i < sels[sel].rowCount; i++){
                                 if(sels[sel].row + i < cacheSection.length){
-                                    //removeArr.push(cacheSection[sels[sel].row + i].ID);
                                     isUpdate = true;
                                     cacheSection.splice(sels[sel].row + i, 1);
                                     me.updateRationItem();
-                                    //me.rationsCodes.splice(me.rationsCodes.indexOf(cacheSection[sels[sel].row + i].code), 1);
                                 }
                             }
                         }
@@ -125,7 +116,6 @@ var rationGLJOprObj = {
                             });
                         }
                         else if(sels[sel].col !== 0 && sels[sel].col !== 5 && !(sels[sel].col === 1 && sels.col + sels[sel].colCount -1 === 3)){
-                            console.log(`enter`);
                             if(cacheSection){
                                 for(let i = sels[sel].row === -1 ? 1 : 0; i < sels[sel].rowCount; i++){
                                     if(sels[sel].row + i < cacheSection.length){
@@ -137,7 +127,6 @@ var rationGLJOprObj = {
                                             }
                                         }
                                     }
-                                    //updateArr.push(cacheSection[sels[sel].row + i]);
                                 }
                             }
                         }
@@ -250,7 +239,7 @@ var rationGLJOprObj = {
             }
         } else {
             //重新更新工料机
-            if (args.editingText == null || args.editingText.trim() == "") {
+            /*if (args.editingText == null || args.editingText.trim() == "") {
                 //delete
                 if (me.cache["_GLJ_" + me.currentRationItem.ID]) {
                     var cacheArr = me.cache["_GLJ_" + me.currentRationItem.ID];
@@ -261,12 +250,13 @@ var rationGLJOprObj = {
                         me.showGljItems(me.currentRationItem.ID);
                     }
                 }
-            } else {
+            } else*/
+            if(args.editingText !== null && args.editingText.trim().length !== 0){
                 var repId = storageUtil.getSessionCache("RationGrp","repositoryID");
                 if (repId) {
                     var codes = [];
                     codes.push(args.editingText.trim());
-                    me.addGljItems(codes, repId);
+                    me.addGljItems(codes, repId, args);
                 }
             }
         }
@@ -286,7 +276,7 @@ var rationGLJOprObj = {
         });
     },
 
-    addGljItems: function(codes, repId) {
+    addGljItems: function(codes, repId, args) {
         var me = this;
         $.ajax({
             type:"POST",
@@ -296,38 +286,56 @@ var rationGLJOprObj = {
             cache:false,
             timeout:5000,
             success:function(result){
-                sheetCommonObj.cleanSheet(me.sheet, me.setting, -1);
+                //sheetCommonObj.cleanSheet(me.sheet, me.setting, -1);
                 if (result) {
-                    var rstArr = [], dummyR = {gljId: 0, consumeAmt:0}, newAddArr = [];
-                    for (var i = 0; i < result.data.length; i++) {
-                        dummyR.gljId = result.data[i].ID;
-                        rstArr.push(me.createRationGljDisplayItem(dummyR, result.data[i]));
-                    }
-                    if (me.cache["_GLJ_" + me.currentRationItem.ID]) {
-                        var cacheArr = me.cache["_GLJ_" + me.currentRationItem.ID];
-                        for (var i = 0; i < rstArr.length; i++) {
-                            var hasDup = false;
-                            for (var j = 0; j < cacheArr.length; j++) {
-                                if (cacheArr[j].gljId == rstArr[i].gljId) {
-                                    hasDup = true;
-                                    break;
+                    if(result.data.length > 0){
+                        sheetCommonObj.cleanSheet(me.sheet, me.setting, -1);
+                        var rstArr = [], dummyR = {gljId: 0, consumeAmt:0}, newAddArr = [];
+                        for (var i = 0; i < result.data.length; i++) {
+                            dummyR.gljId = result.data[i].ID;
+                            rstArr.push(me.createRationGljDisplayItem(dummyR, result.data[i]));
+                        }
+                        if (me.cache["_GLJ_" + me.currentRationItem.ID]) {
+                            var cacheArr = me.cache["_GLJ_" + me.currentRationItem.ID];
+                            for (var i = 0; i < rstArr.length; i++) {
+                                var hasDup = false;
+                                for (var j = 0; j < cacheArr.length; j++) {
+                                    if (cacheArr[j].gljId == rstArr[i].gljId) {
+                                        hasDup = true;
+                                        break;
+                                    }
+                                }
+                                if (!hasDup) {
+                                    newAddArr.push(rstArr[i]);
                                 }
                             }
-                            if (!hasDup) {
-                                newAddArr.push(rstArr[i]);
-                            }
+                            me.cache["_GLJ_" + me.currentRationItem.ID] = cacheArr.concat(newAddArr);
+                            me.cache["_GLJ_" + me.currentRationItem.ID].sort(function(a, b) {
+                                var rst = 0;
+                                if (a.code > b.code) rst = 1
+                                else if (a.code < b.code) rst = -1;
+                                return rst;
+                            });
+                        }
+                        me.showGljItems(me.currentRationItem.ID);
+                        if (newAddArr.length > 0) {
+                            me.updateRationItem();
                         }
-                        cacheArr.sort(function(a, b) {
-                            var rst = 0;
-                            if (a.code > b.code) rst = 1
-                            else if (a.code < b.code) rst = -1;
-                            return rst;
-                        });
-                        me.cache["_GLJ_" + me.currentRationItem.ID] = cacheArr.concat(newAddArr);
                     }
-                    me.showGljItems(me.currentRationItem.ID);
-                    if (newAddArr.length > 0) {
-                        me.updateRationItem();
+                    else{
+                        $('#alertModalBtn').click();
+                        $('#alertText').text("工料机"+ codes + "不存在,请查找你所需要的工料机,或新增工料机");
+                        me.sheet.options.isProtected = true;
+                        $('#alertModalCls').click(function () {
+                            sheetCommonObj.lockCells(me.sheet, me.setting);
+                            me.showGljItems(me.currentRationItem.ID);
+                            args.sheet.setValue(args.row, args.col, '');
+                        });
+                        $('#alertModalCof').click(function () {
+                            sheetCommonObj.lockCells(me.sheet, me.setting);
+                            me.showGljItems(me.currentRationItem.ID);
+                           args.sheet.setValue(args.row, args.col, '');
+                        })
                     }
                 }
                 sheetCommonObj.lockCells(me.sheet, me.setting);

+ 3 - 3
web/maintain/ration_repository/js/repository_glj.js

@@ -87,11 +87,11 @@ var pageOprObj = {
             }
         });
         distTypeTree.distTypesArr.forEach(function (distTypeObj) {
-            if(distTypeObj.children.length === 0 && distTypeObj.data.fullName !== '普通机械' &&distTypeObj.data.fullName !== '机械组成物'
+            /*if(distTypeObj.children.length === 0 && distTypeObj.data.fullName !== '普通机械' &&distTypeObj.data.fullName !== '机械组成物'
             && distTypeObj.data.fullName !== '机上人工'){
                 distTypeTree.comboDatas.push({text: distTypeObj.data.fullName, value: distTypeObj.data.ID});
-            }
-            if(distTypeObj.data.fullName === '机械'){
+            }*/
+            if(distTypeObj.data.fullName !== '材料'){
                 distTypeTree.comboDatas.push({text: distTypeObj.data.fullName, value: distTypeObj.data.ID});
             }
         });

+ 0 - 2
web/maintain/ration_repository/js/section_tree.js

@@ -322,8 +322,6 @@ var zTreeOprObj = {
         $("#addBtn_"+treeNode.tId).unbind().remove();
     },
     onClick: function(event,treeId,treeNode) {
-        console.log(`treeNode`);
-        console.log(treeNode);
         var sectionID = treeNode.ID;
         if (!(treeNode.items) || treeNode.items.length == 0) {
             rationOprObj.getRationItems(sectionID);

+ 34 - 2
web/maintain/ration_repository/main.html

@@ -46,7 +46,7 @@
         </div>
     </div>
     <!--弹出添加-->
-    <div class="modal fade" id="add" data-backdrop="static" style="display: none;" aria-hidden="true">
+    <!--<div class="modal fade" id="add" data-backdrop="static" style="display: none;" aria-hidden="true">
         <div class="modal-dialog" role="document">
             <div class="modal-content">
                 <div class="modal-header">
@@ -69,6 +69,38 @@
                 </div>
             </div>
         </div>
+    </div>-->
+    <div class="modal fade" id="add" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h5 class="modal-title">添加定额库</h5>
+                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">×</span>
+                    </button>
+                </div>
+                <div class="modal-body">
+                    <form>
+                        <div class="form-group">
+                            <label>定额库名称</label>
+                            <input class="form-control" placeholder="输入定额库名称" type="text">
+                        </div>
+                        <div class="form-group">
+                            <label>编办名称</label>
+                            <select id="compilationSels" class="form-control"></select>
+                        </div>
+                        <div class="form-group">
+                            <label>工料机库</label>
+                            <select id="gljLibSels" class="form-control"></select>
+                        </div>
+                    </form>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <a href="" class="btn btn-primary">新建</a>
+                </div>
+            </div>
+        </div>
     </div>
     <!--弹出编辑-->
     <div class="modal fade" id="edit" data-backdrop="static" style="display: none;" aria-hidden="true">
@@ -130,7 +162,7 @@
     <script type="text/javascript" src="/public/web/storageUtil.js"></script>
 </body>
 <script type="text/javascript">
-let userAccount = '<%=userAccount %>';
+    let userAccount = '<%=userAccount %>';
 </script>
 
 </html>

+ 1 - 0
web/maintain/report/rpt_test.html

@@ -20,6 +20,7 @@
                     <option value="2">07-1表</option>
                     <option value="1">08-2表</option>
                     <option value="3">计量-清单支付09表</option>
+                    <option value="88">多流水测试报表</option>
                 </select>
                 <select name="select2" id="select_k2" onchange="ajaxCall()">
                     <option value="A4">A4</option>

+ 279 - 0
web/maintain/std_glj_lib/css/main.css

@@ -0,0 +1,279 @@
+/*building SAAS 0.1*/
+/*bootstrap 初始化*/
+body {
+    font-size: 0.9rem
+}
+.dropdown-menu {
+    font-size: 0.9rem
+}
+/*自定义css*/
+.header {
+    background: #e1e1e1
+}
+.header .header-logo {
+    background: #ff6501;
+    color: #fff;
+    float: left;
+    padding-top: .25rem;
+    padding-bottom: .25rem;
+    margin-right: 1rem;
+    font-size: 1.25rem;
+    line-height: inherit
+}
+.top-msg{
+  position: fixed;
+  top:0;
+  width:100%;
+  z-index: 999
+}
+.in-1{padding-left:0rem!important}
+.in-2{padding-left:1rem!important}
+.in-3{padding-left:1.5rem!important}
+.in-4{padding-left:2rem!important}
+.in-5{padding-left:2.5rem!important}
+.in-6{padding-left:3rem!important}
+.main {
+    position: relative;
+    background: #f7f7f9;
+}
+.main-nav {
+    position: absolute;
+    text-align: center;
+    z-index: 999;
+    padding: 2px 0 0 2px
+}
+.main-nav .nav a {
+    display: block;
+    width: 28px;
+    text-align: center;
+    line-height: 18px;
+    color: #999;
+    padding: 10px 0;
+    border-right: 1px solid #ccc;
+}
+.main-nav .nav a:hover {
+    background: #fff;
+    color: #333;
+    text-decoration: none;
+}
+.main-nav .nav a.active {
+    border: 1px solid #ccc;
+    border-right: 1px solid #fff;
+    background: #fff;
+    color: #333
+}
+.content {
+    background: #fff
+}
+.tools-btn {
+    height: 30px;
+    line-height: 30px;
+}
+.toolsbar .tools-btn.btn:hover {
+    background: #f7f7f9;
+}
+.main-side {
+    border-right: 1px solid #ccc;
+    overflow:hidden;
+}
+.main-side .tab-bar {
+    padding:5px 10px;
+    height:38px;
+    position:fixed;
+}
+.main-side .tab-content {
+    margin-top: 38px
+}
+.top-content, .fluid-content {
+    overflow: hidden;
+    border-bottom: 1px solid #ccc;
+}
+.warp-p2 {
+    padding: 2px
+}
+.bottom-content .nav,.top-content .nav {
+    background: #f7f7f9;
+    padding:0 0 0 2px
+}
+.bottom-content .nav-tabs .nav-link, .side-tabs .nav-tabs .nav-link,.top-content .nav-tabs .nav-link {
+    border-radius: 0;
+    padding: 0.2em 0.5em
+}
+.side-tabs .nav-tabs .nav-item {
+  z-index: 999
+}
+.side-tabs .nav-tabs {
+    border-bottom: none;
+    margin-bottom: -1px
+}
+.side-tabs .nav-tabs .nav-link {
+    border-radius: 0;
+    padding: 0em 0.5em;
+    line-height: 30px;
+    z-index: 999
+}
+.bottom-content .nav-tabs .nav-link.active {
+    border-top: 1px solid #f7f7f9
+}
+.side-tabs .nav-tabs .nav-link.active {
+    border-top: none;
+    border-bottom:1px solid #fff
+}
+.side-tabs a.active, .sub-nav a.active {
+    background: #ccc
+}
+.poj-manage {
+    background: #fff
+}
+.slide-sidebar {
+    border-left: 1px solid #E1E1E1;
+    box-shadow: 0px 15px 15px rgba(0, 0, 0, 0.1);
+    background: none repeat scroll 0% 0% #ffffff;
+    overflow: hidden;
+    position: absolute;
+    right: 0px;
+    top: 0;
+    z-index: 999;
+    width: 0px;
+}
+.new-msg {
+    -webkit-animation: tada 1s infinite .2s ease both;
+    -moz-animation: tada 1s infinite .2s ease both;
+}
+@-webkit-keyframes tada {
+    0% {
+        -webkit-transform: scale(1)
+    }
+    10%, 20% {
+        -webkit-transform: scale(0.9) rotate(-3deg)
+    }
+    30%, 50%, 70%, 90% {
+        -webkit-transform: scale(1.1) rotate(3deg)
+    }
+    40%, 60%, 80% {
+        -webkit-transform: scale(1.1) rotate(-3deg)
+    }
+    100% {
+        -webkit-transform: scale(1) rotate(0)
+    }
+}
+@-moz-keyframes tada {
+    0% {
+        -moz-transform: scale(1)
+    }
+    10%, 20% {
+        -moz-transform: scale(0.9) rotate(-3deg)
+    }
+    30%, 50%, 70%, 90% {
+        -moz-transform: scale(1.1) rotate(3deg)
+    }
+    40%, 60%, 80% {
+        -moz-transform: scale(1.1) rotate(-3deg)
+    }
+    100% {
+        -moz-transform: scale(1) rotate(0)
+    }
+}
+.has-danger {
+    -webkit-animation: shake 1s .2s ease both;
+    -moz-animation: shake 1s .2s ease both;
+    animation: shake 1s .2s ease both;
+}
+@-webkit-keyframes shake {
+    0%, 100% {
+        -webkit-transform: translateX(0);
+    }
+    10%, 30%, 50%, 70%, 90% {
+        -webkit-transform: translateX(-10px);
+    }
+    20%, 40%, 60%, 80% {
+        -webkit-transform: translateX(10px);
+    }
+}
+@-moz-keyframes shake {
+    0%, 100% {
+        -moz-transform: translateX(0);
+    }
+    10%, 30%, 50%, 70%, 90% {
+        -moz-transform: translateX(-10px);
+    }
+    20%, 40%, 60%, 80% {
+        -moz-transform: translateX(10px);
+    }
+}
+@keyframes shake {
+    0%, 100% {
+        transform: translateX(0);
+    }
+    10%, 30%, 50%, 70%, 90% {
+        transform: translateX(-10px);
+    }
+    20%, 40%, 60%, 80% {
+        transform: translateX(10px);
+    }
+}
+.bottom-content {
+    height: 370px;
+    overflow: hidden;
+}
+.bottom-content .tab-content .main-data-bottom{
+    height: 340px;
+    overflow: auto;
+}
+.form-signin {
+    max-width: 500px;
+    margin: 150px auto;
+}
+.poj-list, .side-content {
+    overflow: auto;
+}
+.poj-list span.poj-icon {
+  padding-right:10px;
+  color:#ccc
+}
+.print-toolsbar{
+  padding:5px
+}
+.print-toolsbar .panel {
+  display:inline-block;
+  vertical-align:top;
+  background:#f7f7f9
+}
+.print-toolsbar .panel .panel-foot{
+  text-align: center;
+  font-size: 12px
+}
+.print-list {
+  border-right:1px solid #ccc
+}
+.print-list .form-list {
+  overflow: auto
+}
+.print-list .list-tools{
+  height:50px;
+  padding:10px 0;
+  border-bottom:1px solid #f2f2f2
+}
+.pageContainer {
+  background: #ededed;
+  text-align: center
+}
+.pageContainer .page{
+  border:9px solid transparent;
+  display: inline-block;
+}
+.pageContainer .page img{
+  width:inherit;
+  height: inherit;
+}
+.codeList{
+    max-height: 200px;
+    overflow:auto;
+}
+.main-data-top,.main-data-bottom,.main-data{
+  overflow: hidden;
+}
+.modal-fixed-height {
+    height:400px;
+    overflow-y:auto;
+}

+ 265 - 0
web/maintain/std_glj_lib/html/gongliao.html

@@ -0,0 +1,265 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<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>工料机库编辑器</title>
+    <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css">
+    <link rel="stylesheet" href="/web/maintain/std_glj_lib/css/main.css">
+    <link rel="stylesheet" href="/lib/font-awesome/font-awesome.min.css">
+    <link rel="stylesheet" href="/lib/spreadjs/sheets/css/gc.spread.sheets.excel2013lightGray.10.0.1.css" type="text/css">
+    <style type="text/css">
+        .ztree li span.button.add{margin-right:2px;background-position:-144px 0;vertical-align:top;*vertical-align:middle}
+    </style>
+    <!--zTree-->
+  	<link rel="stylesheet" href="/lib/ztree/css/zTreeStyle.css" type="text/css">
+</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"></div>
+        </nav>
+        <nav class="navbar navbar-toggleable-lg justify-content-between navbar-light p-0">
+              <ul class="nav nav-tabs" role="tablist">
+                  <li class="nav-item">
+                      <a class="nav-link active px-3" href="javascript:void(0);">工料机</a>
+                  </li>
+              </ul>
+        </nav>
+    </div>
+    <div class="main">
+        <div class="content">
+            <div class="container-fluid">
+                <div class="row">
+                  <div class="main-side col-lg-3 p-0" style="width: 100%; height: 100%; overflow-y: auto">
+                        <ul id="repositoryTree" class="ztree"></ul>
+                  </div>
+                  <div class="main-content col-lg-7 p-0">
+                    <div id="GLJListSheet" class="main-data">
+                      <!--<table class="table table-sm table-bordered m-0">
+                      <thead>
+                        <tr>
+                          <th></th>
+                          <th>编码</th>
+                          <th>名称</th>
+                          <th>规格型号</th>
+                          <th>计量单位</th>
+                          <th>单价</th>
+                          <th>类型</th>
+                        </tr>
+                      </thead>
+                      <tbody>
+                        <tr>
+                          <td>1</td>
+                          <td>00010201</td>
+                          <td>土石方综合工日</td>
+                          <td></td>
+                          <td>工日</td>
+                          <td>22.00</td>
+                          <td>人工</td>
+                        </tr>
+                        <tr>
+                          <td>2</td>
+                          <td>03010101</td>
+                          <td>钢材</td>
+                          <td></td>
+                          <td>t</td>
+                          <td>2600.00</td>
+                          <td>材料</td>
+                        </tr>
+                        <tr>
+                          <td>3</td>
+                          <td>36290101</td>
+                          <td>水</td>
+                          <td></td>
+                          <td>m3</td>
+                          <td>2600.00</td>
+                          <td>材料</td>
+                        </tr>
+                        <tr>
+                          <td>4</td>
+                          <td></td>
+                          <td></td>
+                          <td></td>
+                          <td></td>
+                          <td></td>
+                          <td></td>
+                        </tr>
+                        <tr>
+                          <td>5</td>
+                          <td></td>
+                          <td></td>
+                          <td></td>
+                          <td></td>
+                          <td></td>
+                          <td></td>
+                        </tr>
+                        <tr>
+                          <td>6</td>
+                          <td></td>
+                          <td></td>
+                          <td></td>
+                          <td></td>
+                          <td></td>
+                          <td></td>
+                        </tr>
+                      </tbody>
+                    </table>-->
+                    </div>
+                  </div>
+                    <div id="gljComponentSheet" class="main-side col-lg-2 p-0">
+                     <!-- <table class="table table-sm table-bordered m-0">
+                        <thead>
+                          <tr><th></th><th>编码</th><th>名称</th><th>计量单位</th><th>单价</th><th>消耗量</th></tr>
+                        </thead>
+                        <tbody>
+                          <tr><td>1</td><td></td><td></td><td></td><td></td><td></td></tr>
+                          <tr><td>2</td><td></td><td></td><td></td><td></td><td></td></tr>
+                          <tr><td>3</td><td></td><td></td><td></td><td></td><td></td></tr>
+                          <tr><td>4</td><td></td><td></td><td></td><td></td><td></td></tr>
+                        </tbody>
+                      </table>
+                      <table class="table table-sm table-bordered m-0">
+                        <thead>
+                          <tr><th></th><th>编码</th><th>名称</th><th>计量单位</th><th>单价</th><th>消耗量</th></tr>
+                        </thead>
+                        <tbody>
+                          <tr><td>1</td><td>01010101</td><td>水泥32.5</td><td>kg</td><td>0.25</td><td>243.000</td></tr>
+                          <tr><td>2</td><td></td><td></td><td></td><td></td><td></td></tr>
+                          <tr><td>3</td><td></td><td></td><td></td><td></td><td></td></tr>
+                          <tr><td>4</td><td></td><td></td><td></td><td></td><td></td></tr>
+                        </tbody>
+                      </table>
+                      <table class="table table-sm table-bordered m-0">
+                        <thead>
+                          <tr><th></th><th>编码</th><th>名称</th><th>计量单位</th><th>单价</th><th>消耗量</th></tr>
+                        </thead>
+                        <tbody>
+                          <tr><td>1</td><td>xxx</td><td>机上人工</td><td>工日</td><td>28.00</td><td>2.540</td></tr>
+                          <tr><td>2</td><td></td><td></td><td></td><td></td><td></td></tr>
+                          <tr><td>3</td><td></td><td></td><td></td><td></td><td></td></tr>
+                          <tr><td>4</td><td></td><td></td><td></td><td></td><td></td></tr>
+                        </tbody>
+                      </table>-->
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <button id="gljAlertBtn" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#gljAlert" style="display: none"></button>
+    <button id="codeAlertBtn" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#codeAlert" style="display: none"></button>
+    <div class="modal fade" id="gljAlert" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <input type="hidden" id="gdid" value="123">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h5 class="modal-title">取消确认</h5>
+                    <button type="button" id="gljAleClose" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">×</span>
+                    </button>
+                </div>
+                <div class="modal-body">
+                    <h5 class="text-danger" id="alertGljTxt">编号和类型不可为空!是否取消操作?</h5>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" id="aleCanceBtn" data-dismiss="modal">取消</button>
+                    <a href="javascript: void(0);" id="aleConfBtn" class="btn btn-danger" data-dismiss="modal">确认</a>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="modal" id="codeAlert" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <input type="hidden" id="codedid" value="123">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h5 class="modal-title">警告</h5>
+                    <button type="button" id="codAleClose" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">×</span>
+                    </button>
+                </div>
+                <div class="modal-body">
+                    <h5 class="text-danger" id="alertText">输入的编号已存在,请重新输入!</h5>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-danger" id="codAleConfBtn" data-dismiss="modal">确认</button>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <!-- JS. -->
+    <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/std_glj_lib/js/global.js"></script>
+    <!-- zTree -->
+    <script src = "/lib/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js"></script>
+    <script>GC.Spread.Sheets.LicenseKey = "559432293813965#A0y3iTOzEDOzkjMyMDN9UTNiojIklkI1pjIEJCLi4TPB9mM5AFNTd4cvZ7SaJUVy3CWKtWYXx4VVhjMpp7dYNGdx2ia9sEVlZGOTh7NRlTUwkWR9wEV4gmbjBDZ4ElR8N7cGdHVvEWVBtCOwIGW0ZmeYVWVr3mI0IyUiwCMzETN8kzNzYTM0IicfJye&Qf35VfiEzRwEkI0IyQiwiIwEjL6ByUKBCZhVmcwNlI0IiTis7W0ICZyBlIsIyNyMzM5ADI5ADNwcTMwIjI0ICdyNkIsIibj9SbvNmL4N7bjRnch56ciojIz5GRiwiI8+Y9sWY9QmZ0Jyp96uL9v6L0wap9biY9qiq95q197Wr9g+89iojIh94Wiqi";</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/treeDataHelper.js"></script>
+    <script type="text/javascript" src="/public/web/QueryParam.js"></script>
+    <script type="text/javascript" src="/web/maintain/std_glj_lib/js/glj.js"></script>
+    <script type="text/javascript" src="/web/maintain/std_glj_lib/js/gljComponent.js"></script>
+    <script type="text/javascript" src="/public/web/ztree_common.js"></script>
+    <script type="text/javascript" src="/public/web/sheet/sheet_common.js"></script>
+    <script type="text/javascript" src="/public/web/storageUtil.js"></script>
+    <SCRIPT type="text/javascript">
+        let userAccount = '<%=userAccount %>';
+        var gljSetting = {
+            view: {
+                //addHoverDom: gljTypeTreeOprObj.addHoverDom,
+                //removeHoverDom: gljTypeTreeOprObj.removeHoverDom,
+                expandSpeed: "",
+                selectedMulti: false
+            },
+            edit: {
+                enable: false,
+                editNameSelectAll: true,
+                showRemoveBtn: true,
+                showRenameBtn: true,
+                removeTitle: "删除节点",
+                renameTitle: "更改名称"
+            },
+            data: {
+                keep: {
+                    parent:true,
+                    leaf:true
+                },
+                key: {
+                    children: "items",
+                    name: "Name"
+                },
+                simpleData: {
+                    enable: false,
+                    idKey: "ID",
+                    pIdKey: "ParentID",
+                    rootPId: -1
+                }
+            },
+            callback:{
+                beforeRename: gljTypeTreeOprObj.beforeRename,
+                onRename: gljTypeTreeOprObj.onRename,
+                beforeRemove: gljTypeTreeOprObj.onBeforeRemove,
+                onRemove: gljTypeTreeOprObj.onRemove,
+                onClick: gljTypeTreeOprObj.onClick
+            }
+        };
+        $(document).ready(function(){
+            pageOprObj.initPage($("#GLJListSheet")[0], $('#gljComponentSheet')[0]);
+            //repositoryGljObj.buildSheet($("#GLJListSheet")[0]);
+        });
+  	</SCRIPT>
+</body>
+<script type="text/javascript">
+    autoFlashHeight();
+</script>
+
+</html>

+ 144 - 0
web/maintain/std_glj_lib/html/main.html

@@ -0,0 +1,144 @@
+<!DOCTYPE html>
+<html lang="en">
+<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>工料机库编辑器</title>
+    <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css">
+    <link rel="stylesheet" href="/web/maintain/std_glj_lib/css/main.css">
+    <link rel="stylesheet" href="/lib/font-awesome/font-awesome.min.css">
+    <!--zTree-->
+  	<link rel="stylesheet" href="/lib/ztree/css/zTreeStyle.css" type="text/css">
+</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"></div>
+        </nav>
+        <nav class="navbar navbar-toggleable-lg justify-content-between navbar-light p-0">
+          <ul class="nav navbar-nav px-1">
+              <li class="nav-item">
+                  <a class="nav-link" href="javacript:void(0);" aria-haspopup="true" aria-expanded="false" data-toggle="modal" data-target="#add">新建工料机库</a>
+              </li>
+          </ul>
+        </nav>
+    </div>
+    <div class="main">
+        <div class="content">
+            <div class="container-fluid">
+                <div class="row">
+                  <div class="col-md-8">
+                    <div class="warp-p2 mt-3">
+                      <table class="table table-hover table-bordered">
+                        <thead><tr><th>工料机库名称</th><th>编办</th><th>定额库</th><th width="160">添加时间</th><th width="90">操作</th></tr></thead>
+                        <tbody id="showArea">
+                      <!--    <tr><td><a href="gongliao.html">XX工料机库</a></td><td>重庆2018</td><td>XXX定额库(重庆2018)</td><td>2017-01-01 </td><td><a href="javacript:void(0);" data-toggle="modal" data-target="#edit" title="编辑"><i class="fa fa-pencil-square-o"></i></a> <a href="javacript:void(0);" data-toggle="modal" data-target="#del" class="text-danger" title="删除"><i class="fa fa-remove"></i></a></td></tr>
+                          <tr><td><a href="gongliao.html">XX工料机库</a></td><td>重庆2018</td><td></td><td>2017-01-01 </td><td><a href="javacript:void(0);" data-toggle="modal" data-target="#edit" title="编辑"><i class="fa fa-pencil-square-o"></i></a> <a href="javacript:void(0);" data-toggle="modal" data-target="#del" class="text-danger" title="删除"><i class="fa fa-remove"></i></a></td></tr>
+                          <tr><td><a href="gongliao.html">XX工料机库</a></td><td>重庆2018</td><td></td><td>2017-01-01 </td><td><a href="javacript:void(0);" data-toggle="modal" data-target="#edit" title="编辑"><i class="fa fa-pencil-square-o"></i></a> <a href="javacript:void(0);" data-toggle="modal" data-target="#del" class="text-danger" title="删除"><i class="fa fa-remove"></i></a></td></tr>-->
+                        </tbody>
+                      </table>
+                    </div>
+                  </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!--弹出添加-->
+    <div class="modal fade" id="add" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                  <h5 class="modal-title">添加工料机库</h5>
+                  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                  </button>
+                </div>
+                <div class="modal-body">
+                  <form>
+                    <div class="form-group">
+                      <label>工料机名称</label>
+                      <input id="libNameTxt" class="form-control" placeholder="输入工料机库名称" type="text">
+                    </div>
+                    <div class="form-group">
+                      <label>编办名称</label>
+                      <select id="compilationSels" class="form-control"></select>
+                    </div>
+                  </form>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" id="cancelBtn" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <a id="addBtn" href="javascript:void(0)" class="btn btn-primary">新建</a>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!--弹出编辑-->
+    <div class="modal fade" id="edit" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                  <h5 class="modal-title">编辑工料机库</h5>
+                  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                  </button>
+                </div>
+                <div class="modal-body">
+                  <form>
+                    <div class="form-group">
+                      <label>工料机库名称</label>
+                      <input class="form-control" id="renameText" placeholder="输入工料机库名称" type="text" value="">
+                    </div>
+                    <div class="form-group">
+                      <label>编办名称</label>
+                      <select id="compilationEdit" class="form-control" disabled><option></option></select>
+                    </div>
+                  </form>
+                </div>
+                <div class="modal-footer">
+                    <button id="editCancelBtn" type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <a href="javascript: void(0);"  id="renameA" class="btn btn-primary">确定</a>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <!--弹出删除-->
+    <div class="modal fade" id="del" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                  <h5 class="modal-title">删除确认</h5>
+                  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                  </button>
+                </div>
+                <div class="modal-body">
+                    <h5 class="text-danger">删除后无法恢复,确认是否删除?</h5>
+                </div>
+                <div class="modal-footer">
+                    <button id="delCancelBtn" type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <a id="deleteA" href="javascript: void(0);" class="btn btn-danger">删除</a>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!-- JS. -->
+    <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/std_glj_lib/js/global.js"></script>
+    <!-- zTree -->
+  	<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="/web/maintain/std_glj_lib/js/main.js"></script>
+
+</body>
+<script type="text/javascript">
+    let oprtor =  '<%= userAccount %>';
+    autoFlashHeight();
+</script>
+
+</html>

File diff suppressed because it is too large
+ 1069 - 0
web/maintain/std_glj_lib/js/glj.js


+ 370 - 0
web/maintain/std_glj_lib/js/gljComponent.js

@@ -0,0 +1,370 @@
+/**
+ * Created by Zhong on 2017/8/15.
+ */
+
+let gljComponentOprObj = {
+    workBook: null,
+    setting: {
+        owner: "gljComponent",
+        header:[
+            {headerName:"编码",headerWidth:50,dataCode:"code", dataType: "String", formatter: "@", hAlign: "left", vAlign: "center"},
+            {headerName:"名称",headerWidth:60,dataCode:"name", dataType: "String", hAlign: "left", vAlign: "center"},
+            {headerName:"计量单位",headerWidth:60,dataCode:"unit", dataType: "String", hAlign: "center", vAlign: "center"},
+            {headerName:"单价",headerWidth:50,dataCode:"basePrice", dataType: "Number", formatter: "0.00", hAlign: "right", vAlign: "center"},
+            {headerName:"消耗量",headerWidth:55,dataCode:"consumeAmt", dataType: "Number", formatter: "0.000", hAlign: "right", vAlign: "center"}
+        ],
+        view: {
+            lockedCells:[1, 2, 3]
+        }
+    },
+    buildSheet: function(container) {
+        var me = gljComponentOprObj;
+        me.workBook = sheetCommonObj.buildSheet(container, me.setting, 30, me);
+        me.workBook.getSheet(0).setColumnWidth(0, 20, GC.Spread.Sheets.SheetArea.rowHeader);
+        me.workBook.getSheet(0).setFormatter(-1, 0, "@", GC.Spread.Sheets.SheetArea.viewport);
+        me.workBook.getSheet(0).options.isProtected = true;
+        sheetCommonObj.cleanSheet(me.workBook.getSheet(0), me.setting, -1);
+
+        me.gljComponentDelOpr();
+        me.workBook.bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting);
+        me.workBook.bind(GC.Spread.Sheets.Events.ClipboardPasted, me.onClipboardPasted);
+        me.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.EditStarting, me.onCellEditStart);
+        me.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.EditEnded, me.onCellEditEnd);
+       /* me.repositoryGljDelOpr();
+        me.workBook.bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting);
+        me.workBook.bind(GC.Spread.Sheets.Events.ClipboardPasted, me.onClipboardPasted);
+        me.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.EditStarting, me.onCellEditStart);
+        me.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.EditEnded, me.onCellEditEnd);
+        me.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.EnterCell, me.onEnterCell);*/
+    },
+    getRowData: function (sheet, row, setting) {
+        let rst = {};
+        for(let i = 0; i < setting.header.length; i++){
+            rst[setting.header[i].dataCode] = sheet.getValue(row, i);
+        }
+        return rst;
+    },
+    getComponent: function (sheet, rowCount) {
+        let component = [];
+        for(let row = 0; row < rowCount; row++){
+            let obj = {};
+            obj.consumeAmt = sheet.getValue(row, 4);
+            obj.ID = sheet.getTag(row, 0);
+            component.push(obj);
+        }
+        return component;
+    },
+    gljComponentDelOpr: function () {
+        let me = gljComponentOprObj, that = repositoryGljObj, updateArr = [], removeArr = [], isUpdate = false;
+        me.workBook.commandManager().register('gljComponentDel', function () {
+            let sels = me.workBook.getSheet(0).getSelections();
+            if(sels.length > 0 && that.currentComponent.length > 0){
+                let component = that.currentGlj.component;
+                for(let i = 0; i < sels.length > 0; i++){
+                    if(sels[i].colCount === me.setting.header.length){//可删除
+                        for(let j = 0; j < sels[i].rowCount; j++){
+                            if(sels[i].row + j < that.currentComponent.length){
+                                removeArr.push(that.currentComponent[sels[i].row + j].ID);
+
+                            }
+                        }
+                    }
+                    else if(sels[i].col === 0){
+                            //编码不可为空
+                            alert("编码不可为空!");
+
+                    }
+                    else if(sels[i].col === 4){//消耗量修改为0
+                        if(sels[i].row === -1){//全修改
+                           for(let j = 0; j < that.currentComponent.length; j++){
+                               isUpdate = true;
+                               that.currentComponent[j].consumeAmt = 0;
+                               for(let k = 0; k < component.length; k++){
+                                   if(component[k].ID === that.currentComponent[j].ID){
+                                       component[k].consumeAmt = 0;
+                                       break;
+                                   }
+                               }
+                           }
+                        }
+                        else{//部分修改
+                            for(let j = 0; j < sels[i].rowCount; j++){
+                                if(sels[i].row + j < that.currentComponent.length){
+                                    isUpdate = true;
+                                    that.currentComponent[sels[i].row + j].consumeAmt = 0;
+                                    for(let k = 0; k < component.length; k++){
+                                        if(component[k].ID === that.currentComponent[sels[i].row + j].ID){
+                                            component[k].consumeAmt = 0;
+                                            break;
+                                        }
+                                    }
+
+                                }
+                            }
+                        }
+                    }
+                }
+                if(removeArr.length > 0 || isUpdate){
+                    for(let i = 0; i < removeArr.length; i++){
+                        for(let j = 0; j < that.currentComponent.length; j++){
+                            if(that.currentComponent[j].ID === removeArr[i]){
+                                that.currentComponent.splice(j--, 1);
+                            }
+                        }
+                        for(let j = 0; j < component.length; j++){
+                            if(component[j].ID === removeArr[i]){
+                                component.splice(j--, 1);
+                            }
+                        }
+                    }
+                    //重新计算工料机
+                    let gljBasePrc = me.reCalGljBasePrc(that.currentComponent);
+                    that.currentGlj.basePrice = gljBasePrc;
+                    that.reshowGljBasePrc(that.currentGlj);
+                    updateArr.push(that.currentGlj);
+                    console.log(updateArr);
+                    me.updateComponent(updateArr);
+                }
+            }
+        });
+        me.workBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false);
+        me.workBook.commandManager().setShortcutKey('gljComponentDel', GC.Spread.Commands.Key.del, false, false, false, false);
+    },
+    onCellEditStart: function(sender, args) {
+        let me = gljComponentOprObj, that = repositoryGljObj;
+        let rObj = me.getRowData(args.sheet, args.row, me.setting);
+        me.currentEditingComponent = rObj;
+    },
+    onCellEditEnd: function (sender, args) {
+        let me = gljComponentOprObj, that = repositoryGljObj;
+        let gljList = that.gljList, updateArr = [], materialComponent = [202, 203, 204], machineComponent = [302, 303];
+        if(args.editingText !== me.currentEditingComponent.code){
+            if(args.col === 0 && args.editingText && args.editingText.trim().length > 0){
+                let component = that.currentGlj.component, hasCode = false;
+                for(let i = 0; i < gljList.length; i++){
+                    if(gljList[i].code === args.editingText){//有效的组成物
+                        hasCode = true;
+                        if((materialComponent.indexOf(that.currentGlj.gljType) !== -1 && gljList[i].gljType === 201)
+                            || (that.currentGlj.gljType === 3 && machineComponent.indexOf(gljList[i].gljType) !== -1 )){//普通材料
+                            //是否与原有组成物不同
+                            let isExist = false;
+                            for(let j = 0; j < component.length; j++){
+                                if(component[j].ID === gljList[i].ID){
+                                    isExist = true;
+                                    break;
+                                }
+                            }
+                            if(!isExist){
+                                let rObj = {};
+                                rObj.ID = gljList[i].ID;
+                                //rObj.basePrice = gljList[i].basePrice;
+                                if(typeof that.currentComponent[args.row] !== 'undefined'){
+                                    rObj.consumeAmt = that.currentComponent[args.row].consumeAmt;
+                                    let index;
+                                    for(let j = 0; j < component.length; j++){
+                                        if(component[j].ID === that.currentComponent[args.row].ID){
+                                            index = j;
+                                            break;
+                                        }
+                                    }
+                                    component.splice(index, 1);
+                                    component.splice(index, 0, rObj);
+                                    updateArr.push(that.currentGlj);
+                                }
+                                else{
+                                    rObj.consumeAmt = 0;
+                                    component.push(rObj);
+                                    updateArr.push(that.currentGlj);
+                                }
+                                break;
+                            }
+                            else{
+                                //已存在
+                                alert("已存在!");
+                                args.sheet.setValue(args.row, args.col, me.currentEditingComponent[me.setting.header[args.col].dataCode] ?
+                                    me.currentEditingComponent[me.setting.header[args.col].dataCode]: '');
+                            }
+
+                        }
+                        else{
+                            alert("无效!");
+                            args.sheet.setValue(args.row, args.col, me.currentEditingComponent[me.setting.header[args.col].dataCode] ?
+                                me.currentEditingComponent[me.setting.header[args.col].dataCode]: '');
+                            //无效
+                        }
+                    }
+                }
+                if(!hasCode){
+                    alert("不存在,请添加!");
+                    args.sheet.setValue(args.row, args.col, me.currentEditingComponent[me.setting.header[args.col].dataCode] ?
+                        me.currentEditingComponent[me.setting.header[args.col].dataCode] : '');
+                    //不存在
+                }
+            }
+            else if(args.col === 4 && me.currentEditingComponent.code && args.editingText && args.editingText.trim().length > 0){//消耗量
+                let consumeAmt = parseFloat(args.editingText);
+                if(!isNaN(consumeAmt) && consumeAmt !== me.currentEditingComponent.consumeAmt){
+                    let component = that.currentGlj.component;
+                    for(let i = 0; i < component.length; i++){
+                        if(component[i].ID === that.currentComponent[args.row].ID){
+                            component[i].consumeAmt = consumeAmt
+                        }
+                    }
+                    that.currentComponent[args.row].consumeAmt = consumeAmt;
+                    //计算工料机单价
+                    let gljBasePrc = me.reCalGljBasePrc(that.currentComponent);
+                    that.currentGlj.basePrice = gljBasePrc;
+                    that.reshowGljBasePrc(that.currentGlj);
+                    updateArr.push(that.currentGlj);
+                }
+                else{
+                    //只能输入数值
+                    args.sheet.setValue(args.row, args.col, me.currentEditingComponent[me.setting.header[args.col].dataCode] ?
+                        me.currentEditingComponent[me.setting.header[args.col].dataCode]: 0);
+
+                }
+            }
+            else{
+                args.sheet.setValue(args.row, args.col, '');
+            }
+        }
+        if(updateArr.length > 0){
+            me.updateComponent(updateArr);
+            //保存
+        }
+    },
+    onClipboardPasting: function (sender, info) {
+
+    },
+    onClipboardPasted: function (sender, info) {
+        let me = gljComponentOprObj, that = repositoryGljObj, updateArr = [] ,materialComponent = [202, 203, 204], machineComponent = [302, 303],
+            component = that.currentGlj.component, newComponent = [], concatComponent = [], isChange = false;
+        let items = sheetCommonObj.analyzePasteData(me.setting, info);
+        let gljCache = that.gljList;
+        if(info.cellRange.col === 0){
+            for(let i = 0; i < items.length; i++){
+                for(let j = 0; j < gljCache.length; j++){
+                    if(items[i].code === gljCache[j].code){
+                        if((materialComponent.indexOf(that.currentGlj.gljType) !== -1 && gljCache[j].gljType === 201)
+                            || (that.currentGlj.gljType === 3 && machineComponent.indexOf(gljCache[j].gljType) !== -1 )){
+                            //是否与原有组成物不同
+                            let isExist = false;
+                            for(let k = 0; k < component.length; k++){
+                                if(component[k].ID === gljCache[j].ID){
+                                    isExist = true;
+                                    me.workBook.getSheet(0).setValue(info.cellRange.row + i, info.cellRange.col,
+                                        typeof that.currentComponent[info.cellRange.row + i] !== 'undefined'? that.currentComponent[info.cellRange.row + i].code : '');
+                                    break;
+                                }
+                            }
+                            if(!isExist){
+                                isChange = true;
+                                let obj = {};
+                                obj.ID = gljCache[j].ID;
+                                if(typeof that.currentComponent[info.cellRange.row + i] !== 'undefined'){//更新
+                                    obj.consumeAmt = that.currentComponent[info.cellRange.row + i].consumeAmt;
+                                    let index;
+                                    for(let k = 0; k < component.length; k++){
+                                        if(that.currentComponent[info.cellRange.row + i].ID === component[k].ID){
+                                            index = k;
+                                            break;
+                                        }
+                                    }
+                                    component.splice(index, 1);
+                                    component.splice(index, 0, obj);
+                                }
+                                else{//新增
+                                    obj.consumeAmt = 0;
+                                    component.push(obj);
+                                }
+                                break;
+                            }
+
+                        }
+                        else{
+                            me.workBook.getSheet(0).setValue(info.cellRange.row + i, info.cellRange.col,
+                            typeof that.currentComponent[info.cellRange.row + i] !== 'undefined'? that.currentComponent[info.cellRange.row + i].code : '');
+
+                        }
+
+                    }
+                    else{
+                        me.workBook.getSheet(0).setValue(info.cellRange.row + i, info.cellRange.col,
+                            typeof that.currentComponent[info.cellRange.row + i] !== 'undefined'? that.currentComponent[info.cellRange.row + i].code : '');
+                    }
+                }
+            }
+            if(isChange){
+                updateArr.push(that.currentGlj);
+            }
+        }
+        else if(info.cellRange.col === 4){
+            let items = sheetCommonObj.analyzePasteData(me.setting, info);
+            let row = info.cellRange.row;
+            for(let i = 0; i < items.length; i++){
+                if(row + i < that.currentComponent.length){
+                    let currentObj = that.currentComponent[row + i];
+                    if(items[i].consumeAmt.trim().length > 0 && items[i].consumeAmt !== currentObj.consumeAmt){
+                        isChange = true;
+                        currentObj.consumeAmt = items[i].consumeAmt;
+                        for(let j = 0; j < component.length; j++){
+                            if(component[j].ID === currentObj.ID){
+                                component[j].consumeAmt = currentObj.consumeAmt;
+                                break;
+                            }
+                        }
+                    }
+                    else{
+                        me.workBook.getSheet(0).setValue(row + i, info.cellRange.col, currentObj.consumeAmt);
+                    }
+                }
+                else{
+                    me.workBook.getSheet(0).setValue(row + i, info.cellRange.col, '');
+                }
+            }
+            if(isChange){
+                //计算工料机单价
+                let gljBasePrc = me.reCalGljBasePrc(that.currentComponent);
+                that.currentGlj.basePrice = gljBasePrc;
+                that.reshowGljBasePrc(that.currentGlj);
+                updateArr.push(that.currentGlj);
+            }
+        }
+        if(updateArr.length > 0){
+            me.updateComponent(updateArr);
+        }
+    },
+    updateComponent: function (updateArr) {
+        let me = gljComponentOprObj, that = repositoryGljObj;
+        $.ajax({
+            type: 'post',
+            url: 'api/updateComponent',
+            data: {libId: pageOprObj.gljLibId, updateArr: updateArr, oprtor: userAccount},
+            dataType: 'json',
+            success: function (result) {
+                console.log(result);
+                if(result.data.length > 0){
+                    if(result.data[0]){
+                        that.currentComponent =  that.getCurrentComponent(result.data[0].component);
+                        console.log(that.currentComponent);
+                        sheetCommonObj.cleanSheet(me.workBook.getSheet(0), me.setting, -1);
+                        sheetCommonObj.showData(me.workBook.getSheet(0), me.setting, that.currentComponent);
+                    }
+                }
+            }
+        })
+    },
+    round: function (v, e) {
+        var t=1;
+        for(;e>0;t*=10,e--);
+        for(;e<0;t/=10,e++);
+        return Math.round(v*t)/t;
+    },
+    reCalGljBasePrc: function (component) {
+        let me = gljComponentOprObj, gljBasePrc = 0;
+        for(let i = 0; i < component.length; i++){
+            gljBasePrc += me.round(component[i].basePrice * component[i].consumeAmt, 2);
+        }
+        return gljBasePrc;
+    }
+};

+ 42 - 0
web/maintain/std_glj_lib/js/global.js

@@ -0,0 +1,42 @@
+/*全局自适应高度*/
+function autoFlashHeight(){
+    var headerHeight = $(".header").height();
+    var bottomContentHeight = $(".bottom-content").height();
+    var toolsBar = $(".tools-bar").height();
+    $(".content").height($(window).height()-headerHeight);
+    $(".main-side").height($(window).height()-headerHeight-2);
+    $(".fluid-content").height($(window).height()-headerHeight-1);
+    $(".side-content").height($(window).height()-headerHeight );
+    $(".poj-list").height($(window).height()-headerHeight);
+    $(".form-list").height($(window).height()-headerHeight-50 );
+    $(".main-data-top").height($(window).height()-headerHeight-toolsBar-bottomContentHeight-2);
+    $(".main-data").height($(window).height()-headerHeight);
+};
+$(window).resize(autoFlashHeight);
+/*全局自适应高度结束*/
+$(function(){
+/*侧滑*/
+$(".open-sidebar").click(function(){
+    $(".slide-sidebar").animate({width:"800"}).addClass("open");
+});
+$("body").click(function(event){
+        var e = event || window.event; //浏览器兼容性
+        if(!$(event.target).is('a')) {
+            var elem = event.target || e.srcElement;
+            while (elem) { //循环判断至跟节点,防止点击的是div子元素
+                if (elem.className == "open-sidebar" || elem.className == 'slide-sidebar open') {
+                    return false;
+                }
+                elem = elem.parentNode;
+            }
+            $(".slide-sidebar").animate({width:"0"}).removeClass("open")// 关闭处理
+        }
+
+    });
+/*侧滑*/
+/*工具提示*/
+$('*[data-toggle=tooltip]').mouseover(function() {
+ $(this).tooltip('show');
+  });
+/*工具提示*/
+});

+ 191 - 0
web/maintain/std_glj_lib/js/main.js

@@ -0,0 +1,191 @@
+/**
+ * Created by Zhong on 2017/8/14.
+ */
+$(function () {
+    let dispNameArr;
+    getAllGljLib(function (dispNames) {
+        dispNameArr = dispNames;
+        //添加
+        $('#addBtn').click(function () {
+            let compilationName = $('#compilationSels option:selected').text();
+            let compilationId = $('#compilationSels option:selected').val();
+            let libName = $('#libNameTxt').val();
+            if(libName.trim().length === 0){
+                alert('名称不可为空!');
+                $('#libNameTxt').val('')
+            }
+            else if(dispNames.indexOf(libName) !== -1){
+                alert('此工料机库已存在!');
+                $('#libNameTxt').val('')
+            }
+            else if(compilationName.trim().length === 0){
+                alert('编办不可为空!');
+            }
+            else{
+                let newGljLib = {};
+                newGljLib.dispName = libName;
+                newGljLib.compilationId = compilationId;
+                newGljLib.compilationName = compilationName;
+                newGljLib.creator = oprtor;
+                newGljLib.appType = "建筑";
+                $('#libNameTxt').val('');
+                createGljLib(newGljLib, dispNameArr);
+            }
+        });
+        //重命名
+        $("#showArea").on("click", "[data-target = '#edit']", function(){
+            let renameId = $(this).parent().parent().attr("id");
+            let compilationName = $(this).parent().parent().children()[1].textContent;
+            $('#compilationEdit option').text(compilationName);
+            $("#renameA").attr("renameId", renameId);
+        });
+        $("#renameA").click(function(){
+            let newName = $("#renameText").val();
+            let libId = $(this).attr("renameId");
+            let jqSel = "#" + libId + " td:first" + " a";
+            let orgName = $(jqSel).text();
+            if(newName.trim().length === 0){
+                alert("名称不可为空!");
+                $("#renameText").val('');
+            }
+            else if(dispNameArr.indexOf(newName) !== -1){
+                alert("该工料机库已存在!");
+                $("#renameText").val('');
+            }
+           else{
+               renameGljLib({ID: libId, newName: newName, orgName: orgName}, dispNameArr);
+            }
+        });
+        //删除
+        $("#showArea").on("click", "[data-target = '#del']", function(){
+            let deleteId = $(this).parent().parent().attr("id");
+            $("#deleteA").attr("deleteId", deleteId);
+        });
+        $("#deleteA").click(function(){
+            let deleteId = $(this).attr("deleteId");
+            let jqSel = "#" + deleteId + " td:first" + " a";
+            let libName = $(jqSel).text();
+            removeGljLib({libId: deleteId, libName: libName}, dispNameArr);
+        });
+
+
+    });
+    getCompilationList();
+});
+
+function getAllGljLib(callback){
+    $.ajax({
+        type: 'post',
+        url: 'api/getAllGljLib',
+        dataType: 'json',
+        success: function (result) {
+            let dispNames = [];
+            if(result.data.length > 0){
+                for(let i = 0; i < result.data.length; i++){
+                    let id = result.data[i].ID;
+                    let libName = result.data[i].dispName;
+                    let createDate = result.data[i].createDate.split(' ')[0];
+                    let compilationName = result.data[i].compilationName;
+                    dispNames.push(result.data[i].dispName);
+                    $("#showArea").append(
+                        "<tr id='tempId'>" +
+                        "<td><a href='/stdGljRepository/glj'>"+libName+"</a></td>" +
+                        "<td>"+compilationName+" </td>" +
+                        "<td>"+'xx定额库(xx)'+" </td>" +
+                        "<td>"+createDate+" </td>" +
+                        "<td><a href='javascript:void(0);' data-toggle='modal' data-target='#edit' title='编辑'>" +
+                        "<i class='fa fa-pencil-square-o'></i></a> <a href='javascript:void(0);' data-toggle='modal' data-target='#del' class='text-danger' title='删除'>" +
+                        "<i class='fa fa-remove'></i></a></td></tr>");
+                    var newHref = "/stdGljRepository/glj?gljLibId="+id;
+                    $("#tempId td:first a").attr("href", newHref);
+                    $("#tempId").attr("id", id);
+                }
+            }
+            callback(dispNames);
+        }
+    });
+}
+function getCompilationList(){
+    $.ajax({
+        type: 'post',
+        url: 'api/getCompilationList',
+        dataType: 'json',
+        success: function (result) {
+            //addoptions
+            for(let i = 0; i < result.data.length; i++){
+                let $option =  $("<option >"+ result.data[i].name +"</option>");
+                $option.val( result.data[i]._id);
+                $('#compilationSels').append($option);
+            }
+            $('#compilationSels').on("change", function () {
+            });
+        }
+    });
+}
+function createGljLib(gljLibObj, dispNamesArr){
+    $.ajax({
+        type: 'post',
+        url: 'api/createGljLib',
+        data: {gljLibObj: JSON.stringify(gljLibObj)},
+        dataType: 'json',
+        success: function (result) {
+            console.log(result);
+            if(result.data){
+                let id = result.data.ID;
+                let libName = result.data.dispName;
+                let createDate = result.data.createDate.split(' ')[0];
+                let compilationName = result.data.compilationName;
+                dispNamesArr.push(libName);
+                $("#showArea").append(
+                    "<tr id='tempId'>" +
+                    "<td><a href='/stdGljRepository/glj'>"+libName+"</a></td>" +
+                    "<td>"+compilationName+" </td>" +
+                    "<td>"+'xx定额库(xx)'+" </td>" +
+                    "<td>"+createDate+" </td>" +
+                    "<td><a href='javascript:void(0);' data-toggle='modal' data-target='#edit' title='编辑'>" +
+                    "<i class='fa fa-pencil-square-o'></i></a> <a href='javascript:void(0);' data-toggle='modal' data-target='#del' class='text-danger' title='删除'>" +
+                    "<i class='fa fa-remove'></i></a></td></tr>");
+                var newHref = "/stdGljRepository/glj?gljLibId="+id;
+                $("#tempId td:first a").attr("href", newHref);
+                $("#tempId").attr("id", id);
+            }
+            $('#cancelBtn').click();
+        }
+    })
+}
+function renameGljLib(renameObj, dispNames){
+    $.ajax({
+        type: 'post',
+        url: 'api/renameGljLib',
+        data: {oprtor: oprtor, renameObj: JSON.stringify(renameObj)},
+        dataType: 'json',
+        success: function (result) {
+            if(!result.error){
+                let jqSel = "#" + renameObj.ID + " td:first" + " a";
+                $(jqSel).text(renameObj.newName);
+                let index = dispNames.indexOf(renameObj.orgName);
+                dispNames.splice(index, 1);
+                dispNames.splice(index, 0, renameObj.newName);
+            }
+            $('#editCancelBtn').click();
+            $('#renameText').val('');
+        }
+    })
+}
+function removeGljLib(delObj, dispNames){
+    $.ajax({
+        type: 'post',
+        url: 'api/removeGljLib',
+        data: {oprtor: oprtor, libId: delObj.libId},
+        dataType: 'json',
+        success: function (result) {
+            if(!result.error){
+                var jqSel = "#"+ delObj.libId;
+                $(jqSel).remove();
+                let index = dispNames.indexOf(delObj.libName);
+                dispNames.splice(index, 1);
+                $('#delCancelBtn').click();
+            }
+        }
+    })
+}

+ 33 - 5
web/users/js/compilation.js

@@ -24,7 +24,7 @@ $(document).ready(function() {
     // 新增编办
     $("#add-compilation").click(function() {
         try {
-            let [name, standardBill, rationLib, standardBillString, rationLibString] = getAndValidData(model);
+            let [name, standardBill, rationLib, gljLib, standardBillString, rationLibString, gljLibString] = getAndValidData(model);
 
             let url = '/compilation/add';
             if (model === 'all') {
@@ -64,6 +64,9 @@ $(document).ready(function() {
                         addLib.name = rationLibString;
                         addLib.id = rationLib;
                         break;
+                    case 'glj':
+                        addLib.name = gljLibString;
+                        addLib.id = gljLib;
                 }
                 // 判断是否有重复的数据
                 if ($("input:hidden[name='"+ model +"_lib'][data-id='"+ addLib.id +"']").length > 0) {
@@ -129,20 +132,29 @@ $(document).ready(function() {
                 $("#name-area").show();
                 $("#bill-area").hide();
                 $("#ration-area").hide();
+                $("#glj-area").hide();
                 $("#add-compilation-title").text('添加新编办');
                 break;
             case 'bill':
                 $("#name-area").hide();
                 $("#bill-area").show();
                 $("#ration-area").hide();
+                $("#glj-area").hide();
                 $("#add-compilation-title").text('添加标准清单');
                 break;
             case 'ration':
                 $("#name-area").hide();
                 $("#bill-area").hide();
                 $("#ration-area").show();
+                $("#glj-area").hide();
                 $("#add-compilation-title").text('添加定额库');
                 break;
+            case 'glj':
+                $("#name-area").hide();
+                $("#bill-area").hide();
+                $("#ration-area").hide();
+                $("#glj-area").show();
+                $("#add-compilation-title").text('添加定额库');
         }
 
         $("#addcompilation").modal('show');
@@ -232,14 +244,15 @@ $(document).ready(function() {
 function initCompilation() {
     let billListData = billList === undefined ? [] : JSON.parse(billList);
     let rationLibData = rationList === undefined ? [] : JSON.parse(rationList);
+    let gljLibData = gljList === undefined ? [] : JSON.parse(gljList);
 
+    if (billListData.length <= 0 || rationLibData.length <= 0 || gljLibData.length <= 0) {
+        return false;
+    }
     // 初始化 造价书列设置
     colSpread = SheetDataHelper.createNewSpread($('#main-tree-col')[0]);
     SheetDataHelper.loadSheetHeader(JSON.parse(mainTreeCol), colSpread.getActiveSheet());
 
-    if (billListData.length <= 0 || rationLibData.length <= 0) {
-        return false;
-    }
     // 标准清单
     let html = '';
     for(let tmp of billListData) {
@@ -255,6 +268,15 @@ function initCompilation() {
         html += tmpHtml;
     }
     $("select[name='ration_lib']").children("option").first().after(html);
+
+    // 工料机库
+    html = '';
+    for(let tmp of gljLibData) {
+        let tmpHtml = '<option value="' + tmp.id + '">' + tmp.name + '</option>';
+        html += tmpHtml;
+    }
+    $("select[name='glj_lib']").children("option").first().after(html);
+
 }
 
 /**
@@ -267,6 +289,7 @@ function getAndValidData(model) {
     let name = $("input[name='compilation_name']").val();
     let standardBill = $("select[name='standard_bill']").children("option:selected").val();
     let rationLib = $("select[name='ration_lib']").children("option:selected").val();
+    let gljLib = $("select[name='glj_lib']").children("option:selected").val();
 
     if (name === '' && model === 'all') {
         throw '编办名字不能为空';
@@ -280,10 +303,15 @@ function getAndValidData(model) {
         throw '请选择定额库';
     }
 
+    if (model === 'glj' && (gljLib === '' || gljLib === undefined)) {
+        throw '请选择工料机库';
+    }
+
     let standardBillString = $("select[name='standard_bill']").children("option:selected").text();
     let rationLibString = $("select[name='ration_lib']").children("option:selected").text();
+    let gljLibString = $("select[name='glj_lib']").children("option:selected").text();
 
-    return [name, standardBill, rationLib, standardBillString, rationLibString];
+    return [name, standardBill, rationLib, gljLib, standardBillString, rationLibString, gljLibString];
 }
 
 /**

+ 22 - 4
web/users/views/compilation/add.html

@@ -53,13 +53,13 @@
                             <label>标准清单</label>
                             <div class="bill-list">
                                 <% if (valuationData.bill_lib.length > 0) { %>
-                                <% valuationData.bill_lib.forEach(function (bill){ %>
+                                <% valuationData.bill_lib.forEach(function (bill, index){ %>
                                 <p class="form-control-static">
                                     <a class="pull-right text-danger remove-lib" data-model="bill" title="移除">
                                         <span class="glyphicon glyphicon-remove"></span>
                                     </a>
                                     <input type="hidden" name="bill_lib" data-id="<%= bill.id %>" value="<%= JSON.stringify({id: bill.id, name: bill.name}) %>">
-                                    <%= bill.name %>
+                                    <% if (index === 0) {%><i class="glyphicon glyphicon-flag"></i>&nbsp;<% } %><%= bill.name %>
                                 </p>
                                 <% }) %>
                                 <% } %>
@@ -70,19 +70,36 @@
                             <label>定额库</label>
                             <div class="ration-list">
                                 <% if (valuationData.ration_lib.length > 0) { %>
-                                <% valuationData.ration_lib.forEach(function (ration){ %>
+                                <% valuationData.ration_lib.forEach(function (ration, index){ %>
                                 <p class="form-control-static">
                                     <a class="pull-right text-danger remove-lib" data-model="ration" title="移除" data-id="<%= ration.id %>">
                                         <span class="glyphicon glyphicon-remove"></span>
                                     </a>
                                     <input type="hidden" name="ration_lib" data-id="<%= ration.id %>" value="<%= JSON.stringify({id: ration.id, name: ration.name}) %>">
-                                    <%= ration.name %>
+                                    <% if (index === 0) {%><i class="glyphicon glyphicon-flag"></i>&nbsp;<% } %><%= ration.name %>
                                 </p>
                                 <% }) %>
                                 <% } %>
                             </div>
                             <a href="#" class="btn btn-link btn-sm add-compilation" data-model="ration">添加</a>
                         </div>
+                        <div class="form-group">
+                            <label>工料机库</label>
+                            <div class="glj-list">
+                                <% if (valuationData.glj_lib.length > 0) { %>
+                                <% valuationData.glj_lib.forEach(function (glj, index){ %>
+                                <p class="form-control-static">
+                                    <a class="pull-right text-danger remove-lib" data-model="glj" title="移除" data-id="<%= glj.id %>">
+                                        <span class="glyphicon glyphicon-remove"></span>
+                                    </a>
+                                    <input type="hidden" name="glj_lib" data-id="<%= glj.id %>" value="<%= JSON.stringify({id: glj.id, name: glj.name}) %>">
+                                    <% if (index === 0) {%><i class="glyphicon glyphicon-flag"></i>&nbsp;<% } %><%= glj.name %>
+                                </p>
+                                <% }) %>
+                                <% } %>
+                            </div>
+                            <a href="#" class="btn btn-link btn-sm add-compilation" data-model="glj">添加</a>
+                        </div>
                     </div>
                     <div class="col-md-8">
                         <legend>造价书列设置<a href="javascript:void(0)" data-toggle="modal" data-target="#set-column" class="btn btn-primary btn-sm pull-right">设置</a></legend>
@@ -100,6 +117,7 @@
 <script type="text/javascript">
     let billList = '<%- billList %>';
     let rationList = '<%- rationList %>';
+    let gljList = '<%- gljList %>';
     let mainTreeCol = '<%- mainTreeCol %>';
     let colSpread = null;
     let colEditSpread = null;

+ 10 - 0
web/users/views/compilation/modal.html

@@ -31,6 +31,16 @@
                         </div>
                     </div>
                 </div>
+                <div class="form-group" id="glj-area">
+                    <label>工料机库</label>
+                    <div class="row">
+                        <div class="col-xs-12">
+                            <select class="form-control" name="glj_lib">
+                                <option value="">请选择工料机库</option>
+                            </select>
+                        </div>
+                    </div>
+                </div>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>