Quellcode durchsuchen

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

TonyKang vor 7 Jahren
Ursprung
Commit
3c20c518ef

+ 42 - 0
modules/ration_repository/controllers/installation_controller.js

@@ -0,0 +1,42 @@
+/**
+ * Created by Zhong on 2018/1/24.
+ */
+import BaseController from '../../common/base/base_controller';
+import InstallationDao from '../models/installation';
+
+let installationDao = new InstallationDao();
+let callback = function(req,res,err,message, data){
+    res.json({error: err, message: message, data: data});
+};
+
+class InstallationController extends BaseController{
+    getInstallation(req, res){
+        let data = JSON.parse(req.body.data);
+        installationDao.getInstallation(data.rationRepId, function (err, data) {
+            callback(req, res, err, '', data);
+        });
+    }
+
+    updateSection(req, res){
+        let data = JSON.parse(req.body.data);
+        installationDao.updateSection(data.updateData, function (err, data) {
+            callback(req, res, err, '', data);
+        });
+    }
+
+    updateFeeItem(req, res){
+        let data = JSON.parse(req.body.data);
+        installationDao.updateFeeItem(data.updateData, function (err, data) {
+            callback(req, res, err, '', data);
+        });
+    }
+
+    batchUpdateInst(req, res){
+        let data = JSON.parse(req.body.data);
+        installationDao.batchUpdateInst(data.rationSection, data.inst, function (err, data) {
+            callback(req, res, err, '', data);
+        });
+    }
+}
+
+export default InstallationController;

+ 76 - 0
modules/ration_repository/models/installation.js

@@ -0,0 +1,76 @@
+/**
+ * Created by Zhong on 2018/1/24.
+ */
+
+import {rationItemModel, installFeeItemModel, installSectionModel} from '../models/schemas';
+
+class InstallationDao{
+    async getInstallation(rationRepId, callback){
+        try {
+            let feeItems = await installFeeItemModel.find({rationRepId: rationRepId, $or: [{deleted: false}, {deleted: null}]});
+            for(let feeItem of feeItems){
+                let sids = [];
+                for(let sec of feeItem.section){
+                    sids.push(sec.ID);
+                }
+                if(sids.length > 0){
+                    let sections = await installSectionModel.find({ID: {$in: sids}, $or: [{deleted: false}, {deleted: null}]});
+                    feeItem._doc.section = sections;
+                }
+            }
+            callback(0, feeItems);
+        }
+        catch(err){
+            callback(err, null);
+        }
+    }
+
+    async updateSection(updateData, callback){
+        try{
+            for(let data of updateData){
+                if(data.updateType === 'new'){
+                    await installSectionModel.create(data.updateData);
+                }
+                else if(data.updateType === 'update'){
+                    await installSectionModel.update({ID: data.updateData.ID}, data.updateData);
+                }
+            }
+            callback(0, null);
+        }
+        catch(err){
+            callback(err, null);
+        }
+    }
+
+    async updateFeeItem(updateData, callback){
+        try{
+            for(let data of updateData){
+                if(data.updateType === 'new'){
+                    await installFeeItemModel.create(data.updateData);
+                }
+                else if(data.updateType === 'update'){
+                    await installFeeItemModel.update({ID: data.updateData.ID}, data.updateData);
+                }
+            }
+            callback(0, null);
+        }
+        catch(err){
+            callback(err, null);
+        }
+    }
+
+    async batchUpdateInst(rationSection, inst, callback){
+        try{
+            for(let sectionId of rationSection){
+                await rationItemModel.update({sectionId: sectionId, $or: [{isDeleted: null}, {isDeleted: false}]},
+                    {$addToSet: {rationInstList: {feeItemId: inst.feeItemId, sectionId: inst.sectionId}}}, {multi: true});
+            }
+            callback(0, null);
+        }
+        catch(err){
+            callback(err, null);
+        }
+    }
+}
+
+export default InstallationDao;

+ 16 - 6
modules/ration_repository/models/schemas.js

@@ -69,6 +69,12 @@ let rationGljItemSchema = new Schema({
     proportion: Number //配合比,暂时无需使用,默认0
 }, { _id: false });
 
+//定额安装增加费用
+let rationInstSchema = new Schema({
+    feeItemId: String,
+    sectionId: String
+},{_id: false});
+
 //辅助定额调整
 let rationAssItemSchema = new Schema({
     name: String,
@@ -85,7 +91,6 @@ let rationAssItemSchema = new Schema({
 //安装增加费-费用规则
 let feeRuleSchema = new Schema({
     ID: String,
-    sectionId: String, //分册章节id
     code: String,
     rule: String,
     base: String,
@@ -97,20 +102,24 @@ let feeRuleSchema = new Schema({
 
 //安装增加费-分册章节
 let installSectionSchema = new Schema({
+    rationRepId: Number,
     ID: String,
     feeItemId: String,
     name: String,
-    feeRule: [feeRuleSchema]
-});
+    feeRule: [feeRuleSchema],
+    deleted: false
+}, {versionKey: false});
 
 //安装增加费-费用项
 let installFeeItemSchema = new Schema({
+    rationRepId: Number,
     ID: String,
     feeItem: String, //费用项
     feeType: String, //费用类型
     position: String, //记取位置
-    section: []
-});
+    section: [],
+    deleted: false
+}, {versionKey: false});
 
 //定额
 var rationItemSchema = new Schema({
@@ -131,6 +140,7 @@ var rationItemSchema = new Schema({
     rationGljList: [rationGljItemSchema],
     rationCoeList: Array,
     rationAssList: [rationAssItemSchema],
+    rationInstList: [rationInstSchema],
     isDeleted: Boolean
 });
 
@@ -162,7 +172,7 @@ let coeListModel = db.model("std_ration_lib_coe_list",coeListSchema, "std_ration
 let rationRepository = db.model("std_ration_lib_map", RepositoryMapSchema, "std_ration_lib_map");
 let rationChapterTreeModel = db.model("std_ration_lib_ration_chapter_trees", rationChapterTreeSchema, "std_ration_lib_ration_chapter_trees");
 let rationItemModel = db.model("std_ration_lib_ration_items",rationItemSchema, "std_ration_lib_ration_items");
-let installSectionModel = db.model("std_ration_lib_installationSection", installSectionSchema, "std_ration_lib_installationSection")
+let installSectionModel = db.model("std_ration_lib_installationSection", installSectionSchema, "std_ration_lib_installationSection");
 let installFeeItemModel = db.model("std_ration_lib_installation", installFeeItemSchema, "std_ration_lib_installation");
 //补充定额
 let compleRationModel = db.model('complementary_ration_items', compleRationSchema, 'complementary_ration_items');

+ 8 - 0
modules/ration_repository/routes/ration_rep_routes.js

@@ -12,11 +12,13 @@ import RepositoryGljController from "../controllers/repository_glj_controller";
 import CoeListController from "../controllers/coe_controller";
 import SearchController from "../controllers/search_controller";
 import GljController from "../../std_glj_lib/controllers/gljController";
+import InstallationController from '../controllers/installation_controller';
 let viewsController = new ViewsController();
 let rationRepositoryController = new RationRepositoryController();
 let rationChapterTreeController = new RationChapterTreeController();
 let rationController = new RationController();
 let coeListController = new CoeListController();
+let installationController = new InstallationController();
 let searchController = new SearchController();
 let repositoryGljController = new RepositoryGljController();
 let gljController = new GljController();
@@ -71,6 +73,12 @@ module.exports =  function (app) {
     apiRouter.post("/getCoeItemsByIDs",coeListController.auth, coeListController.init, coeListController.getCoeItemsByIDs);
     apiRouter.post("/getCoeItemsByNos",coeListController.auth, coeListController.init, coeListController.getCoeItemsByNos);
 
+    //安装增加费
+    apiRouter.post('/getInstallation', installationController.auth, installationController.init, installationController.getInstallation);
+    apiRouter.post('/updateFeeItem', installationController.auth, installationController.init, installationController.updateFeeItem);
+    apiRouter.post('/updateSection', installationController.auth, installationController.init, installationController.updateSection);
+    apiRouter.post('/batchUpdateInst', installationController.auth, installationController.init, installationController.batchUpdateInst);
+
     apiRouter.post('/getRationItem',searchController.auth, searchController.init, searchController.getRationItem);
     apiRouter.post('/findRation', searchController.auth, searchController.init, searchController.findRation);
 

+ 171 - 0
web/maintain/ration_repository/anzhuang.html

@@ -0,0 +1,171 @@
+<!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/spreadjs/sheets/css/gc.spread.sheets.excel2013lightGray.10.0.1.css" type="text/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/jquery-contextmenu/jquery.contextMenu.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="dinge" href="dinge.html">定额</a>
+                  </li>
+                  <li class="nav-item">
+                      <a class="nav-link px-3" id="gongliao" href="gongliao.html">工料机</a>
+                  </li>
+                  <li class="nav-item">
+                      <a class="nav-link px-3" id="fuzhu" href="fuzhu.html">附注条件</a>
+                  </li>
+                  <li class="nav-item">
+                      <a class="nav-link active px-3" >安装增加费</a>
+                  </li>
+              </ul>
+        </nav>
+    </div>
+    <div class="main">
+        <div class="content">
+            <div class="container-fluid">
+              <div class="row">
+                <div class="main-content col-lg-12 p-0">
+                    <div class="container-fluid">
+                      <div class="row">
+                          <div class="main-data-top-fluid" id="feeItemSpread" style="width: 50%">
+                          <!--  <table class="table table-sm table-bordered mt-1">
+                              <thead><tr><th></th><th>费用项</th><th>费用类型</th><th>记取位置</th></tr></thead>
+                              <tbody>
+                                <tr><td>1</td><td>高层增加费</td><td>子目费用</td><td></td></tr>
+                              </tbody>
+                            </table>-->
+                          </div>
+                          <div class="main-data-top-fluid" id="instSectionSpread" style="width: 50%" >
+                            <!--<table class="table table-sm table-bordered mt-1">
+                              <thead><tr><th></th><th>分册章节</th></tr></thead>
+                              <tbody>
+                                <tr><td>1</td><td>第一册 机械设备安装工程1~6、8~16章节</td></tr>
+                              </tbody>
+                            </table>-->
+                          </div>
+                      </div>
+                    </div>
+                    <div class="bottom-content" id="instFeeRuleSpread">
+                        <!--<table class="table table-sm table-bordered">
+                          <thead><tr><th></th><th>编码</th><th>费用规则</th><th>基数</th><th>费率(%)</th><th>其中人工(%)</th><th>其中材料(%)</th><th>其中机械(%)</th></tr></thead>
+                          <tbody>
+                            <tr><td>1</td><td>AZFY1</td><td>超高费(标高15m以内)(第一册 机械设备安装工程1~6章节)</td><td>分贝按人材机乘系数</td><td></td><td>25</td><td></td><td>25</td></tr>
+                          </tbody>
+                        </table>-->
+                    </div>
+                  </div>
+              </div>
+            </div>
+        </div>
+    </div>
+    <button id="rcjAlertBtn" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#rcjAlert" 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="rcjAlert" 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">人工、材料、机械之和必须为100,是否取消输入?</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-secondary" id="codAlertQX" data-dismiss="modal">取消</button>
+                    <button type="button" class="btn btn-danger" id="codAlertQR" data-dismiss="modal">确认</button>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <!--批量关联分册至定额-->
+    <div class="modal fade" id="sectionTreeModal" data-backdrop="static">
+        <div class="modal-dialog modal-feeRate" role="document" id="fee_rate_dialog">
+            <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-body" >
+                    <input type="hidden" id="edit_from">
+                    <div class="row" style="height: 500px">
+                        <div class="modal-auto-height col-12" style="overflow: hidden" id="batchSectionSpread"></div>
+                    </div>
+                    <div class="modal-footer">
+                        <button type="button" id="scTreeCancel" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                        <a href="javascript:void(0);" id="bsTree_conf" class="btn btn-primary">确定</a>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <!-- JS. -->
+    <!-- JS. -->
+    <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 src="/lib/jquery/jquery.min.js"></script>
+    <script src="/lib/jquery-contextmenu/jquery.contextMenu.min.js"></script>
+    <script src="/lib/jquery-contextmenu/jquery.ui.position.js"></script>
+    <script src="/lib/tether/tether.min.js"></script>
+    <script src="/lib/bootstrap/bootstrap.min.js"></script>
+    <script type="text/javascript" src="/public/web/QueryParam.js"></script>
+    <script src="/public/web/uuid.js"></script>
+    <script src="/public/web/scMathUtil.js"></script>
+    <script src="/public/common_util.js"></script>
+    <script src="/public/web/storageUtil.js"></script>
+    <script  src="/public/web/id_tree.js"></script>
+    <script src="/public/web/tree_sheet/tree_sheet_controller.js"></script>
+    <script src="/public/web/tree_sheet/tree_sheet_helper.js"></script>
+    <script src="/public/web/sheet/sheet_common.js"></script>
+    <script src="/public/web/common_ajax.js"></script>
+    <script src="/web/maintain/ration_repository/js/global.js"></script>
+    <script src="/web/maintain/ration_repository/js/installation.js"></script>
+
+</body>
+<script type="text/javascript">
+    autoFlashHeight();
+</script>
+
+</html>

+ 10 - 3
web/maintain/ration_repository/dinge.html

@@ -97,8 +97,7 @@
                                           <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>
+                                          <a class="nav-link" id="linkAZZJ" data-toggle="tab" href="#" role="tab">安装增加费</a>
                                       </li>
                                   </ul>
                                   <!-- 内容 -->
@@ -461,6 +460,7 @@
         <script type="text/javascript" src="/web/maintain/ration_repository/js/rationUnits.js"></script>
         <script type="text/javascript" src="/web/maintain/ration_repository/js/ration.js"></script>
         <script type="text/javascript" src="/web/maintain/ration_repository/js/ration_glj.js"></script>
+        <script type="text/javascript" src="/web/maintain/ration_repository/js/ration_installation.js"></script>
         <script type="text/javascript" src="/public/web/sheet/sheet_creater.js"></script>
         <script type="text/javascript" src="/web/maintain/ration_repository/js/ration_coe.js"></script>
         <script type="text/javascript" src="/web/maintain/ration_repository/js/ration_assist.js"></script>
@@ -523,7 +523,7 @@
                // sheetCommonObj.shieldAllCells(rationOprObj.workBook.getSheet(0), rationOprObj.setting);
 
                // tabPanel 下有多个Spread时,相互之间不能正确显示。改成一个Spread下多个Sheet。
-                var rdSpread = sheetCommonObj.createSpread($("#rdSpread")[0], 3);
+                var rdSpread = sheetCommonObj.createSpread($("#rdSpread")[0], 4);
                 rationGLJOprObj.buildSheet(rdSpread.getSheet(0));
                // sheetCommonObj.shieldAllCells(rdSpread.getSheet(0), rationGLJOprObj.setting);
 
@@ -532,6 +532,9 @@
 
                 rationCoeOprObj.buildSheet(rdSpread.getSheet(2));
               //  sheetCommonObj.shieldAllCells(rdSpread.getSheet(2), rationCoeOprObj.setting);
+                rationInstObj.getInstallation(parseInt(getQueryString("repository")), function () {
+                    rationInstObj.buildSheet(rdSpread.getSheet(3));
+                });
 
                 $("#linkGLJ").click(function(){
                     rationGLJOprObj.bindRationGljDelOpr();
@@ -547,6 +550,10 @@
                     rationCoeOprObj.bindRationCoeDel();
                     rdSpread.setActiveSheetIndex(2);
                 });
+                $("#linkAZZJ").click(function(){
+                    rationInstObj.bindRationInstDel();
+                    rdSpread.setActiveSheetIndex(3);
+                });
             });
         </script>
     </div>

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

@@ -10,6 +10,7 @@ function autoFlashHeight(){
     $(".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-top-fluid").height($(window).height()-headerHeight-bottomContentHeight-2);
     $(".main-data").height($(window).height()-headerHeight);
     $(".main-side .tab-content").height($(window).height()-headerHeight-38);
 };

Datei-Diff unterdrückt, da er zu groß ist
+ 1206 - 0
web/maintain/ration_repository/js/installation.js


+ 13 - 2
web/maintain/ration_repository/js/ration.js

@@ -82,10 +82,12 @@ let rationOprObj = {
             let me = rationOprObj,
                 sheetGLJ = rationGLJOprObj.sheet, settingGLJ = rationGLJOprObj.setting,
                 sheetCoe = rationCoeOprObj.sheet, settingCoe = rationCoeOprObj.setting,
-                sheetAss = rationAssistOprObj.sheet, settingAss = rationAssistOprObj.setting;
+                sheetAss = rationAssistOprObj.sheet, settingAss = rationAssistOprObj.setting,
+                sheetInst = rationInstObj.sheet, settingInst = rationInstObj.setting;
             sheetCommonObj.cleanSheet(sheetGLJ, settingGLJ, -1);
             sheetCommonObj.cleanSheet(sheetCoe, settingCoe, -1);
             sheetCommonObj.cleanSheet(sheetAss, settingAss, -1);
+            sheetCommonObj.cleanSheet(sheetInst, settingInst, -1);
             let cacheSection = me.getCache();
             if (cacheSection && row < cacheSection.length) {
                 rationGLJOprObj.getGljItems(cacheSection[row], function () {
@@ -95,6 +97,9 @@ let rationOprObj = {
                     me.workBook.focus(true);
                 });
                 rationAssistOprObj.getAssItems(cacheSection[row]);
+                rationInstObj.getInstItems(cacheSection[row], function () {
+                    me.workBook.focus(true);
+                });
             }
             else {
                 rationGLJOprObj.currentRationItem = null;
@@ -135,6 +140,7 @@ let rationOprObj = {
                         cacheSection[j]["rationGljList"] = result.data.ops[i]["rationGljList"];
                         cacheSection[j]["rationCoeList"] = result.data.ops[i]["rationCoeList"];
                         cacheSection[j]["rationAssList"] = result.data.ops[i]["rationAssList"];
+                        cacheSection[j]["rationInstList"] = result.data.ops[i]["rationInstList"];
                     }
                 }
             }
@@ -564,7 +570,8 @@ let rationOprObj = {
         let me = rationOprObj,
             sheetGLJ = rationGLJOprObj.sheet, settingGLJ = rationGLJOprObj.setting,
             sheetCoe = rationCoeOprObj.sheet, settingCoe = rationCoeOprObj.setting,
-            sheetAss = rationAssistOprObj.sheet, settingAss = rationAssistOprObj.setting;
+            sheetAss = rationAssistOprObj.sheet, settingAss = rationAssistOprObj.setting,
+            sheetInst = rationInstObj.sheet, settingInst = rationInstObj.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];
@@ -579,15 +586,18 @@ let rationOprObj = {
                         sheetCommonObj.cleanData(sheetGLJ, settingGLJ, -1);
                         sheetCommonObj.cleanData(sheetCoe, settingCoe, -1);
                         sheetCommonObj.cleanData(sheetAss, settingAss, -1);
+                        sheetCommonObj.cleanData(sheetInst, settingInst, -1);
                         rationGLJOprObj.getGljItems(cacheSection[row]);
                         rationCoeOprObj.getCoeItems(cacheSection[row]);
                         rationAssistOprObj.getAssItems(cacheSection[row]);
+                        rationInstObj.getInstItems(cacheSection[row]);
                     }
                     else {
                         rationGLJOprObj.currentRationItem = null;
                         sheetCommonObj.cleanData(sheetGLJ, settingGLJ, -1);
                         sheetCommonObj.cleanData(sheetCoe, settingCoe, -1);
                         sheetCommonObj.cleanData(sheetAss, settingAss, -1);
+                        sheetCommonObj.cleanData(sheetInst, settingInst, -1);
                         sheetCommonObj.setDynamicCombo(sheetAss, 0, 5, sheetAss.getRowCount(), rationAssistOprObj.setting.comboItems, false, false);
                     }
                 }
@@ -601,6 +611,7 @@ let rationOprObj = {
                 sheetCommonObj.cleanSheet(sheetGLJ, settingGLJ, -1);
                 sheetCommonObj.cleanSheet(sheetCoe, settingCoe, -1);
                 sheetCommonObj.cleanSheet(sheetAss, settingAss, -1);
+                sheetCommonObj.cleanSheet(sheetInst, settingInst, -1);
             }
            //--- me.workBook.focus(true);
         }

+ 301 - 0
web/maintain/ration_repository/js/ration_installation.js

@@ -0,0 +1,301 @@
+/**
+ * Created by Zhong on 2018/1/25.
+ */
+let rationInstObj = {
+    IDMapping: null, //ID - name
+    feeItem: null, //name - ID
+    sheet: null,
+    rationRepId: null,
+    curRation: null,
+    cache: [],
+    setting: {
+        header:[
+            {headerName:"费用项",headerWidth:120,dataCode:"feeItem", dataType: "String", hAlign: 'left'},
+            {headerName:"分册章节",headerWidth:400,dataCode:"section", dataType: "String", hAlign: 'left'}
+        ],
+        view:{
+            comboBox:[],
+            lockColumns:[]
+        },
+    },
+    buildSheet: function(sheet) {
+        let me = this;
+        me.sheet = sheet;
+        me.sheet.options.clipBoardOptions = GC.Spread.Sheets.ClipboardPasteOptions.values;
+        me.rationRepId = parseInt(pageOprObj.rationLibId); // 不可靠,有时取不到
+        if (me.rationRepId == undefined){me.rationRepId = parseInt(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.EnterCell, me.onEnterCell);
+        me.sheet.bind(GC.Spread.Sheets.Events.EditStarting, me.onEditStarting);
+        me.sheet.bind(GC.Spread.Sheets.Events.EditEnded, me.onEditEnded);
+        //右键
+      //  me.onContextmenuOpr();
+    },
+    renderFunc: function (sheet, func) {
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        if(func){
+            func();
+        }
+        sheet.resumePaint();
+        sheet.resumeEvent();
+    },
+    isDef: function (v) {
+        return v !== undefined && v !== null;
+    },
+    getInstallation: function (rationRepId, callback) {
+        let me = this;
+        CommonAjax.post('/rationRepository/api/getInstallation', {rationRepId: rationRepId}, function (rstData) {
+            //建立name - ID 映射, ID - name 映射
+            me.feeItem = {};
+            me.IDMapping = {feeItem: {}, section: {}};
+            for(let feeItem of rstData){
+                me.feeItem[feeItem.feeItem] = {ID: feeItem.ID, section: {}};
+                me.IDMapping['feeItem'][feeItem.ID] = feeItem.feeItem;
+                for(let section of feeItem.section){
+                    me.feeItem[feeItem.feeItem]['section'][section.name] = section.ID;
+                    me.IDMapping['section'][section.ID] = section.name;
+                }
+            }
+            if(callback){
+                callback(rstData);
+            }
+        });
+    },
+    getFeeItemCombo: function () {
+        let feeItemArr = [];
+        for(let name in this.feeItem){
+            feeItemArr.push(name);
+        }
+        let combo = sheetCommonObj.getDynamicCombo();
+        combo.items(feeItemArr).itemHeight(10).editable(false);
+        return combo;
+    },
+    getSectionCombo: function (feeItem) {
+        let sectionObjs = this.feeItem[feeItem]['section'];
+        let sectionArr = [];
+        for(let name in sectionObjs){
+            sectionArr.push(name);
+        }
+        let combo = sheetCommonObj.getDynamicCombo();
+        combo.items(sectionArr).itemHeight(10).editable(false);
+        return combo;
+    },
+    getInstItems: function (ration, callback) {
+        let me = this, rst = [];
+        me.curRation = ration;
+        me.cache = ration.rationInstList;
+        for(let inst of me.cache){
+            let data = Object.create(null);
+            let feeItem = me.IDMapping['feeItem'][inst.feeItemId];
+            let section = me.IDMapping['section'][inst.sectionId];
+            data.feeItem = me.isDef(feeItem) ? feeItem : '';
+            data.section = me.isDef(section) ? section : '';
+            rst.push(data);
+        }
+        me.showInstItems(rst);
+        if(callback){
+            callback();
+        }
+    },
+    showInstItems: function (data) {
+        let me = this;
+        sheetCommonObj.showData(this.sheet, this.setting, data);
+        //init combo
+        this.renderFunc(this.sheet, function () {
+            let feeIemCombo = me.getFeeItemCombo();
+            let rowCount = me.sheet.getRowCount();
+            for(let i = 0, len = rowCount.length; i < len; i++){
+                me.getRange(i, -1, 1, -1).cellType(null);
+            }
+            me.sheet.getRange(-1, 0, -1, 1).cellType(feeIemCombo);
+            for(let i = 0, len = data.length; i < len; i++){
+                let sectionCombo = me.getSectionCombo(data[i].feeItem);
+                me.sheet.getCell(i, 1).cellType(sectionCombo);
+            }
+        });
+    },
+    onEnterCell: function (sender, args) {
+        args.sheet.repaint();
+    },
+    onEditStarting: function (sender, args) {
+        let me = rationInstObj;
+        if(!me.isDef(me.curRation)){
+            args.cancel = true;
+            return;
+        }
+        if(!me.isDef(me.cache[args.row]) && args.col === 1){
+            args.cancel = true;
+            return;
+        }
+    },
+    onEditEnded: function (sender, args) {
+        let me = rationInstObj;
+        let v = me.isDef(args.editingText) ? args.editingText.toString().trim() : '';
+        let field = me.setting.header[args.col]['dataCode'];
+        let inst = me.cache[args.row];
+        let toUpdate = false;
+        //update
+        if(me.isDef(inst)){
+            if(field === 'feeItem'){
+                let feeItemId = me.isDef(me.feeItem[v]) ? me.feeItem[v]['ID'] : null;
+                if(feeItemId){
+                    inst.feeItemId = feeItemId;
+                    toUpdate = true;
+                }
+                else {
+                    me.sheet.setValue(args.row, args.col, me.IDMapping['feeItem'][inst.feeItemId]);
+                    return;
+                }
+            }
+            else{
+                let sectionId = me.isDef(me.feeItem[me.IDMapping['feeItem'][inst.feeItemId]]) ? me.feeItem[me.IDMapping['feeItem'][inst.feeItemId]]['section'][v] : null;
+                inst.sectionId = sectionId;
+                toUpdate = true;
+            }
+        }
+        //insert
+        else{
+            let feeItemId = me.isDef(me.feeItem[v]) ? me.feeItem[v]['ID'] : null;
+            if(feeItemId){
+                let obj = {feeItemId: feeItemId, sectionId: null};
+                me.cache.push(obj);
+                toUpdate = true;
+            }
+        }
+        if(toUpdate){
+            me.updateRation(me.curRation, function () {
+                me.getInstItems(me.curRation);
+            });
+        }
+    },
+    validUpdatePaste: function (rowData, data) {
+        if(this.isDef(data.feeItem) && this.isDef(data.section) && data.feeItem !== '' && data.section !== ''){
+            if(!this.isDef(this.feeItem[data.feeItem])){
+                return false;
+            }
+            if(!this.isDef(this.feeItem[data.feeItem]['section'][data.section])){
+                return false;
+            }
+        }
+        else if(this.isDef(data.feeItem) && data.feeItem !== ''){
+            if(!this.isDef(this.feeItem[data.feeItem])){
+                return false;
+            }
+        }
+        else if(this.isDef(data.section) && data.section !== ''){
+            if(!this.isDef(this.feeItem[this.IDMapping['feeItem'][rowData.feeItemId]]['section'][data.section])){
+                return false;
+            }
+        }
+        return true;
+    },
+    validInsertPaste: function (data) {
+        if(!this.isDef(data.feeItem) || data.feeItem == ''){
+            return false;
+        }
+        if(!this.isDef(this.feeItem[data.feeItem])){
+            return false;
+        }
+        if(this.isDef(data.section) && data.section !== '' && !this.isDef(this.feeItem[data.feeItem]['section'][data.section])){
+            return false;
+        }
+        return true;
+    },
+    toSaveData: function (data, rowData = null) {
+        let obj = {feeItemId: null, sectionId: null};
+        if(this.isDef(data.feeItem) && data.feeItem !== ''){
+            obj.feeItemId = this.isDef(this.feeItem[data.feeItem]) ? this.feeItem[data.feeItem]['ID'] : null;
+        }
+        else if(this.isDef(rowData)){
+            obj.feeItemId = rowData.feeItemId;
+        }
+        if(this.isDef(data.section) && data.section !== ''){
+            obj.sectionId = this.isDef(this.feeItem[this.IDMapping['feeItem'][obj.feeItemId]]['section'][data.section]) ?
+                this.feeItem[this.IDMapping['feeItem'][obj.feeItemId]]['section'][data.section]: null;
+        }
+        return obj;
+    },
+    bindRationInstDel: function () {
+        let me = this;
+        let workBook = me.sheet.getParent();
+        workBook.commandManager().register('rationInstDel', function () {
+            let toUpdate = false;
+            let sels = me.sheet.getSelections();
+            for(let i = 0, len = sels.length; i < len; i++){
+                let sel = sels[i];
+                //delete
+                if(sel.colCount === me.setting.header.length){
+                    for(let j = 0, jLen = sel.rowCount; j < jLen; j++){
+                        let row = sel.row + j;
+                        let inst = me.cache[row];
+                        //有数据,删除数据
+                        if(me.isDef(inst)){
+                            if(!toUpdate){
+                                toUpdate = true;
+                            }
+                        }
+                    }
+                    //front delete
+                    me.cache.splice(sel.row, sel.rowCount);
+                }
+            }
+            if(toUpdate && me.curRation){
+                me.updateRation(me.curRation, function () {
+                    me.getInstItems(me.curRation);
+                });
+            }
+        });
+        workBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false);
+        workBook.commandManager().setShortcutKey('rationInstDel', GC.Spread.Commands.Key.del, false, false, false, false);
+    },
+    onClipboardPasting: function (sender, info) {
+        let me = rationInstObj;
+        if(!me.isDef(me.curRation)){
+            info.cancel = true;
+        }
+    },
+    onClipboardPasted: function (sender, info) {
+        let me = rationInstObj;
+        let items = sheetCommonObj.analyzePasteData(me.setting, info);
+        let toUpdate = false;
+        for(let i = 0, len = items.length; i < len; i++){
+            let row = info.cellRange.row + i;
+            //update
+            let inst = me.cache[row];
+            if(me.isDef(inst)){
+                if(me.validUpdatePaste(inst, items[i])){
+                    let updateObj = me.toSaveData(items[i], inst);
+                    for(let attr in updateObj){
+                        inst[attr] = updateObj[attr];
+                    }
+                    toUpdate = true;
+                }
+            }
+            //insert
+            else{
+                if(me.validInsertPaste(items[i])){
+                    me.cache.push(me.toSaveData(items[i]));
+                    toUpdate = true;
+                }
+            }
+        }
+        if(toUpdate){
+            me.updateRation(me.curRation, function () {
+                me.getInstItems(me.curRation);
+            });
+        }
+        else {
+            me.getInstItems(me.curRation);
+        }
+    },
+    updateRation: function (ration,callback) {
+        rationOprObj.mixUpdateRequest([ration], [], [], function () {
+            if(callback){
+                callback();
+            }
+        });
+    }
+};

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

@@ -535,9 +535,12 @@ let sectionTreeObj = {
             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);
+            sheetCommonObj.cleanSheet(rationAssistOprObj.sheet, rationAssistOprObj.setting, -1);
+            sheetCommonObj.cleanSheet(rationCoeOprObj.sheet, rationCoeOprObj.setting, -1);
+            sheetCommonObj.cleanSheet(rationInstObj.sheet, rationInstObj.setting, -1);
+            rationGLJOprObj.sheet.getParent().focus(false);
         }
-        sheetCommonObj.cleanSheet(rationGLJOprObj.sheet, rationGLJOprObj.setting, -1);
-        rationGLJOprObj.sheet.getParent().focus(false);
         me.workBook.focus(true);
     }
 };