Selaa lähdekoodia

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

zhangweicheng 7 vuotta sitten
vanhempi
commit
b09e83266e
41 muutettua tiedostoa jossa 6441 lisäystä ja 113 poistoa
  1. 0 1
      modules/complementary_glj_lib/controllers/gljController.js
  2. 1 1
      modules/ration_repository/controllers/ration_controller.js
  3. 1 1
      modules/ration_repository/controllers/ration_repository_controller.js
  4. 1 1
      modules/ration_repository/controllers/ration_section_tree_controller.js
  5. 2 2
      modules/ration_repository/controllers/search_controller.js
  6. 1 1
      modules/ration_repository/models/glj_repository.js
  7. 5 1
      modules/ration_repository/models/ration_item.js
  8. 5 1
      modules/ration_repository/models/ration_section_tree.js
  9. 5 1
      modules/ration_repository/models/repository_map.js
  10. 53 3
      modules/reports/rpt_component/jpc_flow_tab.js
  11. 2 2
      modules/reports/util/rpt_construct_data_util.js
  12. 8 0
      public/web/sheet/sheet_common.js
  13. 2 2
      test/unit/reports/test_tpl_09.js
  14. 505 0
      web/building_saas/complementary_ration_lib/html/dinge.html
  15. 159 0
      web/building_saas/complementary_ration_lib/html/fuzhu.html
  16. 283 0
      web/building_saas/complementary_ration_lib/html/gongliao.html
  17. 54 0
      web/building_saas/complementary_ration_lib/html/main.html
  18. 407 0
      web/building_saas/complementary_ration_lib/js/annotation.js
  19. 645 0
      web/building_saas/complementary_ration_lib/js/coe.js
  20. 95 0
      web/building_saas/complementary_ration_lib/js/explanatory.js
  21. 43 0
      web/building_saas/complementary_ration_lib/js/global.js
  22. 414 0
      web/building_saas/complementary_ration_lib/js/jobContent.js
  23. 33 0
      web/building_saas/complementary_ration_lib/js/main.js
  24. 659 0
      web/building_saas/complementary_ration_lib/js/ration.js
  25. 49 0
      web/building_saas/complementary_ration_lib/js/rationUnits.js
  26. 194 0
      web/building_saas/complementary_ration_lib/js/ration_assist.js
  27. 324 0
      web/building_saas/complementary_ration_lib/js/ration_coe.js
  28. 576 0
      web/building_saas/complementary_ration_lib/js/ration_glj.js
  29. 984 0
      web/building_saas/complementary_ration_lib/js/repository_glj.js
  30. 526 0
      web/building_saas/complementary_ration_lib/js/section_tree.js
  31. 202 0
      web/building_saas/complementary_ration_lib/js/sheetsOpr.js
  32. 69 6
      web/building_saas/main/html/main.html
  33. 34 8
      web/building_saas/main/js/models/calc_base.js
  34. 7 7
      web/building_saas/main/js/views/calc_base_view.js
  35. 51 40
      web/building_saas/main/js/views/character_content_view.js
  36. 2 2
      web/building_saas/main/js/views/glj_view.js
  37. 1 1
      web/building_saas/main/js/views/project_property_decimal_view.js
  38. 7 31
      web/building_saas/main/js/views/sub_view.js
  39. 16 0
      web/building_saas/report/html/rpt_main.html
  40. 14 0
      web/building_saas/report/js/rpt_main.js
  41. 2 1
      web/common/html/header.html

+ 0 - 1
modules/complementary_glj_lib/controllers/gljController.js

@@ -13,7 +13,6 @@ let callback = function(req, res, err, message, data){
 
 class GljController extends BaseController{
     async redirectGlj(req, res){
-        console.log(req.s)
         let gljLibId = null, engineeringId, sessionCompilation = req.session.sessionCompilation,
             rationValuation = sessionCompilation.ration_valuation,
             billValuation = sessionCompilation.bill_valuation,

+ 1 - 1
modules/ration_repository/controllers/ration_controller.js

@@ -2,7 +2,7 @@
  * Created by Tony on 2017/5/2.
  */
 
-var rationItem = require('../models/ration_item');
+var rationItem = require('../models/ration_item').Dao;
 var callback = function(req, res, err, message, data){
     res.json({error: err, message: message, data: data});
 };

+ 1 - 1
modules/ration_repository/controllers/ration_repository_controller.js

@@ -1,7 +1,7 @@
 /**
  * Created by Tony on 2017/4/20.
  */
-var rationRepository = require("../models/repository_map");
+var rationRepository = require("../models/repository_map").Dao;
 
 var callback = function(req, res, err, message, data){
     res.json({error: err, message: message, data: data});

+ 1 - 1
modules/ration_repository/controllers/ration_section_tree_controller.js

@@ -2,7 +2,7 @@
  * Created by Tony on 2017/4/21.
  */
 
-var rationChapterTreeData = require('../models/ration_section_tree');
+var rationChapterTreeData = require('../models/ration_section_tree').Dao;
 var callback = function(req,res,err,message, data){
     res.json({error: err, message: message, data: data});
 }

+ 2 - 2
modules/ration_repository/controllers/search_controller.js

@@ -1,8 +1,8 @@
 /**
  * Created by Mai on 2017/6/5.
  */
-var rationItem = require('../models/ration_item');
-let rationChapter = require('../models/ration_section_tree');
+var rationItem = require('../models/ration_item').Dao;;
+let rationChapter = require('../models/ration_section_tree').Dao;
 let asyncTool = require('async');
 var callback = function(req, res, err, message, data){
     res.json({error: err, message: message, data: data});

+ 1 - 1
modules/ration_repository/models/glj_repository.js

@@ -33,7 +33,7 @@ var gljSchema = mongoose.Schema({
 });
 var gljTypeModel = db.model("std_ration_lib_glj_type",gljTypeSchema, "std_ration_lib_glj_type");
 var gljItemModel = mongoose.model("std_glj_lib_gljList");
-var repositoryMap = require('./repository_map');
+var repositoryMap = require('./repository_map').Dao;
 var counter = require('../../../public/counter/counter');
 
 var gljItemDAO = function(){};

+ 5 - 1
modules/ration_repository/models/ration_item.js

@@ -213,5 +213,9 @@ rationItemDAO.prototype.updateRationItems = function(rationLibId, sectionId, ite
     });
 };
 
-module.exports = new rationItemDAO()
+module.exports = {
+    Dao: new rationItemDAO(),
+    Model: rationItemModel
+};
+//module.exports = new rationItemDAO()
 

+ 5 - 1
modules/ration_repository/models/ration_section_tree.js

@@ -117,4 +117,8 @@ rationChapterTreeDAO.prototype.getRationChapter = function (repId, chapterID, ca
     }
 }
 
-module.exports = new rationChapterTreeDAO()
+module.exports = {
+    Model: rationChapterTreeModel,
+    Dao: new rationChapterTreeDAO()
+};
+//module.exports = new rationChapterTreeDAO()

+ 5 - 1
modules/ration_repository/models/repository_map.js

@@ -117,4 +117,8 @@ rationRepositoryDao.prototype.deleteRationLib = function(rationName,callback){
     });
 }
 
-module.exports = new rationRepositoryDao();
+module.exports = {
+    Dao: new rationRepositoryDao(),
+    Model: rationRepository
+}
+//module.exports = new rationRepositoryDao();

+ 53 - 3
modules/reports/rpt_component/jpc_flow_tab.js

@@ -85,6 +85,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
         me.seg_sum_fields_idx = [];
         me.seg_sum_tab_fields = [];
         me.page_sum_fields_idx = [];
+        me.page_sum_tab_fields = [];
 
         me.group_fields = [];
         me.group_sum_fields = [];
@@ -95,6 +96,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
         me.pageStatusLst = [];
         me.groupSumValLst = [];
         me.segSumValLst = [];
+        me.pageSumValLst = [];
         me.multiCols = 1;
         me.pagesAmt = 0;
     };
@@ -102,7 +104,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
         let me = this;
         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_PAGE_SUM][JV.PROP_SUM_FIELDS], me.page_sum_tab_fields, me.page_sum_fields_idx, me.isEx);
         JpcFieldHelper.findAndPutDataFieldIdx(rptTpl, rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_GROUP][JV.PROP_GROUP_FIELDS], me.group_fields, null, me.isEx);
         JpcFieldHelper.findAndPutDataFieldIdx(rptTpl, rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_GROUP][JV.PROP_SUM_FIELDS], me.group_sum_fields, null, me.isEx);
         for (let si = 0; si < dataSeq.length; si++) {
@@ -355,15 +357,18 @@ JpcFlowTabSrv.prototype.createNew = function(){
                     } else {
                         if (currentRecAmt + maxRowRec >= ttlSegRecAmt) {
                             pageStatus[JV.STATUS_SEGMENT_END] = true;
+                            pageStatus[JV.STATUS_REPORT_END] = true;
                             private_resetBandArea();
                             let hasAdHocRow = !JpcFlowTabHelper.chkSegEnd(bands, rptTpl, ttlSegRecAmt, currentRecAmt, maxRowRec, me.isEx);
                             if (hasAdHocRow) {
                                 //add page info(pre segment end)
                                 pageStatus[JV.STATUS_SEGMENT_END] = false;
+                                pageStatus[JV.STATUS_REPORT_END] = false;
                                 private_addPage(segIdx, grpSeqInfo, false, false, -1);
                             }
                             //add page info
                             pageStatus[JV.STATUS_SEGMENT_END] = true;
+                            pageStatus[JV.STATUS_REPORT_END] = true;
                             private_addPage(segIdx, grpSeqInfo, false, false, -1);
                         } else {
                             private_addPage(segIdx, grpSeqInfo, false, false, -1);
@@ -503,6 +508,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
             // 2.3 Sum Seg
             tabRstLst.push(me.outputSegSum(rptTpl, dataObj, page, segIdx, bands, unitFactor, controls));
             // 2.4 Sum Page
+            tabRstLst.push(me.outputPageSum(rptTpl, dataObj, page, segIdx, bands, unitFactor, controls));
             // 2.5 Group
             // 2.6 Discrete
             tabRstLst.push(JpcDiscreteHelper.outputDiscreteInfo(rptTpl[FLOW_NODE_STR][JV.NODE_DISCRETE_INFO], bands, dataObj, unitFactor, me.pageStatusLst[page - 1], segIdx, 1, 0, $CURRENT_RPT));
@@ -536,6 +542,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
                 // 2.3 Sum Seg
                 tabRstLst.push(me.outputSegSum(rptTpl, dataObj, actualPage, segIdx, bands, unitFactor, controls));
                 // 2.4 Sum Page
+                tabRstLst.push(me.outputPageSum(rptTpl, dataObj, actualPage, segIdx, bands, unitFactor, controls));
                 // 2.5 Group
                 // 2.6 Discrete
                 if (pi === 0) {
@@ -563,6 +570,15 @@ JpcFlowTabSrv.prototype.createNew = function(){
                 let data_details = me.isEx?dataObj[JV.DATA_DETAIL_DATA_EX]:dataObj[JV.DATA_DETAIL_DATA];
                 let data_details_ex = $CURRENT_RPT.isFollowMode?dataObj[JV.DATA_DETAIL_DATA_EX]:null;
                 let contentValuesIdx = me.dispValueIdxLst[page - 1];
+                let page_sum_data_fields = [];
+                for (let i = 0; i < me.page_sum_fields_idx.length; i++) {
+                    let data_field = data_details[me.page_sum_fields_idx[i]];
+                    page_sum_data_fields.push(data_field);
+                }
+                let rowGrandTotal = [];
+                for (let di = 0; di < page_sum_data_fields.length; di++) {
+                    rowGrandTotal.push(0.0);
+                }
                 //normal content
                 for (let rowIdx = 0; rowIdx < contentValuesIdx.length; rowIdx++) {
                     for (let i = 0; i < tab_fields.length; i++) {
@@ -603,7 +619,12 @@ JpcFlowTabSrv.prototype.createNew = function(){
                             }
                         }
                     }
+                    //page sum content
+                    for (let di = 0; di < page_sum_data_fields.length; di++) {
+                        rowGrandTotal[di] = rowGrandTotal[di] + 1.0 * JpcFieldHelper.getValue(page_sum_data_fields[di], contentValuesIdx[rowIdx][2]);
+                    }
                 }
+                me.pageSumValLst.push(rowGrandTotal);
                 //grouping content
                 for (let rowIdx = 0; rowIdx < contentValuesIdx.length; rowIdx++) {
                     if (contentValuesIdx[rowIdx][1] === JV.DISPLAY_VAL_TYPE_GROUP) {
@@ -672,6 +693,35 @@ JpcFlowTabSrv.prototype.createNew = function(){
         }
         return rst;
     };
+    JpcFlowTabResult.outputPageSum = function (rptTpl, dataObj, page, segIdx, bands, unitFactor, controls) {
+        let me = this, rst = [];
+        let FLOW_NODE_STR = me.isEx?JV.NODE_FLOW_INFO_EX:JV.NODE_FLOW_INFO;
+        let tab = rptTpl[FLOW_NODE_STR][JV.NODE_FLOW_PAGE_SUM];
+        let band = bands[tab[JV.PROP_BAND_NAME]];
+        if (band) {
+            let pageStatus = me.pageStatusLst[page - 1];
+            if (pageStatus[band[JV.BAND_PROP_DISPLAY_TYPE]]) {
+                let tab_fields = me.page_sum_tab_fields;
+                for (let i = 0; i < tab_fields.length; i++) {
+                    let cellItem = JpcCommonOutputHelper.createCommonOutput(tab_fields[i], me.pageSumValLst[page - 1], controls);
+                    cellItem[JV.PROP_AREA] = JpcAreaHelper.outputArea(tab_fields[i][JV.PROP_AREA], band, unitFactor, 1, 0, 1, 0, me.multiCols, 0, true, false);
+                    rst.push(cellItem);
+                }
+                if (tab[JV.PROP_TEXT]) {
+                    rst.push(JpcTextHelper.outputText(tab[JV.PROP_TEXT], band, unitFactor, 1, 0, 1, 0, me.multiCols, 0));
+                }
+                if (tab[JV.PROP_TEXTS]) {
+                    for (let j = 0; j < tab[JV.PROP_TEXTS].length; j++) {
+                        rst.push(JpcTextHelper.outputText(tab[JV.PROP_TEXTS][j], band, unitFactor, 1, 0, 1, 0, me.multiCols, 0));
+                    }
+                }
+                if (tab[JV.NODE_DISCRETE_INFO]) {
+                    rst = rst.concat(JpcDiscreteHelper.outputDiscreteInfo(tab[JV.NODE_DISCRETE_INFO], bands, dataObj, unitFactor, me.pageStatusLst[page - 1], segIdx, me.multiCols, 0));
+                }
+            }
+        }
+        return rst;
+    };
     JpcFlowTabResult.outputTabField = function (band, tab_field, data_field, valueIdx, serialIdx, rows, rowIdx, cols, colIdx, unitFactor, isRow, controls, multiColIdx) {
         let me = this,
             rst = JpcCommonOutputHelper.createCommonOutput(tab_field, JpcFieldHelper.getValue(data_field, valueIdx), controls);
@@ -695,10 +745,10 @@ JpcFlowTabSrv.prototype.createNew = function(){
             }
         }
         if (grp_line[JV.PROP_DISCRETE_FIELDS]) {
-            //
+            //暂时不支持
         }
         if (grp_line[JV.PROP_PARAMS]) {
-            //
+            //暂时不支持
         }
         // console.log(rst);
         return rst;

+ 2 - 2
modules/reports/util/rpt_construct_data_util.js

@@ -747,7 +747,7 @@ function ext_getFee(feeKey, dtlFeeKey) {
 function pri_getFee(dItem, feeKey, dtlFeeKey) {
     let rst = 0;
     let hasValue = false;
-    if (dItem.hasOwnProperty("fees")) {
+    if (dItem["fees"]) {
         for (let fee of dItem["fees"]) {
             if (fee["fieldName"] === feeKey) {
                 if (dtlFeeKey) {
@@ -759,7 +759,7 @@ function pri_getFee(dItem, feeKey, dtlFeeKey) {
                 break;
             }
         }
-    } else if (dItem.hasOwnProperty(feeKey)) {
+    } else if (dItem[feeKey]) {
         hasValue = true;
         rst = dItem[feeKey];
     } else {

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

@@ -70,6 +70,14 @@ var sheetCommonObj = {
         sheet.resumeEvent();
         sheet.resumePaint();
     },
+    cleanData: function (sheet, setting, rowCount) {
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        sheet.clear(-1, 0, -1, setting.header.length, GC.Spread.Sheets.SheetArea.viewport, GC.Spread.Sheets.StorageType.data);
+        if (rowCount > 0) sheet.setRowCount(rowCount);
+        sheet.resumeEvent();
+        sheet.resumePaint();
+    },
     setAreaAlign: function(area, hAlign, vAlign){
         if (!(hAlign) || hAlign === "left") {
             area.hAlign(GC.Spread.Sheets.HorizontalAlign.left);

+ 2 - 2
test/unit/reports/test_tpl_09.js

@@ -44,8 +44,8 @@ let demoRptId = 232, pagesize = "A4";
 
 let userId_Leng = 1142; //小冷User Id
 // demoPrjId = 720; //QA: DW3
-demoPrjId = 1296; //QA:
-//*/
+demoPrjId = 1348; //QA:
+/*/
 let userId_Dft = userId_Leng;
 /*/
  let userId_Dft = 76075;

+ 505 - 0
web/building_saas/complementary_ration_lib/html/dinge.html

@@ -0,0 +1,505 @@
+<!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="/lib/css/bootstrap/themes.css">-->
+    <link rel="stylesheet" href="/web/building_saas/css/main.css">
+    <link rel="stylesheet" href="/lib/font-awesome/font-awesome.min.css">
+    <link rel="stylesheet" href="/lib/jquery-contextmenu/jquery.contextMenu.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>
+</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 id="rationname" class="navbar-text"><a href="main">定额库</a><i class="fa fa-angle-right fa-fw"></i>XXX定额库</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" id ="dinge" >定额</a>
+                  </li>
+                  <li class="nav-item">
+                      <a class="nav-link px-3" id="gongliao" href="#">工料机</a>
+                  </li>
+                  <li class="nav-item">
+                      <a class="nav-link px-3" id="fuzhu" href="#">附注条件</a>
+                  </li>
+                  <li class="nav-item">
+                      <a class="nav-link px-3" href="#">安装增加费</a>
+                  </li>
+              </ul>
+        </nav>
+    </div>
+    <div class="main" style="overflow: hidden">
+        <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: hidden">
+                      <div class="tab-bar">
+                          <a href="javascript:void(0);" id="tree_Insert" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="插入"><i class="fa fa-plus" aria-hidden="true"></i></a>
+                          <a href="javascript:void(0);" id="tree_remove" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="删除"><i class="fa fa-remove" aria-hidden="true"></i></a>
+                          <a href="javascript:void(0);" id="tree_upLevel" class="btn btn-sm " data-toggle="tooltip" data-placement="bottom" title="" data-original-title="升级"><i class="fa fa-arrow-left" aria-hidden="true"></i></a>
+                          <a href="javascript:void(0);" id="tree_downLevel" class="btn btn-sm " data-toggle="tooltip" data-placement="bottom" title="" data-original-title="降级"><i class="fa fa-arrow-right" aria-hidden="true"></i></a>
+                          <a href="javascript:void(0);" id="tree_downMove" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="下移"><i class="fa fa-arrow-down" aria-hidden="true"></i></a>
+                          <a href="javascript:void(0);" id="tree_upMove" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="上移"><i class="fa fa-arrow-up" aria-hidden="true"></i></a>
+                      </div>
+                    <div class="tab-content" id="sectionSpread" style="overflow: hidden">
+                      <!--<ul id="rationChapterTree" class="ztree"></ul>-->
+                    </div>
+                  </div>
+                  <div class="main-content col-lg-9 p-0">
+                      <!-- 右标签 -->
+                      <ul class="nav nav-tabs tools-bar" role="tablist">
+                          <li class="nav-item">
+                              <a class="nav-link active" data-toggle="tab" href="#tde" role="tab">定额</a>
+                          </li>
+                          <li class="nav-item">
+                              <a class="nav-link" data-toggle="tab" href="#tsm" role="tab" id="explanationLink">说明</a>
+                          </li>
+                          <li class="nav-item">
+                              <a class="nav-link" data-toggle="tab" href="#tjs" role="tab">计算规则</a>
+                          </li>
+                          <li class="nav-item">
+                              <a class="nav-link" data-toggle="tab" href="#tgz" role="tab">工作内容</a>
+                          </li>
+                          <li class="nav-item">
+                              <a class="nav-link" data-toggle="tab" href="#tfz" role="tab">附注</a>
+                          </li>
+                      </ul>
+                      <div class="tab-content">
+                          <!--定额-->
+                          <div class="tab-pane active" id="tde" role="tabpanel">
+                              <!--定额top-->
+                              <div id="rationItemsSheet" class="main-data-top"></div>
+                              <!--定额bottom-->
+                              <div class="bottom-content">
+                                  <!-- 标签 -->
+                                  <ul class="nav nav-tabs" role="tablist">
+                                      <li class="nav-item">
+                                          <a class="nav-link active" id="linkGLJ" data-toggle="tab" href="#rDetail" role="tab">工料机</a>
+                                      </li>
+                                      <li class="nav-item">
+                                          <a class="nav-link" id="linkFZDE" data-toggle="tab" href="#rDetail" role="tab">辅助定额调整</a>
+                                      </li>
+                                      <li class="nav-item">
+                                          <a class="nav-link" id="linkFZTJ" data-toggle="tab" href="#rDetail" role="tab">附注条件调整</a>
+                                      </li>
+                                      <li class="nav-item">
+                                          <!--<a class="nav-link" id="linkAZZJ" data-toggle="tab" href="#" role="tab">安装增加费</a>-->
+                                          <a class="nav-link" href="#">安装增加费</a>
+                                      </li>
+                                  </ul>
+                                  <!-- 内容 -->
+                                  <div class="tab-content">
+                                      <div class="tab-pane active" id="rDetail" role="tabpanel">
+                                          <div id="rdSpread" class="main-data-bottom" style="overflow: hidden"></div>
+                                      </div>
+                                  </div>
+                              </div>
+                          </div>
+                          <!--说明-->
+                          <div class="tab-pane" id="tsm" role="tabpanel">
+                              <div class="main-data">
+                                <!--  <div class="m-2"><a href="javacript:void(0);" data-toggle="modal" data-target="#editTsm" title="编辑">编辑说明</a></div>-->
+                                  <div class="main-content m-2">
+                                      <h5>说明</h5>
+                                      <textarea id="explanationShow" class="form-control" rows="35" style="background: white;"></textarea>
+                                  </div>
+                              </div>
+                          </div>
+                          <!--计算规则-->
+                          <div class="tab-pane" id="tjs" role="tabpanel">
+                              <div class="main-data">
+                         <!--         <div class="m-2"><a href="javacript:void(0);" data-toggle="modal" data-target="#editTjs" title="编辑">编辑计算规则</a></div>-->
+                                  <div class="main-content m-2">
+                                      <h5>计算规则</h5>
+                                      <textarea id="ruleTextShow" class="form-control"   rows="35" style="background: white;"></textarea>
+                                  </div>
+                              </div>
+                          </div>
+                          <!--工作内容-->
+                          <div class="tab-pane" id="tgz" role="tabpanel">
+                              <div class="main-data">
+                                  <div class="form-check m-2"><label class="form-check-label"><input type="radio" class="form-check-input" name="optionsRadios" value="ALL" disabled=""> 适合本项所有定额</label>&nbsp;&nbsp;<label class="form-check-label"><input type="radio" class="form-check-input" name="optionsRadios" value="PARTIAL" disabled> 适合本项部分定额</label></div>
+                                  <!-- <p class="m-2">适合本项所有定额</p> -->
+                                  <table class="table table-sm table-bordered m-0" id="tableAll">
+                                      <tr>
+                                          <td><textarea class="form-control" rows="30" id="txtareaAll"></textarea></td>
+                                      </tr>
+                                  </table>
+                                  <table class="table table-sm table-bordered m-0" id="tablePartial">
+                                  </table>
+                              </div>
+                          </div>
+                          <!--附注-->
+                          <div class="tab-pane" id="tfz" role="tabpanel">
+                              <div class="main-data">
+                                  <div class="form-check m-2"><label class="form-check-label"><input type="radio" class="form-check-input" name="fzRadios" value="ALL" disabled=""> 适合本项所有定额</label>&nbsp;&nbsp;<label class="form-check-label"><input type="radio" class="form-check-input" name="fzRadios" value="PARTIAL" disabled> 适合本项部分定额</label></div>
+                                  <!-- <p class="m-2">适合本项所有定额</p> -->
+                                  <table class="table table-sm table-bordered m-0" id="fzTableAll">
+                                      <tr>
+                                          <td><textarea class="form-control" rows="30" id="fzTxtareaAll"></textarea></td>
+                                      </tr>
+                                  </table>
+                                  <table class="table table-sm table-bordered m-0" id="fzTablePartial">
+                                  </table>
+                              </div>
+                          </div>
+                  </div>
+                </div>
+            </div>
+        </div>
+    </div>
+        <!--弹出添加-->
+        <button id="gznrBtn" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#addNewgznr" style="display: none"></button>
+        <div class="modal fade" id="addNewgznr" 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>
+                                <textarea class="form-control" rows="5"></textarea>
+                            </div>
+                        </form>
+                        <form>
+                            <div class="form-group">
+                                <label>编码</label>
+                                <div class="form-control">
+                                    <div class="row code">
+                                        <div class="col">
+                                            <label class="form-check-label">
+                                                <input class="form-check-input" type="checkbox" value="option1" checked> AA0017
+                                            </label>
+                                        </div>
+                                        <div class="col">
+                                            <label class="form-check-label">
+                                                <input class="form-check-input" type="checkbox" value="option1" checked> AA0018
+                                            </label>
+                                        </div>
+                                        <div class="col">
+                                            <label class="form-check-label">
+                                                <input class="form-check-input" type="checkbox" value="option1" checked> AA0019
+                                            </label>
+                                        </div>
+                                        <div class="w-100"></div>
+                                        <div class="col">
+                                            <label class="form-check-label">
+                                                <input class="form-check-input" type="checkbox" value="option1"> AA0020
+                                            </label>
+                                        </div>
+                                        <div class="col">
+                                            <label class="form-check-label">
+                                                <input class="form-check-input" type="checkbox" value="option1"> AA0021
+                                            </label>
+                                        </div>
+                                        <div class="col">
+                                            <label class="form-check-label">
+                                                <input class="form-check-input" type="checkbox" value="option1"> AA0022
+                                            </label>
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
+
+                            <div class="form-group">
+                                <label>内容</label>
+                                <textarea class="form-control" rows="5"></textarea>
+                            </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="editTsm" 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>
+                                <textarea class="form-control" rows="5" id="explanationAdd"></textarea>
+                            </div>
+                        </form>
+                    </div>
+                    <div class="modal-footer">
+                        <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                        <a href="javascript:void(0);" class="btn btn-primary" id="explanationBtn" data-dismiss="modal">确定</a>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="modal fade" id="editTjs" 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>
+                                <textarea class="form-control" rows="5"></textarea>
+                            </div>
+                        </form>
+                    </div>
+                    <div class="modal-footer">
+                        <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                        <a href="javascript:void(0);" class="btn btn-primary" data-dismiss="modal" id="ruleTextAdd">确定</a>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="modal fade" id="editBianmaQ" 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>
+                                <div class="form-control">
+                                    <div class="row code" id="updateCon">
+                                    </div>
+                                </div>
+                            </div>
+                        </form>
+                    </div>
+                    <div class="modal-footer">
+                        <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                        <a href="javascript: void(0);" class="btn btn-primary" data-dismiss="modal" id="updateConBtn">确定</a>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="modal fade" id="editBianma" 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>
+                                <div class="form-control">
+                                    <div class="row code" id="addCon">
+                                    </div>
+                                </div>
+                            </div>
+                        </form>
+                    </div>
+                    <div class="modal-footer">
+                        <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                        <a href="javascript: void(0);" class="btn btn-primary" data-dismiss="modal" id="addConBtn">确定</a>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <!--弹出附注-->
+        <div class="modal fade" id="fzEditBianmaQ" 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>
+                                <div class="form-control">
+                                    <div class="row code" id="fzUpdateCon">
+                                    </div>
+                                </div>
+                            </div>
+                        </form>
+                    </div>
+                    <div class="modal-footer">
+                        <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                        <a href="javascript: void(0);" class="btn btn-primary" data-dismiss="modal" id="fzUpdateConBtn">确定</a>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="modal fade" id="fzEditBianma" 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>
+                                <div class="form-control">
+                                    <div class="row code" id="fzAddCon">
+                                    </div>
+                                </div>
+                            </div>
+                        </form>
+                    </div>
+                    <div class="modal-footer">
+                        <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                        <a href="javascript: void(0);" class="btn btn-primary" data-dismiss="modal" id="fzAddConBtn">确定</a>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <!--弹出警告窗-->
+        <button id="rationAlertBtn" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#rationAlert" style="display: none"></button>
+        <div class="modal fade" id="rationAlert" 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="rationAlertCls" class="close" data-dismiss="modal" aria-label="Close">
+                            <span aria-hidden="true">×</span>
+                        </button>
+                    </div>
+                    <div class="modal-body">
+                        <h5 class="text-danger" id="alertRationTxt">编码不可为空,继续新增定额?</h5>
+                    </div>
+                    <div class="modal-footer">
+                        <button type="button" class="btn btn-secondary" id="rationAlertCac" data-dismiss="modal">取消</button>
+                        <a href="javascript: void(0);" id="rationAlertCof" class="btn btn-danger" data-dismiss="modal">确认</a>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <button id="alertModalBtn" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#alertModal" style="display: none"></button>
+        <div class="modal fade" id="alertModal" 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="alertModalCls" 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="alertModalCof" data-dismiss="modal">确认</button>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <!-- JS. -->
+        <script type="text/javascript" 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/jquery/jquery-3.2.1.min.js"></script>
+        <script type="text/javascript" src="/lib/jquery-contextmenu/jquery.contextMenu.min.js"></script>
+        <script type="text/javascript" src="/lib/jquery-contextmenu/jquery.ui.position.js"></script>
+        <script type="text/javascript" src="/lib/popper/popper.min.js"></script>
+        <script type="text/javascript" src="/lib/bootstrap/bootstrap.min.js"></script>
+        <script type="text/javascript" src="/web/building_saas/complementary_ration_lib/js/global.js"></script>
+        <script type="text/javascript" src="/public/web/id_tree.js"></script>
+        <script type="text/javascript" src="/public/web/tree_sheet/tree_sheet_controller.js"></script>
+        <script type="text/javascript" src="/public/web/tree_sheet/tree_sheet_helper.js"></script>
+        <script type="text/javascript" src="/public/web/treeDataHelper.js"></script>
+        <script type="text/javascript" src="/public/web/sheet/sheet_common.js"></script>
+        <script type="text/javascript" src="/web/building_saas/complementary_ration_lib/js/sheetsOpr.js"></script>
+        <script type="text/javascript" src="/public/web/QueryParam.js"></script>
+        <script type="text/javascript" src="/public/web/storageUtil.js"></script>
+
+        <script type="text/javascript" src="/web/building_saas/complementary_ration_lib/js/section_tree.js"></script>
+        <script type="text/javascript" src="/web/building_saas/complementary_ration_lib/js/explanatory.js"></script>
+        <script type="text/javascript" src="/web/building_saas/complementary_ration_lib/js/jobContent.js"></script>
+        <script type="text/javascript" src="/web/building_saas/complementary_ration_lib/js/annotation.js"></script>
+        <script type="text/javascript" src="/public/web/scMathUtil.js"></script>
+        <script type="text/javascript" src="/public/web/common_ajax.js"></script>
+        <script type="text/javascript" src="/public/web/ztree_common.js"></script>
+        <script type="text/javascript" src="/web/building_saas/complementary_ration_lib/js/rationUnits.js"></script>
+        <script type="text/javascript" src="/web/building_saas/complementary_ration_lib/js/ration.js"></script>
+        <script type="text/javascript" src="/web/building_saas/complementary_ration_lib/js/ration_glj.js"></script>
+   <!--     <script type="text/javascript" src="/public/web/sheet/sheet_creater.js"></script>-->
+        <script type="text/javascript" src="/web/building_saas/complementary_ration_lib/js/ration_coe.js"></script>
+        <script type="text/javascript" src="/web/building_saas/complementary_ration_lib/js/ration_assist.js"></script>
+        <script type="text/javascript">
+            let userID = '<%=userID %>';
+            $(document).ready(function(){
+                pageOprObj.initPage();
+                rationOprObj.buildSheet($("#rationItemsSheet")[0]);
+               // sheetCommonObj.shieldAllCells(rationOprObj.workBook.getSheet(0), rationOprObj.setting);
+
+               // tabPanel 下有多个Spread时,相互之间不能正确显示。改成一个Spread下多个Sheet。
+                var rdSpread = sheetCommonObj.createSpread($("#rdSpread")[0], 3);
+                rationGLJOprObj.buildSheet(rdSpread.getSheet(0));
+               // sheetCommonObj.shieldAllCells(rdSpread.getSheet(0), rationGLJOprObj.setting);
+
+                rationAssistOprObj.buildSheet(rdSpread.getSheet(1));
+             //   sheetCommonObj.shieldAllCells(rdSpread.getSheet(1), rationAssistOprObj.setting);
+
+                rationCoeOprObj.buildSheet(rdSpread.getSheet(2));
+              //  sheetCommonObj.shieldAllCells(rdSpread.getSheet(2), rationCoeOprObj.setting);
+
+                $("#linkGLJ").click(function(){
+                    rationGLJOprObj.bindRationGljDelOpr();
+                    rdSpread.setActiveSheetIndex(0);
+                });
+
+                $("#linkFZDE").click(function(){
+                    rationAssistOprObj.bindRationAssDel();
+                    rdSpread.setActiveSheetIndex(1);
+                });
+
+                $("#linkFZTJ").click(function(){
+                    rationCoeOprObj.bindRationCoeDel();
+                    rdSpread.setActiveSheetIndex(2);
+                });
+            });
+        </script>
+    </div>
+</body>
+<script type="text/javascript">
+    autoFlashHeight();
+</script>
+
+</html>

+ 159 - 0
web/building_saas/complementary_ration_lib/html/fuzhu.html

@@ -0,0 +1,159 @@
+<!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/ration_repository/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">
+    <!--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" id="rationname"><a href="main">定额库</a><i class="fa fa-angle-right fa-fw"></i>XXX定额库</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 px-3" id="drirect-dinge" href="javascript:void(0);">定额</a>
+                  </li>
+                  <li class="nav-item">
+                      <a class="nav-link px-3" id="gongliao" href="javascript:void(0);">工料机</a>
+                  </li>
+                  <li class="nav-item">
+                      <a class="nav-link active px-3">附注条件</a>
+                  </li>
+                  <li class="nav-item">
+                      <a class="nav-link px-3" href="#maz">安装增加费</a>
+                  </li>
+
+                  <li class="nav-item">
+                  <!--<input type="button" id="btnAddRow" value="Add Row" />-->
+                  <!--<input type="button" id="btnDeleteRow" value="Delete Row" />-->
+                  </li>
+              </ul>
+        </nav>
+    </div>
+   <!-- <div class="main">
+        <div class="content">
+            <div class="container-fluid">
+                <div class="row">
+                  <div class="main-side col-lg-7 p-0">
+                    <div class="main-data" id="mainSpread"  style="height:1000px;"></div>
+                  </div>
+                  <div class="main-content col-lg-5 p-0">
+                      <div class="main-data" id="contentSpread" style="height:1000px;"></div>
+                  </div>
+                </div>
+            </div>
+        </div>
+    </div>-->
+    <div class="main">
+        <div class="content">
+            <div class="container-fluid">
+                <div class="row">
+                    <div class="main-content col-lg-7 p-0">
+                        <div class="main-data" id="mainSpread">
+                        </div>
+                    </div>
+                    <div class="main-side col-lg-5 p-0">
+                        <div class="main-data" id="contentSpread" >
+                        </div>
+                    </div>
+                </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 type="text/javascript" src="/web/maintain/ration_repository/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 src="/public/common_util.js"></script>
+    <script src="/public/debug.js"></script>
+    <script type="text/javascript" src="/public/web/sheet/sheet_common.js"></script>
+    <script type="text/javascript" src="/web/maintain/ration_repository/js/sheetsOpr.js"></script>
+    <script type="text/javascript" src="/public/web/storageUtil.js"></script>
+    <script type="text/javascript" src="/web/maintain/ration_repository/js/coe.js"></script>
+    <script type="text/javascript">
+        $(document).ready(function () {
+            pageObj.initPage();
+        });
+    </script>
+   <!-- <SCRIPT type="text/javascript">
+  		&lt;!&ndash;
+  		var setting = {
+  			view: {
+  				showIcon: false
+  			},
+  			data: {
+  				simpleData: {
+  					enable: true
+  				}
+  			}
+  		};
+
+  		var zNodes =[
+  			{ id:1, pId:0, name:"父节点1 - 展开", open:true},
+  			{ id:11, pId:1, name:"父节点11 - 折叠"},
+  			{ id:111, pId:11, name:"叶子节点111"},
+  			{ id:112, pId:11, name:"叶子节点112"},
+  			{ id:113, pId:11, name:"叶子节点113"},
+  			{ id:114, pId:11, name:"叶子节点114"},
+  			{ id:12, pId:1, name:"父节点12 - 折叠"},
+  			{ id:121, pId:12, name:"叶子节点121"},
+  			{ id:122, pId:12, name:"叶子节点122"},
+  			{ id:123, pId:12, name:"叶子节点123"},
+  			{ id:124, pId:12, name:"叶子节点124"},
+  			{ id:13, pId:1, name:"父节点13 - 没有子节点", isParent:true},
+  			{ id:2, pId:0, name:"父节点2 - 折叠"},
+  			{ id:21, pId:2, name:"父节点21 - 展开", open:true},
+  			{ id:211, pId:21, name:"叶子节点211"},
+  			{ id:212, pId:21, name:"叶子节点212"},
+  			{ id:213, pId:21, name:"叶子节点213"},
+  			{ id:214, pId:21, name:"叶子节点214"},
+  			{ id:22, pId:2, name:"父节点22 - 折叠"},
+  			{ id:221, pId:22, name:"叶子节点221"},
+  			{ id:222, pId:22, name:"叶子节点222"},
+  			{ id:223, pId:22, name:"叶子节点223"},
+  			{ id:224, pId:22, name:"叶子节点224"},
+  			{ id:23, pId:2, name:"父节点23 - 折叠"},
+  			{ id:231, pId:23, name:"叶子节点231"},
+  			{ id:232, pId:23, name:"叶子节点232"},
+  			{ id:233, pId:23, name:"叶子节点233"},
+  			{ id:234, pId:23, name:"叶子节点234"},
+  			{ id:3, pId:0, name:"父节点3 - 没有子节点", isParent:true}
+  		];
+
+  		function showIconForTree(treeId, treeNode) {
+  			return !treeNode.isParent;
+  		};
+
+  		$(document).ready(function(){
+  			$.fn.zTree.init($("#treeDemo"), setting, zNodes);
+  		});
+  		//&ndash;&gt;
+  	</SCRIPT>-->
+</body>
+<script type="text/javascript">
+    autoFlashHeight();
+</script>
+
+</html>

+ 283 - 0
web/building_saas/complementary_ration_lib/html/gongliao.html

@@ -0,0 +1,283 @@
+<!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/ration_repository/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">
+    <!--zTree-->
+  	<link rel="stylesheet" href="/lib/ztree/css/zTreeStyle.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>
+</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 id="rationname" class="navbar-text"><a href="main">定额库</a><i class="fa fa-angle-right fa-fw"></i>XXX定额库</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 px-3" id="drirect-dinge" href="/rationRepository/ration">定额</a>
+                  </li>
+                  <li class="nav-item">
+                      <a class="nav-link active px-3">工料机</a>
+                  </li>
+                  <li class="nav-item">
+                      <a class="nav-link px-3" id="fuzhu" href="javascript:void(0);">附注条件</a>
+                  </li>
+                  <li class="nav-item">
+                      <a class="nav-link px-3" href="#maz">安装增加费</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-9 p-0">
+                        <div id="GLJListSheet" class="main-data"></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 class="form-control" id="gljcode" placeholder="输入编码" type="text">
+                    </div>
+                    <div class="form-group">
+                      <label>名称</label>
+                      <input class="form-control" id="gljname" placeholder="输入名称" type="text">
+                    </div>
+                    <div class="form-group">
+                      <label>规格</label>
+                      <input class="form-control" id="gljgg" placeholder="输入规格" type="text">
+                    </div>
+                    <div class="form-group">
+                      <label>单位</label>
+                      <select class="form-control" id = "gljdw"><option>选择单位</option><option>工日</option><option>t</option><option>m3</option></select>
+                    </div>
+                    <div class="form-group">
+                      <label>基价单价</label>
+                      <input class="form-control" id="gljjj" placeholder="输入基价" type="number">
+                    </div>
+                    <div class="form-group">
+                      <label>类型</label>
+                      <select class="form-control" id="gljlx"><option>人工</option><option>材料</option></select>
+                    </div>
+                  </form>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" id="btadd" data-dismiss="modal">添加</button>
+                    <a   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" placeholder="输入编码" id="Ecode" type="text" value="">
+                    </div>
+                    <div class="form-group">
+                      <label>名称</label>
+                      <input class="form-control" placeholder="输入名称" id ="Ename" type="text" vaule="">
+                    </div>
+                    <div class="form-group">
+                      <label>规格</label>
+                      <input class="form-control" placeholder="输入规格" id="Eguige" type="text">
+                    </div>
+                    <div class="form-group">
+                      <label>单位</label>
+                      <select class="form-control" id="Edanwei"><option>工日</option></select>
+                    </div>
+                    <div class="form-group">
+                      <label>基价单价</label>
+                      <input class="form-control" id="Ejijia" placeholder="输入基价" type="number" value="">
+                    </div>
+                    <div class="form-group">
+                      <label>类型</label>
+                      <select class="form-control" id="Eleixing"><option>人工</option></select>
+                    </div>
+                  </form>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <button type="button" class="btn btn-secondary" id="edtglj" data-dismiss="modal">确定</button>
+
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <!--弹出删除-->
+    <div class="modal fade" id="del" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <input type="hidden" id="did" value="">
+        <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 type="button" class="btn btn-secondary"   data-dismiss="modal">取消</button>
+                    <button type="button" class="btn btn-secondary" id="deleteGLJ"  data-dismiss="modal">删除</button>
+                   <!-- <a href="" class="btn btn-danger" >删除</a>-->
+                </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 type="text/javascript" src="/web/maintain/ration_repository/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/ration_repository/js/repository_glj.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="/web/maintain/ration_repository/js/sheetsOpr.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]);
+            //repositoryGljObj.buildSheet($("#GLJListSheet")[0]);
+        });
+  	</script>
+</body>
+<script type="text/javascript">
+    autoFlashHeight();
+</script>
+
+</html>

+ 54 - 0
web/building_saas/complementary_ration_lib/html/main.html

@@ -0,0 +1,54 @@
+<!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="css/bootstrap/themes.css">-->
+    <link rel="stylesheet" href="/web/building_saas/css/main.css">
+    <link rel="stylesheet" href="/lib/font-awesome/font-awesome.min.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>
+    </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></tr></thead>
+                        <tbody id="showArea">
+                        </tbody>
+                      </table>
+                    </div>
+                  </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!-- JS. -->
+    <script src="/lib/popper/popper.min.js"></script>
+    <script src="/lib/jquery/jquery-3.2.1.min.js"></script>
+    <script src="/lib/bootstrap/bootstrap.min.js"></script>
+    <script src="/web/building_saas/js/global.js"></script>
+    <!-- zTree -->
+    <script type="text/javascript" src="/public/web/date_util.js"></script>
+    <script type="text/javascript" src="/public/web/common_ajax.js"></script>
+    <script type="text/javascript" src="/web/building_saas/complementary_ration_lib/js/main.js"></script>
+    <script type="text/javascript" src="/public/web/storageUtil.js"></script>
+</body>
+<script type="text/javascript">
+    let userID = '<%=userID %>';
+</script>
+
+</html>

+ 407 - 0
web/building_saas/complementary_ration_lib/js/annotation.js

@@ -0,0 +1,407 @@
+/**
+ * Created by Zhong on 2017/12/20.
+ */
+//附注
+let annotationOprObj = {
+    situations: {ALL: 'ALL', PARTIAL: 'PARTIAL', NONE: 'NONE'},
+    currentSituation: null,//本项适用情况
+    radios: $("input[name = 'fzRadios']"),
+    fzTableAll: $('#fzTableAll'),
+    fzTablePartial: $('#fzTablePartial'),
+    currentOprTr: null,
+    currentAnnotation: null,
+    addCon: $('#fzAddCon'),//勾选编码模态框
+    updateCon: $('#fzUpdateCon'),//编辑编码模态框
+    clickUpdate: function (txtarea) {//解决编辑完后在未失去焦点的时候直接定额章节树
+        let me = annotationOprObj;
+        if(txtarea.is(':focus')){
+            let annotation = txtarea.val();
+            if(annotation !== me.currentAnnotation){
+                jobContentOprObj.preTreeNode.data.annotation = annotation;
+                me.unbindEvents(txtarea);
+                txtarea.blur();
+                let updateCodes = [];
+                for(let i = 0, len = jobContentOprObj.currentRationItems.length; i < len; i++){
+                    updateCodes.push(jobContentOprObj.currentRationItems[i].code);
+                    jobContentOprObj.currentRationItems[i].annotation = annotation;
+                }
+                me.updateAnnotation(pageOprObj.rationLibId, me.getUpdateArr(updateCodes, annotation), function () {
+                    me.bindAllEvents(txtarea);
+                });
+            }
+            else {
+                txtarea.blur();
+            }
+        }
+    },
+    getGroup: function (rationItems) {
+        let rst = [];//rst = [{jobContent: String, items: Array}]
+        for(let i = 0, len = rationItems.length; i < len; i++){
+            if(typeof rationItems[i].annotation !== 'undefined' && rationItems[i].annotation.toString().trim().length > 0){
+                let isExist = false;
+                for(let j = 0, jLen = rst.length; j < jLen; j++){
+                    if(rst[j].annotation === rationItems[i].annotation){
+                        isExist = true;
+                        rst[j].items.push(rationItems[i].code);
+                        break;
+                    }
+                }
+                if(!isExist){
+                    rst.push({annotation: rationItems[i].annotation, items: [rationItems[i].code]});
+                }
+            }
+        }
+        return rst;
+    },
+    hideTable: function (tableAll, tablePartial) {
+        if(tableAll){
+            tableAll.hide();
+        }
+        if(tablePartial){
+            tablePartial.hide();
+        }
+    },
+    //建table
+    buildTablePartial: function (table, group) {
+        let me = annotationOprObj;
+        table.empty();
+        let $thead = $("<thead><tr><th></th><th>编码</th><th>附注</th>/tr></thead>");
+        let $tbody = $("<tbody></tbody>");
+        let count = 1;
+        for(let i = 0, len = group.length; i < len; i++){
+            let $newTr = me.getNewTr($tbody, group[i].items, group[i].annotation);
+            $tbody.append($newTr);
+            count++;
+        }
+        let $trEnd = $("<tr><td>"+ count +"</td><td><a href data-toggle='modal' data-target='#fzEditBianma' class='m-0'>点击勾选编码</a></td><td><textarea class='form-control'></textarea></td></tr>");//勾选行
+        $($trEnd.children().children()[0]).bind('click', function () {
+            me.onclickFuncAdd($(this));
+            me.currentOprTr = $trEnd;
+            me.currentAnnotation = $(me.currentOprTr.children()[2]).children().val();
+        });
+        $tbody.append($trEnd);
+        table.append($thead);
+        table.append($tbody);
+    },
+    //新增一行tr
+    getNewTr: function (tbody, codes, jobContent) {
+        let me = annotationOprObj;
+        let count = tbody.children().length > 0 ? tbody.children().length : 1;
+        let $textTd = $("<td></td>");
+        let $textarea = $("<textarea class='form-control'></textarea>");
+        $textarea.val(jobContent);
+        $textTd.append($textarea);
+        let $tr = $("<tr><td>" + count + "</td><td><a href data-toggle='modal' data-target='#fzEditBianmaQ' class='m-0'>编辑编码</a></td></tr>");
+        $tr.children().children().bind('click', function () {
+            me.currentOprTr = $tr;
+            me.currentAnnotation = $(me.currentOprTr.children()[2]).children().val();
+            me.onclickFuncEdit($(this));
+        });
+        //文本变化;
+        $textarea.bind('change', function () {
+            let codes = me.getUpdateCodes($($(this).parent().parent().children()[1]).children());
+            let annotation = $(this).val();
+            me.updateAnnotation(pageOprObj.rationLibId, me.getUpdateArr(codes, annotation), function () {
+                if(annotation.trim().length === 0){
+                    me.buildTablePartial(me.fzTablePartial, me.getGroup(jobContentOprObj.currentRationItems));
+                }
+            });
+        });
+        $tr.append($textTd);
+        for(let i = 0, len = codes.length; i < len; i ++){
+            let $p = $("<p class='m-0'>" + codes[i] + "</p>");
+            $tr.children()[1].append($p[0]);
+        }
+        me.setTextareaHeight($textarea, codes.length + 1);
+        return $tr[0];
+    },
+    onclickFuncAdd: function (obj) {
+        let me = annotationOprObj;
+        let txtarea = $(obj.parent().parent().children().children()[1]);
+        let annotation = txtarea.val();
+        if(annotation.trim().length > 0){
+            let codesObj = me.getAddCodes(jobContentOprObj.currentRationItems);
+            me.buildCheckCodesCon(me.addCon, codesObj.checkedCodes, codesObj.disabledCodes)
+            obj.attr('data-target', '#fzEditBianma');
+        }
+        else{
+            obj.attr('data-target', '');
+            alert("附注不能为空!");
+        }
+    },
+    onclickFuncEdit: function (obj) {
+        let me = annotationOprObj;
+        me.buildEditableCodesCon(jobContentOprObj.currentRationItems, me.updateCon, me.getUpdateCodes(obj));
+    },
+    //获取编码td中的编码
+    getUpdateCodes: function (jq) {
+        let rst = [];
+        let nodes = jq.parent().children();
+        for(let i = 1, len = nodes.length; i < len; i++){
+            rst.push(nodes[i].textContent);
+        }
+        return rst;
+    },
+    //建一个编码checkbox Div
+    buildCodeOption: function (code, attr) {
+        let $div = $("<div class='col'><label class='form-check-label'><input class='form-check-input' type='checkbox' value= "+ code +"> "+ code +"</label></div>");
+        let $checkBox = $div.children().children();
+        if(attr){
+            $checkBox.attr(attr, true);
+        }
+        return $div;
+    },
+    //建修改编码弹窗
+    buildEditableCodesCon: function (rationItems, container, codes) {
+        let me = annotationOprObj;
+        let codeDivs = [];
+        container.empty();
+        for(let i = 0, len = codes.length; i < len; i++){
+            codeDivs.push({code: codes[i], attr: 'checked'});
+        }
+        for(let i = 0, len = rationItems.length; i < len; i++){
+            if(codes.indexOf(rationItems[i].code) === -1){
+                if(typeof rationItems[i].annotation !== 'undefined' && rationItems[i].annotation.toString().trim().length > 0){
+                    codeDivs.push({code: rationItems[i].code, attr: 'disabled'});
+                }
+                else{
+                    codeDivs.push({code: rationItems[i].code, attr: ''});
+                }
+            }
+        }
+        //排序
+        codeDivs.sort(function (a, b) {
+            let rst = 0;
+            if(a.code > b.code) rst = 1;
+            else if(a.code < b.code) rst = -1;
+            return rst;
+        });
+        for(let i = 0, len = codeDivs.length; i < len; i++){
+            container.append(me.buildCodeOption(codeDivs[i].code, codeDivs[i].attr));
+        }
+    },
+    //建勾选编码弹窗
+    buildCheckCodesCon: function (container, checkedCodes, disabledCodes) {
+        let me = annotationOprObj;
+        container.empty();
+        for(let i = 0, len = checkedCodes.length; i < len; i++){
+            let $codeDiv = me.buildCodeOption(checkedCodes[i], 'checked');
+            container.append($codeDiv);
+        }
+        for(let i = 0, len = disabledCodes.length; i < len; i++){
+            let $codeDiv = me.buildCodeOption(disabledCodes[i], 'disabled');
+            container.append($codeDiv);
+        }
+    },
+    getAddCodes: function (rationItems) {
+        let me = annotationOprObj;
+        let rst = {checkedCodes: [], disabledCodes: []};
+        for(let i = 0, len = rationItems.length; i < len; i++){
+            if(typeof rationItems[i].annotation !== 'undefined' && rationItems[i].annotation.toString().trim().length > 0){
+                rst.disabledCodes.push(rationItems[i].code);
+            }
+            else{
+                rst.checkedCodes.push(rationItems[i].code);
+            }
+        }
+        return rst;
+    },
+    //获取选择后的编码窗口的编码及状态
+    getCodesAfterS: function (checkNodes) {
+        let rst = {checked: [], unchecked: []};
+        for(let i = 0, len = checkNodes.length; i < len; i++){
+            if(checkNodes[i].checked){
+                rst.checked.push(checkNodes[i].value);
+            }
+            else if(!checkNodes[i].checked && !checkNodes[i].disabled){
+                rst.unchecked.push(checkNodes[i].value);
+            }
+        }
+        return rst;
+    },
+    setRadiosChecked: function (situation, radios) {
+        let me = annotationOprObj;
+        if(situation === me.situations.ALL){
+            radios[0].checked = true;
+            radios[1].checked = false;
+            $('#fzTxtareaAll').val(jobContentOprObj.currentRationItems.length > 0 ? jobContentOprObj.currentRationItems[0].annotation : '');
+            me.currentAnnotation = jobContentOprObj.currentRationItems.length > 0 ? jobContentOprObj.currentRationItems[0].annotation : '';
+            me.fzTableAll.show();
+            me.fzTablePartial.hide();
+        }
+        else if(situation === me.situations.PARTIAL){
+            radios[0].checked = false;
+            radios[1].checked = true;
+            me.fzTableAll.hide();
+            me.fzTablePartial.show();
+        }
+        else if(situation === me.situations.NONE){
+            radios[0].checked = false;
+            radios[1].checked = false;
+            me.fzTableAll.hide();
+            me.fzTablePartial.hide();
+        }
+    },
+    //radios是否可用,只有在定额章节树的底层节点才可用
+    setRadiosDisabled: function (val, radios) {
+        let me =annotationOprObj;
+        if(val){
+            radios[0].checked = false;
+            radios[1].checked = false;
+            me.currentSituation = me.situations.NONE;
+        }
+        radios.attr('disabled', val);
+    },
+    radiosChange: function (radios, tableAll, tablePartial) {
+        let me = annotationOprObj;
+        radios.change(function () {
+            let val = $("input[name = 'fzRadios']:checked").val();
+            let selectedNode = sectionTreeObj.tree.selected;
+            me.updateAnnoSituation(pageOprObj.rationLibId, selectedNode.getID(), val, function () {
+                selectedNode.data.annotationSituation = val;
+                me.currentSituation = val;
+                if(val === me.situations.ALL){
+                    let updateCodes = [];
+                    for(let i = 0, len = jobContentOprObj.currentRationItems.length; i < len; i++){
+                        updateCodes.push(jobContentOprObj.currentRationItems[i].code);
+                    }
+                    me.updateAnnotation(pageOprObj.rationLibId, me.getUpdateArr(updateCodes, ''), function () {
+                        me.currentAnnotation = '';
+                        $('#fzTxtareaAll').val('');
+                        tableAll.show();
+                        tablePartial.hide();
+                    });
+                }
+                else{
+                    me.buildTablePartial(me.fzTablePartial, me.getGroup(jobContentOprObj.currentRationItems));
+                    tableAll.hide();
+                    tablePartial.show();
+                }
+            });
+        });
+    },
+    setTextareaHeight: function (textarea, nodesCount) {
+        const perHeight = 21.6;
+        textarea.height(nodesCount * 21.6);
+    },
+    bindEvents: function (txtarea) {
+        let me = annotationOprObj;
+        txtarea.bind('change', function () {
+            let annotation = txtarea.val();
+            let jqNodes = txtarea.parent().parent().children()[1].children;
+            let updateCodes = me.getUpdateCodes(jqNodes);
+            txtarea.attr('disabled', true);
+            me.updateAnnotation(pageOprObj.rationLibId, me.getUpdateArr(updateCodes, annotation), function () {
+                txtarea.attr('disabled', false);
+            });
+        });
+    },
+    bindAllEvents: function (txtarea) {
+        let me = annotationOprObj;
+        txtarea.bind('change', function () {
+            let met = this;
+            let annotation = $(met).val();
+            $(met).attr('disabled', true);
+            let updateCodes = [];
+            for(let i = 0, len = jobContentOprObj.currentRationItems.length; i < len; i++){
+                updateCodes.push(jobContentOprObj.currentRationItems[i].code);
+                jobContentOprObj.currentRationItems[i].annotation = annotation;
+            }
+            me.currentAnnotation = annotation;
+            me.updateAnnotation(pageOprObj.rationLibId, me.getUpdateArr(updateCodes, annotation), function () {
+                $(met).attr('disabled', false);
+            });
+        });
+    },
+    unbindEvents: function (txtarea) {
+        txtarea.unbind();
+    },
+    //定额工作内容相关操作
+    rationAnnotationOpr: function (rationItems) {
+        let me = annotationOprObj;
+        me.setRadiosDisabled(rationItems.length > 0 ? false : true, me.radios);
+        me.setRadiosChecked(me.currentSituation, me.radios);
+        me.buildTablePartial(me.fzTablePartial, me.getGroup(rationItems));
+    },
+    getUpdateArr: function (updateCodes, annotation) {
+        let rst = [];
+        for(let i = 0, len = updateCodes.length; i < len; i++){
+            rst.push({code: updateCodes[i], annotation: annotation});
+        }
+        return rst;
+    },
+    bindAddConBtn: function () {
+        let me = annotationOprObj;
+        return function () {
+            let codesObj = me.getCodesAfterS(me.addCon.children().children().children());
+            let $tbody = $('#fzTablePartial tbody');
+            let lastEle = $tbody[0].lastElementChild;
+            let txtare = lastEle.lastElementChild.children[0];
+            if(me.currentAnnotation.trim().length > 0){//工作内容不为空才可添加编码
+                let updateArr = me.getUpdateArr(codesObj.checked, me.currentAnnotation);
+                me.updateAnnotation(pageOprObj.rationLibId, updateArr, function () {
+                    me.buildTablePartial(me.fzTablePartial, me.getGroup(jobContentOprObj.currentRationItems));
+                    $(txtare).val('');
+                });
+            }
+            else{
+                alert("附注不能为空!");
+            }
+        }
+    },
+    bindUpdateConBtn: function () {
+        let me = annotationOprObj;
+        return function () {
+            let codesObj = me.getCodesAfterS(me.updateCon.children().children().children());
+            let updateC = me.getUpdateArr(codesObj.checked, me.currentAnnotation),
+                updateUnC = me.getUpdateArr(codesObj.unchecked, ''),
+                updateArr = updateC.concat(updateUnC);
+            me.updateAnnotation(pageOprObj.rationLibId, updateArr, function () {
+                me.buildTablePartial(me.fzTablePartial, me.getGroup(jobContentOprObj.currentRationItems));
+            });
+        }
+    },
+    //更新缓存的定额
+    updateRationItem: function (rationItems, updateArr) {
+        for(let i = 0, len = rationItems.length; i < len; i++){
+            for(let j = 0, jLen = updateArr.length; j < jLen; j++){
+                if(rationItems[i].code === updateArr[j].code){
+                    rationItems[i].annotation = updateArr[j].annotation;
+                    break;
+                }
+            }
+        }
+    },
+    updateAnnotation: function (repId, updateArr, callback){
+        let me = annotationOprObj;
+        $.ajax({
+            type: 'post',
+            url: 'api/updateAnnotation',
+            data: {lastOpr: userAccount, repId: repId, updateArr: JSON.stringify(updateArr)},
+            dataType: 'json',
+            success: function (result) {
+                if(!result.error){
+                    me.updateRationItem(jobContentOprObj.currentRationItems, updateArr);
+                    callback();
+                }
+            }
+        });
+    },
+    updateAnnoSituation: function (repId, nodeId, situation, callback) {
+        let me = annotationOprObj;
+        $.ajax({
+            type: 'post',
+            url: 'api/updateAnnoSituation',
+            data: {lastOpr: userAccount, repId: repId, nodeId: nodeId, situation: situation},
+            dataType: 'json',
+            success: function (result) {
+                if(!result.error){
+                    if(callback){
+                        callback();
+                    }
+                }
+            }
+        })
+    }
+
+};

+ 645 - 0
web/building_saas/complementary_ration_lib/js/coe.js

@@ -0,0 +1,645 @@
+/**
+ * Created by CSL on 2017-05-18.
+ */
+//modiyied by zhong on 2017/9/21
+
+
+var pageObj = {
+    libID: null,
+    gljLibID: null,
+    initPage: function (){
+        $("#drirect-dinge").click(function(){
+            $(this).attr('href', "/rationRepository/ration" + "?repository=" + getQueryString("repository"))
+        });
+
+        $("#gongliao").click(function(){
+            $(this).attr('href', "/rationRepository/lmm" + "?repository=" + getQueryString("repository"))
+        });
+
+        var libID = getQueryString("repository");
+        var libName = storageUtil.getSessionCache("RationGrp","repositoryID_" + libID);
+        if (libName) {
+            var html = $("#rationname")[0].outerHTML;
+            html = html.replace("XXX定额库", libName);
+            $("#rationname")[0].outerHTML = html;
+        };
+        this.gljLibID = storageUtil.getSessionCache("gljLib", "repositoryID_" + libID);
+        this.libID = libID;
+        coeOprObj.buildSheet($('#mainSpread')[0]);
+        gljAdjOprObj.buildSheet($('#contentSpread')[0]);
+        coeOprObj.getCoeList();
+        gljAdjOprObj.getGljItemsOcc();
+
+    },
+    showData: function(sheet, setting, data) {
+        let me = pageObj, ch = GC.Spread.Sheets.SheetArea.viewport;
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        sheet.clear(0, 0, sheet.getRowCount(), sheet.getColumnCount(), GC.Spread.Sheets.SheetArea.viewport, GC.Spread.Sheets.StorageType.data);
+        sheet.setRowCount(data.length + 3);
+        for (let col = 0; col < setting.header.length; col++) {
+            var hAlign = "left", vAlign = "center";
+            if (setting.header[col].hAlign) {
+                hAlign = setting.header[col].hAlign;
+            } else if (setting.header[col].dataType !== "String"){
+                hAlign = "right";
+            }
+            if(setting.header[col].readOnly){
+                sheet.getRange(-1, col, -1, 1).locked(true);
+            }
+            else{
+                sheet.getRange(-1, col, -1, 1).locked(false);
+            }
+            vAlign = setting.header[col].vAlign?setting.header[col].vAlign:vAlign;
+            sheetCommonObj.setAreaAlign(sheet.getRange(-1, col, -1, 1), hAlign, vAlign);
+            if (setting.header[col].formatter) {
+                sheet.setFormatter(-1, col, setting.header[col].formatter, GC.Spread.Sheets.SheetArea.viewport);
+            }
+            for (let row = 0; row < data.length; row++) {
+                let val = data[row][setting.header[col].dataCode];
+                sheet.setValue(row, col, val, ch);
+            }
+        }
+        sheet.resumeEvent();
+        sheet.resumePaint();
+    }
+};
+
+let coeOprObj = {
+    workBook: null,
+    workSheet: null,
+    currentCoeList: [],
+    currentCoe: null,
+    currentMaxNo: null,
+    setting: {
+        header: [
+            {headerName:"编号", headerWidth:60, dataCode:"serialNo", dataType: "String", hAlign: "center", vAlign: "center", readOnly: false},
+            {headerName:"名称", headerWidth:280, dataCode:"name", dataType: "String", hAlign: "left", vAlign: "center", readOnly: false},
+            {headerName:"内容", headerWidth:250, dataCode:"content", dataType: "String", hAlign: "left", vAlign: "center", readOnly: false},
+        ]
+    },
+    buildSheet: function (container) {
+        let me = coeOprObj;
+        me.workBook = sheetCommonObj.buildSheet(container, me.setting, 30);
+        me.workSheet = me.workBook.getSheet(0);
+        me.workSheet.options.isProtected = true;
+        me.onDelOpr(me.workBook, me.setting);
+        me.workSheet.bind(GC.Spread.Sheets.Events.SelectionChanged, me.onSelectionChanged);
+        me.workSheet.bind(GC.Spread.Sheets.Events.EditEnded, me.onEditEnded);
+        me.workBook.bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting);
+        me.workBook.bind(GC.Spread.Sheets.Events.ClipboardPasted, me.onClipboardPasted);
+    },
+    onSelectionChanged: function (sender, info) {
+        let me = coeOprObj, that = gljAdjOprObj;
+        if(info.oldSelections.length === 0 && info.newSelections.length > 0 || info.oldSelections[0].row !== info.newSelections[0].row){
+            let row = info.newSelections[0].row;
+            if(row < me.currentCoeList.length){
+                me.currentCoe = me.currentCoeList[row];
+                that.currentGljAdjList = me.currentCoe.coes;
+                that.buildDynamicComboBox(that.workSheet);
+            }
+            else{
+                me.currentCoe = null;
+                that.currentGljAdjList = [];
+                that.buildBaseCell(that.workSheet);
+            }
+            //refresh & show coes
+            sheetCommonObj.cleanSheet(that.workSheet, that.setting, -1);
+            me.workBook.focus(true);
+            that.show(that.currentGljAdjList);
+        }
+    },
+    onEditEnded: function (sender, args) {
+        let me = coeOprObj, addArr = [], updateArr = [], dataCode = me.setting.header[args.col].dataCode;
+        if(args.editingText && args.editingText.toString().trim().length > 0){
+            let inputT = args.editingText.toString().trim();
+            //update
+            if(args.row < me.currentCoeList.length){
+                let updateObj = me.currentCoeList[args.row];
+                if(updateObj[dataCode] != inputT){
+                    if(dataCode === 'serialNo'){
+                        if(me.isInt(inputT) && !me.hasTisNo(me.currentCoeList, inputT)){
+                            me.currentMaxNo = me.currentMaxNo >= inputT ? me.currentMaxNo : inputT;
+                            updateObj[dataCode] = inputT;
+                            updateArr.push(updateObj);
+                            me.save([], updateArr, [], true);
+                        }
+                        else if(!me.isInt(inputT)){
+                            alert('编号只能为整数!');
+                            args.sheet.setValue(args.row, args.col, updateObj[dataCode] + '');
+                        }
+                        else if(me.hasTisNo(me.currentCoeList, inputT)){
+                            alert('该编号已存在!');
+                            args.sheet.setValue(args.row, args.col, updateObj[dataCode] + '');
+                        }
+                    }
+                    else {
+                        updateObj[dataCode] = inputT;
+                        updateArr.push(updateObj);
+                        me.save([], updateArr, [], true);
+                    }
+                }
+            }
+            //insert
+            else{
+                let newCoe = {};
+                newCoe.libID = pageObj.libID;
+                if(dataCode === 'serialNo'){
+                    if(me.isInt(inputT) && !me.hasTisNo(me.currentCoeList, inputT)){
+                        me.currentMaxNo = me.currentMaxNo >= inputT ? me.currentMaxNo : inputT;
+                        newCoe[dataCode] = inputT;
+                        addArr.push(newCoe);
+                        me.save(addArr, [], [], true, function (result) {
+                            me.updateCurrentCoeList(result);
+                        });
+                    }
+                    else if(!me.isInt(inputT)){
+                        args.sheet.setValue(args.row, args.col, '');
+                        alert('编号只能为整数!');
+                    }
+                    else if(me.hasTisNo(me.currentCoeList, inputT)){
+                        args.sheet.setValue(args.row, args.col, '');
+                        alert('该编号已存在!');
+                    }
+                }
+                else{
+                    newCoe.serialNo = ++me.currentMaxNo;
+                    newCoe[dataCode] = inputT;
+                    addArr.push(newCoe);
+                    me.save(addArr, [], [], true, function (result) {
+                        me.updateCurrentCoeList(result);
+                    });
+                }
+            }
+        }
+    },
+    onClipboardPasting: function (sender, info) {
+        let me = coeOprObj, maxCol = info.cellRange.col + info.cellRange.colCount - 1;
+        if(maxCol > me.setting.header.length){
+            info.cancel = true;
+        }
+    },
+    onClipboardPasted: function (sender, info) {
+        let me = coeOprObj, addArr = [], updateArr = [];
+        let items = sheetCommonObj.analyzePasteData(me.setting, info);
+        let uniqItems = me.makeUniqItems(items);
+        for(let i = 0, len = uniqItems.length; i < len; i++){
+            let row = i + info.cellRange.row;
+            //update
+            if(row < me.currentCoeList.length){
+                let updateObj = me.currentCoeList[row];
+                for(let attr in uniqItems[i]){
+                    if(attr === 'serialNo'){
+                        if(me.isInt(uniqItems[i][attr]) && !me.hasTisNo(me.currentCoeList, uniqItems[i][attr])){
+                            me.currentMaxNo = me.currentMaxNo >= uniqItems[i][attr] ? me.currentMaxNo : uniqItems[i][attr];
+                            updateObj[attr] = uniqItems[i][attr];
+                        }
+                    }
+                    else {
+                        updateObj[attr] = uniqItems[i][attr];
+                    }
+                }
+                updateArr.push(updateObj);
+            }
+            //insert
+            else {
+                if(typeof uniqItems[i].serialNo !== 'undefined' && uniqItems[i] && me.isInt(uniqItems[i].serialNo) && !me.hasTisNo(me.currentCoeList, uniqItems[i].serialNo)){
+                    me.currentMaxNo = me.currentMaxNo >= uniqItems[i].serialNo ? me.currentMaxNo : uniqItems[i].serialNo;
+                }
+                else {
+                    uniqItems[i].serialNo = ++me.currentMaxNo;
+                }
+                uniqItems[i].libID = pageObj.libID;
+                addArr.push(uniqItems[i]);
+            }
+        }
+        if(addArr.length > 0 || updateArr.length > 0){
+            me.save(addArr, updateArr, [], true, function (result) {
+                me.updateCurrentCoeList(result);
+            });
+        }
+    },
+    onDelOpr: function (workBook, setting) {
+        let me = coeOprObj, that = gljAdjOprObj;
+        workBook.commandManager().register('coeListDel', function () {
+            let deleteArr = [];
+            let sheet = workBook.getSheet(0);
+            let sels = sheet.getSelections();
+            let idx = sels[0].row;
+            for(let i = 0, len = sels.length; i < len; i++){
+                if(idx > sels[i].row){
+                    idx = sels[i].row;
+                }
+                if(sels[i].colCount === setting.header.length){//can del
+                    for(let r = 0, rLen = sels[i].rowCount; r < rLen; r++){
+                        let row = sels[i].row + r;
+                        if(row < me.currentCoeList.length){
+                            deleteArr.push({libID: me.currentCoeList[row].libID, ID: me.currentCoeList[row].ID});
+                        }
+                    }
+                    me.currentCoeList.splice(sels[i].row, sels[i].rowCount);
+                }
+            }
+            if(deleteArr.length > 0){
+                me.save([], [], deleteArr, true);
+                me.currentCoe = typeof me.currentCoeList[idx] !== 'undefined' ? me.currentCoeList[idx] : null;
+                that.currentGljAdjList = me.currentCoe ? me.currentCoe.coes : [];
+                gljAdjOprObj.show(that.currentGljAdjList);
+            }
+
+        });
+        workBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false);
+        workBook.commandManager().setShortcutKey('coeListDel', GC.Spread.Commands.Key.del, false, false, false, false);
+    },
+    //粘贴的数据,编号唯一化,去除编号重复的项
+    makeUniqItems: function (items) {
+        let rst = [];
+        for(let i = 0, len = items.length; i < len; i++){
+            if(typeof items[i].serialNo !== 'undefined' && items[i].serialNo){
+                if(rst.length === 0){
+                    rst.push(items[i]);
+                }
+                else{
+                    let isExist = false;
+                    for(let j = 0, jLen = rst.length; j < jLen; j++){
+                        if(items[i].serialNo === rst[j].serialNo){
+                            isExist = true;
+                            break;
+                        }
+                    }
+                    if(!isExist){
+                        rst.push(items[i]);
+                    }
+                }
+            }
+            else {
+                rst.push(items[i]);
+            }
+        }
+        return rst;
+    },
+    isInt: function (num) {
+        return !isNaN(num) && num % 1 === 0;
+    },
+    hasTisNo: function (coeList, newSerialNo) {
+        let rst = false;
+        for(let i = 0, len = coeList.length; i < len; i++){
+            if(coeList[i].serialNo == newSerialNo){
+                rst = true;
+                break;
+            }
+        }
+        return rst;
+    },
+    updateCurrentCoeList: function (newCoeList) {
+        let me = coeOprObj;
+        if(newCoeList){
+            me.currentCoeList = me.currentCoeList.concat(newCoeList);
+        }
+    },
+    sortCoeList: function (coeList) {
+        coeList.sort(function (a, b) {
+            let rst = 0;
+            if(a.serialNo > b.serialNo) rst = 1;
+            else if(a.serialNo < b.serialNo) rst = -1;
+            return rst;
+        });
+    },
+    getCoeList: function () {
+        let me = coeOprObj;
+        $.ajax({
+            type: 'post',
+            url: '/rationRepository/api/getCoeList',
+            data: {libID: pageObj.libID},
+            dataType: 'json',
+            timeout:20000,
+            success: function (result) {
+                if(!result.error){
+                    me.currentCoeList = result.data;
+                    me.sortCoeList(me.currentCoeList);
+                    me.currentMaxNo =  me.currentCoeList.length > 0 ? me.currentCoeList[me.currentCoeList.length - 1].serialNo : 0;
+                    pageObj.showData(me.workSheet, me.setting, me.currentCoeList);
+                    me.workSheet.clearSelection();
+                }
+            },
+            error:function(err){
+                alert("内部程序错误!");
+            }
+        });
+    },
+    save: function (addArr, updateArr, deleteArr, refresh, callback) {
+        let me = coeOprObj;
+        $.ajax({
+            type:"POST",
+            url:"api/saveCoeList",
+            data: {data: JSON.stringify({addArr: addArr, updateArr: updateArr, deleteArr: deleteArr})},
+            dataType:"json",
+            timeout:5000,
+            success:function(result){
+                if (result.error) {
+                    alert(result.message);
+                } else{
+                    if(callback){
+                        if(result.message === 'mixed'){
+                            for(let i = 0, len = result.data.length; i < len; i++){
+                                if(result.data[i][0] === 'addSc'){
+                                    result.data = result.data[i][1];
+                                    break;
+                                }
+                            }
+                        }
+                        callback(result.data);
+                    }
+                    if(refresh){
+                        me.sortCoeList(me.currentCoeList);
+                        me.currentMaxNo = me.currentCoeList.length > 0 ? me.currentCoeList[me.currentCoeList.length - 1].serialNo : 0;
+                        pageObj.showData(me.workSheet, me.setting, me.currentCoeList);
+                    }
+                }
+            },
+            error:function(err){
+                alert("内部程序错误!");
+            }
+        });
+    }
+};
+
+let gljAdjOprObj = {
+    workBook: null,
+    workSheet: null,
+    currentGljAdjList: [],
+    gljList: [],//只含编号和名称的总工料机列表
+    setting: {
+        header: [
+            {headerName:"调整类型", headerWidth:100, dataCode:"coeType", dataType: "String", hAlign: "center", vAlign: "center", readOnly: false},
+            {headerName:"工料机编码", headerWidth:100, dataCode:"gljCode", dataType: "String", formatter: '@', hAlign: "center", vAlign: "center", readOnly: false},
+            {headerName:"名称", headerWidth:100, dataCode:"gljName", dataType: "String", hAlign: "center", vAlign: "center", readOnly: true},
+            {headerName:"操作符", headerWidth:60, dataCode:"operator", dataType: "String", hAlign: "center", vAlign: "center", readOnly: false},
+            {headerName:"数量", headerWidth:80, dataCode:"amount", dataType: "String", hAlign: "center", vAlign: "center" , readOnly: false},
+        ],
+        comboItems: {
+            //调整类型下拉菜单
+            coeType: ['定额子目', '人工类', '材料类', '机械类', '主材类', '设备类', '单个工料机'],
+            //操作符下拉菜单
+            operator: ['+', '-', '*', '/', '=']
+        }
+    },
+    buildSheet: function (container) {
+        let me = gljAdjOprObj;
+        me.workBook = sheetCommonObj.buildSheet(container, me.setting, 3);
+        me.workSheet = me.workBook.getSheet(0);
+        me.workSheet.options.isProtected = true;
+        me.onDelOpr(me.workBook, me.setting);
+        me.workSheet.clearSelection();
+        me.workSheet.bind(GC.Spread.Sheets.Events.EditStarting, me.onEditStart);
+        me.workSheet.bind(GC.Spread.Sheets.Events.EditEnded, me.onEditEnded);
+        me.workSheet.bind(GC.Spread.Sheets.Events.EnterCell, me.onEnterCell);
+        me.workSheet.bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting);
+        me.workSheet.bind(GC.Spread.Sheets.Events.ClipboardPasted, me.onClipboardPasted);
+    },
+    buildBaseCell: function (sheet) {
+        let me = gljAdjOprObj;
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        let baseCell = GC.Spread.Sheets.CellTypes.Base();
+        sheet.getCell(-1, 0).cellType(baseCell);
+        sheet.getCell(-1, 3).cellType(baseCell);
+        sheet.resumePaint();
+        sheet.resumeEvent();
+    },
+    buildDynamicComboBox: function (sheet) {
+        let me = gljAdjOprObj;
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        let dynamicCombo = sheetCommonObj.getDynamicCombo();
+        dynamicCombo.items(me.setting.comboItems.coeType);
+        let dynamicOprCombo = sheetCommonObj.getDynamicCombo();
+        dynamicOprCombo.items(me.setting.comboItems.operator);
+        sheet.getCell(-1, 0).cellType(dynamicCombo);
+        sheet.getCell(-1, 3).cellType(dynamicOprCombo);
+        sheet.resumePaint();
+        sheet.resumeEvent();
+    },
+    onEnterCell: function (sender, args) {
+        args.sheet.repaint();
+    },
+    onEditStart: function (sender, args) {
+        let me = gljAdjOprObj;
+        if(!coeOprObj.currentCoe || args.row >= me.currentGljAdjList.length && args.col === 1
+            || args.row < me.currentGljAdjList.length && args.col === 1 && me.currentGljAdjList[args.row].coeType !== '单个工料机'){
+            args.cancel = true;
+        }
+    },
+    onEditEnded: function (sender, args) {
+        let me = gljAdjOprObj, isUpdate = false,
+            dataCode = me.setting.header[args.col].dataCode;
+        if(args.editingText && args.editingText.toString().trim().length > 0){
+            if(dataCode === 'amount' &&  isNaN(args.editingText)){
+                alert("只能输入数值!");
+                args.sheet.setValue(args.row, args.col, typeof me.currentGljAdjList[args.row] !== 'undefined' && typeof me.currentGljAdjList[args.row][dataCode] !== 'undefined'
+                    ? me.currentGljAdjList[args.row][dataCode] + '' : '');
+            }
+            else {
+                //update
+                if(args.row < me.currentGljAdjList.length && args.editingText.toString().trim() !== me.currentGljAdjList[args.row][dataCode]){
+                    let updateObj = me.currentGljAdjList[args.row];
+                    if(dataCode === 'gljCode' && typeof updateObj.coeType !== 'undefined' && updateObj.coeType === '单个工料机'){
+                        let gljName = me.getGljName(args.editingText, me.gljList);
+                        if(gljName){
+                            updateObj.gljCode = args.editingText;
+                            updateObj.gljName = gljName;
+                            isUpdate = true;
+                        }
+                        else {
+                            alert("不存在编号为"+ args.editingText +"的工料机");
+                        }
+                    }
+                    else if(dataCode !== 'gljCode') {
+                        isUpdate = true;
+                        updateObj[dataCode] = args.editingText;
+                    }
+                }
+                //insert
+                else if(args.row >= me.currentGljAdjList.length){
+                    isUpdate = true;
+                    let newAdjGlj = {};
+                    newAdjGlj[dataCode] = args.editingText;
+                    me.currentGljAdjList.push(newAdjGlj);
+                }
+                if(isUpdate){
+                    coeOprObj.save([], [coeOprObj.currentCoe], [], false, function () {
+                        me.show(me.currentGljAdjList);
+                    });
+                }
+                else {
+                    args.sheet.setValue(args.row, args.col, typeof me.currentGljAdjList[args.row] !== 'undefined' && typeof me.currentGljAdjList[args.row][dataCode] !== 'undefined'
+                        ? me.currentGljAdjList[args.row][dataCode] + '' : '');
+                }
+            }
+        }
+    },
+    onClipboardPasting: function (sender, info) {
+
+    },
+    getValidPasteDatas: function (pasteItems, info) {
+        let me = gljAdjOprObj;
+        let rst = [];
+        for(let i = 0, len = pasteItems.length; i < len; i++){
+            let row = i + info.cellRange.row;
+            let validObj = {};
+            //update
+            if(row < me.currentGljAdjList.length){
+                let updateObj = me.currentGljAdjList[row];
+                if(typeof pasteItems[i].coeType !== 'undefined' && typeof pasteItems[i].gljCode !== 'undefined'){
+                    let gljName = me.getGljName(pasteItems[i].gljCode, me.gljList);
+                    if(pasteItems[i].coeType === '单个工料机' && gljName){
+                        validObj.coeType = pasteItems[i].coeType;
+                        validObj.gljCode = pasteItems[i].gljCode;
+                        validObj.gljName = gljName;
+                    }
+                    else if(pasteItems[i].coeType !== '单个工料机' && me.setting.comboItems.coeType.indexOf(pasteItems[i].coeType) !== -1){
+                        validObj.coeType = pasteItems[i].coeType;
+                    }
+                }
+                else if(typeof pasteItems[i].coeType === 'undefined' && typeof pasteItems[i].gljCode !== 'undefined'){
+                    let gljName = me.getGljName(pasteItems[i].gljCode, me.gljList);
+                    if(typeof updateObj.coeType !== 'undefined' && updateObj.coeType === '单个工料机' && gljName){
+                        validObj.gljCode = pasteItems[i].gljCode;
+                        validObj.gljName = gljName;
+                    }
+                }
+                else if(typeof pasteItems[i].coeType !== 'undefined' && typeof pasteItems[i].gljCode === 'undefined'){
+                    if(me.setting.comboItems.coeType.indexOf(pasteItems[i].coeType) !== -1){
+                        validObj.coeType = pasteItems[i].coeType;
+                        if(validObj.coeType !== '单个工料机' && typeof updateObj.gljCode !== '单个工料机' && updateObj.gljCode.toString().trim().length > 0){
+                            validObj.gljCode = '';
+                            validObj.gljName = '';
+                        }
+                    }
+                }
+                else {
+                    if(typeof pasteItems[i].operator !== 'undefined' && me.setting.comboItems.operator.indexOf(pasteItems[i].operator) !== -1){
+                        validObj.operator = pasteItems[i].operator;
+                    }
+                    if(typeof pasteItems[i].amount !== 'undefined' && !isNaN(pasteItems[i].amount)){
+                        validObj.amount = pasteItems[i].amount;
+                    }
+                }
+            }
+            else {
+                if(typeof pasteItems[i].coeType !== 'undefined' && typeof pasteItems[i].gljCode !== 'undefined'){
+                    let gljName = me.getGljName(pasteItems[i].gljCode, me.gljList);
+                    if(pasteItems[i].coeType === '单个工料机' && gljName){
+                        validObj.coeType = pasteItems[i].coeType;
+                        validObj.gljCode = pasteItems[i].gljCode;
+                        validObj.gljName = gljName;
+                    }
+                    else if(pasteItems[i].coeType !== '单个工料机' && me.setting.comboItems.coeType.indexOf(pasteItems[i].coeType) !== -1){
+                        validObj.coeType = pasteItems[i].coeType;
+                    }
+                }
+                else if(typeof pasteItems[i].gljCode === 'undefined') {
+                    if(typeof pasteItems[i].coeType !== 'undefined' && me.setting.comboItems.coeType.indexOf(pasteItems[i].coeType) !== -1){
+                        validObj.coeType = pasteItems[i].coeType;
+                    }
+                    if(typeof pasteItems[i].operator !== 'undefined' && me.setting.comboItems.operator.indexOf(pasteItems[i].operator) !== -1){
+                        validObj.operator = pasteItems[i].operator;
+                    }
+                    if(typeof pasteItems[i].amount !== 'undefined' && !isNaN(pasteItems[i].amount)){
+                        validObj.amount = pasteItems[i].amount;
+                    }
+                }
+            }
+            if(Object.keys(validObj).length > 0){
+                rst.push(validObj);
+            }
+        }
+        return rst;
+    },
+    onClipboardPasted: function (sender, info) {
+        let me = gljAdjOprObj, row;
+        let items = sheetCommonObj.analyzePasteData(me.setting, info);
+        let validDatas = me.getValidPasteDatas(items, info);
+        for(let i = 0, len = validDatas.length; i < len; i++){
+            row = i + info.cellRange.row;
+            //update
+            if(row < me.currentGljAdjList.length){
+                let updateObj = me.currentGljAdjList[row];
+                for(let attr in validDatas[i]){
+                    updateObj[attr] = validDatas[i][attr];
+                }
+            }
+            //insert
+            else{
+                me.currentGljAdjList.push(validDatas[i]);
+            }
+        }
+        if(validDatas.length > 0){
+            coeOprObj.save([], [coeOprObj.currentCoe], [], false, function () {
+                me.show(me.currentGljAdjList);
+            });
+        }
+        else {
+            me.show(me.currentGljAdjList);
+        }
+    },
+    onDelOpr: function (workBook, setting) {
+        let me = gljAdjOprObj;
+        workBook.commandManager().register('gljAdjDel', function () {
+            let sheet = workBook.getSheet(0);
+            let sels = sheet.getSelections();
+            let isUpdate = false;
+            for(let i = 0, len = sels.length; i < len; i++){
+                if(sels[i].colCount === setting.header.length){//can del
+                    if(sels[i].row < me.currentGljAdjList.length){
+                        isUpdate = true;
+                        me.currentGljAdjList.splice(sels[i].row, sels[i].rowCount);
+                    }
+                }
+            }
+            if(isUpdate){
+                coeOprObj.save([], [coeOprObj.currentCoe], [], false, function () {
+                    me.show(me.currentGljAdjList);
+                });
+            }
+        });
+        workBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false);
+        workBook.commandManager().setShortcutKey('gljAdjDel', GC.Spread.Commands.Key.del, false, false, false, false);
+    },
+    getGljName: function (gljCode, gljList) {
+        let rst = null;
+        for(let i = 0, len = gljList.length; i < len; i++){
+            if(gljCode === gljList[i].code){
+                rst = gljList[i].name;
+                break;
+            }
+        }
+        return rst;
+    },
+    show: function (coes) {
+        let me = gljAdjOprObj;
+        pageObj.showData(me.workSheet, me.setting, coes)
+    },
+    getGljItemsOcc: function () {
+        let me = gljAdjOprObj;
+        $.ajax({
+            type: 'post',
+            url: '/stdGljRepository/api/getGljItemsOccupied',
+            data: {repId: pageObj.gljLibID, occupation: '-_id code name'},
+            dataType: 'json',
+            timeout: 5000,
+            success:function(result){
+                if (result.error) {
+                    alert(result.message);
+                } else{
+                    me.gljList = result.data;
+                }
+            },
+            error:function(err){
+                alert("内部程序错误!");
+            }
+        });
+    }
+};
+
+

+ 95 - 0
web/building_saas/complementary_ration_lib/js/explanatory.js

@@ -0,0 +1,95 @@
+/**
+ * Created by Zhong on 2017/12/20.
+ */
+//定额章节节点说明、计算规则
+let explanatoryOprObj = {
+    preTreeNode: null,
+    currentTreeNode: null,//定额章节树节点
+    currentExplanation: null,
+    currentRuleText: null,
+    setAttribute: function (preNode, currentNode, explanation, ruleText) {
+        let me = explanatoryOprObj;
+        me.preTreeNode = preNode;
+        me.currentTreeNode = currentNode;
+        me.currentExplanation = explanation;
+        me.currentRuleText = ruleText;
+    },
+    clickUpdate: function (exarea, ruarea) {//解决编辑完后在未失去焦点的时候直接定额章节树
+        let me = explanatoryOprObj;
+        if(exarea.is(':focus')){
+            let explanation = exarea.val();
+            if(explanation !== me.currentExplanation){
+                me.preTreeNode.data.explanation = explanation;
+                me.unbindEvents(exarea, ruarea);
+                exarea.blur();
+                me.updateExplanation(pageOprObj.rationLibId, me.preTreeNode.getID(), explanation, function () {
+                    me.bindEvents(exarea, ruarea);
+                });
+            }
+        }
+        if(ruarea.is(':focus')){
+            let ruleText = ruarea.val();
+            if(ruleText !== me.currentRuleText){
+                me.preTreeNode.data.ruleText = ruleText;
+                me.unbindEvents(exarea, ruarea);
+                ruarea.blur();
+                me.updateRuleText(pageOprObj.rationLibId, me.preTreeNode.getID(), ruleText, function () {
+                    me.bindEvents(exarea, ruarea);
+                });
+            }
+        }
+    },
+    unbindEvents: function (exarea, ruarea) {
+        exarea.unbind();
+        ruarea.unbind();
+    },
+    bindEvents: function (exarea, ruarea) {
+        let me = explanatoryOprObj;
+        exarea.bind('change', function () {
+            let explanation = exarea.val();
+            let node = me.currentTreeNode;
+            exarea.attr('disabled', true);
+            me.updateExplanation(pageOprObj.rationLibId, node.getID(), explanation, function () {
+                node.data.explanation = explanation;
+                exarea.attr('disabled', false);
+            });
+        });
+        ruarea.bind('change', function () {
+            let ruleText = ruarea.val();
+            let node = me.currentTreeNode;
+            ruarea.attr('disabled', true);
+            me.updateRuleText(pageOprObj.rationLibId, node.getID(), ruleText, function () {
+                node.data.ruleText = ruleText;
+                ruarea.attr('disabled', false);
+            });
+        });
+    },
+    showText: function (exarea, ruarea, explanation, ruleText) {
+        exarea.val(explanation && explanation !== 'undefined' ? explanation : '');
+        ruarea.val(ruleText && ruleText !== 'undefined' ? ruleText : '');
+    },
+    //更新说明
+    updateExplanation: function (repId, nodeId, explanation, callback) {
+        $.ajax({
+            type: 'post',
+            url: 'api/updateExplanation',
+            data: {lastOpr: userAccount, repId: pageOprObj.rationLibId, nodeId: nodeId, explanation: explanation},
+            dataType: 'json',
+            success: function () {
+                callback();
+            }
+        });
+    },
+    //更新计算规则
+    updateRuleText: function (repId, nodeId, explanation, callback) {
+        $.ajax({
+            type: 'post',
+            url: 'api/updateRuleText',
+            data: {lastOpr: userAccount, repId: pageOprObj.rationLibId, nodeId: nodeId, ruleText: explanation},
+            dataType: 'json',
+            success: function () {
+                callback();
+            }
+        });
+    }
+};

+ 43 - 0
web/building_saas/complementary_ration_lib/js/global.js

@@ -0,0 +1,43 @@
+/*全局自适应高度*/
+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);
+    $(".main-side .tab-content").height($(window).height()-headerHeight-38);
+};
+$(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');
+  });
+/*工具提示*/
+});

+ 414 - 0
web/building_saas/complementary_ration_lib/js/jobContent.js

@@ -0,0 +1,414 @@
+/**
+ * Created by Zhong on 2017/12/20.
+ */
+//工作内容
+let jobContentOprObj = {
+    situations: {ALL: 'ALL', PARTIAL: 'PARTIAL', NONE: 'NONE'},//所有ALL(包括未定义本项工作内容)、部分PARTIA,不可用NONE(无定额时)
+    currentSituation: null,//本项适用情况
+    currentTreeNode: null,
+    preTreeNode: null,
+    radios: $("input[name = 'optionsRadios']"),
+    tableAll: $('#tableAll'),
+    tablePartial: $('#tablePartial'),
+    currentOprTr: null,
+    currentJobContent: null,
+    currentRationItems: null,
+    addCon: $('#addCon'),//勾选编码模态框
+    updateCon: $('#updateCon'),//编辑编码模态框
+    setAttribute: function (preNode, currentNode) {
+        let me = jobContentOprObj;
+        me.preTreeNode = preNode;
+        me.currentTreeNode = currentNode;
+    },
+    clickUpdate: function (txtarea) {//解决编辑完后在未失去焦点的时候直接定额章节树
+        let me = jobContentOprObj;
+        if(txtarea.is(':focus')){
+            let jobContent = txtarea.val();
+            if(jobContent !== me.currentJobContent){
+                me.preTreeNode.data.jobContent = jobContent;
+                me.unbindEvents(txtarea);
+                txtarea.blur();
+                let updateCodes = [];
+                for(let i = 0, len = me.currentRationItems.length; i < len; i++){
+                    updateCodes.push(me.currentRationItems[i].code);
+                    me.currentRationItems[i].jobContent = jobContent;
+                }
+                me.updateJobContent(pageOprObj.rationLibId, me.getUpdateArr(updateCodes, jobContent), function () {
+                    me.bindAllEvents(txtarea);
+                })
+            }
+            else {
+                txtarea.blur();
+            }
+        }
+    },
+    getGroup: function (rationItems) {
+        let rst = [];//rst = [{jobContent: String, items: Array}]
+        for(let i = 0, len = rationItems.length; i < len; i++){
+            if(typeof rationItems[i].jobContent !== 'undefined' && rationItems[i].jobContent.toString().trim().length > 0){
+                let isExist = false;
+                for(let j = 0, jLen = rst.length; j < jLen; j++){
+                    if(rst[j].jobContent === rationItems[i].jobContent){
+                        isExist = true;
+                        rst[j].items.push(rationItems[i].code);
+                        break;
+                    }
+                }
+                if(!isExist){
+                    rst.push({jobContent: rationItems[i].jobContent, items: [rationItems[i].code]});
+                }
+            }
+        }
+        return rst;
+    },
+    hideTable: function (tableAll, tablePartial) {
+        if(tableAll){
+            tableAll.hide();
+        }
+        if(tablePartial){
+            tablePartial.hide();
+        }
+    },
+    //建table
+    buildTablePartial: function (table, group) {
+        let me = jobContentOprObj;
+        table.empty();
+        let $thead = $("<thead><tr><th></th><th>编码</th><th>工作内容</th>/tr></thead>");
+        let $tbody = $("<tbody></tbody>");
+        let count = 1;
+        for(let i = 0, len = group.length; i < len; i++){
+            let $newTr = me.getNewTr($tbody, group[i].items, group[i].jobContent);
+            $tbody.append($newTr);
+            count++;
+        }
+        let $trEnd = $("<tr><td>"+ count +"</td><td><a href data-toggle='modal' data-target='#editBianma' class='m-0'>点击勾选编码</a></td><td><textarea class='form-control'></textarea></td></tr>");//勾选行
+        $($trEnd.children().children()[0]).bind('click', function () {
+            me.onclickFuncAdd($(this));
+            me.currentOprTr = $trEnd;
+            me.currentJobContent = $(me.currentOprTr.children()[2]).children().val();
+        });
+        $tbody.append($trEnd);
+        table.append($thead);
+        table.append($tbody);
+    },
+    //新增一行tr
+    getNewTr: function (tbody, codes, jobContent) {
+        let me = jobContentOprObj;
+        let count = tbody.children().length > 0 ? tbody.children().length : 1;
+        let $textTd = $("<td></td>");
+        let $textarea = $("<textarea class='form-control'></textarea>");
+        $textarea.val(jobContent);
+        $textTd.append($textarea);
+        let $tr = $("<tr><td>" + count + "</td><td><a href data-toggle='modal' data-target='#editBianmaQ' class='m-0'>编辑编码</a></td></tr>");
+        $tr.children().children().bind('click', function () {
+            me.currentOprTr = $tr;
+            me.currentJobContent = $(me.currentOprTr.children()[2]).children().val();
+            me.onclickFuncEdit($(this));
+        });
+        //文本变化;
+        $textarea.bind('change', function () {
+            let codes = me.getUpdateCodes($($(this).parent().parent().children()[1]).children());
+            let jobContent = $(this).val();
+            me.updateJobContent(pageOprObj.rationLibId, me.getUpdateArr(codes, jobContent), function () {
+                if(jobContent.trim().length === 0){
+                    me.buildTablePartial(me.tablePartial, me.getGroup(me.currentRationItems));
+                }
+            });
+        });
+        $tr.append($textTd);
+        for(let i = 0, len = codes.length; i < len; i ++){
+            let $p = $("<p class='m-0'>" + codes[i] + "</p>");
+            $tr.children()[1].append($p[0]);
+        }
+        me.setTextareaHeight($textarea, codes.length + 1);
+        return $tr[0];
+    },
+    onclickFuncAdd: function (obj) {
+        let me = jobContentOprObj;
+        let txtarea = $(obj.parent().parent().children().children()[1]);
+        let jobContent = txtarea.val();
+        if(jobContent.trim().length > 0){//工作内容不为空才可添加编码
+            let codesObj = me.getAddCodes(me.currentRationItems);
+            me.buildCheckCodesCon(me.addCon, codesObj.checkedCodes, codesObj.disabledCodes)
+            obj.attr('data-target', '#editBianma');
+        }
+        else{
+            obj.attr('data-target', '');
+            alert("工作内容不能为空!");
+        }
+    },
+    onclickFuncEdit: function (obj) {
+        let me = jobContentOprObj;
+        me.buildEditableCodesCon(me.currentRationItems, me.updateCon, me.getUpdateCodes(obj));
+    },
+    //获取编码td中的编码
+    getUpdateCodes: function (jq) {
+        let rst = [];
+        let nodes = jq.parent().children();
+        for(let i = 1, len = nodes.length; i < len; i++){
+            rst.push(nodes[i].textContent);
+        }
+        return rst;
+    },
+    //建一个编码checkbox Div
+    buildCodeOption: function (code, attr) {
+        let $div = $("<div class='col'><label class='form-check-label'><input class='form-check-input' type='checkbox' value= "+ code +"> "+ code +"</label></div>");
+        let $checkBox = $div.children().children();
+        if(attr){
+            $checkBox.attr(attr, true);
+        }
+        return $div;
+    },
+    //建修改编码弹窗
+    buildEditableCodesCon: function (rationItems, container,codes) {
+        let me = jobContentOprObj;
+        let codeDivs = [];
+        container.empty();
+        for(let i = 0, len = codes.length; i < len; i++){
+            codeDivs.push({code: codes[i], attr: 'checked'});
+        }
+        for(let i = 0, len = rationItems.length; i < len; i++){
+            if(codes.indexOf(rationItems[i].code) === -1){
+                if(typeof rationItems[i].jobContent !== 'undefined' && rationItems[i].jobContent.toString().trim().length > 0){
+                    codeDivs.push({code: rationItems[i].code, attr: 'disabled'});
+                }
+                else{
+                    codeDivs.push({code: rationItems[i].code, attr: ''});
+                }
+            }
+        }
+        //排序
+        codeDivs.sort(function (a, b) {
+            let rst = 0;
+            if(a.code > b.code) rst = 1;
+            else if(a.code < b.code) rst = -1;
+            return rst;
+        });
+        for(let i = 0, len = codeDivs.length; i < len; i++){
+            container.append(me.buildCodeOption(codeDivs[i].code, codeDivs[i].attr));
+        }
+    },
+    //建勾选编码弹窗
+    buildCheckCodesCon: function (container, checkedCodes, disabledCodes) {
+        let me = jobContentOprObj;
+        container.empty();
+        for(let i = 0, len = checkedCodes.length; i < len; i++){
+            let $codeDiv = me.buildCodeOption(checkedCodes[i], 'checked');
+            container.append($codeDiv);
+        }
+        for(let i = 0, len = disabledCodes.length; i < len; i++){
+            let $codeDiv = me.buildCodeOption(disabledCodes[i], 'disabled');
+            container.append($codeDiv);
+        }
+    },
+    getAddCodes: function (rationItems) {
+        let me = jobContentOprObj;
+        let rst = {checkedCodes: [], disabledCodes: []};
+        for(let i = 0, len = rationItems.length; i < len; i++){
+            if(typeof rationItems[i].jobContent !== 'undefined' && rationItems[i].jobContent.toString().trim().length > 0){
+                rst.disabledCodes.push(rationItems[i].code);
+            }
+            else{
+                rst.checkedCodes.push(rationItems[i].code);
+            }
+        }
+        return rst;
+    },
+    //获取选择后的编码窗口的编码及状态
+    getCodesAfterS: function (checkNodes) {
+        let rst = {checked: [], unchecked: []};
+        for(let i = 0, len = checkNodes.length; i < len; i++){
+            if(checkNodes[i].checked){
+                rst.checked.push(checkNodes[i].value);
+            }
+            else if(!checkNodes[i].checked && !checkNodes[i].disabled){
+                rst.unchecked.push(checkNodes[i].value);
+            }
+        }
+        return rst;
+    },
+    setRadiosChecked: function (situation, radios) {
+        let me = jobContentOprObj;
+        if(situation === me.situations.ALL){
+            radios[0].checked = true;
+            radios[1].checked = false;
+            $('#txtareaAll').val(me.currentRationItems.length > 0 ? me.currentRationItems[0].jobContent : '');
+            me.currentJobContent = me.currentRationItems.length > 0 ? me.currentRationItems[0].jobContent : '';
+            me.tableAll.show();
+            me.tablePartial.hide();
+        }
+        else if(situation === me.situations.PARTIAL){
+            radios[0].checked = false;
+            radios[1].checked = true;
+            me.tableAll.hide();
+            me.tablePartial.show();
+        }
+        else if(situation === me.situations.NONE){
+            radios[0].checked = false;
+            radios[1].checked = false;
+            me.tableAll.hide();
+            me.tablePartial.hide();
+        }
+    },
+    //radios是否可用,只有在定额章节树的底层节点才可用
+    setRadiosDisabled: function (val, radios) {
+        let me =jobContentOprObj;
+        if(val){
+            radios[0].checked = false;
+            radios[1].checked = false;
+            me.currentSituation = me.situations.NONE;
+        }
+        radios.attr('disabled', val);
+    },
+    radiosChange: function (radios, tableAll, tablePartial) {
+        let me = jobContentOprObj;
+        radios.change(function () {
+            let val = $("input[name = 'optionsRadios']:checked").val();
+            let selectedNode = sectionTreeObj.tree.selected;
+            me.updateSituation(pageOprObj.rationLibId, selectedNode.getID(), val, function () {
+                selectedNode.data.jobContentSituation = val;
+                me.currentSituation = val;
+                if(val === me.situations.ALL){
+                    let updateCodes = [];
+                    for(let i = 0, len = me.currentRationItems.length; i < len; i++){
+                        updateCodes.push(me.currentRationItems[i].code);
+                    }
+                    me.updateJobContent(pageOprObj.rationLibId, me.getUpdateArr(updateCodes, ''), function () {
+                        me.currentJobContent = '';
+                        $('#txtareaAll').val('');
+                        tableAll.show();
+                        tablePartial.hide();
+                    });
+                }
+                else{
+                    me.buildTablePartial(me.tablePartial, me.getGroup(me.currentRationItems));
+                    tableAll.hide();
+                    tablePartial.show();
+                }
+            });
+        });
+    },
+    setTextareaHeight: function (textarea, nodesCount) {
+        const perHeight = 21.6;
+        textarea.height(nodesCount * 21.6);
+    },
+    bindEvents: function (txtarea) {
+        let me = jobContentOprObj;
+        txtarea.bind('change', function () {
+            let jobContent = txtarea.val();
+            let jqNodes = txtarea.parent().parent().children()[1].children;
+            let updateCodes = me.getUpdateCodes(jqNodes);
+            txtarea.attr('disabled', true);
+            me.updateJobContent(pageOprObj.rationLibId, me.getUpdateArr(updateCodes, jobContent), function () {
+                txtarea.attr('disabled', false);
+            });
+        });
+    },
+    bindAllEvents: function (txtarea) {
+        let me = jobContentOprObj;
+        txtarea.bind('change', function () {
+            let met = this;
+            let jobContent = $(met).val();
+            $(met).attr('disabled', true);
+            let updateCodes = [];
+            for(let i = 0, len = me.currentRationItems.length; i < len; i++){
+                updateCodes.push(me.currentRationItems[i].code);
+                me.currentRationItems[i].jobContent = jobContent;
+            }
+            me.currentJobContent = jobContent;
+            me.updateJobContent(pageOprObj.rationLibId, me.getUpdateArr(updateCodes, jobContent), function () {
+                $(met).attr('disabled', false);
+            });
+        });
+    },
+    unbindEvents: function (txtarea) {
+        txtarea.unbind();
+    },
+    //定额工作内容相关操作
+    rationJobContentOpr: function (rationItems) {
+        let me = jobContentOprObj;
+        me.setRadiosDisabled(me.currentRationItems.length > 0 ? false : true, me.radios);
+        me.setRadiosChecked(me.currentSituation, me.radios);
+        me.buildTablePartial(me.tablePartial, me.getGroup(rationItems));
+    },
+    getUpdateArr: function (updateCodes, jobContent) {
+        let rst = [];
+        for(let i = 0, len = updateCodes.length; i < len; i++){
+            rst.push({code: updateCodes[i], jobContent: jobContent});
+        }
+        return rst;
+    },
+    bindAddConBtn: function () {
+        let me = jobContentOprObj;
+        return function () {
+            let codesObj = me.getCodesAfterS(me.addCon.children().children().children());
+            let $tbody = $('#tablePartial tbody');
+            let lastEle = $tbody[0].lastElementChild;
+            let txtare = lastEle.lastElementChild.children[0];
+            if(me.currentJobContent.trim().length > 0){//工作内容不为空才可添加编码
+                let updateArr = me.getUpdateArr(codesObj.checked, me.currentJobContent);
+                me.updateJobContent(pageOprObj.rationLibId, updateArr, function () {
+                    me.buildTablePartial(me.tablePartial, me.getGroup(me.currentRationItems));
+                    $(txtare).val('');
+                });
+            }
+            else{
+                alert("工作内容不能为空!");
+            }
+        }
+    },
+    bindUpdateConBtn: function () {
+        let me = jobContentOprObj;
+        return function () {
+            let codesObj = me.getCodesAfterS(me.updateCon.children().children().children());
+            let updateC = me.getUpdateArr(codesObj.checked, me.currentJobContent),
+                updateUnC = me.getUpdateArr(codesObj.unchecked, ''),
+                updateArr = updateC.concat(updateUnC);
+            me.updateJobContent(pageOprObj.rationLibId, updateArr, function () {
+                me.buildTablePartial(me.tablePartial, me.getGroup(me.currentRationItems));
+            });
+        }
+    },
+    //更新缓存的定额
+    updateRationItem: function (rationItems, updateArr) {
+        for(let i = 0, len = rationItems.length; i < len; i++){
+            for(let j = 0, jLen = updateArr.length; j < jLen; j++){
+                if(rationItems[i].code === updateArr[j].code){
+                    rationItems[i].jobContent = updateArr[j].jobContent;
+                    break;
+                }
+            }
+        }
+    },
+    updateJobContent: function (repId, updateArr, callback){
+        let me = jobContentOprObj;
+        $.ajax({
+            type: 'post',
+            url: 'api/updateJobContent',
+            data: {lastOpr: userAccount, repId: pageOprObj.rationLibId, updateArr: JSON.stringify(updateArr)},
+            dataType: 'json',
+            success: function (result) {
+                if(!result.error){
+                    me.updateRationItem(jobContentOprObj.currentRationItems, updateArr);
+                    callback();
+                }
+            }
+        });
+    },
+    updateSituation: function (repId, nodeId, situation, callback) {
+        let me = jobContentOprObj;
+        $.ajax({
+            type: 'post',
+            url: 'api/updateSituation',
+            data: {lastOpr: userAccount, repId: pageOprObj.rationLibId, nodeId: nodeId, situation: situation},
+            dataType: 'json',
+            success: function (result) {
+                if(!result.error){
+                    if(callback){
+                        callback();
+                    }
+                }
+            }
+        })
+    }
+};

+ 33 - 0
web/building_saas/complementary_ration_lib/js/main.js

@@ -0,0 +1,33 @@
+/**
+ * Created by Zhong on 2017/12/22.
+ */
+
+let compleRationMain = {
+    getRationLibs: function () {
+        let scFunc = function (rstData) {
+            $("#comple_ration_table").empty();
+            for(let i = 0; i < rstData.length; i++){
+                storageUtil.setSessionCache("RationGrp","repositoryID_" + rstData[i].ID, rstData[i].dispName);
+                if(rstData[i].gljLib){
+                    storageUtil.setSessionCache("gljLib","repositoryID_" + rstData[i].ID, rstData[i].gljLib);
+                }
+                let id = rstData[i].ID;
+                let libName = rstData[i].dispName;
+                $("#comple_ration_table").append(
+                    "<tr id='tempId'>" +
+                    "<td><a href='/stdGljRepository/glj'>"+libName+"</a></td></tr>"
+                );
+                var newHref = "/complementaryRation/ration?repository="+id;
+                $("#tempId td:first a").attr("href", newHref);
+                $("#tempId").attr("id", id);
+            }
+        };
+        CommonAjax.post('/complementaryRation/api/getRationLibs', {user_id: userID}, scFunc);
+    }
+};
+
+$(document).ready(function () {
+    $('#comple-ration').on('shown.bs.modal', function () {
+        compleRationMain.getRationLibs();
+    });
+});

+ 659 - 0
web/building_saas/complementary_ration_lib/js/ration.js

@@ -0,0 +1,659 @@
+/**
+ * Created by Tony on 2017/4/28.
+ */
+
+$("#gongliao").click(function(){
+    $(this).attr('href', "/rationRepository/lmm" + "?repository=" + getQueryString("repository"))
+});
+
+$("#fuzhu").click(function(){
+    $(this).attr('href', "/rationRepository/coeList" + "?repository=" + getQueryString("repository"))
+});
+const digital = {
+    gljPrc: -3,//计算定额基价时单个工料机价格取三位
+    rationBasePrc: -2,
+    consumeAmt: -3
+};
+let rationOprObj = {
+    workBook: null,
+    currentRations: {},
+    currentEditingRation: null,
+    currentSectionId: -1,
+    rationsCodes: [],
+    setting: {
+        header:[
+            {headerName:"编码",headerWidth:120,dataCode:"code", dataType: "String", formatter: "@"},
+            {headerName:"名称",headerWidth:280,dataCode:"name", dataType: "String"},
+            {headerName:"计量单位",headerWidth:120,dataCode:"unit", dataType: "String", hAlign: "center"},
+            {headerName:"人工费",headerWidth:120,dataCode:"labourPrice", dataType: "Number", formatter: "0.00", hAlign: "right"},
+            {headerName:"材料费",headerWidth:120,dataCode:"materialPrice", dataType: "Number", formatter: "0.00",  hAlign: "right"},
+            {headerName:"机械费",headerWidth:120,dataCode:"machinePrice", dataType: "Number", formatter: "0.00", hAlign: "right"},
+            {headerName:"基价",headerWidth:120,dataCode:"basePrice", dataType: "Number", formatter: "0.00", hAlign: "right"},
+            {headerName:"显示名称(以%s表示参数)",headerWidth:280,dataCode:"caption", dataType: "String"},
+            {headerName:"取费专业",headerWidth:100,dataCode:"feeType", dataType: "Number", hAlign: "center"}
+        ],
+        view:{
+            comboBox:[
+                {row:-1,col:2,rowCount:-1,colCount:1}
+            ],
+            lockedCells:[
+                {row:-1,col:3,rowCount:-1, colCount:1}
+            ],
+            lockColumns: [
+                3, 4, 5, 6
+            ]
+        }
+    },
+    buildSheet: function(container) {
+        let rationRepId = getQueryString("repository");
+        let me = rationOprObj;
+        let gljLibID = storageUtil.getSessionCache("gljLib", "repositoryID_" + rationRepId);
+        if(!gljLibID || typeof gljLibID === 'undefined' || gljLibID == -1){
+            alert("没有引用工料机库!");
+            window.location.href = "/rationRepository/main";
+        }
+        me.workBook = sheetCommonObj.buildSheet(container, me.setting, 30);
+        me.getRationsCodes(rationRepId);
+        me.rationDelOpr();
+        me.setCombo(me.workBook.getSheet(0), 'dynamic');
+        me.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting);
+        me.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.ClipboardPasted, me.onClipboardPasted);
+        me.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.LeaveCell, me.onLeaveCell);
+        me.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.EnterCell, me.onEnterCell);
+        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.SelectionChanged, me.onSelectionChanged);
+    },
+    setCombo: function (sheet, combo) {
+        let me = rationOprObj;
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        if(combo){
+            combo = sheetCommonObj.getDynamicCombo();
+            combo.items(rationUnits).itemHeight(10).editable(true);
+        }
+        sheet.getRange(-1, me.setting.view.comboBox[0].col, -1, 1).cellType(combo);
+        sheet.resumePaint();
+        sheet.resumeEvent();
+    },
+    onSelectionChanged: function (sender, info) {
+        if(info.oldSelections.length === 0 && info.newSelections.length > 0 || info.oldSelections[0].row !== info.newSelections[0].row){
+            let row = info.newSelections[0].row;
+            let me = rationOprObj,
+                sheetGLJ = rationGLJOprObj.sheet, settingGLJ = rationGLJOprObj.setting,
+                sheetCoe = rationCoeOprObj.sheet, settingCoe = rationCoeOprObj.setting,
+                sheetAss = rationAssistOprObj.sheet, settingAss = rationAssistOprObj.setting;
+            sheetCommonObj.cleanSheet(sheetGLJ, settingGLJ, -1);
+            sheetCommonObj.cleanSheet(sheetCoe, settingCoe, -1);
+            sheetCommonObj.cleanSheet(sheetAss, settingAss, -1);
+            let cacheSection = me.getCache();
+            if (cacheSection && row < cacheSection.length) {
+                rationGLJOprObj.getGljItems(cacheSection[row], function () {
+                    me.workBook.focus(true);
+                });
+                rationCoeOprObj.getCoeItems(cacheSection[row], function () {
+                    me.workBook.focus(true);
+                });
+                rationAssistOprObj.getAssItems(cacheSection[row]);
+            }
+            else {
+                rationGLJOprObj.currentRationItem = null;
+            }
+            me.workBook.focus(true);
+        }
+    },
+
+    isInt: function (num) {
+        return !isNaN(num) && num % 1 === 0;
+    },
+    getCache: function() {
+        let me = this, rst = me.currentRations["_SEC_ID_" + me.currentSectionId];
+        if (!(rst)) {
+            me.currentRations["_SEC_ID_" + me.currentSectionId] = [];
+            rst = me.currentRations["_SEC_ID_" + me.currentSectionId];
+        }
+        return rst;
+    },
+    updateCache: function(addArr, updateArr, removeIds, result) {
+        let me = this, cacheSection = me.getCache();
+        if (addArr.length > 0) {
+            me.currentRations["_SEC_ID_" + me.currentSectionId] = cacheSection.concat(addArr);
+            cacheSection = me.currentRations["_SEC_ID_" + me.currentSectionId];
+        }
+        for (let i = removeIds.length - 1; i >= 0; i--) {
+            for (let j = cacheSection.length - 1; j >= 0 ; j--) {
+                if (cacheSection[j]["ID"] == removeIds[i]) {
+                    cacheSection.splice(j,1);
+                }
+            }
+        }
+        if (result && result.data.ops && result.data.ops.length > 0) {
+            for (let i = 0; i < result.data.ops.length; i++) {
+                for (let j = 0; j < cacheSection.length; j++) {
+                    if (cacheSection[j][me.setting.header[0].dataCode] == result.data.ops[i][me.setting.header[0].dataCode]) {
+                        cacheSection[j]["ID"] = result.data.ops[i]["ID"];
+                        cacheSection[j]["rationGljList"] = result.data.ops[i]["rationGljList"];
+                        cacheSection[j]["rationCoeList"] = result.data.ops[i]["rationCoeList"];
+                        cacheSection[j]["rationAssList"] = result.data.ops[i]["rationAssList"];
+                    }
+                }
+            }
+        }
+        for (let i = 0; i < updateArr.length; i++) {
+            for (let j = 0; j < cacheSection.length; j++) {
+                if (updateArr[i]["ID"] && cacheSection[j]["ID"]) {
+                    if (cacheSection[j]["ID"] == updateArr[i]["ID"]) {
+                        cacheSection[j] = updateArr[i];
+                    }
+                } else {
+                    if (cacheSection[j][me.setting.header[0].dataCode] == updateArr[i][me.setting.header[0].dataCode]) {
+                        cacheSection[j] = updateArr[i];
+                    }
+                }
+            }
+        }
+        return cacheSection;
+    },
+    rationDelOpr: function () {
+        let me = rationOprObj;
+        me.workBook.commandManager().register('rationDelete', function () {
+            let rationSheet = me.workBook.getActiveSheet();
+            let sels = rationSheet.getSelections(), updateArr = [], removeArr = [], lockCols = me.setting.view.lockColumns;
+            let cacheSection = me.getCache();
+            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);
+                                    me.rationsCodes.splice(me.rationsCodes.indexOf(cacheSection[sels[sel].row + i].code), 1);
+                                }
+                            }
+                        }
+                    }
+                    else{
+                        if(sels[sel].col === 0){
+                            $('#alertText').text("编号不能为空,修改失败!");
+                            $('#alertModalBtn').click();
+                            $('#alertModalCls').click(function () {
+                            });
+                            $('#alertModalCof').click(function () {
+                            })
+                        }
+                        else if(sels[sel].col !== 0 && !(sels[sel].col === 3 && sels.col + sels[sel].colCount -1 === 6)){
+                            if(cacheSection){
+                                for(let i = sels[sel].row === -1 ? 1 : 0; i < sels[sel].rowCount; i++){
+                                    if(sels[sel].row + i < cacheSection.length){
+                                        for(let col = sels[sel].col; col <= sels[sel].col + sels[sel].colCount - 1; col++){
+                                            if(lockCols.indexOf(col) === -1){
+                                                cacheSection[sels[sel].row + i][me.setting.header[col].dataCode] = '';
+                                            }
+                                        }
+                                    }
+                                    if(cacheSection[sels[sel].row + i] && typeof cacheSection[sels[sel].row + i] !== 'undefined'){
+                                        updateArr.push(cacheSection[sels[sel].row + i]);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            if(updateArr.length > 0 || removeArr.length > 0){
+                me.mixUpdate = 1;
+                me.mixDel = removeArr.length > 0 ? 1 : 0;
+                me.mixUpdateRequest(updateArr, [], removeArr);
+            }
+
+        });
+        me.workBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false);
+        me.workBook.commandManager().setShortcutKey('rationDelete', GC.Spread.Commands.Key.del, false, false, false, false);
+    },
+    onLeaveCell: function (sender, args) {
+        let me = rationOprObj;
+        me.lastCol = me.setting.header[args.col];
+    },
+    onEnterCell: function (sender, args) {
+        let me = rationOprObj;
+        if(me.setting.header[args.col]['dataCode'] === 'unit' || me.lastCol.dataCode === 'unit'){
+            args.sheet.repaint();
+        }
+        me.cellRowIdx = args.row;
+        let isHasData = false;
+        if(me.addRationItem){
+            for(let i=0; i<me.setting.header.length; i++){
+                if(me.addRationItem[me.setting.header[i].dataCode]){
+                    isHasData = true;
+                    break;
+                }
+            }
+        }
+        if(isHasData){
+            if(me.editingRowIdx !== me.cellRowIdx) {
+                let focusToCol = !me.addRationItem.code ? 0 : -1;
+                if(focusToCol !== -1){
+                    $('#rationAlertBtn').click();
+                    $('#rationAlertCac').click(function () {
+                        me.addRationItem = null;
+                        for(let col=0; col<me.setting.header.length; col++){
+                            me.workBook.getSheet(0).getCell(me.editingRowIdx, col).value('');
+                        }
+                    });
+                    $('#rationAlertCls').click(function () {
+                        me.workBook.getSheet(0).setActiveCell(me.editingRowIdx, focusToCol);
+                    });
+                    $('#rationAlertCof').click(function () {
+                        me.workBook.getSheet(0).setActiveCell(me.editingRowIdx, focusToCol);
+                    });
+                }
+            }
+        }
+    },
+    onCellEditStart: function(sender, args) {
+        let me = rationOprObj;
+        if(!me.canRations || me.setting.view.lockColumns.indexOf(args.col) !== -1){
+            args.cancel = true;
+        }
+        else{
+            let rObj = sheetsOprObj.combineRationRowData(me.workBook.getSheet(0), me.setting, args.row);
+            me.currentEditingRation = rObj;
+            let cacheSection = me.getCache();
+            if (cacheSection) {
+                for (let j = 0; j < cacheSection.length; j++) {
+                    if (cacheSection[j][me.setting.header[0].dataCode] == rObj[me.setting.header[0].dataCode]) {
+                        rObj["ID"] = cacheSection[j]["ID"];
+                        break;
+                    }
+                }
+            }
+        }
+    },
+    onCellEditEnd: function(sender, args) {
+        let me = rationOprObj, rObj = sheetsOprObj.combineRationRowData(me.workBook.getSheet(0), me.setting, args.row),
+            updateArr = [], addArr = [];
+        let dataCode = me.setting.header[args.col].dataCode;
+        me.editingRowIdx = args.row;
+        if (me.currentEditingRation["ID"]) {
+            if((!args.editingText || args.editingText.toString().trim().length === 0) && args.col === 0){
+                args.sheet.setValue(args.row, args.col, me.currentEditingRation[dataCode] + '');
+            }
+            else {
+                rObj["ID"] = me.currentEditingRation["ID"];
+                if(me.currentEditingRation[dataCode] !== rObj[dataCode]){
+                    me.addRationItem = rObj;
+                    if(dataCode === 'code'){
+                        if(me.rationsCodes.indexOf(rObj.code) === -1){
+                            me.rationsCodes.splice(me.rationsCodes.indexOf(rObj.code), 1);
+                            me.rationsCodes.push(rObj.code);
+                            updateArr.push(rObj);
+                        }
+                        else{
+                            alert("编码已存在!");
+                            args.sheet.setValue(args.row, args.col, me.currentEditingRation[dataCode]);
+
+                        }
+                    }
+                    else if(dataCode === 'feeType'){//取费专业控制为整数
+                        if(me.isInt(rObj[dataCode])){
+                            updateArr.push(rObj);
+                        }
+                        else {
+                            rObj[dataCode] = '';
+                            args.sheet.setValue(args.row, args.col, typeof me.currentEditingRation[dataCode] !== 'undefined' && me.currentEditingRation[dataCode] ? me.currentEditingRation[dataCode] : '');
+                        }
+                    }
+                    else{
+                        updateArr.push(rObj);
+                    }
+                }
+            }
+        }
+        else if(!me.currentEditingRation["ID"]) {
+            if (!sheetCommonObj.chkIfEmpty(rObj, me.setting)) {
+                //addArr.push(rObj);
+                me.addRationItem = rObj;
+                if(rObj.code && rObj.code.toString().trim().length > 0){
+                    if(me.rationsCodes.indexOf(rObj.code) === -1){
+                        //jobContent
+                        if(jobContentOprObj && jobContentOprObj.currentSituation === jobContentOprObj.situations.ALL){
+                            rObj.jobContent = jobContentOprObj.currentJobContent ? jobContentOprObj.currentJobContent : '';
+                        }
+                        if(annotationOprObj && annotationOprObj.currentSituation === annotationOprObj.situations.ALL){
+                            rObj.annotation = annotationOprObj.currentAnnotation ? annotationOprObj.currentAnnotation : '';
+                        }
+                        me.setInitPrc(rObj);
+                        addArr.push(rObj);
+                        me.rationsCodes.push(rObj.code);
+                        me.addRationItem = null;
+                    }
+                    else{
+                        alert('编码已存在!');
+                        me.workBook.getSheet(0).setValue(args.row, args.col, '');
+                    }
+                }
+                else if(rObj.code && rObj.code.toString.trim().length === 0){
+                    me.workBook.getSheet(0).setValue(args.row, args.col, '');
+                }
+            }
+        }
+        if (updateArr.length > 0 || addArr.length > 0) {
+            me.currentEditingRation = null;
+            me.mixUpdate = 1;
+            me.mixUpdateRequest(updateArr, addArr, []);
+        }
+    },
+    canPasted: function (beginCol, maxCol) {
+        let rst = false;
+        if(maxCol < 3 || beginCol > 6){
+            rst = true;
+        }
+        return rst;
+    },
+    onClipboardPasting: function(sender, args) {
+        let me = rationOprObj;
+        let maxCol = args.cellRange.col + args.cellRange.colCount -1;
+        if(!me.canRations || !me.canPasted(args.cellRange.col, maxCol) || maxCol > me.setting.header.length - 1){
+            args.cancel = true;
+        }
+    },
+    //todo: overwrite?
+    onClipboardPasted: function(e, info) {
+        let me = rationOprObj;
+        let cacheSection = me.getCache();
+        let updateArr = [], addArr = [];
+        let items = sheetCommonObj.analyzePasteData(me.setting, info);
+        for (let i = 0; i < items.length; i++) {
+            let rowIdx = info.cellRange.row + i;
+            if (cacheSection) {
+                if(!me.isValidUnit(items[i], rationUnits)){//无效单位
+                    items[i].unit = rowIdx < cacheSection.length  && typeof cacheSection[rowIdx].unit !== 'undefined' ? cacheSection[rowIdx].unit : '';
+                }
+                if(!cacheSection[rowIdx] && info.cellRange.col === 0 ){
+                    if(me.rationsCodes.indexOf(items[i].code) === -1){
+                        //jobConten
+                        if(jobContentOprObj && jobContentOprObj.currentSituation === jobContentOprObj.situations.ALL){
+                            items[i].jobContent = jobContentOprObj.currentJobContent ? jobContentOprObj.currentJobContent : '';
+                        }
+                        if(annotationOprObj && annotationOprObj.currentSituation === annotationOprObj.situations.ALL){
+                            items[i].annotation = annotationOprObj.currentAnnotation ? annotationOprObj.currentAnnotation : '';
+                        }
+                        me.setInitPrc(items[i]);
+                        addArr.push(items[i]);
+                        me.rationsCodes.push(items[i].code);
+                    }
+                    else{
+                        me.workBook.getSheet(0).setValue(rowIdx, 0, '');
+                    }
+                }
+                else if(cacheSection[rowIdx]){
+                    for(let col = 0; col < me.setting.header.length; col++){
+                        if(!items[i][me.setting.header[col].dataCode] && typeof cacheSection[rowIdx][me.setting.header[col].dataCode] !== 'undefined'){
+                            items[i][me.setting.header[col].dataCode] = cacheSection[rowIdx][me.setting.header[col].dataCode];
+                        }
+                    }
+                    if(items[i].feeType && !me.isInt(items[i].feeType)){
+                        items[i].feeType = '';
+                        me.workBook.getSheet(0).setValue(rowIdx, 8, '');
+                    }
+                    if(info.cellRange.col === 0){
+                        if(me.rationsCodes.indexOf(items[i].code) === -1){
+                            items[i].ID = cacheSection[rowIdx].ID;
+                            updateArr.push(items[i]);
+                        }
+                        else{
+                            me.workBook.getSheet(0).setValue(rowIdx, 0, cacheSection[rowIdx].code);
+                        }
+                    }
+                    else{
+                        items[i].ID = cacheSection[rowIdx].ID;
+                        updateArr.push(items[i]);
+                    }
+                }
+
+            } else {
+                if(!me.isValidUnit(items[i], rationUnits)){//无效单位
+                    items[i].unit = '';
+                }
+                //add
+                if(info.cellRange.col === 0){
+                    //是否含有已存在的编号
+                        if(me.rationsCodes.indexOf(items[i].code) === -1){
+                            //jobConten
+                            if(jobContentOprObj && jobContentOprObj.currentSituation === jobContentOprObj.situations.ALL){
+                                items[i].jobContent = jobContentOprObj.currentJobContent ? jobContentOprObj.currentJobContent : '';
+                            }
+                            if(annotationOprObj && annotationOprObj.currentSituation === annotationOprObj.situations.ALL){
+                                items[i].annotation = annotationOprObj.currentAnnotation ? annotationOprObj.currentAnnotation : '';
+                            }
+                            me.setInitPrc(items[i]);
+                            addArr.push(items[i]);
+                        }
+                }
+            }
+        };
+         if (updateArr.length > 0 || addArr.length > 0) {
+             me.mixUpdate = 1;
+            me.mixUpdateRequest(updateArr, addArr, []);
+        }
+        else{
+             me.getRationItems(me.currentSectionId);
+         }
+    },
+    setInitPrc: function (obj) {
+        obj.labourPrice = 0;
+        obj.materialPrice = 0;
+        obj.machinePrice = 0;
+        obj.basePrice = 0;
+    },
+    isValidUnit: function (rationObj, validUnits) {
+        let rst = true;
+        if(typeof rationObj.unit !== 'undefined' && rationObj.unit && validUnits.indexOf(rationObj.unit) === -1){//无效
+            rst = false;
+        }
+        return rst;
+    },
+    getRationsCodes: function (repId) {
+        let me = rationOprObj;
+        $.ajax({
+            type: 'post',
+            url: 'api/getRationsCodes',
+            data: {data: JSON.stringify({repId: repId})},
+            dataType: 'json',
+            success: function (result) {
+                if(!result.error){
+                    me.rationsCodes = result.data;
+                }
+            }
+        })
+    },
+    mixUpdateRequest: function(updateArr, addArr, removeIds, callback) {
+        let me = rationOprObj;
+        me.saveInString(updateArr);
+        $.ajax({
+            type:"POST",
+            url:"api/mixUpdateRationItems",
+            data:{"rationLibId": getQueryString("repository"), "lastOpr": userAccount, "sectionID": me.currentSectionId, "updateItems": JSON.stringify(updateArr), "addItems": JSON.stringify(addArr), "removeIds": JSON.stringify(removeIds)},
+            dataType:"json",
+            cache:false,
+            timeout:20000,
+            success:function(result){
+                if (result.error) {
+                    alert('error');
+                    me.getRationItems(me.currentSectionId);
+                } else {
+                    let cacheSection = me.updateCache(addArr, updateArr, removeIds, result);
+                    cacheSection.sort(function(a, b){
+                        let rst = 0;
+                        if (a.code > b.code) rst = 1
+                        else if (a.code < b.code) rst = -1;
+                        return rst;
+                    });
+                    //jobContent
+                    if(jobContentOprObj ){
+                        jobContentOprObj.currentRationItems = cacheSection;
+                        jobContentOprObj.setRadiosDisabled(cacheSection.length > 0 ? false : true, jobContentOprObj.radios);
+                        if(cacheSection.length === 0){
+                            jobContentOprObj.updateSituation(pageOprObj.rationLibId, me.currentSectionId, 'NONE');
+                        }
+                        jobContentOprObj.setRadiosChecked(jobContentOprObj.currentSituation, jobContentOprObj.radios);
+                        if(jobContentOprObj.currentSituation === jobContentOprObj.situations.PARTIAL){
+                            jobContentOprObj.buildTablePartial(jobContentOprObj.tablePartial, jobContentOprObj.getGroup(cacheSection));
+                        }
+                    }
+                    if(annotationOprObj ){
+                        annotationOprObj.setRadiosDisabled(cacheSection.length > 0 ? false : true, annotationOprObj.radios);
+                        if(cacheSection.length === 0){
+                            annotationOprObj.updateAnnoSituation(pageOprObj.rationLibId, me.currentSectionId, 'NONE');
+                        }
+                        annotationOprObj.setRadiosChecked(annotationOprObj.currentSituation, annotationOprObj.radios);
+                        if(annotationOprObj.currentSituation === annotationOprObj.situations.PARTIAL){
+                            annotationOprObj.buildTablePartial(annotationOprObj.fzTablePartial, annotationOprObj.getGroup(cacheSection));
+                        }
+                    }
+                    me.showRationItems(me.currentSectionId);
+                    me.mixUpdate = 0;
+                    me.mixDel = 0;
+                }
+                if(callback) callback();
+            },
+            error:function(){
+            }
+        });
+    },
+    getRationItems: function(sectionID){
+        if (sectionID != -1) {
+            let me = rationOprObj;
+            me.mixUpdate = 0;
+            me.currentSectionId = sectionID;
+            if (me.currentRations["_SEC_ID_" + sectionID]) {
+                //jobContent--
+                jobContentOprObj.currentRationItems = me.currentRations["_SEC_ID_" + sectionID];
+                jobContentOprObj.rationJobContentOpr(me.currentRations["_SEC_ID_" + sectionID]);
+                //annotation
+                annotationOprObj.rationAnnotationOpr(me.currentRations["_SEC_ID_" + sectionID]);
+                me.showRationItems(sectionID);
+            } else {
+                CommonAjax.post('api/getRationItems', {rationRepId: pageOprObj.rationLibId, sectionId: sectionID}, function (rstData) {
+                    me.currentRations["_SEC_ID_" + sectionID] = rstData;
+                    me.sortByCode(me.currentRations["_SEC_ID_" + sectionID]);
+                    //job--
+                    jobContentOprObj.currentRationItems = me.currentRations["_SEC_ID_" + sectionID];
+                    jobContentOprObj.rationJobContentOpr(me.currentRations["_SEC_ID_" + sectionID]);
+                    //annotation
+                    annotationOprObj.rationAnnotationOpr(me.currentRations["_SEC_ID_" + sectionID]);
+                    me.showRationItems(sectionID);
+                });
+         /*       $.ajax({
+                    type:"POST",
+                    url:"api/getRationItems",
+                    data:{"rationRepId": pageOprObj.rationLibId, "sectionID": sectionID},
+                    dataType:"json",
+                    cache:false,
+                    timeout:10000,
+                    success:function(result){
+                        if (result) {
+                            me.currentRations["_SEC_ID_" + sectionID] = result.data;
+                            me.sortByCode(me.currentRations["_SEC_ID_" + sectionID]);
+                            //job--
+                            jobContentOprObj.currentRationItems = me.currentRations["_SEC_ID_" + sectionID];
+                            jobContentOprObj.rationJobContentOpr(me.currentRations["_SEC_ID_" + sectionID]);
+                            //annotation
+                            annotationOprObj.rationAnnotationOpr(me.currentRations["_SEC_ID_" + sectionID]);
+                            me.showRationItems(sectionID);
+                        }
+                    },
+                    error:function(err){
+                        alert(err);
+                    }
+                })*/
+            }
+        }
+    },
+    showRationItems: function(sectionID){
+        let me = rationOprObj,
+            sheetGLJ = rationGLJOprObj.sheet, settingGLJ = rationGLJOprObj.setting,
+            sheetCoe = rationCoeOprObj.sheet, settingCoe = rationCoeOprObj.setting,
+            sheetAss = rationAssistOprObj.sheet, settingAss = rationAssistOprObj.setting;
+        if (me.workBook) {
+            if (me.currentRations && me.currentRations["_SEC_ID_" + sectionID] && me.currentRations["_SEC_ID_" + sectionID].length > 0) {
+                let cacheSection = me.currentRations["_SEC_ID_" + sectionID];
+                sheetCommonObj.cleanData(me.workBook.getSheet(0), me.setting, -1);
+                sheetsOprObj.showData(me.workBook.getSheet(0), me.setting, cacheSection);
+                //combo
+                //sheetCommonObj.setStaticCombo(me.workBook.getActiveSheet(), 0, 2, cacheSection.length, rationUnits, 10, false);
+                //--sheetCommonObj.setDynamicCombo(me.workBook.getActiveSheet(), 0, 2, me.workBook.getActiveSheet().getRowCount(), rationUnits, 10, false);
+                if(me.mixDel === 1){
+                    let row = me.workBook.getSheet(0).getSelections()[0].row;
+                    if (cacheSection && row < cacheSection.length) {
+                        sheetCommonObj.cleanData(sheetGLJ, settingGLJ, -1);
+                        sheetCommonObj.cleanData(sheetCoe, settingCoe, -1);
+                        sheetCommonObj.cleanData(sheetAss, settingAss, -1);
+                        rationGLJOprObj.getGljItems(cacheSection[row]);
+                        rationCoeOprObj.getCoeItems(cacheSection[row]);
+                        rationAssistOprObj.getAssItems(cacheSection[row]);
+                    }
+                    else {
+                        rationGLJOprObj.currentRationItem = null;
+                        sheetCommonObj.cleanData(sheetGLJ, settingGLJ, -1);
+                        sheetCommonObj.cleanData(sheetCoe, settingCoe, -1);
+                        sheetCommonObj.cleanData(sheetAss, settingAss, -1);
+                        sheetCommonObj.setDynamicCombo(sheetAss, 0, 5, sheetAss.getRowCount(), rationAssistOprObj.setting.comboItems, false, false);
+                    }
+                }
+
+            } else {
+                sheetCommonObj.setDynamicCombo(sheetAss, 0, 5, sheetAss.getRowCount(), rationAssistOprObj.setting.comboItems, false, false);
+                //--sheetCommonObj.setDynamicCombo(me.workBook.getActiveSheet(), 0, 2, me.workBook.getActiveSheet().getRowCount(), rationUnits, 10, false);
+                //清除ration数据及工料机数据
+                rationGLJOprObj.currentRationItem = null;
+                sheetCommonObj.cleanSheet(me.workBook.getSheet(0), me.setting, -1);
+                sheetCommonObj.cleanSheet(sheetGLJ, settingGLJ, -1);
+                sheetCommonObj.cleanSheet(sheetCoe, settingCoe, -1);
+                sheetCommonObj.cleanSheet(sheetAss, settingAss, -1);
+            }
+           //--- me.workBook.focus(true);
+        }
+        sectionTreeObj.workBook.focus(true);
+    },
+    sortByCode: function(arr){
+        function compare(){
+            return function (a, b) {
+                let rst = 0;
+                if (a.code > b.code) {
+                    rst = 1;
+                }
+                else if (a.code < b.code) {
+                    rst = -1;
+                }
+                return rst;
+            }
+        }
+        arr.sort(compare());
+    },
+    saveInString(datas){
+        for(let i = 0, len = datas.length; i < len; i++){
+            let data = datas[i];
+            if(data.labourPrice !== undefined && data.labourPrice){
+                data.labourPrice = data.labourPrice.toString();
+            }
+            if(data.materialPrice !== undefined && data.materialPrice){
+                data.materialPrice = data.materialPrice.toString();
+            }
+            if(data.machinePrice !== undefined && data.machinePrice){
+                data.machinePrice = data.machinePrice.toString();
+            }
+            if(data.basePrice !== undefined && data.basePrice){
+                data.basePrice = data.basePrice.toString();
+            }
+            if(data.rationGljList !== undefined && data.rationGljList && data.rationGljList.length > 0){
+                for(let j = 0, jLen = data.rationGljList.length; j < jLen; j++){
+                    let raGljObj = data.rationGljList[j];
+                    if(raGljObj.consumeAmt !== undefined && raGljObj.consumeAmt){
+                        raGljObj.consumeAmt = raGljObj.consumeAmt.toString();
+                    }
+                }
+            }
+        }
+    }
+}

+ 49 - 0
web/building_saas/complementary_ration_lib/js/rationUnits.js

@@ -0,0 +1,49 @@
+/**
+ * Created by Zhong on 2017/9/8.
+ * 定额列表单位下拉表
+ */
+let rationUnits =[
+    'm',
+    'km',
+    'm2',
+    'm3',
+    'kg',
+    't',
+    '10m',
+    '10m2',
+    '10m3',
+    '100m',
+    '100m2',
+    '100m3',
+    '1000m2',
+    '1000m3',
+    'à·km',
+    '总额',
+    '月',
+    '项',
+    '处',
+    '个',
+    '根',
+    '棵',
+    '块',
+    '每一试桩',
+    '桥长米',
+    '公路公里',
+    '株',
+    '组',
+    '座',
+    '元',
+    '工日',
+    '套',
+    '台班',
+    '艘班',
+    'm/处',
+    'm/道',
+    'm/座',
+    'm2/m',
+    'm3/m',
+    'm3/处',
+    '根/米',
+    '亩',
+    'm3/m2'
+];

+ 194 - 0
web/building_saas/complementary_ration_lib/js/ration_assist.js

@@ -0,0 +1,194 @@
+/**
+ * Created by CSL on 2017-06-14.
+ */
+var rationAssistOprObj = {
+    sheet: null,
+    libID: null,
+    ration: null,
+    setting: {
+        header:[
+            {headerName:"调整名称",headerWidth:200,dataCode:"name", dataType: "String", hAlign: "left"},
+            {headerName:"辅助定额号",headerWidth:120,dataCode:"assistCode", dataType: "String", hAlign: "center"},
+            {headerName:"标准值",headerWidth:100,dataCode:"stdValue", dataType: "String", hAlign: "right"},
+            {headerName:"步距",headerWidth:100,dataCode:"stepValue", dataType: "String", hAlign: "right"},
+            {headerName:"精度",headerWidth:80,dataCode:"decimal",  dataType: "String", hAlign: "right"},
+            {headerName:"进位方式",headerWidth:100,dataCode:"carryBit", dataType: "String", hAlign: "center"},
+            {headerName:"最小值",headerWidth:100,dataCode:"minValue", dataType: "String", hAlign: "right"},
+            {headerName:"最大值",headerWidth:100,dataCode:"maxValue", dataType: "String", hAlign: "right"}
+        ],
+        view:{},
+        comboItems: ["四舍五入", "进一"]
+    },
+
+    buildSheet: function(sheet) {
+        var me = this;
+        me.sheet = sheet;
+        me.libID = storageUtil.getSessionCache("RationGrp","repositoryID"); // 不可靠,有时取不到
+        if (me.libID == undefined){me.libID = getQueryString('repository')};
+
+        sheetCommonObj.initSheet(me.sheet, me.setting, 30);
+
+        me.sheet.bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting);
+        me.sheet.bind(GC.Spread.Sheets.Events.ClipboardPasted, me.onClipboardPasted);
+        me.sheet.bind(GC.Spread.Sheets.Events.EditStarting, me.onEditStarting);
+        me.sheet.bind(GC.Spread.Sheets.Events.EditEnded, me.onEditEnded);
+        me.sheet.bind(GC.Spread.Sheets.Events.EnterCell, me.onEnterCell);
+    },
+
+    onEnterCell: function (sender, args) {
+        let me = rationAssistOprObj;
+        args.sheet.repaint();
+        let cellType = args.sheet.getCellType(args.row, 5);
+        if(cellType.typeName !== 'undefined' && cellType.typeName === '1'){
+          //  sheetCommonObj.setStaticCombo(args.sheet, 0, 5, 0, me.setting.comboItems, false);
+            sheetCommonObj.setDynamicCombo(args.sheet, 0, 5, me.sheet.getRowCount(), me.setting.comboItems, false, false);
+        }
+    },
+
+    onClipboardPasting: function(sender, args) {
+        let me = rationAssistOprObj;
+        let rationSection = rationOprObj.getCache();
+        let rationRow = rationOprObj.workBook.getSheet(0).getSelections()[0].row;
+        me.ration = rationRow < rationSection.length ? rationSection[rationRow] : null;
+        if (!me.ration) {
+            args.cancel = true;
+        }
+    },
+
+    onClipboardPasted: function(e, info) {
+        var me = rationAssistOprObj;
+        if (!me.ration) {return;};
+        var tempArr = sheetCommonObj.analyzePasteData(me.setting, info);
+        var assList = me.ration.rationAssList;
+        if (assList == undefined) {
+            me.ration.rationAssList = tempArr;
+        }else{
+            assList = assList.concat(tempArr);
+            me.ration.rationAssList = assList;
+        };
+
+        rationOprObj.mixUpdateRequest([me.ration], [], [], function () {
+            me.sheet.getParent().focus(true);
+        });
+        sheetCommonObj.cleanData(me.sheet, me.setting, -1);
+        //sheetCommonObj.setStaticCombo(me.sheet, 0, 5, me.ration.rationAssList.length, me.setting.comboItems, false, false);
+        sheetCommonObj.setDynamicCombo(me.sheet, 0, 5, me.sheet.getRowCount(), me.setting.comboItems, false, false);
+        sheetCommonObj.showData(me.sheet, me.setting, me.ration.rationAssList);
+    },
+
+    onEditStarting: function (sender, args) {
+        let me = rationAssistOprObj;
+        let rationSection = rationOprObj.getCache();
+        let rationRow = rationOprObj.workBook.getSheet(0).getSelections()[0].row;
+        me.ration = rationRow < rationSection.length ? rationSection[rationRow] : null;
+        if(!me.ration){
+            args.cancel = true;
+        }
+    },
+
+    onEditEnded: function(sender, args){
+        var me = rationAssistOprObj;
+        if (!me.ration) {return;};
+        if(typeof me.ration.rationAssList === 'undefined'){
+            me.ration.rationAssList = [];
+        }
+        var assList = me.ration.rationAssList;
+        var assObj = sheetsOprObj.combineRationRowData(me.sheet, me.setting, args.row);
+        let dataCode = me.setting.header[args.col].dataCode;
+        if((args.col === 2 || args.col === 3 || args.col === 6 || args.col === 7)
+            && args.editingText && args.editingText.toString().trim().length > 0 && isNaN(args.editingText)){
+            args.sheet.setValue(args.row, args.col, args.row < assList.length ? assList[args.row][dataCode] : '');
+            alert(me.setting.header[args.col].headerName + '只能为数值!');
+            return;
+        }
+        else if(args.col === 4 && args.editingText && (args.editingText.toString().trim().length === 0 ||
+                isNaN(args.editingText) || args.editingText % 1 !== 0)){
+            args.sheet.setValue(args.row, args.col, args.row < assList.length ? assList[args.row][dataCode] : 0);
+            alert(me.setting.header[args.col].headerName + '只能为整数!');
+            return;
+        }
+        // 新增
+        if (args.row >= assList.length) {
+            if (assObj.decimal == undefined || assObj.decimal == null){assObj.decimal = '0';};
+            if (assObj.carryBit == undefined || assObj.carryBit == null){assObj.carryBit = '四舍五入';};
+            assList.push(assObj);
+        }
+        // 修改
+        else{ assList[args.row] = assObj; };
+        rationOprObj.mixUpdateRequest([me.ration], [], [], function () {
+            me.sheet.getParent().focus(true);
+        });
+        sheetCommonObj.cleanData(me.sheet, me.setting, -1);
+        //sheetCommonObj.setStaticCombo(me.sheet, 0, 5, assList.length, me.setting.comboItems, false, false);
+        sheetCommonObj.setDynamicCombo(me.sheet, 0, 5, me.sheet.getRowCount(), me.setting.comboItems, false, false);
+        sheetCommonObj.showData(me.sheet, me.setting, assList);
+    },
+
+    onRangeChanged: function(sender, args) {
+        if (args.action == GC.Spread.Sheets.RangeChangedAction.clear) {
+            if (!confirm(`确定要删除选中的 ${args.rowCount} 条辅助定额吗?`)){return; }
+
+            var me = rationAssistOprObj;
+            if (!me.ration) {return;};
+            var assList = me.ration.rationAssList;
+            for (var i = args.rowCount - 1; i >= 0; i--) {
+                if (args.row + i < assList.length) {
+                    assList.splice(args.row + i, 1);
+                };
+            };
+
+            rationOprObj.mixUpdateRequest([me.ration], [], []);
+            sheetCommonObj.cleanSheet(me.sheet, me.setting, -1);
+            sheetCommonObj.showData(me.sheet, me.setting, assList);
+        };
+    },
+    bindRationAssDel: function () {
+        let me = rationAssistOprObj;
+        let workBook = me.sheet.getParent();
+        workBook.commandManager().register('rationAssDel', function () {
+            let sels = me.sheet.getSelections(), isUpdate = false;
+            if(me.ration){
+                let curCahe = me.ration.rationAssList;
+                for(let i = 0, len = sels.length; i < len; i ++ ){
+                    if(sels[i].colCount === me.setting.header.length){
+                        if(sels[i].row < curCahe.length){
+                            isUpdate = true;
+                            curCahe.splice(sels[i].row, sels[i].rowCount);
+                        }
+                    }
+                }
+                if(isUpdate){
+                    rationOprObj.mixUpdateRequest([me.ration], [], [], function () {
+                        workBook.focus(true);
+                    });
+                    sheetCommonObj.cleanData(me.sheet, me.setting, -1);
+                    //sheetCommonObj.setStaticCombo(me.sheet, 0, 5, curCahe.length, me.setting.comboItems, false);
+                    sheetCommonObj.setDynamicCombo(me.sheet, 0, 5, me.sheet.getRowCount(), me.setting.comboItems, false);
+                    sheetCommonObj.showData(me.sheet, me.setting, curCahe);
+                }
+            }
+        });
+        workBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false);
+        workBook.commandManager().setShortcutKey('rationAssDel', GC.Spread.Commands.Key.del, false, false, false, false);
+    },
+
+    getAssItems: function(ration) {
+        var me = this;
+        me.ration = ration;
+
+        sheetCommonObj.cleanSheet(me.sheet, me.setting, -1);
+        sheetCommonObj.unShieldAllCells(me.sheet);
+
+        if (ration == undefined || ration.rationAssList == undefined ||
+            ration.rationAssList.length == 0){
+            //sheetCommonObj.setStaticCombo(me.sheet, 0, 5, 0, me.setting.comboItems, false);
+            sheetCommonObj.setDynamicCombo(me.sheet, 0, 5, me.sheet.getRowCount(), me.setting.comboItems, false, false);
+            return;
+        }
+        else {
+            //sheetCommonObj.setStaticCombo(me.sheet, 0, 5, ration.rationAssList.length, me.setting.comboItems, false);
+            sheetCommonObj.setDynamicCombo(me.sheet, 0, 5, me.sheet.getRowCount(), me.setting.comboItems, false, false);
+        }
+        sheetCommonObj.showData(me.sheet, me.setting, ration.rationAssList);
+    }
+}

+ 324 - 0
web/building_saas/complementary_ration_lib/js/ration_coe.js

@@ -0,0 +1,324 @@
+/**
+ * Created by CSL on 2017-06-08.
+ */
+ //modified by zhong on 2017-09-25
+var rationCoeOprObj = {
+    sheet: null,
+    libID: null,
+    curRation: null,
+    tempDelArr: [],
+    cache: {},
+    setting: {
+        header:[
+            {headerName:"编号",headerWidth:120,dataCode:"serialNo", dataType: "Number", hAlign: 'left'},
+            {headerName:"名称",headerWidth:400,dataCode:"name", dataType: "String", hAlign: 'left'},
+            {headerName:"内容",headerWidth:300,dataCode:"content", dataType: "String", hAlign: 'left'}
+        ],
+        view:{
+            comboBox:[],
+            lockColumns:[1,2]
+        }
+    },
+
+    buildSheet: function(sheet) {
+        var me = this;
+        me.sheet = sheet;
+        me.libID = storageUtil.getSessionCache("RationGrp","repositoryID"); // 不可靠,有时取不到
+        if (me.libID == undefined){me.libID = getQueryString('repository')};
+        sheetCommonObj.initSheet(me.sheet, me.setting, 30);
+        me.sheet.bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting);
+        me.sheet.bind(GC.Spread.Sheets.Events.ClipboardPasted, me.onClipboardPasted);
+        me.sheet.bind(GC.Spread.Sheets.Events.EditStarting, me.onEditStarting);
+        me.sheet.bind(GC.Spread.Sheets.Events.EditEnded, me.onEditEnded);
+       // me.sheet.bind(GC.Spread.Sheets.Events.RangeChanged, me.onRangeChanged);
+    },
+
+    onClipboardPasting: function(sender, args) {
+        var me = rationCoeOprObj;
+        let rationSection = rationOprObj.getCache();
+        let rationRow = rationOprObj.workBook.getSheet(0).getSelections()[0].row;
+        me.curRation = rationRow < rationSection.length ? rationSection[rationRow] : null;
+        if (args.cellRange.colCount != 1 || args.cellRange.col != 0 || !(me.curRation)) {
+            args.cancel = true;
+        }
+    },
+
+    onClipboardPasted: function(e, info) {
+        var me = rationCoeOprObj;
+        if (me.libID) {
+            // 修改第一列(编号)
+            if (info.cellRange.col == 0) {
+                me.tempDelArr = [];
+                var coeNos = [];
+                var items = sheetCommonObj.analyzePasteData({header:[{dataCode: "serialNo"}] }, info);
+                let curCache = typeof me.cache["_Coe_" + me.curRation.ID] !== 'undefined' ? me.cache["_Coe_" + me.curRation.ID] : [];
+                let isRefresh = false;
+                for(let i = 0, len = items.length; i < len; i++){
+                    if(!isNaN(items[i].serialNo)){
+                        let row = i + info.cellRange.row;
+                        //update
+                        if(row < curCache.length){
+                            let isExist = false;
+                            for(let j = 0, jLen = curCache.length; j < jLen; j++){
+                                if(items[i].serialNo === curCache[j].serialNo && j !== row){
+                                    isExist = true;
+                                    break;
+                                }
+                            }
+                            if(!isExist){
+                                me.tempDelArr.push({org: curCache[row], newNo: items[i].serialNo});
+                                coeNos.push(items[i].serialNo);
+                            }
+                            else{
+                                isRefresh = true;
+                            }
+                        }
+                        else{
+                            coeNos.push(items[i].serialNo);
+                        }
+                    }
+                }
+                //delete in front
+                if(me.tempDelArr.length > 0){
+                   for(let i = 0, len = me.tempDelArr.length; i < len; i++){
+                       for(let j = 0; j < curCache.length; j++){
+                           if(me.tempDelArr[i].org.serialNo === curCache[j].serialNo){
+                               curCache.splice(j, 1);
+                               break;
+                           }
+                       }
+                   }
+                }
+                me.addCoeItems(coeNos);
+                if(isRefresh){
+                    me.showCoeItems(me.curRation.ID);
+                }
+            } else {
+                //修改其它列。
+            }
+        }
+    },
+    onEditStarting: function (sender, args) {
+        let me = rationCoeOprObj;
+        let rationSection = rationOprObj.getCache();
+        let rationRow = rationOprObj.workBook.getSheet(0).getSelections()[0].row;
+        me.curRation = rationRow < rationSection.length ? rationSection[rationRow] : null;
+        if(!me.curRation || args.col !== 0){
+            args.cancel = true;
+        }
+
+    },
+    onEditEnded: function(sender, args){
+        var me = rationCoeOprObj;
+        if (args.col == 0 && args.editingText && args.editingText.toString().trim().length > 0 && !isNaN(args.editingText)) {   // 编号列
+            let curCahe = typeof me.cache["_Coe_" + me.curRation.ID] !== 'undefined' ? me.cache["_Coe_" + me.curRation.ID] : [];
+            me.tempDelArr = [];
+            //update
+            if(args.row < curCahe.length && args.editingText != curCahe[args.row].serialNo){
+                let isExist = false;
+                for(let i = 0, len = curCahe.length; i < len; i++){
+                    if(args.editingText == curCahe[i].serialNo){
+                        isExist = true;
+                        break;
+                    }
+                }
+                if(!isExist){
+                    me.tempDelArr.push({org: curCahe[args.row], newNo: args.editingText});
+                    curCahe.splice(args.row, 1);
+                    me.addCoeItems([args.editingText]);
+                }
+                else{
+                    me.showCoeItems(me.curRation.ID);
+                }
+            }
+            //insert
+            else{
+                me.addCoeItems([args.editingText]);
+            }
+        }
+        else{
+            sheetCommonObj.cleanData(me.sheet, me.setting, -1);
+            me.showCoeItems(me.curRation.ID);
+        }
+    },
+
+    bindRationCoeDel: function () {
+        let me = rationCoeOprObj;
+        let workBook = me.sheet.getParent();
+        workBook.commandManager().register('rationCoeDel', function () {
+            let sels = me.sheet.getSelections(), isUpdate = false;
+            let curCahe = me.cache["_Coe_" + me.curRation.ID];
+            for(let i = 0, len = sels.length; i < len; i ++ ){
+                if(sels[i].colCount === me.setting.header.length){
+                    if(sels[i].row < curCahe.length){
+                        isUpdate = true;
+                        curCahe.splice(sels[i].row, sels[i].rowCount);
+                    }
+                }
+            }
+            if(isUpdate){
+                me.updateCurRation(function () {
+                    me.sheet.getParent().focus(true);
+                });
+                sheetCommonObj.cleanData(me.sheet, me.setting, -1);
+                me.showCoeItems(me.curRation.ID);
+            }
+        });
+        workBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false);
+        workBook.commandManager().setShortcutKey('rationCoeDel', GC.Spread.Commands.Key.del, false, false, false, false);
+    },
+    getRecoveryArr: function (tempDelArr, newArr) {//获得更新的coe不存在,恢复删除的被更新数据
+        let rst = [];
+        for(let i = 0, len = tempDelArr.length; i < len; i++){
+            let isExist = false;
+            for(let j = 0, jLen = newArr.length; j < jLen; j++){
+                if(tempDelArr[i].newNo == newArr[j].serialNo){
+                    isExist = true;
+                    break;
+                }
+            }
+            if(!isExist){
+                rst.push(tempDelArr[i].org);
+            }
+        }
+        return rst;
+    },
+    addCoeItems: function(coeNos) {
+        var me = this;
+        sheetCommonObj.cleanData(me.sheet, me.setting, -1);
+
+        var curCache = me.cache["_Coe_" + me.curRation.ID];
+        var temp = [];
+        if (curCache) {
+            for (var i = 0; i < coeNos.length; i++) {
+                var isExist = false;
+                for (let obj of curCache) {
+                    if (obj.serialNo == coeNos[i]) {
+                        isExist = true;
+                        break;
+                    };
+                };
+                if (!isExist) {
+                    temp.push(coeNos[i]);
+                };
+            };
+        }else{
+            for (let obj of coeNos){temp.push(obj)};
+        };
+
+        if(temp.length == 0){
+            me.showCoeItems(me.curRation.ID);
+            //sheetCommonObj.lockCells(me.sheet, me.setting);
+        }else{
+            $.ajax({
+                type:"POST",
+                url:"api/getCoeItemsByNos",
+                data: {"data": JSON.stringify({"libID": me.libID, "coeNos": temp})},
+                dataType:"json",
+                cache:false,
+                timeout:5000,
+                success:function(result){
+                    if (result) {
+                        var rstArr = [];
+                        for (let obj of result.data){rstArr.push(obj)};
+                        if (curCache) {
+                            curCache = curCache.concat(rstArr);
+                        }else{
+                            curCache = rstArr;
+                        }
+                        let recoveryArr = me.getRecoveryArr(me.tempDelArr, result.data);
+                        if(recoveryArr.length > 0){
+                            curCache = curCache.concat(recoveryArr);
+                        }
+                        me.cache["_Coe_" + me.curRation.ID] = curCache;
+                        me.updateCurRation(function () {
+                            me.sheet.getParent().focus(true);
+                        });
+                        me.showCoeItems(me.curRation.ID);
+                    };
+                    //sheetCommonObj.lockCells(me.sheet, me.setting);
+                },
+                error:function(err){
+                    alert(err);
+                }
+            });
+        };
+    },
+
+    getCoeItems: function(ration, callback) {
+        var me = this;
+        me.curRation = ration;
+
+        /*if (ration == undefined || ration.rationCoeList == undefined ||
+            ration.rationCoeList.length == 0){return;};*/
+
+        var coeList = ration.rationCoeList;
+        var curCache = me.cache["_Coe_" + ration.ID];
+        if (curCache) {
+            me.showCoeItems(ration.ID);
+            //sheetCommonObj.lockCells(me.sheet, me.setting);
+        } else if(!curCache && typeof coeList !== 'undefined' && coeList.length > 0) {
+            var data = {"libID": me.libID, "coeIDs": coeList};
+            $.ajax({
+                type:"POST",
+                url:"api/getCoeItemsByIDs",
+                data: {"data": JSON.stringify(data)},
+                dataType:"json",
+                cache:false,
+                timeout:5000,
+                success:function(result){
+                    sheetCommonObj.cleanData(me.sheet, me.setting, -1);
+                    if (result.data) {
+                        var tempResult = [];
+                        for (let obj of result.data) {
+                            tempResult.push(obj);
+                        };
+
+                        me.cache["_Coe_" + ration.ID] = tempResult;
+
+                        me.showCoeItems(ration.ID);
+                    }
+                    //sheetCommonObj.lockCells(me.sheet, me.setting);
+                    if(callback) callback();
+                },
+                error:function(err){
+                    alert(err);
+                }
+            });
+        };
+    },
+
+    showCoeItems: function(rationID) {
+        var me = this;
+        var curCache = me.cache["_Coe_" + rationID];
+        if (curCache) {
+            curCache.sort(function(a, b) {
+                var rst = 0;
+                if (a.serialNo > b.serialNo) rst = 1
+                else if (a.serialNo < b.serialNo) rst = -1;
+                return rst;
+            });
+            sheetsOprObj.showData(me.sheet, me.setting, curCache);
+        }
+    },
+
+    updateCurRation: function(callback) {
+        var me = this, updateArr = [];
+        if (me.curRation) {
+            var rst = [];
+            var curCache = me.cache["_Coe_" + me.curRation.ID];
+            if (curCache) {
+                for (let obj of curCache) {
+                    rst.push(obj.ID);
+                };
+                me.curRation.rationCoeList = rst;
+                updateArr.push(me.curRation);
+                rationOprObj.mixUpdateRequest(updateArr, [], [], function () {
+                    if(callback) callback();
+                });
+            };
+        };
+    }
+}
+
+

+ 576 - 0
web/building_saas/complementary_ration_lib/js/ration_glj.js

@@ -0,0 +1,576 @@
+/**
+ * Created by Tony on 2017/4/28.
+ */
+var rationGLJOprObj = {
+    sheet: null,
+    currentRationItem: null,
+    distTypeTree: null,
+    activeCell: null,
+    tempCacheArr: [],//被更新的工料机,若更新的工料机不存在,则恢复
+    cache: {},
+    setting: {
+        header:[
+            {headerName:"编码",headerWidth:120,dataCode:"code", dataType: "String", formatter: "@"},
+            {headerName:"名称",headerWidth:400,dataCode:"name", dataType: "String"},
+            {headerName:"规格型号",headerWidth:120,dataCode:"specs", dataType: "String"},
+            {headerName:"单位",headerWidth:160,dataCode:"unit", dataType: "String", hAlign: "center", vAlign: "center"},
+            {headerName:"基价单价",headerWidth:160, dataCode:"basePrice", dataType: "Number", formatter:"0.00",  precision: 2},
+            {headerName:"定额消耗",headerWidth:160, dataCode:"consumeAmt", dataType: "Number", formatter: "0.000", precision: 3},
+            {headerName:"类型",headerWidth:160,dataCode:"gljType", dataType: "String", hAlign: "center", vAlign: "center"}
+        ],
+        view:{
+            comboBox:[],
+            lockColumns:[1,2,3,4,6]
+        }
+    },
+    getDistTypeTree: function (gljDistType) {
+        let me = this;
+        let distType;
+        let distTypeTree = {
+            prefix : 'gljDistType',
+            distTypes: {},
+            comboDatas: [],
+            distTypesArr: []
+        };
+        gljDistType.forEach(function (typeData) {
+            let typeObj = {
+                data: typeData,
+                children: [],
+                parent: null
+            }
+            distTypeTree.distTypes[distTypeTree.prefix + typeData.ID] = typeObj;
+            distTypeTree.distTypesArr.push(typeObj);
+        });
+        gljDistType.forEach(function (typeData) {
+            distType = distTypeTree.distTypes[distTypeTree.prefix + typeData.ID];
+            let parent = distTypeTree.distTypes[distTypeTree.prefix + typeData.ParentID];
+            if(parent){
+                distType.parent = parent;
+                parent.children.push(distType);
+            }
+        });
+        distTypeTree.distTypesArr.forEach(function (distTypeObj) {
+            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 === '机械'){
+                distTypeTree.comboDatas.push({text: distTypeObj.data.fullName, value: distTypeObj.data.ID});
+            }
+        });
+        return distTypeTree;
+    },
+    getGljDistType: function (callback) {
+        let me = this;
+        $.ajax({
+            type: 'post',
+            url: "api/getGljDistType",
+            dataType: 'json',
+            success: function (result) {
+                if(!result.error && callback){
+                    me.distTypeTree = me.getDistTypeTree(result.data);
+                    callback();
+                }
+            }
+        })
+    },
+    buildSheet: function(sheet) {
+        var me = this;
+        me.sheet = sheet;
+        me.getGljDistType(function () {
+           // me.onContextmenuOpr();
+            sheetCommonObj.initSheet(me.sheet, me.setting, 30);
+            me.bindRationGljDelOpr();
+            me.sheet.bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting);
+            me.sheet.bind(GC.Spread.Sheets.Events.ClipboardPasted, me.onClipboardPasted);
+            me.sheet.bind(GC.Spread.Sheets.Events.EditStarting, me.onEditStarting);
+            me.sheet.bind(GC.Spread.Sheets.Events.EditEnded, me.onCellEditEnd);
+        });
+    },
+    bindRationGljDelOpr: function () {
+        let me = rationGLJOprObj, spreadBook = me.sheet.getParent();
+        spreadBook.commandManager().register('rationGljDelete', function () {
+            let sels = me.sheet.getSelections(), lockCols = me.setting.view.lockColumns;
+            let cacheSection = me.cache["_GLJ_" + me.currentRationItem.ID], isUpdate = false;
+            if(sels.length > 0){
+                for(let sel = 0; sel < sels.length; sel++){
+                    if(sels[sel].colCount === me.setting.header.length){
+                        if(cacheSection && sels[sel].row < cacheSection.length){
+                            isUpdate = true;
+                            cacheSection.splice(sels[sel].row, sels[sel].rowCount);
+                        }
+                    }
+                    else{
+                         if(sels[sel].col !== 0 && sels[sel].col !== 5 && !(sels[sel].col === 1 && sels.col + sels[sel].colCount -1 === 3)){
+                            if(cacheSection){
+                                for(let i = sels[sel].row === -1 ? 1 : 0; i < sels[sel].rowCount; i++){
+                                    if(sels[sel].row + i < cacheSection.length){
+                                        for(let col = sels[sel].col; col <= sels[sel].col + sels[sel].colCount - 1; col++){
+                                            if(lockCols.indexOf(col) === -1){
+                                                isUpdate = true;
+                                                cacheSection[sels[sel].row + i][me.setting.header[col].dataCode] = 0;
+                                                me.sheet.setValue(sels[sel].row + i, col, 0.00);
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            if(isUpdate){
+                me.updateRationItem(function () {
+                    me.sheet.getParent().focus(true);
+                });
+                sheetCommonObj.cleanData(me.sheet, me.setting, -1);
+                me.showGljItems(me.currentRationItem.ID);
+            }
+        });
+        spreadBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false);
+        spreadBook.commandManager().setShortcutKey('rationGljDelete', GC.Spread.Commands.Key.del, false, false, false, false);
+    },
+    onClipboardPasting: function(sender, args) {
+        var me = rationGLJOprObj;
+        let rationSection = rationOprObj.getCache();
+        let rationRow = rationOprObj.workBook.getSheet(0).getSelections()[0].row;
+        me.currentRationItem = rationRow < rationSection.length ? rationSection[rationRow] : null;
+        if(me.currentRationItem && typeof me.cache["_GLJ_" + me.currentRationItem.ID] === 'undefined'){
+            me.cache["_GLJ_" + me.currentRationItem.ID] = [];
+        }
+        if (!(args.cellRange.col === 0 || args.cellRange.col === 5) || !(me.currentRationItem)) {
+            args.cancel = true;
+        }
+    },
+    onClipboardPasted: function(e, info) {
+        var me = rationGLJOprObj, repId = storageUtil.getSessionCache("RationGrp","repositoryID");
+        me.tempCacheArr = [];
+        if (repId) {
+            let gljLibId = storageUtil.getSessionCache("gljLib", "repositoryID_" + repId);
+            if(gljLibId){
+                if (info.cellRange.col == 0) {
+                    let cacheArr = me.cache["_GLJ_" + me.currentRationItem.ID];
+                    var tmpCodes = sheetCommonObj.analyzePasteData({header:[{dataCode: "code"}] }, info);
+                    var codes = [];
+                    for (var i = 0; i < tmpCodes.length; i++) {
+                        let rowIdx = info.cellRange.row + i;
+                        if(rowIdx < cacheArr.length){//更新
+                            me.tempCacheArr.push({org: cacheArr[rowIdx], newCode: tmpCodes[i].code});
+                            cacheArr.splice(rowIdx--, 1);
+                        }
+                        codes.push(tmpCodes[i].code);
+                    }
+                    me.addGljItems(codes, gljLibId, info.cellRange);
+                } else {
+                    //修改用量
+                    if(me.cache["_GLJ_" + me.currentRationItem.ID] && info.cellRange.row < me.cache["_GLJ_" + me.currentRationItem.ID].length){
+                        let tempConsumes = sheetCommonObj.analyzePasteData(me.setting, info);
+                        let maxCount = info.cellRange.row + info.cellRange.rowCount -1 > me.cache["_GLJ_" + me.currentRationItem.ID].length -1 ?
+                        me.cache["_GLJ_" + me.currentRationItem.ID].length - info.cellRange.row : info.cellRange.rowCount;
+                        for(let i = 0; i < maxCount; i++){
+                            let roundCons = scMathUtil.roundTo(tempConsumes[i].consumeAmt, -3);
+                            me.cache["_GLJ_" + me.currentRationItem.ID][info.cellRange.row + i].consumeAmt = roundCons;
+                        }
+                        me.updateRationItem(function () {
+                            me.sheet.getParent().focus(true);
+                        });
+                        if(info.cellRange.row + info.cellRange.rowCount -1 >= me.cache["_GLJ_" + me.currentRationItem.ID].length -1){
+                            me.sheet.suspendPaint();
+                            for(let rowIdx = me.cache["_GLJ_" + me.currentRationItem.ID].length; rowIdx <= info.cellRange.row + info.cellRange.rowCount -1; rowIdx++){
+                                me.sheet.setValue(rowIdx, info.cellRange.col, '');
+                            }
+                            me.sheet.resumePaint();
+                        }
+                    }
+                    else if(info.cellRange.row >= me.cache["_GLJ_" + me.currentRationItem.ID].length){
+                        me.sheet.suspendPaint();
+                        for(let rowIdx = info.cellRange.row; rowIdx <= info.cellRange.row + info.cellRange.rowCount -1; rowIdx ++){
+                            me.sheet.setValue(rowIdx, info.cellRange.col, '');
+                        }
+                        me.sheet.resumePaint();
+                    }
+                }
+            }
+        }
+    },
+    onEditStarting: function (sender, args) {
+        let me = rationGLJOprObj;
+        let rationSection = rationOprObj.getCache();
+        let rationRow = rationOprObj.workBook.getSheet(0).getSelections()[0].row;
+        me.currentRationItem = rationRow < rationSection.length ? rationSection[rationRow] : null;
+        if(me.currentRationItem && typeof me.cache["_GLJ_" + me.currentRationItem.ID] === 'undefined'){
+            me.cache["_GLJ_" + me.currentRationItem.ID] = [];
+        }
+        if(!me.currentRationItem){
+            args.cancel = true;
+        }
+        else {
+            if(args.col !== 0 && args.col !== 5 || args.col === 5 && args.row >= me.cache["_GLJ_" + me.currentRationItem.ID].length){
+                args.cancel = true;
+            }
+        }
+    },
+    onCellEditEnd: function(sender, args){
+        var me = rationGLJOprObj;
+        if(me.currentRationItem) {
+            var cacheArr = me.cache["_GLJ_" + me.currentRationItem.ID];
+            me.tempCacheArr = [];
+            if (args.col != 0) {
+                if (args.row < cacheArr.length) {
+                    var editGlj = cacheArr[args.row];
+                    if (editGlj["consumeAmt"] != args.editingText) {
+                        let parseNum = parseFloat(args.editingText);
+                        if (isNaN(parseFloat(args.editingText))) {
+                            $('#alertModalBtn').click();
+                            $('#alertText').text("定额消耗只能输入数值!");
+                            $('#alertModalCls').click(function () {
+                                args.sheet.setValue(args.row, args.col, editGlj['consumeAmt']);
+                            });
+                            $('#alertModalCof').click(function () {
+                                args.sheet.setValue(args.row, args.col, editGlj['consumeAmt']);
+                            })
+                        }
+                        else {
+                            args.sheet.setValue(args.row, args.col, parseNum);
+                            let roundNum = scMathUtil.roundTo(parseNum, -3);
+                            editGlj["consumeAmt"] = roundNum;
+                            me.updateRationItem(function () {
+                                me.sheet.getParent().focus(true);
+                            });
+                        }
+                    }
+                }
+            } else {
+                if (args.editingText && args.editingText.toString().trim().length !== 0) {
+                    let isExist = false;
+                    for (let i = 0, len = cacheArr.length; i < len; i++) {
+                        if (cacheArr[i].code === args.editingText && i !== args.row) {
+                            isExist = true;
+                            break;
+                        }
+                    }
+                    if (isExist) {
+                        alert("该工料机已存在!");
+                        args.sheet.setValue(args.row, args.col, typeof cacheArr[args.row] !== 'undefined' ? cacheArr[args.row].code + '' : '');
+                    }
+                    else {
+                        if (args.row < cacheArr.length && args.editingText !== cacheArr[args.row].code) {//更新
+                            me.tempCacheArr.push({org: cacheArr[args.row], newCode: args.editingText.toString().trim()});
+                            cacheArr.splice(args.row, 1);
+                            let rationRepId = storageUtil.getSessionCache("RationGrp", "repositoryID");
+                            let gljLibID = storageUtil.getSessionCache("gljLib", "repositoryID_" + rationRepId);
+                            let codes = [];
+                            codes.push(args.editingText.toString().trim());
+                            me.addGljItems(codes, gljLibID, args);
+                        }
+                        else if (args.row >= cacheArr.length) {//新增
+                            let rationRepId = storageUtil.getSessionCache("RationGrp", "repositoryID");
+                            let gljLibID = storageUtil.getSessionCache("gljLib", "repositoryID_" + rationRepId);
+                            if (gljLibID) {
+                                var codes = [];
+                                codes.push(args.editingText.toString().trim());
+                                me.addGljItems(codes, gljLibID, args);
+                            }
+                        }
+                    }
+                }
+                else {
+                    args.sheet.setValue(args.row, args.col, args.row < cacheArr.length ? cacheArr[args.row].code : '');
+                }
+            }
+        }
+        else {
+            args.sheet.setValue(args.row, args.col, '');
+        }
+    },
+    onContextmenuOpr: function () {
+        let me = rationGLJOprObj;
+        $.contextMenu({
+            selector: '#rdSpread',
+            build: function ($triggerElement, e) {
+                //控制允许右键菜单在哪个位置出现
+                let sheet = me.sheet;
+                let offset = $triggerElement.offset(),
+                    x = e.pageX - offset.left,
+                    y = e.pageY - offset.top;
+                let target = sheet.hitTest(x, y);
+                if(sheet.parent.getActiveSheetIndex() === 0 && target.hitTestType === 3 && typeof target.row !== 'undefined' && typeof target.col !== 'undefined'){
+                    let delDis = true, cacheSection;
+                    sheet.setActiveCell(target.row, target.col);
+                    if(me.currentRationItem){
+                        let cacheSection = me.cache["_GLJ_" + me.currentRationItem.ID];
+                        if(target.row < cacheSection.length){
+                            delDis = false;
+                        }
+                    }
+                    return {
+                        callback: function(key, options) {
+                        },
+                        items: {
+                            "delete": {name: "删除", icon: 'fa-remove', disabled: delDis, callback: function (key, opt) {
+                                cacheSection.splice(target.row, 1);
+                                me.updateRationItem(function () {
+                                    me.sheet.getParent().focus(true);
+                                });
+                                sheetCommonObj.cleanData(me.sheet, me.setting, -1);
+                                me.showGljItems(me.currentRationItem.ID);
+                            }}
+                        }
+                    };
+                }
+                else{
+                    return false;
+                }
+            }
+        });
+    },
+    getRecoveryArr: function (tempDelArr, newArr) {//获得更新的code不存在,恢复删除的被更新数据
+        let rst = [];
+        for(let i = 0, len = tempDelArr.length; i < len; i++){
+            let isExist = false;
+            for(let j = 0, jLen = newArr.length; j < jLen; j++){
+                if(tempDelArr[i].newCode == newArr[j].code){
+                    isExist = true;
+                    break;
+                }
+            }
+            if(!isExist){
+                rst.push(tempDelArr[i].org);
+            }
+        }
+        return rst;
+    },
+    addGljItems: function(codes, repId, args) {
+        var me = this;
+        $.ajax({
+            type:"POST",
+            url:"api/getGljItemsByCodes",
+            data:{"gljCodes": JSON.stringify(codes), repId: repId},
+            dataType:"json",
+            cache:false,
+            timeout:5000,
+            success:function(result){
+                if (result) {
+                    if(result.data.length > 0){
+                        sheetCommonObj.cleanData(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]);
+                                }
+                            }
+                            me.cache["_GLJ_" + me.currentRationItem.ID] = cacheArr.concat(newAddArr);
+                            let recoveryArr = me.getRecoveryArr(me.tempCacheArr, result.data);
+                            if(recoveryArr.length > 0){
+                                me.cache["_GLJ_" + me.currentRationItem.ID] = me.cache["_GLJ_" + me.currentRationItem.ID].concat(recoveryArr);
+                            }
+                            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(function () {
+                                me.sheet.getParent().focus(true);
+                            });
+                        }
+                    }
+                    else{
+                        let cacheArr = me.cache["_GLJ_" + me.currentRationItem.ID]?  me.cache["_GLJ_" + me.currentRationItem.ID] : [];
+                        let recoveryArr = me.getRecoveryArr(me.tempCacheArr, []);
+                        if(recoveryArr.length > 0){
+                            me.cache["_GLJ_" + me.currentRationItem.ID] = cacheArr.concat(recoveryArr);
+                        }
+                        //更新的工料机不存在
+                        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;
+                        });
+                        $('#alertModalBtn').click();
+                        $('#alertText').text("工料机"+ codes + "不存在,请查找你所需要的工料机,或新增工料机");
+                        $('#alertModalCls').click(function () {
+                            me.showGljItems(me.currentRationItem.ID);
+                        });
+                        $('#alertModalCof').click(function () {
+                            me.showGljItems(me.currentRationItem.ID);
+                        })
+                    }
+                }
+            },
+            error:function(err){
+                alert(err);
+            }
+        })
+    },
+    round(v, e){
+        var t=1;
+        for(;e>0;t*=10,e--);
+        for(;e<0;t/=10,e++);
+        return Math.round(v*t)/t;
+    },
+    rationCal: function () {
+        let me = rationGLJOprObj;
+        let price = {gljType1: [], gljType2: [], gljType3: []}, rst = {labourPrice: 0, materialPrice: 0, machinePrice: 0}, rationBasePrc = 0;
+        if(me.currentRationItem && me.cache['_GLJ_' + me.currentRationItem.ID]){
+            let cacheArr = me.cache['_GLJ_' + me.currentRationItem.ID];
+            cacheArr.forEach(function (gljData) {
+                if(gljData.gljType && gljData.basePrice && gljData.consumeAmt){
+                    let parent = me.distTypeTree.distTypes[me.distTypeTree.prefix + gljData.gljType].parent;
+                    if(parent && parent.data.ID <= 3){
+                        price['gljType' + parent.data.ID].push(scMathUtil.roundTo( gljData.basePrice * gljData.consumeAmt, -3));//取三位
+                    }
+                    if(!parent && gljData.gljType <= 3){
+                        price['gljType' + gljData.gljType].push(scMathUtil.roundTo( gljData.basePrice * gljData.consumeAmt, -3));//取三位
+                    }
+                }
+            });
+            if(price.gljType1.length > 0){
+                let labourPrice = 0;
+                price.gljType1.forEach(function (singlePrc) {
+                    labourPrice += singlePrc;
+                });
+                let roundPrice = scMathUtil.roundTo(labourPrice, -2);
+                rst.labourPrice = roundPrice;
+                rationBasePrc += roundPrice;
+            }
+            if(price.gljType2.length > 0){
+                let materialPrice = 0;
+                price.gljType2.forEach(function (singlePrc) {
+                    materialPrice += singlePrc;
+                });
+                let roundPrice = scMathUtil.roundTo(materialPrice, -2);
+                rst.materialPrice = roundPrice;
+                rationBasePrc += roundPrice;
+            }
+            if(price.gljType3.length > 0){
+                let machinePrice = 0;
+                price.gljType3.forEach(function (singlePrc) {
+                    machinePrice += singlePrc;
+                });
+                let roundPrice = scMathUtil.roundTo(machinePrice, -2);
+                rst.machinePrice = roundPrice;
+                rationBasePrc += roundPrice;
+            }
+            rst.rationBasePrc = rationBasePrc;
+        }
+        return rst;
+    },
+    updateRationItem: function(callback) {
+        var me = this, updateArr = [];
+        if (me.currentRationItem) {
+            me.currentRationItem.rationGljList = me.buildRationItemGlj();
+            //recalculate ration basePrice
+            let price = me.rationCal();
+            me.currentRationItem.labourPrice = price.labourPrice;
+            me.currentRationItem.materialPrice = price.materialPrice;
+            me.currentRationItem.machinePrice = price.machinePrice;
+            me.currentRationItem.basePrice = price.rationBasePrc;
+            updateArr.push(me.currentRationItem);
+            rationOprObj.mixUpdateRequest(updateArr, [], [], function () {
+                if(callback) callback();
+            });
+        }
+    },
+
+    buildRationItemGlj: function(){
+        var me = this, rst = [];
+        if (me.currentRationItem && me.cache["_GLJ_" + me.currentRationItem.ID]) {
+            var cacheArr = me.cache["_GLJ_" + me.currentRationItem.ID];
+            for (var i = 0; i < cacheArr.length; i++) {
+                rst.push({gljId: cacheArr[i].gljId, consumeAmt: cacheArr[i].consumeAmt, proportion: 0});
+            }
+        }
+        return rst;
+    },
+
+    createRationGljDisplayItem: function(rItem, repGlj) {
+        var rst = {};
+        rst.gljId = rItem.gljId;
+        rst.consumeAmt = rItem.consumeAmt;
+        rst.code = repGlj.code;
+        rst.name = repGlj.name;
+        rst.specs = repGlj.specs;
+        rst.unit = repGlj.unit;
+        rst.basePrice = repGlj.basePrice;
+        rst.gljType = repGlj.gljType;
+        return rst;
+    },
+    getGljItems: function(rationItem, callback) {
+        var me = this, rationID = rationItem.ID, rationGljList = rationItem.rationGljList;
+        me.currentRationItem = rationItem;
+        if (me.cache["_GLJ_" + rationID]) {
+            me.showGljItems(rationID);
+        } else {
+            var gljIds = [];
+            for (var i = 0; i < rationGljList.length; i++) {
+                gljIds.push(rationGljList[i].gljId);
+            }
+                $.ajax({
+                    type:"POST",
+                    url:"api/getGljItemsByIds",
+                    data:{"gljIds": JSON.stringify(gljIds)},
+                    dataType:"json",
+                    cache:false,
+                    timeout:5000,
+                    success:function(result){
+                        sheetCommonObj.cleanSheet(me.sheet, me.setting, -1);
+                        if (result) {
+                            var cacheArr = [];
+                            for (var i = 0; i < result.data.length; i++) {
+                                for (var j = 0; j < rationGljList.length; j++) {
+                                    if (rationGljList[j].gljId == result.data[i].ID) {
+                                        cacheArr.push(me.createRationGljDisplayItem(rationGljList[j], result.data[i]));
+                                        break;
+                                    }
+                                }
+                            }
+                            function compare(){
+                                return function (a, b) {
+                                    let rst = 0;
+                                    if (a.code > b.code) {
+                                        rst = 1;
+                                    }
+                                    else if (a.code < b.code) {
+                                        rst = -1;
+                                    }
+                                    return rst;
+                                }
+                            }
+                            cacheArr.sort(compare());
+                            me.cache["_GLJ_" + rationID] = cacheArr;
+                            me.showGljItems(rationID);
+                        }
+                        if(callback) callback();
+                    },
+                    error:function(err){
+                        alert(err);
+                    }
+                })
+        }
+    },
+    showGljItems: function(rationID) {
+        var me = this;
+        if (me.cache["_GLJ_" + rationID]) {
+            sheetCommonObj.cleanData(me.sheet, me.setting, -1);
+            sheetsOprObj.showData(me.sheet, me.setting, me.cache["_GLJ_" + rationID], me.distTypeTree);
+        }
+    }
+}

+ 984 - 0
web/building_saas/complementary_ration_lib/js/repository_glj.js

@@ -0,0 +1,984 @@
+/**
+ * Created by Tony on 2017/5/5.
+ */
+
+$("#drirect-dinge").click(function(){
+    $(this).attr('href', "/rationRepository/ration" + "?repository=" + getQueryString("repository"))
+});
+
+$("#fuzhu").click(function(){
+    $(this).attr('href', "/rationRepository/coeList" + "?repository=" + getQueryString("repository"))
+});
+
+var pageOprObj = {
+    rationLibName : null,
+    rationLibId: null,
+    initPage : function(container) {
+        var me = this, rationLibId = getQueryString("repository"),//获取定额库参数
+            rationLibName = storageUtil.getSessionCache("RationGrp","repositoryID_" + rationLibId);
+        me.rationLibId = rationLibId;
+        if (rationLibName) {
+            var html = $("#rationname")[0].outerHTML;
+            html = html.replace("XXX定额库", rationLibName);
+            $("#rationname")[0].outerHTML = html;
+            me.rationLibName = rationLibName;
+            repositoryGljObj.buildSheet(container);
+            repositoryGljObj.getRationGljIds(rationLibId);
+            repositoryGljObj.getGljDistType(function () {
+                repositoryGljObj.currentRepositoryId = parseInt(rationLibId);
+                //引用的工料机库
+                let gljLibID = storageUtil.getSessionCache("gljLib", "repositoryID_" + rationLibId);
+                if(gljLibID && typeof gljLibID !== 'undefined'){
+                    repositoryGljObj.getGljTree(gljLibID, function () {
+                        repositoryGljObj.getGljItems(gljLibID);
+                    });
+                }
+                sheetCommonObj.shieldAllCells(repositoryGljObj.workBook.getSheet(0), repositoryGljObj.setting);
+            });
+        }
+    }
+}
+repositoryGljObj = {
+    treeObj : null,
+    workBook: null,
+    gljCurTypeId: -1,
+    currentRepositoryId: -1,
+    currentCache: null,
+    parentNodeIds: {},
+    gljList: [],
+    distTypeTree: null,//add
+    setting: {
+        header:[
+            {headerName:"编码",headerWidth:120,dataCode:"code", dataType: "String", formatter: "@", hAlign: "left", vAlign: "center"},
+            {headerName:"名称",headerWidth:260,dataCode:"name", dataType: "String", hAlign: "left", vAlign: "center"},
+            {headerName:"规格型号",headerWidth:260,dataCode:"specs", dataType: "String", hAlign: "left", vAlign: "center"},
+            {headerName:"单位",headerWidth:120,dataCode:"unit", dataType: "String", hAlign: "center", vAlign: "center"},
+            {headerName:"定额价",headerWidth:120,dataCode:"basePrice", dataType: "Number", formatter: "0.00", hAlign: "right", vAlign: "center"},
+            {headerName:"类型",headerWidth:120,dataCode:"gljType", dataType: "String", hAlign: "center", vAlign: "center"}
+        ],
+        view:{
+            comboBox:[
+                {row:-1,col:3,rowCount:-1,colCount:1}
+            ],
+            lockedCells:[
+            ]
+        }
+    },
+    getComboData: function (gljDistType) {
+        let me = this;
+        let distType;
+        let distTypeTree = {
+            prefix : 'gljType',
+            distTypes: {},
+            comboDatas: [],
+            distTypesArr: []
+        };
+        gljDistType.forEach(function (typeData) {
+            let typeObj = {
+                data: typeData,
+                children: [],
+                parent: null
+            }
+            distTypeTree.distTypes[distTypeTree.prefix + typeData.ID] = typeObj;
+            distTypeTree.distTypesArr.push(typeObj);
+        });
+        gljDistType.forEach(function (typeData) {
+            distType = distTypeTree.distTypes[distTypeTree.prefix + typeData.ID];
+            let parent = distTypeTree.distTypes[distTypeTree.prefix + typeData.ParentID];
+            if(parent){
+                distType.parent = parent;
+                parent.children.push(distType);
+            }
+        });
+        distTypeTree.distTypesArr.forEach(function (distTypeObj) {
+            if(distTypeObj.data.fullName !== '材料'){
+                distTypeTree.comboDatas.push({text: distTypeObj.data.fullName, value: distTypeObj.data.ID});
+            }
+        });
+        return distTypeTree;
+    },
+    getGljDistType: function (callback) {
+        let me = this;
+        $.ajax({
+            type: 'post',
+            url: "api/getGljDistType",
+            dataType: 'json',
+            success: function (result) {
+                if(!result.error && callback){
+                    me.distTypeTree = me.getComboData(result.data);
+                    /*let combo = new GC.Spread.Sheets.CellTypes.ComboBox();
+                    combo.items(me.distTypeTree.comboDatas).editorValueType(GC.Spread.Sheets.CellTypes.EditorValueType.text);*/
+                    me.workBook.getSheet(0).getCell(-1, 5, GC.Spread.Sheets.SheetArea.viewport).value(me.distTypeTree.comboDatas[0].text);
+                    callback();
+                }
+            }
+        })
+    },
+    getGljTree: function(gljLibID, callback) {
+        var me = this;
+        $.ajax({
+            type:"POST",
+            url:"api/getGljTree",
+            data:{"gljLibID": gljLibID},
+            dataType:"json",
+            cache:false,
+            timeout:20000,
+            success:function(result,textStatus,status){
+                if(status.status == 200) {
+                    zTreeHelper.createTree(result.data, gljSetting, "repositoryTree", me);
+                    if (result.data && result.data.length > 0) {
+                        me.gljCurTypeId = result.data[0].ID;
+                    } else {
+                        gljTypeTreeOprObj.addRootNode();
+                    }
+                    callback();
+                }
+            },
+            error:function(err){
+                alert(err.responseJSON.error);
+            }
+        })
+    },
+    getGljItems: function(gljLibID) {
+        var me = this;
+        $.ajax({
+            type:"POST",
+            url:"api/getGljItems",
+            data:{"repositoryId": gljLibID},
+            dataType:"json",
+            cache:false,
+            timeout:5000,
+            success:function(result){
+                if(!result.error) {
+                    me.gljList = result.data;
+                    me.workBook.getSheet(0).setRowCount(result.data.length);
+                    me.sortGlj();
+                    let rootNode = me.treeObj.getNodes()[0];
+                    if(rootNode && rootNode.isParent && rootNode.isFirstNode){
+                        me.treeObj.selectNode(rootNode);
+                        gljTypeTreeOprObj.onClick(null, 'repositoryTree', rootNode);
+                    }
+                    //me.showGljItems(result.data, me.gljCurTypeId);
+                }
+            },
+            error:function(err){
+                alert(err.responseJSON.error);
+            }
+        })
+    },
+    showGljItems: function(data, type) {
+        var me = repositoryGljObj;
+        if (me.workBook) {
+            var cacheSection = [];
+            var pArr = me.parentNodeIds["_pNodeId_" + type];
+            for (var i = 0; i < data.length; i++) {
+                if (pArr && pArr.indexOf(data[i].gljClass) >= 0) {
+                    cacheSection.push(data[i]);
+                } else if (type == data[i].gljClass) {
+                    //data[i].gljDistType = me.distTypeTree.distTypes[me.distTypeTree.prefix + data[i].gljDistType].data.fullName;
+                    cacheSection.push(data[i]);
+                }
+            }
+            sheetCommonObj.cleanSheet(me.workBook.getSheet(0), me.setting, -1);
+            sheetsOprObj.showData(me.workBook.getSheet(0), me.setting, cacheSection, me.distTypeTree);
+
+            cacheSection = null;
+        }
+    },
+    buildSheet: function(container) {
+        var me = repositoryGljObj;
+        me.workBook = sheetCommonObj.buildSheet(container, me.setting, 30, me);
+        me.workBook.getSheet(0).options.isProtected = true;
+        /* 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.RangeChanged, me.onRangeChanged);
+         me.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.EnterCell, me.onEnterCell);*/
+    },
+    onEnterCell: function (sender, args) {
+        let me = repositoryGljObj;
+        me.cellRowIdx = args.row;
+        let isHasData = false;
+        if(me.addGljObj){
+            for(let i=0; i<me.setting.header.length; i++){
+                if(me.addGljObj[me.setting.header[i].dataCode]){
+                    isHasData = true;
+                    break;
+                }
+            }
+        }
+        if(isHasData){
+            if(me.editingRowIdx !== me.cellRowIdx) {
+                let isComple = true;
+                let focusToCol;
+                function getFocusToCol (me){
+                    if(!me.addGljObj[me.setting.header[0].dataCode]){
+                        $('#alertGljTxt').text('编号不能为空,是否取消增加工料机?');
+                        return 0;
+                    }
+                    else if(!me.addGljObj[me.setting.header[1].dataCode]){
+                        $('#alertGljTxt').text('名称不能为空,是否取消增加工料机?');
+                        return 1;
+                    }
+                    else if(!me.addGljObj[me.setting.header[5].dataCode]){
+                        $('#alertGljTxt').text('类型不能为空,是否取消增加工料机?');
+                        return 5;
+                    }
+                    else {
+                        return -1;
+                    }
+                }
+                focusToCol = getFocusToCol(me);
+                if(focusToCol === -1){
+
+                }
+                else {
+                    $('#gljAlertBtn').click();
+                    //me.workBook.getSheet(0).options.isProtected = true;
+                    sheetCommonObj.lockAllCells(args.sheet);
+                    $('#aleCanceBtn').click(function () {
+                        // me.workBook.getSheet(0).options.isProtected = false;
+                        sheetCommonObj.unLockAllCells(args.sheet);
+                        sheetsOprObj.reLockSomeCodes(args.sheet, 0, repositoryGljObj.currentCache.length);
+                        me.workBook.getSheet(0).setActiveCell(me.editingRowIdx, focusToCol);
+                    });
+                    $('#gljAleClose').click(function () {
+                        // me.workBook.getSheet(0).options.isProtected = false;
+                        sheetCommonObj.unLockAllCells(args.sheet);
+                        sheetsOprObj.reLockSomeCodes(args.sheet, 0, repositoryGljObj.currentCache.length);
+                        me.workBook.getSheet(0).setActiveCell(me.editingRowIdx, focusToCol);
+                    });
+                    $('#aleConfBtn').click(function () {
+                        // me.workBook.getSheet(0).options.isProtected = false;
+                        sheetCommonObj.unLockAllCells(args.sheet);
+                        sheetsOprObj.reLockSomeCodes(args.sheet, 0, repositoryGljObj.currentCache.length);
+                        me.addGljObj = null;
+                        for(let col=0; col<me.setting.header.length; col++){
+                            let field = me.setting.header[col].dataCode;
+                            if(field === 'gljType'){
+                                me.workBook.getSheet(0).getCell(me.editingRowIdx, col).value(
+                                    me.distTypeTree.distTypes[me.distTypeTree.prefix + me.currentEditingGlj[field]].data.fullName);
+                            }
+                            else{
+                                me.workBook.getSheet(0).getCell(me.editingRowIdx, col).value(me.currentEditingGlj[me.setting.header[col].dataCode]);
+                            }
+                        }
+                        me.workBook.getSheet(0).setActiveCell(me.editingRowIdx, 0);
+                    });
+                }
+            }
+        }
+    },
+    onCellEditStart: function(sender, args) {
+        var me = repositoryGljObj;
+        var rObj = sheetsOprObj.combineRowData(me.workBook.getSheet(0), me.setting, args.row);
+        me.currentEditingGlj = rObj;
+        me.orgCode = me.workBook.getSheet(0).getValue(args.row, 0);
+        var cacheSection = me.gljList;
+        if (cacheSection) {
+            for (var j = 0; j < cacheSection.length; j++) {
+                if (cacheSection[j][me.setting.header[0].dataCode] && cacheSection[j][me.setting.header[0].dataCode] == rObj[me.setting.header[0].dataCode]) {
+                    rObj["ID"] = cacheSection[j]["ID"];
+                    rObj.gljClass = cacheSection[j].gljClass;
+                    break;
+                }
+            }
+        }
+    },
+    onCellEditEnd: function(sender, args) {
+        var me = repositoryGljObj, rObj = sheetsOprObj.combineRowData(me.workBook.getSheet(0), me.setting, args.row, me),
+            updateArr = [], addArr = [], updateBasePrcArr = [];
+        me.editingRowIdx = args.row;
+        rObj.basePrice = rObj.basePrice ? rObj.basePrice : 0;
+        if (me.currentEditingGlj["ID"]) {
+            rObj["ID"] = me.currentEditingGlj["ID"];
+            rObj.gljClass = me.currentEditingGlj.gljClass;
+            for(let col =0; col< me.setting.header.length; col++){
+                if(me.currentEditingGlj[me.setting.header[col].dataCode] !== rObj[me.setting.header[col].dataCode]){
+                    me.addGljObj = rObj;
+                    if(rObj[me.setting.header[0].dataCode] && rObj[me.setting.header[1].dataCode] && rObj[me.setting.header[5].dataCode]){
+                        updateArr.push(rObj);
+                        break;
+                    }
+                }
+            }
+            if(me.currentEditingGlj.basePrice !== rObj.basePrice){
+                //update basePrice of ration when editting basePrice of glj
+                let gljType = -1;
+                let gljTypeParent = me.distTypeTree.distTypes[me.distTypeTree.prefix + me.currentEditingGlj.gljType].parent;
+                if(gljTypeParent && gljTypeParent.data.ID <=3){
+                    gljType = gljTypeParent.data.ID;
+                }
+                if(!gljTypeParent && me.currentEditingGlj.gljType <= 3){
+                    gljType = me.currentEditingGlj.gljType;
+                }
+                let gljBasePrcObj = {gljId: me.currentEditingGlj.ID, gljType: gljType, basePrice: rObj.basePrice};
+                if(gljBasePrcObj.gljType !== -1){
+                    updateBasePrcArr.push(gljBasePrcObj);
+                    me.updateRationBasePrcRq(updateBasePrcArr);
+                }
+            }
+            //update basePrice of ration when editting gljType of glj
+            if(me.currentEditingGlj.gljType !== rObj.gljType){
+                let gljTypeObj = {gljId: me.currentEditingGlj.ID, gljType: rObj.gljType, basePrice: rObj.basePrice};
+                updateBasePrcArr.push(gljTypeObj);
+                me.updateRationBasePrcRq(updateBasePrcArr);
+            }
+        } else {
+            me.addGljObj = rObj;
+            let isCanSav = true;
+            if(!rObj[me.setting.header[0].dataCode] || !rObj[me.setting.header[1].dataCode] || !rObj[me.setting.header[5].dataCode]){
+                isCanSav = false;
+            }
+            if(isCanSav){
+                me.addGljObj = null;
+                addArr.push(rObj);
+            }
+        }
+        if(me.gljCurTypeId !== 1){
+            rObj.gljClass = me.gljCurTypeId;
+        }
+        if(updateArr.length >0 || addArr.length >0){
+            me.currentEditingGlj = null;
+            //me.workBook.getSheet(0).setValue(11, 5, "人工");
+            me.mixUpdateRequest(updateArr, addArr, []);
+        }
+    },
+    repositoryGljDelOpr: function () {
+        let me = repositoryGljObj;
+        me.workBook.commandManager().register('repositoryGljDel', function () {
+            let sheet = me.workBook.getSheet(0),
+                updateArr = [], removeArr = [],
+                tempRemoveArr= [],
+                refGljCodes = [], //已被引用的工料机
+                updateBasePrcArr = [],//删除基价单位后重新计算
+                sels = sheet.getSelections(),
+                cacheSection = me.currentCache;
+            if(sels.length > 0 && cacheSection.length > 0){
+                for(let i = 0; i < sels.length; i++){
+                    if(sels[i].colCount === me.setting.header.length){
+                        for(let j = 0; j < sels[i].rowCount; j++){
+                            if(sels[i].row + j < cacheSection.length){
+                                tempRemoveArr.push({ID: cacheSection[sels[i].row + j].ID, code: cacheSection[sels[i].row + j].code});
+                            }
+                        }
+                    }
+                    else{
+                        let maxCol = sels[i].col + sels[i].colCount - 1;
+                        if(sels[i].col >= 2 && maxCol <= 4){
+                            for(let j = 0; j < sels[i].rowCount; j++){
+                                if(sels[i].row + j < cacheSection.length){
+                                    let updateObj = cacheSection[sels[i].row + j];
+                                    for(let col = sels[i].col; col <= maxCol; col++){
+                                        if(me.setting.header[col].dataCode === 'basePrice'){
+                                            updateObj[me.setting.header[col].dataCode] = 0;
+                                            updateBasePrcArr.push({gljId: updateObj.ID, gljType: updateObj.gljType, basePrice: 0});
+                                        }
+                                        else{
+                                            updateObj[me.setting.header[col].dataCode] = '';
+                                        }
+                                    }
+                                    updateArr.push(updateObj);
+                                }
+                            }
+                        }
+                        //编号、名称、类型不可为空
+                        else{
+                            if(sels[i].row < cacheSection.length){
+                                let text = '', cantNullStr =['编码', '名称', '类型'];
+                                for(let col = sels[i].col; col <= sels[i].col + sels[i].colCount -1; col++){
+                                    if(cantNullStr.indexOf(me.setting.header[col].headerName) !== -1){
+                                        text += me.setting.header[col].headerName + " ";
+                                    }
+                                }
+                                $('#alertText').text(text + "不可为空!");
+                                $('#codeAlertBtn').click();
+                                sheet.options.isProtected = true;
+                                $('#codAleConfBtn').click(function () {
+                                    sheetsOprObj.lockSomeCodes(sheet, 0, cacheSection.length);
+                                });
+                                $('#codAleClose').click(function () {
+                                    sheetsOprObj.lockSomeCodes(sheet, 0, cacheSection.length);
+                                });
+                            }
+                        }
+                    }
+                }
+                //提取已被引用工料机
+                if(tempRemoveArr.length > 0){
+                    for(let i = 0; i < tempRemoveArr.length; i++){
+                        if(me.rationGljIds.indexOf(tempRemoveArr[i].ID) !== -1){
+                            refGljCodes.push(tempRemoveArr[i].code);
+                            tempRemoveArr.splice(i--, 1);
+                        }
+                        else{
+                            removeArr.push(tempRemoveArr[i].ID);
+                        }
+                    }
+                }
+                //提示
+                if(refGljCodes.length > 0){
+                    let alertText;
+                    if(refGljCodes.length > 3){
+                        alertText = "编号: " + refGljCodes[0]+" 、" + refGljCodes[1] + " 、" + refGljCodes[2] + "...等工料机已有定额引用,删除失败!";
+                    }
+                    else {
+                        let alertCode = " ";
+                        for(let i=0; i< refGljCodes.length; i++){
+                            alertCode += refGljCodes[i] + " 、";
+                        }
+                        alertText = "编号:" + alertCode + "工料机已有定额引用,删除失败!"
+                    }
+                    $('#alertText').text(alertText);
+                    $('#codeAlertBtn').click();
+                    sheet.options.isProtected = true;
+                    $('#codAleConfBtn').click(function () {
+                        sheetsOprObj.lockSomeCodes(sheet, 0, cacheSection.length);
+                        if(removeArr.length > 0){
+                            me.mixUpdateRequest(updateArr, [], removeArr);
+                        }
+                    });
+                    $('#codAleClose').click(function () {
+                        sheetsOprObj.lockSomeCodes(sheet, 0, cacheSection.length);
+                        me.mixUpdateRequest(updateArr, [], removeArr);
+                    });
+                }
+                else if(removeArr.length > 0 || updateArr.length > 0){
+                    me.mixUpdateRequest(updateArr, [], removeArr);
+                    if(updateBasePrcArr.length > 0){
+                        me.updateRationBasePrcRq(updateBasePrcArr);
+                    }
+                }
+            }
+
+        });
+
+        me.workBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false);
+        me.workBook.commandManager().setShortcutKey('repositoryGljDel', GC.Spread.Commands.Key.del, false, false, false, false);
+    },
+    validUpdateObj: function (pasteObj, rowIdx) {
+        let rst = {}, backUpObj = {},
+            me = repositoryGljObj,
+            tempObj = me.currentCache[rowIdx],
+            reCalBasePrc = false, isValid = true;
+        //备份原始数据
+        for(let atr in tempObj){
+            backUpObj[atr] = tempObj[atr];
+        }
+        if(typeof pasteObj.code !== 'undefined'){
+            if(pasteObj.code.trim().length !== 0){
+                let isExist = false;
+                for(let i = 0; i < me.gljList.length; i++){
+                    if(me.gljList[i].code === pasteObj.code){
+                        isExist = true;
+                        break;
+                    }
+                }
+                if(!isExist){
+                    tempObj.code = pasteObj.code;
+                }
+                else isValid = false;
+            }
+            else isValid = false;
+        }
+        if(typeof pasteObj.name !== 'undefined'){
+            if(pasteObj.name.trim().length === 0) isValid = false;
+            else tempObj.name = pasteObj.name;
+        }
+        if(typeof pasteObj.specs !== 'undefined'){
+            tempObj.specs = pasteObj.specs;
+        }
+        if(typeof pasteObj.unit !== 'undefined'){
+            tempObj.unit = pasteObj.unit;
+        }
+        if(typeof pasteObj.gljType !== 'undefined'){
+            let isExsit = false;
+            for(let i = 0; i < me.distTypeTree.comboDatas.length; i++){
+                if(pasteObj.gljType === me.distTypeTree.comboDatas[i].text){
+                    isExsit = true;
+                    reCalBasePrc = true;
+                    tempObj.gljType = me.distTypeTree.comboDatas[i].value;
+                    tempObj.shortName = me.distTypeTree.distTypes[me.distTypeTree.prefix + tempObj.gljType].data.shortName;
+
+                }
+            }
+            if(!isExsit) isValid = false;
+        }
+        //
+        pasteObj.basePrice = !isNaN(parseFloat(pasteObj.basePrice)) && (pasteObj.basePrice && typeof pasteObj.basePrice !== 'undefined') ? parseFloat(pasteObj.basePrice) :
+            me.currentCache[rowIdx].basePrice;
+        if(pasteObj.basePrice !== me.currentCache[rowIdx].basePrice){
+            reCalBasePrc = true;
+            tempObj.basePrice = pasteObj.basePrice;
+        }
+        if(isValid){
+            rst.updateGlj = tempObj;
+            if(reCalBasePrc){
+                //重新计算定额基价对象
+                rst.updateBasePrc = {gljId: tempObj.ID, gljType: tempObj.gljType, basePrice: tempObj.basePrice};
+            }
+        }
+        else {
+            for(let attr in backUpObj){
+                tempObj[attr] = backUpObj[attr];
+            }
+        }
+        return rst;
+    },
+    //粘贴的数据是否是可添加的数据,只有含有编号,名称,类型才可添加
+    isValidObj: function(pasteObj) {
+        let me = repositoryGljObj;
+        if(!(pasteObj.code && typeof pasteObj.code !== 'undefined') || !(pasteObj.name && typeof pasteObj.name !== 'undefined') ||
+            !(pasteObj.gljType && typeof pasteObj.gljType !== 'undefined')){
+            return false;
+        }
+        if(pasteObj.gljType && typeof pasteObj.gljType !== 'undefined'){
+            let isExist = false;
+            for(let i = 0; i < me.distTypeTree.comboDatas.length; i++){
+                if(me.distTypeTree.comboDatas[i].text === pasteObj.gljType){
+                    isExist = true;
+                    pasteObj.gljType = me.distTypeTree.comboDatas[i].value;
+                    pasteObj.shortName = me.distTypeTree.distTypes[me.distTypeTree.prefix + pasteObj.gljType].data.shortName;
+                    break;
+                }
+            }
+            if(!isExist){
+                return false;
+            }
+        }
+        if(pasteObj.code && typeof pasteObj.code !== 'undefined'){
+            for(let i = 0; i < me.gljList.length; i++){
+                if(me.gljList[i].code === pasteObj.code){
+                    return false;
+                }
+            }
+        }
+        pasteObj.basePrice = !isNaN(parseFloat(pasteObj.basePrice)) && (pasteObj.basePrice && typeof pasteObj.basePrice !== 'undefined') ? parseFloat(pasteObj.basePrice) : 0;
+        pasteObj.gljClass = me.gljCurTypeId;
+        return true;
+    },
+    onClipboardPasting: function(sender, args) {
+        var me = repositoryGljObj;
+        /*if (args.cellRange.colCount != me.setting.header.length || me.gljCurTypeId < 0 || me.parentNodeIds["_pNodeId_" + me.gljCurTypeId]) {
+         args.cancel = true;
+         }*/
+        if (me.gljCurTypeId < 0 ) {
+            args.cancel = true;
+        }
+    },
+    onClipboardPasted: function(e, info) {
+        var me = repositoryGljObj;
+        var updateArr = [], addArr = [];
+        var items = sheetCommonObj.analyzePasteData(me.setting, info);
+        let beginRow = info.cellRange.row, endRow = info.cellRange.row + info.cellRange.rowCount - 1,
+            maxRow = me.currentCache.length - 1, updateItems = [], addItems = [], updateBasePrcArr = [] , updateCount, resumeArr = [];
+        if(endRow <= maxRow){
+            //updateItems = items;
+            for(let i = 0; i < items.length; i++){
+                let updateObj = me.validUpdateObj(items[i], info.cellRange.row + i);
+                if(updateObj && typeof updateObj.updateGlj !== 'undefined'){
+                    updateArr.push(updateObj.updateGlj);
+                    if(typeof updateObj.updateBasePrc !== 'undefined'){
+                        updateBasePrcArr.push(updateObj.updateBasePrc);
+                    }
+                }
+                else{
+                    resumeArr.push(info.cellRange.row + i);
+                }
+            }
+        }
+        else if(beginRow <= maxRow && endRow > maxRow){
+            updateCount = maxRow - beginRow + 1;
+            for(let i = 0; i < updateCount; i++){
+                let updateObj = me.validUpdateObj(items[i], info.cellRange.row + i);
+                if(updateObj && typeof updateObj.updateGlj !== 'undefined'){
+                    updateArr.push(updateObj.updateGlj);
+                    if(typeof updateObj.updateBasePrc !== 'undefined'){
+                        updateBasePrcArr.push(updateObj.updateBasePrc);
+                    }
+                }
+                else{
+                    resumeArr.push(info.cellRange.row + i);
+                }
+            }
+            if(info.cellRange.colCount === me.setting.header.length){
+                for(let i = updateCount ; i < items.length; i++){
+                    if(me.isValidObj(items[i])){
+                        addItems.push(items[i]);
+                        addArr.push(items[i]);
+                    }
+                    else{
+                        resumeArr.push(info.cellRange.row + i);
+                    }
+                }
+            }
+            else{
+                for(let i = updateCount ; i < items.length; i++){
+                    resumeArr.push(info.cellRange.row + i);
+                }
+            }
+        }
+        else{
+            if(info.cellRange.colCount === me.setting.header.length){
+                for(let i = 0; i < items.length; i++){
+                    if(me.isValidObj(items[i])){
+                        addArr.push(items[i]);
+                    }
+                    else{
+                        resumeArr.push(info.cellRange.row + i);
+                    }
+                }
+            }
+            else{
+                for(let i = 0; i < items.length; i++){
+                    resumeArr.push(info.cellRange.row + i);
+                }
+            }
+        }
+        //repaint
+        if(resumeArr.length > 0){
+            info.sheet.suspendPaint();
+            for(let i = 0; i < resumeArr.length ; i++){
+                if(resumeArr[i] < me.currentCache.length){
+                    for(let col = 0; col < me.setting.header.length; col++){
+                        if(me.setting.header[col].dataCode === 'gljType'){
+                            let gljType = me.currentCache[resumeArr[i]][me.setting.header[col].dataCode];
+                            info.sheet.setValue(resumeArr[i], col, me.distTypeTree.distTypes["gljType" + gljType].data.fullName);
+                        }
+                        else{
+                            info.sheet.setValue(resumeArr[i], col, me.currentCache[resumeArr[i]][me.setting.header[col].dataCode]);
+                        }
+                    }
+                }
+                else{
+                    for(let col = 0; col < me.setting.header.length; col++){
+                        info.sheet.setValue(resumeArr[i], col, '');
+                    }
+                }
+            }
+            info.sheet.resumePaint();
+        }
+        if (updateArr.length > 0 || addArr.length > 0) {
+            me.mixUpdateRequest(updateArr, addArr, []);
+        }
+        if(updateBasePrcArr.length > 0){
+            me.updateRationBasePrcRq(updateBasePrcArr);
+        }
+    },
+    updateRationBasePrcRq: function (basePrcArr) {
+        $.ajax({
+            type: 'post',
+            url: 'api/updateRationBasePrc',
+            data:{data: JSON.stringify({repId: pageOprObj.rationLibId, lastOpr: userAccount, basePrcArr: basePrcArr})},
+            dataType: 'json',
+            success: function (result) {
+                if(result.error){
+                    alert("计算定额基价失败");
+                }
+            }
+        });
+    },
+    getRationGljIds: function (repId) {
+        let me = repositoryGljObj;
+        $.ajax({
+            type: 'post',
+            url: 'api/getRationGljIds',
+            data: {data: JSON.stringify({repId: repId})},
+            dataType: 'json',
+            success: function(result){
+                if(!result.error){
+                    me.rationGljIds = result.data;
+                }
+            }
+        });
+    },
+    mixUpdateRequest: function(updateArr, addArr, removeIds) {
+        var me = repositoryGljObj;
+        $.ajax({
+            type:"POST",
+            url:"api/mixUpdateGljItems",
+            data:{"repositoryId": me.currentRepositoryId, "lastOpr": userAccount, "updateItems": JSON.stringify(updateArr), "addItems": JSON.stringify(addArr), "removeIds": JSON.stringify(removeIds)},
+            dataType:"json",
+            cache:false,
+            timeout:5000,
+            success:function(result){
+                if (result.error) {
+                    alert(result.message);
+                    me.getRationItems(me.currentRepositoryId);
+                } else {
+                    me.updateCache(addArr, updateArr, removeIds, result);
+                    me.sortGlj();
+                    if(me.currentOprParent === 1){
+                        me.currentCache = me.getParentCache(me.parentNodeIds["_pNodeId_" + me.gljCurTypeId]);
+                    }
+                    else{
+                        me.currentCache = me.getCache();
+                        //sheetCommonObj.unLockAllCells(me.workBook.getSheet(0));
+                        sheetsOprObj.reLockSomeCodes(me.workBook.getSheet(0), 0, me.currentCache.length);
+                        //sheetCommonObj.lockSomeCodes(me.workBook.getSheet(0), 0, me.currentCache.length);
+                    }
+                    me.showGljItems(me.gljList, me.gljCurTypeId);
+                }
+            },
+            error:function(err){
+                alert("保存失败");
+            }
+        })
+    },
+    getParentCache: function (nodes) {
+        let me = repositoryGljObj, rst = [];
+        for(let i = 0; i < me.gljList.length; i++){
+            if(nodes.indexOf(me.gljList[i].gljClass) !== -1){
+                rst.push(me.gljList[i]);
+            }
+        }
+        rst.sort(function (a, b) {
+            let rst = 0;
+            if(a.code > b.code) rst = 1;
+            else if(a.code < b.code)rst = -1;
+            return rst;
+        });
+        return rst;
+    },
+    getCache: function() {
+        var me = this, rst = [];
+        for (var i = 0; i < me.gljList.length; i++) {
+            if (me.gljList[i].gljClass == me.gljCurTypeId) {
+                rst.push(me.gljList[i]);
+            }
+        }
+        return rst;
+    },
+    updateCache: function(addArr, updateArr, removeIds, result) {
+        var me = this, cacheSection = me.gljList;
+        if (addArr.length > 0) {
+            me.gljList = me.gljList.concat(addArr);
+            cacheSection = me.gljList;
+        }
+        for (var i = removeIds.length - 1; i >= 0; i--) {
+            for (var j = cacheSection.length - 1; j >= 0 ; j--) {
+                if (cacheSection[j]["ID"] == removeIds[i]) {
+                    cacheSection.splice(j,1);
+                }
+            }
+        }
+        if (result && result.data.ops && result.data.ops.length > 0) {
+            for (var i = 0; i < result.data.ops.length; i++) {
+                for (var j = 0; j < cacheSection.length; j++) {
+                    if (cacheSection[j][me.setting.header[0].dataCode] == result.data.ops[i][me.setting.header[0].dataCode]) {
+                        cacheSection[j]["ID"] = result.data.ops[i]["ID"];
+                    }
+                }
+            }
+        }
+        for (var i = 0; i < updateArr.length; i++) {
+            for (var j = 0; j < cacheSection.length; j++) {
+                if (updateArr[i]["ID"] && cacheSection[j]["ID"]) {
+                    if (cacheSection[j]["ID"] == updateArr[i]["ID"]) {
+                        cacheSection[j] = updateArr[i];
+                    }
+                } else {
+                    if (cacheSection[j][me.setting.header[0].dataCode] == updateArr[i][me.setting.header[0].dataCode]) {
+                        cacheSection[j] = updateArr[i];
+                    }
+                }
+            }
+        }
+    },
+    sortGlj: function() {
+        var me = this;
+        me.gljList.sort(function(a, b){
+            var rst = 0;
+            if (a.code > b.code) rst = 1
+            else if (a.code < b.code) rst = -1;
+            return rst;
+        });
+    }
+}
+
+var gljTypeTreeOprObj = {
+    onClick: function(event,treeId,treeNode) {
+        var me = repositoryGljObj,
+            gljTypeId = treeNode.ID;
+        me.gljCurTypeId = treeNode.ID;
+        if (me.parentNodeIds["_pNodeId_" + treeNode.ID]) {
+            me.currentOprParent = 1;
+            me.currentCache = me.getParentCache(me.parentNodeIds["_pNodeId_" + treeNode.ID]);
+           // sheetCommonObj.lockCodeCells(me.workBook.getSheet(0), me.currentCache.length);
+            me.workBook.getSheet(0).setRowCount(me.currentCache.length);
+        } else {
+            me.currentOprParent = 0;
+            me.currentCache = me.getCache();
+            me.workBook.getSheet(0).setRowCount(me.currentCache.length);
+            /*sheetCommonObj.unLockAllCells(me.workBook.getSheet(0));
+            sheetCommonObj.reLockSomeCodes(me.workBook.getSheet(0), 0, me.currentCache.length);*/
+        }
+        me.showGljItems(me.gljList, gljTypeId);
+        me.workBook.getSheet(0).setRowCount(me.currentCache.length);
+    },
+    beforeRename: function(treeId, treeNode, newName, isCancel) {
+        if (newName.length == 0) {
+            return false;
+        }
+        return true;
+    },
+    onRename : function(e, treeId, treeNode, isCancel) {
+        var nodes = [];
+        nodes.push(treeNode);
+        gljTypeTreeOprObj.updateNodes(nodes);
+    },
+    onBeforeRemove: function(treeId, treeNode){
+        let me = this;
+        if (treeNode.ParentID == -1 && treeNode.isFirstNode) {
+            alert("不允许删除全部!");
+            return false;
+        }
+        if (!confirm("您确定要删除此节点及所有子节点的数据?删除后不可恢复!")) {
+            return false;
+        }
+        var nodeIds = [], preNode = treeNode.getPreNode(), preNodeId = -1;
+        if (preNode) {
+            preNodeId = preNode.ID;
+        }
+        private_fetchAllSubItems = function(pItem){
+            nodeIds.push(pItem.ID);
+            if (pItem.items && pItem.items.length > 0) {
+                for (var i = 0; i < pItem.items.length; i++) {
+                    private_fetchAllSubItems(pItem.items[i]);
+                }
+            }
+        };
+        nodeIds.push(treeNode.ID);
+        for (var i = 0; i < treeNode.items.length; i++) {
+            private_fetchAllSubItems(treeNode.items[i]);
+        }
+        $.ajax({
+            type:"POST",
+            url:"api/deleteGljNodes",
+            data:{"repId": pageOprObj.rationLibId, "lastOpr": userAccount, "nodes": JSON.stringify(nodeIds), "preNodeId": preNodeId, "preNodeNextId": treeNode.NextSiblingID},
+            dataType:"json",
+            cache:false,
+            timeout:5000,
+            success:function(result,textStatus,status){
+                var pNode = treeNode.getParentNode();
+                if (pNode && pNode.items && pNode.items.length == 1) {
+                    pNode.isParent = false;
+                }
+            },
+            error:function(){
+            }
+        });
+        return true;
+    },
+    onRemove: function(e, treeId, treeNode){
+        var me = repositoryGljObj, pNode = me.treeObj.getNodeByTId(treeNode.parentTId);
+        if (pNode && pNode.items && pNode.items.length == 0) {
+            pNode.isParent = false;
+            me.treeObj.refresh();
+        }
+    },
+    updateNodes: function(nodes){
+        if (nodes && nodes.length > 0) {
+            var reqData = []
+            for (var i = 0; i < nodes.length; i++) {
+                var node = {};
+                node.repositoryId = nodes[i].repositoryId;
+                node.ID = nodes[i].ID;
+                node.ParentID = nodes[i].ParentID;
+                node.NextSiblingID = nodes[i].NextSiblingID;
+                node.Name = nodes[i].Name;
+                if (nodes[i].__v != null) node.__v = nodes[i].__v + 1
+                else node.__v = 0;
+                reqData.push(node);
+            }
+            $.ajax({
+                type:"POST",
+                url:"api/updateGljNodes",
+                data:{"repId": pageOprObj.rationLibId, "lastOpr": userAccount, "nodes": JSON.stringify(reqData)},
+                dataType:"json",
+                cache:false,
+                timeout:5000,
+                success:function(result,textStatus,status){
+                    console.log(status + ' : ' + result);
+                },
+                error:function(){
+                }
+            })
+        }
+    },
+    addRootNode: function() {
+        var me = repositoryGljObj, rawNode = {ParentID: -1, NextSiblingID: -1, Name: "所有"}, lastNodeId = -1;
+        if (me.treeObj) {
+            var rootNodes = me.treeObj.getNodes();
+            if (rootNodes.length == 0) {
+                gljTypeTreeOprObj.addNewNode(rawNode, lastNodeId, function(err, rst){
+                    if (!(err)) {
+                        var newNodes = [], isSilent = false;
+                        newNodes.push({ repositoryId: rst.data.repositoryId, ID: rst.data.ID, ParentID: rst.data.ParentID, NextSiblingID:-1, Name:"所有",isParent:false, items:[]});
+                        me.treeObj.addNodes(null, -1, newNodes, isSilent);
+                    }
+                });
+            }
+        }
+    },
+    addNewNode : function(rawNode, lastNodeId, callback){
+        $.ajax({
+            type:"POST",
+            url:"api/createNewGljTypeNode",
+            data:{"lastOpr": userAccount, "repositoryId": repositoryGljObj.currentRepositoryId,"lastNodeId": lastNodeId, "rawNodeData": JSON.stringify(rawNode)},
+            dataType:"json",
+            cache:false,
+            timeout:1000,
+            success: function(result,textStatus,status){
+                callback(false, result);
+            },
+            error:function(err){
+                callback(err);
+            }
+        })
+    },
+    addHoverDom: function(treeId, treeNode) {
+        if(typeof treeNode.doing !== 'undefined' && treeNode.doing){
+            return false;
+        }
+        hoverOpr();
+        function hoverOpr(){
+            //console.log(treeNode);
+            var me = repositoryGljObj, sObj = $("#" + treeNode.tId + "_span");
+            if (treeNode.editNameFlag || $("#addBtn_"+treeNode.tId).length>0) return;
+            var addStr = "<span class='button add' id='addBtn_" + treeNode.tId + "' title='新增子节点' onfocus='this.blur();'></span>";
+            sObj.after(addStr);
+            var btn = $("#addBtn_"+treeNode.tId);
+            if (btn) btn.bind("click", function(){
+                treeNode.doing = true;
+                var rawNode = {ParentID: treeNode.ID, NextSiblingID: -1, Name: "新增子节点"}, lastNodeId = -1;
+                if (treeNode.items.length > 0) {
+                    lastNodeId = treeNode.items[treeNode.items.length - 1].ID;
+                }
+                gljTypeTreeOprObj.addNewNode(rawNode, lastNodeId, function(err, rst){
+                    if (!(err)) {
+                        var newNodes = [], isSilent = false;
+                        if(treeNode.items.length > 0){
+                            treeNode.items[treeNode.items.length - 1].NextSiblingID = rst.data.ID;
+                        }
+                        newNodes.push({ repositoryId: rst.data.repositoryId, ID: rst.data.ID, ParentID: rst.data.ParentID, NextSiblingID:-1, Name:"新增子节点",isParent:false, items:[]});
+                        treeNode.isParent = true;
+                        if (me.treeObj) {
+                            me.treeObj.addNodes(treeNode, -1, newNodes, isSilent);
+                        } else {
+                            me.treeObj = $.fn.zTree.init($("#rationChapterTree"), gljSetting, newNodes);
+                        }
+                        treeNode.doing = false;
+                        hoverOpr();
+                    }
+                });
+            });
+        }
+    },
+    removeHoverDom: function(treeId, treeNode) {
+        $("#addBtn_"+treeNode.tId).unbind().remove();
+    }
+
+}

+ 526 - 0
web/building_saas/complementary_ration_lib/js/section_tree.js

@@ -0,0 +1,526 @@
+/**
+ * Created by Zhong on 2017/12/18.
+ */
+let pageOprObj = {
+    rationLibName : null,
+    rationLibId : null,
+    initPage : function() {
+        var me = this, rationLibId = getQueryString("repository"),//获取定额库参数
+            rationLibName = storageUtil.getSessionCache("RationGrp","repositoryID_" + rationLibId);
+        if (rationLibName) {
+            var html = $("#rationname")[0].outerHTML;
+            html = html.replace("XXX定额库", rationLibName);
+            $("#rationname")[0].outerHTML = html;
+            me.rationLibName = rationLibName;
+            me.rationLibId = rationLibId;
+            sectionTreeObj.getSectionTree(rationLibId);
+            //job
+            jobContentOprObj.radiosChange(jobContentOprObj.radios, jobContentOprObj.tableAll, jobContentOprObj.tablePartial);
+            $('#addConBtn').click(jobContentOprObj.bindAddConBtn());
+            $('#updateConBtn').click(jobContentOprObj.bindUpdateConBtn());
+            jobContentOprObj.bindAllEvents($('#txtareaAll'));
+            //fz
+            annotationOprObj.radiosChange(annotationOprObj.radios, annotationOprObj.fzTableAll, annotationOprObj.fzTablePartial);
+            $('#fzAddConBtn').click(annotationOprObj.bindAddConBtn());
+            $('#fzUpdateConBtn').click(annotationOprObj.bindUpdateConBtn());
+            annotationOprObj.bindAllEvents($('#fzTxtareaAll'));
+        }
+    }
+}
+
+let sectionTreeObj = {
+    cache: null,//ref to tree.items
+    tree: null,
+    controller: null,
+    workBook: null,
+    sheet: null,
+    updateType: {new: 'new', update: 'update'},
+    insertBtn: $('#tree_Insert'),
+    removeBtn: $('#tree_remove'),
+    upLevelBtn: $('#tree_upLevel'),
+    downLevelBtn: $('#tree_downLevel'),
+    downMoveBtn: $('#tree_downMove'),
+    upMoveBtn: $('#tree_upMove'),
+    setting: {
+        sheet: {
+            cols:[
+                {
+                    head: {
+                        titleNames: ['名称'],
+                        spanCols: [1],
+                        spanRows: [2],
+                        vAlign: [1, 1],
+                        hAlign: [1, 1],
+                        font: 'Arial'
+                    },
+                    data: {
+                        field: 'name',
+                        vAlign: 1,
+                        hAlign: 0,
+                        font: 'Arial'
+                    },
+                    width: 400
+                }
+            ],
+            headRows: 1,
+            headRowHeight: [47],
+            emptyRows: 0,
+            treeCol: 0
+        },
+        tree: {
+            id: 'ID',
+            pid: 'ParentID',
+            nid: 'NextSiblingID',
+            rootId: -1
+        },
+        options: {
+            tabStripVisible:  false,
+            allowCopyPasteExcelStyle : false,
+            allowExtendPasteRange: false,
+            allowUserDragDrop : false,
+            allowUserDragFill: false,
+            scrollbarMaxAlign : true
+        }
+    },
+
+    isDef: function (v) {
+        return v !== undefined && v !== null;
+    },
+    isFunc: function (v) {
+        return this.isDef(v) && typeof v === 'function';
+    },
+    //sheet things
+    setOptions: function (workbook, opts) {
+        for(let opt in opts){
+            workbook.options[opt] = opts[opt];
+        }
+    },
+
+    renderFunc: function (sheet, func) {
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        if(this.isFunc(func)){
+            func();
+        }
+        sheet.resumePaint();
+        sheet.resumeEvent();
+    },
+
+    buildSheet: function () {
+        if(!this.isDef(this.workBook)){
+            this.workBook = new GC.Spread.Sheets.Workbook($('#sectionSpread')[0], {sheetCount: 1});
+            this.sheet = this.workBook.getSheet(0);
+            this.bindEvents(this.sheet);
+            this.setOptions(this.workBook, this.setting.options);
+            this.sheet.options.clipBoardOptions = GC.Spread.Sheets.ClipboardPasteOptions.values;
+        }
+    },
+
+    bindEvents: function (sheet) {
+        let me = sectionTreeObj;
+        const Events = GC.Spread.Sheets.Events;
+        sheet.bind(Events.SelectionChanging, me.onSelectionChanging);
+        sheet.bind(Events.EditEnded, me.onEditEnded);
+        sheet.bind(Events.ClipboardPasted, me.onClipboardPasted);
+    },
+
+    onSelectionChanging: function (sender, info) {
+        let me = sectionTreeObj;
+        if(info.oldSelections.length === 0 && info.newSelections.length > 0 || info.oldSelections[0].row !== info.newSelections[0].row){
+            let row = info.newSelections[0].row;
+            let section = me.cache[row];
+            me.initSelection(section);
+        }
+        else {
+            me.refreshBtn(null);
+        }
+    },
+
+    onEditEnded: function (sender, args) {
+        let me = sectionTreeObj;
+        let postData = [];
+        let v = me.isDef(args.editingText) ? args.editingText.toString().trim() : '';
+        let node = me.cache[args.row];
+        if(me.isDef(node) && node.data.name !== v){
+            let updateObj = me.getUpdateObj(me.updateType.update, node.getID(), null, null, v, null);
+            postData.push(updateObj);
+            //ajax
+            //update
+            me.sectionTreeAjax(postData, function (rstData) {
+                node.data.name = v;
+            }, function () {
+                args.sheet.setValue(args.row, args.col, node.data.name ? node.data.name : '');
+            });
+        }
+    },
+
+    onClipboardPasted: function (sender, info) {
+        let me = sectionTreeObj;
+        let items = sheetCommonObj.analyzePasteData({header: [{dataCode: 'name'}]}, info);
+        let postData = [];
+        let frontData = [];
+        for(let i = 0, len = items.length; i < len; i++){
+            let row = info.cellRange.row + i;
+            let node = me.cache[row];
+            if(me.isDef(node) && me.isDef(items[i].name) && node.data.name !== items[i].name){
+                let updateObj = me.getUpdateObj(me.updateType.update, node.getID(), null, null, items[i].name, null);
+                postData.push(updateObj);
+                frontData.push({row: row, name: items[i].name});
+                node.data.name = items[i].name;
+            }
+        }
+        if(postData.length > 0){
+            //ajax
+            me.sectionTreeAjax(postData, function (rstData) {
+                for(let i = 0, len = frontData.length; i < len; i++){
+                    let node = me.cache[frontData[i]['row']];
+                    if(me.isDef(node)){
+                        node.data.name = frontData[i]['name'];
+                    }
+                }
+            }, function () {
+                for(let i = 0, len = frontData.length; i < len; i++){
+                    let node = me.cache[frontData[i]['row']];
+                    me.sheet.setValue(frontData[i]['row'], 0, me.isDef(node) ? node.data.name : '');
+                }
+            });
+        }
+    },
+
+    getSectionTree: function (repId) {
+        let me = sectionTreeObj;
+        let url = 'api/getRationTree';
+        let postData = {rationRepId: repId};
+        let sucFunc = function (rstData) {
+            if(rstData.length > 0){
+                storageUtil.setSessionCache("RationGrp","repositoryID",rstData[0].rationRepId);
+            }
+            //init
+            me.buildSheet();
+            me.initTree(rstData);
+            me.cache = me.tree.items;
+            me.bindBtn();
+            me.initController(me.tree, me.sheet, me.setting.sheet);
+            me.controller.showTreeData();
+            me.sheet.setFormatter(-1, 0, '@');
+            me.initSelection(me.tree.selected);
+            explanatoryOprObj.bindEvents($('#explanationShow'), $('#ruleTextShow'));
+        };
+        let errFunc = function () {
+
+        };
+        CommonAjax.post(url, postData, sucFunc, errFunc);
+    },
+    
+    initTree: function (datas) {
+        this.tree = idTree.createNew(this.setting.tree);
+        this.tree.loadDatas(datas);
+        this.tree.selected = this.tree.items.length > 0 ? this.tree.items[0] : null;
+    },
+
+    initController: function (tree, sheet, setting) {
+        this.controller = TREE_SHEET_CONTROLLER.createNew(tree, sheet, setting);
+    },
+    
+    refreshBtn: function (selected) {
+        let me = this;
+        me.insertBtn.removeClass('disabled');
+        me.removeBtn.removeClass('disabled');
+        me.upLevelBtn.removeClass('disabled');
+        me.downLevelBtn.removeClass('disabled');
+        me.downMoveBtn.removeClass('disabled');
+        me.upMoveBtn.removeClass('disabled');
+        if(!me.isDef(selected)){
+            me.removeBtn.addClass('disabled');
+            me.upLevelBtn.addClass('disabled');
+            me.downLevelBtn.addClass('disabled');
+            me.downMoveBtn.addClass('disabled');
+            me.upMoveBtn.addClass('disabled');
+        }
+        else {
+            if(!me.isDef(selected.preSibling)){
+                me.downLevelBtn.addClass('disabled');
+                me.upMoveBtn.addClass('disabled');
+            }
+            if(!me.isDef(selected.nextSibling)){
+                me.downMoveBtn.addClass('disabled');
+            }
+            if(!me.isDef(selected.parent)){
+                me.upLevelBtn.addClass('disabled');
+            }
+        }
+    },
+    
+    bindBtn: function () {
+        let me = this;
+        me.insertBtn.click(function () {
+            me.insert();
+        });
+        me.removeBtn.click(function () {
+           me.remove(me.tree.selected);
+        });
+        me.upLevelBtn.click(function () {
+            me.upLevel(me.tree.selected);
+        });
+        me.downLevelBtn.click(function () {
+            me.downLevel(me.tree.selected);
+        });
+        me.downMoveBtn.click(function () {
+            me.downMove(me.tree.selected);
+        });
+        me.upMoveBtn.click(function () {
+            me.upMove(me.tree.selected);
+        });
+    },
+    
+    insert: function () {
+        let me = this;
+        me.insertBtn.addClass('disabled');
+        let postData = [];
+        let newID = me.tree.newNodeID();
+        let selected = me.tree.selected;
+        let insertObj = me.getUpdateObj(me.updateType.new, newID, -1, -1, '', null);
+        if(me.isDef(selected)) {
+            let updateObj = me.getUpdateObj(me.updateType.update, selected.getID(), newID, null, null, null);
+            postData.push(updateObj);
+            insertObj.updateData.ParentID = selected.getParentID();
+            if(me.isDef(selected.nextSibling)){
+                insertObj.updateData.NextSiblingID = selected.getNextSiblingID();
+            }
+        }
+        postData.push(insertObj);
+        if(postData.length > 0){
+            //ajax
+            me.sectionTreeAjax(postData, function (rstData) {
+                me.controller.insert();
+                me.refreshBtn(me.tree.selected);
+                //fresh tools
+                me.initTools(me.tree.selected);
+            });
+        }
+    },
+    remove: function (selected) {
+        let me = this;
+        me.removeBtn.addClass('disabled');
+        let postData = [], IDs = [];
+        if(!selected){
+            return;
+        }
+        getDelIds(selected);
+        function getDelIds(node){
+            if(me.isDef(node)){
+                IDs.push(node.getID());
+                if(node.children.length > 0){
+                    for(let i = 0, len = node.children.length; i < len; i++){
+                        getDelIds(node.children[i]);
+                    }
+                }
+            }
+        }
+        if(me.isDef(selected.preSibling)){
+            let updateObj = me.getUpdateObj(me.updateType.update, selected.preSibling.getID(), selected.getNextSiblingID(), null, null, null);
+            postData.push(updateObj);
+        }
+        if(IDs.length > 0){
+            for(let i = 0, len = IDs.length; i < len; i++){
+                let delObj = me.getUpdateObj(me.updateType.update, IDs[i], null, null, null, true);
+                postData.push(delObj);
+            }
+        }
+        if(postData.length > 0){
+            //ajax
+            me.sectionTreeAjax(postData, function (rstData) {
+                me.controller.delete();
+                me.refreshBtn(me.tree.selected);
+                me.initTools(me.tree.selected);
+            });
+        }
+    },
+    upLevel: function (selected) {
+        let me = this;
+        me.upLevelBtn.addClass('disabled');
+        let postData = [];
+        if(!me.isDef(selected)){
+            return;
+        }
+        if(!me.isDef(selected.parent)){
+            return;
+        }
+        if(me.isDef(selected.preSibling)){
+            let updateObj = me.getUpdateObj(me.updateType.update, selected.preSibling.getID(), -1, null, null, null);
+            postData.push(updateObj);
+        }
+        let updateObj = me.getUpdateObj(me.updateType.update, selected.getID(), selected.parent.getNextSiblingID(), selected.parent.getParentID(), null, null);
+        postData.push(updateObj);
+        let updateParent = me.getUpdateObj(me.updateType.update, selected.getParentID(), selected.getID(), null, null, null);
+        postData.push(updateParent);
+        let nextIDs = [];
+        getNext(selected);
+        function getNext(node){
+            if(me.isDef(node.nextSibling)){
+                nextIDs.push(node.getNextSiblingID());
+                getNext(node.nextSibling);
+            }
+        }
+        for(let i = 0, len = nextIDs.length; i < len; i++){
+            postData.push(me.getUpdateObj(me.updateType.update, nextIDs[i], null, selected.getID(), null, null));
+        }
+        if(postData.length > 0){
+            //ajax
+            me.sectionTreeAjax(postData, function (rstData) {
+                me.controller.upLevel();
+                me.refreshBtn(me.tree.selected);
+            });
+        }
+
+    },
+    downLevel: function (selected) {
+        let me = this;
+        me.downLevelBtn.addClass('disabled');
+        let postData = [];
+        if(!me.isDef(selected)){
+            return;
+        }
+        if(!me.isDef(selected.preSibling)){
+            return;
+        }
+        let updatePre = me.getUpdateObj(me.updateType.update, selected.preSibling.getID(), selected.getNextSiblingID(), null, null, null);
+        postData.push(updatePre);
+        if(selected.preSibling.children.length > 0){
+            let updateObj = me.getUpdateObj(me.updateType.update, selected.preSibling.children[selected.preSibling.children.length - 1].getID(), selected.getID(), null, null, null);
+            postData.push(updateObj);
+        }
+        let updateObj = me.getUpdateObj(me.updateType.update, selected.getID(), -1, selected.preSibling.getID(), null, null);
+        postData.push(updateObj);
+        if(postData.length > 0){
+            //ajax
+            me.sectionTreeAjax(postData, function (rstData) {
+                me.controller.downLevel();
+                me.refreshBtn(me.tree.selected);
+            });
+        }
+    },
+    upMove: function (selected) {
+        let me = this;
+        me.upMoveBtn.addClass('disabled');
+        let postData = [];
+        if(!me.isDef(selected)){
+            return;
+        }
+        if(!me.isDef(selected.preSibling)){
+            return;
+        }
+        let updateObj = me.getUpdateObj(me.updateType.update, selected.getID(), selected.preSibling.getID(), null, null, null);
+        postData.push(updateObj);
+        let updatePre = me.getUpdateObj(me.updateType.update, selected.preSibling.getID(), selected.getNextSiblingID(), null, null, null);
+        postData.push(updatePre);
+        if(me.isDef(selected.preSibling.preSibling)){
+            let updatePrepre = me.getUpdateObj(me.updateType.update, selected.preSibling.preSibling.getID(), selected.getID(), null, null, null);
+            postData.push(updatePrepre);
+        }
+        if(postData.length > 0){
+            //ajax
+            me.sectionTreeAjax(postData, function (rstData) {
+                me.controller.upMove();
+                me.refreshBtn(me.tree.selected);
+            });
+        }
+    },
+    downMove: function (selected) {
+        let me = this;
+        me.downMoveBtn.addClass('disabled');
+        let postData = [];
+        if(!me.isDef(selected)){
+            return;
+        }
+        if(!me.isDef(selected.nextSibling)){
+            return;
+        }
+        if(me.isDef(selected.preSibling)){
+            let updatePre = me.getUpdateObj(me.updateType.update, selected.preSibling.getID(), selected.getNextSiblingID(), null, null, null);
+            postData.push(updatePre);
+        }
+        let updateObj = me.getUpdateObj(me.updateType.update, selected.getID(), selected.nextSibling.getNextSiblingID(), null, null, null);
+        postData.push(updateObj);
+        let updateNext = me.getUpdateObj(me.updateType.update, selected.getNextSiblingID(), selected.getID(), null, null, null);
+        postData.push(updateNext);
+        if(postData.length > 0){
+            //ajax
+            me.sectionTreeAjax(postData, function (rstData) {
+                me.controller.downMove();
+                me.refreshBtn(me.tree.selected);
+            });
+        }
+    },
+    getUpdateObj: function (updateType, id, nid, pid, name, deleted) {
+        let updateObj = Object.create(null);
+        updateObj.updateType = '';
+        updateObj.updateData = Object.create(null);
+        updateObj.updateData.rationRepId = pageOprObj.rationLibId;
+        if(this.isDef(updateType)){
+            updateObj.updateType = updateType;
+        }
+        if(this.isDef(id)){
+            updateObj.updateData.ID = id;
+        }
+        if(this.isDef(nid)){
+            updateObj.updateData.NextSiblingID = nid;
+        }
+        if(this.isDef(pid)){
+            updateObj.updateData.ParentID = pid;
+        }
+        if(this.isDef(name)){
+            updateObj.updateData.name = name;
+        }
+        if(this.isDef(deleted)){
+            updateObj.updateData.isDeleted = true;
+        }
+        return updateObj;
+    },
+    sectionTreeAjax: function (postData, scFunc, errFunc) {
+        CommonAjax.post('api/updateNodes', {updateData: postData, lastOpr: userAccount}, scFunc, errFunc);
+    },
+    initTools: function (node) {
+        if(this.isDef(node)){
+            explanatoryOprObj.setAttribute(explanatoryOprObj.currentTreeNode ? explanatoryOprObj.currentTreeNode : node, node, node.data.explanation, node.data.ruleText);
+            explanatoryOprObj.clickUpdate($('#explanationShow'), $('#ruleTextShow'));
+            explanatoryOprObj.showText($('#explanationShow'), $('#ruleTextShow'), node.data.explanation, node.data.ruleText);
+            //job
+            jobContentOprObj.currentSituation = typeof node.data.jobContentSituation !== 'undefined'? node.data.jobContentSituation : jobContentOprObj.situations.NONE;
+            jobContentOprObj.setAttribute(jobContentOprObj.currentTreeNode ? jobContentOprObj.currentTreeNode : node, node);
+            jobContentOprObj.clickUpdate($('#txtareaAll'));
+            //fz
+            annotationOprObj.currentSituation = typeof node.data.annotationSituation !== 'undefined'? node.data.annotationSituation : annotationOprObj.situations.NONE;
+            annotationOprObj.clickUpdate($('#fzTxtareaAll'));
+        }
+    },
+    //模仿默认点击
+    initSelection: function (node) {
+        let me = this;
+        if(!me.isDef(node)){
+            return;
+        }
+        me.initTools(node);
+        me.refreshBtn(node);
+        if(!me.isDef(node.children) || node.children.length === 0){
+            rationOprObj.canRations = true;
+            rationOprObj.workBook.getSheet(0).clearSelection();
+            rationOprObj.getRationItems(node.data.ID);
+            rationOprObj.setCombo(rationOprObj.workBook.getSheet(0), 'dynamic');
+        }
+        else {
+            rationOprObj.canRations = false;
+            rationOprObj.currentSectionId = node.data.ID;
+            rationOprObj.workBook.getSheet(0).setRowCount(30);
+            rationOprObj.setCombo(rationOprObj.workBook.getSheet(0), null);
+            jobContentOprObj.setRadiosDisabled(true, jobContentOprObj.radios);
+            jobContentOprObj.hideTable($('#tableAll'), $('#tablePartial'));
+            annotationOprObj.setRadiosDisabled(true, annotationOprObj.radios);
+            annotationOprObj.hideTable($('#fzTableAll'), $('#fzTablePartial'));
+            sheetCommonObj.cleanSheet(rationOprObj.workBook.getSheet(0), rationOprObj.setting, -1);
+        }
+        sheetCommonObj.cleanSheet(rationGLJOprObj.sheet, rationGLJOprObj.setting, -1);
+        rationGLJOprObj.sheet.getParent().focus(false);
+        me.workBook.focus(true);
+    }
+};

+ 202 - 0
web/building_saas/complementary_ration_lib/js/sheetsOpr.js

@@ -0,0 +1,202 @@
+/**
+ * Created by Zhong on 2017/9/29.
+ */
+let sheetsOprObj = {
+    setAreaAlign: function(area, hAlign, vAlign){
+        if (!(hAlign) || hAlign === "left") {
+            area.hAlign(GC.Spread.Sheets.HorizontalAlign.left);
+        } else if (hAlign === "right") {
+            area.hAlign(GC.Spread.Sheets.HorizontalAlign.right);
+        } else if (hAlign === "center") {
+            area.hAlign(GC.Spread.Sheets.HorizontalAlign.center);
+        } else {
+            area.hAlign(GC.Spread.Sheets.HorizontalAlign.left);
+        }
+        if (!(vAlign) || vAlign === "center") {
+            area.vAlign(GC.Spread.Sheets.VerticalAlign.center);
+        } else if (vAlign === "top") {
+            area.vAlign(GC.Spread.Sheets.VerticalAlign.top);
+        } else if (vAlign === "bottom") {
+            area.vAlign(GC.Spread.Sheets.VerticalAlign.bottom);
+        } else {
+            area.vAlign(GC.Spread.Sheets.VerticalAlign.center);
+        }
+    },
+    showData: function(sheet, setting, data, distTypeTree) {
+        var me = this, ch = GC.Spread.Sheets.SheetArea.viewport;
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        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 + 10);
+        }
+        /*if(data.length === 0){
+            for(let i = 0; i < sheet.getRowCount(); i++){
+                sheet.getCell(i, 4, GC.Spread.Sheets.SheetArea.viewport).locked(false);
+            }
+        }*/
+        for (var col = 0; col < setting.header.length; col++) {
+            var hAlign = "left", vAlign = "center";
+            if (setting.header[col].hAlign) {
+                hAlign = setting.header[col].hAlign;
+            } else if (setting.header[col].dataType !== "String"){
+                hAlign = "right";
+            }
+            vAlign = setting.header[col].vAlign?setting.header[col].vAlign:vAlign;
+            me.setAreaAlign(sheet.getRange(-1, col, -1, 1), hAlign, vAlign);
+            if (setting.header[col].formatter) {
+                //var style = new GC.Spread.Sheets.Style();
+                //style.formatter = setting.header[col].formatter;
+                //sheet.setStyle(row,col,style,GC.Spread.Sheets.SheetArea.viewport);
+                sheet.setFormatter(-1, col, setting.header[col].formatter, GC.Spread.Sheets.SheetArea.viewport);
+            }
+            for (var row = 0; row < data.length; row++) {
+                //var cell = sheet.getCell(row, col, GC.Spread.Sheets.SheetArea.viewport);
+                if(setting.header[col].dataCode === 'gljType' && data[row].gljType){
+                   /* if(typeof repositoryGljObj !== 'undefined' && typeof repositoryGljObj.allowComponent !== 'undefined' && repositoryGljObj.allowComponent.indexOf(data[row].gljType) !== -1){
+                        sheet.getCell(row, 4, GC.Spread.Sheets.SheetArea.viewport).locked(true);
+                    }
+                    else if(typeof repositoryGljObj !== 'undefined' && typeof repositoryGljObj.allowComponent !== 'undefined' && repositoryGljObj.allowComponent.indexOf(data[row].gljType) === -1){
+                        sheet.getCell(row, 4, GC.Spread.Sheets.SheetArea.viewport).locked(false);
+                    }*/
+                    let distTypeVal =  distTypeTree.distTypes[distTypeTree.prefix + data[row].gljType].data.fullName;
+                    sheet.setValue(row, col, distTypeVal, ch);
+                }
+                else {
+                    sheet.setValue(row, col, data[row][setting.header[col].dataCode], ch);
+                    sheet.setTag(row, 0, data[row].ID, ch);
+                    /*if(typeof setting.owner !== 'undefined' && setting.owner !== 'gljComponent'){
+                        sheet.getCell(row, 0, GC.Spread.Sheets.SheetArea.viewport).locked(true);
+                    }*/
+                }
+            }
+          /*  for(let i = data.length; i < sheet.getRowCount(); i++){
+                sheet.getCell(i, 4, GC.Spread.Sheets.SheetArea.viewport).locked(false);
+            }*/
+        }
+        sheet.resumeEvent();
+        sheet.resumePaint();
+        //me.shieldAllCells(sheet);
+    },
+    combineRowData: function(sheet, setting, row, repositoryGljObj) {
+        let me = this;
+        var rst = {};
+        let comboBoxCellType = sheet.getCellType(row, 5);
+        let items = comboBoxCellType.items();
+        for (var col = 0; col < setting.header.length; col++) {
+            if(setting.header[col].dataCode === 'gljType'){
+                items.forEach(function(item){
+                    if(sheet.getValue(row, col) === item.text){
+                        rst[setting.header[col].dataCode] = item.value;
+                        if(repositoryGljObj){
+                            rst.shortName = repositoryGljObj.distTypeTree.distTypes[repositoryGljObj.distTypeTree.prefix + item.value].data.shortName;
+                        }
+                    }
+                });
+            }
+            else if (setting.header[col].dataCode === 'code'){
+                if(repositoryGljObj){
+                    let gljList = repositoryGljObj.gljList,
+                        orgCode = repositoryGljObj.orgCode,
+                        isExist = false;
+                    for(let i=0; i< gljList.length; i++){
+                        if(gljList[i].code === sheet.getValue(row, col) && sheet.getValue(row, col)!== orgCode){
+                           // sheetCommonObj.lockAllCells(sheet);
+                            $('#alertText').text("输入的编号已存在,请重新输入!");
+                            $('#codeAlertBtn').click();
+                            $('#codAleConfBtn').click(function () {
+                                // me.reLockSomeCodes(sheet, 0, repositoryGljObj.currentCache.length);
+                               // sheetCommonObj.unLockAllCells(sheet);
+                                //me.reLockSomeCodes(sheet, 0, repositoryGljObj.currentCache.length);
+                                sheet.setValue(row, 0, orgCode);
+                                sheet.getCell(row, 0).formatter("@");
+                                sheet.setActiveCell(row, 0);
+                            });
+                            $('#codAleClose').click(function () {
+                                //me.reLockSomeCodes(sheet, 0, repositoryGljObj.currentCache.length);
+                                //sheetCommonObj.unLockAllCells(sheet);
+                                //me.reLockSomeCodes(sheet, 0, repositoryGljObj.currentCache.length);
+                                sheet.setValue(row, 0, orgCode);
+                                sheet.getCell(row, 0).formatter("@");
+                                sheet.setActiveCell(row, 0);
+                            });
+                            // sheet.setValue(row, col, orgCode);
+                            isExist = true
+                        }
+                    }
+                    if(!isExist){
+                        rst[setting.header[col].dataCode] = sheet.getValue(row, col);
+                    }
+                }
+                else{
+                    rst[setting.header[col].dataCode] = sheet.getValue(row, col);
+                }
+            }
+            else{
+                rst[setting.header[col].dataCode] = sheet.getValue(row, col);
+            }
+        }
+        return rst;
+    },
+    combineRationRowData: function(sheet, setting, row) {
+        var rst = {};
+        for (var col = 0; col < setting.header.length; col++) {
+            rst[setting.header[col].dataCode] = sheet.getValue(row, col);
+        }
+        return rst;
+    },
+    reLockSomeCodes: function (sheet, beginRow, endRow) {
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        let defaultStyle = new GC.Spread.Sheets.Style();
+        defaultStyle.locked = false;
+        sheet.setDefaultStyle(defaultStyle, GC.Spread.Sheets.SheetArea.viewport);
+        let unLockStyle = new GC.Spread.Sheets.Style();
+        unLockStyle.locked = false;
+        let lockStyle = new GC.Spread.Sheets.Style();
+        lockStyle.locked = true;
+        for(let row = beginRow; row < endRow; row++){
+            sheet.setStyle(row, 0, lockStyle);
+        }
+        for(let row = endRow; row < sheet.getRowCount(); row++){
+            sheet.setStyle(row, 0, unLockStyle);
+        }
+        sheet.options.isProtected = true;
+        sheet.resumePaint();
+        sheet.resumeEvent();
+    },
+    lockSomeCodes: function (sheet, beginRow, endRow) {
+        let defaultStyle = new GC.Spread.Sheets.Style();
+        defaultStyle.locked = false;
+        sheet.setDefaultStyle(defaultStyle, GC.Spread.Sheets.SheetArea.viewport);
+        let style = new  GC.Spread.Sheets.Style();
+        style.locked = true;
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        for(let i = beginRow; i < endRow; i++){
+            sheet.setStyle(i, 0, style);
+        }
+        sheet.options.isProtected = true;
+        sheet.resumePaint();
+        sheet.resumeEvent();
+    },
+    lockCodeCells: function (sheet, rowCount) {
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        let sheetRowCount = sheet.getRowCount();
+        let defaultStyle = new GC.Spread.Sheets.Style();
+        defaultStyle.locked = false;
+        sheet.setDefaultStyle(defaultStyle, GC.Spread.Sheets.SheetArea.viewport);
+        let style = new GC.Spread.Sheets.Style();
+        style.locked = true;
+        sheet.setStyle(-1, 0, style);
+        for(let i =rowCount; i<sheetRowCount; i++){
+            sheet.setStyle(i, -1, style);
+        }
+        sheet.options.isProtected = true;
+        sheet.resumePaint();
+        sheet.resumeEvent();
+    }
+};

+ 69 - 6
web/building_saas/main/html/main.html

@@ -574,9 +574,9 @@
         </div>
     </div>
     <!--工料机选择窗口-->
-    <div class="modal fade" id="glj_tree_div" data-backdrop="static">
+    <!--<div class="modal fade" id="glj_tree_div" data-backdrop="static">
         <div class="modal-dialog modal-lg" role="document" id="modalCon">
-            <div class="modal-content" >
+            <div class="modal-content" style="width: 910px;">
                 <div class="modal-header">
                     <h5 class="modal-title">请选择工料机</h5>
                     <button type="button" class="close" data-dismiss="modal" aria-label="Close">
@@ -586,8 +586,50 @@
                 </div>
                 <div class="modal-body">
                     <div class="row">
-                        <div class="col-4">
-                            <div  class="modal-auto-height" id="componentTreeDiv" style="overflow: hidden">
+                        <div class="col-4" >
+                            <div  class="modal-auto-height" id="componentTreeDiv" style="overflow: hidden;">
+                                &lt;!&ndash;<div class="print-list">&ndash;&gt;
+                                <div style="width: 100%; height: 100%; overflow: auto">
+                                    <ul id="gljTree" class="ztree"></ul>
+                                </div>
+                                &lt;!&ndash;</div>&ndash;&gt;
+                            </div>
+                        </div>
+                        <div class="col-8">
+                            <div class="row">
+                                <div class="col-12" id="gljRadios">
+                                    <input type="radio" class="glj-radio" name="glj" value="allGljs" checked>所有工料机&nbsp;&nbsp;
+                                    <input type="radio" class="glj-radio" name="glj" value="stdGLJ">标准工料机&nbsp;&nbsp;
+                                    <input type="radio" class="glj-radio" name="glj" value="complementaryGLJs">补充工料机&nbsp;&nbsp;
+                                    &lt;!&ndash; <div class="form-group"><input id="searchGlj" type="text" class="form-control-sm" placeholder="查询工料机"></div>&ndash;&gt;
+                                </div>
+                                <div class="modal-auto-height col-12" style="overflow: hidden" id="gljLibSheet">
+
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" id="componentsCacnel" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <a href="javascript:void(0);" id="glj_selected_conf" class="btn btn-primary">确定</a>
+                </div>
+            </div>
+        </div>
+    </div>-->
+    <div class="modal fade" id="glj_tree_div" data-backdrop="static">
+        <div class="modal-dialog modal-lg" role="document" id="modalCon">
+            <div class="modal-content" style="width: 910px;">
+                <div class="modal-header">
+                    <h5 class="modal-title">请选择工料机</h5>
+                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">&times;</span>
+                    </button>
+                    <input type="hidden" id="actionType">
+                </div>
+                <div class="modal-body">
+                        <div style="width: 33%; float: left;">
+                            <div  class="modal-auto-height" id="componentTreeDiv" style=" height: 415px; overflow: hidden;">
                                 <!--<div class="print-list">-->
                                 <div style="width: 100%; height: 100%; overflow: auto">
                                     <ul id="gljTree" class="ztree"></ul>
@@ -595,7 +637,7 @@
                                 <!--</div>-->
                             </div>
                         </div>
-                        <div class="col-8">
+                        <div style="width:67%; padding-left: 8px; float: left;">
                             <div class="row">
                                 <div class="col-12" id="gljRadios">
                                     <input type="radio" class="glj-radio" name="glj" value="allGljs" checked>所有工料机&nbsp;&nbsp;
@@ -608,7 +650,6 @@
                                 </div>
                             </div>
                         </div>
-                    </div>
                 </div>
                 <div class="modal-footer">
                     <button type="button" id="componentsCacnel" class="btn btn-secondary" data-dismiss="modal">取消</button>
@@ -703,6 +744,26 @@
             </div>
         </div>
     </div>
+    <!--弹出补充定额库-->
+    <div class="modal fade" id="comple-ration" data-backdrop="static">
+        <div class="modal-dialog modal-lg" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h5 class="modal-title">定额库</h5>
+                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">&times;</span>
+                    </button>
+                </div>
+                <div class="modal-auto-height">
+                    <table class="table table-hover table-bordered">
+                        <thead><tr><th>定额库名称</th></tr></thead>
+                        <tbody id="comple_ration_table">
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+        </div>
+    </div>
         <!-- JS. -->
         <script type="text/javascript" src="/lib/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js"></script>
 
@@ -824,6 +885,8 @@
         <script type="text/javascript" src="/web/building_saas/main/js/views/sub_fee_rate_views.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/calc_base_view.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_labour_coe_view.js"></script>
+        <script type="text/javascript" src="/web/building_saas/complementary_ration_lib/js/main.js"></script>
+         <script type="text/javascript" src="/public/web/storageUtil.js"></script>
         <!-- endinject -->
 
         <script type="text/javascript">

+ 34 - 8
web/building_saas/main/js/models/calc_base.js

@@ -201,7 +201,7 @@ let cbTools = {
         }
         function getBase(node){
             if(node && node.children.length === 0){
-                if(cbTools.isDef(node.data.calcBase)){
+                if(cbTools.isDef(node.data.calcBase) && node.data.calcBase !== ''){
                     let figures = cbParser.getFigure(node.data.calcBase);
                     tempBases = tempBases.concat(figures);
                 }
@@ -435,12 +435,23 @@ let cbAnalyzer = {
     },
     //输入合法性
     inputLegal: function (exp) {
-        let ilegalRex = /[^0-9,\u4e00-\u9fa5,\+,\-,\/,\*,\(,\),.]/g;
+        let ilegalRex = /[^0-9,\u4e00-\u9fa5,\+,\-,\/,\*,\(,\),.,{,}]/g;
         return !ilegalRex.test(exp);
     },
     //基数合法性、存在性
     baseLegal: function (baseFigures, exp) {
+        //保证中文表达式在{}里
+        let cnExps = cbParser.getCN(exp);
         let expFigures = cbParser.getFigure(exp);
+        if(cnExps.length !== expFigures.length){
+            return false;
+        }
+        for(let i = 0, len = cnExps.length; i < len; i++){
+            if(cnExps[i] !== expFigures[i]){
+                return false;
+            }
+        }
+        //基数存在性
         for(let i = 0, len = expFigures.length; i < len; i++){
             if(cbTools.isUnDef(baseFigures[expFigures[i]])){
                 return false;
@@ -485,9 +496,11 @@ let cbAnalyzer = {
         }
     },
     //四则运算合法性,前端控制不允许重复出现运算符,这里主要判断()的使用问题,这里再判断一次
-    arithmeticLeagl: function (exp) {
+    arithmeticLegal: function (exp) {
         let ilegalRex = /[\+,\-,\*,\/]{2}/g;
-        return !ilegalRex.test(exp);
+        let rex2 = /[{]{2}/g;
+        let rex3 = /[}]{2}/g;
+        return !ilegalRex.test(exp) && !rex2.test(exp) && !rex3.test(exp);
     },
     //
     legalExp: function (node) {
@@ -495,7 +508,7 @@ let cbAnalyzer = {
         if(this.inputLegal(exp)){
             if(this.baseLegal(cbTools.getFigure(node), exp)){
                 if(!this.cycleCalc(node, cbTools.getFigure(node), exp)){
-                    if(this.arithmeticLeagl(exp)){
+                    if(this.arithmeticLegal(exp)){
                         return exp;
                     }
                 }
@@ -508,8 +521,8 @@ let cbAnalyzer = {
 
 //输入式转换器
 let cbParser = {
-    //获取表达式中的基数
-    getFigure: function(expr){
+    //获取表达式中的中文式,没有{}需求时
+    getCN: function(expr){
         let rst = [];
         let cnRex = /[^\u4e00-\u9fa5]/;
         let temp = expr.split(cnRex);
@@ -520,6 +533,18 @@ let cbParser = {
         }
         return rst;
     },
+    //获取表达式中的基数
+    getFigure: function(expr){
+        let rst = [];
+        let rex = /\{([^}]*)\}/g;
+        let temp = expr.match(rex);
+        if(cbTools.isDef(temp)){
+            for(let i = 0, len = temp.length; i < len; i++){
+                rst.push(temp[i].replace(/[{,}]/g, ''));
+            }
+        }
+        return rst;
+    },
 
     //将表达式转换为可编译的表达式
     toCompileExpr: function(v){
@@ -533,6 +558,8 @@ let cbParser = {
             exp.orgExp = strs[i];
             exps.push(exp);
         }
+        //去{}
+        v = v.replace(/[{, }]/g, '');
         for(let i = 0, len = exps.length;i < len; i++){
             exps[i].compileExp = '$CBC.base(\'' + exps[i].orgExp;
             exps[i].compileExp = exps[i].compileExp + '\')';
@@ -599,7 +626,6 @@ let calcBase = {
             if(!cbTools.isDef(exp)){
                 throw '表达式不正确';
             }
-
             //输入式转换表达式
             let compileExp = $CBP.toCompileExpr(exp);
 

+ 7 - 7
web/building_saas/main/js/views/calc_base_view.js

@@ -8,7 +8,6 @@ let calcBaseView = {
     //可用计算基数的清单固定列映射(与fixedFlag)
     inputExpr: $('#calcBaseExp'),
     confirmBtn: $('#calcBaseConf'),
-    noBaseBills: [1, 3],
     editingCell: null,
     workBook: null,
     setting:{
@@ -24,7 +23,6 @@ let calcBaseView = {
             allowUserDragFill: false,
             scrollbarMaxAlign : true
         },
-        dateRows: [],
         locked: {
             rows: [],
             cols: [0, 1]
@@ -96,7 +94,7 @@ let calcBaseView = {
     onCellDoubleClick: function (sender, args) {
         let me = calcBaseView;
         if(args.col === 0){
-            let baseFigure = args.sheet.getValue(args.row, args.col);
+            let baseFigure = '{' + args.sheet.getValue(args.row, args.col) + '}';
             if(baseFigure.trim() !== ''){
                 //在光标后面插入
                 let insertStr = me.insertStr(baseFigure);
@@ -148,9 +146,11 @@ let calcBaseView = {
     },
 
     //四则运算符控制,不可连续出现: ++ +*...
-    arithmeticLeagl: function (v) {
+    arithmeticLegal: function (v) {
         let rex = /[\+,\-,\*,\/]{2}/g;
-        return !rex.test(v);
+        let rex2 = /[{]{2}/g;
+        let rex3 = /[}]{2}/g;
+        return !rex.test(v) && !rex2.test(v) && !rex3.test(v);
     },
 
     //运算符点击显示到运算窗口
@@ -160,7 +160,7 @@ let calcBaseView = {
             operators[i].bind('click', function () {
                 let v = $(this)[0].textContent;
                 let insertStr = me.insertStr(v);
-                if(me.arithmeticLeagl(insertStr)){
+                if(me.arithmeticLegal(insertStr)){
                     me.inputExpr.val(insertStr);
                 }
                 me.inputExpr.focus();
@@ -184,7 +184,7 @@ let calcBaseView = {
     inputControl: function () {
         let me = calcBaseView;
         me.inputExpr.keydown(function (e) {
-            if(!me.arithmeticLeagl(me.inputExpr.val() + e.key)){
+            if(!me.arithmeticLegal(me.inputExpr.val() + e.key)){
                 return false;
             }
         });

+ 51 - 40
web/building_saas/main/js/views/character_content_view.js

@@ -78,27 +78,31 @@ let contentOprObj = {
         sheet.addRows(sheet.getRowCount(), 1);
         sheet.getCell(sheet.getRowCount() - 1, 1).cellType(checkBox);
     },
-    upMove: function (rowIdx) {
+    upMove: function (cell) {
         let me = contentOprObj;
-        let thisObj = me.currentCache[rowIdx],
-            preObj = me.currentCache[rowIdx - 1],
+        let thisObj = me.currentCache[cell.row],
+            preObj = me.currentCache[cell.row - 1],
             temp, contentTxt;
         temp = thisObj.serialNo;
         thisObj.serialNo = preObj.serialNo;
         preObj.serialNo = temp;
         me.sortCache(me.currentCache);
-        me.save();
+        me.save(function () {
+            me.workBook.getSheet(0).setActiveCell(cell.row - 1, cell.col);
+        });
     },
-    downMove: function (rowIdx) {
+    downMove: function (cell) {
         let me = contentOprObj;
-        let thisObj = me.currentCache[rowIdx],
-            nextObj = me.currentCache[rowIdx + 1],
+        let thisObj = me.currentCache[cell.row],
+            nextObj = me.currentCache[cell.row + 1],
             temp, contentTxt;
         temp = thisObj.serialNo;
         thisObj.serialNo = nextObj.serialNo;
         nextObj.serialNo = temp;
         me.sortCache(me.currentCache);
-        me.save();
+        me.save(function () {
+            me.workBook.getSheet(0).setActiveCell(cell.row + 1, cell.col);
+        });
     },
     deleteContent: function (rowIdx) {
         let me = contentOprObj;
@@ -117,14 +121,10 @@ let contentOprObj = {
         me.currentCache.push(newObj);
 
     },
-    save: function () {
+    save: function (callback) {
         let selectedNode = projectObj.mainController.tree.selected;
-        const setting = projectObj.project.property.addRule !== undefined ? projectObj.project.property.addRule : null;
-        pageCCOprObj.setCharacterBySetting(selectedNode, setting);
-        // let me = contentOprObj;
-        // let contentTxt = me.getColData(me.currentCache);
-        // let txtObj =  {field: 'jobContentText', text: contentTxt ? contentTxt : ''};
-        // pageCCOprObj.updateCharacterContent(pageCCOprObj.currentFindSet, {field: 'jobContent', updateArr: me.currentCache}, txtObj, contentOprObj);
+        const setting = projectObj.project.property.addRule !== undefined ? projectObj.project.property.addRule : getAddRuleSetting();
+        pageCCOprObj.setCharacterBySetting(contentOprObj, selectedNode, setting, callback);
     },
     onEditEnded: function (sender, args) {
         let me = contentOprObj;
@@ -248,11 +248,11 @@ let contentOprObj = {
                                 me.deleteContent(target.row);
                             }},
                             "upMove": {name: "上移", disabled: upDis, icon: "fa-arrow-up", callback: function (key, opt) {
-                                me.upMove(target.row);
+                                me.upMove({row: target.row, col: target.col});
 
                             }},
                             "downMove": {name: "下移", disabled: downDis, icon: "fa-arrow-down", callback: function (key, opt) {
-                                me.downMove(target.row);
+                                me.downMove({row: target.row, col: target.col});
                             }}
                         }
                     };
@@ -391,27 +391,31 @@ let characterOprObj = {
         sheet.getCell(rowIdx, 1).cellType(combo);
         sheet.getCell(rowIdx, 2).cellType(checkBox);
     },
-    upMove: function (rowIdx) {
+    upMove: function (cell) {
         let me = characterOprObj;
-        let thisObj = me.currentCache[rowIdx],
-            preObj = me.currentCache[rowIdx - 1],
+        let thisObj = me.currentCache[cell.row],
+            preObj = me.currentCache[cell.row - 1],
             temp;
         temp = thisObj.serialNo;
         thisObj.serialNo = preObj.serialNo;
         preObj.serialNo = temp;
         contentOprObj.sortCache(me.currentCache);
-        me.save();
+        me.save(function () {
+            me.workBook.getSheet(0).setActiveCell(cell.row - 1, cell.col);
+        });
     },
-    downMove: function (rowIdx) {
+    downMove: function (cell) {
         let me = characterOprObj;
-        let thisObj = me.currentCache[rowIdx],
-            nextObj = me.currentCache[rowIdx + 1],
+        let thisObj = me.currentCache[cell.row],
+            nextObj = me.currentCache[cell.row + 1],
             temp;
         temp = thisObj.serialNo;
         thisObj.serialNo = nextObj.serialNo;
         nextObj.serialNo = temp;
         contentOprObj.sortCache(me.currentCache);
-        me.save();
+        me.save(function () {
+            me.workBook.getSheet(0).setActiveCell(cell.row + 1, cell.col);
+        });
     },
     deleteCharacter: function (rowIdx) {
         let me = characterOprObj;
@@ -491,14 +495,10 @@ let characterOprObj = {
             me.currentCache.push(newCharacter);
         }
     },
-    save: function () {
+    save: function (callback) {
         let selectedNode = projectObj.mainController.tree.selected;
-        const setting = projectObj.project.property.addRule !== undefined ? projectObj.project.property.addRule : null;
-        pageCCOprObj.setCharacterBySetting(selectedNode, setting);
-        // let me = characterOprObj;
-        // let characterTxt = me.getColData(me.currentCache);
-        // let txtObj =  {field: 'itemCharacterText', text: characterTxt ? characterTxt : ''};
-        // pageCCOprObj.updateCharacterContent(pageCCOprObj.currentFindSet, {field: 'itemCharacter', updateArr: me.currentCache}, txtObj, characterOprObj);
+        const setting = projectObj.project.property.addRule !== undefined ? projectObj.project.property.addRule : getAddRuleSetting();
+        pageCCOprObj.setCharacterBySetting(characterOprObj, selectedNode, setting, callback);
     },
     onEditStart: function (sender, args) {
         let me = characterOprObj;
@@ -627,10 +627,10 @@ let characterOprObj = {
                                 me.deleteCharacter(target.row);
                             }},
                             "upMove": {name: "上移", disabled: upDis, icon: "fa-arrow-up", callback: function (key, opt) {
-                                me.upMove(target.row);
+                                me.upMove({row: target.row, col: target.col});
                             }},
                             "downMove": {name: "下移", disabled: downDis, icon: "fa-arrow-down", callback: function (key, opt) {
-                                me.downMove(target.row);
+                                me.downMove({row: target.row, col: target.col});
                             }}
                         }
                     };
@@ -737,7 +737,7 @@ let pageCCOprObj = {
         projectObj.mainSpread.focus(true);
     },
     //更新特征及内容数据
-    updateCharacterContent: function (findSet, updateObj, txtObj, oprObj) {
+    updateCharacterContent: function (findSet, updateObj, txtObj, oprObj, callback) {
         let me = pageCCOprObj, updateCol;
         if(txtObj){
             updateCol = txtObj.field === 'itemCharacterText' ? 4 : 5;//更新清单行特征列或内容列
@@ -763,6 +763,9 @@ let pageCCOprObj = {
                 let activeCell = projectObj.mainSpread.getActiveSheet().getSelections()[0];
                 projectObj.mainSpread.getActiveSheet().setValue(activeCell.row, updateCol, txtObj.text + ''); //刷新输出显示
                 projectObj.mainSpread.getActiveSheet().autoFitRow(activeCell.row);
+                if(callback){
+                    callback();
+                }
             }
         });
     },
@@ -819,7 +822,7 @@ let pageCCOprObj = {
      * @param {Object} setting - 设置
      * @return {void}
      */
-    setCharacterBySetting: function(node, setting) {
+    setCharacterBySetting: function(oprObj, node, setting, callback) {
         let self = this;
 
         // 保存的条件数据
@@ -840,6 +843,10 @@ let pageCCOprObj = {
             node.data.name = updateData.name;
             node.data.itemCharacterText = updateData.itemCharacterText;
             node.data.jobContentText = updateData.jobContentText;
+            pageCCOprObj.showData(oprObj.workBook.getSheet(0), oprObj.setting, oprObj.currentCache);//刷新特征及内容Spread
+            if(callback){
+                callback();
+            }
         });
 
     },
@@ -979,6 +986,10 @@ let pageCCOprObj = {
      * @return {Object} - 返回更新的数据
      */
     getCharacterUpdateData: function(setting, node) {
+        // 获取原名称
+        const name = node.data.name.split("\n");
+        this.nameCache = name[0] !== undefined ? name[0] : "";
+
         let updateData = {
             itemCharacterText: '',
             jobContentText: '',
@@ -1027,10 +1038,10 @@ let pageCCOprObj = {
         switch (setting.displayFormat) {
             case "1":
                 // 换行分隔
-                content = contentArray.join("\r\n");
+                content = contentArray.join("\n");
 
-                currentData.character = currentData.character.join("\r\n");
-                currentData.content = currentData.content.join("\r\n");
+                currentData.character = currentData.character.join("\n");
+                currentData.content = currentData.content.join("\n");
                 break;
             case "2":
                 // 逗号分隔
@@ -1052,7 +1063,7 @@ let pageCCOprObj = {
                 break;
             case "2":
                 // 添加到清单名称列
-                content = this.nameCache + "\r\n" + content;
+                content = this.nameCache + "\n" + content;
                 updateData.name = content;
                 break;
             case "3":

+ 2 - 2
web/building_saas/main/js/views/glj_view.js

@@ -226,8 +226,8 @@ var gljOprObj = {
                 vAlign: "center"
             },
             {
-                headerName: "计量单位",
-                headerWidth: 80,
+                headerName: "单位",
+                headerWidth: 40,
                 dataCode: "unit",
                 dataType: "String",
                 hAlign: "center",

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

@@ -105,7 +105,7 @@ function toUpdateDecimal(orgV, newV){
 function setDecimal(_digits, data){
     if(isDef(data)){
         for(let attr in data){
-            _digits[attr] = data[attr] || defaultDecimal['_def'][attr]['data'];
+            _digits[attr] = returnV(data[attr], defaultDecimal['_def'][attr]['data']);
         }
     }
     else {

+ 7 - 31
web/building_saas/main/js/views/sub_view.js

@@ -129,9 +129,6 @@ $("#use-to-current").click(function() {
     const self = $(this);
     self.attr('disabled', 'disabled');
     let selectedNode = projectObj.mainController.tree.selected;
-    // 获取原名称
-    const name = selectedNode.data.name.split("\r\n");
-    pageCCOprObj.nameCache = name[0] !== undefined ? name[0] : "";
     // 操作内容
     pageCCOprObj.setCharacterBySetting(selectedNode, setting);
 
@@ -148,35 +145,14 @@ $("#use-to-all").click(function() {
     if (treeNode.items === undefined || treeNode.items.length <= 0) {
         return false;
     }
-    // 获取所有标准清单
-    const stdBillsLibID = $("#stdBillsLibSelect").is(":visible") ?
-        $("#stdBillsLibSelect").val() : (projectInfoObj.projectInfo.engineeringInfo.bill_lib[0] !== undefined ? projectInfoObj.projectInfo.engineeringInfo.bill_lib[0].id : 0);
-    if (stdBillsLibID <= 0) {
-        return false;
-    }
-    let stdBillData = {};
-    CommonAjax.post('/stdBillsEditor/getBills', {userId: userID, billsLibId: stdBillsLibID}, function (data) {
-        if (!data instanceof Array || data.length <= 0) {
-            return false;
+    // 处理结果
+    for (const item of treeNode.items) {
+        if (item.data.jobContent === undefined || item.data.jobContent.length <= 0 ||
+            item.data.itemCharacter === undefined || item.data.itemCharacter.length <= 0 || item.data.code === undefined) {
+            continue;
         }
-        // 整理数据
-        for (const tmp of data) {
-            stdBillData[tmp.code] = tmp;
-        }
-        // 处理结果
-        for (const item of treeNode.items) {
-            if (item.data.jobContent === undefined || item.data.jobContent.length <= 0 ||
-                item.data.itemCharacter === undefined || item.data.itemCharacter.length <= 0 || item.data.code === undefined) {
-                continue;
-            }
-            const orgCode = item.data.code.substr(0, 9);
-            if (stdBillData[orgCode] === undefined) {
-                continue;
-            }
-            pageCCOprObj.nameCache = stdBillData[orgCode].name;
-            pageCCOprObj.setCharacterBySetting(item, setting);
-        }
-    });
+        pageCCOprObj.setCharacterBySetting(item, setting);
+    }
 });
 
 // 添加位置选择

+ 16 - 0
web/building_saas/report/html/rpt_main.html

@@ -73,6 +73,22 @@
                             报表设置
                         </div>
                     </div>
+                    <div class="panel">
+                        <div class="panel-body">
+                            <div class="input-group input-group-sm" role="group">
+                            <span class="input-group-btn">
+                              <button type="button" class="btn btn-secondary btn-sm" data-toggle="tooltip" data-placement="bottom" title="上一页"><i class="fa fa-chevron-left" onclick="rptControlObj.prePage(this)"></i></button>
+                            </span>
+                                <input class="form-control" id="rpt_page_num" value="" style="width:60px"  data-toggle="tooltip" data-placement="bottom" title="输入页码按回车键,快速跳转">
+                                <span class="input-group-btn">
+                              <button type="button" class="btn btn-secondary btn-sm" data-toggle="tooltip" data-placement="bottom" title="下一页"><i class="fa fa-chevron-right" onclick="rptControlObj.nextPage(this)"></i></button>
+                            </span>
+                            </div>
+                        </div>
+                        <div class="panel-foot text-muted">
+                            翻页
+                        </div>
+                    </div>
                 </div>
             </div>
             <div class="print-view poj-list">

+ 14 - 0
web/building_saas/report/js/rpt_main.js

@@ -85,6 +85,7 @@ let zTreeOprObj = {
                         me.currentRptPageRst = pageRst;
                         me.maxPages = pageRst.items.length;
                         me.currentPage = 1;
+                        me.displayPageValue();
                         let size = JpcCanvasOutput.getReportSizeInPixel(me.currentRptPageRst, getScreenDPI());
                         canvas.width = size[0] + 20;
                         if (size[1] > size[0]) {
@@ -106,6 +107,11 @@ let zTreeOprObj = {
             JpcCanvasOutput.drawPageBorder(me.currentRptPageRst, canvas, getScreenDPI());
             JpcCanvasOutput.drawToCanvas(me.currentRptPageRst, canvas, me.currentPage);
         }
+        me.displayPageValue();
+    },
+    displayPageValue: function() {
+        let me = zTreeOprObj;
+        $("#rpt_page_num").get(0).value = me.currentPage + "/" + me.maxPages;
     }
 };
 
@@ -210,5 +216,13 @@ let rptControlObj = {
                 me.getCurrentPageSize() + "/" + orgRptName;
             window.location = url;//这里不能使用get方法跳转,否则下载不成功
         }
+    },
+    prePage: function(dom) {
+        let canvas = document.getElementById("rptCanvas");
+        zTreeOprObj.showPage(zTreeOprObj.currentPage - 1, canvas);
+    },
+    nextPage: function(dom) {
+        let canvas = document.getElementById("rptCanvas");
+        zTreeOprObj.showPage(zTreeOprObj.currentPage + 1, canvas);
     }
 };

+ 2 - 1
web/common/html/header.html

@@ -10,7 +10,8 @@
         <li class="nav-item dropdown">
             <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-wrench"></i> 工具</a>
             <div class="dropdown-menu">
-                <a class="dropdown-item" href="#">定额库编辑器</a>
+                <!--<a class="dropdown-item" href="/complementaryRation/main">定额库编辑器</a>-->
+                <a class="dropdown-item" href="javascript:void(0);" data-toggle="modal" data-target="#comple-ration">定额库编辑器</a>
                 <a class="dropdown-item" href="/complementaryGlj">工料机库编辑器</a>
             </div>
         </li>