Browse Source

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

Conflicts:
	server.js
Chenshilong 8 years ago
parent
commit
5266cd9d59

+ 2 - 0
Dockerfile

@@ -8,6 +8,8 @@ RUN cnpm install
 
 EXPOSE 6060
 
+ENV NODE_ENV=prod
+
 ENTRYPOINT babel-node server.js
 
 

+ 15 - 0
Dockerfile_qa

@@ -0,0 +1,15 @@
+FROM server:2.0
+
+COPY . ConstructionCost
+
+WORKDIR ConstructionCost
+
+RUN cnpm install
+
+EXPOSE 6060
+
+ENV NODE_ENV=qa
+
+ENTRYPOINT babel-node server.js
+
+

+ 8 - 16
config/config.js

@@ -1,22 +1,15 @@
 module.exports = {
-    current: {server: "192.168.1.184", port: "60666"},
+    current: {server: "192.168.1.184", port: "60666",redis:{server:'192.168.1.184',port:'6379',pwd:'smartCost'}},
     local: {server: "localhost", port: "27017"},
     qa: {server: "192.168.1.184", port: "60666"},
     prod: {server: "", port: ""},
-    setToLocalDb: function() {
-        var me = this;
-        me.current.server = me.local.server;
-        me.current.port = me.local.port;
-    },
-    setToQaDb: function() {
-        var me = this;
-        me.current.server = me.qa.server;
-        me.current.port = me.qa.port;
-    },
-    setToProdDb: function() {
-        var me = this;
-        me.current.server = me.prod.server;
-        me.current.port = me.prod.port;
+    redis_local:{server:'127.0.0.1',port:'6379',pwd:'smartCost'},
+    redis_qa:{server:'192.168.1.184',port:'6379',pwd:'smartCost'},
+    setupDb:function (env="local") {
+        let me = this;
+        me.current.server = me[env].server;
+        me.current.port = me[env].port;
+        me.current.redis=me["redis_"+env];
     },
     options:{
             "user": "",
@@ -29,6 +22,5 @@ module.exports = {
                 "connectTimeoutMS": 10000
                 }
             }
-
         }
 }

+ 220 - 0
config/redis.js

@@ -0,0 +1,220 @@
+/**
+ * Created by chen on 2017/8/21.
+ */
+
+let Redis = require('ioredis'),
+    config=require('./config'),
+    redisConfig = config.current.redis;
+    redis = new Redis({
+        port: redisConfig.port,          // Redis port
+        host: redisConfig.server,   // Redis host
+        family: 4,           // 4 (IPv4) or 6 (IPv6)
+        password:redisConfig.pwd,
+        db: 0
+    });
+let client={};
+
+redis.on('ready',function(res){
+    console.log('ready');
+});
+
+redis.on("error", function (err) {
+    console.log("Error " + err);
+});
+client.redis = redis;
+//redis.hmset('测试',{12525:55,'a':'aaaa',b:"bbbbb"});
+
+//var stream = redis.scanStream({  match: '测*'});
+
+/*redis.hmset('RATION',{12525:55,'a':'aaaa',b:"bbbbb"});
+
+redis.hgetall("RATION",function (err,result) {
+    console.log(result);
+})*/
+
+
+client.scan = function(options,callback){
+    var stream = null;
+    if(options){
+        stream = redis.scanStream(options);
+    }else {
+        stream = redis.scanStream();
+    }
+    var keys = [];
+    stream.on('data', function (resultKeys) {
+        // `resultKeys` is an array of strings representing key names
+        for (var i = 0; i < resultKeys.length; i++) {
+            keys.push(resultKeys[i]);
+        }
+    });
+    stream.on('end', function () {
+        console.log('done with the keys: ', keys);
+        callback(keys);
+    });
+}
+
+client.set = function(key, value, expire, callback){
+    return redis.set(key, value, function(err, result){
+        if (err) {
+            console.log(err);
+            callback(err,null);
+            return;
+        }
+        if (!isNaN(expire) && expire > 0) {
+            redis.expire(key, parseInt(expire));
+        }
+        if(callback){
+            callback(null,result);
+        }
+    })
+}
+
+
+client.get = function(key, callback){
+    return redis.get(key, function(err,result){
+        if (err) {
+            console.log(err);
+            callback(err,null);
+            return;
+        }
+        if(callback){
+            callback(null,result);
+        }
+    });
+}
+
+client.hmset = function(key, value, expire, callback){
+    return redis.hmset(key, value, function(err, result){
+        if (err) {
+            console.log(err);
+            callback(err,null);
+            return;
+        }
+        if (!isNaN(expire) && expire > 0) {
+            redis.expire(key, parseInt(expire));
+        }
+        if(callback){
+            callback(null,result);
+        }
+    })
+}
+
+client.hmget = function (key,fields,callback) {
+    return redis.hmget(key,fields,function(err,result){
+        if (err) {
+            console.log(err);
+            callback(err,null)
+            return;
+        }
+        if(callback){
+            callback(null,result);
+        }
+    })
+}
+
+client.hgetall = function (key,callback) {
+    return redis.hgetall(key,function (err,result) {
+        if (err) {
+            console.log(err);
+            callback(err,null)
+            return;
+        }
+        callback(null,result);
+    })
+}
+
+
+client.hscan = function (key,options) {
+    var stream = null;
+    if(options){
+        stream = redis.hscanStream(key,options);
+    }else {
+        stream = redis.hscanStream(key);
+    }
+    var fields = [];
+    stream.on('data', function (resultFields) {
+        // `resultKeys` is an array of strings representing key names
+        for (var i = 0; i < resultFields.length; i++) {
+            fields.push(resultFields[i]);
+        }
+    });
+    stream.on('end', function () {
+        console.log('done with the keys: ', fields);
+        callback(fields);
+    });
+}
+
+client.rpush = function(key,value,expire, callback){
+    return redis.rpush(key, value, function(err, result){
+        if (err) {
+            console.log(err);
+            callback(err,null);
+            return;
+        }
+        if (!isNaN(expire) && expire > 0) {
+            redis.expire(key, parseInt(expire));
+        }
+        if(callback){
+            callback(null,result);
+        }
+    })
+}
+
+client.lrange= function (key,start,end,callback) {
+   return redis.lrange(key,start,end,callback);//获取列表在给定范围上的所有值 array lrange('key', 0, -1) (返回所有值)
+}
+
+client.lindex =function (key,index,callback) {
+    return redis.lindex(key,index,callback);//获取列表在给定位置上的单个元素 lindex('key', 1)
+}
+
+client.lpop = function (key,callback) {
+    return redis.lpop(key,callback);//从列表左端弹出一个值,并返回被弹出的值lpop('key')
+}
+
+client.rpop = function (key,callback) {
+    return redis.rpop(key,callback);//从列表右端弹出一个值,并返回被弹出的值rpop('key')
+}
+
+client.ltrim = function (key,start,end,callback) {
+    return redis.ltrim(key,start,end,callback);//将列表按指定的index范围裁减 ltrim('key', 'start', 'end')
+}
+
+
+client.del = function (keys,callback) {
+    return redis.del(keys,callback);// 删除一个(或多个)keys return 被删除的keys的数量  del('key1'[, 'key2', ...])
+}
+
+client.exists = function (key,callback) {
+    return redis.exists(key,callback);// 查询一个key是否存在  1/0 exists('key')
+}
+
+client.multi = function () {
+    return redis.multi();//用于开启一个事务,它总是返回 OK 。
+}
+
+client.exec =function () {
+   return redis.exec();//执行所有事务块内的命令
+}
+
+client.application_init = function () {
+    redis.flushdb();//清空所有keys
+    // load datas -- to do
+    /*data=[{
+     method:'hmset',
+     key:'ration:25555',
+     value:{
+     name:'aaa',
+     quantily:255
+     },
+     expire:2000,//options
+     callback:function, //option
+     }]
+     for(let data of datas){
+     client[data.method](data.key,data.value,data.expire,data.callback);
+     }
+     */
+}
+
+
+module.exports = client

+ 3 - 4
modules/complementary_glj_lib/controllers/gljController.js

@@ -106,10 +106,9 @@ class GljController extends BaseController{
         });
     }*/
     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) {
+        let userId = req.body.userId;
+        let updateArr = JSON.parse(req.body.updateArr);
+        gljDao.updateComponent(userId, updateArr, function (err, message, rst) {
             callback(req, res, err, message, rst);
         })
     }

+ 2 - 3
modules/complementary_glj_lib/models/gljModel.js

@@ -80,8 +80,7 @@ class GljDao {
         })
     };
 
-    //-oprtor
-    updateComponent(libId, updateArr, callback){
+    updateComponent(userId, updateArr, callback){
         let parallelFucs = [];
         for(let i = 0; i < updateArr.length; i++){
             parallelFucs.push((function(obj){
@@ -89,7 +88,7 @@ class GljDao {
                     if(typeof obj.component === 'undefined'){
                         obj.component = [];
                     }
-                    gljModel.update({repositoryId: libId, ID: obj.ID}, obj, function (err, result) {
+                    complementaryGljModel.update({userId: userId, ID: obj.ID}, obj, function (err, result) {
                         if(err){
                             cb(err);
                         }

+ 1 - 1
modules/complementary_glj_lib/routes/routes.js

@@ -9,7 +9,7 @@ let router = express.Router();
 let gljController = new GljController();
 
 module.exports = function (app) {
-    app.get('/complementartGlj', gljController.init, gljController.redirectGlj);
+    app.get('/complementaryGlj', gljController.init, gljController.redirectGlj);
 
    /* router.post("/updateRationBasePrc",gljController.init, gljController.updateRationBasePrc);//更新定额单价
     router.post("/getRationGljIds", gljController.init, gljController.getRationGljIds);

+ 2 - 1
package.json

@@ -27,7 +27,8 @@
     "moment": "^2.18.1",
     "socket.io": "^2.0.3",
     "ua-parser-js": "^0.7.14",
-    "uuid": "^3.1.0"
+    "uuid": "^3.1.0",
+    "ioredis":"^3.1.4"
   },
   "scripts": {
     "start": "C:\\Users\\mai\\AppData\\Roaming\\npm\\babel-node.cmd server.js"

+ 1 - 1
server.js

@@ -4,7 +4,7 @@ let config = require("./config/config.js");
 let fileUtils = require("./modules/common/fileUtils");
 let dbm = require("./config/db/db_manager");
 ///config.setToLocalDb();
-config.setToQaDb();
+config.setupDb(process.env.NODE_ENV);
 
 let path = require('path');
 let session = require('express-session');

+ 9 - 7
web/building_saas/complementary_glj_lib/html/tools-gongliaoji.html

@@ -29,7 +29,7 @@
         </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="navbar-text"><a href="/pm">项目管理</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>
@@ -54,7 +54,7 @@
                     <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>
+                        <a class="dropdown-item" href="/complementaryGlj">工料机库编辑器</a>
                     </div>
                 </li>
                 <li class="nav-item dropdown">
@@ -82,7 +82,7 @@
         <div class="main-nav">
             <ul class="nav flex-column">
               <li><a href="#">定额库编辑器</a></li>
-              <li><a href="tools-gongliaoji.html" class="active">工料机库编辑器</a></li>
+              <li><a href="/complementaryGlj" class="active">工料机库编辑器</a></li>
             </ul>
         </div>
         <div class="content">
@@ -131,7 +131,9 @@
                               <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">补充工料机
+                                  <input type="radio" class="glj-radio" name="glj" value="complementaryGljs">补充工料机&nbsp;&nbsp;
+                                  <input type="radio" class="glj-radio" name="glj" value="selectedGljs">已选工料机机&nbsp;&nbsp;
+                                 <!-- <div class="form-group"><input id="searchGlj" type="text" class="form-control-sm" placeholder="查询工料机"></div>-->
                               </div>
                               <div class="modal-auto-height col-12"  id="componentSheet">
                                <!--   <table class="table table-sm table-bordered m-0">
@@ -151,8 +153,8 @@
                     </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>
+                      <button type="button" id="componentsCacnel" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                      <a href="javascript:void(0);" id="componentsConf" class="btn btn-primary">确定</a>
                   </div>
               </div>
           </div>
@@ -301,7 +303,7 @@
             $('#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]);
+            pageOprObj.initPage($("#GLJListSheet")[0], $('#gljComponentSheet')[0], $("#componentSheet")[0]);
         });
         //组成物弹出窗大小设置
         $(window).resize(function () {

+ 112 - 31
web/building_saas/complementary_glj_lib/js/components.js

@@ -9,6 +9,7 @@ let componentOprObj = {
     rootNode: null,//分类树根节点
     radiosSelected: null,//allGljs, stdGljs, complementaryGljs
     workBook: null,
+    selectedList: [],//选中的组成物
     setting: {
         owner: "components",
         header: [
@@ -30,10 +31,55 @@ let componentOprObj = {
         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.workBook.bind(GC.Spread.Sheets.Events.ButtonClicked, me.onButtonClicked);//复选框点击事件
+        //sheetOpr.cleanSheet(me.workBook.getSheet(0), me.setting, -1);
+        me.componentsBtnOpr($('#componentsConf'));
         me.radiosChange();
+        //me.searchChange();
     },
-    setShowGljList: function (gljList) {
+    onButtonClicked: function (sender, args) {
+        let me = componentOprObj, re = repositoryGljObj;
+        let val = args.sheet.getValue(args.row, args.col);
+        let thisComponent = me.currentCache[args.row];
+        thisComponent.isChecked = val;
+        console.log(val);
+        //维护选中组成物列表
+        if(val === true){
+            //解决复选框编辑状态的暂时方法todo
+            let isExist = false;
+            for(let i = 0, len = me.selectedList.length; i < len; i++){
+                if(me.selectedList[i].ID === thisComponent.ID){
+                    isExist = true;
+                    break;
+                }
+            }
+            if(!isExist){
+                me.selectedList.push(thisComponent);
+            }
+        }
+        else if(val === false){
+            for(let i = 0, len = me.selectedList.length; i < len; i++){
+                if(me.selectedList[i].ID === thisComponent.ID){
+                    me.selectedList.splice(i, 1);
+                    break;
+                }
+            }
+            if($("input[name='glj']:checked").val() === 'selectedGljs'){//radio为已选工料机时
+                me.showGljList = [];
+                me.setShowGljList(me.selectedList, false);
+                re.sortGlj(me.showGljList);
+                //重新显示
+                me.showGljItems(me.showGljList, me.gljCurTypeId);
+                if (re.parentNodeIds["_pNodeId_" + me.gljCurTypeId]) {//更新cache
+                    me.currentOprParent = 1;
+                    me.currentCache = me.getParentCache(re.parentNodeIds["_pNodeId_" + me.gljCurTypeId]);
+                } else {
+                    me.currentCache = me.getCache();
+                }
+            }
+        }
+    },
+    setShowGljList: function (gljList, clearChecked) {
         //初始为所有工料机,机械类型可添加机械组成物,混凝土,砂浆、配合比可添加普通材料
         let materialArr = [202, 203, 204];//混凝土、砂浆、配合比, 201普通材料
         let that = repositoryGljObj, me = componentOprObj;
@@ -49,8 +95,17 @@ let componentOprObj = {
                         }
                     }
                     if(!isExist){
-                        gljList[i].isChecked = false;
-                        me.showGljList.push(gljList[i]);
+                        if(clearChecked){
+                            gljList[i].isChecked = false;//切换的时候清空选择
+                        }
+                       /* if(isSelected){//已选择工料机显示
+                            if(gljList[i].isChecked === true){
+                                me.showGljList.push(gljList[i]);
+                            }
+                        }*/
+                   //     else{
+                            me.showGljList.push(gljList[i]);
+                      //  }
                     }
                 }
             }
@@ -58,6 +113,9 @@ let componentOprObj = {
     //初始默认radio
     initRadio: function () {
         let that = repositoryGljObj, me = componentOprObj;
+        $('#searchGlj').val('');//恢复搜索文本
+        //初始化组成物列表
+        me.selectedList = [];
         //默认radio所有工料机
         if(typeof $("input[name='glj']:checked")[0] !== 'undefined'){
             $("input[name='glj']:checked")[0].checked = false;
@@ -67,8 +125,8 @@ let componentOprObj = {
         //初始为所有工料机,机械类型可添加机械组成物,混凝土,砂浆、配合比可添加普通材料
         me.showGljList = [];
         if(me.radiosSelected === 'allGljs'){
-            me.setShowGljList(that.stdGljList);
-            me.setShowGljList(that.complementaryGljList);
+            me.setShowGljList(that.stdGljList, true);
+            me.setShowGljList(that.complementaryGljList, true);
             that.sortGlj(me.showGljList);
         }
     },
@@ -80,6 +138,8 @@ let componentOprObj = {
             let val = $("input[name='glj']:checked").val();
             me.radiosSelected = val;
             //选择改变,数据重新筛选显示
+            //清空选中的组成物列表
+            //me.selectedList = [];
             me.showGljList = [];
             if(me.radiosSelected === 'allGljs'){
                 me.setShowGljList(re.stdGljList);
@@ -91,6 +151,11 @@ let componentOprObj = {
             else if(me.radiosSelected === 'complementaryGljs'){
                 me.setShowGljList(re.complementaryGljList);
             }
+            else if(me.radiosSelected === 'selectedGljs'){
+                /*me.setShowGljList(re.stdGljList, false, true);
+                me.setShowGljList(re.complementaryGljList, false, true);*/
+                me.setShowGljList(me.selectedList, false);
+            }
             re.sortGlj(me.showGljList);
             //重新显示
             me.showGljItems(me.showGljList, me.gljCurTypeId);
@@ -107,7 +172,20 @@ let componentOprObj = {
             }
         });
     },
-    //切换分类树时,记住当前分类的选择, value = true、false、null
+    //实时模糊搜索
+    searchChange: function () {
+        let me = componentOprObj, re = repositoryGljObj;
+        let interval = null;
+        function search(){
+            console.log($('#searchGlj').val());
+        }
+        $('#searchGlj').focus(function () {
+            interval = setInterval(search, 500);
+        }).blur(function () {
+            clearInterval(interval);
+        });
+    },
+  /*  //切换分类树时,记住当前分类的选择, value = true、false、null
     setComponentChecked: function (sheet) {
         let me = componentOprObj;
         for(let i = 0; i < sheet.getRowCount(); i ++){
@@ -118,7 +196,7 @@ let componentOprObj = {
                 me.preCache[i].isChecked = false;
             }
         }
-    },
+    },*/
     //获得选择的组成物
     getComponents: function () {
         let rst = [];
@@ -167,41 +245,44 @@ let componentOprObj = {
             sheetOpr.showData(me.workBook.getSheet(0), me.setting, cacheSection, re.distTypeTree);
             cacheSection = null;
         }
+    },
+    //组成物窗口按钮操作
+    componentsBtnOpr: function (conf) {//确定、取消、关闭按钮
+        let me = componentOprObj, that = gljComponentOprObj, re = repositoryGljObj;
+        conf.click(function () {
+           //添加选择添加的组成物
+            let updateArr = [];
+            if(me.selectedList.length > 0){
+                for(let i = 0, len = me.selectedList.length; i < len; i++){
+                    re.currentGlj.component.push({ID: me.selectedList[i].ID, consumeAmt: 0});
+                }
+                updateArr.push(re.currentGlj);
+                that.updateComponent(updateArr);
+            }
+
+        });
     }
 };
 
 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();
-                }
+            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);
+            //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).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);

+ 107 - 74
web/building_saas/complementary_glj_lib/js/glj.js

@@ -190,10 +190,10 @@ let repositoryGljObj = {
     },
     buildSheet: function(container) {
         let me = repositoryGljObj;
-        me.workBook = sheetOpr.buildSheet(container, me.setting, 30, me);
+        me.workBook = sheetOpr.buildSheet(container, me.setting, 30);
         me.repositoryGljDelOpr();
-        me.workBook.bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting);
-        me.workBook.bind(GC.Spread.Sheets.Events.ClipboardPasted, me.onClipboardPasted);
+        me.workBook.getActiveSheet().bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting);
+        me.workBook.getActiveSheet().bind(GC.Spread.Sheets.Events.ClipboardPasted, me.onClipboardPasted);
         me.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.EditStarting, me.onCellEditStart);
         me.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.EditEnded, me.onCellEditEnd);
         me.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.EnterCell, me.onEnterCell);
@@ -214,6 +214,17 @@ let repositoryGljObj = {
                     rst.push(obj);
                 }
             }
+            for(let j = 0; j < me.stdGljList.length; j++){
+                if(gljComponent[i].ID == me.stdGljList[j].ID){
+                    obj.ID = me.stdGljList[j].ID;
+                    obj.code = me.stdGljList[j].code;
+                    obj.name = me.stdGljList[j].name;
+                    obj.unit = me.stdGljList[j].unit;
+                    obj.basePrice = me.stdGljList[j].basePrice;
+                    obj.consumeAmt = gljComponent[i].consumeAmt;
+                    rst.push(obj);
+                }
+            }
         }
         rst.sort(function (a, b) {
             let r = 0;
@@ -289,7 +300,7 @@ let repositoryGljObj = {
                 //标记当前工料机
                 me.currentGlj = me.currentCache[row];
                 if(me.allowComponent.indexOf(me.currentCache[row].gljType) !== -1){
-                    that.workBook.getSheet(0).getRange(-1, 0 , -1, 1, GC.Spread.Sheets.SheetArea.viewport).locked(false);
+                    //that.workBook.getSheet(0).getRange(-1, 0 , -1, 1, GC.Spread.Sheets.SheetArea.viewport).locked(false);
                     that.workBook.getSheet(0).getRange(-1, 4 , -1, 1, GC.Spread.Sheets.SheetArea.viewport).locked(false);
                     that.isLocked = false;
                     //展示数据
@@ -372,9 +383,12 @@ let repositoryGljObj = {
                             let field = me.setting.header[col].dataCode;
                             if(field === 'gljType'){
                                 me.workBook.getSheet(0).getCell(me.editingRowIdx, col).value(
-                                    me.distTypeTree.distTypes[me.distTypeTree.prefix + me.currentEditingGlj[field]].data.fullName);
+                                    typeof me.currentEditingGlj[field] !== 'undefined'?
+                                    me.distTypeTree.distTypes[me.distTypeTree.prefix + me.currentEditingGlj[field]].data.fullName
+                                    : '');
                             }
                             else{
+                                me.workBook.getSheet(0).getCell(me.editingRowIdx, 0).formatter("@");
                                 me.workBook.getSheet(0).getCell(me.editingRowIdx, col).value(me.currentEditingGlj[me.setting.header[col].dataCode]);
                             }
                         }
@@ -410,30 +424,33 @@ let repositoryGljObj = {
         if (me.currentEditingGlj["ID"]) {
             rObj["ID"] = me.currentEditingGlj["ID"];
             rObj.gljClass = me.currentEditingGlj.gljClass;
-            for(let col =0; col< me.setting.header.length; col++){
-                if(me.currentEditingGlj[me.setting.header[col].dataCode] !== rObj[me.setting.header[col].dataCode]){
-                    me.addGljObj = rObj;
-                    if(rObj[me.setting.header[0].dataCode] && rObj[me.setting.header[1].dataCode] && rObj[me.setting.header[5].dataCode]){
+            //for(let col =0; col< me.setting.header.length; col++){
+                if(me.currentEditingGlj[me.setting.header[args.col].dataCode] !== rObj[me.setting.header[args.col].dataCode]){
+                    //me.addGljObj = rObj;
+                    //编码、名称、单位、类型不可为空
+                    if(rObj[me.setting.header[0].dataCode] && rObj[me.setting.header[1].dataCode] && rObj[me.setting.header[3].dataCode] && rObj[me.setting.header[5].dataCode]
+                    &&rObj[me.setting.header[0].dataCode].toString().trim().length !== 0 && rObj[me.setting.header[1].dataCode].toString().trim().length !== 0 && rObj[me.setting.header[3].dataCode].toString().trim().length !== 0&&
+                        rObj[me.setting.header[5].dataCode].toString().trim().length !== 0){
                         if(rObj.gljType !== me.currentEditingGlj.gljType){//修改了工料机类型
-                            if(me.currentGlj){
-                                me.currentGlj.component = [];
-                            }
-                            if(me.allowComponent.indexOf(rObj.gljType) !== -1){
-                                rObj.basePrice = 0;
-                            }
-                            if(me.componentGljType.indexOf(me.currentEditingGlj.gljType) !== -1 &&
-                                !(me.currentEditingGlj.gljType === 302 && rObj.gljType === 303) && !(me.currentEditingGlj.gljType === 303 && rObj.gljType === 302)){//修改了原本是组成物的工料机
-                               //寻找所有引用了此组成物的工料机,并从组成物中删去此工料机,并重算单价
-                                let updateGljs = me.getUpdateGljs(rObj);
-                                if(updateGljs.updateArr.length > 0 || updateGljs.updateBasePrcArr.length > 0){
-                                    for(let i = 0; i < updateGljs.updateArr.length; i++){
-                                        updateArr.push(updateGljs.updateArr[i]);
-                                    }
-                                    for(let i = 0; i < updateGljs.updateBasePrcArr.length; i++){
-                                        updateArr.push(updateGljs.updateBasePrcArr[i]);
+                                if(me.currentGlj){
+                                    me.currentGlj.component = [];
+                                }
+                                if(me.allowComponent.indexOf(rObj.gljType) !== -1){
+                                    rObj.basePrice = 0;
+                                }
+                                if(me.componentGljType.indexOf(me.currentEditingGlj.gljType) !== -1 &&
+                                    !(me.currentEditingGlj.gljType === 302 && rObj.gljType === 303) && !(me.currentEditingGlj.gljType === 303 && rObj.gljType === 302)){//修改了原本是组成物的工料机
+                                    //寻找所有引用了此组成物的工料机,并从组成物中删去此工料机,并重算单价
+                                    let updateGljs = me.getUpdateGljs(rObj);
+                                    if(updateGljs.updateArr.length > 0 || updateGljs.updateBasePrcArr.length > 0){
+                                        for(let i = 0; i < updateGljs.updateArr.length; i++){
+                                            updateArr.push(updateGljs.updateArr[i]);
+                                        }
+                                        for(let i = 0; i < updateGljs.updateBasePrcArr.length; i++){
+                                            updateArr.push(updateGljs.updateBasePrcArr[i]);
+                                        }
                                     }
                                 }
-                            }
                         }
                         else if(rObj.basePrice !== me.currentEditingGlj.basePrice){//修改了单价,可修改单价的必为可成为组成物的
                             //寻找所有引用了此组成物的工料机,并从组成物中删去此工料机,并重算单价
@@ -446,14 +463,23 @@ let repositoryGljObj = {
                                     updateArr.push(updateGljs.updateBasePrcArr[i]);
                                 }
                             }
-                            rObj.basePrice = !isNaN(parseFloat(rObj.basePrice)) && (rObj.basePrice && typeof rObj.basePrice !== 'undefined') ? me.round(parseFloat(rObj.basePrice), 2) : 0;
+                            rObj.basePrice = !isNaN(parseFloat(rObj.basePrice)) && (rObj.basePrice && typeof rObj.basePrice !== 'undefined') ? that.round(parseFloat(rObj.basePrice), 2) : 0;
                         }
                         rObj.component = me.currentGlj.component;
                         updateArr.push(rObj);
-                        break;
+                    }
+                    else{
+                        if(me.setting.header[args.col].dataCode === 'gljType'){
+                            console.log(me.distTypeTree);
+                            let distTypeVal =  me.distTypeTree.distTypes[me.distTypeTree.prefix + me.currentEditingGlj[me.setting.header[args.col].dataCode]].data.fullName;
+                            args.sheet.setValue(args.row, args.col, distTypeVal);
+                        }
+                        else{
+                            args.sheet.setValue(args.row, args.col, me.currentEditingGlj[me.setting.header[args.col].dataCode]);
+                        }
                     }
                 }
-            }
+          //  }
             //--------------------------------------
             if(me.currentEditingGlj.basePrice !== rObj.basePrice){
                 //update basePrice of ration when editting basePrice of glj
@@ -485,20 +511,22 @@ let repositoryGljObj = {
         }
         //新增
         else {
-            me.addGljObj = rObj;
-            let isCanSav = true;
-            if(!rObj[me.setting.header[0].dataCode] || !rObj[me.setting.header[1].dataCode] || !rObj[me.setting.header[3].dataCode] || !rObj[me.setting.header[5].dataCode]){
-                isCanSav = false;
-            }
-            if(isCanSav){
-                me.addGljObj = null;
-                rObj.component = [];
-                //如果类型为混凝土、砂浆、配合比、机械台班时,添加时填写的单价清空
-                if(me.allowComponent.indexOf(rObj.gljType) !== -1){
-                    rObj.basePrice = 0;
+            if(typeof rObj.code !== 'undefined'){
+                me.addGljObj = rObj;
+                let isCanSav = true;
+                if(!rObj[me.setting.header[0].dataCode] || !rObj[me.setting.header[1].dataCode] || !rObj[me.setting.header[3].dataCode] || !rObj[me.setting.header[5].dataCode]){
+                    isCanSav = false;
+                }
+                if(isCanSav){
+                    me.addGljObj = null;
+                    rObj.component = [];
+                    //如果类型为混凝土、砂浆、配合比、机械台班时,添加时填写的单价清空
+                    if(me.allowComponent.indexOf(rObj.gljType) !== -1){
+                        rObj.basePrice = 0;
+                    }
+                    rObj.basePrice = !isNaN(parseFloat(rObj.basePrice)) && (rObj.basePrice && typeof rObj.basePrice !== 'undefined') ? parseFloat(rObj.basePrice) : 0;
+                    addArr.push(rObj);
                 }
-                rObj.basePrice = !isNaN(parseFloat(rObj.basePrice)) && (rObj.basePrice && typeof rObj.basePrice !== 'undefined') ? parseFloat(rObj.basePrice) : 0;
-                addArr.push(rObj);
             }
         }
         if(me.gljCurTypeId !== 732){
@@ -507,7 +535,6 @@ let repositoryGljObj = {
         if(updateArr.length >0 || addArr.length >0){
             me.currentEditingGlj = null;
             //me.workBook.getSheet(0).setValue(11, 5, "人工");
-            console.log(updateArr);
             me.mixUpdateRequest(updateArr, addArr, []);
         }
     },
@@ -537,7 +564,6 @@ let repositoryGljObj = {
                                         updateBasePrcArr.push(updateGljs.updateBasePrcArr[i]);
                                     }
                                 }
-                                console.log(updateArr);
                                 removeArr.push(cacheSection[sels[i].row + j].ID);
                                 //tempRemoveArr.push({ID: cacheSection[sels[i].row + j].ID, code: cacheSection[sels[i].row + j].code});
                                 //删除后重新计算引用了此工料机的定额单价
@@ -600,9 +626,9 @@ let repositoryGljObj = {
                     //确认
                     $('#aleConfBtn').click(function () {
                         me.mixUpdateRequest(updateArr, [], removeArr);
-                        if(updateBasePrcArr.length > 0 && me.rationLibs.length > 0){
+                        /*if(updateBasePrcArr.length > 0 && me.rationLibs.length > 0){
                             me.updateRationBasePrcRq(updateBasePrcArr);
-                        }
+                        }*/
                     });
                 }
             }
@@ -615,6 +641,7 @@ let repositoryGljObj = {
     validUpdateObj: function (pasteObj, rowIdx) {
         let rst = {updateGlj: [], updateBasePrcArr: []}, backUpObj = {},
             me = repositoryGljObj,
+            that = gljComponentOprObj,
             tempObj = me.currentCache[rowIdx],
             reCalBasePrc = false,
             isValid = true;
@@ -687,7 +714,7 @@ let repositoryGljObj = {
             if(!isExsit) isValid = false;
         }
         //
-        pasteObj.basePrice = !isNaN(parseFloat(pasteObj.basePrice)) && (pasteObj.basePrice && typeof pasteObj.basePrice !== 'undefined') ? me.round(parseFloat(pasteObj.basePrice), 2) :
+        pasteObj.basePrice = !isNaN(parseFloat(pasteObj.basePrice)) && (pasteObj.basePrice && typeof pasteObj.basePrice !== 'undefined') ? that.round(parseFloat(pasteObj.basePrice), 2) :
             me.currentCache[rowIdx].basePrice;
         if(pasteObj.basePrice !== me.currentCache[rowIdx].basePrice){
             reCalBasePrc = true;
@@ -758,24 +785,19 @@ let repositoryGljObj = {
     },
     onClipboardPasting: function(sender, args) {
         let me = repositoryGljObj;
-        /*if (args.cellRange.colCount != me.setting.header.length || me.gljCurTypeId < 0 || me.parentNodeIds["_pNodeId_" + me.gljCurTypeId]) {
-         args.cancel = true;
-         }*/
-        if (me.gljCurTypeId < 0 ) {
-            args.cancel = true;
-        }
         let maxCol = args.cellRange.col + args.cellRange.colCount - 1;
         //复制的列数超过正确的列数,不可复制
-        if(maxCol >= me.setting.header.length){
+        if (me.gljCurTypeId < 0 || maxCol >= me.setting.header.length -1) {
             args.cancel = true;
         }
     },
     onClipboardPasted: function(e, info) {
-        let me = repositoryGljObj;
+        if(info.pasteData.text.trim().length > 0){
+            let me = repositoryGljObj;
             let updateArr = [], addArr = [];
             let items = sheetOpr.analyzePasteData(me.setting, info);
-            let beginRow = info.cellRange.row, endRow = info.cellRange.row + info.cellRange.rowCount - 1,
-                maxRow = me.currentCache.length - 1,
+            let beginRow = info.cellRange.row, endRow = info.cellRange.row + info.cellRange.rowCount - 1,//复制的起始行数和结束行数
+                maxRow = me.currentCache.length - 1,//当前数据最大行数
                 updateBasePrcArr = [] ,
                 updateCount, resumeArr = [];
             if(endRow <= maxRow){
@@ -784,9 +806,9 @@ let repositoryGljObj = {
                     let updateObj = me.validUpdateObj(items[i], info.cellRange.row + i);
                     if(updateObj && typeof updateObj.updateGlj !== 'undefined'){
                         updateArr = updateObj.updateGlj;
-                        if(typeof updateObj.updateBasePrc !== 'undefined'){
-                            updateBasePrcArr = updateObj.updateBasePrc;
-                        }
+                        /*if(typeof updateObj.updateBasePrcArr !== 'undefined'){
+                         updateBasePrcArr = updateObj.updateBasePrcArr;
+                         }*/
                     }
                     else{
                         resumeArr.push(info.cellRange.row + i);
@@ -799,15 +821,15 @@ let repositoryGljObj = {
                     let updateObj = me.validUpdateObj(items[i], info.cellRange.row + i);
                     if(updateObj && typeof updateObj.updateGlj !== 'undefined'){
                         updateArr = updateObj.updateGlj;
-                        if(typeof updateObj.updateBasePrc !== 'undefined'){
-                            updateBasePrcArr = updateObj.updateBasePrc;
-                        }
+                        /* if(typeof updateObj.updateBasePrcArr !== 'undefined'){
+                         updateBasePrcArr = updateObj.updateBasePrcArr;
+                         }*/
                     }
                     else{
                         resumeArr.push(info.cellRange.row + i);
                     }
                 }
-                if(info.cellRange.colCount === me.setting.header.length){
+                if(info.cellRange.colCount === me.setting.header.length -1){
                     for(let i = updateCount ; i < items.length; i++){
                         if(me.isValidObj(items[i])){
                             items[i].component = [];
@@ -829,7 +851,7 @@ let repositoryGljObj = {
                 }
             }
             else{
-                if(info.cellRange.colCount === me.setting.header.length){
+                if(info.cellRange.colCount === me.setting.header.length -1){
                     for(let i = 0; i < items.length; i++){
                         if(me.isValidObj(items[i])){
                             items[i].component = [];
@@ -851,33 +873,42 @@ let repositoryGljObj = {
             }
             //repaint
             if(resumeArr.length > 0){
-                info.sheet.suspendPaint();
+                let sheet = me.workBook.getActiveSheet();
+                sheet.suspendPaint();
                 for(let i = 0; i < resumeArr.length ; i++){
                     if(resumeArr[i] < me.currentCache.length){
-                        for(let col = 0; col < me.setting.header.length; col++){
+                        for(let col = 0; col < me.setting.header.length -1; col++){
                             if(me.setting.header[col].dataCode === 'gljType'){
                                 let gljType = me.currentCache[resumeArr[i]][me.setting.header[col].dataCode];
-                                info.sheet.setValue(resumeArr[i], col, me.distTypeTree.distTypes["gljType" + gljType].data.fullName);
+                                sheet.setValue(resumeArr[i], col, me.distTypeTree.distTypes["gljType" + gljType].data.fullName);
                             }
                             else{
-                                info.sheet.setValue(resumeArr[i], col, me.currentCache[resumeArr[i]][me.setting.header[col].dataCode]);
+                                sheet.setValue(resumeArr[i], col, me.currentCache[resumeArr[i]][me.setting.header[col].dataCode]);
                             }
                         }
                     }
                     else{
-                        for(let col = 0; col < me.setting.header.length; col++){
-                            info.sheet.setValue(resumeArr[i], col, '');
+                        for(let col = 0; col < me.setting.header.length - 1; col++){
+                            sheet.setValue(resumeArr[i], col, '', GC.Spread.Sheets.SheetArea.viewport);
                         }
                     }
                 }
-                info.sheet.resumePaint();
+                sheet.resumePaint();
             }
             if (updateArr.length > 0 || addArr.length > 0) {
                 me.mixUpdateRequest(updateArr, addArr, []);
             }
-            if(updateBasePrcArr.length > 0 && me.rationLibs.length > 0){
-                me.updateRationBasePrcRq(updateBasePrcArr);
+            /*if(updateBasePrcArr.length > 0 && me.rationLibs.length > 0){
+             me.updateRationBasePrcRq(updateBasePrcArr);
+             }*/
+        }
+        else{//解决bug: 从原本的sheet复制一行数据,会两次调用粘贴事件函数..,todo:找出原因
+            for(let i = 0, len = info.cellRange.rowCount; i < len; i++){
+                for(let col = 0; col < 6; col++){
+                    info.sheet.setValue(info.cellRange.row + i, col, '');
+                }
             }
+        }
     },
     updateRationBasePrcRq: function (basePrcArr) {
         $.ajax({
@@ -1018,6 +1049,8 @@ let gljTypeTreeOprObj = {
             gljTypeId = treeNode.ID;
         me.gljCurTypeId = treeNode.ID;
         that.isLocked = true;
+        //消除新增到一半的数据
+        me.addGljObj = null;
         //me.currentCache = me.getCache();
         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);

+ 144 - 113
web/building_saas/complementary_glj_lib/js/gljComponent.js

@@ -8,24 +8,29 @@ let gljComponentOprObj = {
         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:110,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]
+            lockedCells:[0, 1, 2, 3]
         }
     },
     buildSheet: function(container) {
         let me = gljComponentOprObj;
-        me.workBook = sheetOpr.buildSheet(container, me.setting, 30, me);
+        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, 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.onContextmenuOpr();//右键菜单
+        me.gljComponentDelOpr();
+        me.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.EditStarting, me.onCellEditStart);
+        me.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.EditEnded, me.onCellEditEnd);
+        me.workBook.bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting);
+        me.workBook.bind(GC.Spread.Sheets.Events.ClipboardPasted, me.onClipboardPasted);
         /*me.gljComponentDelOpr();
         me.workBook.bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting);
         me.workBook.bind(GC.Spread.Sheets.Events.ClipboardPasted, me.onClipboardPasted);
@@ -81,6 +86,7 @@ let gljComponentOprObj = {
                             "insert": {name: "插入", disabled: insertDis, callback: function (key, opt) {
                                 //默认radio所有工料机
                                 co.initRadio();
+                                co.gljCurTypeId = null;
                                 //默认点击树根节点
                                 if(co.rootNode){
                                     co.treeObj.selectNode(co.rootNode);
@@ -89,7 +95,28 @@ let gljComponentOprObj = {
                                 //弹出窗口
                                 $('#componentBtn').click();
                             }},
-                            "delete": {name: "删除", disabled: delDis}
+                            "delete": {name: "删除", disabled: delDis, callback: function (key, opt) {
+                                //删除
+                                let deleteObj = that.currentComponent[target.row];
+                                let gljComponent = that.currentGlj.component;
+                                let updateArr = [];
+                                //更新当前工料机的组成物列表
+                                for(let i = 0, len = gljComponent.length; i < len; i++){
+                                    if(gljComponent[i].ID === deleteObj.ID){
+                                        gljComponent.splice(i, 1);
+                                        break;
+                                    }
+                                }
+                                //重新计算工料机
+                                let gljBasePrc = me.reCalGljBasePrc(that.getCurrentComponent(gljComponent));
+                                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);
+                            }}
                         }
                     };
                 }
@@ -178,7 +205,7 @@ let gljComponentOprObj = {
             }
         });
         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);
+        //me.workBook.commandManager().setShortcutKey('gljComponentDel', GC.Spread.Commands.Key.del, false, false, false, false);
     },
     onCellEditStart: function(sender, args) {
         let me = gljComponentOprObj, that = repositoryGljObj;
@@ -188,127 +215,127 @@ let gljComponentOprObj = {
     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(args.editingText !== me.currentEditingComponent.code){
+        //编码
+      /*  if(args.col === 0 && args.editingText && args.editingText.trim().length > 0 &&args.editingText !== me.currentEditingComponent.code){
+            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});
+                        }
+                        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;
                                     }
-                                    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);
+                                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});
                                 }
-                                break;
+                                updateArr.push(that.currentGlj);
                             }
                             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]: '');
+                                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{
-                            if(materialComponent.indexOf(that.currentGlj.gljType) === 1){
-                                alert("该组成物只能是普通材料!");
-                            }
-                            else if(that.currentGlj.gljType === 301){
-                                alert("该组成物只能是机械组成物或机上人工!")
-                            }
+                            //已存在
+                            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;
+                    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]: '');
+                        //无效
                     }
-                    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});
+                }
+            }
+            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] : '');
+                //不存在
+            }
+        }*/
+         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;
                     }
-                    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);
-
+                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, '');
+                //只能输入数值
+                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, me.currentEditingComponent.consumeAmt);
+        }
         if(updateArr.length > 0){
             me.updateComponent(updateArr);
-            if(updateBasePrc.length > 0){
+            /*if(updateBasePrc.length > 0){
                 that.updateRationBasePrcRq(updateBasePrc)
-            }
+            }*/
         }
     },
     onClipboardPasting: function (sender, info) {
@@ -324,7 +351,8 @@ let gljComponentOprObj = {
             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){
+        //编码
+   /*     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){
@@ -387,8 +415,9 @@ let gljComponentOprObj = {
                 }
                 updateArr.push(that.currentGlj);
             }
-        }
-        else if(info.cellRange.col === 4){
+        }*/
+        //消耗量
+         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++){
@@ -419,33 +448,35 @@ let gljComponentOprObj = {
                 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});
+                    //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){
+           /* 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},
+            url: 'complementartGlj/api/updateComponent',
+            data: {"userId": pageOprObj.userId, "updateArr": JSON.stringify(updateArr)},
             dataType: 'json',
             success: function (result) {
-                if(result.data.length > 0){
-                    if(result.data[0]){
+                if(!result.error){
                         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);
-                    }
                 }
+                else{
+                    sheetOpr.cleanSheet(me.workBook.getSheet(0), me.setting, -1);
+                }
+                $('#componentsCacnel').click();
             }
         })
     },

+ 46 - 12
web/building_saas/complementary_glj_lib/js/sheetOpr.js

@@ -132,24 +132,22 @@ let sheetOpr = {
                 else {
                     sheet.setValue(row, col, data[row][setting.header[col].dataCode], ch);
                     sheet.setTag(row, 0, data[row].ID, ch);
+                    if(typeof setting.owner === 'undefined'){
+                        sheet.getCell(row, 0, GC.Spread.Sheets.SheetArea.viewport).locked(true);
+                    }
                 }
                 //复选框
                 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.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++){
@@ -205,11 +203,12 @@ let sheetOpr = {
             }
             else if (setting.header[col].dataCode === 'code'){
                 if(repositoryGljObj){
-                    let gljList = repositoryGljObj.gljList,
+                    let stdGljList = repositoryGljObj.stdGljList,
+                        complementaryGljList = repositoryGljObj.complementaryGljList,
                         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){
+                    for(let i=0; i< stdGljList.length; i++){
+                        if(stdGljList[i].code == sheet.getValue(row, col) && sheet.getValue(row, col)!== orgCode){
                             me.lockAllCells(sheet);
                             $('#alertText').text("输入的编号已存在,请重新输入!");
                             $('#codeAlertBtn').click();
@@ -217,18 +216,53 @@ let sheetOpr = {
                                 // me.reLockSomeCodes(sheet, 0, repositoryGljObj.currentCache.length);
                                 me.unLockAllCells(sheet);
                                 me.reLockSomeCodes(sheet, 0, repositoryGljObj.currentCache.length);
-                                sheet.setValue(row, 0, orgCode);
+                                //sheet.setText(row, 0, '');
+                                sheet.getCell(row, 0).formatter("@");
+                                sheet.getCell(row, 0).text("");
                                 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.setText(row, 0, '');
+                                sheet.getCell(row, 0).formatter("@");
+                                sheet.getCell(row, 0).text("");
                                 sheet.setActiveCell(row, 0);
                             });
                             // sheet.setValue(row, col, orgCode);
                             isExist = true
+                            break;
+                        }
+                    }
+                    if(!isExist){
+                        for(let i=0; i< complementaryGljList.length; i++){
+                            if(complementaryGljList[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.setText(row, 0, '');
+                                    sheet.getCell(row, 0).formatter("@");
+                                    sheet.getCell(row, 0).text("");
+                                    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.setText(row, 0, '');
+                                    sheet.getCell(row, 0).formatter("@");
+                                    sheet.getCell(row, 0).text("");
+                                    sheet.setActiveCell(row, 0);
+                                });
+                                // sheet.setValue(row, col, orgCode);
+                                isExist = true
+                                break;
+                            }
                         }
                     }
                     if(!isExist){

+ 1 - 1
web/building_saas/pm/html/project-management.html

@@ -68,7 +68,7 @@
                     <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="#">定额库编辑器</a>
-                        <a class="dropdown-item" href="/complementartGlj">工料机库编辑器</a>
+                        <a class="dropdown-item" href="/complementaryGlj">工料机库编辑器</a>
                     </div>
                 </li>
                 <li class="nav-item dropdown">

+ 41 - 12
web/building_saas/pm/js/pm_main.js

@@ -112,6 +112,7 @@ let ProjTreeSetting = {
             switch(node.data.projType) {
                 case projectType.project:
                     $("#add-engineering-btn").removeClass("disabled");
+                    $("#add-project-btn").removeClass("disabled");
                     break;
                 case projectType.folder:
                     $("#add-folder-btn").removeClass("disabled");
@@ -119,8 +120,10 @@ let ProjTreeSetting = {
                     break;
                 case projectType.engineering:
                     $("#add-tender-btn").removeClass("disabled");
+                    $("#add-engineering-btn").removeClass("disabled");
                     break;
                 case projectType.tender:
+                    $("#add-tender-btn").removeClass("disabled");
                     $("#move-to-btn").removeClass("disabled");
                     $("#copy-to-btn").removeClass("disabled");
                     $("#share-btn").removeClass("disabled");
@@ -143,7 +146,7 @@ $(document).ready(function() {
         try {
             let selectedType = selectedItem !== null && selectedItem.data !== undefined ?
                 selectedItem.data.projType : projectType.folder;
-            if (selectedType !== projectType.folder) {
+            if (selectedType !== projectType.folder && selectedType !== projectType.project) {
                 throw '建设项目只能添加到最外层或文件夹中';
             }
             $('#add-project-dialog').modal('show');
@@ -180,7 +183,7 @@ $(document).ready(function() {
                 throw '请选择要添加到的项目工程';
             }
             let selectedType = selectedItem.data !== undefined ? selectedItem.data.projType : '';
-            if (selectedType !== projectType.project) {
+            if (selectedType !== projectType.project && selectedType !== projectType.engineering) {
                 throw '单项项目只能添加到建设项目中';
             }
             $("#add-engineering-dialog").modal("show");
@@ -202,7 +205,7 @@ $(document).ready(function() {
                 throw '请选择要添加到的单项工程';
             }
             let selectedType = selectedItem.data !== undefined ? selectedItem.data.projType : '';
-            if (selectedType !== projectType.engineering) {
+            if (selectedType !== projectType.engineering && selectedType !== projectType.tender) {
                 throw '单项项目只能添加到单项工程中';
             }
             $("#add-tender-dialog").modal("show");
@@ -215,14 +218,19 @@ $(document).ready(function() {
     $('#add-tender-dialog').on('show.bs.modal', function() {
         // 当前选中的建设项目
         let selectedItem = Tree.selected();
-        let projectInfo = selectedItem !== null && selectedItem.parent !== undefined ? selectedItem.parent : null;
+        let projectInfo = null;
+        if (selectedItem.data.projType === projectType.tender) {
+            projectInfo = selectedItem !== null && selectedItem.parent !== undefined && selectedItem.parent.parent !== undefined ?
+                selectedItem.parent.parent : null;
+        } else {
+            projectInfo = selectedItem !== null && selectedItem.parent !== undefined ? selectedItem.parent : null;
+        }
         if (projectInfo !== null) {
             let savedProjectData = localStorage.getItem(projectInfo.data.name);
             savedProjectData = JSON.parse(savedProjectData);
-            let valuationHtml = '<option value="'+ savedProjectData.valuation +'">'+ savedProjectData.valuationName +'</option>'
+            let valuationHtml = '<option value="'+ savedProjectData.valuation +'">'+ savedProjectData.valuationName +'</option>';
             $("#tender-valuation").html(valuationHtml);
 
-            console.log(savedProjectData);
             $("input[name='tender_valuation_type']").attr('disabled', 'disabled').removeAttr('checked', 'checked');
             $("input[name='tender_valuation_type'][value='"+ savedProjectData.valuationType +"']")
                 .attr("checked", "checked").removeAttr('disabled', 'disabled');
@@ -505,7 +513,7 @@ function AddProject() {
     }
     let valuationName = $("#valuation").children("option:selected").text();
     let valuationType = $("input[name='valuation_type']:checked").val();
-    AddChildrenItem(name, projectType.project, function() {
+    let callback = function() {
         $("#add-project-dialog").modal("hide");
         // 记录选择后的信息
         let projectInfo = {
@@ -514,7 +522,14 @@ function AddProject() {
             valuationName: valuationName
         };
         localStorage.setItem(name, JSON.stringify(projectInfo));
-    });
+    };
+    let selectedItem = Tree.selected();
+    // 如果选择的是建设项目则新增同级数据
+    if (selectedItem !== null && selectedItem.data.projType === projectType.project) {
+        AddSiblingsItem(name, projectType.project, callback);
+    } else {
+        AddChildrenItem(name, projectType.project, callback);
+    }
 }
 
 /**
@@ -587,9 +602,16 @@ function AddEngineering() {
         alert('请填写单项工程名称');
         return false;
     }
-    AddChildrenItem(name, projectType.engineering, function() {
+    let callback = function() {
         $("#add-engineering-dialog").modal("hide");
-    });
+    };
+    let selectedItem = Tree.selected();
+    // 如果选择的是单项工程则新增同级数据
+    if (selectedItem !== null && selectedItem.data.projType === projectType.engineering) {
+        AddSiblingsItem(name, projectType.engineering, callback);
+    } else {
+        AddChildrenItem(name, projectType.engineering, callback);
+    }
 }
 
 /**
@@ -603,9 +625,16 @@ function AddTender() {
         alert('请填写单位工程名称');
         return false;
     }
-    AddChildrenItem(name, projectType.tender, function() {
+    let callback = function() {
         $("#add-tender-dialog").modal("hide");
-    });
+    };
+    let selectedItem = Tree.selected();
+    // 如果选择的是单项工程则新增同级数据
+    if (selectedItem !== null && selectedItem.data.projType === projectType.tender) {
+        AddSiblingsItem(name, projectType.tender, callback);
+    } else {
+        AddChildrenItem(name, projectType.tender, callback);
+    }
 }
 
 /**