浏览代码

feat: 清单规则编辑器添加设计细目

vian 2 年之前
父节点
当前提交
25e0f16cb9

+ 8 - 0
modules/all_models/stdBills_bills.js

@@ -4,6 +4,13 @@
 /*清单库编辑器-清单*/
 const mongoose = require('mongoose');
 const Schema = mongoose.Schema;
+
+// 设计细目
+const designItem = {
+    id: Number,
+    serialNo: Number,
+};
+
 const stdBills_bills = new Schema({
     ID: String,
     ParentID: String,
@@ -18,6 +25,7 @@ const stdBills_bills = new Schema({
     comment: String, //备注,清单精灵处输入
     jobs: [],
     items: [],
+    designs: { type: [designItem], default: [] },
     recharge: String,
     billsLibId: { type: Number, index: true },
     sectionInfo: Schema.Types.Mixed,

+ 14 - 0
modules/all_models/stdBills_design.js

@@ -0,0 +1,14 @@
+const mongoose = require('mongoose');
+const Schema = mongoose.Schema;
+const stdBills_designs = new Schema({
+  id: Number,
+  code: Number,
+  name: String,
+  unit: String,
+  billsLibId: Number,
+  deleted: Boolean
+},
+  { versionKey: false }
+);
+
+mongoose.model('std_bills_lib_designs', stdBills_designs);

+ 119 - 74
modules/bills_lib/controllers/bills_lib_controllers.js

@@ -3,8 +3,8 @@
  */
 
 let billsLibDao = require("./../models/bills_lib_interfaces");
-let callback = function(req, res, err, message, data){
-    res.json({error: err, message: message, data: data});
+let callback = function (req, res, err, message, data) {
+    res.json({ error: err, message: message, data: data });
 }
 
 module.exports = {
@@ -20,67 +20,67 @@ module.exports = {
             callback(req, res, 1, 'copyLib fail', null);
         }
     },
-    getMaxNumber: function(req, res){
+    getMaxNumber: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.getMaxNumber(data, function(err, message, maxNumber){
+        billsLibDao.getMaxNumber(data, function (err, message, maxNumber) {
             callback(req, res, err, message, maxNumber);
         });
     },
-    getABillsLib: function(req, res){
+    getABillsLib: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.getABillsLib(data, function(err, message, data){
+        billsLibDao.getABillsLib(data, function (err, message, data) {
             callback(req, res, err, message, data);
         });
     },
-    getStdBillsLib: function(req, res){
-        billsLibDao.getStdBillsLib(function(err, message, stdBillsLib){
-            callback(req, res, err, message, stdBillsLib );
+    getStdBillsLib: function (req, res) {
+        billsLibDao.getStdBillsLib(function (err, message, stdBillsLib) {
+            callback(req, res, err, message, stdBillsLib);
         });
     },
-    createStdBillsLib: function(req, res){
+    createStdBillsLib: function (req, res) {
         let data = JSON.parse(req.body.data);
-         billsLibDao.createStdBillsLib(data, function(err, message, info){
+        billsLibDao.createStdBillsLib(data, function (err, message, info) {
             callback(req, res, err, message, info);
-         });
+        });
     },
-    deleteStdBillsLib: function(req, res){
+    deleteStdBillsLib: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.deleteStdBillsLib(data, function(err, message){
+        billsLibDao.deleteStdBillsLib(data, function (err, message) {
             callback(req, res, err, message, null);
         });
     },
-    renameStdBillsLib: function(req, res) {
+    renameStdBillsLib: function (req, res) {
         let data = JSON.parse(req.body.data);
         billsLibDao.renameStdBillsLib(data, function (err, message) {
-            callback(req, res, err ,message, null);
+            callback(req, res, err, message, null);
         });
     },
-    getStdBillsLibName: function(req, res){
+    getStdBillsLibName: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.getStdBillsLibName(data.billsLibId, function(err, message, info){
+        billsLibDao.getStdBillsLibName(data.billsLibId, function (err, message, info) {
             callback(req, res, err, message, info);
         });
     },
-    getCurrentUniqId: function(req, res){
-        billsLibDao.getCurrentUniqId(function(err, message, id){
+    getCurrentUniqId: function (req, res) {
+        billsLibDao.getCurrentUniqId(function (err, message, id) {
             callback(req, res, err, message, id);
         });
     },
-    getBills: function(req, res){
+    getBills: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.getBills(data.billsLibId, function(err, message, bills){
+        billsLibDao.getBills(data.billsLibId, function (err, message, bills) {
             callback(req, res, err, message, bills);
         });
     },
-    createBills: function(req, res){
+    createBills: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.createBills(data, function(err, message){
+        billsLibDao.createBills(data, function (err, message) {
             callback(req, res, err, message, null);
         });
     },
-    upMove: function(req, res){
+    upMove: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.upMove(data, function(err, message){
+        billsLibDao.upMove(data, function (err, message) {
             callback(req, res, err, message, null);
         });
     },
@@ -92,7 +92,7 @@ module.exports = {
     },
     upLevel: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.upLevel(data, function(err, message){
+        billsLibDao.upLevel(data, function (err, message) {
             callback(req, res, err, message, null);
         })
     },
@@ -104,19 +104,19 @@ module.exports = {
     },
     updatePNId: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.updatePNId(data, function(err, message){
+        billsLibDao.updatePNId(data, function (err, message) {
             callback(req, res, err, message, null);
         });
     },
     updateSectionInfo: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.updateSectionInfo(data, function(err, message){
+        billsLibDao.updateSectionInfo(data, function (err, message) {
             callback(req, res, err, message, null);
         });
     },
-    updateBills: function(req, res){
+    updateBills: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.updateBills(data, function(err, message){
+        billsLibDao.updateBills(data, function (err, message) {
             callback(req, res, err, message, null);
         });
     },
@@ -132,135 +132,180 @@ module.exports = {
             callback(req, res, err, message, null);
         });
     },
-    updateBillsArr: function(req, res){
+    updateBillsArr: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.updateBillsArr(data, function(err, message){
-           callback(req, res, err, message, null);
+        billsLibDao.updateBillsArr(data, function (err, message) {
+            callback(req, res, err, message, null);
         });
     },
-    pasteBills: function(req, res){
+    pasteBills: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.pasteBills(data, function(err, message){
+        billsLibDao.pasteBills(data, function (err, message) {
             callback(req, res, err, message, null);
         });
     },
-    updateRecharge: function(req, res){
+    updateRecharge: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.updateRecharge(data, function(err, message){
+        billsLibDao.updateRecharge(data, function (err, message) {
             callback(req, res, err, message, null);
         });
     },
-    pasteRel: function(req, res){
+    pasteRel: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.pasteRel(data, function(err, message, datas){
+        billsLibDao.pasteRel(data, function (err, message, datas) {
             callback(req, res, err, message, datas);
         });
     },
-    deleteBills: function(req, res){
+    deleteBills: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.deleteBills(data, function(err, message){
+        billsLibDao.deleteBills(data, function (err, message) {
             callback(req, res, err, message, null);
         });
     },
-    isUsed: function(req, res){
+    isUsed: function (req, res) {
         let data = JSON.parse(req.body.data);
         billsLibDao.isUsed(data, function (err, message, datas) {
             callback(req, res, err, message, datas);
         });
     },
-    getJobContent: function(req, res){
+    getJobContent: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.getJobContent(data, function(err, message, jobs){
+        billsLibDao.getJobContent(data, function (err, message, jobs) {
             callback(req, res, err, message, jobs);
         });
     },
-    createJobContent: function(req, res){
+    createJobContent: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.createJobContent(data, function(err, message, id){
+        billsLibDao.createJobContent(data, function (err, message, id) {
             callback(req, res, err, message, id);
         });
     },
-    updateJobContent: function(req, res){
+    updateJobContent: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.updateJobContent(data, function(err, message, id){
+        billsLibDao.updateJobContent(data, function (err, message, id) {
             callback(req, res, err, message, id);
         });
     },
-    updateValue: function(req, res){
+    updateValue: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.updateValue(data, function(err, message){
+        billsLibDao.updateValue(data, function (err, message) {
             callback(req, res, err, message, null);
         })
     },
-    deleteJobContent: function(req, res){
+    deleteJobContent: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.deleteJobContent(data, function(err, message){
+        billsLibDao.deleteJobContent(data, function (err, message) {
             callback(req, res, err, message, null);
         });
     },
     pasteJobs: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.pasteJobs(data, function(err, message, datas){
+        billsLibDao.pasteJobs(data, function (err, message, datas) {
             callback(req, res, err, message, datas);
         });
     },
-    edCreateJob: function(req, res){
+    edCreateJob: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.edCreateJob(data, function(err, message, id){
+        billsLibDao.edCreateJob(data, function (err, message, id) {
             callback(req, res, err, message, id);
         })
     },
-    edUpdateJob: function(req, res){
+    edUpdateJob: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.edUpdateJob(data, function(err, message, id){
+        billsLibDao.edUpdateJob(data, function (err, message, id) {
             callback(req, res, err, message, id);
         })
     },
-    getItemCharacter: function(req, res){
+
+    getDesignContent: function (req, res) {
+        let data = JSON.parse(req.body.data);
+        billsLibDao.getDesignContent(data, function (err, message, designs) {
+            callback(req, res, err, message, designs);
+        });
+    },
+    createDesignContent: function (req, res) {
+        let data = JSON.parse(req.body.data);
+        billsLibDao.createDesignContent(data, function (err, message, id) {
+            callback(req, res, err, message, id);
+        });
+    },
+    updateDesignContent: function (req, res) {
+        let data = JSON.parse(req.body.data);
+        billsLibDao.updateDesignContent(data, function (err, message, id) {
+            callback(req, res, err, message, id);
+        });
+    },
+    deleteDesignContent: function (req, res) {
+        let data = JSON.parse(req.body.data);
+        billsLibDao.deleteDesignContent(data, function (err, message) {
+            callback(req, res, err, message, null);
+        });
+    },
+    pasteDesigns: function (req, res) {
+        let data = JSON.parse(req.body.data);
+        billsLibDao.pasteDesigns(data, function (err, message, datas) {
+            callback(req, res, err, message, datas);
+        });
+    },
+    edCreateDesign: function (req, res) {
+        let data = JSON.parse(req.body.data);
+        billsLibDao.edCreateDesign(data, function (err, message, id) {
+            callback(req, res, err, message, id);
+        })
+    },
+    edUpdateDesign: function (req, res) {
+        let data = JSON.parse(req.body.data);
+        billsLibDao.edUpdateDesign(data, function (err, message, id) {
+            callback(req, res, err, message, id);
+        })
+    },
+
+
+    getItemCharacter: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.getItemCharacter(data, function(err, message, items){
+        billsLibDao.getItemCharacter(data, function (err, message, items) {
             callback(req, res, err, message, items);
         });
     },
-    createItemCharacter: function(req, res){
+    createItemCharacter: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.createItemCharacter(data, function(err, message, id){
+        billsLibDao.createItemCharacter(data, function (err, message, id) {
             callback(req, res, err, message, id);
         });
     },
-    updateItemCharacter: function(req, res){
+    updateItemCharacter: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.updateItemCharacter(data, function(err, message){
+        billsLibDao.updateItemCharacter(data, function (err, message) {
             callback(req, res, err, message, null);
         });
     },
-    deleteItemCharacter: function(req, res){
+    deleteItemCharacter: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.deleteItemCharacter(data, function(err, message){
+        billsLibDao.deleteItemCharacter(data, function (err, message) {
             callback(req, res, err, message, null);
         });
     },
-    pasteItems: function(req, res){
+    pasteItems: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.pasteItems(data, function(err, message, datas){
+        billsLibDao.pasteItems(data, function (err, message, datas) {
             callback(req, res, err, message, datas);
         });
     },
-    pasteValues: function(req, res){
+    pasteValues: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.pasteValues(data, function(err, message, datas){
+        billsLibDao.pasteValues(data, function (err, message, datas) {
             callback(req, res, err, message, datas);
         });
     },
-    edCreateItem: function(req, res){
+    edCreateItem: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.edCreateItem(data, function(err, message, id){
+        billsLibDao.edCreateItem(data, function (err, message, id) {
             callback(req, res, err, message, id);
         })
     },
-    edUpdateItem: function(req, res){
+    edUpdateItem: function (req, res) {
         let data = JSON.parse(req.body.data);
-        billsLibDao.edUpdateItem(data, function(err, message, id){
+        billsLibDao.edUpdateItem(data, function (err, message, id) {
             callback(req, res, err, message, id);
         })
     }

+ 29 - 0
modules/bills_lib/controllers/designs_permissionController.js

@@ -0,0 +1,29 @@
+let billsController = require("./bills_lib_controllers");
+import baseController from "../../common/base/base_controller";
+
+class designsPermContr extends baseController{
+
+    getDesignContent(req, res){
+        billsController.getDesignContent(req, res);
+    }
+    createDesignContent(req, res){
+        billsController.createDesignContent(req, res);
+    }
+    updateDesignContent(req, res){
+        billsController.updateDesignContent(req, res);
+    }
+    deleteDesignContent(req, res){
+        billsController.deleteDesignContent(req, res);
+    }
+    pasteDesigns(req, res){
+        billsController.pasteDesigns(req, res);
+    }
+    edCreateDesign(req, res){
+        billsController.edCreateDesign(req, res);
+    }
+    edUpdateDesign(req, res){
+        billsController.edUpdateDesign(req, res);
+    }
+}
+
+export default designsPermContr;

+ 4 - 0
modules/bills_lib/controllers/views_permissionController.js

@@ -25,6 +25,10 @@ class viewsPermContr extends baseController{
         res.render('maintain/bills_lib/html/neirong.html',
             {userAccount: req.session.managerData.username, LicenseKey:config.getLicenseKey(process.env.NODE_ENV)});
     }
+    redirectStdDesigns(req, res){
+        res.render('maintain/bills_lib/html/design.html',
+            {userAccount: req.session.managerData.username, LicenseKey:config.getLicenseKey(process.env.NODE_ENV)});
+    }
     redirectStdItems(req, res){
         res.render('maintain/bills_lib/html/tezheng.html',
             {userAccount: req.session.managerData.username, LicenseKey:config.getLicenseKey(process.env.NODE_ENV)});

文件差异内容过多而无法显示
+ 1755 - 1243
modules/bills_lib/models/bills_lib_interfaces.js


+ 13 - 2
modules/bills_lib/routes/bills_lib_routes.js

@@ -2,23 +2,26 @@
  * Created by vian on 2017/3/17.
  */
 let express = require("express");
-let billsRouter =express.Router();
+let billsRouter = express.Router();
 import ViewsPermContr from "../controllers/views_permissionController";
 import BillsLibPermContr from "../controllers/stdBillsLib_permissionController";
 import BillsPermContr from "../controllers/bills_permissionController";
 import JobsPermContr from "../controllers/jobs_permissionController";
+import DesignsPermContr from "../controllers/designs_permissionController";
 import ItemsPermContr from "../controllers/items_permissionController";
 let viewsContr = new ViewsPermContr();
 let billsLibContr = new BillsLibPermContr();
 let billsContr = new BillsPermContr();
 let jobsContr = new JobsPermContr();
+let designsContr = new DesignsPermContr();
 let itemsContr = new ItemsPermContr();
 
 
-module.exports =function (app) {
+module.exports = function (app) {
     app.get("/stdBillsmain", viewsContr.auth, viewsContr.init, viewsContr.redirectStdBillsMain);
     app.get("/stdBills", viewsContr.auth, viewsContr.init, viewsContr.redirectStdBills);
     app.get('/stdJobs', viewsContr.auth, viewsContr.init, viewsContr.redirectStdJobs);
+    app.get('/stdDesigns', viewsContr.auth, viewsContr.init, viewsContr.redirectStdDesigns);
     app.get('/stdItems', viewsContr.auth, viewsContr.init, viewsContr.redirectStdItems);
 
     billsRouter.post('/getCompilationList', billsLibContr.auth, billsLibContr.init, billsLibContr.getCompilationList);
@@ -66,6 +69,14 @@ module.exports =function (app) {
     billsRouter.post("/edCreateJob", jobsContr.auth, jobsContr.init, jobsContr.edCreateJob);
     billsRouter.post("/edUpdateJob", jobsContr.auth, jobsContr.init, jobsContr.edUpdateJob);
 
+    billsRouter.post("/getDesignContent", designsContr.auth, designsContr.init, designsContr.getDesignContent);
+    billsRouter.post("/createDesignContent", designsContr.auth, designsContr.init, designsContr.createDesignContent);
+    billsRouter.post("/updateDesignContent", designsContr.auth, designsContr.init, designsContr.updateDesignContent);
+    billsRouter.post("/deleteDesignContent", designsContr.auth, designsContr.init, designsContr.deleteDesignContent);
+    billsRouter.post("/pasteDesigns", designsContr.auth, designsContr.init, designsContr.pasteDesigns);
+    billsRouter.post("/edCreateDesign", designsContr.auth, designsContr.init, designsContr.edCreateDesign);
+    billsRouter.post("/edUpdateDesign", designsContr.auth, designsContr.init, designsContr.edUpdateDesign);
+
     billsRouter.post("/getItemCharacter", itemsContr.auth, itemsContr.init, itemsContr.getItemCharacter);
     billsRouter.post("/createItemCharacter", itemsContr.auth, itemsContr.init, itemsContr.createItemCharacter);
     billsRouter.post("/updateItemCharacter", itemsContr.auth, itemsContr.init, itemsContr.updateItemCharacter);

+ 1 - 0
public/counter/counter.js

@@ -21,6 +21,7 @@ const COUNTER_MODULE_NAME = {
     stdGljLib: 'stdGljLib',
     billsLib: 'billsLib',
     billsLib_jobs: 'billsLib_jobs',
+    billsLib_designs: 'billsLib_designs',
     billsLib_items: 'billsLib_items',
     coeList: 'coeList',
     installation: 'installation',

+ 374 - 0
web/maintain/bills_lib/html/design.html

@@ -0,0 +1,374 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta http-equiv="x-ua-compatible" content="ie=edge">
+    <title>清单规则编辑器</title>
+    <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css">
+    <!--<link rel="stylesheet" href="../../web/css/bootstrap/themes.css">-->
+    <link rel="stylesheet" href="/web/maintain/bills_lib/css/main.css">
+    <link rel="stylesheet" href="/lib/font-awesome/font-awesome.min.css">
+    <!--spread-->
+    <link rel="stylesheet" href="/lib/spreadjs/sheets/css/gc.spread.sheets.sc.css">
+    <!--zTree-->
+    <link rel="stylesheet" href="/lib/ztree/css/zTreeStyle.css" type="text/css">
+</head>
+
+<body>
+    <div class="header">
+        <nav class="navbar navbar-toggleable-lg navbar-light bg-faded p-0 ">
+            <span class="header-logo px-2">清单规则编辑器</span>
+            <div class="navbar-text"></div>
+        </nav>
+        <nav class="navbar navbar-toggleable-lg justify-content-between navbar-light p-0">
+
+              <ul class="nav nav-tabs" role="tablist">
+                  <li class="nav-item">
+                      <a id="aStdBills" class="nav-link px-3" href="stdBills">清单</a>
+                  </li>
+                  <li class="nav-item">
+                      <a id="aStdJobs" class="nav-link px-3" href="stdJobs">工作内容</a>
+                  </li>
+                  <li class="nav-item">
+                      <a id="aStdItems" class="nav-link px-3" href="stdItems">项目特征</a>
+                  </li>
+                  <li class="nav-item">
+                      <a class="nav-link active px-3" href="javascript: void(0);">设计细目</a>
+                  </li>
+              </ul>
+        </nav>
+    </div>
+    <div class="main">
+      <div class="content">
+        <div class="container-fluid">
+          <div class="row">
+            <div class="main-content col-lg-12 p-0">
+                <nav class="tools-bar">
+                </nav>
+                <div class="main-data" id="spreadAllDesigns">
+                </div>
+            </div>
+          <!--  <div class="main-side col-lg-5 p-0">
+            </div>-->
+          </div>
+        </div>
+      </div>
+    </div>
+    <!--弹出添加-->
+    <div class="modal fade" id="add" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                  <h5 class="modal-title">添加定额</h5>
+                  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                  </button>
+                </div>
+                <div class="modal-body">
+                  <form>
+                    <div class="form-group">
+                      <label>编码</label>
+                      <input class="form-control" placeholder="输入编码" type="text">
+                    </div>
+                    <div class="form-group">
+                      <label>名称</label>
+                      <input class="form-control" placeholder="输入名称" type="text">
+                    </div>
+                    <div class="form-group">
+                      <label>单位</label>
+                      <select class="form-control"><option>选择单位</option><option>m3</option></select>
+                    </div>
+                    <div class="form-group">
+                      <label>基价</label>
+                      <input class="form-control" placeholder="输入基价" type="number">
+                    </div>
+                    <div class="form-group">
+                      <label>显示名称(以%s表示参数)</label>
+                      <input class="form-control" placeholder="输入显示名称" type="text">
+                    </div>
+                    <div class="form-group">
+                      <label>默认取费专业</label>
+                      <input class="form-control" placeholder="输入取费专业" type="text">
+                    </div>
+                  </form>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <a href="" class="btn btn-primary">添加</a>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!--弹出编辑-->
+    <div class="modal fade" id="edit" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                  <h5 class="modal-title">编辑定额</h5>
+                  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                  </button>
+                </div>
+                <div class="modal-body">
+                  <form>
+                    <div class="form-group">
+                      <label>编码</label>
+                      <input class="form-control" placeholder="输入编码" type="text" value="AA0001">
+                    </div>
+                    <div class="form-group">
+                      <label>名称</label>
+                      <input class="form-control" placeholder="输入名称" type="text" value="人工挖土方">
+                    </div>
+                    <div class="form-group">
+                      <label>单位</label>
+                      <select class="form-control"><option>m3</option></select>
+                    </div>
+                    <div class="form-group">
+                      <label>基价</label>
+                      <input class="form-control" placeholder="输入基价" type="number" value="880.84">
+                    </div>
+                    <div class="form-group">
+                      <label>显示名称(以%s表示参数)</label>
+                      <input class="form-control" placeholder="输入显示名称" type="text" value="人工挖土方">
+                    </div>
+                    <div class="form-group">
+                      <label>默认取费专业</label>
+                      <input class="form-control" placeholder="输入取费专业" type="text" value="1">
+                    </div>
+                  </form>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <a href="" class="btn btn-primary">确定</a>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <!--弹出删除-->
+    <div class="modal fade" id="del" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                  <h5 class="modal-title">删除确认</h5>
+                  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                  </button>
+                </div>
+                <div class="modal-body">
+                    <h5 class="text-danger">删除后无法恢复,确认是否删除?</h5>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <a href="" class="btn btn-danger">删除</a>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!--弹出提示窗口-->
+    <button id="alertBtn" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#alertDiv" style="display: none"></button>
+    <div class="modal fade" id="alertDiv" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <input type="hidden"  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="alertCls" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">×</span>
+                    </button>
+                </div>
+                <div class="modal-body">
+                    <h5 class="text-danger" id="alertTxt">编号不存在,请重新输入!</h5>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-danger" id="alertCof" data-dismiss="modal">确认</button>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!--删除-->
+    <div class="modal fade" id="delAlert" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <input type="hidden"  value="123">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h5 class="modal-title">警告</h5>
+                    <button type="button"  class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">×</span>
+                    </button>
+                </div>
+                <div class="modal-body">
+                    <h5 class="text-danger" id="delText">是否删除当前行?</h5>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-danger" id="delConfirm">确认</button>
+                    <button type="button" class="btn btn-secondary"  data-dismiss="modal">取消</button>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!-- JS. -->
+    <script src = "/lib/spreadjs/sheets/gc.spread.sheets.all.11.1.2.min.js"></script>
+    <script>GC.Spread.Sheets.LicenseKey =  '<%- LicenseKey %>';</script>
+    <script src="/lib/jquery/jquery.min.js"></script>
+    <script src="/lib/tether/tether.min.js"></script>
+    <script src="/lib/bootstrap/bootstrap.min.js"></script>
+    <script src="/web/maintain/bills_lib/scripts/global.js"></script>
+    <script src="/public/web/PerfectLoad.js"></script>
+    <script src="/public/web/common_ajax.js"></script>
+    <script src="/public/web/lock_util.js"></script>
+    <script src="/public/web/sheet/sheet_common.js"></script>
+    <script src="/web/maintain/bills_lib/scripts/set_sheets.js"></script>
+    <script src="/web/maintain/bills_lib/scripts/bills_lib_ajax.js"></script>
+    <script src="/web/maintain/bills_lib/scripts/tools.js"></script>
+    <script src="/public/web/tree_sheet/tree_sheet_helper.js"></script>
+    <script src="/web/maintain/bills_lib/scripts/bills_lib_setting.js"></script>
+    <script src="/web/maintain/bills_lib/scripts/db_controller.js"></script>
+    <SCRIPT type="text/javascript">
+        const locked = lockUtil.getLocked();
+        let billsLibId = getQueryString("billsLibId");
+        tools.redirect(billsLibId, 'stdBillsmain');
+        let userAccount = '<%= userAccount%>'
+        let spreadAllDesigns = new GC.Spread.Sheets.Workbook($('#spreadAllDesigns')[0], {sheetCount: 1});
+        spreadAllDesigns.options.allowUserDragFill = false;
+        sheetCommonObj.bindEscKey(spreadAllDesigns, [{sheet: spreadAllDesigns.getSheet(0), editStarting: totalDesignsController.onEditStart, editEnded: totalDesignsController.onEditEnded}]);
+        let orgDesignData;
+        let maxDesignsNumber;
+        let sheetDesignsDatas;
+        $(document).ready(function(){
+            $('#aStdBills').attr('href', function(){
+                return `stdBills?billsLibId=${billsLibId}&locked=${locked}`;
+            });
+            $('#aStdJobs').attr('href', function(){
+                return `stdJobs?billsLibId=${billsLibId}&locked=${locked}`;
+            });
+            $('#aStdItems').attr('href', function(){
+                return `stdItems?billsLibId=${billsLibId}&locked=${locked}`;
+            });
+            billsAjax.getStdBillsLibName(billsLibId);
+            buildAllDesigns(spreadAllDesigns, totalDesignsSetting);
+            lockUtil.lockSpreads([spreadAllDesigns], locked);
+        });
+        function buildAllDesigns(spreadAllDesigns, setting){
+            setSheet.initSheet(spreadAllDesigns, setting, true);
+            myKey.downKey(spreadAllDesigns);
+            myKey.enterKey(spreadAllDesigns);
+            TREE_SHEET_HELPER.loadSheetHeader(setting, spreadAllDesigns.getActiveSheet());
+            designsAjax.getDesignContent(billsLibId, function(datas){
+                spreadAllDesigns.getActiveSheet().suspendPaint();
+                spreadAllDesigns.getActiveSheet().setRowCount(datas.length + 10);
+                let len = datas.length;
+                for(var i=0; i<len; i++){
+                    setting.cols.forEach(function(col, colIdx){
+                        spreadAllDesigns.getActiveSheet().setTag(i, colIdx, datas[i].id, GC.Spread.Sheets.SheetArea.viewport);
+                        if(datas[i][col.data.field]){
+                            spreadAllDesigns.getActiveSheet().getCell(i, colIdx, GC.Spread.Sheets.SheetArea.viewport).value(datas[i][col.data.field]);
+                        }
+                        else {
+                            spreadAllDesigns.getActiveSheet().getCell(i, colIdx, GC.Spread.Sheets.SheetArea.viewport).value('');
+                        }
+                    }); 
+                }
+                spreadAllDesigns.getActiveSheet().resumePaint();
+                let totalDesigns = createObj.newDesigns();
+                totalDesigns.loadDesigns(null, datas);
+                totalDesignsController.totalDesigns = totalDesigns;
+                tools.getBillsIds(function(ids){
+                    myKey.delKey(spreadAllDesigns, ids, totalDesigns, setting, 'totalDesigns');
+                    bindSheet(totalDesigns, spreadAllDesigns.getActiveSheet(), setting);
+                    pasteDesigns(spreadAllDesigns.getActiveSheet(), totalDesigns);
+                });
+            });
+        }
+        function bindSheet(totalDesigns, sheet, setting){
+            setSheet.setMaxRowCount(sheet, totalDesigns.designsArr);
+            mainAjax.getMaxNumber(billsLibId, 'designs', function(result){
+                if(result.length === 0){
+                    maxDesignsNumber = 0;
+                }
+                else {
+                    maxDesignsNumber = result[0].code;
+                }
+                orgDesignData = sheet.getCell(0, 0).value();
+                totalDesignsController.editData(sheet);
+            });
+        }
+
+        function pasteDesigns(sheet, totalDesigns){
+           // sheetDesignsDatas = tools.getsheetDatas(sheet, 'total');
+            sheet.bind(GC.Spread.Sheets.Events.ClipboardPasting, function (sender, args) {
+                sheetDesignsDatas = tools.getsheetDatas(sheet, 'total');
+                let maxCol = args.cellRange.col + args.cellRange.colCount - 1;
+                //复制的列数超过正确的列数,不可复制
+                if(maxCol >= totalDesignsSetting.cols.length){
+                    args.cancel = true;
+                }
+            });
+            sheet.bind(GC.Spread.Sheets.Events.ClipboardPasted, function(sender, args){
+                const colIdx = 1;
+                debugger;
+                let orgRow = args.cellRange.row, orgCol = args.cellRange.col, rowCount = args.cellRange.rowCount, colCount = args.cellRange.colCount;
+                let maxRow = orgRow + rowCount - 1, maxCol = orgCol + colCount -1;
+                let pasteDatas = [], uncrossedDatas = [], crossedDatas = [];
+                for(let i = orgRow; i<= maxRow; i++){
+                    for(let j =0; j<=totalDesignsSetting.cols.length - 1; j++){
+                        const field = totalDesignsSetting.cols[j].data.field;
+                        if(sheet.getCell(i, j).value()){
+                            let unitData = {
+                                billsLibId: billsLibId,
+                                rowIdx: i,
+                                colIdx: j,
+                                field: field,
+                                data: sheet.getCell(i, j).value(),
+                                type:  'Create'
+                            };
+                            pasteDatas.push(unitData);
+                        }
+                    }
+                }
+                let uniqPasteDatas = tools.uniqObjArr(pasteDatas);
+                tools.resetRowIdx(uniqPasteDatas, orgRow);
+                for(let i=0; i< uniqPasteDatas.length; i++){
+                    let crossedData;
+                    let flag = true;
+                    sheetDesignsDatas.forEach(function(orgData){
+                        if(uniqPasteDatas[i].rowIdx === orgData.rowIdx && uniqPasteDatas[i].colIdx === orgData.colIdx){
+                            flag = false;
+                            crossedData = {
+                                billsLibId: billsLibId,
+                                rowIdx: uniqPasteDatas[i].rowIdx,
+                                colIdx: uniqPasteDatas[i].colIdx,
+                                field: uniqPasteDatas[i].field,
+                                orgId: orgData.id,
+                                data: uniqPasteDatas[i].data,
+                                type: 'Update'
+                            }
+                        }
+                    });
+                    if(flag){
+                        uncrossedDatas.push(uniqPasteDatas[i]);
+                    }
+                    else{
+                        crossedDatas.push(crossedData);
+                    }
+                }
+                let encapDatas = tools.encapTotalDesignsDatas(sheet, totalDesigns, uncrossedDatas, crossedDatas);
+                if(encapDatas.updateDatas.length > 0 || encapDatas.createDatas.length >0){
+                    designsAjax.pasteDesigns(userAccount, billsLibId, encapDatas, function(datas){
+                        pasteController.pasteDesignsFront(sheet, totalDesigns,datas);
+                    });
+                }
+                else{
+                    tools.reshowData(sheet, totalDesigns.designsArr, totalDesignsSetting, true);
+                }
+            });
+        }
+  	</SCRIPT>
+</body>
+<script type="text/javascript">
+    autoFlashHeight();
+</script>
+
+</html>

+ 8 - 0
web/maintain/bills_lib/html/neirong.html

@@ -34,6 +34,9 @@
                   <li class="nav-item">
                       <a id="aStdItems" class="nav-link px-3" href="stdItems">项目特征</a>
                   </li>
+                  <li class="nav-item">
+                      <a id="aStdDesigns" class="nav-link px-3" href="stdDesigns">设计细目</a>
+                  </li>
               </ul>
         </nav>
     </div>
@@ -230,6 +233,7 @@
         let userAccount = '<%= userAccount%>'
         let spreadAllJobs = new GC.Spread.Sheets.Workbook($('#spreadAllJobs')[0], {sheetCount: 1});
         spreadAllJobs.options.allowUserDragFill = false;
+        debugger;
         sheetCommonObj.bindEscKey(spreadAllJobs, [{sheet: spreadAllJobs.getSheet(0), editStarting: totalJobsController.onEditStart, editEnded: totalJobsController.onEditEnded}]);
         let orgJobData;
         let maxJobNumer;
@@ -242,6 +246,9 @@
             $('#aStdItems').attr('href', function(){
                 return `stdItems?billsLibId=${billsLibId}&locked=${locked}`;
             });
+            $('#aStdDesigns').attr('href', function(){
+                return `stdDesigns?billsLibId=${billsLibId}&locked=${locked}`;
+            });
             billsAjax.getStdBillsLibName(billsLibId);
             buildAllJobs(spreadAllJobs, totalJobsSetting);
             lockUtil.lockSpreads([spreadAllJobs], locked);
@@ -306,6 +313,7 @@
                 let orgRow = args.cellRange.row, orgCol = args.cellRange.col, rowCount = args.cellRange.rowCount, colCount = args.cellRange.colCount;
                 let maxRow = orgRow + rowCount - 1, maxCol = orgCol + colCount -1;
                 let pasteDatas = [], uncrossedDatas = [], crossedDatas = [];
+                debugger;
                 for(let i = orgRow; i<= maxRow; i++){
                     for(let j =0; j<=1; j++){
                         let filed = j === 0 ? 'code' : 'content';

+ 208 - 17
web/maintain/bills_lib/html/qingdan.html

@@ -33,6 +33,9 @@
                   <li class="nav-item">
                       <a id="aStdItems" class="nav-link px-3" href="stdItems">项目特征</a>
                   </li>
+                  <li class="nav-item">
+                    <a id="aStdDesigns" class="nav-link px-3" href="stdDesigns">设计细目</a>
+                </li>
               </ul>
         </nav>
     </div>
@@ -69,21 +72,25 @@
                 </div>
             </div>
             <div class="main-side col-lg-5 p-0">
-              <div class="container-fluid">
-                  <div  style="width:50%; height: 100%; float: left;">
+              <div class="container-fluid" style="overflow: auto; height: 100%;">
+                  <div  style="width:50%; height: 330px; float: left;">
                       <h5>工作内容</h5>
                       <div id="spreadJobs" class="ovf-hidden" style="width:97%; height: 300px;"></div>
-                  </div>
-                  <div  style="width:50%; height: 100%; float: left;">
-                      <h5>项目特征</h5>
-                      <div id="spreadItems" class="ovf-hidden" style="width: 97%; height: 300px;"></div>
-                  </div>
+                    </div>
+                    <div  style="width:50%; height: 330px; float: left;">
+                        <h5>项目特征</h5>
+                        <div id="spreadItems" class="ovf-hidden" style="width: 97%; height: 300px;"></div>
+                    </div>
+                    <div style="width:100%; height: 330px; float: left;">
+                        <h5>设计细目</h5>
+                        <div id="spreadDesigns" class="ovf-hidden" style="width:97%; height: 300px;"></div>
+                </div>
                  <!-- <div class="form-group">
                       <a class="pull-right" href="javacript:void(0);" data-toggle="modal" data-target="#help" >html怎么写?</a>
                       <label for="exampleTextarea">补注:</label>
                       <textarea id="exampleTextarea" name="editor" class="form-control" rows="8"></textarea>
                   </div>-->
-                  <div class="form-group">
+                  <div class="form-group" style="height: 330px; clear: both;">
                       <a class="pull-right" href="javacript:void(0);" data-toggle="modal" data-target="#help" >html怎么写?</a>
                       <a trigger="billsRecharge" class="pull-right mr-3 uploadImgTrigger lock-btn-control" href="javacript:void(0);" data-toggle="modal" data-target="#uploadimg" ><i class="fa fa-image"></i>上传图片</a>
                       <label for="exampleTextarea">补注:</label>
@@ -372,10 +379,12 @@
     let maxJobsNumber;
     let maxItemsNumber;
     let orgJobData;
+    let orgDesignData;
     let orgItemData;
     let billsTree = billsLibTree.createBillsTree();
     let billsLibId = getQueryString("billsLibId");
     let sheetDatas;
+    let sheetDesignsDatas;
     let sheetItemsDatas;
     let sheetBillsDatas;
     tools.redirect(billsLibId, 'stdBillsmain');
@@ -386,6 +395,9 @@
     let itemsSpread = new GC.Spread.Sheets.Workbook($("#spreadItems")[0], {sheetCount: 1});
     itemsSpread.options.allowUserDragFill = false;
     sheetCommonObj.bindEscKey(itemsSpread, [{sheet: itemsSpread.getSheet(0), editStarting: itemsController.onEditStart, editEnded: itemsController.onEditEnded}]);
+    let designsSpread = new GC.Spread.Sheets.Workbook($("#spreadDesigns")[0], {sheetCount: 1});
+    designsSpread.options.allowUserDragFill = false;
+    sheetCommonObj.bindEscKey(designsSpread, [{sheet: designsSpread.getSheet(0), editStarting: designsController.onEditStart, editEnded: designsController.onEditEnded}]);
     const billKindComboList = [
         { name: '大项费用', value: 1 },
         { name: '项目节', value: 8 },
@@ -398,18 +410,22 @@
         $('#aStdItems').attr('href', function(){
             return `stdItems?billsLibId=${billsLibId}&locked=${locked}`;
         });
+        $('#aStdDesigns').attr('href', function(){
+                return `stdDesigns?billsLibId=${billsLibId}&locked=${locked}`;
+            });
         billsAjax.getStdBillsLibName(billsLibId);
         billsAjax.getBills(billsLibId, function(bills){
-            showBillsSheet(bills, jobsSpread.getActiveSheet(), itemsSpread.getActiveSheet(), billsLibSetting)
-            const spreads = [billsSpread, jobsSpread, itemsSpread];
+            showBillsSheet(bills, jobsSpread.getActiveSheet(), designsSpread.getActiveSheet(), itemsSpread.getActiveSheet(), billsLibSetting)
+            const spreads = [billsSpread, jobsSpread, designsSpread, itemsSpread];
             const $range = $(document.body);
             lockUtil.lockSpreadsAndTools(spreads, $range, locked);
         });
         buildJobs(jobsSpread, jobsSetting);
+        buildDesigns(designsSpread, designsSetting);
         buildItems(itemsSpread, itemsSetting);
     });
 
-    function nodeOpration(controller, totalJobs, totalItems){
+    function nodeOpration(controller, totalJobs, totalDesigns, totalItems){
         let btnInsert = $('#insert');
         let btnDelete = $('#delete');
         let btnUpLevel = $('#upLevel');
@@ -481,7 +497,7 @@
         sheet.resumePaint();
         sheet.resumeEvent();
     }
-    function showBillsSheet(datas, jobsSheet, itemsSheet, setting) {
+    function showBillsSheet(datas, jobsSheet, designsSheet, itemsSheet, setting) {
         billsSpread = new GC.Spread.Sheets.Workbook($('#spreadBills')[0], {sheetCount: 1});
         let billsSheet = billsSpread.getSheet(0);
         sheetCommonObj.bindEscKey(billsSpread, [{sheet: billsSpread.getSheet(0), editStarting: dbController.onEditStart, editEnded: dbController.onEditEnded}]);
@@ -522,7 +538,7 @@
         //补注内容改变
         rechargeChange(controller);//
         //焦点控制
-        switchFcs(controller, controller.sheet, billsSpread, jobsSheet, itemsSheet);
+        switchFcs(controller, controller.sheet, billsSpread, jobsSheet, designsSheet, itemsSheet);
         //jobs
         jobOperation(controller, jobsSheet, function(totalJobs){
             //------关联表粘贴复制
@@ -530,8 +546,12 @@
             //items
             itemOperation(controller, itemsSheet, function(totalItems){
                 bindPasteItemsRel(itemsSheet, controller, totalItems, itemsSetting);
-                //节点操作
-                nodeOpration(controller, totalJobs, totalItems);
+
+                designOperation(controller, designsSheet, function (totalDesigns) {
+                    bindPasteDesignRel(designsSheet, controller, totalDesigns, designsSetting);
+                    //节点操作
+                    nodeOpration(controller, totalJobs, totalDesigns, totalItems);
+                })
             });
         });
         // 设置类别下拉
@@ -544,7 +564,7 @@
         setCombo(billsSheet, comboCol, nameList);
     }
 
-    function switchFcs(controller, billsSheet, billsSpread, jobsSheet, itemsSheet){
+    function switchFcs(controller, billsSheet, billsSpread, jobsSheet, designsSheet, itemsSheet){
         let btnInsert = $('#insert');
         let btnDelete = $('#delete');
         let btnUpMove = $('#upMove');
@@ -554,8 +574,10 @@
         billsSheet.bind(GC.Spread.Sheets.Events.CellClick, function (sender, args) {
                 jobsSheet.clearSelection();
                 itemsSheet.clearSelection();
+                designsSheet.clearSelection();
                 billsSpread.focus(true);
                 jobsSheet.options.isProtected = true;
+                designsSheet.options.isProtected = true;
                 itemsSheet.options.isProtected = true;
                 billsSheet.options.isProtected = false;
 
@@ -568,9 +590,11 @@
         });
         jobsSheet.bind(GC.Spread.Sheets.Events.CellClick, function (sender, args) {
                 itemsSheet.clearSelection();
+                designsSheet.clearSelection();
                 jobsSpread.focus(true);
                 itemsSheet.options.isProtected = true;
                 billsSheet.options.isProtected = true;
+                designsSheet.options.isProtected = true;
                 jobsSheet.options.isProtected = false;
                 controller.tree.selected.args = args;
                 controller.tree.selected.field = 'job';
@@ -605,10 +629,53 @@
                     btnDownMove.attr('canMove', 'false');
                 }
         });
+        designsSheet.bind(GC.Spread.Sheets.Events.CellClick, function (sender, args) {
+                jobsSheet.clearSelection();
+                itemsSheet.clearSelection();
+                designsSpread.focus(true);
+                itemsSheet.options.isProtected = true;
+                jobsSheet.options.isProtected = true;
+                billsSheet.options.isProtected = true;
+                designsSheet.options.isProtected = false;
+                controller.tree.selected.args = args;
+                controller.tree.selected.field = 'design';
+                tools.btnClose(btnInsert);
+                tools.btnClose(btnDelete);
+                tools.btnClose(btnUpLevel);
+                tools.btnClose(btnDownLevel);
+                btnInsert.attr('fcsOnBills', 'false');
+                btnDelete.attr('fcsOnBills', 'false');
+                btnUpLevel.attr('fcsOnBills', 'false');
+                btnDownLevel.attr('fcsOnBills', 'false');
+                btnUpMove.attr('fcsOnBills', 'false');
+                btnDownMove.attr('fcsOnBills', 'false');
+                let selected;
+                if(controller.tree.selected){
+                    selected = controller.tree.selected.jobs[args.row];
+                }
+                if(tools.canUpMove(selected, controller.tree.selected.jobs)){
+                    tools.btnAction(btnUpMove);
+                    btnUpMove.attr('canMove', 'true');
+                }
+                else{
+                    tools.btnClose(btnUpMove);
+                    btnUpMove.attr('canMove', 'false');
+                }
+                if(tools.canDownMove(selected, controller.tree.selected.jobs)){
+                    tools.btnAction(btnDownMove);
+                    btnDownMove.attr('canMove', 'true');
+                }
+                else{
+                    tools.btnClose(btnDownMove);
+                    btnDownMove.attr('canMove', 'false');
+                }
+        });
         itemsSheet.bind(GC.Spread.Sheets.Events.CellClick, function (sender, args) {
                 jobsSheet.clearSelection();
+                designsSheet.clearSelection();
                 itemsSpread.focus(true);
                 jobsSheet.options.isProtected = true;
+                designsSheet.options.isProtected = true;
                 billsSheet.options.isProtected = true;
                 itemsSheet.options.isProtected = false;
 
@@ -722,6 +789,29 @@
         });
     }
 
+    function designOperation(controller, designsSheet, callback){
+        mainAjax.getMaxNumber(billsLibId, 'designs', function(result){
+            if(result.length === 0){
+                maxDesignsNumber = 0;
+            }
+            else {
+                maxDesignsNumber = result[0].code;
+            }
+            designsAjax.getDesignContent(billsLibId, function(datas){
+                let totalDesigns = createObj.newDesigns();
+                totalDesigns.loadDesigns(controller.tree.items, datas);
+                designsController.totalDesigns = totalDesigns;
+                initData(controller, designsSheet, designsSetting, 'designs');
+                myKey.delKey(designsSpread, controller, totalDesigns, designsSetting, 'designs');
+                bindSheet(controller, designsSheet, 'designs', designsSetting);
+                designsController.editData(designsSheet);
+                if (callback){
+                    callback(totalDesigns);
+                }
+            });
+        });
+    }
+
     function itemOperation(controller, itemsSheet, callback){
         mainAjax.getMaxNumber(billsLibId, 'items', function(result){
             if(result.length === 0){
@@ -750,7 +840,7 @@
         if(controller.tree.selected){
             let arr = controller.tree.selected[classify];
             let recharge = controller.tree.selected.data.recharge;
-            let prefix = classify === 'jobs' ? 'job' : 'item';
+            const prefix = classify.replace(/s$/, '');
             if(arr.length > 0){
                 tools.orderReshowData(sheet, arr, setting, prefix,true);
             }
@@ -788,6 +878,16 @@
                     }
                     //sheetDatas = tools.getsheetDatas(sheet, 'jobs');
                 }
+                if(field === 'designs'){
+                    tools.clearData(sheet);
+                    let designs = controller.tree.selected.designs;
+                    setSheet.setMaxRowCount(sheet, designs);
+                    if(designs.length > 0){
+                        tools.orderReshowData(sheet, designs, setting, 'design', true);
+                        orgDesignData = sheet.getValue(0, 0);
+                    }
+                    //sheetDatas = tools.getsheetDatas(sheet, 'jobs');
+                }
                 if(field === 'items'){
                     tools.clearData(sheet);
                     let items = controller.tree.selected.items;
@@ -933,6 +1033,7 @@
         });
         sheet.bind(GC.Spread.Sheets.Events.ClipboardPasted, function(sender, args){
             if(controller.tree.selected){
+                debugger;
                 let orgRow = args.cellRange.row, orgCol = args.cellRange.col, rowCount = args.cellRange.rowCount, colCount = args.cellRange.colCount;
                 let maxRow = orgRow + rowCount - 1, maxCol = orgCol + colCount -1;
                 let pasteArr = [];
@@ -993,6 +1094,88 @@
             }
         });
     }
+
+    function bindPasteDesignRel(sheet, controller, totalDesigns, setting){
+        sheet.bind(GC.Spread.Sheets.Events.ClipboardPasting, function (sender, args) {
+            let maxCol = args.cellRange.col + args.cellRange.colCount - 1;
+            debugger;
+            sheetDesignDatas = tools.getsheetDatas(sheet, 'designs');
+            //复制的列数超过正确的列数,不可复制
+            if(maxCol >= designsSetting.cols.length){
+                args.cancel = true;
+            }
+        });
+        sheet.bind(GC.Spread.Sheets.Events.ClipboardPasted, function(sender, args){
+            if(controller.tree.selected){
+                let orgRow = args.cellRange.row, orgCol = args.cellRange.col, rowCount = args.cellRange.rowCount, colCount = args.cellRange.colCount;
+                let maxRow = orgRow + rowCount - 1, maxCol = orgCol + colCount -1;
+                let pasteArr = [];
+                let crossedDatas = [];
+                let uncrossedDatas = [];
+                const codeCol = 0;
+                const nameCol = 1;
+                const unitCol = 2;
+                debugger;
+                for(let i=orgRow; i<=maxRow; i++){
+                    //粘贴编号列,转换成粘贴内容处理
+                    let code = sheet.getCell(i, codeCol).value();
+                    const name = sheet.getCell(i, nameCol).value();
+                    const unit = sheet.getCell(i, unitCol).value();
+                    if(code && !name && !unit){
+                        const matched = totalDesigns.designsArr.find(item => item.data.code == code);
+                        if(matched){
+                            if (!pasteArr.find(item => item.name == matched.data.name && item.unit == matched.data.unit)) {
+                                pasteArr.push({ name: matched.data.name, unit: matched.data.unit });
+                            }
+                        }
+                    }
+                    if(name || unit){
+                        if (!pasteArr.find(item => item.name == name && item.unit == unit)) {
+                            pasteArr.push({ name, unit });
+                        }
+                    }
+                }
+                let uniqPasteArr = pasteArr;
+                let serialNoUn = tools.getSerialNo(controller.tree.selected.designs) - 1;
+                for(let i =orgRow, j=0; i<=uniqPasteArr.length+orgRow-1; i++, j++ ){
+                    let flag = true;
+                    let crossedData;
+                    sheetDesignDatas.forEach(function(rowData){
+                        if(rowData.rowIdx === i && (rowData.name != uniqPasteArr[j].name || rowData.unit != uniqPasteArr[j].unit)){
+                            flag = false;
+                            let serialNo = tools.getObj(controller.tree.selected.designs, rowData.id, 'design');
+                            crossedData = {
+                                orgId: rowData.id,
+                                name: uniqPasteArr[j].name,
+                                unit: uniqPasteArr[j].unit,
+                                serialNo: serialNo.serialNo
+                            };
+                        }
+                    });
+                    if(flag){
+                        serialNoUn++;
+                        uncrossedDatas.push({name: uniqPasteArr[j].name, unit: uniqPasteArr[j].unit, serialNo: serialNoUn});
+                    }
+                    else {
+                        crossedDatas.push(crossedData);
+                    }
+                }
+                let pasteDatas = tools.encapDesignsData(uncrossedDatas, crossedDatas, controller, totalDesigns);
+                if(pasteDatas.updateDatas.length > 0 || pasteDatas.createDatas.length > 0){
+                    billsAjax.pasteRel(userAccount, billsLibId, pasteDatas.updateDatas, pasteDatas.createDatas, 'designs', function(datas){
+                        pasteController.frontDesignsRelOperator(sheet, setting, controller, totalDesigns, datas);
+                    });
+                }
+                else {
+                    tools.orderReshowData(sheet, controller.tree.selected.designs, setting, 'design', true);
+                }
+            }
+            else {
+                tools.clearData(sheet);
+            }
+        });
+    }
+
     function bindPasteItemsRel(sheet, controller, totalItems, setting){
         //sheetItemsDatas = tools.getsheetDatas(sheet, 'items');
         sheet.bind(GC.Spread.Sheets.Events.ClipboardPasting, function (sender, args) {
@@ -1075,6 +1258,14 @@
         TREE_SHEET_HELPER.loadSheetHeader(jobsSetting, jobsSpread.getActiveSheet());
     }
 
+    function buildDesigns(designsSpread, setting){
+        setSheet.initSheet(designsSpread, setting, true);
+        designsSpread.getActiveSheet().clearSelection();
+        myKey.downKey(designsSpread);
+        myKey.enterKey(designsSpread);
+        TREE_SHEET_HELPER.loadSheetHeader(designsSetting, designsSpread.getActiveSheet());
+    }
+
     function buildItems(itemsSpread, setting){
         setSheet.initSheet(itemsSpread, setting, true);
        // setSheet.setMaxRowCount(itemsSpread.getActiveSheet(), 10);

+ 6 - 0
web/maintain/bills_lib/html/tezheng.html

@@ -34,6 +34,9 @@
                   <li class="nav-item">
                       <a class="nav-link active px-3" href="javascript: void(0);">项目特征</a>
                   </li>
+                  <li class="nav-item">
+                    <a id="aStdDesigns" class="nav-link px-3" href="stdDesigns">设计细目</a>
+                </li>
               </ul>
         </nav>
     </div>
@@ -248,6 +251,9 @@
             $('#aStdJobs').attr('href', function(){
                 return `stdJobs?billsLibId=${billsLibId}&locked=${locked}`;
             });
+            $('#aStdDesigns').attr('href', function(){
+                return `stdDesigns?billsLibId=${billsLibId}&locked=${locked}`;
+            });
 
             billsAjax.getStdBillsLibName(billsLibId);
             buildAllItems(spread, totalItemsSetting);

+ 248 - 157
web/maintain/bills_lib/scripts/bills_lib_ajax.js

@@ -10,9 +10,9 @@ var mainAjax = {
             dataType: 'json',
             success: function (result) {
                 //addoptions
-                for(let i = 0; i < result.data.length; i++){
-                    let $option =  $("<option >"+ result.data[i].name +"</option>");
-                    $option.val( result.data[i]._id);
+                for (let i = 0; i < result.data.length; i++) {
+                    let $option = $("<option >" + result.data[i].name + "</option>");
+                    $option.val(result.data[i]._id);
                     $('#compilationSels').append($option);//
                 }
                 $('#compilationSels').on("change", function () {
@@ -20,30 +20,30 @@ var mainAjax = {
             }
         });
     },
-    getMaxNumber: function(billsLibId, field, callback){
+    getMaxNumber: function (billsLibId, field, callback) {
         $.ajax({
             type: 'post',
             url: '/stdBillsEditor/getMaxNumber',
-            data: {data: JSON.stringify({billsLibId: billsLibId, field: field})},
+            data: { data: JSON.stringify({ billsLibId: billsLibId, field: field }) },
             dataType: 'json',
-            success: function(result){
-                if(!result.error){
-                    if(callback){
+            success: function (result) {
+                if (!result.error) {
+                    if (callback) {
                         callback(result.data);
                     }
                 }
             }
         });
     },
-    getABillsLib: function(billsLibId, callback){
+    getABillsLib: function (billsLibId, callback) {
         $.ajax({
             type: 'post',
             url: '/stdBillsEditor/getABillsLib',
-            data: {data: JSON.stringify({billsLibId: billsLibId})},
+            data: { data: JSON.stringify({ billsLibId: billsLibId }) },
             dataType: 'json',
-            success: function(result){
-                if(!result.error){
-                    if(callback){
+            success: function (result) {
+                if (!result.error) {
+                    if (callback) {
                         callback(result.data);
                     }
                 }
@@ -75,28 +75,28 @@ var mainAjax = {
         }, '');
         return libHtml;
     },
-    getStdBillsLib: function(){
+    getStdBillsLib: function () {
         const me = this;
         $.ajax({
             type: "post",
             url: "/stdBillsEditor/getStdBillsLib",
             dataType: "json",
-            success: function(result){
-                if(result.data){
+            success: function (result) {
+                if (result.data) {
                     $('#showArea').append(me.getLibsHtml(result.data));
                 }
             }
         });
     },
-    createStdBillsLib: function(userAccount, billsLibName){
+    createStdBillsLib: function (userAccount, billsLibName) {
         const me = this;
         $.ajax({
             type: "POST",
             url: "/stdBillsEditor/createStdBillsLib",
-            data: {data: JSON.stringify({userAccount: userAccount, name: billsLibName}) },
+            data: { data: JSON.stringify({ userAccount: userAccount, name: billsLibName }) },
             dataType: "json",
-            success: function(result){
-                if(!result.error){
+            success: function (result) {
+                if (!result.error) {
                     $('#showArea').append(me.getLibsHtml(result.data));
                     $('#add').modal('hide');
                 }
@@ -108,7 +108,7 @@ var mainAjax = {
         $.ajax({
             type: 'post',
             url: '/stdBillsEditor/copyStdBillsLib',
-            data: {data: JSON.stringify({libId, libName})},
+            data: { data: JSON.stringify({ libId, libName }) },
             dataType: 'json',
             timeout: 150000,
             beforeSend: function () {
@@ -125,29 +125,29 @@ var mainAjax = {
             }
         });
     },
-    deleteStdBillsLib: function(lastOperator, billsLibId){
+    deleteStdBillsLib: function (lastOperator, billsLibId) {
         $.ajax({
             type: "POST",
             url: "/stdBillsEditor/deleteStdBillsLib",
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId }) },
             dataType: "json",
-            success: function(result){
-                if(!result.error){
-                    var jqSel = "#"+billsLibId;
+            success: function (result) {
+                if (!result.error) {
+                    var jqSel = "#" + billsLibId;
                     $(jqSel).remove();
                     $('#del').modal('hide');
                 }
             }
         });
     },
-    renameStdBillsLib: function(lastOperator, billsLibId, newName){
+    renameStdBillsLib: function (lastOperator, billsLibId, newName) {
         $.ajax({
             type: "post",
             url: "/stdBillsEditor/renameStdbillsLib",
-            data: {data: JSON.stringify({lastOperator: lastOperator, id: billsLibId, value: newName})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, id: billsLibId, value: newName }) },
             dataType: "json",
-            success: function(result){
-                if(!result.error){
+            success: function (result) {
+                if (!result.error) {
                     var jqSel = "#" + billsLibId + " td:first" + " a";
                     $(jqSel).text(newName);
                 }
@@ -159,8 +159,8 @@ var mainAjax = {
             type: 'post',
             url: 'stdBillsEditor/getCurrentUniqId',
             dataType: 'json',
-            success: function(result){
-                if(!result.error && callback){
+            success: function (result) {
+                if (!result.error && callback) {
                     callback(result.data);
                 }
             }
@@ -169,58 +169,58 @@ var mainAjax = {
 }
 
 var billsAjax = {
-    getStdBillsLibName: function(billsLibId) {
+    getStdBillsLibName: function (billsLibId) {
         $.ajax({
             type: "post",
             url: "/stdBillsEditor/getStdBillsLibName",
-            data: {data: JSON.stringify({billsLibId: billsLibId})},
-            success: function(result){
-                if(!result.error){
+            data: { data: JSON.stringify({ billsLibId: billsLibId }) },
+            success: function (result) {
+                if (!result.error) {
                     $(".navbar-text").append(
-                    "<a href='stdBillsmain'>清单规则</a><i class='fa fa-angle-right fa-fw'></i>"+result.data[0].billsLibName
+                        "<a href='stdBillsmain'>清单规则</a><i class='fa fa-angle-right fa-fw'></i>" + result.data[0].billsLibName
                     );
                 }
             }
         });
     },
-    getBills: function(billsLibId, callback){
+    getBills: function (billsLibId, callback) {
         $.ajax({
             type: "post",
             url: "/stdBillsEditor/getBills",
-            data: {data: JSON.stringify({billsLibId: billsLibId})},
+            data: { data: JSON.stringify({ billsLibId: billsLibId }) },
             dataType: "json",
-            success: function(result){
-                if(!result.error){
-                    if(callback) {
+            success: function (result) {
+                if (!result.error) {
+                    if (callback) {
                         callback(result.data);
                     }
                 }
             }
         });
     },
-    createBills: function(lastOperator, billsLibId, newId, pid, nid, updatePreData, sectionInfo, callback){
+    createBills: function (lastOperator, billsLibId, newId, pid, nid, updatePreData, sectionInfo, callback) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/createBills',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, newId: newId, ParentID: pid, NextSiblingID: nid, updatePreData: updatePreData, sectionInfo: sectionInfo})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, newId: newId, ParentID: pid, NextSiblingID: nid, updatePreData: updatePreData, sectionInfo: sectionInfo }) },
             dataType: 'json',
-            success: function(result){
-                if(!result.error){
-                    if(callback){
+            success: function (result) {
+                if (!result.error) {
+                    if (callback) {
                         callback();
                     }
                 }
             }
         });
     },
-    upMove: function(lastOperator, billsLibId, updateDatas, callback){
+    upMove: function (lastOperator, billsLibId, updateDatas, callback) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/upMove',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, updateDatas: updateDatas})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, updateDatas: updateDatas }) },
             dataType: 'json',
-            success: function(result){
-                if(!result.error && callback){
+            success: function (result) {
+                if (!result.error && callback) {
                     callback();
                 }
             }
@@ -230,24 +230,24 @@ var billsAjax = {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/downMove',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, updateDatas: updateDatas})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, updateDatas: updateDatas }) },
             dataType: 'json',
-            success: function(result){
-                if(!result.error && callback){
+            success: function (result) {
+                if (!result.error && callback) {
                     callback();
                 }
             }
         })
     },
-    updatePNId: function(billsLibId, updateData, callback){
+    updatePNId: function (billsLibId, updateData, callback) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/updatePNId',
-            data: {data: JSON.stringify({billsLibId: billsLibId, updateData: updateData})},
+            data: { data: JSON.stringify({ billsLibId: billsLibId, updateData: updateData }) },
             dataType: 'json',
-            success: function(result){
+            success: function (result) {
                 console.log(`entersFuc`);
-                if(!result.error && callback){
+                if (!result.error && callback) {
                     console.log(`enterSc`);
                     callback();
                 }
@@ -255,19 +255,19 @@ var billsAjax = {
                     //提示窗口:更新失败
                 }
             },
-            error: function(){
+            error: function () {
                 console.log(`error`);
             }
         });
     },
-    upLevel: function(lastOperator, billsLibId, updateDatas, callback){
+    upLevel: function (lastOperator, billsLibId, updateDatas, callback) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/upLevel',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, updateDatas: updateDatas})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, updateDatas: updateDatas }) },
             dataType: 'json',
             success: function (result) {
-                if(!result.error && callback){
+                if (!result.error && callback) {
                     callback();
                 }
             }
@@ -277,25 +277,25 @@ var billsAjax = {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/downLevel',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, updateDatas: updateDatas})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, updateDatas: updateDatas }) },
             dataType: 'json',
             success: function (result) {
-                if(!result.error && callback){
+                if (!result.error && callback) {
                     callback();
                 }
             }
         })
     },
-    deleteBills: function(lastOperator, billsLibId, deleteIds, updateNode, callback){
+    deleteBills: function (lastOperator, billsLibId, deleteIds, updateNode, callback) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/deleteBills',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, deleteIds: deleteIds, updateNode: updateNode})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, deleteIds: deleteIds, updateNode: updateNode }) },
             dataType: 'json',
-            success: function(result){
-                if(!result.error){
+            success: function (result) {
+                if (!result.error) {
                     console.log(result.message);
-                    if(callback){
+                    if (callback) {
                         callback();
                     }
                 }
@@ -303,7 +303,7 @@ var billsAjax = {
 
         });
     },
-    updateBills: function(lastOperator, billsLibId, updateId, field, data){
+    updateBills: function (lastOperator, billsLibId, updateId, field, data) {
         if (field === 'fixedFlag') {
             let findData = BillsFixedFlagList.find((x) => x.name === data);
             if (findData) {
@@ -319,21 +319,21 @@ var billsAjax = {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/updateBills',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, updateId: updateId, field: field, data: data})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, updateId: updateId, field: field, data: data }) },
             dataType: 'json',
-            success: function(result){
+            success: function (result) {
 
             }
         });
     },
-    updateSectionInfo: function(data, callback){
+    updateSectionInfo: function (data, callback) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/updateSectionInfo',
-            data: {data: JSON.stringify({updateData: data})},
+            data: { data: JSON.stringify({ updateData: data }) },
             dataType: 'json',
-            success: function(result){
-                if(!result.error && callback){
+            success: function (result) {
+                if (!result.error && callback) {
                     callback();
                 }
             }
@@ -343,9 +343,9 @@ var billsAjax = {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/removeTotal',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, billsIds: billsIds, delIds: delIds, field: field})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, billsIds: billsIds, delIds: delIds, field: field }) },
             dataType: 'json',
-            success: function(result){
+            success: function (result) {
 
             }
         })
@@ -354,35 +354,35 @@ var billsAjax = {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/updateSerialNo',
-            data: {data: JSON.stringify({lastOperator: userAccount, billsLibId: billsLibId, billsId: billsId, updateArr: updateArr, field: field})},
+            data: { data: JSON.stringify({ lastOperator: userAccount, billsLibId: billsLibId, billsId: billsId, updateArr: updateArr, field: field }) },
             dataType: 'json',
             success: function (result) {
-                if(!result.error && callback){
+                if (!result.error && callback) {
                     callback();
                 }
             }
         });
     },
-    updateBillsArr: function(lastOperator, billsLibId, updateId, orgId, newId, type, classify, callback){
+    updateBillsArr: function (lastOperator, billsLibId, updateId, orgId, newId, type, classify, callback) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/updateBillsArr',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, updateId: updateId, orgId: orgId, newId: newId, type: type, classify: classify})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, updateId: updateId, orgId: orgId, newId: newId, type: type, classify: classify }) },
             dataType: 'json',
-            success: function(result){
-                if(!result.error && callback){
+            success: function (result) {
+                if (!result.error && callback) {
                     callback();
                 }
             }
         });
     },
-    pasteBills: function(lastOperator, billsLibId, datas, successCallback, errorCallback){
+    pasteBills: function (lastOperator, billsLibId, datas, successCallback, errorCallback) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/pasteBills',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, datas: datas})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, datas: datas }) },
             dataType: 'json',
-            success: function(result){
+            success: function (result) {
                 if (!result.error && successCallback) {
                     successCallback();
                 } else if (result.error && errorCallback) {
@@ -398,13 +398,13 @@ var billsAjax = {
             }
         });
     },
-    updateRecharge: function(lastOperator, billsLibId, updateId, data){
+    updateRecharge: function (lastOperator, billsLibId, updateId, data) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/updateRecharge',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, updateId: updateId, data: data})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, updateId: updateId, data: data }) },
             dataType: 'json',
-            success: function(result){
+            success: function (result) {
 
             }
         });
@@ -413,10 +413,10 @@ var billsAjax = {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/pasteRel',
-            data: {data:JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, updateDatas: updateDatas, createDatas: createDatas, field: field})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, updateDatas: updateDatas, createDatas: createDatas, field: field }) },
             dataType: 'json',
-            success: function(result){
-                if(!result.error && callback){
+            success: function (result) {
+                if (!result.error && callback) {
                     callback(result.data);
                 }
             }
@@ -425,102 +425,193 @@ var billsAjax = {
 };
 
 var jobsAjax = {
-    getJobContent: function(billsLidId, callback){
+    getJobContent: function (billsLidId, callback) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/getJobContent',
-            data: {data: JSON.stringify({billsLibId: billsLidId})},
+            data: { data: JSON.stringify({ billsLibId: billsLidId }) },
             dataType: 'json',
-            success: function(result){
-                if(!result.error && callback){
+            success: function (result) {
+                if (!result.error && callback) {
                     callback(result.data);
                 }
             }
         });
     },
-    getSomeJobs: function(billsLibId, ids, callback){
+    getSomeJobs: function (billsLibId, ids, callback) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/getSomeJobs',
-            data: {data: JSON.stringify({billsLibId: billsLibId, ids: ids})},
+            data: { data: JSON.stringify({ billsLibId: billsLibId, ids: ids }) },
             dataType: 'json',
-            success: function(result){
-                if(!result.error && callback){
+            success: function (result) {
+                if (!result.error && callback) {
                     callback(result.data);
                 }
             }
         });
     },
-    createJobContent: function(lastOperator, billsLibId, data, serialNo, callback){
+    createJobContent: function (lastOperator, billsLibId, data, serialNo, callback) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/createJobContent',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, data: data, serialNo: serialNo})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, data: data, serialNo: serialNo }) },
             dataType: 'json',
-            success: function(result){
-                if(!result.error && callback){
+            success: function (result) {
+                if (!result.error && callback) {
                     callback(result.data);
                 }
             }
         });
     },
-    updateJobContent: function(lastOperator, billsLibId, id, field, data){
+    updateJobContent: function (lastOperator, billsLibId, id, field, data) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/updateJobContent',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, updateId: id, field: field, data: data })},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, updateId: id, field: field, data: data }) },
             dataType: 'json',
-            success: function(result){
+            success: function (result) {
 
             }
         });
     },
-    deleteJobContent: function(lastOperator, billsLibId, ids){
+    deleteJobContent: function (lastOperator, billsLibId, ids) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/deleteJobContent',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, ids: ids})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, ids: ids }) },
             dataType: 'json',
-            success: function(result){
+            success: function (result) {
 
             }
         });
     },
-    pasteJobs: function(lastOperator, billsLibId, pasteDatas, callback){
+    pasteJobs: function (lastOperator, billsLibId, pasteDatas, callback) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/pasteJobs',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, pasteDatas: pasteDatas})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, pasteDatas: pasteDatas }) },
             dataType: 'json',
-            success: function(result){
-                if(!result.error && callback){
+            success: function (result) {
+                if (!result.error && callback) {
                     callback(result.data);
                 }
             }
 
         });
     },
-    edCreateJob: function(lastOperator, billsLibId, billsId, data, code, serialNo, callback){
+    edCreateJob: function (lastOperator, billsLibId, billsId, data, code, serialNo, callback) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/edCreateJob',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, billsId:billsId, data: data, code: code, serialNo: serialNo})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, billsId: billsId, data: data, code: code, serialNo: serialNo }) },
             dataType: 'json',
-            success: function(result){
-                if(!result.error && callback){
+            success: function (result) {
+                if (!result.error && callback) {
                     callback(result.data);
                 }
             }
         });
     },
-    edUpdateJob: function(lastOperator, billsLibId, billsId, content, code, orgJobId, callback){
+    edUpdateJob: function (lastOperator, billsLibId, billsId, content, code, orgJobId, callback) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/edUpdateJob',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, billsId:billsId, content: content, code: code, orgJobId: orgJobId})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, billsId: billsId, content: content, code: code, orgJobId: orgJobId }) },
             dataType: 'json',
-            success: function(result){
-                if(!result.error && callback){
+            success: function (result) {
+                if (!result.error && callback) {
+                    callback(result.data);
+                }
+            }
+        });
+    }
+};
+
+var designsAjax = {
+    getDesignContent: function (billsLidId, callback) {
+        $.ajax({
+            type: 'post',
+            url: 'stdBillsEditor/getDesignContent',
+            data: { data: JSON.stringify({ billsLibId: billsLidId }) },
+            dataType: 'json',
+            success: function (result) {
+                if (!result.error && callback) {
+                    callback(result.data);
+                }
+            }
+        });
+    },
+    createDesignContent: function (lastOperator, billsLibId, field, data, serialNo, callback) {
+        $.ajax({
+            type: 'post',
+            url: 'stdBillsEditor/createDesignContent',
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, field, data: data, serialNo: serialNo }) },
+            dataType: 'json',
+            success: function (result) {
+                if (!result.error && callback) {
+                    callback(result.data);
+                }
+            }
+        });
+    },
+    updateDesignContent: function (lastOperator, billsLibId, id, field, data) {
+        $.ajax({
+            type: 'post',
+            url: 'stdBillsEditor/updateDesignContent',
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, updateId: id, field: field, data: data }) },
+            dataType: 'json',
+            success: function (result) {
+
+            }
+        });
+    },
+    deleteDesignContent: function (lastOperator, billsLibId, ids) {
+        $.ajax({
+            type: 'post',
+            url: 'stdBillsEditor/deleteDesignContent',
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, ids: ids }) },
+            dataType: 'json',
+            success: function (result) {
+
+            }
+        });
+    },
+    pasteDesigns: function (lastOperator, billsLibId, pasteDatas, callback) {
+        $.ajax({
+            type: 'post',
+            url: 'stdBillsEditor/pasteDesigns',
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, pasteDatas: pasteDatas }) },
+            dataType: 'json',
+            success: function (result) {
+                if (!result.error && callback) {
+                    callback(result.data);
+                }
+            }
+
+        });
+    },
+    edCreateDesign: function (lastOperator, billsLibId, billsId, field, data, code, serialNo, callback) {
+        $.ajax({
+            type: 'post',
+            url: 'stdBillsEditor/edCreateDesign',
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, billsId: billsId, field, data: data, code: code, serialNo: serialNo }) },
+            dataType: 'json',
+            success: function (result) {
+                if (!result.error && callback) {
+                    callback(result.data);
+                }
+            }
+        });
+    },
+    edUpdateDesign: function (lastOperator, billsLibId, billsId, name, unit, code, orgDesignId, callback) {
+        $.ajax({
+            type: 'post',
+            url: 'stdBillsEditor/edUpdateDesign',
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, billsId: billsId, name, unit, code: code, orgDesignId }) },
+            dataType: 'json',
+            success: function (result) {
+                if (!result.error && callback) {
                     callback(result.data);
                 }
             }
@@ -529,76 +620,76 @@ var jobsAjax = {
 };
 
 var itemsAjax = {
-    getItemCharacter: function(billsLibId, callback){
+    getItemCharacter: function (billsLibId, callback) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/getItemCharacter',
-            data: {data: JSON.stringify({billsLibId: billsLibId})},
+            data: { data: JSON.stringify({ billsLibId: billsLibId }) },
             dataType: 'json',
-            success: function(result){
-                if(!result.error){
-                    if(callback){
+            success: function (result) {
+                if (!result.error) {
+                    if (callback) {
                         callback(result.data);
                     }
                 }
             }
         });
     },
-    createItemCharacter: function(lastOperator, billsLibId,  data, code, callback){
+    createItemCharacter: function (lastOperator, billsLibId, data, code, callback) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/createItemCharacter',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, data: data, code: code})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, data: data, code: code }) },
             dataType: 'json',
-            success: function(result){
-                if(!result.error && callback){
+            success: function (result) {
+                if (!result.error && callback) {
                     callback(result.data);
                 }
             }
         });
     },
-    updateItemCharacter: function(lastOperator, billsLibId, id, field, data){
+    updateItemCharacter: function (lastOperator, billsLibId, id, field, data) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/updateItemCharacter',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, updateId: id, field: field, data: data })},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, updateId: id, field: field, data: data }) },
             dataType: 'json',
-            success: function(result){
+            success: function (result) {
 
             }
         });
     },
-    updateValue: function(lastOperator, billsLibId, id, data, deleteCodes, type){
+    updateValue: function (lastOperator, billsLibId, id, data, deleteCodes, type) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/updateValue',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, updateId: id, data: data, type: type, deleteCodes: deleteCodes})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, updateId: id, data: data, type: type, deleteCodes: deleteCodes }) },
             dataType: 'json',
-            success: function(reslut){
+            success: function (reslut) {
 
             }
         });
     },
-    deleteItemCharacter: function(lastOperator, billsLibId, ids){
+    deleteItemCharacter: function (lastOperator, billsLibId, ids) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/deleteItemCharacter',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, ids: ids})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, ids: ids }) },
             dataType: 'json',
-            success: function(result){
+            success: function (result) {
 
             }
         });
     },
-    pasteItems: function(lastOperator, billsLibId, pasteDatas, callback){
+    pasteItems: function (lastOperator, billsLibId, pasteDatas, callback) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/pasteItems',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, pasteDatas: pasteDatas})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, pasteDatas: pasteDatas }) },
             dataType: 'json',
-            success: function(result){
+            success: function (result) {
                 console.log(result);
-                if(!result.error){
+                if (!result.error) {
                     console.log(result.data);
                     callback(result.data);
                 }
@@ -606,40 +697,40 @@ var itemsAjax = {
 
         });
     },
-    pasteValues: function(lastOperator, billsLibId, pasteDatas, callback){
+    pasteValues: function (lastOperator, billsLibId, pasteDatas, callback) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/pasteValues',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, pasteDatas: pasteDatas})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, pasteDatas: pasteDatas }) },
             dataType: 'json',
-            success: function(result){
-                if(!result.error && callback){
+            success: function (result) {
+                if (!result.error && callback) {
                     callback(result.data);
                 }
             }
         });
     },
-    edCreateItem: function(lastOperator, billsLibId, billsId, data, code, serialNo, callback){
+    edCreateItem: function (lastOperator, billsLibId, billsId, data, code, serialNo, callback) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/edCreateItem',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, billsId:billsId, data: data, code: code, serialNo: serialNo})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, billsId: billsId, data: data, code: code, serialNo: serialNo }) },
             dataType: 'json',
-            success: function(result){
-                if(!result.error && callback){
+            success: function (result) {
+                if (!result.error && callback) {
                     callback(result.data);
                 }
             }
         });
     },
-    edUpdateItem: function(lastOperator, billsLibId, billsId, content, code, orgItemId, callback){
+    edUpdateItem: function (lastOperator, billsLibId, billsId, content, code, orgItemId, callback) {
         $.ajax({
             type: 'post',
             url: 'stdBillsEditor/edUpdateItem',
-            data: {data: JSON.stringify({lastOperator: lastOperator, billsLibId: billsLibId, billsId:billsId, content: content, code: code, orgItemId: orgItemId})},
+            data: { data: JSON.stringify({ lastOperator: lastOperator, billsLibId: billsLibId, billsId: billsId, content: content, code: code, orgItemId: orgItemId }) },
             dataType: 'json',
-            success: function(result){
-                if(!result.error && callback){
+            success: function (result) {
+                if (!result.error && callback) {
                     callback(result.data);
                 }
             }

+ 120 - 0
web/maintain/bills_lib/scripts/bills_lib_setting.js

@@ -172,6 +172,66 @@ var jobsSetting = {
     treeCol: 0
 };
 
+var designsSetting = {
+    cols: [
+        {
+            head: {
+                titleNames: ['编号'],
+                spanCols: [1],
+                spanRows: [2],
+                vAlign: [1, 1],
+                hAlign: [1, 1],
+                font: 'Arial'
+            },
+            data: {
+                field: 'code',
+                vAlign: 1,
+                hAlign: 0,
+                font: 'Arial'
+            },
+            width: 100
+        },
+        {
+            head: {
+                titleNames: ['名称'],
+                spanCols: [1],
+                spanRows: [2],
+                vAlign: [1, 1],
+                hAlign: [1, 1],
+                font: 'Arial'
+            },
+            data: {
+                field: 'name',
+                vAlign: 1,
+                hAlign: 0,
+                font: 'Arial'
+            },
+            width: 200
+        },
+        {
+            head: {
+                titleNames: ['单位'],
+                spanCols: [1],
+                spanRows: [2],
+                vAlign: [1, 1],
+                hAlign: [1, 1],
+                font: 'Arial'
+            },
+            data: {
+                field: 'unit',
+                vAlign: 1,
+                hAlign: 0,
+                font: 'Arial'
+            },
+            width: 200
+        },
+    ],
+    headRows: 1,
+    headRowHeight: [47],
+    emptyRows: 3,
+    treeCol: 0
+};
+
 var itemsSetting = {
     cols: [
         {
@@ -258,6 +318,66 @@ var totalJobsSetting = {
     treeCol: 0
 };
 
+var totalDesignsSetting = {
+    cols: [
+        {
+            head: {
+                titleNames: ['编号'],
+                spanCols: [1],
+                spanRows: [2],
+                vAlign: [1, 1],
+                hAlign: [1, 1],
+                font: 'Arial'
+            },
+            data: {
+                field: 'code',
+                vAlign: 1,
+                hAlign: 0,
+                font: 'Arial'
+            },
+            width: 200
+        },
+        {
+            head: {
+                titleNames: ['名称'],
+                spanCols: [1],
+                spanRows: [2],
+                vAlign: [1, 1],
+                hAlign: [1, 1],
+                font: 'Arial'
+            },
+            data: {
+                field: 'name',
+                vAlign: 1,
+                hAlign: 0,
+                font: 'Arial'
+            },
+            width: 850
+        },
+        {
+            head: {
+                titleNames: ['单位'],
+                spanCols: [1],
+                spanRows: [2],
+                vAlign: [1, 1],
+                hAlign: [1, 1],
+                font: 'Arial'
+            },
+            data: {
+                field: 'unit',
+                vAlign: 1,
+                hAlign: 0,
+                font: 'Arial'
+            },
+            width: 100
+        },
+    ],
+    headRows: 1,
+    headRowHeight: [47],
+    emptyRows: 3,
+    treeCol: 0
+};
+
 var totalItemsSetting = {
     cols: [
         {

+ 773 - 17
web/maintain/bills_lib/scripts/db_controller.js

@@ -242,6 +242,7 @@ var dbController = {
                 controller.delete();
                 //to solve refresh after deleted
                 let jobsSheet = jobsSpread.getActiveSheet();
+                let designsSheet = designsSpread.getActiveSheet();
                 let itemsSheet = itemsSpread.getActiveSheet();
                 let nowNode = controller.tree.selected;
                 if (nowNode) {
@@ -254,6 +255,13 @@ var dbController = {
                     if (jobs.length > 0) {
                         orgJobData = jobsSheet.getValue(0, 0);
                     }
+                    let designs = controller.tree.selected.designs;
+                    setSheet.setMaxRowCount(designsSheet, designs);
+                    tools.orderReshowData(designsSheet, designs, designsSetting, 'design', false);
+                    if (designs.length > 0) {
+                        orgDesignData = designsSheet.getValue(0, 0);
+                    }
+
                     let items = controller.tree.selected.items;
                     setSheet.setMaxRowCount(itemsSheet, items);
                     tools.orderReshowData(itemsSheet, items, itemsSetting, 'item', false);
@@ -263,11 +271,13 @@ var dbController = {
                 }
                 else {
                     tools.clearData(jobsSheet);
+                    tools.clearData(designsSheet);
                     tools.clearData(itemsSheet);
                     codeEditor.setValue('');
                     //$('#exampleTextarea').val("");
                 }
                 sheetDatas = tools.getsheetDatas(jobsSheet, 'jobs');
+                sheetDesignDatas = tools.getsheetDatas(designsSheet, 'designs');
                 sheetItemsDatas = tools.getsheetDatas(itemsSheet, 'items');
                 sheetBillsDatas = tools.getsheetDatas(controller.sheet, 'bills', controller);
                 controller.sheet.getParent().focus(true);
@@ -451,6 +461,68 @@ var createObj = {
         return new TotalJobs();
     },
 
+    newDesign: function (data) {
+        var Design = function (data) {
+            this.data = data;
+            //count = 0则没有被引用了
+            this.count = 0;
+        };
+        return new Design(data);
+    },
+    newDesigns: function () {
+        var TotalDesigns = function () {
+            this.designs = {};
+            this.designsArr = [];
+            this.prefix = '_id';
+        };
+
+        TotalDesigns.prototype.findDesign = function (id) {
+            return this.designs[this.prefix + id] ? this.designs[this.prefix + id] : null;
+        }
+
+
+        TotalDesigns.prototype.loadDesigns = function (nodes, datas) {
+            var me = this;
+            datas.forEach(function (data) {
+                var design = createObj.newDesign(data);
+                me.designs[me.prefix + data.id] = design;
+                me.designsArr.push(design);
+            });
+            if (nodes) {
+                nodes.forEach(function (node) {
+                    node.designs = new Array();
+                    let spliceArr = [];
+                    node.data.designs.forEach(function (obj) {
+                        if (me.designs[me.prefix + obj.id]) {
+                            node.designs.push({ design: me.designs[me.prefix + obj.id], serialNo: obj.serialNo });
+                            me.designs[me.prefix + obj.id].count++;
+                        }
+                        else {
+                            spliceArr.push(obj);
+                        }
+                    });
+                    for (let sItem of spliceArr) {
+                        node.data.designs.splice(node.data.designs.indexOf(sItem), 1);
+                    }
+                });
+            }
+        };
+
+        TotalDesigns.prototype.getUpdateIds = function (nodes, repeatId) {
+            var ids = [];
+            nodes.forEach(function (node) {
+                node.designs.forEach(function (design) {
+                    if (design.data.id === repeatId) {
+                        ids.push(node.getID());
+                    }
+                });
+            });
+            return ids;
+        };
+
+        return new TotalDesigns();
+    },
+
     newItem: function (data) {
         var Item = function (data) {
             this.data = data;
@@ -586,6 +658,14 @@ var tools = {
         }
         return isExist;
     },
+    isDesignExist: function (totalArr, field, newData, sheet, row) {
+        if (field === 'code') {
+            return !!totalArr.find(item => item.data.code == newData);
+        }
+        const name = field === 'name' ? newData : sheet.getValue(row, 1);
+        const unit = field === 'unit' ? newData : sheet.getValue(row, 2);
+        return !!totalArr.find(item => item.data.name == name && item.data.unit == unit);
+    },
     isRepeat: function (arr, field, newData, ref, classify) {
         var isRepeat = false;
         if (classify) {
@@ -614,6 +694,36 @@ var tools = {
         }
         return isRepeat;
     },
+    isDesignRepeat: function (arr, field, newData, ref, classify, sheet, row) {
+        const name = field === 'name' ? newData : sheet.getValue(row, 1);
+        const unit = field === 'unit' ? newData : sheet.getValue(row, 2);
+        var isRepeat = false;
+        if (classify) {
+            if (arr) {
+                arr.forEach(function (item, index) {
+                    if (ref === 'reference' && index !== row && ((item[classify].data.name == name && item[classify].data.unit == unit) || (field === 'code' && item[classify].data.code == newData))) {
+                        isRepeat = true;
+                    }
+                    else if (ref === 'document' && index !== row && ((item.name == name && item.unit == unit) || (field === 'code' && item.code == newData))) {
+                        isRepeat = true;
+                    }
+                });
+            }
+        }
+        else {
+            if (arr) {
+                arr.forEach(function (item) {
+                    if (ref === 'reference' && index !== row && ((item.data.name == name && item.data.unit == unit) || (field === 'code' && item.data.code == newData))) {
+                        isRepeat = true;
+                    }
+                    else if (ref === 'document' && index !== row && ((item.name == name && item.unit == unit) || (field === 'code' && item.code == newData))) {
+                        isRepeat = true;
+                    }
+                });
+            }
+        }
+        return isRepeat;
+    },
 
     getContentByCode: function (items, code) {
         for (let item of items) {
@@ -822,8 +932,9 @@ var tools = {
     },
     //update--
     orderReshowData: function (sheet, arr, setting, classify, isResort) {
-        sheet.setColumnCount(2, GC.Spread.Sheets.SheetArea.viewport);
-        sheet.setColumnCount(2, GC.Spread.Sheets.SheetArea.colHeader);
+        const colCount = setting.cols.length;
+        sheet.setColumnCount(colCount, GC.Spread.Sheets.SheetArea.viewport);
+        sheet.setColumnCount(colCount, GC.Spread.Sheets.SheetArea.colHeader);
         tools.clearData(sheet);
         if (arr.length > 0) {
             sheet.suspendPaint();
@@ -849,8 +960,9 @@ var tools = {
 
     reshowData: function (sheet, arr, setting, isResort) {
         sheet.suspendPaint();
-        sheet.setColumnCount(2, GC.Spread.Sheets.SheetArea.viewport);
-        sheet.setColumnCount(2, GC.Spread.Sheets.SheetArea.colHeader);
+        const colCount = setting.cols.length;
+        sheet.setColumnCount(colCount, GC.Spread.Sheets.SheetArea.viewport);
+        sheet.setColumnCount(colCount, GC.Spread.Sheets.SheetArea.colHeader);
         tools.clearData(sheet);
         if (isResort) {
             tools.resort(arr, 'code', false);
@@ -993,12 +1105,13 @@ var tools = {
 
     getsheetDatas: function (sheet, classify, controller) {
         let rowCount = sheet.getRowCount();
+        let colCount = sheet.getColumnCount();
         const colIdx = 1;
         let sheetDatas;
         if (classify === 'total') {
             sheetDatas = [];
             for (let i = 0; i < rowCount; i++) {
-                for (let j = 0; j <= 1; j++) {
+                for (let j = 0; j <= colCount - 1; j++) {
                     let data = sheet.getCell(i, j).value, id = sheet.getTag(i, j);
                     if (data && id) {
                         let unitData = {
@@ -1024,6 +1137,23 @@ var tools = {
                 sheetDatas.datasIdx['rowIdx' + i] = data;
             }
         }
+        else if (classify === 'designs') {
+            sheetDatas = [];
+            for (let i = 0; i < rowCount; i++) {
+                let name = sheet.getCell(i, 1).value(),
+                    unit = sheet.getCell(i, 2).value(),
+                    id = sheet.getTag(i, colIdx);
+                if (id) {
+                    let rowData = {
+                        rowIdx: i,
+                        name,
+                        unit,
+                        id: id
+                    }
+                    sheetDatas.push(rowData);
+                }
+            }
+        }
         else {
             sheetDatas = [];
             for (let i = 0; i < rowCount; i++) {
@@ -1124,6 +1254,90 @@ var tools = {
         };
         return pasteDatas;
     },
+    getDesignByNameUnit: function (arr, name, unit, fromSelected) {
+        if (fromSelected) {
+            return arr.find(item => item.design.data.name == name && item.design.data.unit == unit);
+        } else {
+            return arr.find(item => item.data.name == name && item.data.unit == unit);
+        }
+    },
+    encapDesignsData: function (uncrossedDatas, crossedDatas, controller, totalDesigns) {
+        const UpdateExist = 'updateExist', UpdateNew = 'updateNew', CreateExist = 'createExist', CreateNew = 'createNew';
+        let updateDatas = [];
+        let createDatas = [];
+        let nodeId = controller.tree.selected.getID();
+        debugger;
+        uncrossedDatas.forEach(obj => {
+            let cnDataObj, ceDataObj, designId;
+            const matchedTotalDesign = tools.getDesignByNameUnit(totalDesigns.designsArr, obj.name, obj.unit, false);
+            const matchedDesign = tools.getDesignByNameUnit(controller.tree.selected.designs, obj.name, obj.unit, true);
+            if (matchedTotalDesign && !matchedDesign) {
+                designId = matchedTotalDesign.data.id;
+                ceDataObj = {
+                    name: obj.name,
+                    unit: obj.unit,
+                    billsLibId: billsLibId,
+                    nodeId: nodeId,
+                    designId: designId,
+                    serialNo: obj.serialNo,
+                    type: CreateExist
+                };
+                createDatas.push(ceDataObj);
+            }
+            if (!matchedTotalDesign) {
+                maxDesignsNumber++;
+                cnDataObj = {
+                    //id: maxJobsNumber,
+                    billsLibId: billsLibId,
+                    nodeId: nodeId,
+                    name: obj.name,
+                    unit: obj.unit,
+                    code: maxDesignsNumber,
+                    serialNo: obj.serialNo,
+                    type: CreateNew
+                };
+                createDatas.push(cnDataObj);
+            }
+        });
+        crossedDatas.forEach(cData => {
+            let ueObj, unObj, newDesignId;
+            const matchedTotalDesign = tools.getDesignByNameUnit(totalDesigns.designsArr, cData.name, cData.unit, false);
+            const matchedDesign = tools.getDesignByNameUnit(controller.tree.selected.designs, cData.name, cData.unit, true);
+            if (matchedTotalDesign && !matchedDesign) {
+                newDesignId = matchedTotalDesign.data.id;
+                ueObj = {
+                    name: cData.name,
+                    unit: cData.unit,
+                    billsLibId: billsLibId,
+                    nodeId: nodeId,
+                    newDesignId: newDesignId,
+                    orgDesignId: cData.orgId,
+                    serialNo: cData.serialNo,
+                    type: UpdateExist
+                };
+                updateDatas.push(ueObj);
+            }
+            if (!matchedTotalDesign && !matchedDesign) {
+                maxDesignsNumber++;
+                unObj = {
+                    billsLibId: billsLibId,
+                    nodeId: nodeId,
+                    name: cData.name,
+                    unit: cData.unit,
+                    orgDesignId: cData.orgId,
+                    code: maxDesignsNumber,
+                    serialNo: cData.serialNo,
+                    type: UpdateNew
+                };
+                updateDatas.push(unObj);
+            }
+        });
+        let pasteDatas = {
+            updateDatas: updateDatas,
+            createDatas: createDatas
+        };
+        return pasteDatas;
+    },
     encapItemsData: function (uncrossedDatas, crossedDatas, controller, totalItems) {
         const UpdateExist = 'updateExist', UpdateNew = 'updateNew', CreateExist = 'createExist', CreateNew = 'createNew';
         let updateDatas = [];
@@ -1264,10 +1478,87 @@ var tools = {
                     maxJobsNumber = maxJobsNumber + 1 > rebuildArr[0].code ? maxJobsNumber : rebuildArr[0].code;
                 }
                 rebuildArr.forEach(function (data) {
-                    if (data.type !== 'CreateT' && data.field === 'content') {
+                    if (!data.code) {
+                        maxJobsNumber++;
+                        let code = maxJobsNumber;
+                        data.code = code;
+                    }
+                    /* if (data.type !== 'CreateT' && data.field === 'content') {
                         maxJobsNumber++;
                         let code = maxJobsNumber;
                         data.code = code;
+                    } */
+                });
+            }
+            //rebuildArr.sort(myCompare);
+        }
+        //rebuildArr.sort(myCompare);
+        pasteDatas = {
+            updateDatas: crossedDatas,
+            createDatas: rebuildArr
+        }
+        return pasteDatas;
+    },
+
+    encapTotalDesignsDatas: function (sheet, totalDesigns, uncrossedDatas, crossedDatas) {
+        let pasteDatas;
+        let rebuildArr = [];
+        if (crossedDatas.length > 0) {
+            for (let i = 0; i < crossedDatas.length; i++) {
+                let field = crossedDatas[i].field, data = crossedDatas[i].data;
+                let isRepeat = tools.isDesignRepeat(totalDesigns.designsArr, field, data, 'reference', null, sheet, crossedDatas[i].rowIdx);
+                if (isRepeat) {
+                    crossedDatas.splice(i--, 1);
+                }
+            }
+            for (let i = 0; i < crossedDatas.length; i++) {
+                let field = crossedDatas[i].field, data = crossedDatas[i].data;
+                if (crossedDatas[i].field === 'code' && typeof data !== 'number') {
+                    crossedDatas.splice(i--, 1);
+                }
+
+            }
+        }
+        if (uncrossedDatas.length > 0) {
+            for (let i = 0; i < uncrossedDatas.length; i++) {
+                let field = uncrossedDatas[i].field;
+                let isRepeat = tools.isDesignRepeat(totalDesigns.designsArr, field, uncrossedDatas[i].data, 'reference', null, sheet, uncrossedDatas[i].rowIdx);
+                if (isRepeat) {
+                    uncrossedDatas.splice(i--, 1);
+                }
+            }
+            for (let i = 0; i < uncrossedDatas.length; i++) {
+                let field = uncrossedDatas[i].field;
+                if (uncrossedDatas[i].field === 'code' && typeof uncrossedDatas[i].data !== 'number') {
+                    uncrossedDatas.splice(i--, 1);
+
+                }
+            }
+            rebuildArr = tools.rebuildArr(uncrossedDatas, 'create');
+            function myCompare(a, b) {
+                if (a.rowIdx > b.rowIdx)
+                    return 1;
+                if (a.rowIdx < b.rowIdx)
+                    return -1;
+                return 0;
+            }
+            function myCompareCode(a, b) {
+                if (a.code > b.code)
+                    return -1;
+                if (a.code < b.code)
+                    return 1;
+                return 0;
+            }
+            if (rebuildArr.length > 0) {
+                rebuildArr.sort(myCompareCode);
+                if (rebuildArr[0].code) {
+                    maxDesignsNumber = maxDesignsNumber + 1 > rebuildArr[0].code ? maxDesignsNumber : rebuildArr[0].code;
+                }
+                rebuildArr.forEach(function (data) {
+                    if (!data.code) {
+                        maxDesignsNumber++;
+                        let code = maxDesignsNumber;
+                        data.code = code;
                     }
                 });
             }
@@ -1280,6 +1571,8 @@ var tools = {
         }
         return pasteDatas;
     },
+
+
     encapTotalItemsDatas: function (sheet, totalItems, uncrossedDatas, crossedDatas) {
         let pasteDatas;
         let rebuildArr = [];
@@ -1335,7 +1628,7 @@ var tools = {
                     maxItemsNumber = maxItemsNumber + 1 > rebuildArr[0].code ? maxItemsNumber : rebuildArr[0].code;
                 }
                 rebuildArr.forEach(function (data) {
-                    if (data.type !== 'CreateT' && data.field === 'content') {
+                    if (!data.code) {
                         maxItemsNumber++;
                         let code = maxItemsNumber;
                         data.code = code;
@@ -1427,13 +1720,26 @@ var tools = {
         let conformDatas = [];
         let flag = true;
         for (let i = 0; i < arr.length; i++) {
+            let conformData = {
+                billsLibId: billsLibId,
+                rowIdx: arr[i].rowIdx,
+                type: classify === 'create' ? 'CreateT' : 'UpdateT',
+            };
+            conformData[arr[i].field] = arr[i].data;;
             for (let j = i + 1; j < arr.length; j++) {
                 if (arr[i].rowIdx === arr[j].rowIdx) {
                     flag = false;
                     let field = arr[i].field;
-                    let conformData;
                     if (classify === 'create') {
-                        if (field === 'code') {
+                        conformData[arr[j].field] = arr[j].data;
+                        /* conformData = {
+                            billsLibId: billsLibId,
+                            rowIdx: arr[i].rowIdx,
+                            type: 'CreateT'
+                        }
+                        conformData[arr[i].field] = arr[i].data;
+                        conformData[arr[j].field] = arr[j].data; */
+                        /* if (field === 'code') {
                             conformData = {
                                 billsLibId: billsLibId,
                                 code: arr[i].data,
@@ -1444,16 +1750,26 @@ var tools = {
                         }
                         else {
                             conformData = {
-                                billsLIbId: billsLibId,
+                                billsLibId: billsLibId,
                                 code: arr[j].data,
                                 content: arr[i].data,
                                 rowIdx: arr[i].rowIdx,
                                 type: 'CreateT'
                             }
-                        }
+                        } */
                     }
                     else {
-                        if (field === 'code') {
+                        conformData.orgId = arr[i].orgId;
+                        conformData[arr[j].field] = arr[j].data;
+                        /* conformData = {
+                            billsLibId: billsLibId,
+                            rowIdx: arr[i].rowIdx,
+                            orgId: arr[i].orgId,
+                            type: 'UpdateT'
+                        }
+                        conformData[arr[i].field] = arr[i].data;
+                        conformData[arr[j].field] = arr[j].data; */
+                        /* if (field === 'code') {
                             conformData = {
                                 billsLibId: billsLibId,
                                 code: arr[i].data,
@@ -1472,14 +1788,16 @@ var tools = {
                                 orgId: arr[i].orgId,
                                 type: 'UpdateT'
                             }
-                        }
+                        } */
                     }
-                    conformDatas.push(conformData);
                 }
             }
-
+            const matched = conformDatas.find(item => item.rowIdx === conformData.rowIdx);
+            if (!matched) {
+                conformDatas.push(conformData);
+            }
         }
-        for (let i = 0; i < arr.length; i++) {
+        /* for (let i = 0; i < arr.length; i++) {
             let flag = true;
             for (let j = 0; j < arr.length; j++) {
                 if (arr[i].rowIdx === arr[j].rowIdx && arr[i].field !== arr[j].field) {
@@ -1490,7 +1808,7 @@ var tools = {
 
                 conformDatas.push(arr[i]);
             }
-        }
+        } */
         return conformDatas;
     },
 
@@ -1626,6 +1944,59 @@ let pasteController = {
         sheetDatas = tools.getsheetDatas(sheet);
 
     },
+    frontDesignsRelOperator: function (sheet, setting, controller, totalDesigns, datas) {
+        const UpdateExist = 'updateExist', UpdateNew = 'updateNew', CreateExist = 'createExist', CreateNew = 'createNew';
+        if (datas.length > 0) {
+            for (let i = 0; i < datas.length; i++) {
+                if (datas[i]) {
+                    if (datas[i].type === UpdateExist) {
+                        const design = tools.getDesignByNameUnit(totalDesigns.designsArr, datas[i].name, datas[i].unit, false);
+                        if (design) {
+                            let serialNo = datas[i].serialNo;
+                            let index = tools.getIndex(controller.tree.selected.designs, datas[i].orgDesignId, 'design');
+                            design.count++;
+                            controller.tree.selected.designs.splice(index, 1);
+                            controller.tree.selected.designs.splice(index, 0, { design: design, serialNo: serialNo });
+                        }
+                    }
+                    else if (datas[i].type === UpdateNew) {
+                        let newDesignData, newDesign;
+                        let newDesignId = datas[i].newDesignId, serialNo = datas[i].serialNo;
+                        newDesignData = { id: newDesignId, name: datas[i].name, unit: datas[i].unit, code: datas[i].code };
+                        newDesign = createObj.newDesign(newDesignData);
+                        newDesign.count = 1;
+                        totalDesigns.designs[totalDesigns.prefix + newDesignId] = newDesign;
+                        totalDesigns.designsArr.push(newDesign);
+                        var index = tools.getIndex(controller.tree.selected.designs, datas[i].orgDesignId, 'design');
+                        controller.tree.selected.designs.splice(index, 1);
+                        controller.tree.selected.designs.splice(index, 0, { design: newDesign, serialNo: serialNo });
+                    }
+                    else if (datas[i].type === CreateExist) {
+                        let serialNo = datas[i].serialNo;
+                        const design = tools.getDesignByNameUnit(totalDesigns.designsArr, datas[i].name, datas[i].unit, false);
+                        if (design) {
+                            design.count++;
+                            controller.tree.selected.designs.push({ design: design, serialNo: serialNo });
+                        }
+                    }
+                    else if (datas[i].type === CreateNew) {
+                        let newDesignId = datas[i].newDesignId, serialNo = datas[i].serialNo;
+                        let newDesignData, newDesign;
+                        newDesignData = { id: newDesignId, name: datas[i].name, unit: datas[i].unit, code: datas[i].code };
+                        newDesign = createObj.newDesign(newDesignData);
+                        newDesign.count = 1;
+                        totalDesigns.designs[totalDesigns.prefix + newDesignId] = newDesign;
+                        totalDesigns.designsArr.push(newDesign);
+                        controller.tree.selected.designs.push({ design: newDesign, serialNo: serialNo });
+                    }
+                }
+            }
+        }
+        //resort&reshow
+        tools.orderReshowData(sheet, controller.tree.selected.designs, setting, 'design', true);
+        sheetDatas = tools.getsheetDatas(sheet, 'designs');
+
+    },
     frontItemsRelOperator: function (sheet, setting, controller, totalItems, datas) {
         const UpdateExist = 'updateExist', UpdateNew = 'updateNew', CreateExist = 'createExist', CreateNew = 'createNew';
         if (datas.length > 0) {
@@ -1721,6 +2092,45 @@ let pasteController = {
         tools.reshowData(sheet, totalJobs.jobsArr, totalJobsSetting, true);
         sheetJobsDatas = tools.getsheetDatas(sheet, 'total');
     },
+    pasteDesignsFront: function (sheet, totalDesigns, datas) {
+        const Update = 'Update', CreateT = 'CreateT';
+        if (datas.length > 0) {
+            for (let i = 0; i < datas.length; i++) {
+                let newDesignData, newDesign;
+                if (datas[i]) {
+                    if (datas[i].type === Update) {
+                        totalDesigns.designsArr.forEach(design => {
+                            if (design.data.id === datas[i].orgId) {
+                                design.data[datas[i].field] = datas[i].data;
+                            }
+                        });
+                    }
+                    else if (datas[i].type === CreateT) {
+                        //maxJobsNumber++;
+                        // maxJobsNumber = maxJobsNumber >= datas[i].code ? maxJobsNumber : datas[i].code;
+                        newDesignData = { id: datas[i].newJobId, name: datas[i].name, code: datas[i].code, unit: datas[i].unit };
+                        newDesign = createObj.newDesign(newDesignData);
+                        totalDesigns.designsArr.push(newDesign);
+                    }
+                    else if (datas[i].type !== CreateT && datas[i].field === 'name') {
+                        newDesignData = { id: datas[i].newJobId, name: datas[i].data, code: datas[i].code };
+                        newDesign = createObj.newDesign(newDesignData);
+                        totalDesigns.designsArr.push(newDesign);
+                    }
+                    else if (datas[i].type !== 'CreateT' && datas[i].field === 'code') {
+                        //  maxJobsNumber++;
+                        // maxJobsNumber = maxJobsNumber >= datas[i].data  ? maxJobsNumber : datas[i].data;
+                        newDesignData = { id: datas[i].newJobId, name: '', code: datas[i].data };
+                        newDesign = createObj.newDesign(newDesignData);
+                        totalDesigns.designsArr.push(newDesign);
+                    }
+                }
+            }
+        }
+        setSheet.setMaxRowCount(sheet, totalDesigns.designsArr);
+        tools.reshowData(sheet, totalDesigns.designsArr, totalDesignsSetting, true);
+        sheetJobsDatas = tools.getsheetDatas(sheet, 'total');
+    },
     pasteItemsFront: function (sheet, totalItems, datas) {
         const Update = 'Update', CreateT = 'CreateT';
         if (datas.length > 0) {
@@ -2042,6 +2452,255 @@ var jobsController = {
 
 };
 
+var designsController = {
+    currentEditData: null,
+    totalDesigns: null,
+    onEditStart: function (sender, args) {
+        let me = designsController;
+        me.currentEditData = args.sheet.getValue(args.row, args.col);
+    },
+    onEditEnded: function (sender, args) {
+        let me = designsController;
+        let sheet = args.sheet;
+        let controller = dbController.controller;
+        let totalDesigns = me.totalDesigns;
+        let setting = designsSetting;
+        var field, newData = args.editingText, id = sheet.getTag(args.row, args.col);
+        setting.cols.forEach(function (col, idx) {
+            if (args.col === idx) {
+                field = col.data.field;
+            }
+        });
+        if (controller.tree.selected && newData != me.currentEditData) {
+            var isExist = tools.isDesignExist(totalDesigns.designsArr, field, newData, args.sheet, args.row);
+            var isRepeat = tools.isDesignRepeat(controller.tree.selected.designs, field, newData, 'reference', 'design', args.sheet, args.row);
+            //create
+            if (!id && newData && !isRepeat) {
+                if (isExist) {
+                    designsController.createExist(sheet, controller, totalDesigns, field, newData, args, setting);
+                }
+                else {
+                    designsController.createNew(sheet, controller, totalDesigns, field, newData, args, setting);
+                }
+            }
+            //update
+            else if (id && !isRepeat) {
+                designsController.update(sheet, controller, totalDesigns, field, newData, id, isExist, args, setting);
+            }
+            //处理重复
+            if (isRepeat) {
+                tools.alertOpr(args, sheet, '该设计细目已存在!', controller.tree.selected.designs, 'design');
+            }
+        }
+        else {
+            sheet.getCell(args.row, args.col).value(me.currentEditData ? me.currentEditData : '');
+        }
+    },
+    editData: function (sheet) {
+        let me = designsController;
+        sheet.bind(GC.Spread.Sheets.Events.EditStarting, me.onEditStart);
+        sheet.bind(GC.Spread.Sheets.Events.EditEnded, me.onEditEnded);
+    },
+
+
+    createNew: function (sheet, controller, totalDesigns, field, newData, args, setting) {
+        if (field === 'name' || field === 'unit') {
+            maxDesignsNumber++;
+            //update--
+            let serialNo = tools.getSerialNo(controller.tree.selected.designs);
+            //--
+            designsAjax.edCreateDesign(userAccount, billsLibId, controller.tree.selected.getID(), field, newData, maxDesignsNumber, serialNo, function (newID) {
+                var newDesignData, newDesign;
+                newDesignData = { id: newID, [field]: newData, code: maxDesignsNumber };
+                newDesign = createObj.newDesign(newDesignData);
+                newDesign.count = 1;
+                totalDesigns.designs[totalDesigns.prefix + newID] = newDesign;
+                totalDesigns.designsArr.push(newDesign);
+                controller.tree.selected.designs.push({ design: newDesign, serialNo: serialNo });//update--
+                tools.orderReshowData(sheet, controller.tree.selected.designs, setting, 'design', true)//update--
+            });
+        }
+        else {
+            tools.alertOpr(args, sheet, '该编号不存在,请重新输入!', controller.tree.selected.designs, 'design');
+        }
+    },
+
+    createExist: function (sheet, controller, totalDesigns, field, newData, args, setting) {
+        const name = field === 'name' ? newData : sheet.getValue(args.row, 1);
+        const unit = field === 'unit' ? newData : sheet.getValue(args.row, 2);
+        if (field === 'code') {
+            matched = totalDesigns.designsArr.find(item => item.data.code == newData);
+        } else {
+            matched = totalDesigns.designsArr.find(item => item.data.name == name && item.data.unit == unit);
+        }
+        if (matched) {
+            let serialNo = tools.getSerialNo(controller.tree.selected.designs);//update--
+            billsAjax.updateBills(userAccount, billsLibId, controller.tree.selected.getID(), 'designs', { id: matched.data.id, serialNo: serialNo });//update--
+            matched.count++;
+            controller.tree.selected.designs.push({ design: matched, serialNo: serialNo });//update--
+            // tools.reshowData(sheet, controllers.tree.selected.designs, setting, true);//update--
+            tools.orderReshowData(sheet, controller.tree.selected.designs, setting, 'design', true);
+        }
+
+
+        /* for (const design of totalDesigns.designsArr) {
+            if ((field === 'name' && newData === design.data.name) || (field === 'unit' && newData === design.data.unit)) {
+                let serialNo = tools.getSerialNo(controller.tree.selected.designs);//update--
+                //billsAjax.updateBills(billsLibId, controllers.tree.selected.getID(), 'designs', job.data.id);//update--
+                billsAjax.updateBills(userAccount, billsLibId, controller.tree.selected.getID(), 'designs', { id: design.data.id, serialNo: serialNo });//update--
+                design.count++;
+                // controllers.tree.selected.designs.push(job);//update--
+                controller.tree.selected.designs.push({ design: design, serialNo: serialNo });//update--
+                //tools.reshowData(sheet, controllers.tree.selected.designs, setting, true);//update--
+                tools.orderReshowData(sheet, controller.tree.selected.designs, setting, 'design', true);
+                break;
+            }
+            else if (field == 'code' && newData == design.data.code) {
+                let serialNo = tools.getSerialNo(controller.tree.selected.designs);//update--
+                billsAjax.updateBills(userAccount, billsLibId, controller.tree.selected.getID(), 'designs', { id: design.data.id, serialNo: serialNo });//update--
+                design.count++;
+                controller.tree.selected.designs.push({ design: design, serialNo: serialNo });//update--
+                // tools.reshowData(sheet, controllers.tree.selected.designs, setting, true);//update--
+                tools.orderReshowData(sheet, controller.tree.selected.designs, setting, 'design', true);
+                break;
+            }
+        } */
+    },
+    update: function (sheet, controller, totalDesigns, field, newData, id, isExist, args, setting) {
+        const name = field === 'name' ? newData : sheet.getValue(args.row, 1);
+        const unit = field === 'unit' ? newData : sheet.getValue(args.row, 2);
+        if (isExist) {
+            let matched
+            if (field === 'code') {
+                matched = totalDesigns.designsArr.find(item => item.data.code == newData);
+            } else {
+                matched = totalDesigns.designsArr.find(item => item.data.name == name && item.data.unit == unit);
+            }
+            if (matched) {
+                let serialNo = tools.getObj(controller.tree.selected.designs, id, 'design').serialNo;//update--add
+                let index = tools.getIndex(controller.tree.selected.designs, id, 'design');//update-- getIndex
+                matched.count++;
+                controller.tree.selected.designs.splice(index, 1);
+                controller.tree.selected.designs.splice(index, 0, { design: matched, serialNo: serialNo });//update--
+                billsAjax.updateBillsArr(userAccount, billsLibId, controller.tree.selected.getID(), id, matched.data.id, 'update', 'designs');
+                tools.orderReshowData(sheet, controller.tree.selected.designs, setting, 'design', true);
+            }
+            /* totalDesigns.designsArr.forEach(function (design) {
+                if (field == 'code' && design.data[field] == newData) {
+                    let serialNo = tools.getObj(controller.tree.selected.designs, id, 'design').serialNo;//update--add
+                    let index = tools.getIndex(controller.tree.selected.designs, id, 'design');//update-- getIndex
+                    design.count++;
+                    controller.tree.selected.designs.splice(index, 1);
+                    controller.tree.selected.designs.splice(index, 0, { design: design, serialNo: serialNo });//update--
+                    billsAjax.updateBillsArr(userAccount, billsLibId, controller.tree.selected.getID(), id, design.data.id, 'update', 'designs');
+                    tools.orderReshowData(sheet, controller.tree.selected.designs, setting, 'design', true);
+                }
+                if (field === 'name' && design.data[field] === newData) {
+                    let serialNo = tools.getObj(controller.tree.selected.designs, id, 'design').serialNo;//update--add
+                    let index = tools.getIndex(controller.tree.selected.designs, id, 'design');
+                    design.count++;
+                    controller.tree.selected.designs.splice(index, 1);
+                    controller.tree.selected.designs.splice(index, 0, { design: design, serialNo: serialNo });//update--
+                    billsAjax.updateBillsArr(userAccount, billsLibId, controller.tree.selected.getID(), id, design.data.id, 'update', 'designs');
+                    // tools.reshowData(sheet, controllers.tree.selected.designs, setting, true);//update--
+                    tools.orderReshowData(sheet, controller.tree.selected.designs, setting, 'design', true);
+                }
+            }); */
+        }
+        else {
+            if (field === 'name' || field === 'unit') {
+                maxDesignsNumber++;
+                //let serialNo = tools.getSerialNo(controllers.tree.selected.designs);//update--
+                let serialNo = tools.getObj(controller.tree.selected.designs, id, 'design').serialNo;
+                designsAjax.edUpdateDesign(userAccount, billsLibId, controller.tree.selected.getID(), name, unit, maxDesignsNumber, id, function (newDesignId) {//update--
+                    var newDesignData, newDesign;
+                    newDesignData = { id: newDesignId, name, unit, code: maxDesignsNumber };
+                    newDesign = createObj.newDesign(newDesignData);
+                    newDesign.count = 1;
+                    totalDesigns.designs[totalDesigns.prefix + newDesignId] = newDesign;
+                    totalDesigns.designsArr.push(newDesign);
+                    var index = tools.getIndex(controller.tree.selected.designs, id, 'design');
+                    controller.tree.selected.designs.splice(index, 1);
+                    controller.tree.selected.designs.splice(index, 0, { design: newDesign, serialNo: serialNo });//update--
+                    //tools.reshowData(sheet, controllers.tree.selected.designs, setting, true);//update--
+                    tools.orderReshowData(sheet, controller.tree.selected.designs, setting, 'design', true);//update--
+                });
+            }
+            else {
+                tools.alertOpr(args, sheet, '该编号不存在,请重新输入!', controller.tree.selected.designs, 'design');
+            }
+        }
+    },
+    upMove: function (controller, sheet) {
+        let updateSelArr = [];
+        $('#upMove').attr('doing', 'true');
+        tools.btnClose($('#upMove'));
+        let args = controller.tree.selected.args,
+            thisDesign = controller.tree.selected.designs[args.row],
+            preDesign = controller.tree.selected.designs[args.row - 1],
+            tempSerialNo;
+        //switch serialNo
+        tempSerialNo = thisDesign.serialNo;
+        thisDesign.serialNo = preDesign.serialNo;
+        preDesign.serialNo = tempSerialNo;
+        updateSelArr.push({ id: thisDesign.design.data.id, serialNo: thisDesign.serialNo });
+        updateSelArr.push({ id: preDesign.design.data.id, serialNo: preDesign.serialNo });
+        billsAjax.updateSerialNo(billsLibId, controller.tree.selected.getID(), updateSelArr, 'designs', function () {
+            tools.orderReshowData(sheet, controller.tree.selected.designs, designsSetting, 'design', true);
+            sheet.setActiveCell(args.row - 1, args.col);
+            controller.tree.selected.args.row = args.row - 1;
+            $('#upMove').attr('doing', 'false');
+            if (tools.canUpMove(controller.tree.selected.designs[controller.tree.selected.args.row], controller.tree.selected.designs)) {
+                $('#upMove').attr('canMove', 'true');
+                tools.btnAction($('#upMove'));
+            }
+            else {
+                $('#upMove').attr('canMove', 'false');
+            }
+            if (tools.canDownMove(controller.tree.selected.designs[controller.tree.selected.args.row], controller.tree.selected.designs)) {
+                $('#downMove').attr('canMove', true);
+                tools.btnAction($('#downMove'));
+            }
+            else {
+                $('#downMove').attr('canMove', 'false');
+                tools.btnClose($('#downMove'));
+            }
+        });
+    },
+    downMove: function (controller, sheet) {
+        let updateSelArr = [];
+        $('#downMove').attr('doing', 'true');
+        tools.btnClose($('#downMove'));
+        let tempSerialNo = controller.tree.selected.designs[controller.tree.selected.args.row].serialNo;
+        controller.tree.selected.designs[controller.tree.selected.args.row].serialNo = controller.tree.selected.designs[controller.tree.selected.args.row + 1].serialNo;
+        controller.tree.selected.designs[controller.tree.selected.args.row + 1].serialNo = tempSerialNo;
+        updateSelArr.push({ id: controller.tree.selected.designs[controller.tree.selected.args.row].design.data.id, serialNo: controller.tree.selected.designs[controller.tree.selected.args.row].serialNo });
+        updateSelArr.push({ id: controller.tree.selected.designs[controller.tree.selected.args.row + 1].design.data.id, serialNo: controller.tree.selected.designs[controller.tree.selected.args.row + 1].serialNo });
+        billsAjax.updateSerialNo(billsLibId, controller.tree.selected.getID(), updateSelArr, 'designs', function () {
+            tools.orderReshowData(sheet, controller.tree.selected.designs, jobsSetting, 'design', true);
+            sheet.setActiveCell(controller.tree.selected.args.row + 1, controller.tree.selected.args.col);
+            controller.tree.selected.args.row = controller.tree.selected.args.row + 1;
+            $('#downMove').attr('doing', 'false');
+            if (tools.canDownMove(controller.tree.selected.designs[controller.tree.selected.args.row], controller.tree.selected.designs)) {
+                $('#downMove').attr('canMove', 'true');
+                tools.btnAction($('#downMove'));
+            }
+            else {
+                $('#downMove').attr('canMove', 'false');
+            }
+            if (tools.canUpMove(controller.tree.selected.designs[controller.tree.selected.args.row], controller.tree.selected.designs)) {
+                $('#upMove').attr('canMove', 'true');
+                tools.btnAction($('#upMove'));
+            }
+            else {
+                $('#upMove').attr('canMove', 'false');
+                tools.btnClose($('#upMove'));
+            }
+        });
+    }
+
+};
+
 var itemsController = {
     currentEditData: null,
     totalItems: null,
@@ -2480,6 +3139,103 @@ var totalJobsController = {
     }
 };
 
+var totalDesignsController = {
+    currentEditData: null,
+    totalDesigns: null,
+    onEditStart: function (sender, args) {
+        let me = totalDesignsController;
+        me.currentEditData = args.sheet.getValue(args.row, args.col);
+    },
+    onEditEnded: function (sender, args) {
+        debugger;
+        let me = totalDesignsController;
+        let totalDesigns = me.totalDesigns;
+        let sheet = args.sheet;
+        let setting = totalDesignsSetting;
+        var newData = args.editingText, tagId = sheet.getTag(args.row, args.col), field, isRepeat;
+        setting.cols.forEach(function (col, colIdx) {
+            if (args.col === colIdx) {
+                field = col.data.field;
+            }
+        });
+        if (newData != me.currentEditData) {
+            isRepeat = tools.isDesignRepeat(totalDesigns.designsArr, field, newData, 'reference', null, args.sheet, args.row);
+            if (!tagId && !isRepeat && newData) {//create
+                totalDesignsController.createDesign(sheet, totalDesigns, field, newData, args);
+            }
+            else if (tagId && !isRepeat) {//update
+                totalDesignsController.updateDesign(totalDesigns, tagId, field, newData, args);
+            }
+            if (isRepeat) {
+                tools.alertTotalOpr(args, '该内容已存在!', totalDesigns.designsArr);
+            }
+        }
+        else {
+            sheet.getCell(args.row, args.col).value(me.currentEditData ? me.currentEditData : '');
+        }
+    },
+    editData: function (sheet) {
+        let me = totalDesignsController;
+        sheet.bind(GC.Spread.Sheets.Events.EditStarting, me.onEditStart);
+        sheet.bind(GC.Spread.Sheets.Events.EditEnded, me.onEditEnded);
+    },
+
+    createDesign: function (sheet, totalDesigns, field, newData, args) {
+        if (field === 'name' || field === 'unit') {
+            maxDesignsNumber++;
+            let code = maxDesignsNumber;
+            designsAjax.createDesignContent(userAccount, billsLibId, field, newData, code, function (newDesignId) {
+                let newDesignData, newDesign;
+                newDesignData = { id: newDesignId, [field]: newData, code: code };
+                newDesign = createObj.newDesign(newDesignData);
+                totalDesigns.designsArr.push(newDesign);
+                //tools.reSetCell(sheet, args.row, 0, code, newDesignId);
+                tools.reshowData(sheet, totalDesigns.designsArr, totalDesignsSetting, true);
+                setSheet.setMaxRowCount(sheet, totalDesigns.designsArr);
+                sheetDesignDatas = tools.getsheetDatas(sheet, 'total');
+            });
+        }
+        else {
+            let parseNum = parseInt(newData);
+            //if(typeof newData === 'number'){
+            if (!isNaN(parseNum)) {
+                maxDesignsNumber = maxDesignsNumber >= newData ? maxDesignsNumber : newData;
+                designsAjax.createDesignContent(userAccount, billsLibId, 'code', newData, newData, function (newDesignId) {
+                    let newDesignData, newDesign;
+                    newDesignData = { id: newDesignId, name: '', unit: '', code: newData };
+                    newDesign = createObj.newDesign(newDesignData);
+                    totalDesigns.designsArr.push(newDesign);
+                    //tools.reSetCell(sheet, args.row, 0, null, newDesignId);
+                    tools.reshowData(sheet, totalDesigns.designsArr, totalDesignsSetting, true);
+                    setSheet.setMaxRowCount(sheet, totalDesigns.designsArr);
+                    sheetDesignDatas = tools.getsheetDatas(sheet, 'total');
+                });
+            }
+            else {
+                //编号只能为数字!
+                tools.alertTotalOpr(args, '编号只能为数字,请重新输入!', totalDesigns.designsArr);
+                // sheet.getCell(args.row, args.col).value("");
+            }
+        }
+    },
+
+    updateDesign: function (totalDesigns, id, field, newData, args) {
+        // if(field === 'code' && typeof newData !== 'number'){
+        if (field === 'code' && isNaN(parseInt(newData))) {
+            tools.alertTotalOpr(args, '编号只能为数字,请重新输入!', totalDesigns.designsArr);
+        }
+        else {
+            totalDesigns.designsArr.forEach(function (job) {
+                if (job.data.id === id) {
+                    job.data[field] = newData;
+                }
+            });
+            tools.reshowData(args.sheet, totalDesigns.designsArr, totalDesignsSetting, true);
+            designsAjax.updateDesignContent(userAccount, billsLibId, id, field, newData);
+        }
+    }
+};
+
 var totalItemsController = {
     currentEditData: null,
     totalItems: null,

+ 0 - 0
web/maintain/bills_lib/scripts/degisn.js


+ 137 - 83
web/maintain/bills_lib/scripts/set_sheets.js

@@ -2,7 +2,7 @@
  * Created by vian on 2017/3/16.
  */
 var setSheet = {
-    initSheet: function(spread, setting, isExtendPaste){
+    initSheet: function (spread, setting, isExtendPaste) {
         var spreadNS = GC.Spread.Sheets, sheet = spread.getActiveSheet();
         sheet.suspendPaint();
         //spread.options.showHorizontalScrollbar = false;
@@ -10,27 +10,27 @@ var setSheet = {
         spread.options.tabStripVisible = false;
         spread.options.scrollbarMaxAlign = true;
         spread.options.allowCopyPasteExcelStyle = false;
-        spread.options.allowExtendPasteRange = isExtendPaste? true : false;
+        spread.options.allowExtendPasteRange = isExtendPaste ? true : false;
         spread.options.allowUserDragDrop = false;
         spread.options.allowContextMenu = false;
         spread.getActiveSheet().options.allowCellOverflow = false;
         spread.getActiveSheet().options.clipBoardOptions = GC.Spread.Sheets.ClipboardPasteOptions.values;
         sheet.showRowOutline(false);
-       // sheet.defaults.rowHeight = 30;
-        setting.cols.forEach(function(col, colIdx){
-            sheet.getRange(-1,colIdx,-1,1, GC.Spread.Sheets.SheetArea.viewport).hAlign(GC.Spread.Sheets.HorizontalAlign.left);
-            sheet.getRange(-1,colIdx,-1,1, GC.Spread.Sheets.SheetArea.viewport).vAlign(GC.Spread.Sheets.VerticalAlign.center);
-            sheet.getRange(-1,colIdx,-1,1, GC.Spread.Sheets.SheetArea.viewport).textIndent(0.5);
+        // sheet.defaults.rowHeight = 30;
+        setting.cols.forEach(function (col, colIdx) {
+            sheet.getRange(-1, colIdx, -1, 1, GC.Spread.Sheets.SheetArea.viewport).hAlign(GC.Spread.Sheets.HorizontalAlign.left);
+            sheet.getRange(-1, colIdx, -1, 1, GC.Spread.Sheets.SheetArea.viewport).vAlign(GC.Spread.Sheets.VerticalAlign.center);
+            sheet.getRange(-1, colIdx, -1, 1, GC.Spread.Sheets.SheetArea.viewport).textIndent(0.5);
         });
         sheet.resumePaint();
     },
-    setEditCol: function(sheet, colIdx){
+    setEditCol: function (sheet, colIdx) {
         var style = new GC.Spread.Sheets.Style();
         style.locked = false;
         sheet.setStyle(-1, colIdx, style);
         sheet.options.isProtected = true;
     },
-    setMaxRowCount: function(sheet, arr){
+    setMaxRowCount: function (sheet, arr) {
         let arrL = arr.length;
         let rowCount = arrL + 10;
         /*if(arrL <10){
@@ -41,32 +41,32 @@ var setSheet = {
         }*/
         sheet.setRowCount(rowCount, GC.Spread.Sheets.SheetArea.viewport);
     },
-    formatter: function(sheet){
+    formatter: function (sheet) {
         sheet.setFormatter(-1, 0, "@", GC.Spread.Sheets.SheetArea.viewport);
     }
 }
 
-function setScrollBar(spread, sheet, initRow){
+function setScrollBar(spread, sheet, initRow) {
     var events = GC.Spread.Sheets.Events;
-    sheet.bind(events.EnterCell, function(e, data){
+    sheet.bind(events.EnterCell, function (e, data) {
         var rowCount = sheet.getRowCount();
         //��ǰ�������ڳ�ʼ����
-        if(rowCount >initRow){
+        if (rowCount > initRow) {
             spread.options.showVerticalScrollbar = true;
         }
-        else{
+        else {
             spread.options.showVerticalScrollbar = false;
         }
     });
 }
 
 var myKey = {
-    enterKey: function(spread){
+    enterKey: function (spread) {
         var sheet = spread.getActiveSheet();
-        spread.commandManager().register("myEnter", function(){
+        spread.commandManager().register("myEnter", function () {
             var idxRow = sheet.getActiveRowIndex();
             var rowCount = sheet.getRowCount();
-            if(idxRow+1 == rowCount){
+            if (idxRow + 1 == rowCount) {
                 sheet.addRows(rowCount, 1);
                 sheet.getRange(rowCount, -1, 1, -1).vAlign(GC.Spread.Sheets.VerticalAlign.center);
                 sheet.getRange(rowCount, -1, 1, -1).hAlign(GC.Spread.Sheets.HorizontalAlign.left);
@@ -77,12 +77,12 @@ var myKey = {
         spread.commandManager().setShortcutKey("myEnter", GC.Spread.Commands.Key.enter, false, false, false, false);
     },
 
-    downKey: function(spread){
+    downKey: function (spread) {
         var sheet = spread.getActiveSheet();
-        spread.commandManager().register("myDown", function(){
+        spread.commandManager().register("myDown", function () {
             var idxRow = sheet.getActiveRowIndex();
             var rowCount = sheet.getRowCount();
-            if(idxRow+1 == rowCount){
+            if (idxRow + 1 == rowCount) {
                 sheet.suspendPaint();
                 sheet.addRows(rowCount, 1);
                 sheet.getRange(rowCount, -1, 1, -1).vAlign(GC.Spread.Sheets.VerticalAlign.center);
@@ -96,84 +96,87 @@ var myKey = {
     },
 
 
-    delKey: function(spread, controller, totalObj, setting, classify){
-        if(classify === 'jobs' || classify === 'items'){
+    delKey: function (spread, controller, totalObj, setting, classify) {
+        if (classify === 'jobs' || classify === 'items' || classify === 'designs') {
             bindRefDel(spread, controller, totalObj, setting, classify);
         }
-        else if(classify === 'totalJobs'){
+        else if (classify === 'totalJobs') {
             bindTotalJobDel(spread, controller, totalObj, setting);
         }
-        else if(classify === 'totalItems'){
+        else if (classify === 'totalDesigns') {
+            bindTotalDesignDel(spread, controller, totalObj, setting);
+        }
+        else if (classify === 'totalItems') {
             bindTotalItemDel(spread, spreadVal.getActiveSheet(), controller, totalObj, setting);
         }
-        else if(classify === 'itemValue'){
+        else if (classify === 'itemValue') {
             bindValDel(spread, totalObj, setting);
         }
-        else if(!classify){
+        else if (!classify) {
             rejectDel(spread);
         }
 
-        function bindRefDel(spread, controller, totalObj, setting, classify){
+        function bindRefDel(spread, controller, totalObj, setting, classify) {
             var sheet = spread.getActiveSheet();
-            spread.commandManager().register('myDelete', function(){
+            spread.commandManager().register('myDelete', function () {
                 spread.suspendEvent();
                 var ids = tools.delIds(sheet);
-                let classifyStr = classify === 'jobs' ? 'job' : 'item';
+                let classifyStr = classify.replace(/s$/, '')/*   === 'jobs' ? 'job' : 'item' */;
                 tools.deleteELes(controller.tree.selected[classify], ids, classifyStr);
-                    //deleteFrontData
-                    //tools.reshowData(sheet, controllers.tree.selected[classify], setting, true);
-                    //deleteDB
-                    billsAjax.updateBillsArr(userAccount, billsLibId, controller.tree.selected.getID(), ids, null, 'delete', classify, function(){
-                        tools.orderReshowData(sheet, controller.tree.selected[classify], setting, classifyStr, true);
-                    });
-                    /*if(result.length > 0){
-                        if(classify === 'jobs'){
-                            /!*result.forEach(function(id){
-                                controllers.tree.selected.jobs.forEach(function(obj){
-                                    if(id === obj.job.data.id){
-                                        controllers.tree.selected.jobs.splice(obj);
-                                    }
-                                });
-                                /!*if(totalObj.findJob(id)){
-                                    totalObj.jobsArr.splice(totalObj.jobsArr.indexOf(totalObj.findJob(id)), 1);
-                                    delete  totalObj.jobs[totalObj.prefix + id];
-                                }*!/
-                            });*!/
-                            //jobsAjax.deleteJobContent(billsLibId, result);
-                            tools.orderReshowData(sheet, controllers.tree.selected.jobs, setting, 'job', true);
-                        }
-                        else {
-                            result.forEach(function(id){
-                                if(totalObj.findItem(id)){
-                                    totalObj.itemsArr.splice(totalObj.itemsArr.indexOf(totalObj.findItem(id)), 1);
-                                    delete totalObj.items[totalObj.prefix + id];
+                //deleteFrontData
+                //tools.reshowData(sheet, controllers.tree.selected[classify], setting, true);
+                //deleteDB
+                billsAjax.updateBillsArr(userAccount, billsLibId, controller.tree.selected.getID(), ids, null, 'delete', classify, function () {
+                    tools.orderReshowData(sheet, controller.tree.selected[classify], setting, classifyStr, true);
+                });
+                /*if(result.length > 0){
+                    if(classify === 'jobs'){
+                        /!*result.forEach(function(id){
+                            controllers.tree.selected.jobs.forEach(function(obj){
+                                if(id === obj.job.data.id){
+                                    controllers.tree.selected.jobs.splice(obj);
                                 }
                             });
-                            itemsAjax.deleteItemCharacter(result);
-                        }
-                    }*/
+                            /!*if(totalObj.findJob(id)){
+                                totalObj.jobsArr.splice(totalObj.jobsArr.indexOf(totalObj.findJob(id)), 1);
+                                delete  totalObj.jobs[totalObj.prefix + id];
+                            }*!/
+                        });*!/
+                        //jobsAjax.deleteJobContent(billsLibId, result);
+                        tools.orderReshowData(sheet, controllers.tree.selected.jobs, setting, 'job', true);
+                    }
+                    else {
+                        result.forEach(function(id){
+                            if(totalObj.findItem(id)){
+                                totalObj.itemsArr.splice(totalObj.itemsArr.indexOf(totalObj.findItem(id)), 1);
+                                delete totalObj.items[totalObj.prefix + id];
+                            }
+                        });
+                        itemsAjax.deleteItemCharacter(result);
+                    }
+                }*/
                 spread.resumeEvent();
             });
             spread.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false);
             spread.commandManager().setShortcutKey('myDelete', GC.Spread.Commands.Key.del, false, false, false, false);
         }
 
-        function rejectDel(spread){
+        function rejectDel(spread) {
             var sheet = spread.getActiveSheet();
             spread.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false);
         }
 
-        function bindTotalJobDel(spread, billsIds, totalJobs, setting){
+        function bindTotalJobDel(spread, billsIds, totalJobs, setting) {
             var sheet = spread.getActiveSheet();
-            spread.commandManager().register('myJobDelete', function(){
+            spread.commandManager().register('myJobDelete', function () {
                 let ids = tools.delIds(sheet);
-                if(ids.length === 0){
+                if (ids.length === 0) {
                     return;
                 }
                 $.bootstrapLoading.start();
-                CommonAjax.post('/stdBillsEditor/isUsed', {field: 'jobs', delIds: ids}, function (rstData) {
+                CommonAjax.post('/stdBillsEditor/isUsed', { field: 'jobs', delIds: ids }, function (rstData) {
                     //被引用了
-                    if(rstData.isUsed){
+                    if (rstData.isUsed) {
                         $('#delText').text('当前工作内容已被引用,不允许删除。');
                         $('#delConfirm').unbind('click');
                         $('#delConfirm').bind('click', function () {
@@ -186,14 +189,14 @@ var myKey = {
                         $('#delConfirm').unbind('click');
                         $('#delConfirm').bind('click', function () {
                             spread.suspendEvent();
-                            ids.forEach(function(id){
+                            ids.forEach(function (id) {
                                 var job = totalJobs.findJob(id);
                                 totalJobs.jobsArr.splice(totalJobs.jobsArr.indexOf(job), 1);
                             });
-                            function myCompareCode(a, b){
+                            function myCompareCode(a, b) {
                                 let valA = a.data.code,
                                     valB = b.data.code;
-                                return valB- valA;
+                                return valB - valA;
                             }
                             totalJobs.jobsArr.sort(myCompareCode);
                             maxJobsNumber = totalJobs.jobsArr.length > 0 ? totalJobs.jobsArr[0].data.code : 0;
@@ -214,7 +217,58 @@ var myKey = {
             spread.commandManager().setShortcutKey('myJobDelete', GC.Spread.Commands.Key.del, false, false, false, false)
         }
 
-        function bindTotalItemDel(spread, valSheet, billsIds, totalItems, setting){
+        function bindTotalDesignDel(spread, billsIds, totalDesigns, setting) {
+            var sheet = spread.getActiveSheet();
+            spread.commandManager().register('myDesignDelete', function () {
+                let ids = tools.delIds(sheet);
+                if (ids.length === 0) {
+                    return;
+                }
+                $.bootstrapLoading.start();
+                CommonAjax.post('/stdBillsEditor/isUsed', { field: 'designs', delIds: ids }, function (rstData) {
+                    //被引用了
+                    if (rstData.isUsed) {
+                        $('#delText').text('当前设计细目已被引用,不允许删除。');
+                        $('#delConfirm').unbind('click');
+                        $('#delConfirm').bind('click', function () {
+                            $('#delAlert').modal('hide');
+                            spread.focus(true);
+                        });
+                    }
+                    else {
+                        $('#delText').text('是否删除当前行?');
+                        $('#delConfirm').unbind('click');
+                        $('#delConfirm').bind('click', function () {
+                            spread.suspendEvent();
+                            ids.forEach(function (id) {
+                                var design = totalDesigns.findDesign(id);
+                                totalDesigns.designsArr.splice(totalDesigns.designsArr.indexOf(design), 1);
+                            });
+                            function myCompareCode(a, b) {
+                                let valA = a.data.code,
+                                    valB = b.data.code;
+                                return valB - valA;
+                            }
+                            totalDesigns.designsArr.sort(myCompareCode);
+                            maxDesignsNumber = totalDesigns.designsArr.length > 0 ? totalDesigns.designsArr[0].data.code : 0;
+                            tools.reshowData(sheet, totalDesigns.designsArr, setting, true);
+                            billsAjax.removeTotal(userAccount, billsLibId, billsIds, ids, 'designs');
+                            spread.resumeEvent();
+                            $('#delAlert').modal('hide');
+                            spread.focus(true);
+                        });
+                    }
+                    $.bootstrapLoading.end();
+                }, function () {
+                    $.bootstrapLoading.end();
+                });
+                $('#delAlert').modal('show');
+            });
+            spread.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false);
+            spread.commandManager().setShortcutKey('myDesignDelete', GC.Spread.Commands.Key.del, false, false, false, false)
+        }
+
+        function bindTotalItemDel(spread, valSheet, billsIds, totalItems, setting) {
             var sheet = spread.getActiveSheet();
             /*$('#delConfirm').click(function () {
                 spread.suspendEvent();
@@ -245,15 +299,15 @@ var myKey = {
                 spread.resumeEvent();
                 $('#delAlert').modal('hide');
             });*/
-            spread.commandManager().register('myItemDelete', function(){
+            spread.commandManager().register('myItemDelete', function () {
                 let ids = tools.delIds(sheet);
-                if(ids.length === 0){
+                if (ids.length === 0) {
                     return;
                 }
                 $.bootstrapLoading.start();
-                CommonAjax.post('/stdBillsEditor/isUsed', {field: 'items', delIds: ids}, function (rstData) {
+                CommonAjax.post('/stdBillsEditor/isUsed', { field: 'items', delIds: ids }, function (rstData) {
                     //被引用了
-                    if(rstData.isUsed){
+                    if (rstData.isUsed) {
                         $('#delText').text('当前项目特征已被引用,不允许删除。');
                         $('#delConfirm').unbind('click');
                         $('#delConfirm').bind('click', function () {
@@ -266,21 +320,21 @@ var myKey = {
                         $('#delConfirm').unbind('click');
                         $('#delConfirm').bind('click', function () {
                             spread.suspendEvent();
-                            ids.forEach(function(id){
+                            ids.forEach(function (id) {
                                 var item = totalItems.findItem(id);
                                 totalItems.itemsArr.splice(totalItems.itemsArr.indexOf(item), 1);
                             });
-                            function myCompareCode(a, b){
+                            function myCompareCode(a, b) {
                                 let valA = a.data.code,
                                     valB = b.data.code;
-                                return valB- valA;
+                                return valB - valA;
                             }
                             totalItems.itemsArr.sort(myCompareCode);
                             maxItemsNumber = totalItems.itemsArr.length > 0 ? totalItems.itemsArr[0].data.code : 0;
                             tools.reshowData(sheet, totalItems.itemsArr, setting, true);
                             billsAjax.removeTotal(userAccount, billsLibId, billsIds, ids, 'items');
                             //reshowVal
-                            if(totalItems.itemsArr.length > 0){
+                            if (totalItems.itemsArr.length > 0) {
                                 selectedId = totalItems.itemsArr[0].data.id;
                                 tools.reshowValue(valSheet, totalItems.itemsArr[0].data.itemValue, eigenValueSetting, true);
                             }
@@ -302,16 +356,16 @@ var myKey = {
             spread.commandManager().setShortcutKey('myItemDelete', GC.Spread.Commands.Key.del, false, false, false, false)
         }
 
-        function bindValDel(spread, totalItems, setting){
+        function bindValDel(spread, totalItems, setting) {
             var sheet = spread.getActiveSheet();
-            spread.commandManager().register('valDelete', function(){
+            spread.commandManager().register('valDelete', function () {
                 spread.suspendEvent();
                 var ids = tools.delIds(sheet);
                 //deleteFront
                 var valsArr = valueController.getValues(totalItems, selectedId);
-                ids.forEach(function(id){
-                    valsArr.forEach(function(val){
-                        if(val.code === id){
+                ids.forEach(function (id) {
+                    valsArr.forEach(function (val) {
+                        if (val.code === id) {
                             valsArr.splice(valsArr.indexOf(val), 1);
                         }
                     });
@@ -325,7 +379,7 @@ var myKey = {
             spread.commandManager().setShortcutKey('valDelete', GC.Spread.Commands.Key.del, false, false, false, false);
         }
 
-        function reSerialNo(){
+        function reSerialNo() {
 
         }