Pārlūkot izejas kodu

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

TonyKang 7 gadi atpakaļ
vecāks
revīzija
d5c7e94ba2
31 mainītis faili ar 1544 papildinājumiem un 551 dzēšanām
  1. 0 12
      config/menu.js
  2. 3 1
      modules/common/helper/mongoose_helper.js
  3. 97 41
      modules/ration_repository/models/coe.js
  4. 1 0
      modules/ration_repository/models/schemas.js
  5. 7 1
      modules/std_glj_lib/controllers/gljController.js
  6. 7 0
      modules/std_glj_lib/models/gljModel.js
  7. 1 0
      modules/std_glj_lib/routes/routes.js
  8. 1 1
      modules/users/controllers/compilation_controller.js
  9. 8 2
      modules/users/controllers/dashboard_controller.js
  10. 201 2
      modules/users/controllers/notify_controller.js
  11. 25 6
      modules/users/models/compilation_model.js
  12. 12 4
      modules/users/models/engineering_lib_model.js
  13. 183 0
      modules/users/models/message_model.js
  14. 51 0
      modules/users/models/schemas/message.js
  15. 7 0
      modules/users/routes/notify_route.js
  16. 10 0
      public/web/sheet/sheet_common.js
  17. 3 0
      web/maintain/ration_repository/dinge.html
  18. 24 3
      web/maintain/ration_repository/fuzhu.html
  19. 474 219
      web/maintain/ration_repository/js/coe.js
  20. 15 13
      web/maintain/ration_repository/js/ration.js
  21. 125 55
      web/maintain/ration_repository/js/ration_coe.js
  22. 86 71
      web/maintain/ration_repository/js/ration_glj.js
  23. 3 1
      web/maintain/ration_repository/js/section_tree.js
  24. 8 2
      web/users/js/col_setting.js
  25. 10 5
      web/users/js/compilation.js
  26. 22 0
      web/users/js/message.js
  27. 2 2
      web/users/views/compilation/engineering.html
  28. 5 23
      web/users/views/dashboard/index.html
  29. 29 0
      web/users/views/notify/common.html
  30. 75 87
      web/users/views/notify/index.html
  31. 49 0
      web/users/views/notify/save.html

+ 0 - 12
config/menu.js

@@ -35,18 +35,6 @@ let menuData = {
         url: '/notify',
         name: 'notify',
         iconClass: 'glyphicon glyphicon-bell',
-        children: {
-            'index' : {
-                title: '用户通知',
-                url: '/notify',
-                name: 'index',
-            },
-            'company' : {
-                title: '内部通知',
-                url: '/notify/company',
-                name: 'company',
-            }
-        }
     },
     'version': {
         title: '编办管理',

+ 3 - 1
modules/common/helper/mongoose_helper.js

@@ -55,9 +55,11 @@ class MongooseHelper {
         let self = this;
         let limit = 0;
         let skip = 0;
+        let sort = {};
         if (option !== null && Object.keys(option).length > 0) {
             limit = option.pageSize !== undefined ? option.pageSize : limit;
             skip = option.offset !== undefined ? option.offset : skip;
+            sort = option.sort !== undefined ? option.sort : sort;
         }
         return new Promise(function (resolve, reject) {
             self.model.find(conditions, fields, option, function (error, data) {
@@ -66,7 +68,7 @@ class MongooseHelper {
                 } else {
                     resolve(data);
                 }
-            }).skip(skip).limit(limit);
+            }).skip(skip).limit(limit).sort(sort);
         });
     }
 

+ 97 - 41
modules/ration_repository/models/coe.js

@@ -2,10 +2,12 @@
  * Created by CSL on 2017/5/3.
  * 系数表。
  */
+//modiyied by zhong on 2017/9/21
 let counter = require('../../../public/counter/counter');
 import {coeListModel} from './schemas';
+import async from 'async';
 
-var coeListDAO = function(){};
+let coeListDAO = function(){};
 
 coeListDAO.prototype.getCoe = function (data, callback) {
     coeListModel.findOne({
@@ -38,75 +40,129 @@ coeListDAO.prototype.getCoesByLibID = function (libID, callback) {
         })
 };
 
+
 coeListDAO.prototype.saveToCoeList = function(data, callback) {
-    var me = this;
-    if (data.addArr.length > 0) {
+    let me = this;
+    /*if (data.addArr.length > 0) {
         me.addItems(data.addArr, callback);
-    };
+    }
 
     if (data.deleteArr.length > 0) {
         me.deleteItems(data.deleteArr, callback);
-    };
+    }
 
     if (data.updateArr.length > 0) {
         me.updateItems(data.updateArr, callback);
-    };
+    }*/
+    if (data.addArr.length > 0 && data.updateArr.length > 0) {
+        async.parallel([
+            function (cb) {
+                me.addItems(data.addArr, cb);
+            },
+            function (cb) {
+                me.updateItems(data.updateArr, cb);
+            }
+        ], function (err, result) {
+            callback(err, 'mixed', result);
+        });
+    }
+    else if(data.addArr.length > 0){
+        me.addItems(data.addArr, callback);
+    }
+    else if (data.updateArr.length > 0) {
+        me.updateItems(data.updateArr, callback);
+    }
+    else if (data.deleteArr.length > 0) {
+        me.deleteItems(data.deleteArr, callback);
+    }
 };
 
 coeListDAO.prototype.addItems = function(addArr, callback) {
     if (addArr && addArr.length > 0) {
         counter.counterDAO.getIDAfterCount(counter.moduleName.coeList, addArr.length, function(err, result){
-            var maxId = result.value.sequence_value;
-            for (var i = 0; i < addArr.length; i++) {
-                var obj = new coeListModel(addArr[i]);
+            let maxId = result.value.sequence_value;
+            let functions = [];
+            for (let i = 0; i < addArr.length; i++) {
+                let obj = new coeListModel(addArr[i]);
                 obj.ID = (maxId - (addArr.length - 1) + i);
-                coeListModel.create(obj, function(err) {
-                    if (err) {
-                        callback(true, "add fail", null);
-                    } else {
-                        callback(false, "add success", obj.ID);
-                    };
-                });
-            };
-
+                functions.push((function (obj) {
+                    return function (cb) {
+                        coeListModel.create(obj, function(err) {
+                            if (err) {
+                                cb(true, null);
+                            } else {
+                                cb(false, obj);
+                            };
+                        });
+                    }
+                })(obj));
+            }
+            async.parallel(functions, function (err, result) {
+                if(err) callback(true, 'add fail', null);
+                else callback(false, 'addSc', result);
+            })
         });
     } else {
         callback(true, "no source", null);
-    };
+    }
 };
 
 coeListDAO.prototype.updateItems = function(updateArr, callback) {
     if (updateArr && updateArr.length > 0) {
-            for (var i = 0; i < updateArr.length; i++) {
-                var obj = updateArr[i];
-                coeListModel.update({"libID": obj.libID, "ID": obj.ID}, updateArr[i], function(err) {
-                    if (err) {
-                        callback(true, "update fail", null);
-                    } else {
-                        callback(false, "update success", obj.ID);
-                    };
-                });
-            };
+        let functions = [];
+        for (let i = 0; i < updateArr.length; i++) {
+            let obj = updateArr[i];
+            let needSet = {};
+            for(let attr in obj){
+                if(attr !== 'libID' || attr !== 'ID'){
+                    needSet[attr] = obj[attr];
+                }
+            }
+            functions.push((function (obj) {
+                return function (cb) {
+                    coeListModel.update({"libID": obj.libID, "ID": obj.ID}, needSet, function(err) {
+                        if (err) {
+                            cb(true);
+                        } else {
+                            cb(false);
+                        }
+                    });
+                }
+            })(obj));
+        }
+        async.parallel(functions, function (err, result) {
+            if(err) callback(true, 'update fail', null);
+            else callback(false, 'updateSc', null);
+        })
     } else {
         callback(true, "no source", null);
-    };
+    }
 };
 
 coeListDAO.prototype.deleteItems = function(deleteArr, callback) {
     if (deleteArr && deleteArr.length > 0) {
-        for (var i = 0; i < deleteArr.length; i++) {
-            var obj = deleteArr[i];
-            coeListModel.remove({"libID": obj.libID, "ID": obj.ID}, function(err) {
-                if (err) {
-                    callback(true, "delete fail", null);
-                } else {
-                    callback(false, "delete success", obj.ID);
-                };
-            });
-        };
+        let functions = [];
+        for (let i = 0; i < deleteArr.length; i++) {
+            let obj = deleteArr[i];
+            functions.push((function (obj) {
+                return function (cb) {
+                    coeListModel.remove({"libID": obj.libID, "ID": obj.ID}, function(err) {
+                        if (err) {
+                            cb(true, null);
+                        } else {
+                            cb(false, obj.ID);
+                        }
+                    });
+                }
+            })(obj));
+        }
+        async.parallel(functions, function (err, result) {
+            if(err) callback(true, 'delete fail', null);
+            else callback(false, 'sc', result);
+        })
     } else {
         callback(true, "no source", null);
-    };
+    }
 };
 
 module.exports = new coeListDAO();

+ 1 - 0
modules/ration_repository/models/schemas.js

@@ -10,6 +10,7 @@ let coeSchema = new Schema({
     coeType: String,                // 系数类型,指作用范围:
                                     // 单个(如:111量0.001)、人工类、材料类、机械类、全部(如:定额×0.925)。
     gljCode: String,                  // 要调整的工料机Code(当coeType=0时有效)
+    gljName: String,
     operator: String,               // 运算符(*、+、-、=)
     amount: String,                 // 调整的量
     _id: false

+ 7 - 1
modules/std_glj_lib/controllers/gljController.js

@@ -125,7 +125,13 @@ class GljController extends BaseController{
             }
         });
     }
-
+    getGljItemsOccupied(req, res){
+        let repId = req.body.repId,
+            occupation = req.body.occupation;
+        gljDao.getGljItemsOccupied(repId, occupation, function (err, message, rst) {
+            callback(req, res, err, message, rst);
+        })
+    }
 }
 
 export default GljController;

+ 7 - 0
modules/std_glj_lib/models/gljModel.js

@@ -372,6 +372,13 @@ class GljDao  extends OprDao{
             })
         });
     }
+
+    getGljItemsOccupied(repId, occupation, callback){
+        gljModel.find({repositoryId: repId}, occupation, function (err, result) {
+            if(err) callback(true, 'fail', null);
+            else callback(false, 'sc', result);
+        });
+    }
 }
 
 export default GljDao;

+ 1 - 0
modules/std_glj_lib/routes/routes.js

@@ -36,6 +36,7 @@ module.exports = function (app) {
     router.post("/mixUpdateGljItems",gljController.auth, gljController.init, gljController.mixUpdateGljItems);
     router.post("/getGljItemsByIds",gljController.auth, gljController.init, gljController.getGljItemsByIds);
     router.post("/getGljItemsByCodes",gljController.auth, gljController.init, gljController.getGljItemsByCodes);
+    router.post("/getGljItemsOccupied",gljController.auth, gljController.init, gljController.getGljItemsOccupied);
 
     app.use("/stdGljRepository/api", router);
 

+ 1 - 1
modules/users/controllers/compilation_controller.js

@@ -263,7 +263,7 @@ class CompilationController extends BaseController {
 
             // 先存入工程专业标准库表
             let engineeringLibModel = new EngineeringLibModel();
-            let result = engineeringLibModel.addLib(valuationId, request.body);
+            let result = await engineeringLibModel.addLib(valuationId, request.body);
 
             if (!result) {
                 throw '保存失败';

+ 8 - 2
modules/users/controllers/dashboard_controller.js

@@ -6,6 +6,7 @@
  * @version
  */
 import BaseController from "../../common/base/base_controller";
+import MessageModel from "../models/message_model";
 
 class DashboardController extends BaseController {
 
@@ -31,11 +32,16 @@ class DashboardController extends BaseController {
      * @param {object} response
      * @return {void}
      */
-    index(request, response) {
+    async index(request, response) {
+        // 获取已发布的通知
+        let messageModel = new MessageModel();
+        let messageList = await messageModel.getList({status: 1}, 1, 5, {release_time: -1});
+
         let renderData = {
             parentTitle: DashboardController.parentTitle,
             parentIndex: DashboardController.parentIndex,
-            layout: 'users/views/layout/layout'
+            layout: 'users/views/layout/layout',
+            messageList: messageList
         };
         response.render('users/views/dashboard/index', renderData);
     }

+ 201 - 2
modules/users/controllers/notify_controller.js

@@ -6,6 +6,8 @@
  * @version
  */
 import BaseController from "../../common/base/base_controller";
+import MessageModel from "../models/message_model";
+import Config from "../../../config/config";
 
 class NotifyController extends BaseController {
 
@@ -16,13 +18,210 @@ class NotifyController extends BaseController {
      * @param {object} response
      * @return {void}
      */
-    index(request, response) {
+    async index(request, response) {
+        let messageModel = new MessageModel();
+        let type = request.query.type;
+        type = type === undefined ? messageModel.USER : type;
+        type = parseInt(type);
+
+        let condition = messageModel.getFilterCondition(request);
+        condition.message_type = type;
+
+        let messageList = await messageModel.getList(condition);
+
+        // 获取消息总数
+        let total = await messageModel.count();
+
+        // 获取用户通知总数
+        let userMessageTotal = await messageModel.count({message_type: messageModel.USER});
+        // 获取内部通知总数
+        let systemMessageTotal = await messageModel.count({message_type: messageModel.SYSTEM});
+
+        // 分页数据
+        let page = request.query.page === undefined ? 1 : request.query.page;
+        let pageData = {
+            current: page,
+            total: parseInt(total / Config.pageSize),
+            queryData: response.locals.urlQuery
+        };
+
         let renderData = {
-            layout: 'users/views/layout/layout'
+            layout: 'users/views/layout/layout',
+            messageList: messageList,
+            pages: pageData,
+            userMessageTotal: userMessageTotal,
+            systemMessageTotal: systemMessageTotal,
+            type: type,
+            filter: request.query
         };
         response.render('users/views/notify/index', renderData);
     }
 
+    /**
+     * 新增消息页面
+     *
+     * @param {object} request
+     * @param {object} response
+     * @return {void}
+     */
+    async add(request, response) {
+        let messageModel = new MessageModel();
+        let type = request.query.type;
+        type = type === undefined ? messageModel.USER : type;
+        type = parseInt(type);
+
+        // 获取用户通知总数
+        let userMessageTotal = await messageModel.count({message_type: messageModel.USER});
+        // 获取内部通知总数
+        let systemMessageTotal = await messageModel.count({message_type: messageModel.SYSTEM});
+
+        let renderData = {
+            layout: 'users/views/layout/layout',
+            messageData: [],
+            type: type,
+            userMessageTotal: userMessageTotal,
+            systemMessageTotal: systemMessageTotal,
+        };
+        response.render('users/views/notify/save', renderData);
+    }
+
+    /**
+     * 新增操作
+     *
+     * @param {object} request
+     * @param {object} response
+     * @return {void}
+     */
+    addMessage(request, response) {
+        let url = '/notify';
+        try {
+            let sessionUserData = request.session.managerData;
+            let messageModel = new MessageModel();
+            let result = messageModel.addData(request.body, sessionUserData.username);
+
+            if (!result) {
+                throw '新增信息失败';
+            }
+        } catch (error) {
+            console.log(error);
+            url = request.headers.referer;
+        }
+
+        response.redirect(url);
+    }
+
+    /**
+     * 编辑消息
+     *
+     * @param {object} request
+     * @param {object} response
+     * @return
+     */
+    async modify(request, response) {
+        let id = request.params.id;
+        if (id <= 0) {
+            return response.redirect('/notify');
+        }
+
+        // 查找对应数据
+        let messageModel = new MessageModel();
+        let messageData = await messageModel.findDataByCondition({_id: id});
+
+        let type = request.query.type;
+        type = type === undefined ? messageModel.USER : type;
+        type = parseInt(type);
+
+        // 获取用户通知总数
+        let userMessageTotal = await messageModel.count({message_type: messageModel.USER});
+        // 获取内部通知总数
+        let systemMessageTotal = await messageModel.count({message_type: messageModel.SYSTEM});
+
+        let renderData = {
+            layout: 'users/views/layout/layout',
+            messageData: messageData,
+            userMessageTotal: userMessageTotal,
+            systemMessageTotal: systemMessageTotal,
+            type: type
+        };
+        response.render("users/views/notify/save", renderData);
+    }
+
+    /**
+     * 修改消息
+     *
+     * @param {object} request
+     * @param {object} response
+     * @return {void}
+     */
+    async modifyMessage(request, response) {
+        let id = request.params.id;
+
+        try {
+            let sessionUserData = request.session.managerData;
+            let modifyData = request.body;
+            modifyData.last_update = sessionUserData.username;
+            // 修改对应数据
+            let messageModel = new MessageModel();
+            let result = messageModel.modifyData(id, modifyData);
+
+            if (!result) {
+                throw '修改数据失败';
+            }
+        } catch (error) {
+            console.log(error);
+        }
+        response.redirect(request.headers.referer);
+    }
+
+    /**
+     * 删除对应消息
+     *
+     * @param {object} request
+     * @param {object} response
+     * @return {void}
+     */
+    async delete(request, response) {
+        let id = request.params.id;
+
+        try {
+            // 修改对应数据
+            let messageModel = new MessageModel();
+            let result = await messageModel.deleteById(id, true);
+
+            if (!result) {
+                throw '删除数据失败';
+            }
+        } catch (error) {
+            console.log(error);
+        }
+        response.redirect('/notify');
+    }
+
+    /**
+     * 发布消息
+     *
+     * @param {object} request
+     * @param {object} response
+     * @return {void}
+     */
+    release(request, response) {
+        let id = request.params.id;
+
+        try {
+            let messageModel = new MessageModel();
+            let sessionUserData = request.session.managerData;
+            let result = messageModel.release(id, sessionUserData.username);
+
+            if (!result) {
+                throw '发布消息失败';
+            }
+        } catch (error) {
+            console.log(error);
+        }
+
+        response.redirect(request.headers.referer);
+    }
+
 }
 
 export default NotifyController;

+ 25 - 6
modules/users/models/compilation_model.js

@@ -281,14 +281,33 @@ class CompilationModel extends BaseModel {
         let sectionString = section + "_valuation";
         let condition = {};
         condition[sectionString + "._id"] = valuationId;
-        condition[sectionString + ".engineering_list.engineering"] = engineering;
 
-        let engineeringLib = await this.findDataByCondition(condition);
-        if (engineeringLib === null) {
-            return engineeringLib;
+        let compilationData = await this.findDataByCondition(condition);
+        if (compilationData === null) {
+            throw '不存在对应编办';
+        }
+        let valuationData = null;
+        for(let valuation of compilationData[sectionString]) {
+            if(valuation._id.toString() === valuationId) {
+                valuationData = valuation;
+            }
+        }
+
+        if (valuationData === null) {
+            throw '不存在对应计价规则';
         }
-        return engineeringLib[sectionString].length > 0 && engineeringLib[sectionString][0].engineering_list ?
-            engineeringLib[sectionString][0].engineering_list : {};
+
+        // 判断是否已有对应数据
+        let engineeringList = valuationData.engineering_list;
+        let engineeringLib = null;
+        for(let tmpEngineering of engineeringList) {
+            if (tmpEngineering.engineering === engineering) {
+                engineeringLib = tmpEngineering;
+                break;
+            }
+        }
+
+        return engineeringLib;
     }
 
     /**

+ 12 - 4
modules/users/models/engineering_lib_model.js

@@ -59,7 +59,13 @@ class EngineeringLibModel extends BaseModel {
         if (data.main_tree_col) {
             data.main_tree_col = JSON.parse(data.main_tree_col);
         } else {
-            delete data['main_tree_col'];
+            data.main_tree_col = {
+                emptyRows: 3,
+                headRows: 0,
+                treeCol: 0,
+                headRowHeight: [],
+                cols:[]
+            }
         }
 
         let result = false;
@@ -69,12 +75,13 @@ class EngineeringLibModel extends BaseModel {
             let compilationModel = new CompilationModel();
             let engineeringLib = await compilationModel.getEngineeringLib(valuationId, data.section, data.engineering);
 
-            let result = false;
             if (engineeringLib === null) {
                 // 不存在则插入
                 result = await this.db.create(data);
             } else {
-                engineeringLib = engineeringLib.length > 0 ? engineeringLib[0] : {};
+                delete data.id;
+                delete data.section;
+                delete data.engineering;
                 // 存在则直接更新
                 let condition = {_id: engineeringLib.engineering_id};
                 result = await this.db.update(condition, data);
@@ -96,11 +103,12 @@ class EngineeringLibModel extends BaseModel {
                     throw '新增编办数据中的专业工程失败!';
                 }
             }
+
         } catch (error) {
             console.log(error);
             result = false;
         }
-
+        console.log(result ? 'pass' : 'fail');
         return result;
     }
 

+ 183 - 0
modules/users/models/message_model.js

@@ -0,0 +1,183 @@
+/**
+ * 消息业务逻辑
+ *
+ * @author CaiAoLin
+ * @date 2017/9/21
+ * @version
+ */
+import BaseModel from "../../common/base/base_model";
+import MessageSchema from "../models/schemas/message";
+
+class MessageModel extends BaseModel {
+
+    /**
+     * 用户通知类型
+     *
+     * @var {Number}
+     */
+    USER = 1;
+
+    /**
+     * 内部通知类型
+     *
+     * @var {Number}
+     */
+    SYSTEM = 2;
+
+    /**
+     * 构造函数
+     *
+     * @return {void}
+     */
+    constructor() {
+        let parent = super();
+        parent.model = MessageSchema;
+        parent.init();
+    }
+
+    /**
+     * 设置场景
+     *
+     * @param {string} scene
+     * @return {void}
+     */
+    setScene(scene = '') {
+        switch (scene) {
+            // 新增
+            case 'add':
+                this.model.schema.path('message_type').required(true);
+                this.model.schema.path('title').required(true);
+                this.model.schema.path('content').required(true);
+                break;
+            // 修改
+            case 'modify':
+                this.model.schema.path('title').required(true);
+                this.model.schema.path('content').required(true);
+                break;
+        }
+    }
+
+    /**
+     * 获取列表
+     *
+     * @param {object} condition
+     * @param {number} page
+     * @param {Number} pageSize
+     * @param {Object} sort
+     * @return {promise}
+     */
+    async getList(condition = null, page = 1, pageSize = 30, sort = {}) {
+        page = parseInt(page);
+        page = page <= 1 ? 1 : page;
+        let option = {pageSize: pageSize, offset: parseInt((page - 1) * pageSize)};
+        option.sort = sort;
+
+        let messageList = await this.db.find(condition, null, option);
+        messageList = messageList.length > 0 ? messageList : [];
+
+        return messageList;
+    }
+
+    /**
+     * 新增消息
+     *
+     * @param {Object} data
+     * @param {String} creator
+     * @return {Promise}
+     */
+    async addData(data, creator) {
+        let result = false;
+
+        if (Object.keys(data).length <= 0 || creator === '') {
+            return result;
+        }
+
+        // 设置场景
+        this.setScene('add');
+
+        data.create_time = new Date().getTime();
+        data.creator = creator;
+
+        result = await this.db.create(data);
+
+        return result;
+    }
+
+    /**
+     * 修改消息
+     *
+     * @param {Number} id
+     * @param {Object} data
+     * @return {Promise}
+     */
+    async modifyData(id, data) {
+        let messageData = await this.findDataByCondition({_id: id});
+        if (messageData === null) {
+            throw '不存在对应数据';
+        }
+
+        this.setScene('modify');
+        data.update_time = new Date().getTime();
+        return await this.updateById(id, data);
+    }
+
+    /**
+     * 发布消息
+     *
+     * @param {String} id
+     * @param {String} releaseUser
+     * @return {Promise}
+     */
+    async release(id, releaseUser) {
+        let data = {
+            status: 1,
+            release_time: new Date().getTime(),
+            release_user: releaseUser
+        };
+
+        return await this.updateById(id, data);
+    }
+
+    /**
+     * 获取过滤条件
+     *
+     * @return {Object}
+     */
+    getFilterCondition(request) {
+        let condition = {};
+        let status = request.query.status;
+        status = status !== '' && status !== undefined ? parseInt(status) : '';
+        if (status !== '') {
+            condition.status = status;
+        }
+
+        let year = request.query.year;
+        let month = request.query.month;
+        let startMonth = 1;
+        let endMonth = 12;
+        let lastDate = 31;
+
+        if (month !== undefined && month !== '') {
+            year = year !== undefined && year !== '' ? year : new Date().getYear();
+            let datetime = new Date(year, month, 0);
+            lastDate = datetime.getDate();
+            startMonth = month;
+            endMonth = month;
+        }
+
+        if (year !== undefined || month !== undefined) {
+            let startTime = Date.parse(new Date(year + '-'+ startMonth +'-1 00:00:00'));
+            let endTime =  Date.parse(new Date(year + '-'+ endMonth +'-'+ lastDate +' 23:59:59'));
+            condition.create_time = {'$gte': startTime, '$lt': endTime};
+        }
+
+        let keyword = request.query.keyword;
+        if (keyword !== '' && keyword !== undefined) {
+            condition.title = keyword;
+        }
+
+        return condition;
+    }
+}
+
+export default MessageModel;

+ 51 - 0
modules/users/models/schemas/message.js

@@ -0,0 +1,51 @@
+/**
+ * 消息通知数据模型
+ *
+ * @author CaiAoLin
+ * @date 2017/9/21
+ * @version
+ */
+import mongoose from "mongoose";
+
+let Schema = mongoose.Schema;
+let collectionName = 'message';
+let modelSchema = {
+    // 消息标题
+    title: String,
+    // 消息内容
+    content: String,
+    // 消息类型
+    message_type: {
+        type: Number,
+        default: 1
+    },
+    // 消息状态
+    status: {
+        type: Number,
+        default: 0
+    },
+    // 发布时间
+    release_time: {
+        type: Number,
+        default: 0
+    },
+    // 创建时间
+    create_time: Number,
+    // 最后修改时间
+    update_time: {
+        type: Number,
+        default: 0
+    },
+    // 创建者
+    creator: String,
+    // 发布者
+    release_user: String,
+    // 最后修改人
+    last_update: {
+        type: String,
+        default: ''
+    }
+
+};
+let model = mongoose.model(collectionName, new Schema(modelSchema, {versionKey: false, collection: collectionName}));
+export {model as default, collectionName as collectionName};

+ 7 - 0
modules/users/routes/notify_route.js

@@ -14,6 +14,13 @@ const notifyController = new NotifyController();
 module.exports =function (app) {
     // action定义区域
     router.get('/', notifyController.auth, notifyController.init, notifyController.index);
+    router.get('/add', notifyController.auth, notifyController.init, notifyController.add);
+    router.get('/modify/:id', notifyController.auth, notifyController.init, notifyController.modify);
+    router.get('/delete/:id', notifyController.auth, notifyController.init, notifyController.delete);
+    router.get('/release/:id', notifyController.auth, notifyController.init, notifyController.release);
+
+    router.post('/add', notifyController.auth, notifyController.init, notifyController.addMessage);
+    router.post('/modify/:id', notifyController.auth, notifyController.init, notifyController.modifyMessage);
 
     app.use("/notify", router);
 };

+ 10 - 0
public/web/sheet/sheet_common.js

@@ -8,6 +8,7 @@ var sheetCommonObj = {
         var me = this;
         var spreadBook = new GC.Spread.Sheets.Workbook(container, { sheetCount: SheetCount });
         spreadBook.options.allowCopyPasteExcelStyle = false;
+        spreadBook.options.allowExtendPasteRange = true;
         spreadBook.options.tabStripVisible = false;
         //spreadBook.options.showHorizontalScrollbar = false;
         spreadBook.options.allowUserDragDrop = false;
@@ -356,6 +357,15 @@ var sheetCommonObj = {
         sheet.resumePaint();
         sheet.resumeEvent();
     },
+    setLockCol: function (sheet, col, isLocked) {
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        for(let row = 0, len = sheet.getRowCount(); row < len; row++){
+            sheet.getCell(row, col).locked(isLocked);
+        }
+        sheet.resumePaint();
+        sheet.resumeEvent();
+    },
     chkIfEmpty: function(rObj, setting) {
         var rst = true;
         if (rObj) {

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

@@ -448,14 +448,17 @@
                 sheetCommonObj.shieldAllCells(rdSpread.getSheet(2), rationCoeOprObj.setting);
 
                 $("#linkGLJ").click(function(){
+                    rationGLJOprObj.bindRationGljDelOpr();
                     rdSpread.setActiveSheetIndex(0);
                 });
 
                 $("#linkFZDE").click(function(){
+                    rationGLJOprObj.unBindDel();
                     rdSpread.setActiveSheetIndex(1);
                 });
 
                 $("#linkFZTJ").click(function(){
+                    rationCoeOprObj.bindRationCoeDel();
                     rdSpread.setActiveSheetIndex(2);
                 });
             });

+ 24 - 3
web/maintain/ration_repository/fuzhu.html

@@ -9,7 +9,7 @@
     <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css">
     <link rel="stylesheet" href="/web/maintain/ration_repository/css/main.css">
     <link rel="stylesheet" href="/lib/font-awesome/font-awesome.min.css">
-    <link rel="stylesheet" href="/lib/spreadjs/sheets/css/gc.spread.sheets.10.0.1.css" type="text/css">
+    <link rel="stylesheet" href="/lib/spreadjs/sheets/css/gc.spread.sheets.excel2013lightGray.10.0.1.css" type="text/css">
     <!--zTree-->
     <link rel="stylesheet" href="/lib/ztree/css/zTreeStyle.css" type="text/css">
 </head>
@@ -42,7 +42,7 @@
               </ul>
         </nav>
     </div>
-    <div class="main">
+   <!-- <div class="main">
         <div class="content">
             <div class="container-fluid">
                 <div class="row">
@@ -55,6 +55,22 @@
                 </div>
             </div>
         </div>
+    </div>-->
+    <div class="main">
+        <div class="content">
+            <div class="container-fluid">
+                <div class="row">
+                    <div class="main-content col-lg-7 p-0">
+                        <div class="main-data" id="mainSpread">
+                        </div>
+                    </div>
+                    <div class="main-side col-lg-5 p-0">
+                        <div class="main-data" id="contentSpread" >
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
     </div>
 
     <!-- JS. -->
@@ -70,11 +86,16 @@
     <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 src="/public/web/sheet/sheet_creater.js"></script>
     <script src="/public/common_util.js"></script>
     <script src="/public/debug.js"></script>
+    <script type="text/javascript" src="/public/web/sheet/sheet_common.js"></script>
     <script type="text/javascript" src="/public/web/storageUtil.js"></script>
     <script type="text/javascript" src="/web/maintain/ration_repository/js/coe.js"></script>
+    <script type="text/javascript">
+        $(document).ready(function () {
+            pageObj.initPage();
+        });
+    </script>
    <!-- <SCRIPT type="text/javascript">
   		&lt;!&ndash;
   		var setting = {

+ 474 - 219
web/maintain/ration_repository/js/coe.js

@@ -1,8 +1,12 @@
 /**
  * Created by CSL on 2017-05-18.
  */
+//modiyied by zhong on 2017/9/21
+
 
 var pageObj = {
+    libID: null,
+    gljLibID: null,
     initPage: function (){
         $("#drirect-dinge").click(function(){
             $(this).attr('href', "/rationRepository/ration" + "?repository=" + getQueryString("repository"))
@@ -19,263 +23,514 @@ var pageObj = {
             html = html.replace("XXX定额库", libName);
             $("#rationname")[0].outerHTML = html;
         };
+        this.gljLibID = storageUtil.getSessionCache("gljLib", "repositoryID_" + libID);
+        this.libID = libID;
+        coeOprObj.buildSheet($('#mainSpread')[0]);
+        gljAdjOprObj.buildSheet($('#contentSpread')[0]);
+        coeOprObj.getCoeList();
+        gljAdjOprObj.getGljItemsOcc();
 
-        coeList.show();
+    },
+    showData: function(sheet, setting, data) {
+        let me = pageObj, ch = GC.Spread.Sheets.SheetArea.viewport;
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        sheet.clear(0, 0, sheet.getRowCount(), sheet.getColumnCount(), GC.Spread.Sheets.SheetArea.viewport, GC.Spread.Sheets.StorageType.data);
+        sheet.setRowCount(data.length + 3);
+        for (let col = 0; col < setting.header.length; col++) {
+            var hAlign = "left", vAlign = "center";
+            if (setting.header[col].hAlign) {
+                hAlign = setting.header[col].hAlign;
+            } else if (setting.header[col].dataType !== "String"){
+                hAlign = "right";
+            }
+            if(setting.header[col].readOnly){
+                sheet.getRange(-1, col, -1, 1).locked(true);
+            }
+            else{
+                sheet.getRange(-1, col, -1, 1).locked(false);
+            }
+            vAlign = setting.header[col].vAlign?setting.header[col].vAlign:vAlign;
+            sheetCommonObj.setAreaAlign(sheet.getRange(-1, col, -1, 1), hAlign, vAlign);
+            if (setting.header[col].formatter) {
+                sheet.setFormatter(-1, col, setting.header[col].formatter, GC.Spread.Sheets.SheetArea.viewport);
+            }
+            for (let row = 0; row < data.length; row++) {
+                let val = data[row][setting.header[col].dataCode];
+                sheet.setValue(row, col, val, ch);
+            }
+        }
+        sheet.resumeEvent();
+        sheet.resumePaint();
     }
 };
 
-var coeList = {
-    mainSpread: null,
-    detailSpread: null,
-    datas: [],
-    libID: Number,
-    tempID: -999999,       // 本地新增一条数据给的默认ID,用作标记,服务端返回新ID后替换该ID
-
-    colDefMain: [
-        {name: "ID", displayName: "ID", size: 60, hAlign: "center", readOnly: true},
-        {name: "name", displayName: "名称", size: 280},
-        {name: "content", displayName: "内容", size: 250}
-    ],
-    colDefContent: [
-        {name: "coeType", displayName: "类型", size: 100, hAlign: "center"},
-        {name: "gljCode", displayName: "工料机编号", size: 100, dataType: "String", formatter: "@", hAlign: "center"},
-        {name: "operator", displayName: "操作符", size: 60, hAlign: "center"},
-        {name: "amount", displayName: "数量", size: 80, hAlign: "right"}
-    ],
-
-    show: function (){
-        var me = this;
-        me.libID = getQueryString("repository");
-        me.getDatas();
-        me.mainSpread = sheetObj.create($('#mainSpread')[0], me.colDefMain, me.datas);
-        me.detailSpread = sheetObj.create($('#contentSpread')[0], me.colDefContent, me.datas[0].coes);
-
-        var coeType = new GC.Spread.Sheets.CellTypes.ComboBox();
-        coeType.items(["单个","定额","人工","材料","机械"]);
-        me.detailSpread.getSheet(0).getRange(-1, 0, -1, 1).cellType(coeType);
-
-        var operType = new GC.Spread.Sheets.CellTypes.ComboBox();
-        operType.items(["+","-","*","/","="]);
-        me.detailSpread.getSheet(0).getRange(-1, 2, -1, 1).cellType(operType);
-
-        me.detailSpread.options.showVerticalScrollbar = false;
-
-        me.mainSpread.getSheet(0).bind(GC.Spread.Sheets.Events.EnterCell, me.onMainEnterCell);
-        me.mainSpread.getSheet(0).bind(GC.Spread.Sheets.Events.CellChanged, me.onMainCellChanged);
-        me.mainSpread.getSheet(0).bind(GC.Spread.Sheets.Events.RangeChanged, me.onMainRangeChanged);
-
-        me.detailSpread.getSheet(0).bind(GC.Spread.Sheets.Events.CellChanged, me.onDetailCellChanged);
-        me.detailSpread.getSheet(0).bind(GC.Spread.Sheets.Events.RangeChanged, me.onDetailRangeChanged);
+let coeOprObj = {
+    workBook: null,
+    workSheet: null,
+    currentCoeList: [],
+    currentCoe: null,
+    //currentMaxNo: null,
+    setting: {
+        header: [
+            {headerName:"编号", headerWidth:60, dataCode:"ID", dataType: "String", hAlign: "center", vAlign: "center", readOnly: true},
+            {headerName:"名称", headerWidth:280, dataCode:"name", dataType: "String", hAlign: "left", vAlign: "center", readOnly: false},
+            {headerName:"内容", headerWidth:250, dataCode:"content", dataType: "String", hAlign: "left", vAlign: "center", readOnly: false},
+        ]
     },
+    buildSheet: function (container) {
+        let me = coeOprObj;
+        me.workBook = sheetCommonObj.buildSheet(container, me.setting, 30);
+        me.workSheet = me.workBook.getSheet(0);
+        me.workSheet.options.isProtected = true;
+        me.onDelOpr(me.workBook, me.setting);
+        me.workSheet.bind(GC.Spread.Sheets.Events.SelectionChanged, me.onSelectionChanged);
+        me.workSheet.bind(GC.Spread.Sheets.Events.EditEnded, me.onEditEnded);
+        me.workBook.bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting);
+        me.workBook.bind(GC.Spread.Sheets.Events.ClipboardPasted, me.onClipboardPasted);
+    },
+    onSelectionChanged: function (sender, info) {
+        let me = coeOprObj, that = gljAdjOprObj;
+        if(info.oldSelections.length === 0 && info.newSelections.length > 0 || info.oldSelections[0].row !== info.newSelections[0].row){
+            let row = info.newSelections[0].row;
+            if(row < me.currentCoeList.length){
+                me.currentCoe = me.currentCoeList[row];
+                that.currentGljAdjList = me.currentCoe.coes;
+            }
+            else{
+                me.currentCoe = null;
+                that.currentGljAdjList = [];
+            }
+            //refresh & show coes
+            sheetCommonObj.cleanSheet(that.workSheet, that.setting, -1);
+            me.workBook.focus(true);
+            that.show(that.currentGljAdjList);
+        }
+    },
+    onEditEnded: function (sender, args) {
+        let me = coeOprObj, addArr = [], updateArr = [], dataCode = me.setting.header[args.col].dataCode;
+        if(args.editingText && args.editingText.toString().trim().length > 0){
+            //update
+            if(args.row < me.currentCoeList.length){
+                let updateObj = me.currentCoeList[args.row];
+                if(updateObj[dataCode] !== args.editingText.toString().trim()){
+                    updateObj[dataCode] = args.editingText;
+                    updateArr.push(updateObj);
+                    me.save([], updateArr, [], true);
+                }
+            }
+            //insert
+            else{
+                let newCoe = {};
+                //me.currentMaxNo ++;
+                newCoe.libID = pageObj.libID;
+                //newCoe.serialNo = me.currentMaxNo;
+                newCoe[dataCode] = args.editingText;
+                addArr.push(newCoe);
+                me.save(addArr, [], [], true, function (result) {
+                    me.updateCurrentCoeList(result);
+                });
+            }
+        }
+    },
+    onClipboardPasting: function (sender, info) {
+        let me = coeOprObj, maxCol = info.cellRange.col + info.cellRange.colCount - 1;
+        if(maxCol > me.setting.header.length){
+            info.cancel = true;
+        }
+    },
+    onClipboardPasted: function (sender, info) {
+        let me = coeOprObj, addArr = [], updateArr = [];
+        let items = sheetCommonObj.analyzePasteData(me.setting, info);
+        for(let i = 0, len = items.length; i < len; i++){
+            let row = i + info.cellRange.row;
+            //update
+            if(row < me.currentCoeList.length){
+                let updateObj = me.currentCoeList[row];
+                for(let attr in items[i]){
+                    updateObj[attr] = items[i][attr];
+                }
+                updateArr.push(updateObj);
+            }
+            //insert
+            else {
+                //items[i].serialNo = ++ me.currentMaxNo;
+                items[i].libID = pageObj.libID;
+                addArr.push(items[i]);
+            }
+        }
+        if(addArr.length > 0 || updateArr.length > 0){
+            me.save(addArr, updateArr, [], true, function (result) {
+                me.updateCurrentCoeList(result)
+            });
+        }
+    },
+    onDelOpr: function (workBook, setting) {
+        let me = coeOprObj, that = gljAdjOprObj;
+        workBook.commandManager().register('coeListDel', function () {
+            let deleteArr = [];
+            let sheet = workBook.getSheet(0);
+            let sels = sheet.getSelections();
+            let idx = sels[0].row;
+            for(let i = 0, len = sels.length; i < len; i++){
+                if(idx > sels[i].row){
+                    idx = sels[i].row;
+                }
+                if(sels[i].colCount === setting.header.length){//can del
+                    for(let r = 0, rLen = sels[i].rowCount; r < rLen; r++){
+                        let row = sels[i].row + r;
+                        if(row < me.currentCoeList.length){
+                            deleteArr.push({libID: me.currentCoeList[row].libID, ID: me.currentCoeList[row].ID});
+                        }
+                    }
+                    me.currentCoeList.splice(sels[i].row, sels[i].rowCount);
+                }
+            }
+            if(deleteArr.length > 0){
+                me.save([], [], deleteArr, true);
+                me.currentCoe = typeof me.currentCoeList[idx] !== 'undefined' ? me.currentCoeList[idx] : null;
+                that.currentGljAdjList = me.currentCoe ? me.currentCoe.coes : [];
+                gljAdjOprObj.show(that.currentGljAdjList);
+            }
 
-    getDatas: function () {
-        var me = this;
-
+        });
+        workBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false);
+        workBook.commandManager().setShortcutKey('coeListDel', GC.Spread.Commands.Key.del, false, false, false, false);
+    },
+    updateCurrentCoeList: function (newCoeList) {
+        let me = coeOprObj;
+        me.currentCoeList = me.currentCoeList.concat(newCoeList);
+        me.sortCoeList(me.currentCoeList);
+    },
+    sortCoeList: function (coeList) {
+        coeList.sort(function (a, b) {
+            let rst = 0;
+            if(a.ID > b.ID) rst = 1;
+            else if(a.ID < b.ID) rst = -1;
+            return rst;
+        });
+    },
+    getCoeList: function () {
+        let me = coeOprObj;
         $.ajax({
-            type:"POST",
-            url:"/rationRepository/api/getCoeList",
-            data:{"libID": me.libID},
-            dataType:"json",
-            cache:false,
-            async: false,
+            type: 'post',
+            url: '/rationRepository/api/getCoeList',
+            data: {libID: pageObj.libID},
+            dataType: 'json',
             timeout:20000,
             success: function (result) {
-                if (result.data) {
-                    me.datas = result.data;
-                };
+                if(!result.error){
+                    me.currentCoeList = result.data;
+                    me.sortCoeList(me.currentCoeList);
+                    //me.currentMaxNo =  me.currentCoeList.length > 0 ? me.currentCoeList[me.currentCoeList.length - 1].serialNo : 0;
+                    pageObj.showData(me.workSheet, me.setting, me.currentCoeList);
+                    me.workSheet.clearSelection();
+                }
             },
-            error: function (result) {
-                alert('内部程序错误!');
+            error:function(err){
+                alert("内部程序错误!");
             }
-        })
+        });
     },
-
-    /*getLibID: function(libName){
-        var me = this;
+    save: function (addArr, updateArr, deleteArr, refresh, callback) {
+        let me = coeOprObj;
         $.ajax({
             type:"POST",
-            url:"/rationRepository/api/getLibIDByName",
-            data:{"libName": libName},
+            url:"api/saveCoeList",
+            data: {data: JSON.stringify({addArr: addArr, updateArr: updateArr, deleteArr: deleteArr})},
             dataType:"json",
-            cache:false,
-            async: false,
-            timeout:20000,
-            success: function (result) {
-                if (result.data) {
-                    me.libID = result.data;
+            timeout:5000,
+            success:function(result){
+                if (result.error) {
+                    alert(result.message);
+                } else{
+                    if(callback){
+                        if(result.message === 'mixed'){
+                            for(let i = 0, len = result.data.length; i < len; i++){
+                                if(result.data[i][0] === 'addSc'){
+                                    result.data = result.data[i][1];
+                                    break;
+                                }
+                            }
+                        }
+                        callback(result.data);
+                    }
+                    if(refresh){
+                        pageObj.showData(me.workSheet, me.setting, me.currentCoeList);
+                    }
                 }
             },
-            error: function (result) {
-                alert('内部程序错误!');
+            error:function(err){
+                alert("内部程序错误!");
             }
-        })
-    },*/
-
-    onMainEnterCell: function(sender, args) {
-        var me = coeList;
-        var row = args.sheet.getActiveRowIndex();
-        me.detailSpread.suspendPaint();
+        });
+    }
+};
 
-        var dSheet = me.detailSpread.getSheet(0);
-        var dData = me.datas[row].coes;
-        if (dData == undefined){
-            dSheet.setDataSource([]);
-            dSheet.setRowCount(0);
-        }else{
-            dSheet.setDataSource(dData);
-            me.showNullRow(dSheet);
-        };
-        me.detailSpread.resumePaint();
+let gljAdjOprObj = {
+    workBook: null,
+    workSheet: null,
+    currentGljAdjList: [],
+    gljList: [],//只含编号和名称的总工料机列表
+    setting: {
+        header: [
+            {headerName:"调整类型", headerWidth:100, dataCode:"coeType", dataType: "String", hAlign: "center", vAlign: "center", readOnly: false},
+            {headerName:"工料机编码", headerWidth:100, dataCode:"gljCode", dataType: "String", formatter: '@', hAlign: "center", vAlign: "center", readOnly: false},
+            {headerName:"名称", headerWidth:100, dataCode:"gljName", dataType: "String", hAlign: "center", vAlign: "center", readOnly: true},
+            {headerName:"操作符", headerWidth:60, dataCode:"operator", dataType: "String", hAlign: "center", vAlign: "center", readOnly: false},
+            {headerName:"数量", headerWidth:80, dataCode:"amount", dataType: "String", hAlign: "center", vAlign: "center" , readOnly: false},
+        ],
+        comboItems: {
+            //调整类型下拉菜单
+            coeType: ['定额子目', '人工类', '材料类', '机械类', '主材类', '设备类', '单个工料机'],
+            //操作符下拉菜单
+            operator: ['+', '-', '*', '/', '=']
+        }
     },
-
-    onMainCellChanged: function(sender, args) {
-        if (args.propertyName !== "value"){return;};
-        var me = coeList;
-        var row = args.sheet.getActiveRowIndex();
-        var obj = me.datas[row];
-
-        if (obj.ID == undefined){           // 空行录入,即新增
-            obj.libID = me.libID;
-            obj.ID = me.tempID;
-            if (obj.name == undefined){obj.name = '';};     // 生成属性,令属性存储顺序一致
-            if (obj.content == undefined){obj.content = '';};
-            obj.coes = [{coeType:"定额", operator:"*", amount: "0"}];
-            me.datas[row] = obj;
-
-            me.save([obj],[],[]);
-
-            me.detailSpread.suspendPaint();
-            me.detailSpread.getSheet(0).setDataSource(me.datas[row].coes);
-            me.detailSpread.resumePaint();
-            var sheet = me.mainSpread.getSheet(0);
-            me.showNullRow(sheet);
+    buildSheet: function (container) {
+        let me = gljAdjOprObj;
+        me.workBook = sheetCommonObj.buildSheet(container, me.setting, 3);
+        me.workSheet = me.workBook.getSheet(0);
+        me.workSheet.options.isProtected = true;
+        me.onDelOpr(me.workBook, me.setting);
+        me.workSheet.clearSelection();
+        me.buildComboBox(me.workSheet);
+        me.workSheet.bind(GC.Spread.Sheets.Events.EditStarting, me.onEditStart);
+        me.workSheet.bind(GC.Spread.Sheets.Events.EditEnded, me.onEditEnded);
+        me.workSheet.bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting);
+        me.workSheet.bind(GC.Spread.Sheets.Events.ClipboardPasted, me.onClipboardPasted);
+    },
+    buildComboBox: function (sheet) {
+        let me = gljAdjOprObj;
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        let comboType = new GC.Spread.Sheets.CellTypes.ComboBox();
+        comboType.items(me.setting.comboItems.coeType);
+        let comboOpr = new GC.Spread.Sheets.CellTypes.ComboBox();
+        comboOpr.items(me.setting.comboItems.operator);
+        sheet.getCell(-1, 0).cellType(comboType);
+        sheet.getCell(-1, 3).cellType(comboOpr);
+        sheet.resumePaint();
+        sheet.resumeEvent();
+    },
+    onEditStart: function (sender, args) {
+        let me = gljAdjOprObj;
+        if(!coeOprObj.currentCoe || args.row >= me.currentGljAdjList.length && args.col === 1
+            || args.row < me.currentGljAdjList.length && args.col === 1 && me.currentGljAdjList[args.row].coeType !== '单个工料机'){
+            args.cancel = true;
+        }
+    }
+    ,
+    onEditEnded: function (sender, args) {
+        let me = gljAdjOprObj, isUpdate = false,
+            dataCode = me.setting.header[args.col].dataCode;
+        if(args.editingText && args.editingText.toString().trim().length > 0){
+            if(dataCode === 'amount' &&  isNaN(args.editingText)){
+                args.sheet.setValue(args.row, args.col, typeof me.currentGljAdjList[args.row] !== 'undefined' && typeof me.currentGljAdjList[args.row][dataCode] !== 'undefined'
+                    ? me.currentGljAdjList[args.row][dataCode] + '' : '');
+                alert("只能输入数值!");
+            }
+            else {
+                //update
+                if(args.row < me.currentGljAdjList.length && args.editingText.toString().trim() !== me.currentGljAdjList[args.row][dataCode]){
+                    let updateObj = me.currentGljAdjList[args.row];
+                    if(dataCode === 'gljCode' && typeof updateObj.coeType !== 'undefined' && updateObj.coeType === '单个工料机'){
+                        let gljName = me.getGljName(args.editingText, me.gljList);
+                        if(gljName){
+                            updateObj.gljCode = args.editingText;
+                            updateObj.gljName = gljName;
+                            isUpdate = true;
+                        }
+                        else {
+                            alert("不存在编号为"+ args.editingText +"的工料机");
+                        }
+                    }
+                    else if(dataCode !== 'gljCode') {
+                        isUpdate = true;
+                        updateObj[dataCode] = args.editingText;
+                    }
+                }
+                //insert
+                else if(args.row >= me.currentGljAdjList.length){
+                    isUpdate = true;
+                    let newAdjGlj = {};
+                    newAdjGlj[dataCode] = args.editingText;
+                    me.currentGljAdjList.push(newAdjGlj);
+                }
+                if(isUpdate){
+                    coeOprObj.save([], [coeOprObj.currentCoe], [], false, function () {
+                        me.show(me.currentGljAdjList);
+                    });
+                }
+                else {
+                    args.sheet.setValue(args.row, args.col, typeof me.currentGljAdjList[args.row] !== 'undefined' && typeof me.currentGljAdjList[args.row][dataCode] !== 'undefined'
+                        ? me.currentGljAdjList[args.row][dataCode] + '' : '');
+                }
+            }
         }
-        else{ // 正常修改
-            me.save([],[],[obj]);
-        };
     },
+    onClipboardPasting: function (sender, info) {
 
-    onMainRangeChanged: function(sender, args) {
-        if (args.action == GC.Spread.Sheets.RangeChangedAction.clear) {
-            if (!confirm('确定要删除本条附注条件吗?')){ args.cancel = true; return; }
-            var me = coeList;
-            var obj = me.datas[args.row];
-            me.save([],[obj],[]);
-            args.sheet.deleteRows(args.row, 1);
-        };
     },
-    
-    onDetailCellChanged: function(sender, args) {
-        if (args.propertyName !== "value"){return;};
-
-        var me = coeList;
-        var mainRow = me.mainSpread.getSheet(0).getActiveRowIndex();
-        var detailRow = args.sheet.getActiveRowIndex();
-        var detailDatas = me.datas[mainRow].coes;
-        var curDetailData = detailDatas[detailRow];
-
-        if (curDetailData !== undefined){       // 当在空白行输入时,curDetailData为undefined。
-            var curType = curDetailData.coeType;
-            if (curType !== '单个'){
-                me.detailSpread.suspendPaint();
-                curDetailData.gljCode = null;
-                me.detailSpread.resumePaint();
-            };
-
-            if (curDetailData.operator == undefined){ curDetailData.operator = "*"; } ;
-            if (curDetailData.amount == undefined){ curDetailData.amount = "0"; } ;
-        };
-
-/*        var curType = args.sheet.getValue(detailRow, 0);
-        if (curType !== '单个'){
-            me.detailSpread.suspendEvent();
-            args.sheet.setValue(detailRow, 1, null);
-            me.detailSpread.resumeEvent();
-            //args.sheet.getCell(row, 1).backColor("red");
+    getValidPasteDatas: function (pasteItems, info) {
+        let me = gljAdjOprObj;
+        let rst = [];
+        for(let i = 0, len = pasteItems.length; i < len; i++){
+            let row = i + info.cellRange.row;
+            let validObj = {};
+            //update
+            if(row < me.currentGljAdjList.length){
+                let updateObj = me.currentGljAdjList[row];
+                if(typeof pasteItems[i].coeType !== 'undefined' && typeof pasteItems[i].gljCode !== 'undefined'){
+                    let gljName = me.getGljName(pasteItems[i].gljCode, me.gljList);
+                    if(pasteItems[i].coeType === '单个工料机' && gljName){
+                        validObj.coeType = pasteItems[i].coeType;
+                        validObj.gljCode = pasteItems[i].gljCode;
+                        validObj.gljName = gljName;
+                    }
+                    else if(pasteItems[i].coeType !== '单个工料机' && me.setting.comboItems.coeType.indexOf(pasteItems[i].coeType) !== -1){
+                        validObj.coeType = pasteItems[i].coeType;
+                    }
+                }
+                else if(typeof pasteItems[i].coeType === 'undefined' && typeof pasteItems[i].gljCode !== 'undefined'){
+                    let gljName = me.getGljName(pasteItems[i].gljCode, me.gljList);
+                    if(typeof updateObj.coeType !== 'undefined' && updateObj.coeType === '单个工料机' && gljName){
+                        validObj.gljCode = pasteItems[i].gljCode;
+                        validObj.gljName = gljName;
+                    }
+                }
+                else if(typeof pasteItems[i].coeType !== 'undefined' && typeof pasteItems[i].gljCode === 'undefined'){
+                    if(me.setting.comboItems.coeType.indexOf(pasteItems[i].coeType) !== -1){
+                        validObj.coeType = pasteItems[i].coeType;
+                        if(validObj.coeType !== '单个工料机' && typeof updateObj.gljCode !== '单个工料机' && updateObj.gljCode.toString().trim().length > 0){
+                            validObj.gljCode = '';
+                            validObj.gljName = '';
+                        }
+                    }
+                }
+                else {
+                    if(typeof pasteItems[i].operator !== 'undefined' && me.setting.comboItems.operator.indexOf(pasteItems[i].operator) !== -1){
+                        validObj.operator = pasteItems[i].operator;
+                    }
+                    if(typeof pasteItems[i].amount !== 'undefined' && !isNaN(pasteItems[i].amount)){
+                        validObj.amount = pasteItems[i].amount;
+                    }
+                }
+            }
+            else {
+                if(typeof pasteItems[i].coeType !== 'undefined' && typeof pasteItems[i].gljCode !== 'undefined'){
+                    let gljName = me.getGljName(pasteItems[i].gljCode, me.gljList);
+                    if(pasteItems[i].coeType === '单个工料机' && gljName){
+                        validObj.coeType = pasteItems[i].coeType;
+                        validObj.gljCode = pasteItems[i].gljCode;
+                        validObj.gljName = gljName;
+                    }
+                    else if(pasteItems[i].coeType !== '单个工料机' && me.setting.comboItems.coeType.indexOf(pasteItems[i].coeType) !== -1){
+                        validObj.coeType = pasteItems[i].coeType;
+                    }
+                }
+                else if(typeof pasteItems[i].gljCode === 'undefined') {
+                    if(typeof pasteItems[i].coeType !== 'undefined' && me.setting.comboItems.coeType.indexOf(pasteItems[i].coeType) !== -1){
+                        validObj.coeType = pasteItems[i].coeType;
+                    }
+                    if(typeof pasteItems[i].operator !== 'undefined' && me.setting.comboItems.operator.indexOf(pasteItems[i].operator) !== -1){
+                        validObj.operator = pasteItems[i].operator;
+                    }
+                    if(typeof pasteItems[i].amount !== 'undefined' && !isNaN(pasteItems[i].amount)){
+                        validObj.amount = pasteItems[i].amount;
+                    }
+                }
+            }
+            if(Object.keys(validObj).length > 0){
+                rst.push(validObj);
+            }
         }
-        else{
-            //args.sheet.getCell(row, 1).backColor("Blue");
-        };*/
-
-
-        var obj = me.datas[mainRow];
-        me.save([],[],[obj]);
-
-        me.showNullRow(args.sheet);
+        return rst;
     },
-
-    onDetailRangeChanged: function(sender, args) {
-        if (args.action == GC.Spread.Sheets.RangeChangedAction.clear) {
-            if (!confirm('确定要删除该类型的明细数据吗?')){ args.cancel = true; return; }
-            var me = coeList;
-            var detailData = args.sheet.getDataSource();
-            args.sheet.deleteRows(args.row, 1);
-            var mainRow = me.mainSpread.getSheet(0).getActiveRowIndex();
-            var obj = me.datas[mainRow];
-            me.save([],[],[obj]);
-        };
+    onClipboardPasted: function (sender, info) {
+        let me = gljAdjOprObj, row;
+        let items = sheetCommonObj.analyzePasteData(me.setting, info);
+        let validDatas = me.getValidPasteDatas(items, info);
+        for(let i = 0, len = validDatas.length; i < len; i++){
+            row = i + info.cellRange.row;
+            //update
+            if(row < me.currentGljAdjList.length){
+                let updateObj = me.currentGljAdjList[row];
+                for(let attr in validDatas[i]){
+                    updateObj[attr] = validDatas[i][attr];
+                }
+            }
+            //insert
+            else{
+                me.currentGljAdjList.push(validDatas[i]);
+            }
+        }
+        if(validDatas.length > 0){
+            coeOprObj.save([], [coeOprObj.currentCoe], [], false, function () {
+                me.show(me.currentGljAdjList);
+            });
+        }
+        else {
+            me.show(me.currentGljAdjList);
+        }
     },
-
-    showNullRow: function(sheet){
-        var datas = sheet.getDataSource();
-        //alert('004: datas.length: ' + datas.length + ', sheet.getRowCount: ' + sheet.getRowCount());
-        var lastData = datas[datas.length - 1];
-        if (!$.isEmptyObject(lastData)){
-            sheet.addRows(sheet.getRowCount(), 1);
-            //alert('005: datas.length: ' + datas.length + ', sheet.getRowCount: ' + sheet.getRowCount());
-        };
+    onDelOpr: function (workBook, setting) {
+        let me = gljAdjOprObj;
+        workBook.commandManager().register('gljAdjDel', function () {
+            let sheet = workBook.getSheet(0);
+            let sels = sheet.getSelections();
+            let isUpdate = false;
+            for(let i = 0, len = sels.length; i < len; i++){
+                if(sels[i].colCount === setting.header.length){//can del
+                    if(sels[i].row < me.currentGljAdjList.length){
+                        isUpdate = true;
+                        me.currentGljAdjList.splice(sels[i].row, sels[i].rowCount);
+                    }
+                }
+            }
+            if(isUpdate){
+                coeOprObj.save([], [coeOprObj.currentCoe], [], false, function () {
+                    me.show(me.currentGljAdjList);
+                });
+            }
+        });
+        workBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false);
+        workBook.commandManager().setShortcutKey('gljAdjDel', GC.Spread.Commands.Key.del, false, false, false, false);
     },
-
-    save: function(addArr, deleteArr, updateArr) {
-        var me = coeList;
-
-        //var addArrTemp = [];
-        //var deleteArrTemp = [];
-        var updateArrTemp = [];
-
-        // 空行会产生空对象数据,清理空对象会给sheet的空行效果带来奇怪的干扰,这里要中转一下。
-        if (updateArr.length > 0){
-            $.extend(true, updateArrTemp, updateArr);
-            //debug.d('011: ', updateArrTemp);
-            //debug.d('012: ', updateArr);
-            deleteEmptyObject(updateArrTemp[0].coes);
-            //debug.d('013: ', updateArrTemp);
-            //debug.d('014: ', updateArr);
-            //return;
-        };
-
+    getGljName: function (gljCode, gljList) {
+        let rst = null;
+        for(let i = 0, len = gljList.length; i < len; i++){
+            if(gljCode === gljList[i].code){
+                rst = gljList[i].name;
+                break;
+            }
+        }
+        return rst;
+    },
+    show: function (coes) {
+        let me = gljAdjOprObj;
+        pageObj.showData(me.workSheet, me.setting, coes)
+    },
+    getGljItemsOcc: function () {
+        let me = gljAdjOprObj;
         $.ajax({
-            type:"POST",
-            url:"api/saveCoeList",
-            data: {"data": JSON.stringify({"addArr": addArr, "deleteArr": deleteArr, "updateArr": updateArrTemp})},
-            dataType:"json",
-            cache:false,
-            timeout:5000,
+            type: 'post',
+            url: '/stdGljRepository/api/getGljItemsOccupied',
+            data: {repId: pageObj.gljLibID, occupation: '-_id code name'},
+            dataType: 'json',
+            timeout: 5000,
             success:function(result){
                 if (result.error) {
                     alert(result.message);
-                } else {
-                    // 成功。更新从后台返回的新ID。
-                    if (addArr.length > 0){
-                        for (var i = 0; i < me.datas.length; i++) {
-                            if (me.datas[i].ID == me.tempID){
-                                me.datas[i].ID = result.data;
-                                me.mainSpread.getSheet(0).repaint();
-                                break;
-                            }
-                        }
-                    };
+                } else{
+                    me.gljList = result.data;
                 }
             },
             error:function(err){
                 alert("内部程序错误!");
             }
-        })
+        });
     }
 };
 
-pageObj.initPage();
-
-
-
 

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

@@ -50,7 +50,6 @@ var rationOprObj = {
             window.location.href = "/rationRepository/main";
         }
         me.workBook = sheetCommonObj.buildSheet(container, me.setting, 30);
-        me.workBook.options.showHorizontalScrollbar = true;
         me.getRationsCodes(rationRepId);
         me.rationDelOpr();
         me.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting);
@@ -85,6 +84,9 @@ var rationOprObj = {
                 });
                 rationAssistOprObj.getAssItems(cacheSection[args.row]);
             }
+            else {
+                rationGLJOprObj.currentRationItem = null;
+            }
         };
         me.workBook.focus(true);
     },
@@ -327,6 +329,7 @@ var rationOprObj = {
                         if(jobContentOprObj && jobContentOprObj.currentSituation === jobContentOprObj.situations.ALL){
                             rObj.jobContent = jobContentOprObj.currentJobContent ? jobContentOprObj.currentJobContent : '';
                         }
+                        me.setInitPrc(rObj);
                         addArr.push(rObj);
                         me.rationsCodes.push(rObj.code);
                         me.addRationItem = null;
@@ -387,6 +390,7 @@ var rationOprObj = {
                         if(jobContentOprObj && jobContentOprObj.currentSituation === jobContentOprObj.situations.ALL){
                             items[i].jobContent = jobContentOprObj.currentJobContent ? jobContentOprObj.currentJobContent : '';
                         }
+                        me.setInitPrc(items[i]);
                         addArr.push(items[i]);
                         me.rationsCodes.push(items[i].code);
                     }
@@ -428,6 +432,7 @@ var rationOprObj = {
                             if(jobContentOprObj && jobContentOprObj.currentSituation === jobContentOprObj.situations.ALL){
                                 items[i].jobContent = jobContentOprObj.currentJobContent ? jobContentOprObj.currentJobContent : '';
                             }
+                            me.setInitPrc(items[i]);
                             addArr.push(items[i]);
                         }
                         else{
@@ -444,6 +449,12 @@ var rationOprObj = {
             me.mixUpdateRequest(updateArr, addArr, []);
         }
     },
+    setInitPrc: function (obj) {
+        obj.labourPrice = 0;
+        obj.materialPrice = 0;
+        obj.machinePrice = 0;
+        obj.basePrice = 0;
+    },
     isValidUnit: function (rationObj, validUnits) {
         let rst = true;
         if(typeof rationObj.unit !== 'undefined' && rationObj.unit && validUnits.indexOf(rationObj.unit) === -1){//无效
@@ -451,15 +462,6 @@ var rationOprObj = {
         }
         return rst;
     },
-    setLockCol: function (sheet, col, isLocked) {
-        sheet.suspendPaint();
-        sheet.suspendEvent();
-        for(let row = 0, len = sheet.getRowCount(); row < len; row++){
-            sheet.getCell(row, col).locked(isLocked);
-        }
-        sheet.resumePaint();
-        sheet.resumeEvent();
-    },
     getRationsCodes: function (repId) {
         let me = rationOprObj;
         $.ajax({
@@ -476,7 +478,7 @@ var rationOprObj = {
     },
     mixUpdateRequest: function(updateArr, addArr, removeIds) {
         var me = rationOprObj;
-        me.setLockCol(me.workBook.getSheet(0), 0, true);
+        sheetCommonObj.setLockCol(me.workBook.getSheet(0), 0, true);
         $.ajax({
             type:"POST",
             url:"api/mixUpdateRationItems",
@@ -505,7 +507,7 @@ var rationOprObj = {
                     me.mixUpdate = 0;
                    // me.workBook.getSheet(0).setActiveCell(me.activeCell.row, me.activeCell.col);
                 }
-                me.setLockCol(me.workBook.getSheet(0), 0, false);
+                sheetCommonObj.setLockCol(me.workBook.getSheet(0), 0, false);
             },
             error:function(){
             }
@@ -581,7 +583,7 @@ var rationOprObj = {
                 //sheetCommonObj.cleanSheet(me.workBook.getSheet(0), me.setting, -1);
                 sheetCommonObj.cleanData(me.workBook.getSheet(0), me.setting, -1);
                 sheetCommonObj.showData(me.workBook.getSheet(0), me.setting, cacheSection);
-                me.setLockCol(me.workBook.getSheet(0), 4, true);
+                sheetCommonObj.setLockCol(me.workBook.getSheet(0), 4, true);
                 //combo
                 me.setCombo(me.workBook.getActiveSheet(), rationUnits);
                 if(me.mixUpdate === 1){

+ 125 - 55
web/maintain/ration_repository/js/ration_coe.js

@@ -1,14 +1,16 @@
 /**
  * Created by CSL on 2017-06-08.
  */
+ //modified by zhong on 2017-09-25
 var rationCoeOprObj = {
     sheet: null,
     libID: null,
     curRation: null,
+    tempDelArr: [],
     cache: {},
     setting: {
         header:[
-            {headerName:"编码",headerWidth:120,dataCode:"ID", dataType: "Number"},
+            {headerName:"编码",headerWidth:120,dataCode:"ID", dataType: "Number", hAlign: 'left'},
             {headerName:"名称",headerWidth:400,dataCode:"name", dataType: "String"},
             {headerName:"内容",headerWidth:300,dataCode:"content", dataType: "String"}
         ],
@@ -27,7 +29,7 @@ var rationCoeOprObj = {
         me.sheet.bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting);
         me.sheet.bind(GC.Spread.Sheets.Events.ClipboardPasted, me.onClipboardPasted);
         me.sheet.bind(GC.Spread.Sheets.Events.EditEnded, me.onEditEnded);
-        me.sheet.bind(GC.Spread.Sheets.Events.RangeChanged, me.onRangeChanged);
+       // me.sheet.bind(GC.Spread.Sheets.Events.RangeChanged, me.onRangeChanged);
     },
 
     onClipboardPasting: function(sender, args) {
@@ -42,12 +44,49 @@ var rationCoeOprObj = {
         if (me.libID) {
             // 修改第一列(编号)
             if (info.cellRange.col == 0) {
+                me.tempDelArr = [];
                 var coeIDs = [];
-                var temp = sheetCommonObj.analyzePasteData({header:[{dataCode: "ID"}] }, info);
-                for (let obj of temp) {
-                    coeIDs.push(obj.ID);
-                };
+                var items = sheetCommonObj.analyzePasteData({header:[{dataCode: "ID"}] }, info);
+                let curCache = typeof me.cache["_Coe_" + me.curRation.ID] !== 'undefined' ? me.cache["_Coe_" + me.curRation.ID] : [];
+                let isRefresh = false;
+                for(let i = 0, len = items.length; i < len; i++){
+                    let row = i + info.cellRange.row;
+                    //update
+                    if(row < curCache.length){
+                        let isExist = false;
+                        for(let j = 0, jLen = curCache.length; j < jLen; j++){
+                            if(items[i].ID === curCache[j].ID && j !== row){
+                                isExist = true;
+                                break;
+                            }
+                        }
+                        if(!isExist){
+                            me.tempDelArr.push({org: curCache[row], newID: items[i].ID});
+                            coeIDs.push(items[i].ID);
+                        }
+                        else{
+                            isRefresh = true;
+                        }
+                    }
+                    else{
+                        coeIDs.push(items[i].ID);
+                    }
+                }
+                //delete in front
+                if(me.tempDelArr.length > 0){
+                   for(let i = 0, len = me.tempDelArr.length; i < len; i++){
+                       for(let j = 0; j < curCache.length; j++){
+                           if(me.tempDelArr[i].org.ID === curCache[j].ID){
+                               curCache.splice(j, 1);
+                               break;
+                           }
+                       }
+                   }
+                }
                 me.addCoeItems(coeIDs);
+                if(isRefresh){
+                    me.showCoeItems(me.curRation.ID);
+                }
             } else {
                 //修改其它列。
             }
@@ -56,52 +95,79 @@ var rationCoeOprObj = {
 
     onEditEnded: function(sender, args){
         var me = rationCoeOprObj;
-        if (args.col == 0) {   // 编号列
-            //delete
-            if (args.editingText == null || args.editingText.trim() == "") {
-                var curCache = me.cache["_Coe_" + me.curRation.ID];
-                if (curCache) {
-                    if (args.row < curCache.length) {
-                        curCache.splice(args.row, 1);
-                        me.updateCurRation();
-                        sheetCommonObj.cleanSheet(me.sheet, me.setting, -1);
-                        me.showCoeItems(me.curRation.ID);
+        if (args.col == 0 && args.editingText && args.editingText.toString().trim().length > 0 && !isNaN(args.editingText)) {   // 编号列
+            let curCahe = typeof me.cache["_Coe_" + me.curRation.ID] !== 'undefined' ? me.cache["_Coe_" + me.curRation.ID] : [];
+            me.tempDelArr = [];
+            //update
+            if(args.row < curCahe.length && args.editingText != curCahe[args.row].ID){
+                let isExist = false;
+                for(let i = 0, len = curCahe.length; i < len; i++){
+                    if(args.editingText == curCahe[i].ID){
+                        isExist = true;
+                        break;
                     }
                 }
-            } else {
-                if (me.libID) {
-                    var ID = args.editingText.trim();
-                    if (!isNaN(ID)) {
-                        me.addCoeItems([ID]);
-                    };
-                };
-            };
-        };
-    },
-
-    onRangeChanged: function(sender, args) {
-        if (args.action == GC.Spread.Sheets.RangeChangedAction.clear) {
-            if (!confirm(`确定要删除选中的 ${args.rowCount} 条附注条件吗?`)){return; }
-            var me = rationCoeOprObj;
-            if (args.col == 0) {
-                var curCache = me.cache["_Coe_" + me.curRation.ID];
-                if (curCache) {
-                    for (var i = args.rowCount - 1; i >= 0; i--) {
-                        if (args.row + i < curCache.length) {
-                            curCache.splice(args.row + i, 1);
-                        };
-                    };
-                    me.updateCurRation();
-                    sheetCommonObj.cleanSheet(me.sheet, me.setting, -1);
+                if(!isExist){
+                    me.tempDelArr.push({org: curCahe[args.row], newID: args.editingText});
+                    curCahe.splice(args.row, 1);
+                    me.addCoeItems([args.editingText]);
+                }
+                else{
                     me.showCoeItems(me.curRation.ID);
-                };
-            };
-        };
+                }
+            }
+            //insert
+            else{
+                me.addCoeItems([args.editingText]);
+            }
+        }
+        else{
+            me.showCoeItems(me.curRation.ID);
+        }
     },
 
+    bindRationCoeDel: function () {
+        let me = rationCoeOprObj;
+        let workBook = me.sheet.getParent();
+        workBook.commandManager().register('rationCoeDel', function () {
+            let sels = me.sheet.getSelections(), isUpdate = false;
+            let curCahe = me.cache["_Coe_" + me.curRation.ID];
+            for(let i = 0, len = sels.length; i < len; i ++ ){
+                if(sels[i].colCount === me.setting.header.length){
+                    if(sels[i].row < curCahe.length){
+                        isUpdate = true;
+                        curCahe.splice(sels[i].row, sels[i].rowCount);
+                    }
+                }
+            }
+            if(isUpdate){
+                me.updateCurRation();
+                sheetCommonObj.cleanData(me.sheet, me.setting, -1);
+                me.showCoeItems(me.curRation.ID);
+            }
+        });
+        workBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false);
+        workBook.commandManager().setShortcutKey('rationCoeDel', GC.Spread.Commands.Key.del, false, false, false, false);
+    },
+    getRecoveryArr: function (tempDelArr, newArr) {//获得更新的coe不存在,恢复删除的被更新数据
+        let rst = [];
+        for(let i = 0, len = tempDelArr.length; i < len; i++){
+            let isExist = false;
+            for(let j = 0, jLen = newArr.length; j < jLen; j++){
+                if(tempDelArr[i].newID == newArr[j].ID){
+                    isExist = true;
+                    break;
+                }
+            }
+            if(!isExist){
+                rst.push(tempDelArr[i].org);
+            }
+        }
+        return rst;
+    },
     addCoeItems: function(coeIDs) {
         var me = this;
-        sheetCommonObj.cleanSheet(me.sheet, me.setting, -1);
+        sheetCommonObj.cleanData(me.sheet, me.setting, -1);
 
         var curCache = me.cache["_Coe_" + me.curRation.ID];
         var temp = [];
@@ -142,14 +208,10 @@ var rationCoeOprObj = {
                         }else{
                             curCache = rstArr;
                         }
-
-                        curCache.sort(function(a, b) {
-                            var rst = 0;
-                            if (a.ID > b.ID) rst = 1
-                            else if (a.ID < b.ID) rst = -1;
-                            return rst;
-                        });
-
+                        let recoveryArr = me.getRecoveryArr(me.tempDelArr, result.data);
+                        if(recoveryArr.length > 0){
+                            curCache = curCache.concat(recoveryArr);
+                        }
                         me.cache["_Coe_" + me.curRation.ID] = curCache;
                         me.updateCurRation();
                         me.showCoeItems(me.curRation.ID);
@@ -186,7 +248,7 @@ var rationCoeOprObj = {
                 cache:false,
                 timeout:5000,
                 success:function(result){
-                    sheetCommonObj.cleanSheet(me.sheet, me.setting, -1);
+                    sheetCommonObj.cleanData(me.sheet, me.setting, -1);
                     if (result.data) {
                         var tempResult = [];
                         for (let obj of result.data) {
@@ -211,6 +273,12 @@ var rationCoeOprObj = {
         var me = this;
         var curCache = me.cache["_Coe_" + rationID];
         if (curCache) {
+            curCache.sort(function(a, b) {
+                var rst = 0;
+                if (a.ID > b.ID) rst = 1
+                else if (a.ID < b.ID) rst = -1;
+                return rst;
+            });
             sheetCommonObj.showData(me.sheet, me.setting, curCache);
         }
     },
@@ -230,4 +298,6 @@ var rationCoeOprObj = {
             };
         };
     }
-}
+}
+
+

+ 86 - 71
web/maintain/ration_repository/js/ration_glj.js

@@ -6,6 +6,7 @@ var rationGLJOprObj = {
     currentRationItem: null,
     distTypeTree: null,
     activeCell: null,
+    tempCacheArr: [],//被更新的工料机,若更新的工料机不存在,则恢复
     cache: {},
     setting: {
         header:[
@@ -79,14 +80,19 @@ var rationGLJOprObj = {
         me.getGljDistType(function () {
             me.onContextmenuOpr();
             sheetCommonObj.initSheet(me.sheet, me.setting, 30);
-            me.rationGljDelOpr();
+            me.bindRationGljDelOpr();
             me.sheet.bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting);
             me.sheet.bind(GC.Spread.Sheets.Events.ClipboardPasted, me.onClipboardPasted);
             me.sheet.bind(GC.Spread.Sheets.Events.EditEnded, me.onCellEditEnd);
             //me.sheet.bind(GC.Spread.Sheets.Events.RangeChanged, me.onRangeChanged);
         });
     },
-    rationGljDelOpr: function () {
+    unBindDel: function () {
+        let me = rationGLJOprObj, spreadBook = me.sheet.getParent();
+        spreadBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false);
+        spreadBook.commandManager().setShortcutKey('clear', GC.Spread.Commands.Key.del, false, false, false, false);
+    },
+    bindRationGljDelOpr: function () {
         let me = rationGLJOprObj, spreadBook = me.sheet.getParent();
         spreadBook.commandManager().register('rationGljDelete', function () {
             let sels = me.sheet.getSelections(), updateArr = [], removeArr = [], lockCols = me.setting.view.lockColumns;
@@ -104,18 +110,7 @@ var rationGLJOprObj = {
                         }
                     }
                     else{
-                        if(sels[sel].col === 0){
-                            $('#alertText').text("编号不能为空,修改失败!");
-                            $('#alertModalBtn').click();
-                            me.sheet.options.isProtected = true;
-                            $('#alertModalCls').click(function () {
-                                me.sheet.options.isProtected = false;
-                            });
-                            $('#alertModalCof').click(function () {
-                                me.sheet.options.isProtected = false;
-                            });
-                        }
-                        else if(sels[sel].col !== 0 && sels[sel].col !== 5 && !(sels[sel].col === 1 && sels.col + sels[sel].colCount -1 === 3)){
+                         if(sels[sel].col !== 0 && sels[sel].col !== 5 && !(sels[sel].col === 1 && sels.col + sels[sel].colCount -1 === 3)){
                             if(cacheSection){
                                 for(let i = sels[sel].row === -1 ? 1 : 0; i < sels[sel].rowCount; i++){
                                     if(sels[sel].row + i < cacheSection.length){
@@ -167,12 +162,13 @@ var rationGLJOprObj = {
     },
     onClipboardPasting: function(sender, args) {
         var me = rationGLJOprObj;
-        /*if (args.cellRange.colCount != 1 || args.cellRange.col != 0 || !(me.currentRationItem)) {
+        if (!(args.cellRange.col === 0 || args.cellRange.col === 5) || !(me.currentRationItem)) {
             args.cancel = true;
-        }*/
+        }
     },
     onClipboardPasted: function(e, info) {
         var me = rationGLJOprObj, repId = storageUtil.getSessionCache("RationGrp","repositoryID");
+        me.tempCacheArr = [];
         if (repId) {
             let gljLibId = storageUtil.getSessionCache("gljLib", "repositoryID_" + repId);
             if(gljLibId){
@@ -183,6 +179,7 @@ var rationGLJOprObj = {
                     for (var i = 0; i < tmpCodes.length; i++) {
                         let rowIdx = info.cellRange.row + i;
                         if(rowIdx < cacheArr.length){//更新
+                            me.tempCacheArr.push(cacheArr[rowIdx]);
                             cacheArr.splice(rowIdx--, 1);
                         }
                         codes.push(tmpCodes[i].code);
@@ -220,67 +217,74 @@ var rationGLJOprObj = {
     },
     onCellEditEnd: function(sender, args){
         var me = rationGLJOprObj;
-        var cacheArr = me.cache["_GLJ_" + me.currentRationItem.ID];
-        if (args.col != 0) {
-            if (args.row < cacheArr.length) {
-                var editGlj = cacheArr[args.row];
-                if (editGlj["consumeAmt"] != args.editingText) {
-                    let parseNum = parseFloat(args.editingText);
-                    if(isNaN(parseFloat(args.editingText))){
-                        $('#alertModalBtn').click();
-                        $('#alertText').text("定额消耗只能输入数值!");
-                        args.sheet.options.isProtected = true;
-                        $('#alertModalCls').click(function () {
-                            args.sheet.options.isProtected = false;
-                            args.sheet.setValue(args.row, args.col, editGlj['consumeAmt']);
-                        });
-                        $('#alertModalCof').click(function () {
-                            args.sheet.options.isProtected = false;
-                            args.sheet.setValue(args.row, args.col, editGlj['consumeAmt']);
-                        })
-                    }
-                    else{
-                        args.sheet.setValue(args.row, args.col, parseNum);
-                        let roundNum = me.round(parseNum, 3);
-                        editGlj["consumeAmt"] = roundNum;
-                        me.updateRationItem();
+        if(me.currentRationItem) {
+            var cacheArr = me.cache["_GLJ_" + me.currentRationItem.ID];
+            me.tempCacheArr = [];
+            if (args.col != 0) {
+                if (args.row < cacheArr.length) {
+                    var editGlj = cacheArr[args.row];
+                    if (editGlj["consumeAmt"] != args.editingText) {
+                        let parseNum = parseFloat(args.editingText);
+                        if (isNaN(parseFloat(args.editingText))) {
+                            $('#alertModalBtn').click();
+                            $('#alertText').text("定额消耗只能输入数值!");
+                            args.sheet.options.isProtected = true;
+                            $('#alertModalCls').click(function () {
+                                args.sheet.options.isProtected = false;
+                                args.sheet.setValue(args.row, args.col, editGlj['consumeAmt']);
+                            });
+                            $('#alertModalCof').click(function () {
+                                args.sheet.options.isProtected = false;
+                                args.sheet.setValue(args.row, args.col, editGlj['consumeAmt']);
+                            })
+                        }
+                        else {
+                            args.sheet.setValue(args.row, args.col, parseNum);
+                            let roundNum = me.round(parseNum, 3);
+                            editGlj["consumeAmt"] = roundNum;
+                            me.updateRationItem();
+                        }
                     }
                 }
-            }
-        } else {
-            if(args.editingText && args.editingText.toString().trim().length !== 0){
-                let isExist = false;
-                for(let i = 0, len = cacheArr.length; i < len; i++){
-                    if(cacheArr[i].code === args.editingText && i !== args.row){
-                        isExist = true;
-                        break;
+            } else {
+                if (args.editingText && args.editingText.toString().trim().length !== 0) {
+                    let isExist = false;
+                    for (let i = 0, len = cacheArr.length; i < len; i++) {
+                        if (cacheArr[i].code === args.editingText && i !== args.row) {
+                            isExist = true;
+                            break;
+                        }
                     }
-                }
-                if(isExist){
-                    alert("该工料机已存在!");
-                    args.sheet.setValue(args.row, args.col, typeof cacheArr[args.row] !== 'undefined' ? cacheArr[args.row].code + '' : '');
-                }
-                else{
-                    if(args.row < cacheArr.length && args.editingText !== cacheArr[args.row].code){//更新
-                        cacheArr.splice(args.row, 1);
-                        let rationRepId = storageUtil.getSessionCache("RationGrp","repositoryID");
-                        let gljLibID = storageUtil.getSessionCache("gljLib", "repositoryID_" + rationRepId);
-                        let codes = [];
-                        codes.push(args.editingText.toString().trim());
-                        me.addGljItems(codes, gljLibID, args);
+                    if (isExist) {
+                        alert("该工料机已存在!");
+                        args.sheet.setValue(args.row, args.col, typeof cacheArr[args.row] !== 'undefined' ? cacheArr[args.row].code + '' : '');
                     }
-                    else if(args.row >= cacheArr.length){//新增
-                            let rationRepId = storageUtil.getSessionCache("RationGrp","repositoryID");
+                    else {
+                        if (args.row < cacheArr.length && args.editingText !== cacheArr[args.row].code) {//更新
+                            me.tempCacheArr.push(cacheArr[args.row]);
+                            cacheArr.splice(args.row, 1);
+                            let rationRepId = storageUtil.getSessionCache("RationGrp", "repositoryID");
+                            let gljLibID = storageUtil.getSessionCache("gljLib", "repositoryID_" + rationRepId);
+                            let codes = [];
+                            codes.push(args.editingText.toString().trim());
+                            me.addGljItems(codes, gljLibID, args);
+                        }
+                        else if (args.row >= cacheArr.length) {//新增
+                            let rationRepId = storageUtil.getSessionCache("RationGrp", "repositoryID");
                             let gljLibID = storageUtil.getSessionCache("gljLib", "repositoryID_" + rationRepId);
                             if (gljLibID) {
                                 var codes = [];
                                 codes.push(args.editingText.toString().trim());
                                 me.addGljItems(codes, gljLibID, args);
                             }
+                        }
                     }
                 }
             }
         }
+        else {
+            args.sheet.setValue(args.row, args.col, '');
+        }
     },
     onContextmenuOpr: function () {
         let me = rationGLJOprObj;
@@ -293,11 +297,11 @@ var rationGLJOprObj = {
                     x = e.pageX - offset.left,
                     y = e.pageY - offset.top;
                 let target = sheet.hitTest(x, y);
-                if(sheet.parent.getActiveSheetIndex() === 0){
-                    let delDis = true;
-                    let cacheSection = me.cache["_GLJ_" + me.currentRationItem.ID];
-                    if(target.hitTestType === 3 && typeof target.row !== 'undefined' && typeof target.col !== 'undefined'){//在表格内
-                        sheet.setActiveCell(target.row, target.col);
+                if(sheet.parent.getActiveSheetIndex() === 0 && target.hitTestType === 3 && typeof target.row !== 'undefined' && typeof target.col !== 'undefined'){
+                    let delDis = true, cacheSection;
+                    sheet.setActiveCell(target.row, target.col);
+                    if(me.currentRationItem){
+                        let cacheSection = me.cache["_GLJ_" + me.currentRationItem.ID];
                         if(target.row < cacheSection.length){
                             delDis = false;
                         }
@@ -326,6 +330,7 @@ var rationGLJOprObj = {
 
     addGljItems: function(codes, repId, args) {
         var me = this;
+        sheetCommonObj.setLockCol(me.sheet, 0, true);
         $.ajax({
             type:"POST",
             url:"api/getGljItemsByCodes",
@@ -337,7 +342,8 @@ var rationGLJOprObj = {
                 //sheetCommonObj.cleanSheet(me.sheet, me.setting, -1);
                 if (result) {
                     if(result.data.length > 0){
-                        sheetCommonObj.cleanSheet(me.sheet, me.setting, -1);
+                        //sheetCommonObj.cleanSheet(me.sheet, me.setting, -1);
+                        sheetCommonObj.cleanData(me.sheet, me.setting, -1);
                         var rstArr = [], dummyR = {gljId: 0, consumeAmt:0}, newAddArr = [];
                         for (var i = 0; i < result.data.length; i++) {
                             dummyR.gljId = result.data[i].ID;
@@ -371,22 +377,30 @@ var rationGLJOprObj = {
                         }
                     }
                     else{
+                        let cacheArr = me.cache["_GLJ_" + me.currentRationItem.ID]?  me.cache["_GLJ_" + me.currentRationItem.ID] : [];
+                        me.cache["_GLJ_" + me.currentRationItem.ID] = cacheArr.concat(me.tempCacheArr);
+                        //更新的工料机不存在
+                        me.cache["_GLJ_" + me.currentRationItem.ID].sort(function(a, b) {
+                            var rst = 0;
+                            if (a.code > b.code) rst = 1
+                            else if (a.code < b.code) rst = -1;
+                            return rst;
+                        });
                         $('#alertModalBtn').click();
                         $('#alertText').text("工料机"+ codes + "不存在,请查找你所需要的工料机,或新增工料机");
                         me.sheet.options.isProtected = true;
                         $('#alertModalCls').click(function () {
                             sheetCommonObj.lockCells(me.sheet, me.setting);
                             me.showGljItems(me.currentRationItem.ID);
-                            me.sheet.setValue(args.row, args.col, '');
                         });
                         $('#alertModalCof').click(function () {
                             sheetCommonObj.lockCells(me.sheet, me.setting);
                             me.showGljItems(me.currentRationItem.ID);
-                           me.sheet.setValue(args.row, args.col, '');
                         })
                     }
                 }
                 sheetCommonObj.lockCells(me.sheet, me.setting);
+                sheetCommonObj.setLockCol(me.sheet, 0, false);
             },
             error:function(err){
                 alert(err);
@@ -542,6 +556,7 @@ var rationGLJOprObj = {
     showGljItems: function(rationID) {
         var me = this;
         if (me.cache["_GLJ_" + rationID]) {
+            sheetCommonObj.cleanData(me.sheet, me.setting, -1);
             sheetCommonObj.showData(me.sheet, me.setting, me.cache["_GLJ_" + rationID], me.distTypeTree);
             //lock
             me.sheet.suspendPaint();

+ 3 - 1
web/maintain/ration_repository/js/section_tree.js

@@ -54,7 +54,7 @@ var zTreeOprObj = {
                     zTreeHelper.createTree(result.data, setting, "rationChapterTree", me);
                     //初始化,初始节点点击
                     let rootNode = me.treeObj.getNodes()[0];
-                    if(rootNode && rootNode.isParent && rootNode.isFirstNode){
+                    if(rootNode && rootNode.isFirstNode){
                         me.treeObj.selectNode(rootNode);
                         me.onClick(null, 'rationChapterTree', rootNode);
                     }
@@ -351,6 +351,7 @@ var zTreeOprObj = {
         var sectionID = treeNode.ID;
         if (!(treeNode.items) || treeNode.items.length == 0) {
             jobContentOprObj.setRadiosDisabled(false, jobContentOprObj.radios);
+            rationOprObj.workBook.getSheet(0).clearSelection();
             rationOprObj.getRationItems(sectionID);
         } else {
             jobContentOprObj.setRadiosDisabled(true, jobContentOprObj.radios);
@@ -360,6 +361,7 @@ var zTreeOprObj = {
         }
         sheetCommonObj.cleanSheet(rationGLJOprObj.sheet, rationGLJOprObj.setting, -1);
         sheetCommonObj.shieldAllCells(rationGLJOprObj.sheet);
+        rationGLJOprObj.sheet.getParent().focus(false);
     }
 };
 //定额章节节点说明、计算规则

+ 8 - 2
web/users/js/col_setting.js

@@ -12,7 +12,7 @@ let ColSettingObj = {
         readOnly: null,
         checkBox: null
     },
-    Rows: {data: 0, filedName: 0, getText: 1, wordWrap: 2, cellType: 3, width: 4, readOnly: 5, showHint: 6, visible: 7},
+    Rows: {data: 0, filedName: 0, getText: 1, wordWrap: 2, cellType: 3, width: 4, readOnly: 5, showHint: 6, visible: 7, customize: 8},
     columnValueChanged: function (e, info) {
         let that = ColSettingObj;
         info.colList.forEach(function (iCol) {
@@ -67,7 +67,7 @@ let ColSettingObj = {
         sheet.setColumnCount(2, GC.Spread.Sheets.SheetArea.rowHeader);
         sheet.setColumnWidth(0, 80, GC.Spread.Sheets.SheetArea.rowHeader);
         sheet.setColumnWidth(1, 70, GC.Spread.Sheets.SheetArea.rowHeader);
-        sheet.setRowCount(setting.headRows + this.Rows.visible + 1);
+        sheet.setRowCount(setting.headRows + this.Rows.customize + 1);
 
         sheet.setText(setting.headRows + this.Rows.data, 0, 'Data', GC.Spread.Sheets.SheetArea.rowHeader);
         sheet.setStyle(setting.headRows + this.Rows.data, -1, this.DEFAULT_DATA_STYLE);
@@ -82,6 +82,7 @@ let ColSettingObj = {
         initColProperty(this.Rows.showHint, 'ShowHint');
         initColProperty(this.Rows.visible, 'Visible');
         initColProperty(this.Rows.cellType, 'CellType');
+        initColProperty(this.Rows.customize, 'Customize');
     },
     initColSetting: function (setting) {
         this.DEFAULT_TITLE_STYLE = this.getCellStyle('Arial', GC.Spread.Sheets.HorizontalAlign.center, GC.Spread.Sheets.VerticalAlign.center);
@@ -159,6 +160,9 @@ let ColSettingObj = {
                 // visible
                 cell = sheet.getCell(this.colSetting.headRows + this.Rows.visible, iCol, GC.Spread.Sheets.SheetArea.viewport);
                 cell.cellType(this.cellType.checkBox).value(col.visible).hAlign(GC.Spread.Sheets.HorizontalAlign.center);
+                // customize
+                cell = sheet.getCell(this.colSetting.headRows + this.Rows.customize, iCol, GC.Spread.Sheets.SheetArea.viewport);
+                cell.cellType(this.cellType.checkBox).value(col.customize).hAlign(GC.Spread.Sheets.HorizontalAlign.center);
             }
         }
 
@@ -185,6 +189,7 @@ let ColSettingObj = {
             sheet.setValue(this.colSetting.headRows + this.Rows.readOnly, iCol, false, GC.Spread.Sheets.SheetArea.viewport);
             sheet.getCell(this.colSetting.headRows + this.Rows.showHint, iCol).cellType(this.cellType.checkBox).hAlign(GC.Spread.Sheets.HorizontalAlign.center);
             sheet.getCell(this.colSetting.headRows + this.Rows.visible, iCol).cellType(this.cellType.checkBox).hAlign(GC.Spread.Sheets.HorizontalAlign.center).value(true);
+            sheet.getCell(this.colSetting.headRows + this.Rows.customize, iCol).cellType(this.cellType.checkBox).hAlign(GC.Spread.Sheets.HorizontalAlign.center).value(false);
         }
     },
     setHeaderRowCount: function (count) {
@@ -244,6 +249,7 @@ let ColSettingObj = {
                 col.showHint = sheet.getValue(setting.headRows + this.Rows.showHint, iCol) || false;
             }
             col.visible = sheet.getValue(setting.headRows + this.Rows.visible, iCol) || false;
+            col.customize = sheet.getValue(setting.headRows + this.Rows.customize, iCol) || false;
 
             col.head = {};
             col.head.titleNames = [];

+ 10 - 5
web/users/js/compilation.js

@@ -234,20 +234,21 @@ function initCompilation() {
     let rationLibData = rationList === undefined ? [] : JSON.parse(rationList);
     let gljLibData = gljList === undefined ? [] : JSON.parse(gljList);
     let feeLibData = feeRateList === undefined ? [] : JSON.parse(feeRateList);
-    mainTreeCol = mainTreeCol === '' ? '' : JSON.parse(mainTreeCol);
-
     let artificialCoefficientData = artificialCoefficientList === undefined ? [] : JSON.parse(artificialCoefficientList);
-    mainTreeCol = mainTreeCol.replace(/\n/g, '\\n');
+
+    mainTreeCol = mainTreeCol !== '' ? mainTreeCol.replace(/\n/g, '\\n') : mainTreeCol;
     billsTemplateData = billsTemplateData.replace(/\n/g, '\\n');
 
+    let mainTreeColObj = mainTreeCol === '' ? {} : JSON.parse(mainTreeCol);
+
     // 初始化 造价书列设置
     colSpread = TREE_SHEET_HELPER.createNewSpread($('#main-tree-col')[0]);
     let billsTemplateTree = idTree.createNew({id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1});
 
     billsTemplateTree.loadDatas(JSON.parse(billsTemplateData));
     if (mainTreeCol !== '') {
-        TREE_SHEET_HELPER.loadSheetHeader(mainTreeCol, colSpread.getActiveSheet());
-        TREE_SHEET_HELPER.showTreeData(mainTreeCol, colSpread.getActiveSheet(), billsTemplateTree);
+        TREE_SHEET_HELPER.loadSheetHeader(mainTreeColObj, colSpread.getActiveSheet());
+        TREE_SHEET_HELPER.showTreeData(mainTreeColObj, colSpread.getActiveSheet(), billsTemplateTree);
     }
 
     if (billListData.length <= 0 || rationLibData.length <= 0 || gljLibData.length <= 0) {
@@ -392,6 +393,10 @@ function validLib() {
             throw '请添加定额库';
         }
 
+        if ($("input:hidden[name='glj_lib']").length <= 0) {
+            throw '请添加工料机库';
+        }
+
         if ($("input:hidden[name='fee_lib']").length <= 0) {
             throw '请添加费率标准';
         }

+ 22 - 0
web/users/js/message.js

@@ -0,0 +1,22 @@
+/**
+ * 消息管理相关js
+ *
+ * @author CaiAoLin
+ * @date 2017/9/21
+ * @version
+ */
+$(document).ready(function() {
+    // 保存按钮
+    $("#save").click(function() {
+        $("form").submit();
+    });
+
+    // 选择框
+    $(".selector > li > a").click(function() {
+        let value = $(this).data("value");
+        let string = $(this).text();
+        let selector = $(this).parent().parent();
+        selector.next("input:hidden").val(value);
+        selector.prev("button").html(string + ' <span class="caret"></span>');
+    });
+});

+ 2 - 2
web/users/views/compilation/engineering.html

@@ -86,8 +86,8 @@
                                     </p>
                                     <% }) %>
                                     <% } %>
-                                    <a href="#" class="btn btn-link btn-sm add-compilation" data-model="fee">添加</a>
                                 </div>
+                                <a href="#" class="btn btn-link btn-sm add-compilation" data-model="fee">添加</a>
                             </div>
                             <div class="form-group col-md-4">
                                 <label>人工系数</label>
@@ -103,8 +103,8 @@
                                     </p>
                                     <% }) %>
                                     <% } %>
-                                    <a href="#" class="btn btn-link btn-sm add-compilation" data-model="artificial">添加</a>
                                 </div>
+                                <a href="#" class="btn btn-link btn-sm add-compilation" data-model="artificial">添加</a>
                             </div>
                         </div>
                     </div>

+ 5 - 23
web/users/views/dashboard/index.html

@@ -16,31 +16,13 @@
                 </tr>
                 </thead>
                 <tbody>
+                <% messageList.forEach(function(message) { %>
                 <tr>
-                    <td><a href="#">标题A</a></td>
-                    <td>2017-02-01 09:30</td>
-                    <td>陈特</td>
-                </tr>
-                <tr>
-                    <td><a href="#">标题B</a></td>
-                    <td>2017-02-01 09:30</td>
-                    <td>陈特</td>
-                </tr>
-                <tr>
-                    <td><a href="#">标题C</a></td>
-                    <td>2017-02-01 09:30</td>
-                    <td>陈特</td>
-                </tr>
-                <tr>
-                    <td>【内部】<a href="#">标题D</a></td>
-                    <td>2017-02-01 09:30</td>
-                    <td>陈特</td>
-                </tr>
-                <tr>
-                    <td><a href="#">标题E</a></td>
-                    <td>2017-02-01 09:30</td>
-                    <td>陈特</td>
+                    <td><%= message.message_type === 2 ? '【内部】' : '' %><a href="#"><%= message.title %></a></td>
+                    <td><%= moment(message.release_time).format('YYYY-MM-DD HH:mm:ss') %></td>
+                    <td><%= message.release_user %></td>
                 </tr>
+                <% }); %>
                 </tbody>
             </table>
         </div>

+ 29 - 0
web/users/views/notify/common.html

@@ -0,0 +1,29 @@
+<div class="panel-sidebar">
+    <div class="panel-title">
+        <div class="title-bar">
+            <h2><%= type === 1 ? '用户' : '内部' %>通知</h2>
+        </div>
+    </div>
+    <div class="scrollbar-auto">
+        <div class="nav-box">
+            <ul class="nav-list list-unstyled">
+                <li <% if (type === 1) {%>class="active"<% } %>>
+                    <a href="/notify">
+                        <span>用户通知</span>
+                        <% if(userMessageTotal !== undefined) {%>
+                        <span class="badge"><%= userMessageTotal %></span>
+                        <% } %>
+                    </a>
+                </li>
+                <li <% if (type === 2) {%>class="active"<% } %>>
+                    <a href="/notify?type=2">
+                        <span>内部通知</span>
+                        <% if(systemMessageTotal !== undefined) {%>
+                        <span class="badge"><%= systemMessageTotal %></span>
+                        <% } %>
+                    </a>
+                </li>
+            </ul>
+        </div>
+    </div>
+</div>

+ 75 - 87
web/users/views/notify/index.html

@@ -1,56 +1,71 @@
-<%include ../layout/second_menu.html %>
+<%include ./common.html %>
 <div class="panel-content">
     <div class="panel-title">
         <div class="title-main">
-            <h2>用户通知
-                <a href="news-add.html" class="btn btn-primary btn-sm pull-right">新建通知</a></h2>
+            <h2><%= type === 1 ? '用户' : '内部' %>通知
+                <a href="/notify/add?type=<%= type %>" class="btn btn-primary btn-sm pull-right">新建通知</a></h2>
         </div>
     </div>
     <div class="content-wrap">
         <div class="c-header">
-            <!--变更类型-->
-            <div class="btn-group">
-                <button type="button" class="btn btn-default dropdown-toggle btn-sm" data-toggle="dropdown"
-                        aria-haspopup="true" aria-expanded="false">
-                    所有状态 <span class="caret"></span>
-                </button>
-                <ul class="dropdown-menu">
-                    <li><a href="#">已发布</a></li>
-                    <li><a href="#">未发布</a></li>
-                </ul>
-            </div>
-            <!--变更类别-->
-            <div class="btn-group">
-                <button type="button" class="btn btn-default dropdown-toggle btn-sm" data-toggle="dropdown"
-                        aria-haspopup="true" aria-expanded="false">
-                    所有年 <span class="caret"></span>
-                </button>
-                <ul class="dropdown-menu">
-                    <li><a href="#">2015</a></li>
-                    <li><a href="#">2016</a></li>
-                    <li><a href="#">2017</a></li>
-                </ul>
-            </div>
-            <!--变更性质-->
-            <div class="btn-group">
-                <button type="button" class="btn btn-default dropdown-toggle btn-sm" data-toggle="dropdown"
-                        aria-haspopup="true" aria-expanded="false">
-                    所有月 <span class="caret"></span>
-                </button>
-                <ul class="dropdown-menu">
-                    <li><a href="#">1</a></li>
-                    <li><a href="#">2</a></li>
-                    <li><a href="#">3</a></li>
-                    <li><a href="#">4</a></li>
-                    <li><a href="#">5</a></li>
-                    <li><a href="#">6</a></li>
-                    <li><a href="#">7</a></li>
-                    <li><a href="#">8</a></li>
-                    <li><a href="#">9</a></li>
-                    <li><a href="#">10</a></li>
-                    <li><a href="#">11</a></li>
-                </ul>
-            </div>
+            <form class="form-inline" method="get" action="">
+                <!--变更类型-->
+                <div class="btn-group">
+                    <button type="button" class="btn btn-default dropdown-toggle btn-sm" data-toggle="dropdown"
+                            aria-haspopup="true" aria-expanded="false">
+                        <%= filter.status === undefined ? '所有状态' : (filter.status === "1" ? '已发布' : '未发布')%> <span class="caret"></span>
+                    </button>
+                    <ul class="dropdown-menu selector">
+                        <li><a href="javascript:void(0);" data-value="1">已发布</a></li>
+                        <li><a href="javascript:void(0);" data-value="0">未发布</a></li>
+                    </ul>
+                    <input type="hidden" name="status" value="<%= filter.status%>" />
+                </div>
+                <!--变更类别-->
+                <div class="btn-group">
+                    <button type="button" class="btn btn-default dropdown-toggle btn-sm" data-toggle="dropdown"
+                            aria-haspopup="true" aria-expanded="false">
+                        <%= filter.year === undefined ? '所有年' : filter.year %>  <span class="caret"></span>
+                    </button>
+                    <ul class="dropdown-menu selector">
+                        <li><a href="javascript:void(0);" data-value="2015">2015</a></li>
+                        <li><a href="javascript:void(0);" data-value="2016">2016</a></li>
+                        <li><a href="javascript:void(0);" data-value="2017">2017</a></li>
+                    </ul>
+                    <input type="hidden" name="year" value="<%= filter.year%>" />
+                </div>
+                <!--变更性质-->
+                <div class="btn-group">
+                    <button type="button" class="btn btn-default dropdown-toggle btn-sm" data-toggle="dropdown"
+                            aria-haspopup="true" aria-expanded="false">
+                        <%= filter.month === undefined ? '所有月' : filter.month %> <span class="caret"></span>
+                    </button>
+                    <ul class="dropdown-menu selector">
+                        <li><a href="javascript:void(0);" data-value="1">1</a></li>
+                        <li><a href="javascript:void(0);" data-value="2">2</a></li>
+                        <li><a href="javascript:void(0);" data-value="3">3</a></li>
+                        <li><a href="javascript:void(0);" data-value="4">4</a></li>
+                        <li><a href="javascript:void(0);" data-value="5">5</a></li>
+                        <li><a href="javascript:void(0);" data-value="6">6</a></li>
+                        <li><a href="javascript:void(0);" data-value="7">7</a></li>
+                        <li><a href="javascript:void(0);" data-value="8">8</a></li>
+                        <li><a href="javascript:void(0);" data-value="9">9</a></li>
+                        <li><a href="javascript:void(0);" data-value="10">10</a></li>
+                        <li><a href="javascript:void(0);" data-value="11">11</a></li>
+                        <li><a href="javascript:void(0);" data-value="12">12</a></li>
+                    </ul>
+                    <input type="hidden" name="month" value="<%= filter.month%>" />
+                </div>
+                <!--搜索-->
+                <div class="btn-group">
+                    <div class="input-group">
+                        <input type="text" class="form-control input-sm" name="keyword" placeholder="输入标题/内容搜索" value="<%= filter.keyword%>">
+                        <span class="input-group-btn">
+                        <button class="btn btn-default btn-sm" type="submit"><i class="glyphicon glyphicon-search"></i></button>
+                    </span>
+                    </div>
+                </div>
+            </form>
         </div>
         <div class="c-body">
             <table class="table">
@@ -63,52 +78,25 @@
                 </tr>
                 </thead>
                 <tbody>
+                <% messageList.forEach(function(message) {%>
                 <tr>
-                    <td><a href="javascript:void(0)" data-toggle="modal" data-target="#view">标题A chick me</a></td>
-                    <td>陈特</td>
-                    <td>2017-03-01 09:03:09</td>
-                    <td><a href="" class="btn btn-xs">编辑</a></td>
+                    <td><a href="javascript:void(0)" data-toggle="modal" data-target="#view"><%= message.title %></a></td>
+                    <td><%= message.creator %></td>
+                    <td><%= message.release_time === 0 ? '未发布' : moment(message.release_time).format('YYYY-MM-DD HH:mm:ss') %></td>
+                    <td>
+                        <a href="/notify/modify/<%= message._id %>" class="btn btn-xs">编辑</a>
+                        <% if(message.status === 0) { %>
+                        <a href="/notify/release/<%= message._id %>" class="btn btn-xs">发布</a>
+                        <% } %>
+                    </td>
                 </tr>
-                <tr class="warning">
-                    <td><a href="#">标题B</a></td>
-                    <td>陈特</td>
-                    <td>未发布</td>
-                    <td><a href="" class="btn btn-xs">编辑</a></td>
-                </tr>
-                <tr>
-                    <td><a href="#">标题C</a></td>
-                    <td>陈特</td>
-                    <td>2017-03-01 09:03:09</td>
-                    <td><a href="" class="btn btn-xs">编辑</a></td>
-                </tr>
-                <tr>
-                    <td><a href="#">标题D</a></td>
-                    <td>陈特</td>
-                    <td>2017-03-01 09:03:09</td>
-                    <td><a href="" class="btn btn-xs">编辑</a></td>
-                </tr>
-
+                <% }); %>
                 </tbody>
             </table>
             <nav aria-label="Page navigation">
-                <ul class="pagination pagination-sm">
-                    <li class="disabled">
-                        <a href="#" aria-label="Previous">
-                            <span aria-hidden="true">&laquo;</span>
-                        </a>
-                    </li>
-                    <li class="active"><a href="#">1</a></li>
-                    <li><a href="#">2</a></li>
-                    <li><a href="#">3</a></li>
-                    <li><a href="#">4</a></li>
-                    <li><a href="#">5</a></li>
-                    <li>
-                        <a href="#" aria-label="Next">
-                            <span aria-hidden="true">&raquo;</span>
-                        </a>
-                    </li>
-                </ul>
+                <%include ../layout/page.html %>
             </nav>
         </div>
     </div>
-</div>
+</div>
+<script type="text/javascript" src="/web/users/js/message.js"></script>

+ 49 - 0
web/users/views/notify/save.html

@@ -0,0 +1,49 @@
+<%include ./common.html %>
+<div class="panel-content">
+    <form method="post" action="/notify/<% if (messageData._id === undefined) { %>add<% }else{ %>modify/<%= messageData._id.toString() %><% } %>" enctype="application/x-www-form-urlencoded">
+        <div class="panel-title">
+            <div class="title-main">
+                <h2><% if (messageData._id === undefined) { %>新建通知<% }else{ %>修改通知<% } %>
+                    <% if (messageData._id === undefined) { %>
+                    <!--新建通知-->
+                    <a href="javascript:void(0);" class="btn btn-default btn-sm pull-right" id="save">保存</a>
+                    <% }else{ %>
+                    <!--编辑通知-->
+                    <a href="javascript:void(0);" class="btn btn-primary btn-sm pull-right" id="save">确定修改</a>
+                    <a href="/notify/delete/<%= messageData._id.toString() %>" class="btn btn-default btn-sm pull-right"><span class="text-danger">删除</span></a>
+                    <% if (messageData.last_update !== undefined) {%>
+                    <span class="pull-right"><h6 class="text-muted">最近保存 <%= messageData.last_update %><br><%= moment(messageData.update_time).format('YYYY-MM-DD HH:mm:ss') %></h6></span>
+                    <% } %>
+                    <% } %>
+                </h2>
+            </div>
+        </div>
+        <div class="content-wrap">
+            <div class="c-body">
+                <form>
+                    <div class="form-group">
+                        <label for="title">通知类型</label>
+                        <div class="radio">
+                            <label>
+                                <input type="radio" name="message_type" value="1" <% if(messageData.message_type === 1) {%>checked="checked"<% } %>> 用户通知
+                            </label>
+                            <label>
+                                <input type="radio" name="message_type" value="2" <% if(messageData.message_type === 2) {%>checked="checked"<% } %>> 内部通知
+                            </label>
+                        </div>
+                    </div>
+                    <div class="form-group has-feedback">
+                        <label for="title">标题</label>
+                        <input type="text" class="form-control" name="title" id="title" placeholder="输入通知标题" value="<%= messageData.title %>">
+                        <span class="form-control-feedback" aria-hidden="true">0/20</span>
+                    </div>
+                    <div class="form-group">
+                        <label for="content">正文</label>
+                        <textarea class="form-control" name="content" id="content" rows="8"><%= messageData.content %></textarea>
+                    </div>
+                </form>
+            </div>
+        </div>
+    </form>
+</div>
+<script type="text/javascript" src="/web/users/js/message.js"></script>