Selaa lähdekoodia

git出错重新提交

zhongzewei 8 vuotta sitten
vanhempi
commit
d8fa48e7b0

+ 131 - 0
modules/billsLib/billsLibControllers/billsLibControllers.js

@@ -0,0 +1,131 @@
+/**
+ * Created by vian on 2017/3/22.
+ */
+
+var billsDao = require("../billsLibModel/billsLibInterfaces");
+//----
+var model = require("../billsLibModel/billsLibModel");
+var counter = require("../../../public/counter/counter");
+var StdBillsLib = model.stdBillsLibMod;
+var Bills = model.billsMod;
+var JobContent = model.jobContentMod;
+var ItemCharacter = model.itemCharacterMod;
+//---
+//ͳһ�ص�����
+var callback = function(req, res, err, message, data){
+    res.json({error: err, message: message, data: data});
+}
+
+module.exports = {
+    getStdBillsLib: function(req, res){
+        var data = JSON.parse(req.body.data);
+        billsDao.getStdBillsLib(data.userId, function(err, message, stdBillsLib){
+            callback(req, res, err, message, stdBillsLib );
+        });
+    },
+    createStdBillsLib: function(req, res){
+        var data = JSON.parse(req.body.data);
+        var billsLibName = data.name;
+         billsDao.createStdBillsLib(data, function(err, message, info){
+            callback(req, res, err, message, info);
+         });
+    },
+    deleteStdBillsLib: function(req, res){
+        var data = JSON.parse(req.body.data);
+        billsDao.deleteStdBillsLib(data.billsLibId, function(err, message){
+            callback(req, res, err, message, null);
+        });
+    },
+    renameStdBillsLib: function(req, res) {
+        var data = JSON.parse(req.body.data);
+        billsDao.renameStdBillsLib(data, function (err, message) {
+            callback(req, res, err ,message, null);
+        });
+    },
+    getStdBillsLibName: function(req, res){
+        var data = JSON.parse(req.body.data);
+        billsDao.getStdBillsLibName(data.billsLibId, function(err, message, info){
+            callback(req, res, err, message, info);
+        });
+    },
+    getBills: function(req, res){
+        var data = JSON.parse(req.body.data);
+        billsDao.getBills(data.billsLibId, function(err, message, bills){
+            callback(req, res, err, message, bills);
+        });
+    },
+    createBills: function(req, res){
+        var data = JSON.parse(req.body.data);
+        billsDao.createBills(data, function(err, message){
+            callback(req, res, err, message, null);
+        });
+    },
+    updatePNId: function (req, res) {
+        var data = JSON.parse(req.body.data);
+        billsDao.updatePNId(data, function(err, message){
+            callback(req, res, err, message, null);
+        });
+    },
+    updateBills: function(req, res){
+        var data = JSON.parse(req.body.data);
+        billsDao.updateBills(data, function(err, message){
+            callback(req, res, err, message, null);
+        });
+    },
+    deleteBills: function(req, res){
+        var data = JSON.parse(req.body.data);
+        billsDao.deleteBills(data.deleteIds, function(err, message){
+            callback(req, res, err, message, null);
+        });
+    },
+    getJobContent: function(req, res){
+        var data = JSON.parse(req.body.data);
+        billsDao.getJobContent(data.billsLibId, function(err, message, jobs){
+            callback(req, res, err, message, jobs);
+        });
+    },
+    createJobContent: function(req, res){
+        var data = JSON.parse(req.body.data);
+        billsDao.createJobContent(data, function(err, message){
+            callback(req, res, err, message, null);
+        });
+    },
+    updateJobContent: function(req, res){
+        var data = JSON.parse(req.body.data);
+        billsDao.updateJobContent(data, function(err, message){
+            callback(req, res, err, message, null);
+        });
+    },
+    deleteJobContent: function(req, res){
+        var data = JSON.parse(req.body.data);
+        billsDao.deleteJobContent(data.jobId, function(err, message){
+            callback(req, res, err, message, null);
+        });
+    },
+    getItemCharacter: function(req, res){
+        var data = JSON.parse(req.body.data);
+        billsDao.getItemCharacter(data.billsLibId, function(err, message, items){
+            callback(req, res, err, message, items);
+        });
+    },
+    createItemCharacter: function(req, res){
+        var data = JSON.parse(req.body.data);
+        billsDao.createItemCharacter(data, function(err, message){
+            callback(req, res, err, message, null);
+        });
+    },
+    updateItemCharacter: function(req, res){
+        var data = JSON.parse(req.body.data);
+        billsDao.updateItemCharacter(data, function(err, message){
+            callback(req, res, err, message, null);
+        });
+    },
+    deleteItemCharacter: function(req, res){
+        var data = JSON.parse(req.body.data);
+        billsDao.deleteItemCharacter(data.itemId, function(err, message){
+            callback(req, res, err, message, null);
+        });
+    }
+
+}
+

+ 386 - 0
modules/billsLib/billsLibModel/billsLibInterfaces.js

@@ -0,0 +1,386 @@
+/**
+ * Created by vian on 2017/3/20.
+ */
+var model = require("./billsLibModel");
+var counter = require("../../../public/counter/counter");
+var StdBillsLib = model.stdBillsLibMod;
+var Bills = model.billsMod;
+var JobContent = model.jobContentMod;
+var ItemCharacter = model.itemCharacterMod;
+
+var fieldArr = ["code", "name", "unit", "ruleText", "Expression"];
+
+var billsDao = function(){};
+//----------StdBillsLib-------------------
+billsDao.prototype.getStdBillsLib = function(userId, callback){
+    StdBillsLib.find({}, "-_id", function(err, data){
+        if(err){
+            callback(1, "Error", null);
+        }
+        else{
+            callback(0, "", data);
+        }
+    })
+}
+
+billsDao.prototype.createStdBillsLib = function(clibData, callback){
+    counter.getIDAfterCount("bills", 1, function(err, result){
+        var billsLibId = result.value.sequence_value;
+        var billsLibName = clibData.name;
+        var createDate = Date.now();
+        var newStdBillsLib = {
+            billsLibId: billsLibId,
+            billsLibName: billsLibName,
+            createDate: createDate
+        }
+        StdBillsLib.create(newStdBillsLib, function(err){
+            if(err){
+                callback(1, "Error", null);
+            }
+            else {
+                StdBillsLib.find({billsLibId: billsLibId}, function(err, data){
+                    if(err){
+                        callback(1, "Error", null)
+                    }
+                    else {
+                        callback(0, "", data);
+                    }
+                });
+            }
+        });
+    });
+}
+
+billsDao.prototype.deleteStdBillsLib = function(billsLibId, callback){
+    StdBillsLib.remove({billsLibId: billsLibId}, function(err){
+        if(err){
+            callback(1, "Error");
+        }
+        else{
+            callback(0, "");
+        }
+    });
+}
+
+billsDao.prototype.renameStdBillsLib = function(renameData, callback){
+    var billsLibId = renameData.id;
+    var renameVal = renameData.value;
+    StdBillsLib.update({billsLibId: billsLibId}, {$set:{billsLibName: renameVal}}, function(err){
+        if(err){
+            callback(1, "Error");
+        }
+        else{
+            callback(0, "");
+        }
+    });
+}
+
+billsDao.prototype.getStdBillsLibName = function(billsLibId, callback){
+    StdBillsLib.find({billsLibId: billsLibId}, "-_id", function(err,  data){
+        if(err){
+            callback(1, "Error", null);
+        }
+        else {
+            callback(0, "", data);
+        }
+    });
+}
+//----------------------------Bills---------------------
+billsDao.prototype.getBills = function (billsLibId, callback) {
+    Bills.find({billsLibId: billsLibId}, "-_id",  function(err, billsData){
+        if(err){
+            callback(1, "Error", null);
+        }
+        else{
+            callback(0, "", billsData);
+        }
+    });
+}
+
+billsDao.prototype.createBills = function(cbillsData, callback){
+    counter.getIDAfterCount('bills', 1, function(err, result){
+        var newId = result.value.sequence_value;
+        var pid = cbillsData.ParentID;
+        var nid = cbillsData.NextSiblingID;
+        var billsLibId = cbillsData.billsLibId;
+        var newBills = {
+            ID: newId,
+            ParentID: pid,
+            NextSiblingID: nid,
+            billsLibId: billsLibId
+        };
+        Bills.create(newBills, function(err){
+            if(err){
+                callback(1, "Error");
+            }
+            else{
+                callback(0, "");
+            }
+        });
+
+    })
+
+}
+
+billsDao.prototype.updatePNId= function(updateData, callback){
+    var updateId = updateData.updateId;
+    var updatepid= updateData.ParentID;
+    var updatenid = updateData.NextSiblingID;
+    if(!updatepid){
+        Bills.update({ID: updateId}, {$set: {NextSiblingID: updatenid}}, function(err){
+            if(err){
+                callback(1, "Error")
+            }
+            else{
+                callback(0, "");
+            }
+        });
+    }
+    else if(!updatenid){
+        Bills.update({ID: updateId}, {$set: {ParentID: updatepid}}, function(err){
+            if(err){
+                callback(1, "Error")
+            }
+            else{
+                callback(0, "");
+            }
+        });
+    }
+    else {
+        Bills.update({ID: updateId}, {$set: {ParentID: updatepid, NextSiblingID: updatenid}}, function(err){
+            if(err){
+                callback(1, "Error")
+            }
+            else{
+                callback(0, "");
+            }
+        });
+    }
+}
+   /* Bills.update({nodeId: updateNode, billsLibId: billsLibId}, {$set: {ParentID: updatepid, NextSiblingID: updatenid}}, function(err){
+        if(err){
+            callback(1, "Error")
+        }
+        else{
+            callback(0, "");
+        }
+    });*/
+
+billsDao.prototype.updateBills = function(ubillsData, callback){
+    var updateId = ubillsData.id;
+    var updateField = ubillsData.field;
+    var updateData = ubillsData.data;
+    if(updateField == "code"){
+        Bills.update({ID: updateId}, {$set:{code: updateData}}, function(err){
+            if(err){
+                callback(1, "Error");
+            }
+            else {
+                callback(0, "");
+            }
+        });
+    }
+    else if(updateField == "name"){
+        Bills.update({ID: updateId}, {$set:{name: updateData}}, function(err){
+            if(err){
+                callback(1, "Error");
+            }
+            else {
+                callback(0, "");
+            }
+        });
+    }
+    else if(updateField == "unit"){
+        Bills.update({ID: updateId}, {$set:{unit: updateData}}, function(err){
+            if(err){
+                callback(1, "Error");
+            }
+            else {
+                callback(0, "");
+            }
+        });
+    }
+    else if(updateField == "ruleText"){
+        Bills.update({ID: updateId}, {$set:{ruleText: updateData}}, function(err){
+            if(err){
+                callback(1, "Error");
+            }
+            else {
+                callback(0, "");
+            }
+        });
+    }
+}
+
+billsDao.prototype.deleteBills = function(deleteIds, callback){
+   //ǰ�˿��Ƶõ���ɾ�������нڵ�deleteIds
+    if(deleteIds){
+        for(var i=0; i<deleteIds.length; i++){
+            Bills.remove({ID: deleteIds[i]}, function(err){
+                if(err){
+                    callback(1, "Error");
+                }
+                else{
+                    callback(0, "");
+                }
+            });
+        }
+    }
+}
+
+//--------------JobContent------------------
+billsDao.prototype.getJobContent = function(billsLibId, callback){
+    JobContent.find({billsLibId: billsLibId}, "-_id", function(err, jobs){
+        if(err){
+            callback(1, "Error", null);
+        }
+        else{
+            callback(0, "", jobs)
+        }
+    });
+}
+
+billsDao.prototype.createJobContent = function(cJobData, callback){
+    var field = cJobData.field;
+    var data = cJobData.data;
+    var id = counter.getIDAfterCount("billsLib", 1);
+    var billsLibId = cJobData.billsLibId;
+    var newJobContent;
+    if(field == "code"){
+        newJobContent = {
+            id: id,
+            billsLibId: billsLibId,
+            code: data
+        }
+    }
+    else if(field == "content"){
+        newJobContent = {
+            id: id,
+            billsLibId: billsLibId,
+            content: data
+        }
+    }
+    JobContent.create(newJobContent, function(err){
+        if(err){
+            callback(1, "Error");
+        }
+        else{
+            callback(0, "");
+        }
+    });
+}
+
+billsDao.prototype.updateJobContent = function(uJobData, callback){
+    var field = cJobData.field;
+    var updateData = cJobData.data;
+    var id = cJobData.id;
+    if(field == "code"){
+        JobContent.update({id: id}, {$set: {code: updateData}}, function(err){
+            if(err){
+                callback(1, "Error");
+            }
+            else{
+                callback(0, "");
+            }
+        });
+    }
+    else if(field == "content"){
+        JobContent.update({id: id}, {$set: {content: updateData}}, function(err){
+            if(err){
+                callback(1, "Error");
+            }
+            else{
+                callback(0, "");
+            }
+        });
+    }
+}
+
+billsDao.prototype.deleteJobContent = function(jobId, callback){
+    JobContent.remove({id: jobId}, function(err){
+        if(err){
+            callback(1, "Error");
+        }
+        else{
+            callback(0, "");
+        }
+    });
+}
+
+
+//----------------------ItemCharacter---------------------
+billsDao.prototype.getItemCharacter = function(billsLibId, callback){
+    ItemCharacter.find({billsLibId: billsLibId}, "-_id", function(err, items){
+        if(err){
+            callback(1, "Error", null);
+        }
+        else{
+            callback(0, "", items)
+        }
+    });
+}
+
+billsDao.prototype.createItemCharacter = function(cItemData, callback){
+    var field = cItemData.field;
+    var data = cItemData.data;
+    var id = counter.getIDAfterCount("billsLib", 1);
+    var billsLibId = cItemData.billsLibId;
+    var newItemCharacter;
+    if(field == "code"){
+        newItemCharacter = {
+            id: id,
+            billsLibId: billsLibId,
+            code: data
+        }
+    }
+    else if(field == "content"){
+        newItemCharacter = {
+            id: id,
+            billsLibId: billsLibId,
+            content: data
+        }
+    }
+}
+
+billsDao.prototype.updateItemCharacter = function(uItemData, callback){
+    var field = uItemData.field;
+    var updateData = uItemData.data;
+    var id = uItemData.id;
+    if(field == "code"){
+        ItemCharacter.update({id: id}, {$set: {code: updateData}}, function(err){
+            if(err){
+                callback(1, "Error");
+            }
+            else{
+                callback(0, "");
+            }
+        });
+    }
+    else if(field == "character"){
+        ItemCharacter.update({id: id}, {$set: {character: updateData}}, function(err){
+            if(err){
+                callback(1, "Error");
+            }
+            else{
+                callback(0, "");
+            }
+        });
+    }
+}
+
+billsDao.prototype.deleteItemCharacter = function(itemId, callback){
+    JobContent.remove({id: itemId}, function(err){
+        if(err){
+            callback(1, "Error");
+        }
+        else{
+            callback(0, "");
+        }
+    });
+}
+
+//----------------------itemValue
+
+//-----------------------------
+
+module.exports = new billsDao();

+ 18 - 0
modules/billsLib/billsLibModel/billsLibModel.js

@@ -0,0 +1,18 @@
+/**
+ * Created by vian on 2017/3/17.
+ */
+var dbm = require("../../../config/db/db_manager");
+var schemas = require("./billsLibSchemas.js");
+//var db = dbm.getLocalConnection("stdBillsLibData");
+var db = dbm.getCfgConnection("stdBillsEditor");
+var stdBillsLibMod = db.model("stdBillsLib", schemas.stdBillsLibSchema);
+var billsMod = db.model("billsLib", schemas.billsSchema);
+var jobContentMod = db.model("jobContent", schemas.jobContentSchema);
+var itemCharacterMod = db.model("itemCharacter", schemas.itemCharacterSchema);
+
+module.exports = {
+    stdBillsLibMod: stdBillsLibMod,
+    billsMod: billsMod,
+    jobContentMod: jobContentMod,
+    itemCharacterMod: itemCharacterMod,
+}

+ 58 - 0
modules/billsLib/billsLibModel/billsLibSchemas.js

@@ -0,0 +1,58 @@
+var mongoose = require('mongoose');
+
+var stdBillsLibSchema =mongoose.Schema({
+    billsLibId: Number,
+    billsLibName: String,
+    createDate: Date
+},
+    {versionKey: false}
+);
+
+var billsSchema = mongoose.Schema({
+    ID: Number,
+    ParentID: Number,
+    NextSiblingID: Number,
+    code: String,
+    name: String,
+    unit: String,
+    ruleText: String,
+    Expression: String,
+    jobs: Array,
+    items: Array,
+    recharge:String,
+    //nodeId: Number,
+    billsLibId: Number
+},
+    {versionKey: false}
+);
+
+var jobContentSchema = mongoose.Schema({
+    id: Number,
+    code: String,
+    content: String,
+    billsLibId: Number
+},
+    {versionKey: false}
+);
+
+var itemCharacterSchema = mongoose.Schema({
+    id: Number,
+    code: String,
+    character: String,
+    itemValue: Array,
+    billsLibId: Number
+},
+    {versionKey: false}
+);
+/*
+var eigenvalueSchema = mongoose.Schema({
+    eigenvalId: Number,
+    eigenvalContent: String
+});*/
+
+module.exports = {
+    stdBillsLibSchema: stdBillsLibSchema,
+    billsSchema: billsSchema,
+    jobContentSchema: jobContentSchema,
+    itemCharacterSchema: itemCharacterSchema
+}

+ 50 - 0
modules/billsLib/billsLibRoutes/billsLibRoutes.js

@@ -0,0 +1,50 @@
+/**
+ * Created by vian on 2017/3/17.
+ */
+var express = require("express");
+var billsController = require("../billsLibControllers/billsLibControllers");
+var billsRouter =express.Router();
+
+
+
+/*billsRouter.get("/", function(req, res) {
+    console.log("get/ing");
+    res.redirect("/stdBillsEditor/main");
+});*/
+
+/*billsRouter.get("/main", function(req, res){
+    res.render("billsLib/html/main.html");
+});
+
+billsRouter.get("/billsLib", function(req, res){
+    res.render("billsLib/html/qingdan.html");
+});
+
+billsRouter.get("/jobs", function(req, res){
+    res.render("billsLib/html/neirong.html");
+});
+
+billsRouter.get("/items", function(req, res){
+    res.render("billsLib/html/tezheng.html");
+});*/
+
+billsRouter.post("/getStdBillsLib", billsController.getStdBillsLib);
+billsRouter.post("/createStdBillsLib", billsController.createStdBillsLib);
+billsRouter.post("/deleteStdBillsLib", billsController.deleteStdBillsLib);
+billsRouter.post("/renameStdBillsLib", billsController.renameStdBillsLib);
+billsRouter.post("/getStdBillsLibName", billsController.getStdBillsLibName);
+billsRouter.post("/getBills", billsController.getBills);
+billsRouter.post("/createBills", billsController.createBills);
+billsRouter.post("/updatePNId", billsController.updatePNId);
+billsRouter.post("/updateBills", billsController.updateBills);
+billsRouter.post("/deleteBills", billsController.deleteBills);
+billsRouter.post("/getJobContent", billsController.getJobContent);
+billsRouter.post("/createJobContent", billsController.createJobContent);
+billsRouter.post("/updateJobContent", billsController.updateJobContent);
+billsRouter.post("/deleteJobContent", billsController.deleteJobContent);
+billsRouter.post("/getItemCharacter", billsController.getItemCharacter);
+billsRouter.post("/createItemCharacter", billsController.createItemCharacter);
+billsRouter.post("/updateItemCharacter", billsController.updateItemCharacter);
+billsRouter.post("/deleteItemCharacter", billsController.deleteItemCharacter);
+
+module.exports = billsRouter;

+ 461 - 0
public/web/idTree.js

@@ -0,0 +1,461 @@
+/**
+ * Created by Mai on 2017/3/17.
+ */
+var idTree = {
+    createNew: function (setting) {
+        var _setting = {
+            id: 'id',
+            pid: 'pid',
+            nid: 'nid',
+            rootId: -1
+        };
+
+        var _eventType = {
+            editedData: 'editedData'
+        };
+
+        var tools = {
+            findNode: function (nodes, check) {
+                for (var i = 0; i < nodes.length; i++) {
+                    if (check(nodes[i])) {
+                        return nodes[i];
+                    }
+                }
+                return null;
+            },
+            reSortNodes: function (nodes, recursive) {
+                var temp = [], first;
+                var findFirstNode = function (nodes) {
+                    return tools.findNode(nodes, function (node) {
+                        return node.preSibling === null;
+                    });
+                };
+                var moveNode = function (node, orgArray, newArray, newIndex) {
+                    var next;
+                    orgArray.splice(orgArray.indexOf(node), 1);
+                    newArray.splice(newIndex, 0, node);
+                    if (node.getNextSiblingID() !== -1) {
+                        next = node.nextSibling;
+                        if (next && (orgArray.indexOf(next) >= 0)) {
+                            moveNode(next, orgArray, newArray, newIndex + 1);
+                        }
+                    }
+                };
+                if (nodes.length === 0) {
+                    return nodes;
+                }
+                if (recursive) {
+                    nodes.forEach(function (node) {
+                        node.children = tools.reSortNodes(node.children, recursive);
+                    });
+                }
+                while (nodes.length > 0) {
+                    first = findFirstNode(nodes);
+                    first = first ? first : nodes[0];
+                    moveNode(first, nodes, temp, temp.length);
+                }
+                nodes = null;
+                tools.reSiblingNodes(temp);
+                return temp;
+            },
+            reSiblingNodes: function (nodes) {
+                var i;
+                for (i = 0; i < nodes.length; i++) {
+                    nodes[i].preSibling = (i === 0) ? null : nodes[i - 1];
+                    nodes[i].nextSibling = (i === nodes.length - 1) ? null : nodes[i + 1];
+                }
+            },
+            // 在nodes中,从iIndex(包括)开始全部移除
+            removeNodes: function (tree, parent, iIndex, count) {
+                var children = parent ? parent.children : tree.roots;
+                var pre = (iIndex < 0 || iIndex >= children.length) ? null : children[iIndex].preSibling;
+                var next = (pre && iIndex + count - 1 < children.length) ? children[iIndex + count] : null;
+                if (pre) {
+                    pre.nextSibling = next;
+                }
+                if (next) {
+                    next.preSibling = pre;
+                }
+                if (arguments.length === 4) {
+                    children.splice(iIndex, count);
+                } else {
+                    children.splice(iIndex, children.length - iIndex);
+                }
+            },
+            // 在nodes中增加addNodes, 位置从index开始
+            addNodes: function (tree, parent, nodes, iIndex) {
+                var children = parent ? parent.children : tree.roots;
+                var pre, next, i;
+                if (nodes.length === 0) { return; }
+                if (arguments.length === 4) {
+                    pre = (iIndex <= 0 || iIndex > children.length) ? null : children[iIndex - 1];
+                    next = pre ? pre.nextSibling : null;
+                } else if (arguments.length === 3) {
+                    pre = children.length === 0 ? null : children[children.length - 1];
+                    next = null;
+                }
+                if (pre) {
+                    pre.nextSibling = nodes[0];
+                }
+                nodes[0].preSibling = pre;
+                if (next) {
+                    next.preSibling = nodes[nodes.length - 1];
+                }
+                nodes[nodes.length - 1].nextSibling = next;
+                for (i = 0; i < nodes.length; i++) {
+                    if (arguments.length === 4) {
+                        children.splice(iIndex + i, 0, nodes[i]);
+                    } else if (arguments.length === 3) {
+                        children.push(nodes[i]);
+                    }
+                    nodes[i].parent = parent;
+                }
+            },
+            sortTreeItems: function (tree) {
+                var addItems = function (items) {
+                    var i;
+                    for (i = 0; i < items.length; i++) {
+                        tree.items.push(items[i]);
+                        addItems(items[i].children);
+                    }
+                };
+                tree.items.splice(0, tree.items.length);
+                addItems(tree.roots);
+            }
+        };
+
+        var Node = function (tree, data) {
+            // 以下的属性,本单元外均不可直接修改
+            this.tree = tree;
+            this.data = data;
+            this.children = [];
+
+            this.parent = null;
+            this.nextSibling = null;
+            this.preSibling = null;
+
+            this.expanded = true;
+            this.visible = true;
+
+            this.visible = true;
+
+            this.isUpdate = false;
+            this.isNew = false;
+        };
+
+        Node.prototype.getID = function () {
+            return this.data[this.tree.setting.id];
+        };
+        Node.prototype.getParentID = function () {
+            return this.parent ? this.parent.getID() : -1;
+        };
+        Node.prototype.getNextSiblingID = function () {
+            return this.nextSibling ? this.nextSibling.getID() : -1;
+        };
+
+        Node.prototype.firstChild = function () {
+            return this.children.length === 0 ? null : this.children[0];
+        };
+        Node.prototype.depth = function () {
+            return this.parent ? this.parent.depth() + 1 : 0;
+        };
+        Node.prototype.isFirst = function () {
+            if (this.parent) {
+                return this.parent.children.indexOf(this) === 0 ? true : false;
+            } else {
+                return this.tree.roots.indexOf(this) === 0 ? true : false;
+            }
+        };
+        Node.prototype.isLast = function () {
+            if (this.parent) {
+                return this.parent.children.indexOf(this) === this.parent.children.length - 1 ? true : false;
+            } else {
+                return this.tree.roots.indexOf(this) === this.tree.roots.length - 1 ? true : false;
+            }
+        };
+        Node.prototype.siblingIndex = function () {
+            return this.parent ? this.parent.children.indexOf(this) : this.tree.roots.indexOf(this);
+        }
+        Node.prototype.posterityCount = function () {
+            var iCount = 0;
+            if (this.children.length !== 0) {
+                iCount += this.children.length;
+                this.children.forEach(function (child) {
+                    iCount += child.posterityCount();
+                });
+            }
+            return iCount;
+            /*return (node.children.length === 0) ? 0 : node.children.reduce(function (x, y) {
+                return x.posterityCount() + y.posterityCount();
+            }) + node.children.count;*/
+        };
+
+        Node.prototype.setExpanded = function (expanded) {
+            var setNodesVisible = function (nodes, visible) {
+                nodes.forEach(function (node) {
+                    node.visible = visible;
+                    setNodesVisible(node.children, visible && node.expanded);
+                })
+            };
+            this.expanded = expanded;
+            setNodesVisible(this.children, expanded);
+        };
+        /*Node.prototype.vis = function () {
+            return this.parent ? this.parent.vis() && this.parent.expanded() : true;
+        };*/
+        Node.prototype.serialNo = function () {
+            return this.tree.items.indexOf(this);
+        };
+
+        Node.prototype.addChild = function (node) {
+            var preSibling = this.children.length === 0 ? null : this.children[this.children.length - 1];
+            node.parent = this;
+            if (preSibling) {
+                preSibling.nextSibling = node;
+            }
+            node.preSibling = preSibling;
+            this.children.push(node);
+        };
+        Node.prototype.removeChild = function (node) {
+            var preSibling = node.preSibling, nextSibling = node.nextSibling;
+            if (preSibling) {
+                preSibling.nextSibling = nextSibling;
+            }
+            if (nextSibling) {
+                nextSibling.preSibling = preSibling;
+            }
+            this.children.splice(this.children.re)
+        };
+
+        Node.prototype.canUpLevel = function () {
+            return this.parent ? true : false;
+        };
+        Node.prototype.canDownLevel = function () {
+            return !this.isFirst();
+        };
+        Node.prototype.canUpMove = function () {
+            return !this.isFirst();
+        };
+        Node.prototype.canDownMove = function () {
+            return !this.isLast();
+        }
+
+        Node.prototype.upLevel = function () {
+            var success = false,
+                iIndex = this.parent.children.indexOf(this), orgParent = this.parent, newNextSibling = this.parent.nextSibling;
+            if (this.canUpLevel) {
+                // NextSiblings become child
+                tools.addNodes(this.tree, this, this.parent.children.slice(iIndex + 1));
+                // Orginal Parent remove node and nextSiblings
+                tools.removeNodes(this.tree, this.parent, iIndex);
+                // New Parent add node
+                tools.addNodes(this.tree, this.parent.parent, [this], this.parent.siblingIndex() + 1);
+                if (!this.expanded) {
+                    this.setExpanded(true);
+                }
+                success = true;
+            }
+            return success;
+        };
+        Node.prototype.downLevel = function () {
+            var success = false, iIndex = this.parent ? this.parent.children.indexOf(this) : this.tree.roots.indexOf(this);
+            var newParent = this.preSibling;
+            if (this.canDownLevel()) {
+                tools.removeNodes(this.tree, this.parent, this.siblingIndex(), 1);
+                tools.addNodes(this.tree, this.preSibling, [this]);
+                if (!newParent.expanded) {
+                    newParent.setExpanded(true);
+                }
+                success = true;
+            }
+            return success;
+        };
+        Node.prototype.upMove = function () {
+            var success = false;
+            var iIndex = this.siblingIndex(), belongArray = this.parent ? this.parent.children : this.tree.roots, orgPre = this.preSibling;
+            if (this.canUpMove()) {
+                orgPre.nextSibling = this.nextSibling;
+                this.preSibling = orgPre.preSibling;
+                orgPre.preSibling = this;
+                this.nextSibling = orgPre;
+                belongArray.splice(iIndex, 1);
+                belongArray.splice(iIndex - 1, 0, this);
+                tools.sortTreeItems(this.tree);
+                success = true;
+            }
+            return success;
+        };
+        Node.prototype.downMove = function () {
+            var success = false;
+            var iIndex = this.siblingIndex(), belongArray = this.parent ? this.parent.children : this.tree.roots, orgNext = this.nextSibling;
+            if (this.canDownMove()) {
+                orgNext.preSibling = this.preSibling;
+                this.nextSibling = orgNext.nextSibling;
+                orgNext.nextSibling = this;
+                this.preSibling = orgNext;
+                belongArray.splice(iIndex, 1);
+                belongArray.splice(iIndex + 1, 0, this);
+                tools.sortTreeItems(this.tree);
+                success = true;
+            }
+            return success;
+        }
+
+        var Tree = function (setting) {
+            this.nodes = {};
+            this.roots = [];
+            this.items = [];
+            this.setting = setting;
+            this.prefix = 'id_';
+            this.selected = null;
+
+            this.event = {};
+            this.eventType = _eventType;
+        };
+
+        Tree.prototype.maxNodeID = (function () {
+            var maxID = 0;
+            return function (ID) {
+                if (arguments.length === 0) {
+                    return maxID;
+                } else {
+                    maxID = Math.max(maxID, ID);
+                }
+            };
+        })();
+        Tree.prototype.rangeNodeID = (function () {
+            var rangeID = -1;
+            return function (ID) {
+                if (arguments.length === 0) {
+                    return rangeID;
+                } else {
+                    rangeID = Math.max(rangeID, ID);
+                }
+            }
+        })();
+        Tree.prototype.newNodeID = function () {
+            if (this.rangeNodeID() === -1) {
+                return this.maxNodeID() + 1;
+            } else {
+                if (this.maxNodeID() >= this.rangeNodeID()) {
+                    return this.maxNodeID() + 1;
+                } else {
+                    return -1;
+                }
+            }
+            /*if (this.maxID >= this.rangeNodeID() || this.rangeNodeID === -1) {
+                return -1;
+            } else {
+                return this.maxNodeID() + 1;
+            }*/
+        };
+
+        Tree.prototype.loadDatas = function (datas) {
+            var prefix = this.prefix, i, node, parent, next, that = this;
+            // prepare index
+            datas.forEach(function (data) {
+                var node = new Node(that, data);
+                that.nodes[prefix + data[that.setting.id]] = node;
+                that.maxNodeID(data[that.setting.id]);
+            });
+            // set parent by pid, set nextSibling by nid
+            datas.forEach(function (data) {
+                node = that.nodes[prefix + data[that.setting.id]];
+                if (data[that.setting.pid] === that.setting.rootId) {
+                    that.roots.push(node);
+                } else {
+                    parent = that.nodes[prefix + data[that.setting.pid]];
+                    if (parent) {
+                        node.parent = parent;
+                        parent.children.push(node);
+                    }
+                }
+                if (data[that.setting.nid] !== that.setting.rootId) {
+                    next = that.nodes[prefix + data[that.setting.nid]];
+                    if (next) {
+                        node.nextSibling = next;
+                        next.preSibling = node;
+                    }
+                }
+            })
+            // sort by nid
+            this.roots = tools.reSortNodes(this.roots, true);
+            tools.sortTreeItems(this);
+        };
+        Tree.prototype.firstNode = function () {
+            return this.roots.length === 0 ? null : this.roots[0];
+        };
+        Tree.prototype.findNode = function (id) {
+            return this.nodes[this.prefix + id];
+        };
+        Tree.prototype.count = function () {
+            var iCount = 0;
+            if (this.roots.length !== 0) {
+                iCount += this.roots.length;
+                this.roots.forEach(function (node) {
+                    iCount += node.posterityCount();
+                });
+            }
+            return iCount;
+        };
+
+        Tree.prototype.insert = function (parentID, nextSiblingID) {
+            var newID = this.newNodeID(), node = null, data = {};
+            var parent = parentID === -1 ? null : this.nodes[this.prefix + parentID];
+            var nextSibling = nextSiblingID === -1 ? null: this.nodes[this.prefix + nextSiblingID];
+            if (newID !== -1) {
+                data = {};
+                data[this.setting.id] = newID;
+                data[this.setting.pid] = parentID;
+                data[this.setting.nid] = nextSiblingID;
+                node = new Node(this, data);
+                if (nextSibling) {
+                    tools.addNodes(this, parent, [node], nextSibling.siblingIndex());
+                } else {
+                    tools.addNodes(this, parent, [node]);
+                }
+                this.nodes[this.prefix + newID] = node;
+                tools.sortTreeItems(this);
+                this.maxNodeID(newID);
+            }
+            return node;
+        };
+        Tree.prototype.delete = function (node) {
+            var success = false;
+            if (node) {
+                delete this.nodes[this.prefix + node.getID()];
+                if (node.preSibling) {
+                    node.preSibling.nextSibling = node.nextSibling;
+                }
+                if (node.nextSibling) {
+                    node.nextSibling.preSibling = node.preSibling;
+                }
+                if (node.parent) {
+                    node.parent.children.splice(node.siblingIndex(), 1);
+                } else {
+                    this.roots.splice(node.siblingIndex(), 1);
+                }
+                tools.sortTreeItems(this);
+                success = true;
+            }
+            return success;
+        };
+
+        /*Tree.prototype.editedData = function (field, id, newText) {
+            var node = this.findNode(id), result = {allow: false, nodes: []};
+            if (this.event[this.eventType.editedData]) {
+                return this.event[this.eventType.editedData](field, node.data);
+            } else {
+                node.data[field] = newText;
+                result.allow = true;
+                return result;
+            }
+        };*/
+
+        Tree.prototype.bind = function (eventName, eventFun) {
+            this.event[eventName] = eventFun;
+        };
+
+        return new Tree(setting);
+    }
+};

+ 136 - 0
public/web/tree_sheet_controller.js

@@ -0,0 +1,136 @@
+/**
+ * Created by Mai on 2017/4/1.
+ */
+
+var TREE_SHEET_CONTROLLER = {
+    createNew: function (tree, sheet, setting) {
+        var controller = function () {
+            this.tree = tree;
+            this.sheet = sheet;
+            this.setting = setting;
+            this.event = {
+                refreshBaseActn: null
+            }
+        };
+
+        controller.prototype.showTreeData = function () {
+            var that = this;
+            TREE_SHEET_HELPER.loadSheetHeader(this.setting, this.sheet);
+            TREE_SHEET_HELPER.showTreeData(this.setting, this.sheet, this.tree);
+
+            this.sheet.bind(GC.Spread.Sheets.Events.SelectionChanged, function (e, info) {
+                that.setTreeSelected(that.tree.findNode(info.sheet.getTag(info.newSelections[0].row, info.newSelections[0].col)));
+            });
+
+            /*this.sheet.bind(GC.Spread.Sheets.Events.EditEnded, function (sender, args) {
+                var result = tree.editedData(setting.cols[args.col].data.field, args.sheet.getTag(args.row, args.col), args.editingText);
+
+                if (result.allow) {
+                    TREE_SHEET_HELPER.refreshTreeNodeData(that.setting, that.sheet, result.nodes, false);
+                } else {
+                    TREE_SHEET_HELPER.refreshTreeNodeData(that.setting, that.sheet, [tree.findNode(args.sheet.getTag(args.row, args.col))], false);
+                };
+            });*/
+        };
+
+        controller.prototype.insert = function () {
+            var newNode = null, that = this,  sels = this.sheet.getSelections();
+            if (this.tree) {
+                if (this.tree.selected) {
+                    newNode = this.tree.insert(this.tree.selected.getParentID(), this.tree.selected.getNextSiblingID());
+                } else {
+                    newNode = this.tree.insert();
+                }
+                if (newNode) {
+                    TREE_SHEET_HELPER.massOperationSheet(this.sheet, function () {
+                        that.sheet.addRows(newNode.serialNo(), 1);
+                        TREE_SHEET_HELPER.refreshTreeNodeData(that.setting, that.sheet, [newNode], false);
+                        that.setTreeSelected(newNode);
+                        that.sheet.setSelection(newNode.serialNo(), sels[0].col, 1, 1);
+                        that.sheet.showRow(newNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center)
+                    });
+                }
+            }
+        };
+        controller.prototype.delete = function () {
+            var that = this, sels = this.sheet.getSelections();
+            if (this.tree.selected) {
+                if (this.tree.delete(this.tree.selected)) {
+                    TREE_SHEET_HELPER.massOperationSheet(this.sheet, function () {
+                        that.sheet.deleteRows(sels[0].row, that.tree.selected.posterityCount() + 1);
+                        that.setTreeSelected(that.tree.findNode(that.sheet.getTag(sels[0].row, 0, GC.Spread.Sheets.SheetArea.viewport)));
+                    });
+                }
+            }
+        };
+        controller.prototype.upLevel = function () {
+            var that = this;
+            if (this.tree.selected) {
+                if (this.tree.selected.upLevel()) {
+                    TREE_SHEET_HELPER.massOperationSheet(this.sheet, function () {
+                        TREE_SHEET_HELPER.refreshNodesVisible([that.tree.selected], that.sheet, true);
+                        that.sheet.showRow(that.tree.selected.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
+                        if (that.event.refreshBaseActn) {
+                            that.event.refreshBaseActn(that.tree);
+                        }
+                    });
+                }
+            }
+        };
+        controller.prototype.downLevel = function () {
+            var that = this;
+            if (this.tree.selected) {
+                if (this.tree.selected.downLevel()) {
+                    TREE_SHEET_HELPER.massOperationSheet(that.sheet, function () {
+                        TREE_SHEET_HELPER.refreshNodesVisible([that.tree.selected.parent], that.sheet, true);
+                        that.sheet.showRow(that.tree.selected.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
+                        if (that.event.refreshBaseActn) {
+                            that.event.refreshBaseActn(that.tree);
+                        }
+                    });
+                }
+            }
+        };
+        controller.prototype.upMove = function () {
+            var that = this, sels = this.sheet.getSelections();
+            if (this.tree.selected) {
+                if (this.tree.selected.upMove()) {
+                    TREE_SHEET_HELPER.massOperationSheet(this.sheet, function () {
+                        TREE_SHEET_HELPER.refreshTreeNodeData(that.setting, that.sheet, [that.tree.selected, that.tree.selected.nextSibling], true);
+                        that.sheet.setSelection(that.tree.selected.serialNo(), sels[0].col, 1, 1);
+                        if (that.event.refreshBaseActn) {
+                            that.event.refreshBaseActn(that.tree);
+                        }
+                    });
+                }
+            }
+        };
+        controller.prototype.downMove = function () {
+            var that = this, sels = this.sheet.getSelections();
+            if (this.tree.selected) {
+                if (this.tree.selected.downMove()) {
+                    TREE_SHEET_HELPER.massOperationSheet(this.sheet, function () {
+                        TREE_SHEET_HELPER.refreshTreeNodeData(that.setting, that.sheet, [that.tree.selected, that.tree.selected.preSibling], true);
+                        that.sheet.setSelection(that.tree.selected.serialNo(), sels[0].col, 1, 1);
+                        if (that.event.refreshBaseActn) {
+                            that.event.refreshBaseActn(that.tree);
+                        }
+                    });
+                }
+            }
+        };
+
+        controller.prototype.setTreeSelected = function (node) {
+            this.tree.selected = node;
+            if (this.event.refreshBaseActn) {
+                this.event.refreshBaseActn(this.tree);
+            }
+        }
+
+        controller.prototype.bind = function (eventName, eventFun) {
+            this.event[eventName] = eventFun;
+        };
+
+        return new controller();
+    }
+};

+ 178 - 0
web/billsLib/html/main.html

@@ -0,0 +1,178 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta http-equiv="x-ua-compatible" content="ie=edge">
+    <title>清单规则编辑器</title>
+    <link rel="stylesheet" href="../../css/bootstrap/bootstrap.min.css">
+    <!--<link rel="stylesheet" href="css/bootstrap/themes.css">-->
+    <link rel="stylesheet" href="../../css/main.css">
+    <link rel="stylesheet" href="../../css/font-awesome/font-awesome.min.css">
+    <!--zTree-->
+  	<link rel="stylesheet" href="../../css/ztree/zTreeStyle.css" type="text/css">
+</head>
+
+<body>
+    <div class="header">
+        <nav class="navbar navbar-toggleable-lg navbar-light bg-faded p-0 ">
+            <span class="header-logo px-2">清单规则编辑器</span>
+            <div class="navbar-text"></div>
+        </nav>
+        <nav class="navbar navbar-toggleable-lg justify-content-between navbar-light p-0">
+          <ul class="nav navbar-nav px-1">
+                          <li class="nav-item">
+                              <a class="nav-link" href="javascript:void(0);" aria-haspopup="true" aria-expanded="false" data-toggle="modal" data-target="#add">新建清单规则</a>
+                          </li>
+                      </ul>
+        </nav>
+    </div>
+    <div class="main">
+        <div class="content">
+            <div class="container-fluid">
+                <div class="row">
+                  <div class="col-md-8">
+                    <div class="warp-p2 mt-3">
+                      <table class="table table-hover table-bordered">
+                        <thead><tr><th>清单规则名称</th><th width="160">添加时间</th><th width="90">操作</th></tr></thead>
+                        <tbody id="showArea">
+                          <!--<tr><td><a href="qingdan.html">XX清单规则</a></td><td>2017-01-01 </td><td><a href="javacript:void(0);" data-toggle="modal" data-target="#edit" title="编辑"><i class="fa fa-pencil-square-o"></i></a> <a href="javacript:void(0);" data-toggle="modal" data-target="#del" class="text-danger" title="删除"><i class="fa fa-remove"></i></a></td></tr>
+                          <tr><td><a href="qingdan.html">XX清单规则</a></td><td>2017-01-01 </td><td><a href="javacript:void(0);" data-toggle="modal" data-target="#edit" title="编辑"><i class="fa fa-pencil-square-o"></i></a> <a href="javacript:void(0);" data-toggle="modal" data-target="#del" class="text-danger" title="删除"><i class="fa fa-remove"></i></a></td></tr>
+                          <tr><td><a href="qingdan.html">XX清单规则</a></td><td>2017-01-01 </td><td><a href="javacript:void(0);" data-toggle="modal" data-target="#edit" title="编辑"><i class="fa fa-pencil-square-o"></i></a> <a href="javacript:void(0);" data-toggle="modal" data-target="#del" class="text-danger" title="删除"><i class="fa fa-remove"></i></a></td></tr>-->
+                        </tbody>
+                      </table>
+                    </div>
+                  </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!--弹出添加-->
+    <div class="modal fade" id="add" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                  <h5 class="modal-title">添加清单规则</h5>
+                  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                  </button>
+                </div>
+                <div class="modal-body">
+                  <form>
+                    <div class="form-group">
+                      <label>清单规则名称</label>
+                      <input id="createText" class="form-control" placeholder="输入清单规则名称" type="text">
+                    </div>
+                  </form>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <a id="createA"  href="javascript:void(0);" class="btn btn-primary" data-dismiss="modal">新建</a>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!--弹出编辑-->
+    <div class="modal fade" id="edit" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                  <h5 class="modal-title">编辑清单规则</h5>
+                  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                  </button>
+                </div>
+                <div class="modal-body">
+                  <form>
+                    <div class="form-group">
+                      <label>清单规则名称</label>
+                      <input id="renameText" class="form-control" placeholder="输入名称" type="text" value="">
+                    </div>
+                  </form>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <a id="renameA" href="javascript: void(0);" class="btn btn-primary" data-dismiss="modal" renameId="">确定</a>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <!--弹出删除-->
+    <div class="modal fade" id="del" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                  <h5 class="modal-title">删除确认</h5>
+                  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                  </button>
+                </div>
+                <div class="modal-body">
+                    <h5 class="text-danger">删除后无法恢复,确认是否删除?</h5>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <a id="deleteA" href="javascript:void(0);" class="btn btn-danger" data-dismiss="modal" deleteId="">删除</a>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!-- JS. -->
+    <script src="lib/jquery/jquery.min.js"></script>
+    <script src="lib/tether/tether.min.js"></script>
+    <script src="lib/bootstrap/bootstrap.min.js"></script>
+    <script src="lib/global.js"></script>
+    <script src="web/billsLib/scripts/billsLibAjax.js"></script>
+    <script src="web/billsLib/scripts/dateFormat.js"></script>
+
+</body>
+<script type="text/javascript">
+    autoFlashHeight();
+    mainAjax.getStdBillsLib(null);
+</script>
+<script>
+    $(document).ready(function(){
+        //main 增删改
+        $("#createA").click(function(){
+            var billsLibName = $("#createText").val();
+            if(billsLibName){
+                mainAjax.createStdBillsLib(billsLibName);
+                $("#createText").val("");
+            }
+            else{
+                alert("请输入清单规则名称!");
+            }
+        });
+
+       $("#showArea").on("click", "[data-target = '#del']", function(){
+            var deleteId = $(this).parent().parent().attr("id")
+           $("#deleteA").attr("deleteId", deleteId);
+       });
+        $("#deleteA").click(function(){
+            var deleteId = $(this).attr("deleteId");
+            mainAjax.deleteStdBillsLib(deleteId);
+        });
+
+       $("#showArea").on("click", "[data-target = '#edit']", function(){
+           var renameId = $(this).parent().parent().attr("id");
+           $("#renameA").attr("renameId", renameId);
+
+       });
+
+        $("#renameA").click(function(){
+            var newName = $("#renameText").val();
+            var renameId = $(this).attr("renameId");
+            if(newName){
+                mainAjax.renameStdBillsLib(renameId, newName);
+                $("#renameText").val("");
+            }
+            else {
+                alert("请输入名称!");
+            }
+        });
+    });
+</script>
+
+</html>

+ 211 - 0
web/billsLib/html/neirong.html

@@ -0,0 +1,211 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta http-equiv="x-ua-compatible" content="ie=edge">
+    <title>清单规则编辑器</title>
+    <link rel="stylesheet" href="../../css/bootstrap/bootstrap.min.css">
+    <!--<link rel="stylesheet" href="../../web/css/bootstrap/themes.css">-->
+    <link rel="stylesheet" href="../../css/main.css">
+    <link rel="stylesheet" href="../../css/font-awesome/font-awesome.min.css">
+    <!--spread-->
+    <link rel="stylesheet" href="../../../web/css/spreadjs/gc.spread.sheets.excel2013white.10.0.1.css">
+    <!--zTree-->
+    <link rel="stylesheet" href="../../css/ztree/zTreeStyle.css" type="text/css">
+</head>
+
+<body>
+    <div class="header">
+        <nav class="navbar navbar-toggleable-lg navbar-light bg-faded p-0 ">
+            <span class="header-logo px-2">清单规则编辑器</span>
+            <div class="navbar-text"><a href="main.html">清单规则</a><i class="fa fa-angle-right fa-fw"></i>XXX清单规则</div>
+        </nav>
+        <nav class="navbar navbar-toggleable-lg justify-content-between navbar-light p-0">
+
+              <ul class="nav nav-tabs" role="tablist">
+                  <li class="nav-item">
+                      <a class="nav-link px-3" href="qingdan.html">清单</a>
+                  </li>
+                  <li class="nav-item">
+                      <a class="nav-link active px-3" href="neirong.html">工作内容</a>
+                  </li>
+                  <li class="nav-item">
+                      <a class="nav-link px-3" href="tezheng.html">项目特征</a>
+                  </li>
+              </ul>
+        </nav>
+    </div>
+    <div class="main">
+      <div class="content">
+        <div class="container-fluid">
+          <div class="row">
+            <div class="main-content col-lg-7 p-0">
+                <nav class="tools-bar">
+                </nav>
+                <div class="main-data" id="spreadAllJobs">
+                </div>
+            </div>
+            <div class="main-side col-lg-5 p-0">
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <!--弹出添加-->
+    <div class="modal fade" id="add" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                  <h5 class="modal-title">添加定额</h5>
+                  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                  </button>
+                </div>
+                <div class="modal-body">
+                  <form>
+                    <div class="form-group">
+                      <label>编码</label>
+                      <input class="form-control" placeholder="输入编码" type="text">
+                    </div>
+                    <div class="form-group">
+                      <label>名称</label>
+                      <input class="form-control" placeholder="输入名称" type="text">
+                    </div>
+                    <div class="form-group">
+                      <label>单位</label>
+                      <select class="form-control"><option>选择单位</option><option>m3</option></select>
+                    </div>
+                    <div class="form-group">
+                      <label>基价</label>
+                      <input class="form-control" placeholder="输入基价" type="number">
+                    </div>
+                    <div class="form-group">
+                      <label>显示名称(以%s表示参数)</label>
+                      <input class="form-control" placeholder="输入显示名称" type="text">
+                    </div>
+                    <div class="form-group">
+                      <label>默认取费专业</label>
+                      <input class="form-control" placeholder="输入取费专业" type="text">
+                    </div>
+                  </form>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <a href="" class="btn btn-primary">添加</a>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!--弹出编辑-->
+    <div class="modal fade" id="edit" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                  <h5 class="modal-title">编辑定额</h5>
+                  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                  </button>
+                </div>
+                <div class="modal-body">
+                  <form>
+                    <div class="form-group">
+                      <label>编码</label>
+                      <input class="form-control" placeholder="输入编码" type="text" value="AA0001">
+                    </div>
+                    <div class="form-group">
+                      <label>名称</label>
+                      <input class="form-control" placeholder="输入名称" type="text" value="人工挖土方">
+                    </div>
+                    <div class="form-group">
+                      <label>单位</label>
+                      <select class="form-control"><option>m3</option></select>
+                    </div>
+                    <div class="form-group">
+                      <label>基价</label>
+                      <input class="form-control" placeholder="输入基价" type="number" value="880.84">
+                    </div>
+                    <div class="form-group">
+                      <label>显示名称(以%s表示参数)</label>
+                      <input class="form-control" placeholder="输入显示名称" type="text" value="人工挖土方">
+                    </div>
+                    <div class="form-group">
+                      <label>默认取费专业</label>
+                      <input class="form-control" placeholder="输入取费专业" type="text" value="1">
+                    </div>
+                  </form>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <a href="" class="btn btn-primary">确定</a>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <!--弹出删除-->
+    <div class="modal fade" id="del" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                  <h5 class="modal-title">删除确认</h5>
+                  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                  </button>
+                </div>
+                <div class="modal-body">
+                    <h5 class="text-danger">删除后无法恢复,确认是否删除?</h5>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <a href="" class="btn btn-danger">删除</a>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!-- JS. -->
+    <script src="../../../lib/spreadjs/gc.spread.sheets.all.10.0.1.min.js"></script>
+    <script src="../../../lib/jquery/jquery.min.js"></script>
+    <script src="../../../lib/tether/tether.min.js"></script>
+    <script src="../../../lib/bootstrap/bootstrap.min.js"></script>
+    <script src="..//scripts/global.js"></script>
+    <script src="..//scripts/setSheets.js"></script>
+    <SCRIPT type="text/javascript">
+        $(document).ready(function(){
+            buildAllJobs();
+        });
+        function buildAllJobs(){
+            var spread = new GC.Spread.Sheets.Workbook($("#spreadAllJobs")[0], {sheetCount: 1});
+            var sheet = spread.getSheet(0);
+            var chRowCount = 2;
+            var vpColCount = 2;
+            var vpRowCount = 28;
+            sheet.suspendPaint();
+            sheet.suspendEvent();
+            initSheet(spread, sheet, chRowCount, vpRowCount, vpColCount);
+            setupColHeader(sheet);
+            //initRowHeight(sheet);
+            setCell(sheet);
+            myCommand(spread, sheet);
+            setScrollBar(spread, sheet, vpRowCount);
+            sheet.resumePaint();
+            sheet.resumeEvent();
+        }
+        function setupColHeader(sheet){
+            var ch = GC.Spread.Sheets.SheetArea.colHeader;
+            sheet.addSpan(0 ,0, 2, 1, ch);
+            sheet.setValue(0, 0, "编号", ch);
+            sheet.setColumnWidth(0, 200);
+            sheet.addSpan(0 ,1, 2, 1, ch);
+            sheet.setValue(0, 1, "工作内容", ch);
+            sheet.setColumnWidth(1, 850);
+        }
+
+  	</SCRIPT>
+</body>
+<script type="text/javascript">
+    autoFlashHeight();
+</script>
+
+</html>

+ 485 - 0
web/billsLib/html/qingdan.html

@@ -0,0 +1,485 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta http-equiv="x-ua-compatible" content="ie=edge">
+    <title>清单规则编辑器</title>
+    <link rel="stylesheet" href="web/css/bootstrap/bootstrap.min.css">
+    <!--<link rel="stylesheet" href="../../web/css/bootstrap/themes.css">-->
+    <link rel="stylesheet" href="web/css/main.css">
+    <link rel="stylesheet" href="web/css/font-awesome/font-awesome.min.css">
+    <!--spread-->
+    <link rel="stylesheet" href="web/css/spreadjs/gc.spread.sheets.excel2013white.10.0.1.css">
+    <!--zTree-->
+    <link rel="stylesheet" href="web/css/ztree/zTreeStyle.css" type="text/css">
+</head>
+
+<body>
+    <div class="header">
+        <nav class="navbar navbar-toggleable-lg navbar-light bg-faded p-0 ">
+            <span class="header-logo px-2">清单规则编辑器</span>
+            <div class="navbar-text"></div>
+        </nav>
+        <nav class="navbar navbar-toggleable-lg justify-content-between navbar-light p-0">
+
+              <ul class="nav nav-tabs" role="tablist">
+                  <li class="nav-item">
+                      <a class="nav-link active px-3" href="qingdan.html">清单</a>
+                  </li>
+                  <li class="nav-item">
+                      <a class="nav-link px-3" href="neirong.html">工作内容</a>
+                  </li>
+                  <li class="nav-item">
+                      <a class="nav-link px-3" href="tezheng.html">项目特征</a>
+                  </li>
+              </ul>
+        </nav>
+    </div>
+    <div class="main">
+      <div class="content" >
+        <div class="container-fluid">
+          <div class="row">
+            <div class="main-content col-lg-7 p-0">
+                <nav class="navbar sticky-top navbar-toggleable-md navbar-light bg-faded tools-bar">
+                  <div class="collapse navbar-collapse" id="navbarNav">
+                      <ul class="navbar-nav">
+                          <li class="nav-item">
+                              <a class="nav-link text-primary" id="insert" href="javascript: void(0);"><i class="fa fa-share" aria-hidden="true"></i>插入</a>
+                          </li>
+                          <li class="nav-item">
+                              <a class="nav-link text-primary" id ="delete" href="javascript:void (0)"><i class="fa fa-remove" aria-hidden="true"></i>删除</a>
+                          </li>
+                          <li class="nav-item">
+                              <a class="nav-link text-primary" id="upLevel"  href="javascript: void(0);"><i class="fa fa-arrow-left" aria-hidden="true"></i>升级</a>
+                          </li>
+                          <li class="nav-item">
+                              <a class="nav-link text-primary" id="downLevl" href="javascript: void(0);"><i class="fa fa-arrow-right" aria-hidden="true"></i>降级</a>
+                          </li>
+                          <li class="nav-item">
+                              <a class="nav-link text-primary" id="upMove" href="javascript: void(0);"><i class="fa fa-arrow-up" aria-hidden="true"></i>上移</a>
+                          </li>
+                          <li class="nav-item">
+                              <a class="nav-link text-primary" id="downMove" href="javascript: void(0);"><i class="fa fa-arrow-down" aria-hidden="true"></i>下移</a>
+                          </li>
+                      </ul>
+                  </div>
+                </nav>
+                <div class="main-data" id="spreadBills">
+                  <!--<div id="spreadBills" style="width: 100%; height: 700px;"></div>-->
+                </div>
+            </div>
+            <div class="main-side col-lg-5 p-0">
+              <div class="container-fluid">
+                <div class="row">
+                  <div class="col" style="width:50%; height: 100%">
+                      <h5>工作内容</h5>
+                      <div id="spreadJobs"  style="width:97%; height: 300px;"></div>
+                  </div>
+                  <div class="col" style="width:50%; height: 100%">
+                    <h5>项目特征</h5>
+                      <div id="spreadItems" style="width: 97%; height: 300px;"></div>
+                  </div>
+                  <div class="w-100"></div>
+                  <div class="col">
+                    <div class="form-group">
+                      <label for="exampleTextarea"><h5>补注:</h5></label>
+                      <textarea class="form-control" id="exampleTextarea" rows="8"></textarea>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <!--弹出添加-->
+    <div class="modal fade" id="add" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                  <h5 class="modal-title">添加定额</h5>
+                  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                  </button>
+                </div>
+                <div class="modal-body">
+                  <form>
+                    <div class="form-group">
+                      <label>编码</label>
+                      <input class="form-control" placeholder="输入编码" type="text">
+                    </div>
+                    <div class="form-group">
+                      <label>名称</label>
+                      <input class="form-control" placeholder="输入名称" type="text">
+                    </div>
+                    <div class="form-group">
+                      <label>单位</label>
+                      <select class="form-control"><option>选择单位</option><option>m3</option></select>
+                    </div>
+                    <div class="form-group">
+                      <label>基价</label>
+                      <input class="form-control" placeholder="输入基价" type="number">
+                    </div>
+                    <div class="form-group">
+                      <label>显示名称(以%s表示参数)</label>
+                      <input class="form-control" placeholder="输入显示名称" type="text">
+                    </div>
+                    <div class="form-group">
+                      <label>默认取费专业</label>
+                      <input class="form-control" placeholder="输入取费专业" type="text">
+                    </div>
+                  </form>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <a href="" class="btn btn-primary">添加</a>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!--弹出编辑-->
+    <div class="modal fade" id="edit" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                  <h5 class="modal-title">编辑定额</h5>
+                  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                  </button>
+                </div>
+                <div class="modal-body">
+                  <form>
+                    <div class="form-group">
+                      <label>编码</label>
+                      <input class="form-control" placeholder="输入编码" type="text" value="AA0001">
+                    </div>
+                    <div class="form-group">
+                      <label>名称</label>
+                      <input class="form-control" placeholder="输入名称" type="text" value="人工挖土方">
+                    </div>
+                    <div class="form-group">
+                      <label>单位</label>
+                      <select class="form-control"><option>m3</option></select>
+                    </div>
+                    <div class="form-group">
+                      <label>基价</label>
+                      <input class="form-control" placeholder="输入基价" type="number" value="880.84">
+                    </div>
+                    <div class="form-group">
+                      <label>显示名称(以%s表示参数)</label>
+                      <input class="form-control" placeholder="输入显示名称" type="text" value="人工挖土方">
+                    </div>
+                    <div class="form-group">
+                      <label>默认取费专业</label>
+                      <input class="form-control" placeholder="输入取费专业" type="text" value="1">
+                    </div>
+                  </form>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <a href="" class="btn btn-primary">确定</a>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <!--弹出删除-->
+    <div class="modal fade" id="del" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                  <h5 class="modal-title">删除确认</h5>
+                  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                  </button>
+                </div>
+                <div class="modal-body">
+                    <h5 class="text-danger">删除后无法恢复,确认是否删除?</h5>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <a href="" class="btn btn-danger">删除</a>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!-- JS. -->
+    <script src="lib/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js"></script>
+    <script src="lib/jquery/jquery.min.js"></script>
+    <script src="lib/tether/tether.min.js"></script>
+    <script src="lib/bootstrap/bootstrap.min.js"></script>
+    <script src="web/billsLib/scripts/global.js"></script>
+    <script src="web/billsLib/scripts/setSheets.js"></script>
+    <script src="web/billsLib/scripts/billsLibAjax.js"></script>
+    <!--idTree-->
+    <script src="public/web/idTree.js"></script>
+    <script src="public/web/tree_sheet_controller.js"></script>
+    <script src="public/web/tree_sheet_helper.js"></script>
+    <script src="web/billsLib/scripts/billsLibSetting.js"></script>
+    <script src="web/billsLib/scripts/billsLibTree.js"></script>
+    <!--<script src="test/tmp_data/data_15690.js"></script>-->
+    <script src="test/tmp_data/bills_grid_setting.js"></script>
+</body>
+<script type="text/javascript">
+    autoFlashHeight();
+    var billsTree = billsLibTree.createBillsTree();
+    var billsLibId = getQueryString("billsLibId");
+    $(document).ready(function(){
+        billsAjax.getStdBillsLibName(billsLibId);
+        billsAjax.getBills(billsLibId);
+        buildJobs();
+        buildItems();
+    });
+    //test
+    //test
+
+    var dbOperation = {
+        insert: function(controller){
+            if(controller.tree.items.length === 0){
+                billsAjax.createBills(billsLibId, -1 , -1);
+                controller.insert();
+            }
+            else {
+                var node = controller.tree.selected;
+                if(node){
+                    var updateId = tagId, createpid = node.getParentID(), createnid = node.getNextSiblingID();
+                    controller.insert();
+                    billsAjax.createBills(billsLibId, createpid, createnid);
+                    billsAjax.updatePNId(updateId, -1, node.getNextSiblingID());
+                }
+                else {
+                    var updateNode = controller.tree.roots[controller.tree.roots.length - 1];
+                    var updateId = updateNode.getID();
+                    controller.insert();
+                    billsAjax.createBills(billsLibId, -1, -1);
+                    billsAjax.updatePNId(updateId, -1, updateNode.getNextSiblingID());
+                }
+            }
+        },
+
+        delete: function(controller){
+            var node = controller.tree.selected;
+            var deleteIds = [];
+            var getDeleteIds = function(node){
+                if(node){
+                    deleteIds.push(node.getID());
+                    if(node.children.length > 0){
+                        for(var i=0; i<node.children.length; i++){
+                            getDeleteIds(node.children[i]);
+                        }
+                    }
+                }
+            };
+            getDeleteIds(node);
+            billsAjax.deleteBills(deleteIds);
+            controller.delete;
+        },
+
+        upLevel: function(controller){
+            var node = controller.tree.selected;
+            if(node){
+                if(node.parent){
+                    //node
+                    billsAjax.updatePNId(node.getID(), node.parent.getParentID(), node.parent.getNextSiblingID());
+                    //parent
+                    billsAjax.updatePNId(node.getParentID(), null, node.getID());
+                    if(node.nextSibling){
+                        //node.nextSibling
+                        billsAjax.updatePNId(node.getNextSiblingID(), node.getID(), null);
+                    }
+                    if(node.preSibling){
+                        billsAjax.updatePNId(node.preSibling.getID(), null, -1);
+                    }
+                }
+                //controllerOp
+                controller.upLevel();
+            }
+
+        },
+
+        downLevel: function(controller){
+            var node = controller.tree.selected;
+            if(node){
+                if(node.preSibling){
+                    billsAjax.updatePNId(node.preSibling.getID(), null, node.getNextSiblingID());
+                    billsAjax.updatePNId(node.getID(), node.preSibling.getID(), -1);
+                    if(node.preSibling.children.length > 0){
+                        billsAjax.updatePNId(node.preSibling.children[node.preSibling.children.length -1].getID(), null, node.getID());
+                    }
+                    controller.downLevel();
+                }
+            }
+        },
+
+        upMove: function(controller){
+            var node = controller.tree.selected;
+            if(node){
+                if(node.preSibling){
+                    billsAjax.updatePNId(node.preSibling.getID(), null, node.getNextSiblingID());
+                    billsAjax.updatePNId(node.getID(), null, node.preSibling.getID());
+                    if(node.preSibling.preSibling){
+                        billsAjax.updatePNId(node.preSibling.preSibling.getID(), null, node.getID());
+                    }
+                    controller.upMove();
+                }
+            }
+        },
+
+        downMove: function(controller){
+            var node = controller.tree.selected;
+            if(node){
+                if(node.nextSibling){
+                    billsAjax.updatePNId(node.getNextSiblingID(), null, node.getID());
+                    billsAjax.updatePNId(node.getID(), null, node.nextSibling.getNextSiblingID());
+                    if(node.preSibling){
+                        billsAjax.updatePNId(node.preSibling.getID(), null, node.getNextSiblingID());
+                    }
+                    controller.downMove();
+                }
+            }
+        }
+    }
+
+    function nodeOpration(controller,sheet){
+        $('#insert').click(function(){
+            //dbOperation.insert(controller, sheet);
+            controller.insert();
+        });
+        $('#delete').click(function(){
+            controller.delete();
+        });
+        $('#upLevel').click(function(){
+            controller.upLevel();
+        });
+        $('#downLevl').click(function(){
+            controller.downLevel();
+        });
+        $('#upMove').click(function(){
+            controller.upMove();
+        });
+        $('#downMove').click(function(){
+            controller.downMove();
+        });
+    }
+
+    function showBillsSheet(datas){
+        var billsSpread = new GC.Spread.Sheets.Workbook($('#spreadBills')[0], {sheetCount: 1});
+        initSheet(billsSpread);
+        billsTree.loadDatas(datas);
+        var controller = TREE_SHEET_CONTROLLER.createNew(billsTree.tree, billsSpread.getActiveSheet(), billsLibSetting);
+        controller.showTreeData();
+        nodeOpration(controller, billsSpread.getActiveSheet());
+    }
+
+
+    function buildBills(){
+        var spread = new GC.Spread.Sheets.Workbook($("#spreadBills")[0], {sheetCount: 1});
+        var sheet = spread.getSheet(0);
+        var chRowCount = 2;
+        var vpColCount = 4;
+        var vpRowCount = 27;
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        initSheet(spread, sheet, chRowCount, vpRowCount, vpColCount );//初始表单设置
+        setupBillsColHeader(sheet);
+        setupEvents(spread, sheet);//事件
+        initRowHeight(sheet);//设置行高
+        setCell(sheet);//设置文本居中
+        myCommand(spread, sheet);
+        setScrollBar(spread, sheet, vpRowCount);
+        sheet.resumePaint();
+        sheet.resumeEvent();
+
+    }
+
+    function setupBillsColHeader(sheet){
+        var ch = GC.Spread.Sheets.SheetArea.colHeader;
+        sheet.addSpan(0, 0, 2, 1, ch);
+        sheet.setValue(0, 0, "编码", ch);
+        sheet.setColumnWidth(0, 160);
+
+        sheet.addSpan(0, 1, 2, 1, ch);
+        sheet.setValue(0, 1, "名称", ch);
+        sheet.setColumnWidth(1, 300);
+
+        sheet.addSpan(0, 2, 2, 1, ch);
+        sheet.setValue(0, 2, "计量单位", ch);
+        sheet.setColumnWidth(2, 160);
+
+        sheet.addSpan(0, 3, 2, 1, ch);
+        sheet.setValue(0, 3, "工程量计算规则", ch);
+        sheet.setColumnWidth(3, 420);
+    }
+    //设置滚动条
+    /*function setScrollBar(spread, sheet){
+        var rowCount = sheet.getR
+    }*/
+    //
+    function buildJobs(){
+        var spread = new GC.Spread.Sheets.Workbook($("#spreadJobs")[0], {sheetCount: 1});
+        var sheet = spread.getSheet(0);
+        var chRowCount = 2;
+        var vpRowCount = 8;
+        var vpColCount = 2;
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        initSheet(spread);
+        setupJobsColHeader(sheet);
+        //initRowHeight(sheet);
+        setCell(sheet);
+        myCommand(spread, sheet);
+        setScrollBar(spread, sheet, vpRowCount);
+        sheet.resumePaint();
+        sheet.resumeEvent();
+    }
+    function setupJobsColHeader(sheet){
+        var ch = GC.Spread.Sheets.SheetArea.colHeader;
+        sheet.addSpan(0, 0, 2, 1, ch);
+        sheet.setValue(0, 0, "编号", ch);
+        sheet.setColumnWidth(0, 100);
+        sheet.addSpan(0, 1, 2, 1, ch);
+        sheet.setValue(0, 1, "工作内容", ch);
+        sheet.setColumnWidth(1, 215);
+    }
+    //
+    function buildItems(){
+        var spread = new GC.Spread.Sheets.Workbook($("#spreadItems")[0], {sheetCount: 1});
+        var sheet = spread.getSheet(0);
+        var chRowCount = 2;
+        var vpRowCount = 8;
+        var vpColCount = 2;
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        initSheet(spread, sheet, chRowCount, vpRowCount, vpColCount);
+        setupItemsColHeader(sheet);
+        //initRowHeight(sheet);
+        setCell(sheet);
+        myCommand(spread, sheet);
+        setScrollBar(spread, sheet, vpRowCount);
+        sheet.resumePaint();
+        sheet.resumeEvent();
+    }
+    function setupItemsColHeader(sheet){
+        var ch = GC.Spread.Sheets.SheetArea.colHeader;
+        sheet.addSpan(0, 0, 2, 1, ch);
+        sheet.setValue(0, 0, "编号", ch);
+        sheet.setColumnWidth(0, 100);
+
+        sheet.addSpan(0, 1, 2, 1, ch);
+        sheet.setValue(0, 1, "项目特征", ch);
+        sheet.setColumnWidth(1, 215);
+    }
+
+    function getQueryString(name)
+    {
+        var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
+        var r = window.location.search.substr(1).match(reg);
+        if(r!=null)return  unescape(r[2]); return null;
+    }
+
+</script>
+
+</html>

+ 19 - 0
web/billsLib/html/test.html

@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>test</title>
+    <script src="../../../lib/jquery/jquery.min.js"></script>
+</head>
+<body>
+    <div id="di">ss</div>
+</body>
+<script>
+    $(document).ready(function(){
+       var test = {a: 1}
+        if(!test.b){
+            alert(1);
+        }
+    });
+</script>
+</html>

+ 240 - 0
web/billsLib/html/tezheng.html

@@ -0,0 +1,240 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta http-equiv="x-ua-compatible" content="ie=edge">
+    <title>清单规则编辑器</title>
+    <link rel="stylesheet" href="../../css/bootstrap/bootstrap.min.css">
+    <!--<link rel="stylesheet" href="../../web/css/bootstrap/themes.css">-->
+    <link rel="stylesheet" href="../../css/main.css">
+    <link rel="stylesheet" href="../../css/font-awesome/font-awesome.min.css">
+    <!--spread-->
+    <link rel="stylesheet" href="../../../web/css/spreadjs/gc.spread.sheets.excel2013white.10.0.1.css">
+    <!--zTree-->
+    <link rel="stylesheet" href="../../css/ztree/zTreeStyle.css" type="text/css">
+</head>
+
+<body>
+    <div class="header">
+        <nav class="navbar navbar-toggleable-lg navbar-light bg-faded p-0 ">
+            <span class="header-logo px-2">清单规则编辑器</span>
+            <div class="navbar-text"><a href="main.html">清单规则</a><i class="fa fa-angle-right fa-fw"></i>XXX清单规则</div>
+        </nav>
+        <nav class="navbar navbar-toggleable-lg justify-content-between navbar-light p-0">
+
+              <ul class="nav nav-tabs" role="tablist">
+                  <li class="nav-item">
+                      <a class="nav-link px-3" href="qingdan.html">清单</a>
+                  </li>
+                  <li class="nav-item">
+                      <a class="nav-link px-3" href="neirong.html">工作内容</a>
+                  </li>
+                  <li class="nav-item">
+                      <a class="nav-link active px-3" href="tezheng.html">项目特征</a>
+                  </li>
+              </ul>
+        </nav>
+    </div>
+    <div class="main">
+      <div class="content">
+        <div class="container-fluid">
+          <div class="row">
+            <div class="main-content col-lg-7 p-0">
+              <nav class="tools-bar"></nav>
+              <div class="main-data" id="spreadAllItems">
+            </div>
+            </div>
+            <div class="main-side col-lg-5 p-0">
+              <div class="main-data" id="spreadEigenvalue">
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <!--弹出添加-->
+    <div class="modal fade" id="add" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                  <h5 class="modal-title">添加定额</h5>
+                  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                  </button>
+                </div>
+                <div class="modal-body">
+                  <form>
+                    <div class="form-group">
+                      <label>编码</label>
+                      <input class="form-control" placeholder="输入编码" type="text">
+                    </div>
+                    <div class="form-group">
+                      <label>名称</label>
+                      <input class="form-control" placeholder="输入名称" type="text">
+                    </div>
+                    <div class="form-group">
+                      <label>单位</label>
+                      <select class="form-control"><option>选择单位</option><option>m3</option></select>
+                    </div>
+                    <div class="form-group">
+                      <label>基价</label>
+                      <input class="form-control" placeholder="输入基价" type="number">
+                    </div>
+                    <div class="form-group">
+                      <label>显示名称(以%s表示参数)</label>
+                      <input class="form-control" placeholder="输入显示名称" type="text">
+                    </div>
+                    <div class="form-group">
+                      <label>默认取费专业</label>
+                      <input class="form-control" placeholder="输入取费专业" type="text">
+                    </div>
+                  </form>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <a href="" class="btn btn-primary">添加</a>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!--弹出编辑-->
+    <div class="modal fade" id="edit" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                  <h5 class="modal-title">编辑定额</h5>
+                  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                  </button>
+                </div>
+                <div class="modal-body">
+                  <form>
+                    <div class="form-group">
+                      <label>编码</label>
+                      <input class="form-control" placeholder="输入编码" type="text" value="AA0001">
+                    </div>
+                    <div class="form-group">
+                      <label>名称</label>
+                      <input class="form-control" placeholder="输入名称" type="text" value="人工挖土方">
+                    </div>
+                    <div class="form-group">
+                      <label>单位</label>
+                      <select class="form-control"><option>m3</option></select>
+                    </div>
+                    <div class="form-group">
+                      <label>基价</label>
+                      <input class="form-control" placeholder="输入基价" type="number" value="880.84">
+                    </div>
+                    <div class="form-group">
+                      <label>显示名称(以%s表示参数)</label>
+                      <input class="form-control" placeholder="输入显示名称" type="text" value="人工挖土方">
+                    </div>
+                    <div class="form-group">
+                      <label>默认取费专业</label>
+                      <input class="form-control" placeholder="输入取费专业" type="text" value="1">
+                    </div>
+                  </form>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <a href="" class="btn btn-primary">确定</a>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <!--弹出删除-->
+    <div class="modal fade" id="del" data-backdrop="static" style="display: none;" aria-hidden="true">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                  <h5 class="modal-title">删除确认</h5>
+                  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                  </button>
+                </div>
+                <div class="modal-body">
+                    <h5 class="text-danger">删除后无法恢复,确认是否删除?</h5>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                    <a href="" class="btn btn-danger">删除</a>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!-- JS. -->
+    <script src="../../../lib/spreadjs/gc.spread.sheets.all.10.0.1.min.js"></script>
+    <script src="../../../lib/jquery/jquery.min.js"></script>
+    <script src="../../../lib/tether/tether.min.js"></script>
+    <script src="../../../lib/bootstrap/bootstrap.min.js"></script>
+    <script src="..//scripts/global.js"></script>
+    <script src="..//scripts/setSheets.js"></script>
+    <SCRIPT type="text/javascript">
+  		$(document).ready(function(){
+            buildAllItems();
+            buildEigenvalue();
+  		});
+        function buildAllItems(){
+            var spread = new GC.Spread.Sheets.Workbook($("#spreadAllItems")[0], {sheetCount: 1});
+            var sheet = spread.getSheet(0);
+            var chRowCount = 2;
+            var vpColCount = 2;
+            var vpRowCount = 28;
+            sheet.suspendPaint();
+            sheet.suspendEvent();
+            initSheet(spread, sheet, chRowCount, vpRowCount, vpColCount);
+            setupItemsColHeader(sheet);
+            //initRowHeight(sheet);
+            setCell(sheet);
+            myCommand(spread, sheet);
+            setScrollBar(spread, sheet, vpRowCount);
+            sheet.resumePaint();
+            sheet.resumeEvent();
+        }
+        function setupItemsColHeader(sheet){
+            var ch = GC.Spread.Sheets.SheetArea.colHeader;
+            sheet.addSpan(0 ,0, 2, 1, ch);
+            sheet.setValue(0, 0, "编号", ch);
+            sheet.setColumnWidth(0, 200);
+            sheet.addSpan(0 ,1, 2, 1, ch);
+            sheet.setValue(0, 1, "项目特征", ch);
+            sheet.setColumnWidth(1, 850);
+        }
+
+        function buildEigenvalue(){
+            var spread = new GC.Spread.Sheets.Workbook($("#spreadEigenvalue")[0], {sheetCount: 1});
+            var sheet = spread.getSheet(0);
+            var chRowCount = 2;
+            var vpColCount = 2;
+            var vpRowCount = 6;
+            sheet.suspendPaint();
+            sheet.suspendEvent();
+            initSheet(spread, sheet, chRowCount, vpRowCount, vpColCount);
+            setupValueColHeader(sheet);
+            //initRowHeight(sheet);
+            setCell(sheet);
+            myCommand(spread, sheet);
+            setScrollBar(spread, sheet, vpRowCount);
+            sheet.resumePaint();
+            sheet.resumeEvent();
+        }
+        function setupValueColHeader(sheet){
+            var ch = GC.Spread.Sheets.SheetArea.colHeader;
+            sheet.addSpan(0 ,0, 2, 1, ch);
+            sheet.setValue(0, 0, "编号", ch);
+            sheet.setColumnWidth(0, 200);
+            sheet.addSpan(0 ,1, 2, 1, ch);
+            sheet.setValue(0, 1, "特征值", ch);
+            sheet.setColumnWidth(1, 550);
+        }
+
+  	</SCRIPT>
+</body>
+<script type="text/javascript">
+    autoFlashHeight();
+</script>
+
+</html>

+ 147 - 0
web/billsLib/scripts/billsLibAjax.js

@@ -0,0 +1,147 @@
+/**
+ * Created by vian on 2017/3/27.
+ */
+var mainAjax = {
+    getStdBillsLib: function(userId){
+        $.ajax({
+            type: "post",
+            url: "/stdBillsEditor/getStdBillsLib",
+            data: {data: JSON.stringify({userId: userId})},
+            dataType: "json",
+            success: function(result){
+                if(result.data){
+                    for(var i=0; i<result.data.length; i++){
+                        var id = result.data[i].billsLibId;
+                        var billsLibName = result.data[i].billsLibName;
+                        var createDate = result.data[i].createDate;
+                        var createDateFmt = new Date(createDate).format("yyyy-MM-dd");
+                        $("#showArea").append(
+                            "<tr id='tempId'>" +
+                            "<td><a href='stdBills'>"+billsLibName+"</a></td>" +
+                            "<td>"+createDateFmt+" </td>" +
+                            "<td><a href='javascript:void(0);' data-toggle='modal' data-target='#edit' title='编辑'>" +
+                            "<i class='fa fa-pencil-square-o'></i></a> <a href='javascript:void(0);' data-toggle='modal' data-target='#del' class='text-danger' title='删除'>" +
+                            "<i class='fa fa-remove'></i></a></td></tr>");
+                        var newHref = "stdBills?billsLibId="+id;
+                        $("#tempId td:first a").attr("href", newHref);
+                        $("#tempId").attr("id", id);
+                    }
+                }
+
+            }
+        });
+    },
+    createStdBillsLib: function(billsLibName){
+        $.ajax({
+            type: "POST",
+            url: "/stdBillsEditor/createStdBillsLib",
+            data: {data: JSON.stringify({name: billsLibName}) },
+            dataType: "json",
+            success: function(result){
+                if(!result.error){
+                    var id = result.data[0].billsLibId;
+                    var createDate = result.data[0].createDate;
+                    var createDateFmt = new Date(createDate).format("yyyy-MM-dd");
+                    $("#showArea").append(
+                        "<tr id='tempId'><td><a href='stdBills'>"+billsLibName+"</a></td><td>"+createDateFmt+" </td><td><a href='javascript:void(0);' data-toggle='modal' data-target='#edit' title='编辑'>" +
+                        "<i class='fa fa-pencil-square-o'></i></a> <a href='javascript:void(0);' data-toggle='modal' data-target='#del' class='text-danger' title='删除'>" +
+                        "<i class='fa fa-remove'></i></a></td></tr>"
+                    );
+                    var newHref = "stdBills?billsLibId="+id;
+                    $("#tempId td:first a").attr("href", newHref);
+                    $("#tempId").attr("id", id);
+                }
+            }
+        });
+    },
+    deleteStdBillsLib: function(billsLibId){
+        $.ajax({
+            type: "POST",
+            url: "/stdBillsEditor/deleteStdBillsLib",
+            data: {data: JSON.stringify({billsLibId: billsLibId})},
+            dataType: "json",
+            success: function(result){
+                if(!result.error){
+                    var jqSel = "#"+billsLibId;
+                    $(jqSel).remove();
+                }
+            }
+        });
+    },
+    renameStdBillsLib: function(billsLibId, newName){
+        $.ajax({
+            type: "post",
+            url: "/stdBillsEditor/renameStdbillsLib",
+            data: {data: JSON.stringify({id: billsLibId, value: newName})},
+            dataType: "json",
+            success: function(result){
+                if(!result.error){
+                    var jqSel = "#" + billsLibId + " td:first" + " a";
+                    $(jqSel).text(newName);
+                }
+            }
+        });
+    }
+}
+
+var billsAjax = {
+    getStdBillsLibName: function(billsLibId) {
+        $.ajax({
+            type: "post",
+            url: "/stdBillsEditor/getStdBillsLibName",
+            data: {data: JSON.stringify({billsLibId: billsLibId})},
+            success: function(result){
+                if(!result.error){
+                    $(".navbar-text").append(
+                    "<a href='stdBillsmain'>清单规则</a><i class='fa fa-angle-right fa-fw'></i>"+result.data[0].billsLibName
+                    );
+                }
+            }
+        });
+    },
+    getBills: function(billsLibId){
+        $.ajax({
+            type: "post",
+            url: "/stdBillsEditor/getBills",
+            data: {data: JSON.stringify({billsLibId: billsLibId})},
+            dataType: "json",
+            success: function(result){
+                if(!result.error){
+                    showBillsSheet(result.data);
+                }
+            }
+        });
+    },
+    createBills: function(billsLibId, pid, nid){
+        $.ajax({
+            type: 'post',
+            url: 'stdBillsEditor/createBills',
+            data: {data: JSON.stringify({billsLibId: billsLibId, ParentID: pid, NextSiblingID: nid})},
+            dataType: 'json',
+            success: function(result){
+            }
+        });
+    },
+    updatePNId: function(updateId, pid, nid){
+        $.ajax({
+            type: 'post',
+            url: 'stdBillsEditor/updatePNId',
+            data: {data: JSON.stringify({updateId: updateId, ParentID: pid, NextSiblingID: nid})},
+            dataType: 'json',
+            success: function(result){
+
+            }
+        });
+    },
+    deleteBills: function(deleteIds){
+        $.ajax({
+            type: 'post',
+            url: 'stdBillsEditor/deleteBills',
+            data: {data: JSON.stringify({deleteIds: deleteIds})},
+            dataType: 'json',
+            success: function(result){
+
+            }
+        });
+    }
+}

+ 165 - 0
web/billsLib/scripts/billsLibSetting.js

@@ -0,0 +1,165 @@
+/**
+ * Created by vian on 2017/4/10.
+ */
+var billsLibSetting = {
+    cols:[
+        {
+            head: {
+                titleNames: ['编码'],
+                spanCols: [1],
+                spanRows: [2],
+                vAlign: [1, 1],
+                hAlign: [1, 1],
+                font: '16px Arial'
+            },
+            data: {
+                field: 'code',
+                vAlign: 1,
+                hAlign: 0,
+                font: '14px Arial'
+            },
+            width: 160
+        },
+        {
+            head: {
+                titleNames: ['名称'],
+                spanCols: [1],
+                spanRows: [2],
+                vAlign: [1, 1],
+                hAlign: [1, 1],
+                font: '16px Arial'
+            },
+            data: {
+                field: 'name',
+                vAlign: 1,
+                hAlign: 0,
+                font: '14px Arial'
+            },
+            width: 300
+        },
+        {
+            head: {
+                titleNames: ['计量单位'],
+                spanCols: [1],
+                spanRows: [2],
+                vAlign: [1, 1],
+                hAlign: [1, 1],
+                font: '16px Arial'
+            },
+            data: {
+                field: 'unit',
+                vAlign: 1,
+                hAlign: 0,
+                font: '14px Arial'
+            },
+            width: 160
+        },
+        {
+            head: {
+                titleNames: ['工程量计算规则'],
+                spanCols: [1],
+                spanRows: [2],
+                vAlign: [1, 1],
+                hAlign: [1, 1],
+                font: '16px Arial'
+            },
+            data: {
+                field: 'ruleText',
+                vAlign: 1,
+                hAlign: 0,
+                font: '14px Arial'
+            },
+            width: 420
+        }
+    ],
+    headRows: 2,
+    headRowHeight: [20, 30, 30],
+    emptyRows: 3,
+    treeCol: 0
+};
+
+var jobsSetting = {
+    cols:[
+        {
+            head: {
+                titleNames: ['编号'],
+                spanCols: [1],
+                spanRows: [2],
+                vAlign: [1, 1],
+                hAlign: [1, 1],
+                font: '16px Arial'
+            },
+            data: {
+                field: 'code',
+                vAlign: 1,
+                hAlign: 0,
+                font: '14px Arial'
+            },
+            width: 100
+        },
+        {
+            head: {
+                titleNames: ['工作内容'],
+                spanCols: [1],
+                spanRows: [2],
+                vAlign: [1, 1],
+                hAlign: [1, 1],
+                font: '16px Arial'
+            },
+            data: {
+                field: 'content',
+                vAlign: 1,
+                hAlign: 0,
+                font: '14px Arial'
+            },
+            width: 215
+        },
+    ],
+    headRows: 2,
+    headRowHeight: [20, 30, 30],
+    emptyRows: 3,
+    treeCol: 0
+};
+
+var itemsSetting = {
+    cols:[
+        {
+            head: {
+                titleNames: ['编号'],
+                spanCols: [1],
+                spanRows: [2],
+                vAlign: [1, 1],
+                hAlign: [1, 1],
+                font: '16px Arial'
+            },
+            data: {
+                field: 'code',
+                vAlign: 1,
+                hAlign: 0,
+                font: '14px Arial'
+            },
+            width: 100
+        },
+        {
+            head: {
+                titleNames: ['项目 特征'],
+                spanCols: [1],
+                spanRows: [2],
+                vAlign: [1, 1],
+                hAlign: [1, 1],
+                font: '16px Arial'
+            },
+            data: {
+                field: 'character',
+                vAlign: 1,
+                hAlign: 0,
+                font: '14px Arial'
+            },
+            width: 215
+        },
+    ],
+    headRows: 2,
+    headRowHeight: [20, 30, 30],
+    emptyRows: 3,
+    treeCol: 0
+}

+ 38 - 0
web/billsLib/scripts/billsLibTree.js

@@ -0,0 +1,38 @@
+/**
+ * Created by vian on 2017/4/10.
+ */
+var billsLibTree = {
+    setting: {
+        id: 'ID',
+        pid: 'ParentID',
+        nid: 'NextSiblingID',
+        rootId: -1
+    },
+    virtualRoot: [{
+        ID: 1,
+        ParentID: -1,
+        NextSiblingID: -1,
+        code: '开始编辑',
+    }],
+    createBillsTree: function(){
+        var billsTree = function(){
+            this.datas = null;
+            this.tree = null;
+        };
+
+        billsTree.prototype.loadDatas = function(datas){
+            if(datas){
+                this.datas = datas;
+                this.tree = idTree.createNew(billsLibTree.setting);
+                this.tree.loadDatas(this.datas);
+           }
+           else {
+                this.datas = [];
+                this.tree = idTree.createNew(billsLibTree.setting);
+                this.tree.loadDatas(this.datas);
+            }
+        };
+
+        return new billsTree();
+    }
+}

+ 21 - 0
web/billsLib/scripts/dateFormat.js

@@ -0,0 +1,21 @@
+/**
+ * Created by vian on 2017/3/30.
+ */
+Date.prototype.format = function(fmt)
+{
+    var o = {
+        "M+" : this.getMonth()+1,                 //月份
+        "d+" : this.getDate(),                    //日
+        "h+" : this.getHours(),                   //小时
+        "m+" : this.getMinutes(),                 //分
+        "s+" : this.getSeconds(),                 //秒
+        "q+" : Math.floor((this.getMonth()+3)/3), //季度
+        "S"  : this.getMilliseconds()             //毫秒
+    };
+    if(/(y+)/.test(fmt))
+        fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
+    for(var k in o)
+        if(new RegExp("("+ k +")").test(fmt))
+            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
+    return fmt;
+}

+ 37 - 0
web/billsLib/scripts/global.js

@@ -0,0 +1,37 @@
+/*全局自适应高度*/
+function autoFlashHeight(){
+    var headerHeight = $(".header").height();
+    var toolsBar = $(".tools-bar").height();
+    $(".content").height($(window).height()-headerHeight);
+    $(".main-side").height($(window).height()-headerHeight-2);
+    $(".main-content").height($(window).height()-headerHeight-2);
+    $(".main-data").height($(window).height()-headerHeight-toolsBar-16);
+};
+$(window).resize(autoFlashHeight);
+/*全局自适应高度结束*/
+$(function(){
+/*侧滑*/
+$(".open-sidebar").click(function(){
+    $(".slide-sidebar").animate({width:"800"}).addClass("open");
+});
+$("body").click(function(event){
+        var e = event || window.event; //浏览器兼容性
+        if(!$(event.target).is('a')) {
+            var elem = event.target || e.srcElement;
+            while (elem) { //循环判断至跟节点,防止点击的是div子元素
+                if (elem.className == "open-sidebar" || elem.className == 'slide-sidebar open') {
+                    return false;
+                }
+                elem = elem.parentNode;
+            }
+            $(".slide-sidebar").animate({width:"0"}).removeClass("open")// 关闭处理
+        }
+
+    });
+/*侧滑*/
+/*工具提示*/
+$('*[data-toggle=tooltip]').mouseover(function() {
+ $(this).tooltip('show');
+  });
+/*工具提示*/
+});

+ 91 - 0
web/billsLib/scripts/setSheets.js

@@ -0,0 +1,91 @@
+/**
+ * Created by vian on 2017/3/16.
+ */
+
+function initSheet(spread){
+    var spreadNS = GC.Spread.Sheets, sheet = spread.getActiveSheet();
+    spread.options.showHorizontalScrollbar = false;
+    spread.options.showVerticalScrollbar =false;
+    spread.options.tabStripVisible = false;
+    spread.options.scrollbarMaxAlign = true;
+    sheet.showRowOutline(false);
+    sheet.defaults.rowHeight = 30;
+}
+
+function initHeader(spread, setting){
+    var sheet = spread.getActiveSheet();
+    sheet.setColumnCount(setting.cols.length);
+    sheet.setRowCount();
+}
+
+function setCell(sheet){
+    var colCount = sheet.getColumnCount();
+    var vp = GC.Spread.Sheets.SheetArea.viewport;
+    var center = GC.Spread.Sheets.VerticalAlign.center;
+    var left =  GC.Spread.Sheets.HorizontalAlign.left;
+    for(var i= 0; i<colCount; i++){
+        sheet.getRange(-1, i, -1, 1, vp).vAlign(center);
+        sheet.getRange(-1, i, -1, 1, vp).hAlign(left);
+        sheet.getRange(-1, i, -1, 1, vp).font("12pt ����");
+    }
+}
+
+function setupEvents(spread, sheet){
+    var events = GC.Spread.Sheets.Events;
+    $("#aDelete").click(function(){
+        var rowIdx = sheet.getActiveRowIndex();
+        sheet.deleteRows(rowIdx, 1);
+    });
+
+   sheet.bind(events.EditEnded, function(e, args){
+       var editRow = args.row;
+       var editCol = args.col;
+       var eiditVal = sheet.getValue(editRow, editCol);
+        console.log("EE: row: "+editRow+"  col: "+editCol +"val: "+eiditVal);
+    });
+
+}
+
+function setScrollBar(spread, sheet, initRow){
+    var events = GC.Spread.Sheets.Events;
+    sheet.bind(events.EnterCell, function(e, data){
+        var rowCount = sheet.getRowCount();
+        //��ǰ�������ڳ�ʼ����
+        if(rowCount >initRow){
+            spread.options.showVerticalScrollbar = true;
+        }
+        else{
+            spread.options.showVerticalScrollbar = false;
+        }
+    });
+}
+
+
+function myCommand(spread, sheet){
+    var keys = GC.Spread.Commands.Key;
+    //enter,���һ�лس����������
+    spread.commandManager().register("myEnter", function(){
+        var idxRow = sheet.getActiveRowIndex();
+        var rowCount = sheet.getRowCount();
+        if(idxRow+1 == rowCount){
+            sheet.addRows(rowCount, 1);
+            sheet.setRowHeight(rowCount, 30);//�����и�
+            sheet.getRange(rowCount, -1, 1, -1).vAlign(GC.Spread.Sheets.VerticalAlign.center);
+            sheet.getRange(rowCount, -1, 1, -1).font("10pt ΢���ź�");
+        }
+    });
+    spread.commandManager().setShortcutKey("myEnter", keys.enter, false, false, false, false);
+    spread.commandManager().register("myDown", function(){
+        var idxRow = sheet.getActiveRowIndex();
+        var rowCount = sheet.getRowCount();
+        if(idxRow+1 == rowCount){
+            sheet.suspendPaint();
+            sheet.addRows(rowCount, 1);
+            sheet.setRowHeight(rowCount, 30);//�����и�
+            sheet.getRange(rowCount, -1, 1, -1).vAlign(GC.Spread.Sheets.VerticalAlign.center);
+            sheet.getRange(rowCount, -1, 1, -1).font("10pt ΢���ź�");
+            sheet.resumePaint();
+        }
+    });
+    spread.commandManager().setShortcutKey("myDown", keys.down, false, false, false, false);
+}