ソースを参照

补充工料机库

zhongzewei 7 年 前
コミット
da2cf7f711

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

@@ -0,0 +1,132 @@
+/**
+ * Created by Zhong on 2017/8/22.
+ */
+import BaseController from "../../common/base/base_controller";
+import stdgljutil  from "../../../public/cache/std_glj_type_util";
+import GljDao from "../models/gljModel";
+
+let gljDao = new GljDao();
+let callback = function(req, res, err, message, data){
+    res.json({error: err, message: message, data: data});
+};
+
+class GljController extends BaseController{
+    redirectGlj(req, res){
+        let gljLibId;
+        if(typeof req.session.sessionCompilation.ration_valuation[0].glj_lib[0] !== 'undefined'){
+            gljLibId = req.session.sessionCompilation.ration_valuation[0].glj_lib[0].id;
+        }
+        else if(typeof req.session.sessionCompilation.bill_valuation[0].glj_lib[0] !== 'undefined'){
+            gljLibId = req.session.sessionCompilation.bill_valuation[0].glj_lib[0].id;
+        }
+        res.render('building_saas/complementary_glj_lib/html/tools-gongliaoji.html',{
+            userID: req.session.sessionUser.ssoId,
+            gljLibId: gljLibId,
+            compilationId: req.session.sessionCompilation._id
+        });
+    }
+    getGljDistType (req, res) {
+        let gljDistTypeCache = stdgljutil.getStdGljTypeCacheObj().toArray();
+        if(gljDistTypeCache.length >0 ){
+            callback(req, res, null, '', gljDistTypeCache);
+        }
+        else {
+            callback(req, res, 1, 'Error', null);
+        }
+    }
+    getGljTree(req,res){
+        let gljLibId = req.body.gljLibId;
+        gljDao.getGljTypes(gljLibId,function(err,data){
+            callback(req,res,err, 'Get Tree', data)
+        });
+    }
+   /* updateRationBasePrc(req, res){
+        let basePrcArr = JSON.parse(req.body.basePrcArr);
+        rationItemDao.updateRationBasePrc(basePrcArr, function (err, message) {
+            if(err){
+                callback(req, res, err, message, null);
+            }
+            else{
+                callback(req, res, err, message, null);
+            }
+        });
+    }*/
+
+   /* getRationGljIds(req, res){
+        let rationLibs = req.body.rationLibs;
+        gljDao.getRationGljIds(rationLibs, function (err, msg, data) {
+            callback(req, res, err, msg, data);
+        })
+    }*/
+    createNewGljTypeNode(req, res) {
+        let repId = req.body.repositoryId;
+        let lastNodeId = req.body.lastNodeId;
+        let lastOpr = req.body.lastOpr;
+        let nodeData = JSON.parse(req.body.rawNodeData);
+        gljDao.createNewNode(repId, lastOpr, lastNodeId, nodeData, function(err, msg, data){
+            callback(req,res,err,msg, data)
+        });
+    }
+    updateGljNodes(req, res) {
+        let nodes = JSON.parse(req.body.nodes);
+        let repId = req.body.repId,
+            lastOpr = req.body.lastOpr;
+        gljDao.updateNodes(repId, lastOpr, nodes, function(err,results){
+            callback(req,res, err, results)
+        });
+    }
+    deleteGljNodes(req, res) {
+        let nodes = JSON.parse(req.body.nodes);
+        let preNodeId = req.body.preNodeId;
+        let preNodeNextId = req.body.preNodeNextId;
+        let repId = req.body.repId, lastOpr = req.body.lastOpr;
+        gljDao.removeNodes(repId, lastOpr, nodes, preNodeId, preNodeNextId, function(err,results){
+            callback(req,res, err, results)
+        });
+    }
+    getGljItems(req, res) {
+        let stdGljLibId = req.body.stdGljLibId,
+            userId = req.body.userId,
+            compilationId = req.body.compilationId;
+            gljDao.getGljItems(stdGljLibId, userId, compilationId, function(err, data){
+                callback(req,res,err,'Get Items',data)
+            });
+    }
+   /* getGljItemsByIds(req, res) {
+        let gljIds = JSON.parse(req.body.gljIds);
+        gljDao.getGljItems(gljIds, function(err, data){
+            callback(req,res,err,'Get Items',data)
+        });
+    }
+    getGljItemsByCodes(req, res) {
+        let gljCodes = JSON.parse(req.body.gljCodes),
+            repId = req.body.repId;
+        gljDao.getGljItemsByCode(repId, gljCodes, function(err, data){
+            callback(req,res,err,'Get Items',data)
+        });
+    }*/
+    updateComponent(req, res){
+        let libId = req.body.libId,
+            updateArr = req.body.updateArr,
+            oprtor = req.body.oprtor;
+        gljDao.updateComponent(libId, oprtor, updateArr, function (err, message, rst) {
+            callback(req, res, err, message, rst);
+        })
+    }
+    mixUpdateGljItems(req, res){
+        let userId = req.body.userId,
+            compilationId = req.body.compilationId,
+            updateItems = JSON.parse(req.body.updateItems),
+            addItems = JSON.parse(req.body.addItems),
+            removeIds = JSON.parse(req.body.removeIds);
+        gljDao.mixUpdateGljItems(userId, compilationId, updateItems, addItems, removeIds, function(err, message, rst){
+            if (err) {
+                callback(req, res, err, message, null);
+            } else {
+                callback(req, res, err, message, rst);
+            }
+        });
+    }
+}
+
+export default GljController;

+ 236 - 0
modules/complementary_glj_lib/models/gljModel.js

@@ -0,0 +1,236 @@
+/**
+ * Created by Zhong on 2017/8/22.
+ */
+import {complementaryGljModel, stdGljModel, gljClassModel} from "./schemas";
+import counter from "../../../public/counter/counter";
+import async from "async";
+
+class GljDao {
+    getGljTypes (gljLibId, callback){
+        gljClassModel.find({"repositoryId": gljLibId, "$or": [{"isDeleted": null}, {"isDeleted": false} ]},function(err,data){
+            if(data.length) {
+                callback(false,data);
+            }
+            else  if(err) callback("获取工料机类型错误!",false);
+        })
+    }
+
+
+    getGljItemsByRep(repositoryId,callback){
+        gljModel.find({"repositoryId": repositoryId},function(err,data){
+            if(err) callback(true, "")
+            else callback(false,data);
+        })
+    }
+
+    getGljItemByType (repositoryId, type, callback){
+        gljModel.find({"repositoryId": repositoryId, "gljType": type},function(err,data){
+            if(err) callback(true, "")
+            else callback(false, data);
+        })
+    };
+
+    getGljItem (repositoryId, code, callback){
+        gljModel.find({"repositoryId": repositoryId, "code": code},function(err,data){
+            if(err) callback(true, "")
+            else callback(false, data);
+        })
+    };
+    //获得用户的补充工料机和用户当前所在编办的标准工料机
+    getGljItems (stdGljLibId, userId, compilationId, callback){
+        let rst = {stdGljs: [], complementaryGljs: []};
+        async.parallel([
+            function (cb) {
+                stdGljModel.find({repositoryId: stdGljLibId}, function (err, stdGljs) {
+                    if(err){
+                        cb(err);
+                    }
+                    else{
+                        rst.stdGljs = stdGljs;
+                        cb(null);
+                    }
+                });
+            },
+            function (cb) {
+                complementaryGljModel.find({userId: userId, compilationId: compilationId}, function (err, complementaryGljs) {
+                    if(err){
+                        cb(err);
+                    }
+                    else{
+                        rst.complementaryGljs = complementaryGljs;
+                        cb(null);
+                    }
+                });
+            }
+        ], function (err) {
+            if(err){
+                callback(true, null);
+            }
+            else{
+                callback(false, rst);
+            }
+        })
+
+    };
+
+    getGljItemsByCode (repositoryId, codes, callback){
+        gljModel.find({"repositoryId": repositoryId,"code": {"$in": codes}},function(err,data){
+            if(err) callback(true, "")
+            else callback(false, data);
+        })
+    };
+
+    //-oprtor
+    updateComponent(libId, updateArr, callback){
+        let parallelFucs = [];
+        for(let i = 0; i < updateArr.length; i++){
+            parallelFucs.push((function(obj){
+                return function (cb) {
+                    if(typeof obj.component === 'undefined'){
+                        obj.component = [];
+                    }
+                    gljModel.update({repositoryId: libId, ID: obj.ID}, obj, function (err, result) {
+                        if(err){
+                            cb(err);
+                        }
+                        else{
+                            cb(null, obj);
+                        }
+                    })
+                }
+            })(updateArr[i]));
+        }
+        async.parallel(parallelFucs, function (err, result) {
+            if(err){
+                callback(err, '更新组成物错误!', null);
+            }
+            else{
+                callback(null, '成功!', result);
+            }
+        });
+    }
+    //-oprtor
+    mixUpdateGljItems (userId, compilationId, updateItems, addItems, rIds, callback) {
+        if (updateItems.length == 0 && rIds.length == 0) {
+            GljDao.addGljItems(userId, compilationId, addItems, callback);
+        }
+        else if(rIds.length > 0 && updateItems.length > 0){
+            async.parallel([
+                function (cb) {
+                    GljDao.removeGljItems(rIds, cb);
+                },
+                function (cb) {
+                    GljDao.updateGljItems(userId, compilationId, updateItems, cb);
+                }
+            ], function (err) {
+                if(err){
+                    callback(true, "Fail to update and delete", false)
+                }
+                else{
+                    callback(false, "Save successfully", false);
+                }
+            })
+        }
+        else if (rIds.length > 0 && updateItems.length === 0) {
+            GljDao.removeGljItems(rIds, callback);
+        }
+        else if(updateItems.length > 0 || addItems.length > 0){
+            GljDao.updateGljItems(userId, compilationId, updateItems, function(err, results){
+                if (err) {
+                    callback(true, "Fail to update", false);
+                } else {
+                    if (addItems && addItems.length > 0) {
+                        GljDao.addGljItems(userId, compilationId, addItems, callback);
+                    } else {
+                        callback(false, "Save successfully", results);
+                    }
+                }
+            });
+        }
+    }
+
+    /*mixUpdateGljItems (repId, lastOpr, updateItems, addItems, rIds, callback) {
+     if (updateItems.length == 0 && rIds.length == 0) {
+     GljDao.addGljItems(repId, lastOpr, addItems, callback);
+     } else if (rIds.length > 0) {
+     GljDao.removeGljItems(repId, lastOpr, rIds, function(err, message, docs) {
+     });
+     }else{
+     GljDao.updateGljItems(repId, lastOpr, updateItems, function(err, results){
+     if (err) {
+     callback(true, "Fail to update", false);
+     } else {
+     if (addItems && addItems.length > 0) {
+     GljDao.addGljItems(repId, lastOpr, addItems, callback);
+     } else {
+     callback(false, "Save successfully", results);
+     }
+     }
+     });
+     }
+     };*/
+
+    static removeGljItems (rIds, callback) {
+        if (rIds && rIds.length > 0) {
+            complementaryGljModel.collection.remove({ID: {$in: rIds}}, null, function(err, docs){
+                if (err) {
+                    callback(true, "Fail to remove", false);
+                } else {
+                    callback(false, "Remove successfully", docs);
+                }
+            })
+        } else {
+            callback(false, "No records were deleted!", null);
+        }
+    }
+
+    static addGljItems (userId, compilationId, items, callback) {
+        if (items && items.length > 0) {
+            counter.counterDAO.getIDAfterCount(counter.moduleName.GLJ, items.length, function(err, result){
+                var maxId = result.value.sequence_value;
+                var arr = [];
+                for (var i = 0; i < items.length; i++) {
+                    var obj = new complementaryGljModel(items[i]);
+                    obj.ID = (maxId - (items.length - 1) + i);
+                    obj.userId = userId;
+                    obj.compilationId = compilationId;
+                    arr.push(obj);
+                }
+                complementaryGljModel.collection.insert(arr, null, function(err, docs){
+                    if (err) {
+                        callback(true, "Fail to add", false);
+                    } else {
+                        callback(false, "Add successfully", docs);
+                    }
+                });
+            });
+        } else {
+            callback(true, "No source", false);
+        }
+    }
+
+    static updateGljItems(userId, compilationId, items, callback) {
+        var functions = [];
+        for (var i=0; i < items.length; i++) {
+            functions.push((function(doc) {
+                return function(cb) {
+                    var filter = {};
+                    if (doc.ID) {
+                        filter.ID = doc.ID;
+                    } else {
+                        filter.userId = userId;
+                        filter.compilationId = compilationId;
+                        filter.code = doc.code;
+                    }
+                    complementaryGljModel.update(filter, doc, cb);
+                };
+            })(items[i]));
+        }
+        async.parallel(functions, function(err, results) {
+            callback(err, results);
+        });
+    }
+}
+
+export default GljDao;
+

+ 60 - 0
modules/complementary_glj_lib/models/schemas.js

@@ -0,0 +1,60 @@
+/**
+ * Created by Zhong on 2017/8/22.
+ */
+import mongoose from "mongoose";
+
+let Schema = mongoose.Schema;
+let gjlComponentSchema = mongoose.Schema(
+    {
+        ID: Number,
+        consumeAmt: Number
+    },
+    {_id: false},
+    {versionKey: false}
+);
+//补充工料机跟用户和编办绑定
+let complementaryGljSchema = new Schema({
+    userId: Number,
+    compilationId: String,
+    ID: Number,
+    code: String,
+    name: String,
+    specs: String,
+    unit: String,
+    basePrice: String,
+    gljClass: Number,
+    gljType: Number,
+    shortName: String,
+    component: [gjlComponentSchema]
+}, {versionKey: false});
+
+//标准工料机
+let stdGljSchema = new Schema({
+    deleted: Boolean,
+    repositoryId: Number,
+    ID: Number,
+    code: String,
+    name: String,
+    specs: String,
+    basePrice: Number,
+    gljClass: Number,
+    gljType: Number,
+    shortName: String,
+    component: [gjlComponentSchema]
+},{versionKey: false});
+
+//标准工料机分类树
+let gljClassSchema = mongoose.Schema({
+    repositoryId: Number,
+    ID: Number,
+    ParentID: Number,
+    NextSiblingID: Number,
+    Name: String,
+    deleted: Boolean
+}, {versionKey: false});
+
+let complementaryGljModel = mongoose.model('complementary_glj_lib', complementaryGljSchema, 'complementary_glj_lib');
+let stdGljModel = mongoose.model('std_glj_lib_gljList', stdGljSchema, 'std_glj_lib_gljList');
+let gljClassModel = mongoose.model('std_glj_lib_gljClass', gljClassSchema, 'std_glj_lib_gljClass');
+
+export {complementaryGljModel, stdGljModel, gljClassModel};

+ 29 - 0
modules/complementary_glj_lib/routes/routes.js

@@ -0,0 +1,29 @@
+/**
+ * Created by Zhong on 2017/8/22.
+ */
+
+import express from "express";
+import GljController from "../controllers/gljController"
+
+let router = express.Router();
+let gljController = new GljController();
+
+module.exports = function (app) {
+    app.get('/complementartGlj', gljController.init, gljController.redirectGlj);
+
+   /* router.post("/updateRationBasePrc",gljController.init, gljController.updateRationBasePrc);//更新定额单价
+    router.post("/getRationGljIds", gljController.init, gljController.getRationGljIds);
+    router.post("/createNewGljTypeNode", gljController.init, gljController.createNewGljTypeNode);
+    router.post("/updateGljNodes", gljController.init, gljController.updateGljNodes);
+    router.post("/deleteGljNodes", gljController.init, gljController.deleteGljNodes);*/
+    router.post("/getGljDistType", gljController.init, gljController.getGljDistType);
+    router.post("/getGljTree", gljController.init, gljController.getGljTree);
+    router.post("/getGljItems", gljController.init, gljController.getGljItems);
+    router.post("/updateComponent", gljController.init, gljController.updateComponent);
+    router.post("/mixUpdateGljItems", gljController.init, gljController.mixUpdateGljItems);
+    //router.post("/getGljItemsByIds", gljController.init, gljController.getGljItemsByIds);
+    //router.post("/getGljItemsByCodes", gljController.init, gljController.getGljItemsByCodes);
+
+    app.use("/complementartGlj/api", router);
+
+};

+ 319 - 0
web/building_saas/complementary_glj_lib/html/tools-gongliaoji.html

@@ -0,0 +1,319 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta http-equiv="x-ua-compatible" content="ie=edge">
+    <title>工料机库编辑-Smartcost</title>
+    <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css" type="text/css">
+    <link rel="stylesheet" href="/web/building_saas/css/main.css" type="text/css">
+    <link rel="stylesheet" href="/lib/font-awesome/font-awesome.min.css" type="text/css">
+    <link rel="stylesheet" href="/lib/jquery-contextmenu/jquery.contextMenu.css" type="text/css">
+    <!--zTree-->
+  	<link rel="stylesheet" href="/lib/ztree/css/zTreeStyle.css" type="text/css">
+    <link rel="stylesheet" href="/lib/spreadjs/sheets/css/gc.spread.sheets.excel2013lightGray.10.0.1.css" type="text/css">
+    <style type="text/css">
+        .modal-lg{max-width: 1000px}
+    </style>
+</head>
+<body>
+    <div class="header">
+        <!-- <div class="top-msg clearfix">
+            <div class="alert alert-warning mb-0 py-0" role="alert">
+                <button type="button" class="close" data-dismiss="alert" aria-label="Close">
+                  <span aria-hidden="true">&times;</span>
+                </button>
+                <strong>Warning!</strong> Better check yourself, you're not looking too good.
+            </div>
+        </div> -->
+        <nav class="navbar navbar-toggleable-lg navbar-light bg-faded p-0 justify-content-between">
+            <span class="header-logo px-2">Smartcost</span>
+            <div class="navbar-text"><a href="project-management.html">项目管理</a></div>
+            <div class="float-lg-right navbar-text pt-0">
+                <div class="dropdown d-inline-block">
+                    <button class="btn btn-link btn-sm dropdown-toggle" type="button" data-toggle="dropdown">陈特</button>
+                    <div class="dropdown-menu dropdown-menu-right">
+                        <a class="dropdown-item" href="user-info.html" target="_blank">账号资料</a>
+                        <a class="dropdown-item" href="user-buy.html" target="_blank">产品购买</a>
+                        <a class="dropdown-item" href="user-set.html" target="_blank">偏好设置</a>
+                    </div>
+                </div>
+                <span class="btn btn-link btn-sm new-msg">
+                  <i class="fa fa-envelope-o" aria-hidden="true"></i>&nbsp;2
+                </span>
+                <button class="btn btn-link btn-sm">注销</button>
+            </div>
+        </nav>
+        <nav class="navbar navbar-toggleable-lg justify-content-between navbar-light p-0">
+            <ul class="nav navbar-nav px-1">
+                <li class="nav-item">
+                    <a class="nav-link" href="#" aria-expanded="false"><i class="fa fa-sliders"></i> 选项</a>
+                </li>
+                <li class="nav-item dropdown">
+                    <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-wrench"></i> 工具</a>
+                    <div class="dropdown-menu">
+                        <a class="dropdown-item" href="#">定额库编辑器</a>
+                        <a class="dropdown-item" href="#">工料机库编辑器</a>
+                    </div>
+                </li>
+                <li class="nav-item dropdown">
+                    <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-question-circle-o"></i> 帮助</a>
+                    <div class="dropdown-menu">
+                        <a class="dropdown-item" href="#">帮助</a>
+                        <a class="dropdown-item" href="#">升级说明</a>
+                        <a class="dropdown-item" href="#">重庆市2008定额说明</a>
+                        <a class="dropdown-item" href="#">纵横官网</a>
+                        <a class="dropdown-item" href="#">动画教程</a>
+                        <a class="dropdown-item" href="#">联系客服</a>
+                        <a class="dropdown-item" href="#">关于</a>
+                    </div>
+                </li>
+                <li class="nav-item">
+                    <a href="javacript:void(0);" data-toggle="modal" data-target="#history" class="nav-link"><i class="fa fa-history"></i> 历史记录</a>
+                </li>
+            </ul>
+            <form class="form-inline">
+                <input class="form-control form-control-sm mr-1" type="text" placeholder="告诉我你想做什么">
+            </form>
+        </nav>
+    </div>
+    <div class="main">
+        <div class="main-nav">
+            <ul class="nav flex-column">
+              <li><a href="#">定额库编辑器</a></li>
+              <li><a href="tools-gongliaoji.html" class="active">工料机库编辑器</a></li>
+            </ul>
+        </div>
+        <div class="content">
+            <div class="container-fluid">
+              <div class="row">
+                <div class="col-lg-2 p-0">
+                  <div class="print-list">
+                    <div class="form-list">
+                      <ul id="repositoryTree" class="ztree"></ul>
+                    </div>
+                  </div>
+                </div>
+                <div id="GLJListSheet" class="col-lg-7 p-0">
+
+                </div>
+                <div id="gljComponentSheet" class="col-lg-3 p-0">
+                </div>
+              </div>
+            </div>
+        </div>
+      </div>
+      <!--弹出组成物-->
+    <button id="componentBtn" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#component" style="display: none"></button>
+      <div class="modal fade" id="component" data-backdrop="static">
+          <div class="modal-dialog modal-lg" role="document" id="modalCon">
+              <div class="modal-content" >
+                  <div class="modal-header">
+                    <h5 class="modal-title">内容</h5>
+                      <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">&times;</span>
+                      </button>
+                  </div>
+                  <div class="modal-body">
+                    <div class="row">
+                      <div class="col-4">
+                        <div  class="modal-auto-height">
+                            <div class="print-list">
+                                <div class="form-list" id="componentTreeDiv">
+                                    <ul id="componentTree" class="ztree"></ul>
+                                </div>
+                            </div>
+                        </div>
+                      </div>
+                      <div class="col-8">
+                          <div class="row">
+                              <div class="modal-auto-height col-12" id="gljRadios">
+                                  <input type="radio" class="glj-radio" name="glj" value="allGljs">所有工料机&nbsp;&nbsp;
+                                  <input type="radio" class="glj-radio" name="glj" value="stdGljs">标准工料机&nbsp;&nbsp;
+                                  <input type="radio" class="glj-radio" name="glj" value="complementaryGljs">补充工料机
+                              </div>
+                              <div class="modal-auto-height col-12"  id="componentSheet">
+                               <!--   <table class="table table-sm table-bordered m-0">
+                                      <thead>
+                                      <tr><th></th><th>编码</th><th>名称</th><th>规格型号</th><th>计量单位</th><th>单价</th><th>类型</th></tr>
+                                      </thead>
+                                      <tbody>
+                                      <tr><td>1</td><td></td><td></td><td></td><td></td><td></td></tr>
+                                      <tr><td>2</td><td></td><td></td><td></td><td></td><td></td></tr>
+                                      <tr><td>3</td><td></td><td></td><td></td><td></td><td></td></tr>
+                                      <tr><td>4</td><td></td><td></td><td></td><td></td><td></td></tr>
+                                      </tbody>
+                                  </table>-->
+                              </div>
+                          </div>
+                      </div>
+                    </div>
+                  </div>
+                  <div class="modal-footer">
+                      <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                      <a href="javascript:void(0);" class="btn btn-primary">确定</a>
+                  </div>
+              </div>
+          </div>
+      </div>
+    <!--弹出警告-->
+    <button id="gljAlertBtn" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#gljAlert" style="display: none"></button>
+    <button id="codeAlertBtn" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#codeAlert" style="display: none"></button>
+    <div class="modal fade" id="gljAlert" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <input type="hidden" id="gdid" value="123">
+        <div class="modal-dialog" role="document" style="width: 1200px;">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h5 class="modal-title">取消确认</h5>
+                    <button type="button" id="gljAleClose" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">×</span>
+                    </button>
+                </div>
+                <div class="modal-body">
+                    <h5 class="text-danger" id="alertGljTxt">编号和类型不可为空!是否取消操作?</h5>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" id="aleCanceBtn" data-dismiss="modal">取消</button>
+                    <a href="javascript: void(0);" id="aleConfBtn" class="btn btn-danger" data-dismiss="modal">确认</a>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="modal" id="codeAlert" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <input type="hidden" id="codedid" value="123">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h5 class="modal-title">警告</h5>
+                    <button type="button" id="codAleClose" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">×</span>
+                    </button>
+                </div>
+                <div class="modal-body">
+                    <h5 class="text-danger" id="alertText">输入的编号已存在,请重新输入!</h5>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-danger" id="codAleConfBtn" data-dismiss="modal">确认</button>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!-- JS. -->
+    <script src="/lib/jquery/jquery.min.js"></script>
+    <script src="/lib/jquery-contextmenu/jquery.contextMenu.min.js"></script>
+    <script src="/lib/jquery-contextmenu/jquery.ui.position.js"></script>
+    <script src="/lib/tether/tether.min.js"></script>
+    <script src="/lib/bootstrap/bootstrap.min.js"></script>
+    <script src="/web/building_saas/js/global.js"></script>
+    <!-- zTree -->
+    <script src = "/lib/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js"></script>
+    <script>GC.Spread.Sheets.LicenseKey = "559432293813965#A0y3iTOzEDOzkjMyMDN9UTNiojIklkI1pjIEJCLi4TPB9mM5AFNTd4cvZ7SaJUVy3CWKtWYXx4VVhjMpp7dYNGdx2ia9sEVlZGOTh7NRlTUwkWR9wEV4gmbjBDZ4ElR8N7cGdHVvEWVBtCOwIGW0ZmeYVWVr3mI0IyUiwCMzETN8kzNzYTM0IicfJye&Qf35VfiEzRwEkI0IyQiwiIwEjL6ByUKBCZhVmcwNlI0IiTis7W0ICZyBlIsIyNyMzM5ADI5ADNwcTMwIjI0ICdyNkIsIibj9SbvNmL4N7bjRnch56ciojIz5GRiwiI8+Y9sWY9QmZ0Jyp96uL9v6L0wap9biY9qiq95q197Wr9g+89iojIh94Wiqi";</script>
+    <script type="text/javascript" src="/lib/ztree/jquery.ztree.core.js"></script>
+    <script type="text/javascript" src="/lib/ztree/jquery.ztree.excheck.js"></script>
+    <script type="text/javascript" src="/lib/ztree/jquery.ztree.exedit.js"></script>
+    <script type="text/javascript" src="/public/web/treeDataHelper.js"></script>
+    <script type="text/javascript" src="/public/web/QueryParam.js"></script>
+    <script type="text/javascript" src="/web/building_saas/complementary_glj_lib/js/glj.js"></script>
+    <script type="text/javascript" src="/web/building_saas/complementary_glj_lib/js/gljComponent.js"></script>
+    <script type="text/javascript" src="/web/building_saas/complementary_glj_lib/js/components.js"></script>
+    <script type="text/javascript" src="/public/web/ztree_common.js"></script>
+    <script type="text/javascript" src="/web/building_saas/complementary_glj_lib/js/sheetOpr.js"></script>
+    <script type="text/javascript" src="/public/web/storageUtil.js"></script>
+    <SCRIPT type="text/javascript">
+        let userId = "<%= userID%>";
+        let compilationId = "<%= compilationId%>";
+        let stdGljLibId = "<%= gljLibId%>";//用户当前编办下的标准工料机库ID,目前认为一个编办只有一个标准工料机库
+        let gljSetting = {
+            view: {
+                //addHoverDom: gljTypeTreeOprObj.addHoverDom,
+                //removeHoverDom: gljTypeTreeOprObj.removeHoverDom,
+                expandSpeed: "",
+                selectedMulti: false
+            },
+            edit: {
+                enable: false,
+                editNameSelectAll: true,
+                showRemoveBtn: true,
+                showRenameBtn: true,
+                removeTitle: "删除节点",
+                renameTitle: "更改名称"
+            },
+            data: {
+                keep: {
+                    parent:true,
+                    leaf:true
+                },
+                key: {
+                    children: "items",
+                    name: "Name"
+                },
+                simpleData: {
+                    enable: false,
+                    idKey: "ID",
+                    pIdKey: "ParentID",
+                    rootPId: -1
+                }
+            },
+            callback:{
+                onClick: gljTypeTreeOprObj.onClick
+            }
+        };
+        //组成物弹出窗口组成物分类树
+        let componentSetting = {
+            view: {
+                //addHoverDom: gljTypeTreeOprObj.addHoverDom,
+                //removeHoverDom: gljTypeTreeOprObj.removeHoverDom,
+                expandSpeed: "",
+                selectedMulti: false
+            },
+            edit: {
+                enable: false,
+                editNameSelectAll: true,
+                showRemoveBtn: true,
+                showRenameBtn: true,
+                removeTitle: "删除节点",
+                renameTitle: "更改名称"
+            },
+            data: {
+                keep: {
+                    parent:true,
+                    leaf:true
+                },
+                key: {
+                    children: "items",
+                    name: "Name"
+                },
+                simpleData: {
+                    enable: false,
+                    idKey: "ID",
+                    pIdKey: "ParentID",
+                    rootPId: -1
+                }
+            },
+            callback:{
+                onClick: componentTypeTreeOprObj.onClick
+            }
+        };
+        $(document).ready(function(){
+            //解决spreadjs sheet初始化没高度宽度
+            $('#modalCon').width($(window).width()*0.5);
+            $('#componentTreeDiv').height($(window).height() - 300);
+            $("#componentSheet").height($("#componentTreeDiv").height()-21.6);
+            $("#componentSheet").width($('#modalCon').width() * 0.63);
+            pageOprObj.initPage($("#GLJListSheet")[0], $('#gljComponentSheet')[0], $('#componentSheet')[0]);
+        });
+        //组成物弹出窗大小设置
+        $(window).resize(function () {
+            $('#modalCon').width($(window).width()*0.5);
+            $('#componentTreeDiv').height($(window).height() - 300);
+            $("#componentSheet").height($("#componentTreeDiv").height()-21.6);
+            $("#componentSheet").width($('#modalCon').width()* 0.63);
+        });
+  	</SCRIPT>
+</body>
+<script type="text/javascript">
+    autoFlashHeight();
+</script>
+
+</html>

+ 210 - 0
web/building_saas/complementary_glj_lib/js/components.js

@@ -0,0 +1,210 @@
+/**
+ * Created by Zhong on 2017/8/25.
+ */
+/*
+   弹出组成物窗口 组成物表
+ * */
+let componentOprObj = {
+    treeObj:null,
+    rootNode: null,//分类树根节点
+    radiosSelected: null,//allGljs, stdGljs, complementaryGljs
+    workBook: null,
+    setting: {
+        owner: "components",
+        header: [
+            {headerName:"选择", headerWidth: 40, dataCode: "select", hAlign: "center", vAlign: "center"},
+            {headerName:"编码",headerWidth:80,dataCode:"code", dataType: "String", formatter: "@", hAlign: "left", vAlign: "center"},
+            {headerName:"名称",headerWidth:120,dataCode:"name", dataType: "String", hAlign: "left", vAlign: "center"},
+            {headerName:"规格型号",headerWidth:80,dataCode:"specs", dataType: "String", hAlign: "center", vAlign: "center"},
+            {headerName:"计量单位",headerWidth:80,dataCode:"unit", dataType: "String", hAlign: "center", vAlign: "center"},
+            {headerName:"单价",headerWidth:80,dataCode:"basePrice", dataType: "Number", formatter: "0.00", hAlign: "right", vAlign: "center"},
+            {headerName:"类型",headerWidth:80,dataCode:"gljType", dataType: "String",  hAlign: "center", vAlign: "center"}
+        ],
+        view: {
+            lockedCells: [1, 2, 3]
+        }
+    },
+    buildSheet: function (container) {
+        let me = componentOprObj;
+        me.workBook = sheetOpr.buildSheet(container, me.setting, 30);
+        me.workBook.getSheet(0).setColumnWidth(0, 20, GC.Spread.Sheets.SheetArea.rowHeader);
+        me.workBook.getSheet(0).setFormatter(-1, 1, "@", GC.Spread.Sheets.SheetArea.viewport);
+        me.workBook.getSheet(0).options.isProtected = true;
+        sheetOpr.cleanSheet(me.workBook.getSheet(0), me.setting, -1);
+        me.radiosChange();
+    },
+    setShowGljList: function (gljList) {
+        //初始为所有工料机,机械类型可添加机械组成物,混凝土,砂浆、配合比可添加普通材料
+        let materialArr = [202, 203, 204];//混凝土、砂浆、配合比, 201普通材料
+        let that = repositoryGljObj, me = componentOprObj;
+            for(let i = 0; i < gljList.length; i++){
+                if(that.currentGlj.gljType === 3 && gljList[i].gljType === 302 ||
+                    materialArr.indexOf(that.currentGlj.gljType) !== -1 && gljList[i].gljType === 201){
+                    //去除与已添加的组成物重复的条目
+                    let isExist = false;
+                    for(let j = 0; j < that.currentComponent.length; j++){
+                        if(that.currentComponent[j].ID === gljList[i].ID){
+                            isExist = true;
+                            break;
+                        }
+                    }
+                    if(!isExist){
+                        gljList[i].isChecked = false;
+                        me.showGljList.push(gljList[i]);
+                    }
+                }
+            }
+    },
+    //初始默认radio
+    initRadio: function () {
+        let that = repositoryGljObj, me = componentOprObj;
+        //默认radio所有工料机
+        if(typeof $("input[name='glj']:checked")[0] !== 'undefined'){
+            $("input[name='glj']:checked")[0].checked = false;
+        }
+        $("input[value = 'allGljs']")[0].checked = true;
+        me.radiosSelected = 'allGljs';
+        //初始为所有工料机,机械类型可添加机械组成物,混凝土,砂浆、配合比可添加普通材料
+        me.showGljList = [];
+        if(me.radiosSelected === 'allGljs'){
+            me.setShowGljList(that.stdGljList);
+            me.setShowGljList(that.complementaryGljList);
+            that.sortGlj(me.showGljList);
+        }
+    },
+    //监听radios选择事件
+    radiosChange: function () {
+        let me = componentOprObj, re = repositoryGljObj;
+        let materialArr = [202, 203, 204];//混凝土、砂浆、配合比, 201普通材料
+        $('.glj-radio').change(function () {
+            let val = $("input[name='glj']:checked").val();
+            me.radiosSelected = val;
+            //选择改变,数据重新筛选显示
+            me.showGljList = [];
+            if(me.radiosSelected === 'allGljs'){
+                me.setShowGljList(re.stdGljList);
+                me.setShowGljList(re.complementaryGljList);
+            }
+            else if(me.radiosSelected === 'stdGljs'){
+               me.setShowGljList(re.stdGljList);
+            }
+            else if(me.radiosSelected === 'complementaryGljs'){
+                me.setShowGljList(re.complementaryGljList);
+            }
+            re.sortGlj(me.showGljList);
+            //重新显示
+            me.showGljItems(me.showGljList, me.gljCurTypeId);
+            //切换radio后更新cache
+            if (me.currentOprParent = 1) {
+                if(re.parentNodeIds["_pNodeId_" + me.gljCurTypeId]){
+                    me.currentCache = me.getParentCache(re.parentNodeIds["_pNodeId_" + me.gljCurTypeId]);
+                }
+                else{
+                    me.currentCache = [];
+                }
+            } else {
+                me.currentCache = me.getCache();
+            }
+        });
+    },
+    //切换分类树时,记住当前分类的选择, value = true、false、null
+    setComponentChecked: function (sheet) {
+        let me = componentOprObj;
+        for(let i = 0; i < sheet.getRowCount(); i ++){
+            if(sheet.getValue(i, 0) === true){//选择了
+                me.preCache[i].isChecked = true;
+            }
+            else if(sheet.getValue(i, 0) === false){//避免value为null
+                me.preCache[i].isChecked = false;
+            }
+        }
+    },
+    //获得选择的组成物
+    getComponents: function () {
+        let rst = [];
+        let me = componentOprObj;
+        for(let i = 0; i < me.showGljList.length; i++){
+
+        }
+    },
+    getParentCache: function (nodes) {
+        let me = componentOprObj, rst = [];
+        for(let i = 0; i < me.showGljList.length; i++){
+            if(nodes.indexOf(me.showGljList[i].gljClass) !== -1){
+                rst.push(me.showGljList[i]);
+            }
+        }
+        rst.sort(function (a, b) {
+            let rst = 0;
+            if(a.code > b.code) rst = 1;
+            else if(a.code < b.code)rst = -1;
+            return rst;
+        });
+        return rst;
+    },
+    getCache: function() {
+        let me = componentOprObj, rst = [];
+        for (let i = 0; i < me.showGljList.length; i++) {
+            if (me.showGljList[i].gljClass == me.gljCurTypeId) {
+                rst.push(me.showGljList[i]);
+            }
+        }
+        return rst;
+    },
+    showGljItems: function(data, type) {
+        let me = componentOprObj, re = repositoryGljObj;
+        if (me.workBook) {
+            let cacheSection = [];
+            let pArr = re.parentNodeIds["_pNodeId_" + type];
+            for (let i = 0; i < data.length; i++) {
+                if (pArr && pArr.indexOf(data[i].gljClass) >= 0) {
+                    cacheSection.push(data[i]);
+                } else if (type == data[i].gljClass) {
+                    cacheSection.push(data[i]);
+                }
+            }
+            sheetOpr.cleanSheet(me.workBook.getSheet(0), me.setting, -1);
+            sheetOpr.showData(me.workBook.getSheet(0), me.setting, cacheSection, re.distTypeTree);
+            cacheSection = null;
+        }
+    }
+};
+
+let componentTypeTreeOprObj = {
+    //todo: 当关闭后,将gljcurTypeId置0
+    onClick: function(event,treeId,treeNode) {
+        let me = componentOprObj, re = repositoryGljObj, that = gljComponentOprObj, gljTypeId = treeNode.ID;
+        if(me.gljCurTypeId !== treeNode.ID){
+            me.gljCurTypeId = treeNode.ID;
+            if(typeof me.currentCache === 'undefined'){
+                if (re.parentNodeIds["_pNodeId_" + treeNode.ID]) {
+                    me.currentOprParent = 1;
+                    me.currentCache = me.getParentCache(re.parentNodeIds["_pNodeId_" + treeNode.ID]);
+                } else {
+                    me.currentCache = me.getCache();
+                }
+                me.preCache = me.currentCache;
+            }
+            else{
+                me.preCache = me.currentCache;
+                if (re.parentNodeIds["_pNodeId_" + treeNode.ID]) {
+                    me.currentOprParent = 1;
+                    me.currentCache = me.getParentCache(re.parentNodeIds["_pNodeId_" + treeNode.ID]);
+                } else {
+                    me.currentCache = me.getCache();
+                }
+            }
+            //切换分类树时,记住当前分类的选择
+            me.setComponentChecked(me.workBook.getSheet(0));
+            me.showGljItems(me.showGljList, gljTypeId);
+        }
+        /*sheetOpr.cleanSheet(that.workBook.getSheet(0), that.setting, 5);
+        that.workBook.getSheet(0).getRange(-1, 0 , -1, 1, GC.Spread.Sheets.SheetArea.viewport).locked(true);
+        that.workBook.getSheet(0).getRange(-1, 4 , -1, 1, GC.Spread.Sheets.SheetArea.viewport).locked(true);
+        re.workBook.getSheet(0).getRange(-1, 6 , -1, 1, GC.Spread.Sheets.SheetArea.viewport).locked(true);*/
+        //that.workBook.getSheet(0).options.isProtected = true;
+
+        //sheetOpr.lockCodeCells(re.workBook.getSheet(0), re.currentCache.length);
+        //re.workBook.getSheet(0).setRowCount(re.currentCache.length);
+    }
+}

ファイルの差分が大きいため隠しています
+ 1040 - 0
web/building_saas/complementary_glj_lib/js/glj.js


+ 466 - 0
web/building_saas/complementary_glj_lib/js/gljComponent.js

@@ -0,0 +1,466 @@
+/**
+ * Created by Zhong on 2017/8/15.
+ */
+
+let gljComponentOprObj = {
+    workBook: null,
+    setting: {
+        owner: "gljComponent",
+        header:[
+            {headerName:"编码",headerWidth:80,dataCode:"code", dataType: "String", formatter: "@", hAlign: "left", vAlign: "center"},
+            {headerName:"名称",headerWidth:120,dataCode:"name", dataType: "String", hAlign: "left", vAlign: "center"},
+            {headerName:"计量单位",headerWidth:80,dataCode:"unit", dataType: "String", hAlign: "center", vAlign: "center"},
+            {headerName:"单价",headerWidth:80,dataCode:"basePrice", dataType: "Number", formatter: "0.00", hAlign: "right", vAlign: "center"},
+            {headerName:"消耗量",headerWidth:80,dataCode:"consumeAmt", dataType: "Number", formatter: "0.000", hAlign: "right", vAlign: "center"}
+        ],
+        view: {
+            lockedCells:[1, 2, 3]
+        }
+    },
+    buildSheet: function(container) {
+        let me = gljComponentOprObj;
+        me.workBook = sheetOpr.buildSheet(container, me.setting, 30, me);
+        me.workBook.getSheet(0).setColumnWidth(0, 20, GC.Spread.Sheets.SheetArea.rowHeader);
+        me.workBook.getSheet(0).setFormatter(-1, 0, "@", GC.Spread.Sheets.SheetArea.viewport);
+        me.workBook.getSheet(0).options.isProtected = true;
+        sheetOpr.cleanSheet(me.workBook.getSheet(0), me.setting, -1);
+
+        me.onContextmenuOpr();
+        /*me.gljComponentDelOpr();
+        me.workBook.bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting);
+        me.workBook.bind(GC.Spread.Sheets.Events.ClipboardPasted, me.onClipboardPasted);
+        me.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.EditStarting, me.onCellEditStart);
+        me.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.EditEnded, me.onCellEditEnd);*/
+
+    },
+    getRowData: function (sheet, row, setting) {
+        let rst = {};
+        for(let i = 0; i < setting.header.length; i++){
+            rst[setting.header[i].dataCode] = sheet.getValue(row, i);
+        }
+        return rst;
+    },
+    getComponent: function (sheet, rowCount) {
+        let component = [];
+        for(let row = 0; row < rowCount; row++){
+            let obj = {};
+            obj.consumeAmt = sheet.getValue(row, 4);
+            obj.ID = sheet.getTag(row, 0);
+            component.push(obj);
+        }
+        return component;
+    },
+    onContextmenuOpr: function () {
+        let me = gljComponentOprObj, that = repositoryGljObj, co = componentOprObj;
+        $.contextMenu({
+            selector: '#gljComponentSheet',
+            build: function($triggerElement, e){
+                //控制允许右键菜单在哪个位置出现
+                let clientX = e.originalEvent.clientX,
+                    clientY = e.originalEvent.clientY;
+                let sheet = me.workBook.getSheet(0);
+                let offset = $("#gljComponentSheet").offset(),
+                    x = clientX - offset.left,
+                    y = clientY - offset.top;
+                let target = sheet.hitTest(x, y);
+                if(target.hitTestType === 3 && typeof target.row !== 'undefined' && typeof target.col !== 'undefined'){//在表格内
+                    sheet.setActiveCell(target.row, target.col);
+                    //控制按钮是否可用
+                    let insertDis = false,
+                        delDis = false;
+                    if(me.isLocked){
+                        insertDis = true;
+                        delDis = true;
+                    }
+                    if(typeof that.currentComponent !== 'undefined' && target.row >= that.currentComponent.length){//右键定位在有组成物的行,删除键才显示可用
+                        delDis = true;
+                    }
+                    return {
+                        callback: function(){},
+                        items: {
+                            "insert": {name: "插入", disabled: insertDis, callback: function (key, opt) {
+                                //默认radio所有工料机
+                                co.initRadio();
+                                //默认点击树根节点
+                                if(co.rootNode){
+                                    co.treeObj.selectNode(co.rootNode);
+                                    componentTypeTreeOprObj.onClick(null, 'componentTree', co.rootNode);
+                                }
+                                //弹出窗口
+                                $('#componentBtn').click();
+                            }},
+                            "delete": {name: "删除", disabled: delDis}
+                        }
+                    };
+                }
+                else{
+                    return false;
+                }
+            }
+        });
+    },
+    gljComponentDelOpr: function () {
+        let me = gljComponentOprObj, that = repositoryGljObj, updateArr = [], removeArr = [], isUpdate = false, updateBasePrc= [];
+        me.workBook.commandManager().register('gljComponentDel', function () {
+            let sels = me.workBook.getSheet(0).getSelections();
+            if(sels.length > 0 && that.currentComponent.length > 0){
+                let component = that.currentGlj.component;
+                for(let i = 0; i < sels.length > 0; i++){
+                    if(sels[i].colCount === me.setting.header.length){//可删除
+                        for(let j = 0; j < sels[i].rowCount; j++){
+                            if(sels[i].row + j < that.currentComponent.length){
+                                removeArr.push(that.currentComponent[sels[i].row + j].ID);
+
+                            }
+                        }
+                    }
+                    else if(sels[i].col === 0){
+                            //编码不可为空
+                            alert("编码不可为空!");
+
+                    }
+                    else if(sels[i].col === 4){//消耗量修改为0
+                        if(sels[i].row === -1){//全修改
+                           for(let j = 0; j < that.currentComponent.length; j++){
+                               isUpdate = true;
+                               that.currentComponent[j].consumeAmt = 0;
+                               for(let k = 0; k < component.length; k++){
+                                   if(component[k].ID === that.currentComponent[j].ID){
+                                       component[k].consumeAmt = 0;
+                                       break;
+                                   }
+                               }
+                           }
+                        }
+                        else{//部分修改
+                            for(let j = 0; j < sels[i].rowCount; j++){
+                                if(sels[i].row + j < that.currentComponent.length){
+                                    isUpdate = true;
+                                    that.currentComponent[sels[i].row + j].consumeAmt = 0;
+                                    for(let k = 0; k < component.length; k++){
+                                        if(component[k].ID === that.currentComponent[sels[i].row + j].ID){
+                                            component[k].consumeAmt = 0;
+                                            break;
+                                        }
+                                    }
+
+                                }
+                            }
+                        }
+                    }
+                }
+                if(removeArr.length > 0 || isUpdate){
+                    for(let i = 0; i < removeArr.length; i++){
+                        for(let j = 0; j < that.currentComponent.length; j++){
+                            if(that.currentComponent[j].ID === removeArr[i]){
+                                that.currentComponent.splice(j--, 1);
+                            }
+                        }
+                        for(let j = 0; j < component.length; j++){
+                            if(component[j].ID === removeArr[i]){
+                                component.splice(j--, 1);
+                            }
+                        }
+                    }
+                    //重新计算工料机
+                    let gljBasePrc = me.reCalGljBasePrc(that.currentComponent);
+                    if(gljBasePrc !== that.currentGlj.basePrice){
+                        that.currentGlj.basePrice = gljBasePrc;
+                        that.reshowGljBasePrc(that.currentGlj);
+                        updateBasePrc.push({gljId: that.currentGlj.ID, gljType: that.currentGlj.gljType, basePrice: that.currentGlj.basePrice});
+                    }
+                    updateArr.push(that.currentGlj);
+                    me.updateComponent(updateArr);
+                    if(updateBasePrc.length > 0){
+                        that.updateRationBasePrcRq(updateBasePrc);
+                    }
+                }
+            }
+        });
+        me.workBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false);
+        me.workBook.commandManager().setShortcutKey('gljComponentDel', GC.Spread.Commands.Key.del, false, false, false, false);
+    },
+    onCellEditStart: function(sender, args) {
+        let me = gljComponentOprObj, that = repositoryGljObj;
+        let rObj = me.getRowData(args.sheet, args.row, me.setting);
+        me.currentEditingComponent = rObj;
+    },
+    onCellEditEnd: function (sender, args) {
+        let me = gljComponentOprObj, that = repositoryGljObj, updateBasePrc = [];
+        let gljList = that.gljList, updateArr = [], materialComponent = [202, 203, 204], machineComponent = [302, 303];
+        if(args.editingText !== me.currentEditingComponent.code){
+            if(args.col === 0 && args.editingText && args.editingText.trim().length > 0){
+                let component = that.currentGlj.component, hasCode = false;
+                for(let i = 0; i < gljList.length; i++){
+                    if(gljList[i].code === args.editingText){//有效的组成物
+                        hasCode = true;
+                        if((materialComponent.indexOf(that.currentGlj.gljType) !== -1 && gljList[i].gljType === 201)
+                            || (that.currentGlj.gljType === 301 && machineComponent.indexOf(gljList[i].gljType) !== -1 )){//普通材料
+                            //是否与原有组成物不同
+                            let isExist = false;
+                            for(let j = 0; j < component.length; j++){
+                                if(component[j].ID === gljList[i].ID){
+                                    isExist = true;
+                                    break;
+                                }
+                            }
+                            if(!isExist){
+                                let rObj = {};
+                                rObj.ID = gljList[i].ID;
+                                //rObj.basePrice = gljList[i].basePrice;
+                                if(typeof that.currentComponent[args.row] !== 'undefined'){
+                                    rObj.consumeAmt = that.currentComponent[args.row].consumeAmt;
+                                    let index;
+                                    for(let j = 0; j < component.length; j++){
+                                        if(component[j].ID === that.currentComponent[args.row].ID){
+                                            index = j;
+                                            break;
+                                        }
+                                    }
+                                    component.splice(index, 1);
+                                    component.splice(index, 0, rObj);
+                                    //计算工料机单价
+                                    let gljBasePrc = me.reCalGljBasePrc(that.getCurrentComponent(component));
+                                    if(gljBasePrc !== that.currentGlj.basePrice){
+                                        that.currentGlj.basePrice = gljBasePrc;
+                                        that.reshowGljBasePrc(that.currentGlj);
+                                        //工料机单价改变,重算引用了该工料机的定额单价
+                                        updateBasePrc.push({gljId: that.currentGlj.ID, gljType: that.currentGlj.gljType, basePrice: that.currentGlj.basePrice});
+                                    }
+                                    updateArr.push(that.currentGlj);
+                                }
+                                else{
+                                    rObj.consumeAmt = 0;
+                                    component.push(rObj);
+                                    //计算工料机单价
+                                    let gljBasePrc = me.reCalGljBasePrc(that.getCurrentComponent(component));
+                                    if(gljBasePrc !== that.currentGlj.basePrice){
+                                        that.currentGlj.basePrice = gljBasePrc;
+                                        that.reshowGljBasePrc(that.currentGlj);
+                                        //工料机单价改变,重算引用了该工料机的定额单价
+                                        updateBasePrc.push({gljId: that.currentGlj.ID, gljType: that.currentGlj.gljType, basePrice: that.currentGlj.basePrice});
+                                    }
+                                    updateArr.push(that.currentGlj);
+                                }
+                                break;
+                            }
+                            else{
+                                //已存在
+                                alert("已存在!");
+                                args.sheet.setValue(args.row, args.col, me.currentEditingComponent[me.setting.header[args.col].dataCode] ?
+                                    me.currentEditingComponent[me.setting.header[args.col].dataCode]: '');
+                            }
+
+                        }
+                        else{
+                            if(materialComponent.indexOf(that.currentGlj.gljType) === 1){
+                                alert("该组成物只能是普通材料!");
+                            }
+                            else if(that.currentGlj.gljType === 301){
+                                alert("该组成物只能是机械组成物或机上人工!")
+                            }
+                            args.sheet.setValue(args.row, args.col, me.currentEditingComponent[me.setting.header[args.col].dataCode] ?
+                                me.currentEditingComponent[me.setting.header[args.col].dataCode]: '');
+                            //无效
+                        }
+                    }
+                }
+                if(!hasCode){
+                    alert("不存在此工料机,请先添加!");
+                    args.sheet.setValue(args.row, args.col, me.currentEditingComponent[me.setting.header[args.col].dataCode] ?
+                        me.currentEditingComponent[me.setting.header[args.col].dataCode] : '');
+                    //不存在
+                }
+            }
+            else if(args.col === 4 && me.currentEditingComponent.code && args.editingText && args.editingText.trim().length > 0){//消耗量
+                let consumeAmt = parseFloat(args.editingText);
+                if(!isNaN(consumeAmt) && consumeAmt !== me.currentEditingComponent.consumeAmt){
+                    let roundCons = me.round(consumeAmt, 3);
+                    let component = that.currentGlj.component;
+                    for(let i = 0; i < component.length; i++){
+                        if(component[i].ID === that.currentComponent[args.row].ID){
+                            component[i].consumeAmt = roundCons;
+                        }
+                    }
+                    that.currentComponent[args.row].consumeAmt = roundCons;
+                    //计算工料机单价
+                    let gljBasePrc = me.reCalGljBasePrc(that.currentComponent);
+                    if(gljBasePrc !== that.currentGlj.basePrice){
+                        that.currentGlj.basePrice = gljBasePrc;
+                        that.reshowGljBasePrc(that.currentGlj);
+                        //工料机单价改变,重算引用了该工料机的定额单价
+                        updateBasePrc.push({gljId: that.currentGlj.ID, gljType: that.currentGlj.gljType, basePrice: that.currentGlj.basePrice});
+                    }
+                    updateArr.push(that.currentGlj);
+                }
+                else{
+                    //只能输入数值
+                    args.sheet.setValue(args.row, args.col, me.currentEditingComponent[me.setting.header[args.col].dataCode] ?
+                        me.currentEditingComponent[me.setting.header[args.col].dataCode]: 0);
+
+                }
+            }
+            else{
+                args.sheet.setValue(args.row, args.col, '');
+            }
+        }
+        if(updateArr.length > 0){
+            me.updateComponent(updateArr);
+            if(updateBasePrc.length > 0){
+                that.updateRationBasePrcRq(updateBasePrc)
+            }
+        }
+    },
+    onClipboardPasting: function (sender, info) {
+        let me = gljComponentOprObj;
+        let maxCol = info.cellRange.col + info.cellRange.colCount - 1;
+        //复制的列数超过正确的列数,不可复制
+        if(maxCol >= me.setting.header.length){
+            args.cancel = true;
+        }
+    },
+    onClipboardPasted: function (sender, info) {
+        let me = gljComponentOprObj, that = repositoryGljObj, updateArr = [] ,materialComponent = [202, 203, 204], machineComponent = [302, 303],
+            component = that.currentGlj.component, newComponent = [], concatComponent = [], isChange = false, updateBasePrc = [];
+        let items = sheetOpr.analyzePasteData(me.setting, info);
+        let gljCache = that.gljList;
+        if(info.cellRange.col === 0){
+            for(let i = 0; i < items.length; i++){
+                for(let j = 0; j < gljCache.length; j++){
+                    if(items[i].code === gljCache[j].code){
+                        if((materialComponent.indexOf(that.currentGlj.gljType) !== -1 && gljCache[j].gljType === 201)
+                            || (that.currentGlj.gljType === 301 && machineComponent.indexOf(gljCache[j].gljType) !== -1 )){
+                            //是否与原有组成物不同
+                            let isExist = false;
+                            for(let k = 0; k < component.length; k++){
+                                if(component[k].ID === gljCache[j].ID){
+                                    isExist = true;
+                                    me.workBook.getSheet(0).setValue(info.cellRange.row + i, info.cellRange.col,
+                                        typeof that.currentComponent[info.cellRange.row + i] !== 'undefined'? that.currentComponent[info.cellRange.row + i].code : '');
+                                    break;
+                                }
+                            }
+                            if(!isExist){
+                                isChange = true;
+                                let obj = {};
+                                obj.ID = gljCache[j].ID;
+                                if(typeof that.currentComponent[info.cellRange.row + i] !== 'undefined'){//更新
+                                    obj.consumeAmt = that.currentComponent[info.cellRange.row + i].consumeAmt;
+                                    let index;
+                                    for(let k = 0; k < component.length; k++){
+                                        if(that.currentComponent[info.cellRange.row + i].ID === component[k].ID){
+                                            index = k;
+                                            break;
+                                        }
+                                    }
+                                    component.splice(index, 1);
+                                    component.splice(index, 0, obj);
+                                }
+                                else{//新增
+                                    obj.consumeAmt = 0;
+                                    component.push(obj);
+                                }
+                                break;
+                            }
+
+                        }
+                        else{
+                            me.workBook.getSheet(0).setValue(info.cellRange.row + i, info.cellRange.col,
+                            typeof that.currentComponent[info.cellRange.row + i] !== 'undefined'? that.currentComponent[info.cellRange.row + i].code : '');
+
+                        }
+
+                    }
+                    else{
+                        me.workBook.getSheet(0).setValue(info.cellRange.row + i, info.cellRange.col,
+                            typeof that.currentComponent[info.cellRange.row + i] !== 'undefined'? that.currentComponent[info.cellRange.row + i].code : '');
+                    }
+                }
+            }
+            if(isChange){
+                //计算工料机单价
+                let gljBasePrc = me.reCalGljBasePrc(that.getCurrentComponent(component));
+                if(gljBasePrc !== that.currentGlj.basePrice){
+                    that.currentGlj.basePrice = gljBasePrc;
+                    that.reshowGljBasePrc(that.currentGlj);
+                    updateBasePrc.push({gljId: that.currentGlj.ID, gljType: that.currentGlj.gljType, basePrice: that.currentGlj.basePrice});
+                }
+                updateArr.push(that.currentGlj);
+            }
+        }
+        else if(info.cellRange.col === 4){
+            let items = sheetOpr.analyzePasteData(me.setting, info);
+            let row = info.cellRange.row;
+            for(let i = 0; i < items.length; i++){
+                if(row + i < that.currentComponent.length){
+                    let currentObj = that.currentComponent[row + i];
+                    if(items[i].consumeAmt.trim().length > 0 && items[i].consumeAmt !== currentObj.consumeAmt){
+                        let roundCons = me.round(items[i].consumeAmt, 3);
+                        isChange = true;
+                        currentObj.consumeAmt = roundCons;
+                        for(let j = 0; j < component.length; j++){
+                            if(component[j].ID === currentObj.ID){
+                                component[j].consumeAmt = currentObj.consumeAmt;
+                                break;
+                            }
+                        }
+                    }
+                    else{
+                        me.workBook.getSheet(0).setValue(row + i, info.cellRange.col, currentObj.consumeAmt);
+                    }
+                }
+                else{
+                    me.workBook.getSheet(0).setValue(row + i, info.cellRange.col, '');
+                }
+            }
+            if(isChange){
+                //计算工料机单价
+                let gljBasePrc = me.reCalGljBasePrc(that.currentComponent);
+                if(gljBasePrc !== that.currentGlj.basePrice){
+                    that.currentGlj.basePrice = gljBasePrc;
+                    that.reshowGljBasePrc(that.currentGlj);
+                    updateBasePrc.push({gljId: that.currentGlj.ID, gljType: that.currentGlj.gljType, basePrice: that.currentGlj.basePrice});
+                }
+                updateArr.push(that.currentGlj);
+            }
+        }
+        if(updateArr.length > 0){
+            me.updateComponent(updateArr);
+            if(updateBasePrc.length > 0){
+                that.updateRationBasePrcRq(updateBasePrc);
+            }
+        }
+    },
+    updateComponent: function (updateArr) {
+        let me = gljComponentOprObj, that = repositoryGljObj;
+        $.ajax({
+            type: 'post',
+            url: 'api/updateComponent',
+            data: {libId: pageOprObj.gljLibId, updateArr: updateArr, oprtor: userAccount},
+            dataType: 'json',
+            success: function (result) {
+                if(result.data.length > 0){
+                    if(result.data[0]){
+                        that.currentComponent =  that.getCurrentComponent(result.data[0].component);
+                        sheetOpr.cleanSheet(me.workBook.getSheet(0), me.setting, -1);
+                        sheetOpr.showData(me.workBook.getSheet(0), me.setting, that.currentComponent);
+                    }
+                }
+            }
+        })
+    },
+    round: function (v, e) {
+        let t=1;
+        for(;e>0;t*=10,e--);
+        for(;e<0;t/=10,e++);
+        return Math.round(v*t)/t;
+    },
+    reCalGljBasePrc: function (component) {
+        let me = gljComponentOprObj, gljBasePrc = 0;
+        for(let i = 0; i < component.length; i++){
+            let roundBasePrc = me.round(component[i].basePrice, 2);
+            gljBasePrc += me.round(roundBasePrc * component[i].consumeAmt, 2);
+        }
+        return gljBasePrc;
+    }
+};

+ 354 - 0
web/building_saas/complementary_glj_lib/js/sheetOpr.js

@@ -0,0 +1,354 @@
+/**
+ * Created by Zhong on 2017/8/24.
+ */
+let sheetOpr = {
+    createSpread: function(container, SheetCount){
+        var me = this;
+        var spreadBook = new GC.Spread.Sheets.Workbook(container, { sheetCount: SheetCount });
+        spreadBook.options.allowCopyPasteExcelStyle = false;
+        spreadBook.options.tabStripVisible = false;
+        spreadBook.options.showHorizontalScrollbar = false;
+        return spreadBook;
+    },
+
+    initSheet: function(sheet, setting, rowCount) {
+        var me = this;
+        var spreadNS = GC.Spread.Sheets;
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        sheet.setRowCount(1, spreadNS.SheetArea.colHeader);
+        sheet.setColumnCount(setting.header.length, spreadNS.SheetArea.viewport);
+        sheet.options.colHeaderAutoTextIndex = 1;
+        sheet.options.colHeaderAutoText = spreadNS.HeaderAutoText.numbers;
+        sheet.showRowOutline(false);
+        me.buildHeader(sheet, setting);
+        if (rowCount > 0) sheet.setRowCount(rowCount);
+        sheet.resumeEvent();
+        sheet.resumePaint();
+    },
+
+    buildSheet: function(container, setting, rowCount) {
+        var me = this;
+        var spreadBook = new GC.Spread.Sheets.Workbook(container, { sheetCount: 1 });
+        spreadBook.options.tabStripVisible = false;
+        spreadBook.options.showHorizontalScrollbar = false;
+        spreadBook.options.scrollbarMaxAlign = true;
+        spreadBook.options.allowCopyPasteExcelStyle = false;
+        spreadBook.options.allowExtendPasteRange = true;
+        var spreadNS = GC.Spread.Sheets;
+        var sheet = spreadBook.getSheet(0);
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        //Set rowHeader count and columnHeader count.
+        sheet.setRowCount(1, spreadNS.SheetArea.colHeader);
+        sheet.setColumnCount(setting.header.length, spreadNS.SheetArea.viewport);
+        sheet.options.colHeaderAutoTextIndex = 1;
+        sheet.options.colHeaderAutoText = spreadNS.HeaderAutoText.numbers;
+        sheet.showRowOutline(false);
+        //setup column header
+        me.buildHeader(sheet, setting);
+        //setup cells
+        if (rowCount > 0) sheet.setRowCount(rowCount);
+        sheet.resumeEvent();
+        sheet.resumePaint();
+        return spreadBook;
+    },
+    buildHeader: function(sheet, setting){
+        var me = this, ch = GC.Spread.Sheets.SheetArea.colHeader;
+        for (var i = 0; i < setting.header.length; i++) {
+            sheet.setValue(0, i, setting.header[i].headerName, ch);
+            sheet.setColumnWidth(i, setting.header[i].headerWidth?setting.header[i].headerWidth:100);
+        }
+    },
+    cleanSheet: function(sheet, setting, rowCount) {
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        sheet.clear(-1, 0, -1, setting.header.length, GC.Spread.Sheets.SheetArea.viewport, GC.Spread.Sheets.StorageType.data);
+        if (rowCount > 0) sheet.setRowCount(rowCount);
+        sheet.clearSelection();
+        sheet.resumeEvent();
+        sheet.resumePaint();
+    },
+    setAreaAlign: function(area, hAlign, vAlign){
+        if (!(hAlign) || hAlign === "left") {
+            area.hAlign(GC.Spread.Sheets.HorizontalAlign.left);
+        } else if (hAlign === "right") {
+            area.hAlign(GC.Spread.Sheets.HorizontalAlign.right);
+        } else if (hAlign === "center") {
+            area.hAlign(GC.Spread.Sheets.HorizontalAlign.center);
+        } else {
+            area.hAlign(GC.Spread.Sheets.HorizontalAlign.left);
+        }
+        if (!(vAlign) || vAlign === "center") {
+            area.vAlign(GC.Spread.Sheets.VerticalAlign.center);
+        } else if (vAlign === "top") {
+            area.vAlign(GC.Spread.Sheets.VerticalAlign.top);
+        } else if (vAlign === "bottom") {
+            area.vAlign(GC.Spread.Sheets.VerticalAlign.bottom);
+        } else {
+            area.vAlign(GC.Spread.Sheets.VerticalAlign.center);
+        }
+    },
+    showData: function(sheet, setting, data, distTypeTree) {
+        var me = this, ch = GC.Spread.Sheets.SheetArea.viewport;
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        let checkBoxType = new GC.Spread.Sheets.CellTypes.CheckBox();
+        if(typeof setting.owner !== 'undefined' && setting.owner === 'gljComponent'){
+            sheet.setRowCount(data.length + 5);
+        }
+        else{
+            sheet.setRowCount(typeof repositoryGljObj !== 'undefined' && repositoryGljObj.currentOprParent === 1 ? data.length : data.length + 10);
+        }
+        if(data.length === 0){
+            for(let i = 0; i < sheet.getRowCount(); i++){
+                sheet.getCell(i, 4, GC.Spread.Sheets.SheetArea.viewport).locked(false);
+            }
+        }
+        for (var col = 0; col < setting.header.length; col++) {
+            var hAlign = "left", vAlign = "center";
+            if (setting.header[col].hAlign) {
+                hAlign = setting.header[col].hAlign;
+            } else if (setting.header[col].dataType !== "String"){
+                hAlign = "right";
+            }
+            vAlign = setting.header[col].vAlign?setting.header[col].vAlign:vAlign;
+            me.setAreaAlign(sheet.getRange(-1, col, -1, 1), hAlign, vAlign);
+            if (setting.header[col].formatter) {
+                sheet.setFormatter(-1, col, setting.header[col].formatter, GC.Spread.Sheets.SheetArea.viewport);
+            }
+            for (var row = 0; row < data.length; row++) {
+                //var cell = sheet.getCell(row, col, GC.Spread.Sheets.SheetArea.viewport);
+                if(setting.header[col].dataCode === 'gljType' && data[row].gljType){
+                    if(typeof repositoryGljObj !== 'undefined' && typeof repositoryGljObj.allowComponent !== 'undefined' && repositoryGljObj.allowComponent.indexOf(data[row].gljType) !== -1){
+                        sheet.getCell(row, 4, GC.Spread.Sheets.SheetArea.viewport).locked(true);
+                    }
+                    else if(typeof repositoryGljObj !== 'undefined' && typeof repositoryGljObj.allowComponent !== 'undefined' && repositoryGljObj.allowComponent.indexOf(data[row].gljType) === -1){
+                        sheet.getCell(row, 4, GC.Spread.Sheets.SheetArea.viewport).locked(false);
+                    }
+                    let distTypeVal =  distTypeTree.distTypes[distTypeTree.prefix + data[row].gljType].data.fullName;
+                    sheet.setValue(row, col, distTypeVal, ch);
+                }
+                else {
+                    sheet.setValue(row, col, data[row][setting.header[col].dataCode], ch);
+                    sheet.setTag(row, 0, data[row].ID, ch);
+                }
+                //复选框
+                if(setting.header[col].dataCode === 'isComplementary'){
+                    sheet.setCellType(row, col, checkBoxType);
+                    sheet.getCell(row, col).value(1);
+                }
+                //新增组成物表,选择
+                if(setting.header[col].dataCode === 'select'){
+                    sheet.setCellType(row, col, checkBoxType);
+                    sheet.getCell(row, col, GC.Spread.Sheets.SheetArea.viewport).locked(false);
+                    if(data[row].isChecked === true){
+                        console.log(1);
+                        sheet.getCell(row, col).value(1);
+                    }
+                    else if(data[row].isChecked === false){
+                        console.log(2);
+                        sheet.getCell(row, col).value('');
+                    }
+                }
+            }
+            for(let i = data.length; i < sheet.getRowCount(); i++){
+                sheet.setCellType(i, 6, null);
+                sheet.getCell(i, 4, GC.Spread.Sheets.SheetArea.viewport).locked(false);
+            }
+        }
+        sheet.resumeEvent();
+        sheet.resumePaint();
+        //me.shieldAllCells(sheet);
+    },
+    analyzePasteData: function(setting, pastedInfo) {
+        var rst = [], propId = pastedInfo.cellRange.col, preStrIdx = 0, itemObj = {};
+        for (var i = 0; i < pastedInfo.pasteData.text.length; i++) {
+            if (pastedInfo.pasteData.text[i] === "\n") {
+                propId = pastedInfo.cellRange.col;
+                preStrIdx = i + 1;
+                rst.push(itemObj);
+                if (i < pastedInfo.pasteData.text.length - 1) {
+                    itemObj = {};
+                }
+            } else if (pastedInfo.pasteData.text[i] === "\t" || pastedInfo.pasteData.text[i] === "\r") {
+                itemObj[setting.header[propId].dataCode] = pastedInfo.pasteData.text.slice(preStrIdx, i);
+                propId++;
+                preStrIdx = i + 1;
+                //if the last copied-cell were empty, should check whether the end of text
+                if (i == pastedInfo.pasteData.text.length - 1) {
+                    itemObj[setting.header[propId].dataCode] = pastedInfo.pasteData.text.slice(preStrIdx);
+                    rst.push(itemObj);
+                }
+            } else if (i == pastedInfo.pasteData.text.length - 1) {
+                itemObj[setting.header[propId].dataCode] = pastedInfo.pasteData.text.slice(preStrIdx);
+                rst.push(itemObj);
+            }
+        }
+        return rst;
+    },
+    combineRowData: function(sheet, setting, row, repositoryGljObj) {
+        let me = this;
+        var rst = {};
+        let comboBoxCellType = sheet.getCellType(row, 5);
+        let items = comboBoxCellType.items();
+        for (var col = 0; col < setting.header.length; col++) {
+            if(setting.header[col].dataCode === 'gljType'){
+                items.forEach(function(item){
+                    if(sheet.getValue(row, col) === item.text){
+                        rst[setting.header[col].dataCode] = item.value;
+                        if(repositoryGljObj){
+                            rst.shortName = repositoryGljObj.distTypeTree.distTypes[repositoryGljObj.distTypeTree.prefix + item.value].data.shortName;
+                        }
+                    }
+                });
+            }
+            else if (setting.header[col].dataCode === 'code'){
+                if(repositoryGljObj){
+                    let gljList = repositoryGljObj.gljList,
+                        orgCode = repositoryGljObj.orgCode,
+                        isExist = false;
+                    for(let i=0; i< gljList.length; i++){
+                        if(gljList[i].code === sheet.getValue(row, col) && sheet.getValue(row, col)!== orgCode){
+                            me.lockAllCells(sheet);
+                            $('#alertText').text("输入的编号已存在,请重新输入!");
+                            $('#codeAlertBtn').click();
+                            $('#codAleConfBtn').click(function () {
+                                // me.reLockSomeCodes(sheet, 0, repositoryGljObj.currentCache.length);
+                                me.unLockAllCells(sheet);
+                                me.reLockSomeCodes(sheet, 0, repositoryGljObj.currentCache.length);
+                                sheet.setValue(row, 0, orgCode);
+                                sheet.setActiveCell(row, 0);
+                            });
+                            $('#codAleClose').click(function () {
+                                //me.reLockSomeCodes(sheet, 0, repositoryGljObj.currentCache.length);
+                                me.unLockAllCells(sheet);
+                                me.reLockSomeCodes(sheet, 0, repositoryGljObj.currentCache.length);
+                                sheet.setValue(row, 0, orgCode);
+                                sheet.setActiveCell(row, 0);
+                            });
+                            // sheet.setValue(row, col, orgCode);
+                            isExist = true
+                        }
+                    }
+                    if(!isExist){
+                        rst[setting.header[col].dataCode] = sheet.getValue(row, col);
+                    }
+                }
+                else{
+                    rst[setting.header[col].dataCode] = sheet.getValue(row, col);
+                }
+            }
+            else{
+                rst[setting.header[col].dataCode] = sheet.getValue(row, col);
+            }
+        }
+        return rst;
+    },
+    combineRationRowData: function(sheet, setting, row) {
+        var rst = {};
+        for (var col = 0; col < setting.header.length; col++) {
+            rst[setting.header[col].dataCode] = sheet.getValue(row, col);
+        }
+        return rst;
+    },
+    shieldAllCells: function(sheet) {
+        sheet.options.isProtected = true;
+    },
+    unShieldAllCells: function(sheet) {
+        sheet.options.isProtected = false;
+    },
+    reLockSomeCodes: function (sheet, beginRow, endRow) {
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        let defaultStyle = new GC.Spread.Sheets.Style();
+        defaultStyle.locked = false;
+        sheet.setDefaultStyle(defaultStyle, GC.Spread.Sheets.SheetArea.viewport);
+        let unLockStyle = new GC.Spread.Sheets.Style();
+        unLockStyle.locked = false;
+        let lockStyle = new GC.Spread.Sheets.Style();
+        lockStyle.locked = true;
+        for(let row = beginRow; row < endRow; row++){
+            sheet.setStyle(row, 0, lockStyle);
+        }
+        for(let row = endRow; row < sheet.getRowCount(); row++){
+            sheet.setStyle(row, 0, unLockStyle);
+        }
+        sheet.options.isProtected = true;
+        sheet.resumePaint();
+        sheet.resumeEvent();
+    },
+    unLockAllCells: function (sheet) {
+        let defaultStyle = new GC.Spread.Sheets.Style();
+        defaultStyle.locked = false;
+        sheet.setDefaultStyle(defaultStyle, GC.Spread.Sheets.SheetArea.viewport);
+        sheet.setStyle(-1, 0, defaultStyle);
+        sheet.options.isProtected = false;
+    },
+    lockAllCells: function (sheet) {
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        let defaultStyle = new GC.Spread.Sheets.Style();
+        defaultStyle.locked = true;
+        sheet.setDefaultStyle(defaultStyle, GC.Spread.Sheets.SheetArea.viewport);
+        for(let i = 0; i < sheet.getRowCount(); i++){
+            sheet.setStyle(i, 0, defaultStyle);
+        }
+        sheet.options.isProtected = true;
+        sheet.resumePaint();
+        sheet.resumeEvent();
+    },
+    lockSomeCodes: function (sheet, beginRow, endRow) {
+        let defaultStyle = new GC.Spread.Sheets.Style();
+        defaultStyle.locked = false;
+        sheet.setDefaultStyle(defaultStyle, GC.Spread.Sheets.SheetArea.viewport);
+        let style = new  GC.Spread.Sheets.Style();
+        style.locked = true;
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        for(let i = beginRow; i < endRow; i++){
+            sheet.setStyle(i, 0, style);
+        }
+        sheet.options.isProtected = true;
+        sheet.resumePaint();
+        sheet.resumeEvent();
+    },
+    lockCodeCells: function (sheet, rowCount) {
+        let sheetRowCount = sheet.getRowCount();
+        let defaultStyle = new GC.Spread.Sheets.Style();
+        defaultStyle.locked = false;
+        sheet.setDefaultStyle(defaultStyle, GC.Spread.Sheets.SheetArea.viewport);
+        let style = new GC.Spread.Sheets.Style();
+        style.locked = true;
+        sheet.setStyle(-1, 0, style);
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        for(let i =rowCount; i<sheetRowCount; i++){
+            sheet.setStyle(i, -1, style);
+        }
+        sheet.options.isProtected = true;
+        sheet.resumePaint();
+        sheet.resumeEvent();
+    },
+    lockCells: function(sheet, setting){
+        if (setting && setting.view.lockColumns && setting.view.lockColumns.length > 0) {
+            sheet.options.isProtected = true;
+            sheet.getRange(-1, 0, -1, setting.header.length, GC.Spread.Sheets.SheetArea.viewport).locked(false);
+            for (var i = 0; i < setting.view.lockColumns.length; i++) {
+                sheet.getRange(-1,setting.view.lockColumns[i] , -1, 1, GC.Spread.Sheets.SheetArea.viewport).locked(true);
+            }
+        }
+    },
+    chkIfEmpty: function(rObj, setting) {
+        var rst = true;
+        if (rObj) {
+            for (var i = 0; i < setting.header.length; i++) {
+                if (rObj[setting.header[i].dataCode]) {
+                    rst = false;
+                    break;
+                }
+            }
+        }
+        return rst;
+    }
+}

+ 13 - 5
web/building_saas/pm/html/project-management.html

@@ -67,13 +67,21 @@
                 <li class="nav-item dropdown">
                     <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">工具</a>
                     <div class="dropdown-menu">
-                        <a class="dropdown-item" href="#">Action</a>
-                        <a class="dropdown-item" href="#">Another action</a>
-                        <a class="dropdown-item" href="#">Something else here</a>
+                        <a class="dropdown-item" href="#">定额库编辑器</a>
+                        <a class="dropdown-item" href="/complementartGlj">工料机库编辑器</a>
                     </div>
                 </li>
-                <li class="nav-item">
-                    <a class="nav-link" href="#" aria-haspopup="true" aria-expanded="false">帮助</a>
+                <li class="nav-item dropdown">
+                    <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-question-circle-o"></i> 帮助</a>
+                    <div class="dropdown-menu">
+                        <a class="dropdown-item" href="#">帮助</a>
+                        <a class="dropdown-item" href="#">升级说明</a>
+                        <a class="dropdown-item" href="#">重庆市2008定额说明</a>
+                        <a class="dropdown-item" href="#">纵横官网</a>
+                        <a class="dropdown-item" href="#">动画教程</a>
+                        <a class="dropdown-item" href="#">联系客服</a>
+                        <a class="dropdown-item" href="#">关于</a>
+                    </div>
                 </li>
             </ul>
             <form class="form-inline">