Browse Source

feat: 定额库编辑器损耗率相关

vian 1 year ago
parent
commit
01c6d2ec57

+ 13 - 0
modules/all_models/stdRation_lossRate.js

@@ -0,0 +1,13 @@
+const mongoose = require('mongoose');
+const Schema = mongoose.Schema;
+
+
+const lossRateSchema = new Schema({
+  libID: { type: String, index: true },
+  ID: String,
+  serialNo: Number,
+  name: String,
+  rate: Number,
+});
+
+mongoose.model('std_ration_lib_loss_rate_list', lossRateSchema, 'std_ration_lib_loss_rate_list');

+ 5 - 1
modules/all_models/stdRation_ration.js

@@ -7,7 +7,11 @@ const Schema = mongoose.Schema;
 const rationGljItemSchema = new Schema({
     gljId: Number,
     consumeAmt: Number,
-    proportion: { type: Number, default: 0 } //配合比,暂时无需使用,默认0
+    proportion: { type: Number, default: 0 }, //配合比,暂时无需使用,默认0
+    lossRateID: String,
+    lossRateNo: Number,
+    lossRateName: String,
+    lossRate: Number,
 }, { _id: false });
 
 const rationAssItemSchema = new Schema({

+ 41 - 0
modules/ration_repository/controllers/loss_controller.js

@@ -0,0 +1,41 @@
+import BaseController from "../../common/base/base_controller";
+
+const facade = require('../models/lossRate');
+
+class LossController extends BaseController {
+  async getLossList(req, res) {
+    try {
+      const { libID } = req.body;
+      const data = await facade.getLossList(libID);
+      res.json({ error: 0, message: 'getLossList success', data });
+    } catch (err) {
+      console.log(err);
+      res.json({ error: 1, message: err.toString() });
+    }
+  }
+
+  async saveLossList(req, res) {
+    try {
+      const data = await facade.save(JSON.parse(req.body.data));
+      res.json({ error: 0, message: 'saveLossList success', data });
+    } catch (err) {
+      console.log(err);
+      res.json({ error: 1, message: err.toString() });
+    }
+  }
+
+  async getItemsBySerialNos(req, res) {
+    try {
+      const { libID, serialNos } = JSON.parse(req.body.data);
+      const data = await facade.getItemsBySerialNos(libID, serialNos);
+      res.json({ error: 0, message: 'getItemsBySerialNos success', data });
+    } catch (err) {
+      console.log(err);
+      res.json({ error: 1, message: err.toString() });
+    }
+  }
+}
+
+module.exports = {
+  lossController: new LossController()
+};

+ 92 - 0
modules/ration_repository/models/lossRate.js

@@ -0,0 +1,92 @@
+const mongoose = require('mongoose');
+const uuidV1 = require('uuid/v1');
+const _ = require('lodash');
+const lossModel = mongoose.model('std_ration_lib_loss_rate_list');
+const rationModel = mongoose.model('std_ration_lib_ration_items');
+
+const getLossList = async (libID) => {
+  return await lossModel.find({ libID }).lean();
+}
+
+const batchUpdateRationLoss = async (libID, updateRateData) => {
+  const bulks = [];
+  const updateRateMap = {};
+  updateRateData.forEach(item => {
+    updateRateMap[item.ID] = item;
+  });
+  const rations = await rationModel.find({ rationRepId: libID }, '-_id ID rationGljList').lean();
+  rations.forEach(ration => {
+    if (ration.rationGljList && ration.rationGljList.length) {
+      let needUpdate = false;
+      ration.rationGljList.forEach(rGlj => {
+        const matchRateItem = updateRateMap[rGlj.lossRateID];
+        if (matchRateItem) {
+          needUpdate = true;
+          rGlj.lossRateNo = matchRateItem.serialNo;
+          rGlj.lossRateName = matchRateItem.name;
+          rGlj.lossRate = matchRateItem.rate;
+        }
+      });
+      if (needUpdate) {
+        bulks.push({ updateOne: { filter: { ID: ration.ID }, update: { $set: { rationGljList: ration.rationGljList } } } });
+      }
+    }
+  });
+  if (bulks.length) {
+    await rationModel.bulkWrite(bulks);
+  }
+
+}
+
+const save = async (data) => {
+  console.log(data);
+  const { addArr, updateArr, deleteArr } = data;
+  const bulks = [];
+  const newData = [];
+  if (addArr && addArr.length) {
+    addArr.forEach(item => {
+      const newItem = { ...item, ID: uuidV1() };
+      console.log(newItem);
+      newData.push(newItem);
+      bulks.push({ insertOne: { document: newItem } });
+    });
+  }
+  const updateRateData = [];
+  let libID;
+  if (updateArr && updateArr.length) {
+    updateArr.forEach(item => {
+      if (!libID) {
+        libID = item.libID;
+      }
+      const updateObj = { ...item };
+      delete updateObj.ID;
+      delete updateObj.libID;
+      updateRateData.push({ name: updateObj.name, rate: updateObj.rate, serialNo: updateObj.serialNo, ID: item.ID });
+      bulks.push({ updateOne: { filter: { ID: item.ID }, update: { $set: updateObj } } });
+    });
+  }
+  if (deleteArr && deleteArr.length) {
+    deleteArr.forEach(item => {
+      bulks.push({ deleteOne: { filter: { ID: item.ID } } });
+    })
+  }
+  if (bulks.length) {
+    await lossModel.bulkWrite(bulks);
+  }
+  if (libID && updateRateData.length) {
+    await batchUpdateRationLoss(libID, updateRateData)
+  }
+  return newData;
+}
+
+
+const getItemsBySerialNos = async (libID, serialNos) => {
+  return await lossModel.find({ libID, serialNo: { $in: serialNos } }).lean();
+}
+
+
+module.exports = {
+  getLossList,
+  save,
+  getItemsBySerialNos,
+}

+ 50 - 45
modules/ration_repository/routes/ration_rep_routes.js

@@ -2,7 +2,7 @@
  * Created by Tony on 2017/4/20.
  */
 var express = require("express");
-var apiRouter =express.Router();
+var apiRouter = express.Router();
 //var _rootDir = __dirname;
 import ViewsController from "../controllers/repository_views_controller";
 import RationRepositoryController from "../controllers/ration_repository_controller";
@@ -22,10 +22,11 @@ let installationController = new InstallationController();
 let searchController = new SearchController();
 let repositoryGljController = new RepositoryGljController();
 let gljController = new GljController();
+const { lossController } = require('../controllers/loss_controller');
 
-module.exports =  function (app) {
+module.exports = function (app) {
     app.get('/rationRepository/main', viewsController.auth, viewsController.init, viewsController.redirectMain);
-    app.get('/rationRepository/ration',viewsController.auth, viewsController.init, viewsController.redirectRation);
+    app.get('/rationRepository/ration', viewsController.auth, viewsController.init, viewsController.redirectRation);
     app.get('/rationRepository/lmm', viewsController.auth, viewsController.init, viewsController.redirectGlj);
     app.get('/rationRepository/coeList', viewsController.auth, viewsController.init, viewsController.redirectCoeList);
     app.get('/rationRepository/installation', viewsController.auth, viewsController.init, viewsController.redirectInstallation);
@@ -33,53 +34,57 @@ module.exports =  function (app) {
     apiRouter.post("/prepareInitData", rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.prepareInitData);
     apiRouter.post("/getCompilationList", rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.getCompilationList);
     apiRouter.post("/getRationLibsByCompilation", rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.getRationLibsByCompilation);
-    apiRouter.post("/getRationLib",rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.getRationLib);
+    apiRouter.post("/getRationLib", rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.getRationLib);
 
-    apiRouter.post("/getRationDisplayNames",rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.getDisPlayRationLibs);
-    apiRouter.post("/editRationLibs",rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.updateRationRepositoryName);
-    apiRouter.post("/addRationRepository",rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.addRationRepository);
-    apiRouter.post("/deleteRationLibs",rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.deleteRationLib);
-    apiRouter.post("/getRealLibName",rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.getRealLibName);
-    apiRouter.post("/getLibIDByName",rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.getLibIDByName);
+    apiRouter.post("/getRationDisplayNames", rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.getDisPlayRationLibs);
+    apiRouter.post("/editRationLibs", rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.updateRationRepositoryName);
+    apiRouter.post("/addRationRepository", rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.addRationRepository);
+    apiRouter.post("/deleteRationLibs", rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.deleteRationLib);
+    apiRouter.post("/getRealLibName", rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.getRealLibName);
+    apiRouter.post("/getLibIDByName", rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.getLibIDByName);
 
     apiRouter.get('/sectionTemplateCount/:compilationId', rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.sectionTemplateCount);
     apiRouter.post('/initSectionTemplate', rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.initSectionTemplate);
-    apiRouter.post("/getRationTree",rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.getRationChapterTree);
-    apiRouter.post("/getNewRationTreeID",rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.getNewRationTreeID);
-    apiRouter.post("/createNewNode",rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.createNewNode);
-    apiRouter.post("/updateNodes",rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.updateNodes);
-    apiRouter.post("/deleteNodes",rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.deleteNodes);
-    apiRouter.post("/updateExplanation",rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.updateExplanation);
-    apiRouter.post("/updateErratumRecord",rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.updateErratumRecord);
-    apiRouter.post("/updateRuleText",rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.updateRuleText);
-    apiRouter.post("/updateSituation",rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.updateSituation);
-    apiRouter.post("/updateAnnoSituation",rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.updateAnnoSituation);
+    apiRouter.post("/getRationTree", rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.getRationChapterTree);
+    apiRouter.post("/getNewRationTreeID", rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.getNewRationTreeID);
+    apiRouter.post("/createNewNode", rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.createNewNode);
+    apiRouter.post("/updateNodes", rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.updateNodes);
+    apiRouter.post("/deleteNodes", rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.deleteNodes);
+    apiRouter.post("/updateExplanation", rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.updateExplanation);
+    apiRouter.post("/updateErratumRecord", rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.updateErratumRecord);
+    apiRouter.post("/updateRuleText", rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.updateRuleText);
+    apiRouter.post("/updateSituation", rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.updateSituation);
+    apiRouter.post("/updateAnnoSituation", rationChapterTreeController.auth, rationChapterTreeController.init, rationChapterTreeController.updateAnnoSituation);
 
-    apiRouter.post("/getRationItems",rationController.auth, rationController.init, rationController.getRationItemsBySection);
-    apiRouter.post("/getRationItemsByLib",rationController.auth, rationController.init, rationController.getRationItemsByLib);
-    apiRouter.post("/mixUpdateRationItems",rationController.auth, rationController.init, rationController.mixUpdateRationItems);
-    apiRouter.post("/updateRationBasePrc",rationController.auth, rationController.init, rationController.updateRationBasePrc);
-    apiRouter.post("/getRationGljIds",rationController.auth, rationController.init, rationController.getRationGljIds);
-    apiRouter.post("/getRationsCodes",rationController.auth, rationController.init, rationController.getRationsCodes);
-    apiRouter.post("/updateJobContent",rationController.auth, rationController.init, rationController.updateJobContent);
-    apiRouter.post("/updateAnnotation",rationController.auth, rationController.init, rationController.updateAnnotation);
-    apiRouter.post("/updateRationTemplate",rationController.auth, rationController.init, rationController.updateRationTemplate);
+    apiRouter.post("/getRationItems", rationController.auth, rationController.init, rationController.getRationItemsBySection);
+    apiRouter.post("/getRationItemsByLib", rationController.auth, rationController.init, rationController.getRationItemsByLib);
+    apiRouter.post("/mixUpdateRationItems", rationController.auth, rationController.init, rationController.mixUpdateRationItems);
+    apiRouter.post("/updateRationBasePrc", rationController.auth, rationController.init, rationController.updateRationBasePrc);
+    apiRouter.post("/getRationGljIds", rationController.auth, rationController.init, rationController.getRationGljIds);
+    apiRouter.post("/getRationsCodes", rationController.auth, rationController.init, rationController.getRationsCodes);
+    apiRouter.post("/updateJobContent", rationController.auth, rationController.init, rationController.updateJobContent);
+    apiRouter.post("/updateAnnotation", rationController.auth, rationController.init, rationController.updateAnnotation);
+    apiRouter.post("/updateRationTemplate", rationController.auth, rationController.init, rationController.updateRationTemplate);
 
-    apiRouter.post("/createNewGljTypeNode",repositoryGljController.auth, gljController.init, gljController.createNewGljTypeNode);
-    apiRouter.post("/updateGljNodes",repositoryGljController.auth, gljController.init, gljController.updateGljNodes);
-    apiRouter.post("/deleteGljNodes",repositoryGljController.auth, gljController.init, gljController.deleteGljNodes);
-    apiRouter.post("/getGljDistType",repositoryGljController.auth, gljController.init, gljController.getGljDistType);
-    apiRouter.post("/getGljTree",repositoryGljController.auth, gljController.init, gljController.getGljTree);
-    apiRouter.post("/getGljItems",repositoryGljController.auth, gljController.init, gljController.getGljItems);
-    apiRouter.post("/mixUpdateGljItems",repositoryGljController.auth, gljController.init, gljController.mixUpdateGljItems);
-    apiRouter.post("/getGljItemsByIds",repositoryGljController.auth, gljController.init, gljController.getGljItemsByIds);
-    apiRouter.post("/getGljItemsByCodes",repositoryGljController.auth, gljController.init, gljController.getGljItemsByCodes);
+    apiRouter.post("/createNewGljTypeNode", repositoryGljController.auth, gljController.init, gljController.createNewGljTypeNode);
+    apiRouter.post("/updateGljNodes", repositoryGljController.auth, gljController.init, gljController.updateGljNodes);
+    apiRouter.post("/deleteGljNodes", repositoryGljController.auth, gljController.init, gljController.deleteGljNodes);
+    apiRouter.post("/getGljDistType", repositoryGljController.auth, gljController.init, gljController.getGljDistType);
+    apiRouter.post("/getGljTree", repositoryGljController.auth, gljController.init, gljController.getGljTree);
+    apiRouter.post("/getGljItems", repositoryGljController.auth, gljController.init, gljController.getGljItems);
+    apiRouter.post("/mixUpdateGljItems", repositoryGljController.auth, gljController.init, gljController.mixUpdateGljItems);
+    apiRouter.post("/getGljItemsByIds", repositoryGljController.auth, gljController.init, gljController.getGljItemsByIds);
+    apiRouter.post("/getGljItemsByCodes", repositoryGljController.auth, gljController.init, gljController.getGljItemsByCodes);
 
-    apiRouter.post("/getCoeReference",coeListController.auth, coeListController.init, coeListController.getCoeReference);
-    apiRouter.post("/getCoeList",coeListController.auth, coeListController.init, coeListController.getCoeList);
-    apiRouter.post("/saveCoeList",coeListController.auth, coeListController.init, coeListController.saveCoeList);
-    apiRouter.post("/getCoeItemsByIDs",coeListController.auth, coeListController.init, coeListController.getCoeItemsByIDs);
-    apiRouter.post("/getCoeItemsByNos",coeListController.auth, coeListController.init, coeListController.getCoeItemsByNos);
+    apiRouter.post("/getCoeReference", coeListController.auth, coeListController.init, coeListController.getCoeReference);
+    apiRouter.post("/getCoeList", coeListController.auth, coeListController.init, coeListController.getCoeList);
+    apiRouter.post("/saveCoeList", coeListController.auth, coeListController.init, coeListController.saveCoeList);
+    apiRouter.post("/getCoeItemsByIDs", coeListController.auth, coeListController.init, coeListController.getCoeItemsByIDs);
+    apiRouter.post("/getCoeItemsByNos", coeListController.auth, coeListController.init, coeListController.getCoeItemsByNos);
+
+    apiRouter.post("/getLossList", lossController.auth, lossController.init, lossController.getLossList);
+    apiRouter.post("/saveLossList", lossController.auth, lossController.init, lossController.saveLossList);
+    apiRouter.post("/getItemsBySerialNos", lossController.auth, lossController.init, lossController.getItemsBySerialNos);
 
     //安装增加费
     apiRouter.post('/getInstallation', installationController.auth, installationController.init, installationController.getInstallation);
@@ -87,7 +92,7 @@ module.exports =  function (app) {
     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('/getRationItem', searchController.auth, searchController.init, searchController.getRationItem);
     apiRouter.post('/findRation', searchController.auth, searchController.init, searchController.findRation);
 
     apiRouter.post('/reCalcAll', rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.reCalcAll);
@@ -95,5 +100,5 @@ module.exports =  function (app) {
     apiRouter.post('/upload', rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.uploadSourceData);
     apiRouter.get('/export', rationRepositoryController.auth, rationRepositoryController.init, rationRepositoryController.exportRationData);
 
-    app.use("/rationRepository/api",apiRouter);
+    app.use("/rationRepository/api", apiRouter);
 }

+ 20 - 20
modules/std_glj_lib/controllers/viewsController.js

@@ -13,25 +13,25 @@ let config = require("../../../config/config.js");
 const fs = require('fs');
 import { checkCompilationPermission } from '../../common/base/base_util';
 
-class ViewsController extends BaseController{
-    redirectMain(req, res){
+class ViewsController extends BaseController {
+    redirectMain(req, res) {
         res.render('maintain/std_glj_lib/html/main.html',
-        {
-            userAccount: req.session.managerData.username
-        });
+            {
+                userAccount: req.session.managerData.username
+            });
     }
-    async redirectGlj(req, res){
+    async redirectGlj(req, res) {
         let overWriteUrl = null;
-        let stdGljLib = await stdGljLibModel.findOne({ID: req.query.gljLibId, deleted: false});
+        let stdGljLib = await stdGljLibModel.findOne({ ID: req.query.gljLibId, deleted: false });
         let priceProperties = [],
             consumeAmtProperties = [];
-        if(stdGljLib){
+        if (stdGljLib) {
             checkCompilationPermission(req, res, stdGljLib.compilationId, '/stdGljRepository/main');
-           let compilation = await compilationModel.findOne({_id: mongoose.Types.ObjectId(stdGljLib.compilationId)});
-           priceProperties = compilation.priceProperties ? compilation.priceProperties : [];
-           consumeAmtProperties = compilation.consumeAmtProperties ? compilation.consumeAmtProperties : [];
-           let absoluteUrl = compilation.overWriteUrl ? req.app.locals.rootDir + compilation.overWriteUrl : req.app.locals.rootDir;
-           overWriteUrl = fs.existsSync(absoluteUrl) && fs.statSync(absoluteUrl).isFile()? compilation.overWriteUrl : null;
+            let compilation = await compilationModel.findOne({ _id: mongoose.Types.ObjectId(stdGljLib.compilationId) });
+            priceProperties = compilation.priceProperties ? compilation.priceProperties : [];
+            consumeAmtProperties = compilation.consumeAmtProperties ? compilation.consumeAmtProperties : [];
+            let absoluteUrl = compilation.overWriteUrl ? req.app.locals.rootDir + compilation.overWriteUrl : req.app.locals.rootDir;
+            overWriteUrl = fs.existsSync(absoluteUrl) && fs.statSync(absoluteUrl).isFile() ? compilation.overWriteUrl : null;
         }
         // await gljDao.copyLib(7,24); //UAT 部颁2018 -> 部颁2018计价标准
         // await gljDao.copyLib(7,25); //PROD 部颁2018 -> 部颁2018计价标准
@@ -45,13 +45,13 @@ class ViewsController extends BaseController{
         // await gljDao.copyLib(14,33); //PROD 部颁公路工料机库(2007营改增) -> 广东公路养护人材机库(2010) // 这个是公路PROD2.0的数据库,在hw服务器上,4080端口
 
         res.render('maintain/std_glj_lib/html/gongliao.html',
-        {
-            userAccount: req.session.managerData.username,
-            LicenseKey:config.getLicenseKey(process.env.NODE_ENV),
-            priceProperties: JSON.stringify(priceProperties),
-            consumeAmtProperties: JSON.stringify(consumeAmtProperties),
-            overWriteUrl: overWriteUrl
-        });
+            {
+                userAccount: req.session.managerData.username,
+                LicenseKey: config.getLicenseKey(process.env.NODE_ENV),
+                priceProperties: JSON.stringify(priceProperties),
+                consumeAmtProperties: JSON.stringify(consumeAmtProperties),
+                overWriteUrl: overWriteUrl
+            });
     }
 }
 

+ 8 - 5
web/common/js/slideResize.js

@@ -14,7 +14,7 @@
  * 清除相关缓存数据: project_view.js--->$('#property_default').click(callback)
  * */
 
-const SlideResize = (function() {
+const SlideResize = (function () {
     // 水平拖动条的宽度
     const resizeWidth = 10;
     //函数防抖
@@ -27,11 +27,14 @@ const SlideResize = (function() {
     }
     //设置水平拖动条的宽度
     //@param {Object dom}resize滚动条
-    function setResizeWidth (resize) {
+    function setResizeWidth(resize, getOtherFunc) {
         //滚动条节点 及 同层非滚动条节点的索引
         let bros = resize.parent().children();
-        let index = bros.index(resize),
-            otherIndex = index ? 0 : 1;
+        let index = bros.index(resize);
+        let otherIndex = index ? 0 : 1;
+        if (getOtherFunc) {
+            otherIndex = getOtherFunc(index);
+        }
         const other = resize.parent().children(`:eq(${otherIndex})`);
         let resizeParentWidth = resize.parent().width();
         let resizeDecimalWidth = resizeWidth / resizeParentWidth,
@@ -81,7 +84,7 @@ const SlideResize = (function() {
                     rightPercentWidth = rightChange / eleObj.parent.width() * 100 + '%';
                 eleObj.left.css('width', leftPercentWidth);
                 eleObj.right.css('width', rightPercentWidth);
-                setResizeWidth(eleObj.resize);
+                setResizeWidth(eleObj.resize, eleObj.getOtherFunc);
                 mouseMoveCount += Math.abs(moveSize);
                 deBounce(function () {
                     if (callback) {

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

@@ -52,6 +52,9 @@
                 <li class="nav-item">
                     <a class="nav-link px-3" href="javascript:void(0);" id="zmhs">子目换算</a>
                 </li>
+                <li class="nav-item">
+                    <a class="nav-link px-3" href="javascript:void(0);" id="loss">损耗率</a>
+                </li>
             </ul>
         </nav>
     </div>
@@ -203,15 +206,19 @@
                             </div>
                         </div>
                     </div>
-                    <div class="main-side p-0 main-side-right" id="zmhsContent" style="width: 25%; display: none">
+                    <div class="main-side p-0 main-side-right" id="rightContent" style="width: 25%; display: none">
                         <div class="resize-x" id="slideResizeRight"></div>
-                        <div style="width: 99%; float: left">
+                        <div style="width: 99%; float: left" id="zmhsWrap">
                             <div class="main-data-top-fluid" id="mainSpread">
                             </div>
                             <div class="resize-y" id="zmhsAdjResize"></div>
                             <div class="bottom-content" id="contentSpread">
                             </div>
                         </div>
+                        <div style="width: 99%; float: left" id="lossWrap">
+                            <div class="main-data" id="lossSpread">
+                            </div>
+                        </div>
                     </div>
                 </div>
             </div>
@@ -713,6 +720,7 @@
         <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/maintain/ration_repository/js/coe.js"></script>
+        <script type="text/javascript" src="/web/maintain/ration_repository/js/lossRate.js"></script>
         <script src="/lib/codemirror/codemirror.js"></script>
         <script src="/lib/codemirror/xml.js"></script>
         <script src="/web/common/js/uploadImg.js"></script>

+ 35 - 24
web/maintain/ration_repository/js/coe.js

@@ -2,24 +2,27 @@
  * Created by CSL on 2017-05-18.
  */
 
-$(document).ready(function () {
-    function refreshALlWorkBook() {
-        if (sectionTreeObj.workBook) {
-            sectionTreeObj.workBook.refresh();
-        }
-        if (rationOprObj.workBook) {
-            rationOprObj.workBook.refresh();
-        }
-        if (rationGLJOprObj.sheet && rationGLJOprObj.sheet.getParent()) {
-            rationGLJOprObj.sheet.getParent().refresh();
-        }
-        if (coeOprObj.workBook) {
-            coeOprObj.workBook.refresh();
-        }
-        if (gljAdjOprObj.workBook) {
-            gljAdjOprObj.workBook.refresh();
-        }
+function refreshALlWorkBook() {
+    if (sectionTreeObj.workBook) {
+        sectionTreeObj.workBook.refresh();
+    }
+    if (rationOprObj.workBook) {
+        rationOprObj.workBook.refresh();
+    }
+    if (rationGLJOprObj.sheet && rationGLJOprObj.sheet.getParent()) {
+        rationGLJOprObj.sheet.getParent().refresh();
+    }
+    if (coeOprObj.workBook) {
+        coeOprObj.workBook.refresh();
+    }
+    if (gljAdjOprObj.workBook) {
+        gljAdjOprObj.workBook.refresh();
     }
+    if (typeof lossObj !== 'undefined' && lossObj.workBook) {
+        lossObj.workBook.refresh();
+    }
+}
+$(document).ready(function () {
     //定额章节树与定额表
     let leftElesObj = {};
     leftElesObj.module = moduleName;
@@ -27,7 +30,7 @@ $(document).ready(function () {
     leftElesObj.parent = $('#dataRow');
     leftElesObj.left = $('#leftContent');
     leftElesObj.right = $('#mainContent');
-    let maxEval = `$('#zmhsContent').is(':visible') ? $('#dataRow').width() - $('#zmhsContent').width() - 300 : $('#dataRow').width()  - 300`;
+    let maxEval = `$('#rightContent').is(':visible') ? $('#dataRow').width() - $('#rightContent').width() - 300 : $('#dataRow').width()  - 300`;
     SlideResize.horizontalSlide(leftElesObj, { min: 300, max: maxEval }, function () {
         refreshALlWorkBook();
         sectionTreeObj.loadRateWidth();
@@ -48,8 +51,11 @@ $(document).ready(function () {
     rightElesObj.resize = $('#slideResizeRight');
     rightElesObj.parent = $('#dataRow');
     rightElesObj.left = $('#mainContent');
-    rightElesObj.right = $('#zmhsContent');
+    rightElesObj.right = $('#rightContent');
     let maxEvalRight = `$('#dataRow').width() - $('#leftContent').width() - 200`;
+    rightElesObj.getOtherFunc = (index) => {
+        return index ? 0 : $('#zmhs').hasClass('active') ? 1 : 2;
+    };
     SlideResize.horizontalSlide(rightElesObj, { min: 200, max: maxEvalRight }, function () {
         refreshALlWorkBook();
     });
@@ -76,8 +82,8 @@ $(document).ready(function () {
         //宽度比例localstorage key
         let leftContentKey = `${moduleName}${$('#leftContent').attr('id')}Width`,
             mainContentKey = `${moduleName}${$('#mainContent').attr('id')}Width`,
-            zmhsContentKey = `${moduleName}${$('#zmhsContent').attr('id')}Width`;
-        let zmhsWidth = getLocalCache(zmhsContentKey) ? getLocalCache(zmhsContentKey) : $('#zmhsContent')[0].style.width,
+            zmhsContentKey = `${moduleName}${$('#rightContent').attr('id')}Width`;
+        let zmhsWidth = getLocalCache(zmhsContentKey) ? getLocalCache(zmhsContentKey) : $('#rightContent')[0].style.width,
             mainContentWidth = $('#mainContent')[0].style.width,
             leftContentWidth;
         zmhsWidth = parseFloat(zmhsWidth.replace('%', ''));
@@ -98,7 +104,7 @@ $(document).ready(function () {
         setLocalCache(leftContentKey, `${leftContentWidth}%`);
         $('#mainContent').css('width', `${mainContentWidth}%`);
         setLocalCache(mainContentKey, `${mainContentWidth}%`);
-        $('#zmhsContent').css('width', `${zmhsWidth}%`);
+        $('#rightContent').css('width', `${zmhsWidth}%`);
         setLocalCache(zmhsContentKey, `${zmhsWidth}%`);
         let resizes = [$('#slideResizeLeft'), $('#slideResizeRight')];
         for (let resize of resizes) {
@@ -108,9 +114,12 @@ $(document).ready(function () {
     }
     $('#zmhs').click(function () {
         if (!$(this).hasClass('active')) {
+            $('#loss').removeClass('active');
             $(this).addClass('active');
             refreshAfterZmhs(true);
-            $('#zmhsContent').show();
+            $('#zmhsWrap').show();
+            $('#lossWrap').hide();
+            $('#rightContent').show();
             if (!coeOprObj.workBook) {
                 pageObj.initPage();
             }
@@ -118,7 +127,9 @@ $(document).ready(function () {
         } else {
             $(this).removeClass('active');
             refreshAfterZmhs(false);
-            $('#zmhsContent').hide();
+            $('#rightContent').hide();
+            $('#zmhsWrap').hide();
+            $('#lossWrap').hide();
             refreshALlWorkBook();
         }
     });

+ 444 - 0
web/maintain/ration_repository/js/lossRate.js

@@ -0,0 +1,444 @@
+let lossObj = {
+  workBook: null,
+  workSheet: null,
+  currentLossList: [],
+  currentLoss: null,
+  currentMaxNo: null,
+  setting: {
+    header: [
+      { headerName: "编号", headerWidth: 50, dataCode: "serialNo", dataType: "String", hAlign: "center", vAlign: "center", readOnly: false },
+      { headerName: "名称", headerWidth: 200, dataCode: "name", dataType: "String", hAlign: "left", vAlign: "center", readOnly: false },
+      { headerName: "损耗率", headerWidth: 150, dataCode: "rate", dataType: "Number", hAlign: "right", vAlign: "center", readOnly: false },
+    ]
+  },
+  buildSheet: function (container) {
+    let me = lossObj;
+    me.workBook = sheetCommonObj.buildSheet(container, me.setting, 30);
+    sheetCommonObj.bindEscKey(me.workBook, [{ sheet: me.workBook.getSheet(0), editStarting: null, editEnded: me.onEditEnded }]);
+    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) {
+    if (info.oldSelections.length === 0 && info.newSelections.length > 0 || info.oldSelections[0].row !== info.newSelections[0].row) {
+      const row = info.newSelections[0].row;
+      lossObj.lossSelInit(row);
+    }
+  },
+  lossSelInit: function (row) {
+    const me = lossObj;
+    if (row < me.currentLossList.length) {
+      me.currentLoss = me.currentLossList[row];
+    } else {
+      me.currentLoss = null;
+    }
+  },
+  onEditEnded: function (sender, args) {
+    let me = lossObj, 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.currentLossList.length) {
+        let updateObj = me.currentLossList[args.row];
+        if (updateObj[dataCode] != inputT) {
+          if (dataCode === 'serialNo') {
+            if (me.isInt(inputT) && !me.hasTisNo(me.currentLossList, 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.currentLossList, inputT)) {
+              alert('该编号已存在!');
+              args.sheet.setValue(args.row, args.col, updateObj[dataCode] + '');
+            }
+          } else if (dataCode === 'rate' && isNaN(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 newLoss = {};
+        newLoss.libID = pageOprObj.rationLibId;
+        if (dataCode === 'serialNo') {
+          if (me.isInt(inputT) && !me.hasTisNo(me.currentLossList, inputT)) {
+            me.currentMaxNo = me.currentMaxNo >= inputT ? me.currentMaxNo : inputT;
+            newLoss[dataCode] = inputT;
+            addArr.push(newLoss);
+            me.save(addArr, [], [], true, function (result) {
+              me.updateCurrentLossList(result);
+            });
+          }
+          else if (!me.isInt(inputT)) {
+            args.sheet.setValue(args.row, args.col, '');
+            alert('编号只能为整数!');
+          }
+          else if (me.hasTisNo(me.currentLossList, inputT)) {
+            args.sheet.setValue(args.row, args.col, '');
+            alert('该编号已存在!');
+          }
+        }
+        else if (dataCode === 'rate' && isNaN(inputT)) {
+          args.sheet.setValue(args.row, args.col, updateObj[dataCode] + '');
+          alert('损耗率只能为数值!');
+        }
+        else {
+          newLoss.serialNo = ++me.currentMaxNo;
+          newLoss[dataCode] = inputT;
+          addArr.push(newLoss);
+          me.save(addArr, [], [], true, function (result) {
+            me.updateCurrentLossList(result);
+          });
+        }
+      }
+    }
+  },
+  onClipboardPasting: function (sender, info) {
+    let me = lossObj, maxCol = info.cellRange.col + info.cellRange.colCount - 1;
+    if (maxCol > me.setting.header.length) {
+      info.cancel = true;
+    }
+  },
+  onClipboardPasted: function (sender, info) {
+    debugger;
+    let me = lossObj, 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.currentLossList.length) {
+        let updateObj = me.currentLossList[row];
+        for (let attr in uniqItems[i]) {
+          if (attr === 'serialNo') {
+            if (me.isInt(uniqItems[i][attr]) && !me.hasTisNo(me.currentLossList, uniqItems[i][attr])) {
+              me.currentMaxNo = me.currentMaxNo >= uniqItems[i][attr] ? me.currentMaxNo : uniqItems[i][attr];
+              updateObj[attr] = uniqItems[i][attr];
+            }
+          }
+          else if (attr !== 'rate' || !isNaN(uniqItems[i][attr])) {
+            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.currentLossList, uniqItems[i].serialNo)) {
+          me.currentMaxNo = me.currentMaxNo >= uniqItems[i].serialNo ? me.currentMaxNo : uniqItems[i].serialNo;
+        }
+        else {
+          uniqItems[i].serialNo = ++me.currentMaxNo;
+        }
+        if (typeof uniqItems[i].rate !== 'undefined' && isNaN(uniqItems[i].rate)) {
+          delete uniqItems[i].rate;
+        }
+        uniqItems[i].libID = pageOprObj.rationLibId;
+        addArr.push(uniqItems[i]);
+      }
+    }
+    if (addArr.length > 0 || updateArr.length > 0) {
+      me.save(addArr, updateArr, [], true, function (result) {
+        me.updateCurrentLossList(result);
+      });
+    }
+  },
+  onDelOpr: function (workBook, setting) {
+    let me = lossObj;
+    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.currentLossList.length) {
+              deleteArr.push({ libID: me.currentLossList[row].libID, ID: me.currentLossList[row].ID });
+            }
+          }
+          me.currentLossList.splice(sels[i].row, sels[i].rowCount);
+        }
+      }
+      if (deleteArr.length > 0) {
+        me.save([], [], deleteArr, true);
+        me.currentLoss = typeof me.currentLossList[idx] !== 'undefined' ? me.currentLossList[idx] : null;
+      }
+
+    });
+    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 (lossList, newSerialNo) {
+    let rst = false;
+    for (let i = 0, len = lossList.length; i < len; i++) {
+      if (lossList[i].serialNo == newSerialNo) {
+        rst = true;
+        break;
+      }
+    }
+    return rst;
+  },
+  updateCurrentLossList: function (newCoeList) {
+    let me = lossObj;
+    if (newCoeList) {
+      me.currentLossList = me.currentLossList.concat(newCoeList);
+    }
+  },
+  sortLossList: function (lossList) {
+    lossList.sort(function (a, b) {
+      let rst = 0;
+      if (a.serialNo > b.serialNo) rst = 1;
+      else if (a.serialNo < b.serialNo) rst = -1;
+      return rst;
+    });
+  },
+  getLossList: function () {
+    let me = lossObj;
+    $.ajax({
+      type: 'post',
+      url: '/rationRepository/api/getLossList',
+      data: { libID: pageOprObj.rationLibId },
+      dataType: 'json',
+      timeout: 20000,
+      success: function (result) {
+        if (!result.error) {
+          me.currentLossList = result.data;
+          me.sortLossList(me.currentLossList);
+          me.currentMaxNo = me.currentLossList.length > 0 ? me.currentLossList[me.currentLossList.length - 1].serialNo : 0;
+          pageObj.showData(me.workSheet, me.setting, me.currentLossList);
+          me.workSheet.clearSelection();
+        }
+      },
+      error: function (err) {
+        alert("内部程序错误!");
+      }
+    });
+  },
+  updateRationGljs: function (updateMap, rationGljs) {
+    if (!rationGljs || !rationGljs.length) {
+      return;
+    }
+    rationGljs.forEach(glj => {
+      const match = updateMap[glj.lossRateID];
+      if (match) {
+        glj.lossRateNo = match.serialNo;
+        glj.lossRateName = match.name;
+        glj.lossRate = match.rate;
+      }
+    })
+  },
+  updateRationAndGljCache: function (updateRateData) {
+    debugger;
+    const updateMap = {};
+    updateRateData.forEach(item => {
+      updateMap[item.ID] = item;
+    });
+    const rations = Object.values(rationOprObj.currentRations).flat();
+    rations.forEach(ration => {
+      lossObj.updateRationGljs(updateMap, ration.rationGljList);
+    })
+    const rGljList = Object.values(rationGLJOprObj.cache).flat();
+    lossObj.updateRationGljs(updateMap, rGljList);
+    if (rationGLJOprObj.currentRationItem) {
+      rationGLJOprObj.showGljItems(rationGLJOprObj.currentRationItem.ID);
+    }
+  },
+  save: function (addArr, updateArr, deleteArr, refresh, callback) {
+    let me = lossObj;
+    $.ajax({
+      type: "POST",
+      url: "api/saveLossList",
+      data: { data: JSON.stringify({ addArr: addArr, updateArr: updateArr, deleteArr: deleteArr }) },
+      dataType: "json",
+      timeout: 5000,
+      success: function (result) {
+        if (result.error) {
+          alert(result.message);
+        } else {
+          debugger;
+          if (updateArr && updateArr.length) {
+            lossObj.updateRationAndGljCache(updateArr);
+          }
+          if (callback) {
+            callback(result.data);
+          }
+          if (refresh) {
+            me.sortLossList(me.currentLossList);
+            me.currentMaxNo = me.currentLossList.length > 0 ? me.currentLossList[me.currentLossList.length - 1].serialNo : 0;
+            pageObj.showData(me.workSheet, me.setting, me.currentLossList);
+          }
+        }
+      },
+      error: function (err) {
+        alert("内部程序错误!");
+      }
+    });
+  }
+}
+
+$(document).ready(function () {
+  //设置水平拖动条的宽度
+  //@param {Object dom}resize滚动条
+  function setResizeWidth(resize) {
+    const fixedWidth = 10;
+    //跟滚动条同层的其他节点
+    let bros = resize.parent().children();
+    //滚动条节点 及 同层非滚动条节点的索引
+    let index = bros.index(resize),
+      otherIndex = index ? 0 : 2;
+    const other = resize.parent().children(`:eq(${otherIndex})`);
+    let resizeParentWidth = resize.parent().width();
+    let resizeDecimalWidth = fixedWidth / resizeParentWidth,
+      otherDecimalWidth = 1 - resizeDecimalWidth;
+    let resizePercentWidth = resizeDecimalWidth * 100 + '%',
+      otherPercentWidth = otherDecimalWidth * 100 + '%';
+    resize.css('width', resizePercentWidth);
+    other.css('width', otherPercentWidth);
+  }
+  function refreshAfterShow(visible) {
+    const min = 20;
+    //宽度比例localstorage key
+    let leftContentKey = `${moduleName}${$('#leftContent').attr('id')}Width`,
+      mainContentKey = `${moduleName}${$('#mainContent').attr('id')}Width`,
+      lossContentKey = `${moduleName}${$('#rightContent').attr('id')}Width`;
+    let lossWidth = getLocalCache(lossContentKey) ? getLocalCache(lossContentKey) : $('#rightContent')[0].style.width,
+      mainContentWidth = $('#mainContent')[0].style.width,
+      leftContentWidth;
+    lossWidth = parseFloat(lossWidth.replace('%', ''));
+    mainContentWidth = parseFloat(mainContentWidth.replace('%', ''));
+    if (visible) {
+      mainContentWidth = mainContentWidth - lossWidth / 2 < min ? min : mainContentWidth - lossWidth / 2;
+      if (100 - mainContentWidth - lossWidth < min) {
+        leftContentWidth = min;
+        lossWidth = 100 - mainContentWidth - leftContentWidth;
+      } else {
+        leftContentWidth = 100 - mainContentWidth - lossWidth;
+      }
+    } else {
+      mainContentWidth += lossWidth / 2;
+      leftContentWidth = 100 - mainContentWidth;
+    }
+    $('#leftContent').css('width', `${leftContentWidth}%`);
+    setLocalCache(leftContentKey, `${leftContentWidth}%`);
+    $('#mainContent').css('width', `${mainContentWidth}%`);
+    setLocalCache(mainContentKey, `${mainContentWidth}%`);
+    $('#rightContent').css('width', `${lossWidth}%`);
+    setLocalCache(lossContentKey, `${lossWidth}%`);
+    let resizes = [$('#slideResizeLeft'), $('#slideResizeRight')];
+    for (let resize of resizes) {
+      setResizeWidth(resize);
+    }
+    sectionTreeObj.loadRateWidth();
+  }
+  $('#loss').click(function () {
+    if (!$(this).hasClass('active')) {
+      $('#zmhs').removeClass('active');
+      $(this).addClass('active');
+      refreshAfterShow(true);
+      $('#lossWrap').show();
+      $('#zmhsWrap').hide();
+      $('#rightContent').show();
+      if (!lossObj.workBook) {
+        pageObj.initPage();
+      }
+      refreshALlWorkBook();
+    } else {
+      $(this).removeClass('active');
+      refreshAfterShow(false);
+      $('#rightContent').hide();
+      $('#zmhsWrap').hide();
+      $('#lossWrap').hide();
+      refreshALlWorkBook();
+    }
+  });
+
+  var pageObj = {
+    initPage: function () {
+      lossObj.buildSheet($('#lossSpread')[0]);
+      lossObj.getLossList();
+      lockUtil.lockSpreads([lossObj.workBook], locked);
+    },
+    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();
+    }
+  };
+});

+ 200 - 132
web/maintain/ration_repository/js/ration_glj.js

@@ -10,25 +10,27 @@ var rationGLJOprObj = {
     tempCacheArr: [],//被更新的工料机,若更新的工料机不存在,则恢复
     cache: {},
     setting: {
-        header:[
-            {headerName:"编码",headerWidth:80,dataCode:"code", dataType: "String", formatter: "@"},
-            {headerName:"名称",headerWidth:160,dataCode:"name", dataType: "String"},
-            {headerName:"规格型号",headerWidth:100,dataCode:"specs", dataType: "String"},
-            {headerName:"单位",headerWidth:60,dataCode:"unit", dataType: "String", hAlign: "center", vAlign: "center"},
-            {headerName:"定额价",headerWidth:80, dataCode:"basePrice", dataType: "Number", formatter:"0.00",  precision: 2},
-            {headerName:"定额消耗",headerWidth:80, dataCode:"consumeAmt", dataType: "Number", formatter: "0.000", precision: 3},
-            {headerName:"类型",headerWidth:70,dataCode:"gljType", dataType: "String", hAlign: "center", vAlign: "center"},
-            {headerName:"配合比",headerWidth:70,dataCode:"proportion", dataType: "Number", formatter:"0.00",  precision: 2}
+        header: [
+            { headerName: "编码", headerWidth: 80, dataCode: "code", dataType: "String", formatter: "@" },
+            { headerName: "名称", headerWidth: 160, dataCode: "name", dataType: "String" },
+            { headerName: "规格型号", headerWidth: 100, dataCode: "specs", dataType: "String" },
+            { headerName: "单位", headerWidth: 60, dataCode: "unit", dataType: "String", hAlign: "center", vAlign: "center" },
+            { headerName: "定额价", headerWidth: 80, dataCode: "basePrice", dataType: "Number", formatter: "0.00", precision: 2 },
+            { headerName: "定额消耗", headerWidth: 80, dataCode: "consumeAmt", dataType: "Number", formatter: "0.000", precision: 3 },
+            { headerName: "类型", headerWidth: 70, dataCode: "gljType", dataType: "String", hAlign: "center", vAlign: "center" },
+            { headerName: "配合比", headerWidth: 70, dataCode: "proportion", dataType: "Number", formatter: "0.00", precision: 2 },
+            { headerName: "损耗编号", headerWidth: 80, dataCode: "lossRateNo", dataType: "Number" },
+            { headerName: "损耗率", headerWidth: 80, dataCode: "lossRate", dataType: "Number", hAlign: "right", vAlign: "center" },
         ],
-        view:{
-            comboBox:[],
-            lockColumns:[1,2,3,4,6]
+        view: {
+            comboBox: [],
+            lockColumns: [1, 2, 3, 4, 6, 8, 9]
         }
     },
     getDistTypeTree: function (gljDistType) {
         let distType;
         let distTypeTree = {
-            prefix : 'gljDistType',
+            prefix: 'gljDistType',
             distTypes: {},
             comboDatas: [],
             distTypesArr: []
@@ -45,18 +47,18 @@ var rationGLJOprObj = {
         gljDistType.forEach(function (typeData) {
             distType = distTypeTree.distTypes[distTypeTree.prefix + typeData.ID];
             let parent = distTypeTree.distTypes[distTypeTree.prefix + typeData.ParentID];
-            if(parent){
+            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.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});
+            if (distTypeObj.data.fullName === '机械') {
+                distTypeTree.comboDatas.push({ text: distTypeObj.data.fullName, value: distTypeObj.data.ID });
             }
         });
         return distTypeTree;
@@ -65,7 +67,7 @@ var rationGLJOprObj = {
         this.distTypeTree = this.getDistTypeTree(gljDistTypeList);
 
     },
-    buildSheet: function(sheet) {
+    buildSheet: function (sheet) {
         this.sheet = sheet;
         sheetCommonObj.initSheet(this.sheet, this.setting, 30);
         this.onContextmenuOpr();
@@ -106,32 +108,33 @@ var rationGLJOprObj = {
         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) {
+    onClipboardPasting: function (sender, args) {
         const me = rationGLJOprObj;
         const rationCache = rationOprObj.getCache();
         const rationRow = rationOprObj.workBook.getSheet(0).getSelections()[0].row;
         me.currentRationItem = rationRow < rationCache.length ? rationCache[rationRow] : null;
-        if(me.currentRationItem && typeof me.cache["_GLJ_" + me.currentRationItem.ID] === 'undefined'){
+        if (me.currentRationItem && typeof me.cache["_GLJ_" + me.currentRationItem.ID] === 'undefined') {
             me.cache["_GLJ_" + me.currentRationItem.ID] = [];
         }
         const field = me.setting.header[args.cellRange.col].dataCode;
-        const canPasteFields = ['code', 'consumeAmt', 'proportion'];
+        const canPasteFields = ['code', 'consumeAmt', 'proportion', 'lossRateNo'];
         if (!me.currentRationItem || !(canPasteFields.includes(field) && args.cellRange.colCount === 1)) {
             args.cancel = true;
         }
     },
-    onClipboardPasted: function(e, info) {
+    onClipboardPasted: async function (e, info) {
         const me = rationGLJOprObj;
         me.tempCacheArr = [];
         const gljCache = me.cache["_GLJ_" + me.currentRationItem.ID];
         const field = me.setting.header[info.cellRange.col].dataCode;
+        debugger;
         if (field === 'code') {
-            const pasteList = sheetCommonObj.analyzePasteData({header:[{dataCode: "code"}] }, info);
+            const pasteList = sheetCommonObj.analyzePasteData({ header: [{ dataCode: "code" }] }, info);
             const codes = [];
             for (let i = 0; i < pasteList.length; i++) {
                 let rowIdx = info.cellRange.row + i;
-                if(rowIdx < gljCache.length){//更新
-                    me.tempCacheArr.push({org: gljCache[rowIdx], newCode: pasteList[i].code});
+                if (rowIdx < gljCache.length) {//更新
+                    me.tempCacheArr.push({ org: gljCache[rowIdx], newCode: pasteList[i].code });
                     gljCache.splice(rowIdx--, 1);
                 }
                 codes.push(pasteList[i].code);
@@ -139,26 +142,47 @@ var rationGLJOprObj = {
             me.addGljItems(codes, pageOprObj.gljLibId, info.cellRange);
         } else if (gljCache && info.cellRange.row < gljCache.length) {
             const pasteList = sheetCommonObj.analyzePasteData(me.setting, info);
-            const maxCount = info.cellRange.row + info.cellRange.rowCount -1 > gljCache.length -1 ?
+            const maxCount = info.cellRange.row + info.cellRange.rowCount - 1 > gljCache.length - 1 ?
                 gljCache.length - info.cellRange.row : info.cellRange.rowCount;
             const precision = me.setting.header[info.cellRange.col].precision;
-            for (let i = 0; i < maxCount; i++) {
-                let roundCons = scMathUtil.roundTo(pasteList[i][field], -precision);
-                gljCache[info.cellRange.row + i][field] = roundCons;
+            if (field === 'lossRateNo') {
+                const lossRateNos = pasteList.map(item => item.lossRateNo);
+                const lossMap = await rationGLJOprObj.getLossMap(lossRateNos);
+                for (let i = 0; i < maxCount; i++) {
+                    const curGLJ = gljCache[info.cellRange.row + i]
+                    const serialNo = pasteList[i][field];
+                    const loss = lossMap[serialNo];
+                    if (loss) {
+                        curGLJ.lossRateID = loss.ID;
+                        curGLJ.lossRateNo = loss.serialNo;
+                        curGLJ.lossRateName = loss.name;
+                        curGLJ.lossRate = loss.rate;
+                    } else {
+                        delete curGLJ.lossRateID;
+                        delete curGLJ.lossRateNo;
+                        delete curGLJ.lossRateName;
+                        delete curGLJ.lossRate;
+                    }
+                }
+            } else {
+                for (let i = 0; i < maxCount; i++) {
+                    const pasteVal = precision ? scMathUtil.roundTo(pasteList[i][field], -precision) : pasteList[i][field];
+                    gljCache[info.cellRange.row + i][field] = pasteVal;
+                }
             }
             me.updateRationItem(function () {
                 me.sheet.getParent().focus(true);
             });
-            if (info.cellRange.row + info.cellRange.rowCount -1 >= gljCache.length -1) {
+            if (info.cellRange.row + info.cellRange.rowCount - 1 >= gljCache.length - 1) {
                 me.sheet.suspendPaint();
-                for(let rowIdx = gljCache.length; rowIdx <= info.cellRange.row + info.cellRange.rowCount -1; rowIdx++){
+                for (let rowIdx = gljCache.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 >= gljCache.length) {
             me.sheet.suspendPaint();
-            for(let rowIdx = info.cellRange.row; rowIdx <= info.cellRange.row + info.cellRange.rowCount -1; rowIdx ++){
+            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();
@@ -169,31 +193,31 @@ var rationGLJOprObj = {
         const rationSection = rationOprObj.getCache();
         const 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'){
+        if (me.currentRationItem && typeof me.cache["_GLJ_" + me.currentRationItem.ID] === 'undefined') {
             me.cache["_GLJ_" + me.currentRationItem.ID] = [];
         }
         const isEmptyRation = !me.currentRationItem;
         if (isEmptyRation) {
             return args.cancel = true;
         }
-        const canEditFields = ['code', 'consumeAmt', 'proportion'];
+        const canEditFields = ['code', 'consumeAmt', 'proportion', 'lossRateNo'];
         const emptyGLJCanEditFields = ['code'];
         const isEmptyGLJ = args.row >= me.cache["_GLJ_" + me.currentRationItem.ID].length;
         const editingField = me.setting.header[args.col].dataCode;
-        const isValidField =  isEmptyGLJ && emptyGLJCanEditFields.includes(editingField) || !isEmptyGLJ && canEditFields.includes(editingField);
+        const isValidField = isEmptyGLJ && emptyGLJCanEditFields.includes(editingField) || !isEmptyGLJ && canEditFields.includes(editingField);
         if (!isValidField) {
             return args.cancel = true;
         }
     },
-    onCellEditEnd: function(sender, args) {
+    onCellEditEnd: async function (sender, args) {
         const me = rationGLJOprObj;
         me.tempCacheArr = [];
         const cacheArr = me.cache["_GLJ_" + me.currentRationItem.ID];
         const editingField = me.setting.header[args.col].dataCode;
         const trimText = args.editingText ? args.editingText.trim() : '';
         const curGLJ = cacheArr[args.row];
-        const originText = curGLJ  && !commonUtil.isEmptyVal(curGLJ[editingField]) ? String(curGLJ[editingField]) : '';
-        if (!trimText || trimText === originText) {
+        const originText = curGLJ && !commonUtil.isEmptyVal(curGLJ[editingField]) ? String(curGLJ[editingField]) : '';
+        if ((!trimText && editingField === 'code') || trimText === originText) {
             args.sheet.setValue(args.row, args.col, originText);
             return;
         }
@@ -205,7 +229,7 @@ var rationGLJOprObj = {
                 return;
             }
             if (args.row < cacheArr.length) { // 替换人材机
-                me.tempCacheArr.push({org: cacheArr[args.row], newCode: args.editingText.toString().trim()});
+                me.tempCacheArr.push({ org: cacheArr[args.row], newCode: args.editingText.toString().trim() });
                 cacheArr.splice(args.row, 1);
             }
             me.addGljItems([trimText], pageOprObj.gljLibId)
@@ -216,32 +240,65 @@ var rationGLJOprObj = {
                 $('#alertModal').modal('show');
                 args.sheet.setValue(args.row, args.col, originText);
             } else {
-                const precision = me.setting.header[args.col].precision;
-                const roundText = scMathUtil.roundTo(trimText, -precision);
-                curGLJ[editingField] = roundText;
+                if (editingField === 'lossRateNo') {
+                    const lossMap = await rationGLJOprObj.getLossMap([trimText]);
+                    const loss = lossMap[trimText];
+                    if (loss) {
+                        curGLJ.lossRateID = loss.ID;
+                        curGLJ.lossRateNo = loss.serialNo;
+                        curGLJ.lossRateName = loss.name;
+                        curGLJ.lossRate = loss.rate;
+                    } else {
+                        delete curGLJ.lossRateID;
+                        delete curGLJ.lossRateNo;
+                        delete curGLJ.lossRateName;
+                        delete curGLJ.lossRate;
+                    }
+                } else {
+                    const precision = me.setting.header[args.col].precision;
+                    const roundText = scMathUtil.roundTo(trimText, -precision);
+                    curGLJ[editingField] = roundText;
+                }
                 me.updateRationItem(function () {
                     me.sheet.getParent().focus(true);
                 });
             }
         }
     },
+    getLossMap: async function (serialNos) {
+        const lossList = await rationGLJOprObj.getLossListByNos(serialNos);
+        const map = {};
+        lossList.forEach(item => {
+            map[item.serialNo] = item;
+        });
+        return map;
+    },
+    getLossListByNos: async function (serialNos) {
+        try {
+            const res = await ajaxPost('/rationRepository/api/getItemsBySerialNos', { serialNos, libID: pageOprObj.rationLibId });
+            return res;
+        } catch (error) {
+            return [];
+        }
+    },
+
     onContextmenuOpr: function () {//右键菜单
         let me = this;
         let raCoe = rationCoeOprObj;
         $.contextMenu({
             selector: '#rdSpread',
-            build: function($triggerElement, e){
+            build: function ($triggerElement, e) {
                 //控制允许右键菜单在哪个位置出现
                 let target = SheetDataHelper.safeRightClickSelection($triggerElement, e, me.sheet.getParent());
                 let sheet = me.sheet;
-                if(me.sheet.getParent().getActiveSheetIndex() === 0 && target.hitTestType === 3){//在表格内&& typeof target.row !== 'undefined' && typeof target.col !== 'undefined'
+                if (me.sheet.getParent().getActiveSheetIndex() === 0 && target.hitTestType === 3) {//在表格内&& typeof target.row !== 'undefined' && typeof target.col !== 'undefined'
                     //rationGlj表
-                    if(typeof target.row !== 'undefined'){
+                    if (typeof target.row !== 'undefined') {
                         //控制按钮是否可用
                         sheet.setActiveCell(target.row, target.col);
                     }
                     return {
-                        callback: function(){},
+                        callback: function () { },
                         items: {
                             "add": {
                                 name: "添加人材机",
@@ -258,18 +315,19 @@ var rationGLJOprObj = {
                                     gljSelOprObj.initRadio();
                                     gljSelOprObj.gljCurTypeId = null;
                                     //默认点击树根节点
-                                    if(gljSelOprObj.rootNode){
+                                    if (gljSelOprObj.rootNode) {
                                         gljSelOprObj.treeObj.selectNode(gljSelOprObj.rootNode);
                                         gljSelTreeOprObj.setting.callback.onClick(null, 'componentTree', gljSelOprObj.rootNode);
                                     }
                                     //弹出窗口
                                     $('#selGlj').modal('show');
-                                }},
+                                }
+                            },
                             "delete": {
                                 name: "删除人材机",
                                 disabled: function () {
                                     const inValidCell = !commonUtil.isDef(target.row) || !commonUtil.isDef(target.col);
-                                    const rationGlj =  me.cache['_GLJ_' + me.currentRationItem.ID];
+                                    const rationGlj = me.cache['_GLJ_' + me.currentRationItem.ID];
                                     const inValidData = !rationGlj || target.row >= rationGlj.length;
                                     if (locked || inValidCell || !me.currentRationItem || inValidData) {
                                         return true;
@@ -278,23 +336,24 @@ var rationGLJOprObj = {
                                 },
                                 icon: "fa-remove",
                                 callback: function (key, opt) {
-                                    const rationGlj =  me.cache['_GLJ_' + me.currentRationItem.ID];
+                                    const rationGlj = me.cache['_GLJ_' + me.currentRationItem.ID];
                                     rationGlj.splice(target.row, 1);
-                                    me.updateRationItem(function(){
+                                    me.updateRationItem(function () {
                                         me.sheet.getParent().focus();
                                     });
                                     sheetCommonObj.cleanData(me.sheet, me.setting, -1);
                                     me.showGljItems(me.currentRationItem.ID);
-                                }},
+                                }
+                            },
                         }
                     };
                 }
                 //rationCoe表
-                else if(me.sheet.getParent().getActiveSheetIndex() === 2 && target.hitTestType === 3 && typeof target.row !== 'undefined' && typeof target.col !== 'undefined'){
-                    let currentCache = raCoe.curRation && raCoe.isDef(raCoe.cache["_Coe_" + raCoe.curRation.ID])  ? raCoe.cache["_Coe_" + raCoe.curRation.ID] : [];
+                else if (me.sheet.getParent().getActiveSheetIndex() === 2 && target.hitTestType === 3 && typeof target.row !== 'undefined' && typeof target.col !== 'undefined') {
+                    let currentCache = raCoe.curRation && raCoe.isDef(raCoe.cache["_Coe_" + raCoe.curRation.ID]) ? raCoe.cache["_Coe_" + raCoe.curRation.ID] : [];
                     sheet.setActiveCell(target.row, target.col);
                     return {
-                        callback: function(){},
+                        callback: function () { },
                         items: {
                             "upMove": {
                                 name: "上移",
@@ -305,7 +364,7 @@ var rationGLJOprObj = {
                                 },
                                 icon: "fa-arrow-up",
                                 callback: function (key, opt) {
-                                    raCoe.upMove(currentCache[target.row], currentCache[target.row - 1], {row: target.row - 1, col: target.col});
+                                    raCoe.upMove(currentCache[target.row], currentCache[target.row - 1], { row: target.row - 1, col: target.col });
                                 }
                             },
                             "downMove": {
@@ -317,7 +376,7 @@ var rationGLJOprObj = {
                                 },
                                 icon: "fa-arrow-down",
                                 callback: function (key, opt) {
-                                    raCoe.downMove(currentCache[target.row], currentCache[target.row + 1], {row: target.row + 1, col: target.col});
+                                    raCoe.downMove(currentCache[target.row], currentCache[target.row + 1], { row: target.row + 1, col: target.col });
                                 }
                             },
                             "ref": {
@@ -330,19 +389,19 @@ var rationGLJOprObj = {
                                 icon: "fa-arrow-left",
                                 callback: function (key, opt) {
                                     raCoe.updateSectionRation(rationOprObj.currentRations["_SEC_ID_" + rationOprObj.currentSectionId], currentCache[target.row], function (updateArr) {
-                                        for(let i = 0, len = updateArr.length; i < len; i++){
+                                        for (let i = 0, len = updateArr.length; i < len; i++) {
                                             let ration = updateArr[i];
                                             let rationCoeList = updateArr[i].rationCoeList;
                                             let newNo = 1;
-                                            for(let j = 0, jLen = rationCoeList.length; j < jLen; j++){
-                                                if(rationCoeList[j].no >= newNo){
+                                            for (let j = 0, jLen = rationCoeList.length; j < jLen; j++) {
+                                                if (rationCoeList[j].no >= newNo) {
                                                     newNo = rationCoeList[j].no + 1;
                                                 }
                                             }
                                             let theCache = raCoe.cache["_Coe_" + ration.ID];
-                                            if(theCache !== undefined && theCache !== null){
+                                            if (theCache !== undefined && theCache !== null) {
                                                 let newCoe = {};
-                                                for(let attr in currentCache[target.row]){
+                                                for (let attr in currentCache[target.row]) {
                                                     newCoe[attr] = currentCache[target.row][attr];
                                                 }
                                                 newCoe.no = newNo;
@@ -355,7 +414,7 @@ var rationGLJOprObj = {
                         }
                     };
                 }
-                else{
+                else {
                     return false;
                 }
             }
@@ -363,40 +422,40 @@ var rationGLJOprObj = {
     },
     getRecoveryArr: function (tempDelArr, newArr) {//获得更新的code不存在,恢复删除的被更新数据
         let rst = [];
-        for(let i = 0, len = tempDelArr.length; i < len; i++){
+        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){
+            for (let j = 0, jLen = newArr.length; j < jLen; j++) {
+                if (tempDelArr[i].newCode == newArr[j].code) {
                     isExist = true;
                     break;
                 }
             }
-            if(!isExist){
+            if (!isExist) {
                 rst.push(tempDelArr[i].org);
             }
         }
         return rst;
     },
-    addGljItems: function(codes, repId) {
+    addGljItems: function (codes, repId) {
         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){
+            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){
-                        if(priceProperties && priceProperties.length > 0){
+                    if (result.data.length > 0) {
+                        if (priceProperties && priceProperties.length > 0) {
                             let priceField = priceProperties[0].price.dataCode;
-                            for(let glj of result.data){
+                            for (let glj of result.data) {
                                 glj.basePrice = glj.priceProperty && glj.priceProperty[priceField] ? glj.priceProperty[priceField] : 0;
                             }
                         }
                         sheetCommonObj.cleanData(me.sheet, me.setting, -1);
-                        var rstArr = [], dummyR = {gljId: 0, consumeAmt:0},
+                        var rstArr = [], dummyR = { gljId: 0, consumeAmt: 0 },
                             newAddArr = [],
                             validGlj = [];
                         for (var i = 0; i < result.data.length; i++) {
@@ -428,7 +487,7 @@ var rationGLJOprObj = {
                             }
                             me.cache["_GLJ_" + me.currentRationItem.ID] = cacheArr.concat(validGlj);
                             let recoveryArr = me.getRecoveryArr(me.tempCacheArr, result.data);
-                            if(recoveryArr.length > 0){
+                            if (recoveryArr.length > 0) {
                                 me.cache["_GLJ_" + me.currentRationItem.ID] = me.cache["_GLJ_" + me.currentRationItem.ID].concat(recoveryArr);
                             }
                         }
@@ -439,15 +498,15 @@ var rationGLJOprObj = {
                             });
                         }
                     }
-                    else{
-                        let cacheArr = me.cache["_GLJ_" + me.currentRationItem.ID]?  me.cache["_GLJ_" + me.currentRationItem.ID] : [];
+                    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){
+                        if (recoveryArr.length > 0) {
                             me.cache["_GLJ_" + me.currentRationItem.ID] = cacheArr.concat(recoveryArr);
                         }
                         //更新的工料机不存在
                         $('#alertModalBtn').click();
-                        $('#alertText').text("人材机"+ codes + "不存在,请查找你所需要的人材机,或新增人材机");
+                        $('#alertText').text("人材机" + codes + "不存在,请查找你所需要的人材机,或新增人材机");
                         $('#alertModalCls').click(function () {
                             me.showGljItems(me.currentRationItem.ID);
                         });
@@ -457,24 +516,24 @@ var rationGLJOprObj = {
                     }
                 }
             },
-            error:function(err){
+            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;
+    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 rationBasePrc = 0;
-        if(me.currentRationItem && me.cache['_GLJ_' + me.currentRationItem.ID]){
+        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){
+                if (gljData.gljType && gljData.basePrice && gljData.consumeAmt) {
                     rationBasePrc += gljData.basePrice * gljData.consumeAmt;
                 }
             });
@@ -482,7 +541,7 @@ var rationGLJOprObj = {
         }
         return rationBasePrc;
     },
-    updateRationItem: function(callback) {
+    updateRationItem: function (callback) {
         var me = this, updateArr = [];
         if (me.currentRationItem) {
             me.currentRationItem.rationGljList = me.buildRationItemGlj();
@@ -491,27 +550,32 @@ var rationGLJOprObj = {
             me.currentRationItem.basePrice = price;
             updateArr.push(me.currentRationItem);
             rationOprObj.mixUpdateRequest(updateArr, [], [], function () {
-                if(callback) callback();
+                if (callback) callback();
             });
         }
     },
 
-    buildRationItemGlj: function(){
+    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({
+                const rGlj = {
                     gljId: cacheArr[i].gljId,
                     consumeAmt: cacheArr[i].consumeAmt,
-                    proportion: cacheArr[i].proportion
-                });
+                    proportion: cacheArr[i].proportion,
+                    lossRateID: cacheArr[i].lossRateID,
+                    lossRateNo: cacheArr[i].lossRateNo,
+                    lossRateName: cacheArr[i].lossRateName,
+                    lossRate: cacheArr[i].lossRate
+                };
+                rst.push(rGlj);
             }
         }
         return rst;
     },
 
-    createRationGljDisplayItem: function(rItem, repGlj) {
+    createRationGljDisplayItem: function (rItem, repGlj) {
         var rst = {};
         rst.gljId = rItem.gljId;
         rst.consumeAmt = rItem.consumeAmt;
@@ -522,9 +586,13 @@ var rationGLJOprObj = {
         rst.unit = repGlj.unit;
         rst.basePrice = repGlj.basePrice;
         rst.gljType = repGlj.gljType;
+        rst.lossRateID = rItem.lossRateID;
+        rst.lossRateNo = rItem.lossRateNo;
+        rst.lossRateName = rItem.lossRateName;
+        rst.lossRate = rItem.lossRate;
         return rst;
     },
-    getGljItems: function(rationItem, callback) {
+    getGljItems: function (rationItem, callback) {
         var me = this, rationID = rationItem.ID, rationGljList = rationItem.rationGljList ? rationItem.rationGljList : [];
         me.currentRationItem = rationItem;
         if (me.cache["_GLJ_" + rationID]) {
@@ -534,43 +602,43 @@ var rationGLJOprObj = {
             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) {
-                            if(priceProperties && priceProperties.length > 0){
-                                let priceField = priceProperties[0].price.dataCode;
-                                for(let glj of result.data){
-                                    glj.basePrice = glj.priceProperty && glj.priceProperty[priceField] ? glj.priceProperty[priceField] : 0;
-                                }
+            $.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) {
+                        if (priceProperties && priceProperties.length > 0) {
+                            let priceField = priceProperties[0].price.dataCode;
+                            for (let glj of result.data) {
+                                glj.basePrice = glj.priceProperty && glj.priceProperty[priceField] ? glj.priceProperty[priceField] : 0;
                             }
-                            var cacheArr = [];
-                            for (var j = 0; j < rationGljList.length; j++) {
-                                for (var i = 0; i < result.data.length; i++) {
-                                    if (rationGljList[j].gljId == result.data[i].ID) {
-                                        cacheArr.push(me.createRationGljDisplayItem(rationGljList[j], result.data[i]));
-                                        break;
-                                    }
+                        }
+                        var cacheArr = [];
+                        for (var j = 0; j < rationGljList.length; j++) {
+                            for (var i = 0; i < result.data.length; i++) {
+                                if (rationGljList[j].gljId == result.data[i].ID) {
+                                    cacheArr.push(me.createRationGljDisplayItem(rationGljList[j], result.data[i]));
+                                    break;
                                 }
                             }
-                            me.cache["_GLJ_" + rationID] = cacheArr;
-                            me.showGljItems(rationID);
                         }
-                        if(callback) callback();
-                    },
-                    error:function(err){
-                        alert(err);
+                        me.cache["_GLJ_" + rationID] = cacheArr;
+                        me.showGljItems(rationID);
                     }
-                })
+                    if (callback) callback();
+                },
+                error: function (err) {
+                    alert(err);
+                }
+            })
         }
     },
-    showGljItems: function(rationID) {
+    showGljItems: function (rationID) {
         var me = this;
         if (me.cache["_GLJ_" + rationID]) {
             sheetCommonObj.cleanData(me.sheet, me.setting, -1);