ソースを参照

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

Chenshilong 8 年 前
コミット
ebf189ad39

+ 155 - 0
modules/bills/controllers/billsControllers.js

@@ -0,0 +1,155 @@
+/**
+ * Created by vian on 2017/3/22.
+ */
+
+var billsDao = require("../model/interfaces");
+//----
+var model = require("../model/billsModel");
+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 = {};
+        data.name = req.body.name;
+        data.createDate = req.body.createDate;
+        var billsLibId = 1;
+        var billsLibName = data.name;
+        //to do 以服务器时间为准 new Date();
+        var createDate = data.createDate;
+        var newStdBillsLib = new StdBillsLib({billsLibId: billsLibId, billsLibName: billsLibName, createDate: createDate});
+        newStdBillsLib.save(function(err){
+            if(err){
+                res.json({message: "Error"});
+            }
+            else{
+                res.json({success: true, message: "Success"});
+            }
+        });
+        /*  billsDao.createStdBillsLib(data, function(err, message){
+         //callback(req, res, err, message, null);
+
+         });*/
+        //--------
+        /*    var newStdBillsLib = {
+         billsLibId: billsLibId,
+         billsLibName: billsLibName,
+         createDate: createDate
+         }
+         StdBillsLib.create(newStdBillsLib, function(err){
+         if(err){
+         res.json({message: "Error", data: null});
+         }
+         else {
+         res.json({message: "", data: null});
+         }
+         });*/
+        //--------
+    },
+    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);
+        });
+    },
+    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);
+        });
+    },
+    updateNextSiblingId: function (req, res) {
+        var data = JSON.parse(req.body.data);
+        billsDao.updateNextSiblingId(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);
+        });
+    }
+
+}
+

+ 18 - 0
modules/bills/model/billsModel.js

@@ -0,0 +1,18 @@
+/**
+ * Created by vian on 2017/3/17.
+ */
+var dbm = require("../../../config/db/db_manager");
+var schemas = require("./schemas.js");
+//var db = dbm.getLocalConnection("stdBillsLibData");
+var db = dbm.getCfgConnection("stdBillsEditor");
+var stdBillsLibMod = db.model("stdBillsLib", schemas.stdBillsLibSchema);
+var billsMod = db.model("bills", 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,
+}

+ 367 - 0
modules/bills/model/interfaces.js

@@ -0,0 +1,367 @@
+/**
+ * Created by vian on 2017/3/20.
+ */
+var model = require("./billsModel");
+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 billsLibId = 1;
+        var billsLibName = clibData.name;
+        var createDate = clibData.createDate;
+        var newStdBillsLib = {
+            billsLibId: billsLibId,
+            billsLibName: billsLibName,
+            createDate: createDate
+        }
+        StdBillsLib.create(newStdBillsLib, function(err){
+            if(err){
+                callback(1, "Error");
+            }
+            else {
+                callback(0, "");
+            }
+        });
+    //});
+}
+
+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.data;
+    StdBillsLib.update({billsLibId: billsLibId}, {$set:{billsLibName: renameVal}}, function(err){
+        if(err){
+            callback(1, "Error");
+        }
+        else{
+            callback(0, "");
+        }
+    });
+}
+
+//----------------------------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){
+    var field = cbillsData.field;
+    var data = cbillsData.data;
+    var newId = cbillsData.id;//ǰ��ͨ�� counter.getIDAfterCount("bills", 1);���
+    var billsLibId = cbillsData.billsLibId;
+    var newBills;
+    if(field == "code"){
+        newBills = {
+            ID: newId,
+            ParentID: cbillsData.parentId,
+            NextSiblingID: cbillsData.nextSiblingId,
+            billsLibId: billsLibId,
+            code: data
+        }
+    }
+    else if(field == "name"){
+        newBills = {
+            ID: newId,
+            ParentID: cbillsData.parentId,
+            NextSiblingID: cbillsData.nextSiblingId,
+            billsLibId: billsLibId,
+            name: data
+        }
+    }
+    else if(field == "unit"){
+        newBills = {
+            ID: newId,
+            ParentID: cbillsData.parentId,
+            NextSiblingID: cbillsData.nextSiblingId,
+            billsLibId: billsLibId,
+            unit: data
+        }
+    }
+    else if(field == "ruleText"){
+        newBills = {
+            ID: newId,
+            ParentID: cbillsData.parentId,
+            NextSiblingID: cbillsData.nextSiblingId,
+            billsLibId: billsLibId,
+            ruleText: data
+        }
+    }
+    Bills.create(newBills, function(err){
+        if(err){
+            callback(1, "Error");
+        }
+        else{
+            callback(0, "");
+        }
+    });
+
+}
+//������ɾ������¸ı��˵�nextSiblingId
+billsDao.prototype.updateNextSiblingId = function(uNextData, callback){
+    var updateId = uNextData.id;
+    var updateData = uNextData.data;
+    Bills.update({ID: updateId}, {$set: {NextSiblingID: updateData}}, 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("bills", 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("bills", 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();

+ 50 - 0
modules/bills/model/schemas.js

@@ -0,0 +1,50 @@
+var mongoose = require('mongoose');
+//헌데방橙淃커蝎
+var stdBillsLibSchema =mongoose.Schema({
+    billsLibId: Number,
+    billsLibName: String,
+    createDate: Date
+});
+//헌데
+var billsSchema = mongoose.Schema({
+    //serialNo: Number,
+    ID: Number,
+    ParentID: Number,
+    NextSiblingID: Number,
+    code: String,
+    name: String,
+    unit: String,
+    ruleText: String,
+    Expression: String,
+    jobs: Array,//헌데묏鱗코휭
+    items: Array,//헌데淃커景瀝
+    recharge:String,//헌데껸鬧
+    billsLibId: Number//杰橄淃커蝎
+});
+//묏鱗코휭
+var jobContentSchema = mongoose.Schema({
+    id: Number,
+    code: String,
+    content: String,
+    billsLibId: Number//杰橄淃커蝎
+});
+//淃커景瀝
+var itemCharacterSchema = mongoose.Schema({
+    id: Number,
+    code: String,
+    character: String,
+    itemValue: Array,
+    billsLibId: Number//杰橄淃커蝎
+});
+/*//景瀝令
+var eigenvalueSchema = mongoose.Schema({
+    eigenvalId: Number,
+    eigenvalContent: String
+});*/
+
+module.exports = {
+    stdBillsLibSchema: stdBillsLibSchema,
+    billsSchema: billsSchema,
+    jobContentSchema: jobContentSchema,
+    itemCharacterSchema: itemCharacterSchema
+}

+ 49 - 0
modules/bills/routes/billsRoutes.js

@@ -0,0 +1,49 @@
+/**
+ * Created by vian on 2017/3/17.
+ */
+var express = require("express");
+var billsController = require("../controllers/billsControllers");
+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("bills/html/main.html");
+});
+
+billsRouter.get("/bills", function(req, res){
+    res.render("bills/html/qingdan.html");
+});
+
+billsRouter.get("/jobs", function(req, res){
+    res.render("bills/html/neirong.html");
+});
+
+billsRouter.get("/items", function(req, res){
+    res.render("bills/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("/getBills", billsController.getBills);
+billsRouter.post("/createBills", billsController.createBills);
+billsRouter.post("/updateNextSiblingId", billsController.updateNextSiblingId);
+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;

+ 23 - 0
server.js

@@ -85,6 +85,29 @@ app.use(express.static(_rootDir+"/lib"));
 var rations_Router = require("./modules/rationLibEditor/routes/rationLibEditor_route");
 app.use("/rationLibEditor",rations_Router);
 //-----------------------------------------------------------------end
+//----------------
+
+//app.get("/stdBillsEditor/main", function(req, res){
+//    res.render("bills/html/main.html");
+//});
+app.get("/stdBillsmain", function(req, res){
+    res.render("bills/html/main.html");
+});
+
+//app.get("/stdBillsEditor/bills", function(req, res){
+//    res.render("bills/html/qingdan.html");
+//});
+//
+//app.get("/stdBillsEditor/jobs", function(req, res){
+//    res.render("bills/html/neirong.html");
+//});
+//
+//app.get("/stdBillsEditor/items", function(req, res){
+//    res.render("bills/html/tezheng.html");
+//});
+var billsRouter = require("./modules/bills/routes/billsRoutes");
+app.use("/stdBillsEditor", billsRouter);
+//-----------------
 
 app.use(function(req, res, next) {
 	res.status(404).send('404 Error');

+ 150 - 0
web/bills/html/main.html

@@ -0,0 +1,150 @@
+<!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="javacript: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="cBillsLib" 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" 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="XXX库">
+                    </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/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>
+    <!-- zTree -->
+    <script type="text/javascript" src="lib/ztree/jquery.ztree.core.js"></script>
+    <script type="text/javascript" src="lib/ztree/jquery.ztree.excheck.js"></script>
+    <script src="/web/bills/scripts/billsAjax.js"></script>
+
+</body>
+<script type="text/javascript">
+    autoFlashHeight();
+</script>
+<script>
+    $(document).ready(function(){
+        $("#createA").click(function(){
+            var billsLibName = $("#cBillsLib").val();
+            if(billsLibName){
+                mainAjax.createStdBillsLib(billsLibName);
+            }
+            else{
+                alert("请输入清单规则名称!");
+            }
+        });
+    });
+</script>
+
+</html>

+ 211 - 0
web/bills/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="../../../web/bills/scripts/global.js"></script>
+    <script src="../../../web/bills/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>

+ 364 - 0
web/bills/html/qingdan.html

@@ -0,0 +1,364 @@
+<!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="../../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 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" href="#"><i class="fa fa-share" aria-hidden="true"></i>插入</a>
+                          </li>
+                          <li class="nav-item">
+                              <a class="nav-link text-primary" id ="aDelete" 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" href="#"><i class="fa fa-arrow-left" aria-hidden="true"></i>升级</a>
+                          </li>
+                          <li class="nav-item">
+                              <a class="nav-link text-primary" href="#"><i class="fa fa-arrow-right" aria-hidden="true"></i>降级</a>
+                          </li>
+                          <li class="nav-item">
+                              <a class="nav-link disabled" href="#"><i class="fa fa-arrow-up" aria-hidden="true"></i>上移</a>
+                          </li>
+                          <li class="nav-item">
+                              <a class="nav-link disabled" href="#"><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/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>
+</body>
+<script type="text/javascript">
+    autoFlashHeight();
+    $(document).ready(function(){
+        buildBills();
+        buildJobs();
+        buildItems();
+        testSortA();
+        testSortB();
+    });
+    //test
+    function testSortA(){
+        var arr = [5,1,2,8,0,10];
+        arr.sort(function(a1, a2){
+            if(a1>a2){
+                return 1;
+            }
+            else{
+                return -1;
+            }
+        });
+        console.log(arr);
+    }
+
+    function testSortB(){
+        var testDataArr = [
+            {ID: "1", NextSiblingID: "3", ParentID: "-1"},
+            {ID: "2", NextSiblingID: "6", ParentID: "-1"},
+            {ID: "3", NextSiblingID: "2", ParentID: "-1"},
+            {ID: "6", NextSiblingID: "4", ParentID: "-1"},
+            {ID: "4", NextSiblingID: "-1", ParentID: "-1"}
+        ];
+
+        testDataArr.sort(function(a, b){
+            if(a.NextSiblingID == b.ID){
+                return -1;
+            }
+            else{
+                return 1;
+            }
+        });
+        //expect: 1 3 2 6 4
+        //fact:   2 6 4 1 3
+        console.log(testDataArr);
+    }
+
+    //test
+
+    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, sheet, chRowCount, vpRowCount, vpColCount);
+        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);
+    }
+
+</script>
+
+</html>

+ 64 - 0
web/bills/html/testCanvas.html

@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+<head lang="en">
+    <meta charset="UTF-8">
+    <title>Canvas Demo</title>
+    <script src="../../../lib/jquery/jquery.min.js"></script>
+    <script>
+        var test = "test";
+        function setId(){
+            return "testSetId";
+        }
+    </script>
+</head>
+<body>
+<canvas id="cv"></canvas>
+<input type="hidden" id="">
+<div id="di">sss</div>
+</body>
+<script>
+window.onload = function(){
+    var canvas = document.getElementById("cv");
+    var ctx = canvas.getContext("2d");
+    //ctx.setLineDash([1,1]);
+    ctx.beginPath();
+    ctx.moveTo(100, 100);
+    //ctx.lineWidth = 0.5;
+    ctx.strokeStyle = "gray";
+    ctx.lineTo(100, 120);
+    ctx.lineTo(120, 120);
+    ctx.lineTo(120, 100);
+    ctx.lineTo(100, 100);
+    ctx.stroke();
+    ctx.beginPath();
+    ctx.strokeStyle = "black";
+    ctx.moveTo(105, 110);
+    ctx.lineTo(115, 110);
+    ctx.stroke();
+
+    ctx.beginPath();
+    ctx.moveTo(100, 50);
+    ctx.strokeStyle = "gray";
+    ctx.lineTo(100, 70);
+    ctx.lineTo(120, 70);
+    ctx.lineTo(120, 50);
+    ctx.lineTo(100, 50);
+    ctx.stroke();
+    ctx.beginPath();
+    ctx.strokeStyle = "black";
+    ctx.moveTo(105, 60);
+    ctx.lineTo(115, 60);
+    ctx.moveTo(110, 55);
+    ctx.lineTo(110, 65);
+    ctx.stroke();
+
+   /* $("div").attr("id", function(){
+        var a = 1, b=2;
+        return a+b;
+    });*/
+    //alert($("div").attr("id"));
+$("#di").remove();
+
+}
+</script>
+</html>

+ 240 - 0
web/bills/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="../../../web/bills/scripts/global.js"></script>
+    <script src="../../../web/bills/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>

+ 59 - 0
web/bills/scripts/billsAjax.js

@@ -0,0 +1,59 @@
+/**
+ * Created by vian on 2017/3/27.
+ */
+var mainAjax = {
+    getStdBillsLib: function(){
+        $.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 billsLibName = result.data[i].billsLibName;
+                        var createDate = result.data[i].createDate;
+                        $("#showArea").append(
+                            "<tr><td><a href='qingdan.html'>"+billsLibName+"</a></td><td>"+createDate+" </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>");
+                    }
+                }
+
+            }
+        });
+    },
+    createStdBillsLib: function(billsLibName){
+        $.ajax({
+            type: "POST",
+            url: "/stdBillsEditor/createStdBillsLib",
+            //data: {"data": JSON.stringify({"name": billsLibName, "createDate": "no!"}) },
+            data: {"name": billsLibName, "createDate": "no!"},
+            dataType: "json",
+            cache: false,
+            timeout: 50000,
+            success: function(result){
+               alert("success!");
+            },
+            error: function(jqXHR, textStatus, errorThrown){
+                alert('error ' + textStatus + " " + errorThrown);
+            }
+
+        });
+    },
+    deleteStdBillsLib: function(billsLibId){
+        $.ajax({
+            type: "POST",
+            url: "/stdBillsEditor/deleteStdBillsLib",
+            data: {"data": JSON.stringify({"billsLibId": billsLibId})},
+            dataType: "json",
+            success: function(result){
+                if(!result.error){
+                    var jqId = "#"+billsLibId;
+                    $(jqId).remove();
+                }
+            }
+        });
+    }
+
+}

+ 3 - 0
web/bills/scripts/buildTreeData.js

@@ -0,0 +1,3 @@
+/**
+ * Created by vian on 2017/3/24.
+ */

+ 37 - 0
web/bills/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');
+  });
+/*工具提示*/
+});

+ 106 - 0
web/bills/scripts/setSheets.js

@@ -0,0 +1,106 @@
+/**
+ * Created by vian on 2017/3/16.
+ */
+//初始表单
+function initSheet(spread, sheet, chRowCount, vpRowCount, vpColCount){
+    var spreadNS = GC.Spread.Sheets;
+    spread.options.showHorizontalScrollbar = false;
+    spread.options.showVerticalScrollbar =false;
+    spread.options.tabStripVisible = false;
+    spread.options.scrollbarMaxAlign = true;
+    sheet.showRowOutline(false);
+    sheet.defaults.rowHeight = 30;
+    sheet.setRowCount(chRowCount, spreadNS.SheetArea.colHeader);
+    sheet.setRowCount(vpRowCount, spreadNS.SheetArea.viewport);
+    sheet.setColumnCount(vpColCount, spreadNS.SheetArea.viewport);
+
+}
+//设置初始行高
+function initRowHeight(sheet){
+    /*var rowCount = sheet.getRowCount();
+    for(var i=0; i<rowCount; i++){
+        sheet.setRowHeight(i, 30);
+    }*/
+}
+
+//单元格设置
+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);
+    });
+    //EditChange
+   /* sheet.bind(events.EditChange, function(e, args){
+        console.log("EditChange!");
+    });*/
+    //EditEnded
+   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);
+    });
+    //EditEnding
+    /*sheet.bind(events.EditEnding, function(e, args){
+        console.log("EEing");
+    });*/
+}
+//滚动条
+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);
+    //down,最后一行down添加新行
+    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);
+}

+ 25 - 0
web/bills/scripts/testTreeData.js

@@ -0,0 +1,25 @@
+/**
+ * Created by vian on 2017/3/27.
+ */
+var billsData = [
+    {ID: "1", ParentID: "-1", NextSiblingID: 2},
+    {ID: "2", ParentID: "-1", NextSiblingID: 3},
+    {ID: "3", ParentID: "-1", NextSiblingID: 9},
+    {ID: "4", ParentID: "3", NextSiblingID: 5},
+    {ID: "5", ParentID: "3", NextSiblingID: -1},
+    {ID: "6", ParentID: "4", NextSiblingID: 7},
+    {ID: "7", ParentID: "4", NextSiblingID: -1},
+    {ID: "8", ParentID: "6", NextSiblingID: -1},
+    {ID: "9", ParentID: "-1", NextSiblingID: 10},
+    {ID: "10", ParentID: "-1", NextSiblingID: -1},
+    {ID: "11", ParentID: "10", NextSiblingID: -1},
+    {ID: "12", ParentID: "11", NextSiblingID: -1},
+    {ID: "13", ParentID: "12", NextSiblingID: -1},
+    {ID: "14", ParentID: "13", NextSiblingID: -1},
+    {ID: "15", ParentID: "14", NextSiblingID: 16},
+    {ID: "16", ParentID: "14", NextSiblingID: 17},
+    {ID: "17", ParentID: "14", NextSiblingID: -1},
+    {ID: "18", ParentID: "17", NextSiblingID: 19},
+    {ID: "19", ParentID: "17", NextSiblingID: -1},
+    {ID: "20", ParentID: "1", NextSiblingID: -1},
+]