Преглед на файлове

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

Conflicts:
	public/web/idTree.js
	web/main/html/main.html
	web/main/js/models/bills.js
	web/main/js/models/project.js
	web/templates/js/bills.js
zhongzewei преди 8 години
родител
ревизия
80de98c785
променени са 67 файла, в които са добавени 1975 реда и са изтрити 702 реда
  1. 6 6
      modules/fees/models/fees_db.js
  2. 47 0
      modules/main/controllers/GLJ_controller.js
  3. 4 15
      modules/main/controllers/bills_controller.js
  4. 22 0
      modules/main/controllers/project_controller.js
  5. 6 17
      modules/main/controllers/rations_controller.js
  6. 85 0
      modules/main/models/GLJ.js
  7. 35 15
      modules/main/models/bills.js
  8. 1 1
      modules/main/models/billsSubSchemas.js
  9. 0 24
      modules/main/models/gljs.js
  10. 56 0
      modules/main/models/project.js
  11. 12 0
      modules/main/models/projectConsts.js
  12. 1 1
      modules/main/models/projectGLJ.js
  13. 15 15
      modules/main/models/rations.js
  14. 12 0
      modules/main/routes/GLJ_route.js
  15. 2 3
      modules/main/routes/bills_route.js
  16. 10 0
      modules/main/routes/project_route.js
  17. 12 0
      modules/main/routes/ration_route.js
  18. 0 13
      modules/main/routes/rations_route.js
  19. 20 0
      modules/pm/controllers/copy_proj_controller.js
  20. 21 0
      modules/pm/controllers/new_proj_controller.js
  21. 28 4
      modules/pm/controllers/pm_controller.js
  22. 74 28
      modules/pm/models/project.js
  23. 10 0
      modules/pm/routes/pm_route.js
  24. 0 15
      modules/rationLib/models/rationRepository.js
  25. 75 0
      modules/rationRepository/controllers/rationChapterTreeController.js
  26. 73 0
      modules/rationRepository/controllers/rationRepositoryController.js
  27. 134 0
      modules/rationRepository/models/rationChapterTree.js
  28. 95 0
      modules/rationRepository/models/repositoryMap.js
  29. 25 0
      modules/rationRepository/routes/rationRepRoutes.js
  30. 1 6
      modules/templates/controllers/bills_template_controller.js
  31. 13 7
      modules/templates/models/bills_template.js
  32. 4 1
      public/counter/counter.js
  33. 133 0
      public/stringUtil.js
  34. 34 0
      public/web/common_ajax.js
  35. 58 15
      public/web/idTree.js
  36. 14 9
      public/web/scMathUtil.js
  37. 2 12
      public/web/tree_sheet_controller.js
  38. 7 9
      public/web/tree_sheet_helper.js
  39. 61 22
      server.js
  40. 6 23
      test/tmp_data/bills_grid_setting.js
  41. 46 0
      test/tmp_data/test_project_1.js
  42. 37 0
      test/unit/public/testBatchInsertDocs.js
  43. 11 0
      test/unit/public/testPinYin.js
  44. 1 1
      test/unit/public/testScMath.js
  45. 2 0
      web/billsLib/scripts/dbController.js
  46. 1 1
      web/fees/feeRate.html
  47. 11 5
      web/fees/feeRate.js
  48. 35 6
      web/main/html/main.html
  49. 1 1
      web/main/js/main_ajax.js
  50. 49 7
      web/main/js/models/bills.js
  51. 49 0
      web/main/js/models/glj.js
  52. 0 27
      web/main/js/models/gljs.js
  53. 9 0
      web/main/js/models/mainConsts.js
  54. 127 3
      web/main/js/models/project.js
  55. 62 0
      web/main/js/models/ration.js
  56. 0 39
      web/main/js/models/rations.js
  57. 1 0
      web/pm/html/project-management.html
  58. 4 6
      web/pm/js/pm_ajax.js
  59. 65 51
      web/pm/js/pm_main.js
  60. 32 22
      web/rationLibEditor/dinge.html
  61. 125 168
      web/rationLibEditor/js/dinge.js
  62. 27 42
      web/rationLibEditor/js/mainJ.js
  63. 2 1
      web/rationLibEditor/main.html
  64. 8 4
      web/scripts/tree_table.js
  65. 2 1
      web/templates/html/bills.html
  66. 30 53
      web/templates/js/bills.js
  67. 24 3
      web/templates/js/tp_bills_setting.js

+ 6 - 6
modules/fees/models/fees_db.js

@@ -38,12 +38,12 @@ FeeRateFile.prototype.rates = function(fileID, controllerFun){
 
 // 1 保存成功; 0 保存失败;-1没有找到对应记录。
 FeeRateFile.prototype.updateRate = function(rateObj, controllerFun){
-    feeRatesModel.find({"ID": rateObj.fileID}, ["rates"], function(err, data){
-        if(data.length){
-            for (var i = 0; i < data[0].rates.length; i++) {
-                if (data[0].rates[i].ID == rateObj.rateID) {
-                    data[0].rates[i].rate = rateObj.rateValue;
-                    data[0].save(function (err) {
+    feeRatesModel.findOne({"ID": rateObj.fileID}, ["rates"], function(err, data){
+        if(data){
+            for (var i = 0; i < data.rates.length; i++) {
+                if (data.rates[i].ID == rateObj.rateID) {
+                    data.rates[i].rate = rateObj.rateValue;
+                    data.save(function (err) {
                         if (err) { controllerFun(0); } else { controllerFun(1); }
                     });
                     break;

+ 47 - 0
modules/main/controllers/GLJ_controller.js

@@ -0,0 +1,47 @@
+/**
+ * Created by jimiz on 2017/4/17.
+ */
+/**
+ * Created by jimiz on 2017/4/7.
+ */
+var GLJData = require('../models/GLJ');
+
+//统一回调函数
+var callback = function(req, res, err, message, data){
+    res.json({error: err, message: message, data: data});
+};
+
+module.exports = {
+    getData: function(req, res){
+        var data = JSON.parse(req.body.data);
+        billsData.getData(data.projectId, function(err, message, billsList){
+            if (err === 0) {
+                callback(req, res, err, message, billsList);
+            } else {
+                callback(req, res, err, message, null);
+            }
+        });
+    },
+
+    getItemTemplate: function(req, res){
+        //var data = JSON.parse(req.body.data);
+        billsData.getItemTemplate(function(err, message, billsItem){
+            if (billsItem) {
+                callback(req, res, err, message, billsItem);
+            } else {
+                callback(req, res, err, message, null);
+            }
+        });
+    },
+
+    allocIDs: function(req, res){
+        billsData.allocIDs(function(err, message, data){
+            if (err) {
+                callback(req, res, err, message, data);
+            } else {
+                callback(req, res, err, message, null);
+            }
+        });
+    }
+
+};

+ 4 - 15
modules/main/controllers/bills_controller.js

@@ -9,9 +9,9 @@ var callback = function(req, res, err, message, data){
 };
 
 module.exports = {
-    getBills: function(req, res){
+    getData: function(req, res){
         var data = JSON.parse(req.body.data);
-        billsData.getBills(data.projectId, function(err, message, billsList){
+        billsData.getData(data.projectId, function(err, message, billsList){
             if (err === 0) {
                 callback(req, res, err, message, billsList);
             } else {
@@ -20,20 +20,9 @@ module.exports = {
         });
     },
 
-    updateBills: function(req, res){
-        var data = JSON.parse(req.body.data);
-        billsData.updateBills(data, function(err, message, errList){
-            if (err) {
-                callback(req, res, err, message, errList);
-            } else {
-                callback(req, res, err, message, null);
-            }
-        });
-    },
-
-    getBillsItemTemplate: function(req, res){
+    getItemTemplate: function(req, res){
         //var data = JSON.parse(req.body.data);
-        billsData.getBillsItemTemplate(function(err, message, billsItem){
+        billsData.getItemTemplate(function(err, message, billsItem){
             if (billsItem) {
                 callback(req, res, err, message, billsItem);
             } else {

+ 22 - 0
modules/main/controllers/project_controller.js

@@ -0,0 +1,22 @@
+/**
+ * Created by jimiz on 2017/4/16.
+ */
+var Project = require('../models/project');
+
+//统一回调函数
+var callback = function(req, res, err, message, data){
+    res.json({error: err, message: message, data: data});
+};
+
+module.exports = {
+    save: function (req, res) {
+        var data = JSON.parse(req.body.data);
+        Project.save(data, function (err, message, result) {
+            if (err) {
+                callback(req, res, err, message, result);
+            } else {
+                callback(req, res, err, message, null);
+            }
+        });
+    }
+};

+ 6 - 17
modules/main/controllers/rations_controller.js

@@ -1,7 +1,7 @@
 /**
  * Created by jimiz on 2017/4/9.
  */
-var rationsData = require('../models/rations');
+var rationData = require('../models/ration');
 
 //统一回调函数
 var callback = function(req, res, err, message, data){
@@ -9,9 +9,9 @@ var callback = function(req, res, err, message, data){
 };
 
 module.exports = {
-    getRations: function(req, res){
+    getData: function(req, res){
         var data = JSON.parse(req.body.data);
-        rationsData.getRations(data.projectId, function(err, message, rationList){
+        rationData.getData(data.projectId, function(err, message, rationList){
             if (err === 0) {
                 callback(req, res, err, message, rationList);
             } else {
@@ -20,20 +20,9 @@ module.exports = {
         });
     },
 
-    updateRations: function(req, res){
-        var data = JSON.parse(req.body.data);
-        rationsData.updateRations(data, function(err, message, errList){
-            if (err) {
-                callback(req, res, err, message, errList);
-            } else {
-                callback(req, res, err, message, null);
-            }
-        });
-    },
-
-    getRationItemTemplate: function(req, res){
+    getItemTemplate: function(req, res){
         //var data = JSON.parse(req.body.data);
-        rationsData.getRationItemTemplate(function(err, message, rationItem){
+        rationData.getItemTemplate(function(err, message, rationItem){
             if (billsItem) {
                 callback(req, res, err, message, rationItem);
             } else {
@@ -43,7 +32,7 @@ module.exports = {
     },
 
     allocIDs: function(req, res){
-        rationsData.allocIDs(function(err, message, data){
+        rationData.allocIDs(function(err, message, data){
             if (err) {
                 callback(req, res, err, message, data);
             } else {

+ 85 - 0
modules/main/models/GLJ.js

@@ -0,0 +1,85 @@
+/**
+ * Created by jimiz on 2017/4/1.
+ */
+var mongoose = require("mongoose");
+var db = require("../db/project_db");
+var Schema = mongoose.Schema;
+
+var GLJSchema = new Schema({
+    ID: Number,
+    projectID: Number,
+    orgRQuantity: String, //Decimal
+    rQuantity: String, //Decimal
+    customQuantity: String, //Decimal
+    quantity: String, //Decimal
+    rationItemQuantity: String, //Decimal
+    rationPrice: String, //Decimal
+    adjustPrice: String, //Decimal
+    price: String, //Decimal
+    tenderQuantity: String, //Decimal
+    tenderPrice: String, //Decimal
+    type: Number
+    // to do
+
+});
+
+var GLJ = db.model("GLJList", GLJSchema);
+
+var GLJDAO = function(){};
+
+GLJDAO.prototype.getData = function(projectId, callback){
+    GLJ.find({projectId: projectId}, function(err, datas){
+        if (!err) {
+            callback(0, '', datas);
+        } else {
+            callback(1, '', null);
+        };
+    });
+};
+
+GLJDAO.prototype.save = function(datas, callback){
+    var data, errList = [], updateLength = 0;
+    var updateFunc = function (err, errData) {
+        if (err){
+            errList.push(errData);
+        };
+    };
+    if (datas){
+        for (var i = 0; i < datas.length; i++){
+            data = datas[i];
+            if (data.updateType === 'update') {
+                delete data.updateType;
+                data.save(updateFunc);
+            } else if (data.updateType === 'create') {
+                delete data.updateType;
+                data.save(updateFunc);
+            } else if (data.updateType === 'delete') {
+                delete data.updateType;
+                data.remove(updateFunc);
+            };
+        };
+        if (errList.length > 0){
+            callback(1, errList);
+        } else {
+            callback(0, null);
+        };
+    };
+};
+
+GLJDAO.prototype.getItemTemplate = function(callback){
+    var data = new bills;
+    /* to do: 需要根据标准配置库填充fees和flags字段,是否需要更多的参数? */
+    callback(0, '', data);
+};
+
+const
+    IDStep = 50, IDModule = 'bills';
+
+GLJDAO.prototype.allocIDs = function(IDStep, callback){
+    counter.counterDAO.getIDAfterCount(counter.moduleName.GLJ, IDStep, function(err, highID){
+        var lowID = highID - IDStep + 1;
+        callback(0, '', {lowID: lowID, highID: highID});
+    });
+};
+
+module.exports = new GLJDAO();

+ 35 - 15
modules/main/models/bills.js

@@ -4,6 +4,7 @@
 var mongoose = require("mongoose");
 var db = require("../db/project_db");
 var subSchema = require("./billsSubSchemas");
+var deleteSchema = require('../../../public/models/deleteSchema');
 var Schema = mongoose.Schema;
 var counter = require("../../../public/counter/counter.js");
 
@@ -37,15 +38,16 @@ var billsSchema = new Schema({
     // 费用字段
     fees: [subSchema.feesSchema],
     // 标记字段
-    flags: [subSchema.flagsSchema]
+    flags: [subSchema.flagsSchema],
+    deleteInfo: deleteSchema
 });
 
 var bills = db.model("bills", billsSchema);
 
 var billsDAO = function(){};
 
-billsDAO.prototype.getBills = function(projectId, callback){
-    Projects.find({projectId: projectId}, function(err, datas){
+billsDAO.prototype.getData = function(projectID, callback){
+    bills.find({'$or': [{projectID: projectID, deleteInfo: null}, {projectID: projectID, 'deleteInfo.deleted': {$in: [null, false]}}]}, '-_id', function(err, datas){
         if (!err) {
             callback(0, '', datas);
         } else {
@@ -54,7 +56,28 @@ billsDAO.prototype.getBills = function(projectId, callback){
     });
 };
 
-billsDAO.prototype.updateBills = function(datas, callback){
+// get All Project Bills, include deleted
+billsDAO.prototype.getProjectBills = function (projectId, callback) {
+    if (callback) {
+        bills.find({projectID: projectId}, '-_id').exec()
+            .then(function (result, err) {
+                if (err) {
+                    callback(1, '找不到模板', null);
+                } else {
+                    callback(0, '', template);
+                }
+            });
+        return null;
+    } else {
+        return bills.find({projectID: projectId}, '-_id').exec();
+    }
+}
+
+billsDAO.prototype.AddBillsFromTemplate = function (datas, callback) {
+    bills.collection.insert(datas, callback);
+};
+
+billsDAO.prototype.save = function(datas, callback){
     var data, errList = [], updateLength = 0;
     var updateFunc = function (err, errData) {
         if (err){
@@ -76,27 +99,24 @@ billsDAO.prototype.updateBills = function(datas, callback){
             };
         };
         if (errList.length > 0){
-            callback(1, 'update error.', errList);
+            callback(1, errList);
         } else {
-            callback(0, '', null);
+            callback(0, null);
         };
     };
 };
 
-billsDAO.prototype.getBillsItemTemplate = function(callback){
+billsDAO.prototype.getItemTemplate = function(callback){
     var data = new bills;
     /* to do: 需要根据标准配置库填充fees和flags字段,是否需要更多的参数? */
     callback(0, '', data);
 };
 
-const
-    IDStep = 50, IDModule = 'bills';
-
-billsDAO.prototype.allocIDs = function(callback){
-    var lowID, highID;
-    counter.getIDAfterCount(IDModule, IDStep, function(highID, err){});
-    lowID = highID - IDStep + 1;
-    callback(0, '', {lowID: lowID, highID: highID});
+billsDAO.prototype.allocIDs = function(IDStep, callback){
+    counter.counterDAO.getIDAfterCount(counter.moduleName.bills, IDStep, function(err, highID){
+        var lowID = highID - IDStep + 1;
+        callback(0, '', {lowID: lowID, highID: highID});
+    });
 };
 
 module.exports = new billsDAO();

+ 1 - 1
modules/main/models/billsSubSchemas.js

@@ -16,7 +16,7 @@ var feesSchema = new Schema({
 // 标记字段
 var flagsSchema = new Schema({
     fieldName: String,
-    flag: Boolean
+    flag: Number
 });
 
 module.exports = {feesSchema: feesSchema, flagsSchema: flagsSchema};

+ 0 - 24
modules/main/models/gljs.js

@@ -1,24 +0,0 @@
-/**
- * Created by jimiz on 2017/4/1.
- */
-var mongoose = require("mongoose");
-var db = require("../db/project_db");
-var Schema = mongoose.Schema;
-
-var gljSchema = new Schema({
-    ID: Number,
-    projectID: Number,
-    orgRQuantity: String, //Decimal
-    rQuantity: String, //Decimal
-    customQuantity: String, //Decimal
-    quantity: String, //Decimal
-    rationItemQuantity: String, //Decimal
-    rationPrice: String, //Decimal
-    adjustPrice: String, //Decimal
-    price: String, //Decimal
-    tenderQuantity: String, //Decimal
-    tenderPrice: String, //Decimal
-    type: Number
-    // to do
-
-});

+ 56 - 0
modules/main/models/project.js

@@ -0,0 +1,56 @@
+/**
+ * Created by jimiz on 2017/4/16.
+ */
+var billsData = require('./bills');
+var rationData = require('./ration');
+var GLJData = require('./GLJ');
+var consts = require('./projectConsts');
+
+var moduleMap = {};
+
+moduleMap[consts.BILLS] = billsData;
+moduleMap[consts.RATION] = rationData;
+moduleMap[consts.GLJ] = GLJData;
+
+var Project = function (){};
+
+Project.prototype.datas = [];
+
+Project.prototype.prepare = function(data, callback){
+    data.updateData.forEach(function(item){
+        this.datas.push(item);
+        /*
+        to do
+        moduleMap[item.moduleName].prepare(item.data, jobCallback);
+        */
+    });
+};
+
+Project.prototype.save = function(data, callback){
+    var job, savePoint;
+    var errDatas = [];
+    this.prepare(data, function(job, savePoint){});
+
+    var saveCallback = function(err, moduleName, data){
+        if (err != 0){
+            var errData = {moduleName: moduleName, err: err, data: data};
+            errDatas.push(errData);
+        }
+    };
+
+    this.datas.forEach(function(item){
+        moduleMap[item.moduleName].save(item.data, saveCallback);
+    });
+
+    this.datas = [];
+
+    if (errDatas.length > 0){
+        callback(1, 'error', errDatas)
+    }
+    else{
+        callback(0, '', null)
+    }
+
+};
+
+module.exports = new Project();

+ 12 - 0
modules/main/models/projectConsts.js

@@ -0,0 +1,12 @@
+/**
+ * Created by jimiz on 2017/4/18.
+ */
+var projectConst = {
+    BILLS: 'bills',
+    RATION: 'ration',
+    GLJ: 'GLJ',
+    PROJECTGLJ: 'projectGLJ'
+
+};
+
+module.exports = projectConst;

+ 1 - 1
modules/main/models/projectGLJ.js

@@ -7,7 +7,7 @@ var Schema = mongoose.Schema;
 
 var projectGLJSchema = new Schema({
     ID: Number,
-    projectId: Number,
+    projectID: Number,
     code: Number,
     name: String,
     specs: String,

+ 15 - 15
modules/main/models/rations.js

@@ -6,9 +6,9 @@ var db = require("../db/project_db");
 var subSchema = require("./billsSubSchemas");
 var Schema = mongoose.Schema;
 
-var rationsSchema = new Schema({
+var rationSchema = new Schema({
     ID: Number,
-    ProjectID: Number,
+    projectID: Number,
     billsItemID: Number,
     serialNo: Number,
     libID: Number,
@@ -27,12 +27,12 @@ var rationsSchema = new Schema({
     flags: [subSchema.flagsSchema]
 });
 
-var rations = db.model("rations", rationsSchema);
+var ration = db.model("rations", rationSchema);
 
-var rationsDAO = function(){};
+var rationDAO = function(){};
 
-rationsDAO.prototype.getRations = function(projectId, callback){
-    Projects.find({projectID: projectId}, function(err, datas){
+rationDAO.prototype.getData = function(projectId, callback){
+    rations.find({projectID: projectId}, function(err, datas){
         if (!err) {
             callback(0, '', datas);
         } else {
@@ -41,7 +41,7 @@ rationsDAO.prototype.getRations = function(projectId, callback){
     });
 };
 
-rationsDAO.prototype.updateRations = function(projectId, datas, callback){
+rationDAO.prototype.save = function(projectId, datas, callback){
     var data, errList = [], updateLength = 0;
     var updateFunc = function (err, errData) {
         if (err){
@@ -70,8 +70,8 @@ rationsDAO.prototype.updateRations = function(projectId, datas, callback){
     };
 };
 
-rationsDAO.prototype.getRationItemTemplate = function(callback){
-    var data = new rations;
+rationDAO.prototype.getItemTemplate = function(callback){
+    var data = new ration;
     /* to do: 需要根据标准配置库填充fees和flags字段,是否需要更多的参数? */
     callback(0, '', data);
 };
@@ -79,11 +79,11 @@ rationsDAO.prototype.getRationItemTemplate = function(callback){
 const
     IDStep = 50, IDModule = 'rations';
 
-rationsDAO.prototype.allocIDs = function(callback){
-    var lowID, highID;
-    counter.getIDAfterCount(IDModule, IDStep, function(highID, err){});
-    lowID = highID - IDStep + 1;
-    callback(0, '', {lowID: lowID, highID: highID});
+rationDAO.prototype.allocIDs = function(IDStep, callback){
+    counter.counterDAO.getIDAfterCount(counter.moduleName.ration, IDStep, function(err, highID){
+        var lowID = highID - IDStep + 1;
+        callback(0, '', {lowID: lowID, highID: highID});
+    });
 };
 
-module.exports = new rationsDAO();
+module.exports = new rationDAO();

+ 12 - 0
modules/main/routes/GLJ_route.js

@@ -0,0 +1,12 @@
+/**
+ * Created by jimiz on 2017/4/17.
+ */
+var express = require('express');
+var GLJRouter = express.Router();
+var GLJController = require('../controllers/GLJ_controller');
+
+GLJRouter.post('/getData', GLJController.getData);
+GLJRouter.post('/getItemTemplate', GLJController.getItemTemplate);
+GLJRouter.post('/allocIDs', GLJController.allocIDs);
+
+module.exports = GLJRouter;

+ 2 - 3
modules/main/routes/bills_route.js

@@ -5,9 +5,8 @@ var express = require('express');
 var billsRouter = express.Router();
 var billsController = require('../controllers/bills_controller');
 
-billsRouter.post('/getBills', billsController.getBills);
-billsRouter.post('/updateBills', billsController.updateBills);
-billsRouter.post('/getBillsItemTemplate', billsController.getBillsItemTemplate);
+billsRouter.post('/getData', billsController.getData);
+billsRouter.post('/getItemTemplate', billsController.getItemTemplate);
 billsRouter.post('/allocIDs', billsController.allocIDs);
 
 module.exports = billsRouter;

+ 10 - 0
modules/main/routes/project_route.js

@@ -0,0 +1,10 @@
+/**
+ * Created by jimiz on 2017/4/16.
+ */
+var express = require('express');
+var projectRouter = express.Router();
+var projectController = require('../controllers/project_controller');
+
+projectRouter.post('/save', projectController.save);
+
+module.exports = projectRouter;

+ 12 - 0
modules/main/routes/ration_route.js

@@ -0,0 +1,12 @@
+/**
+ * Created by jimiz on 2017/4/7.
+ */
+var express = require('express');
+var rationRouter = express.Router();
+var rationController = require('../controllers/ration_controller');
+
+rationRouter.post('/getData', rationController.getData);
+rationRouter.post('/getItemTemplate', rationController.getItemTemplate);
+rationRouter.post('/allocIDs', rationController.allocIDs);
+
+module.exports = rationRouter;

+ 0 - 13
modules/main/routes/rations_route.js

@@ -1,13 +0,0 @@
-/**
- * Created by jimiz on 2017/4/7.
- */
-var express = require('express');
-var rationsRouter = express.Router();
-var rationsController = require('../controllers/rations_controller');
-
-rationsRouter.post('/getRations', rationsController.getRations);
-rationsRouter.post('/updateRations', rationsController.updateRations);
-rationsRouter.post('/getRationsItemTemplate', rationsController.getRationItemTemplate);
-rationsRouter.post('/allocIDs', rationsController.allocIDs);
-
-module.exports = rationsRouter;

+ 20 - 0
modules/pm/controllers/copy_proj_controller.js

@@ -0,0 +1,20 @@
+/**
+ * Created by Mai on 2017/4/24.
+ */
+
+var billsData = require('../../main/models/bills');
+
+module.exports = {
+    copyProjectData: function (srcProjID, newProjID, callback) {
+        billsData.getProjectBills(srcProjID).then(function (results) {
+            var datas = [];
+            results.forEach(function (result) {
+                result._doc.projectID = newProjID;
+                datas.push(result._doc);
+            });
+            return billsData.AddBillsFromTemplate(datas, callback);
+        }).then(function (err) {
+            callback(err);
+        });
+    }
+};

+ 21 - 0
modules/pm/controllers/new_proj_controller.js

@@ -0,0 +1,21 @@
+/**
+ * Created by Mai on 2017/4/24.
+ */
+
+var billsData = require('../../main/models/bills');
+var BillsTemplateData = require('../../templates/models/bills_template');
+
+module.exports = {
+    copyTemplateData: function (tempType, newProjID, callback) {
+        BillsTemplateData.getTemplate(tempType).then(function (templates) {
+            var datas = [];
+            templates.forEach(function (template) {
+                template._doc.projectID = newProjID;
+                datas.push(template._doc);
+            })
+            return billsData.AddBillsFromTemplate(datas, callback);
+        }).catch(function (err) {
+            callback(err);
+        });
+    }
+};

+ 28 - 4
modules/pm/controllers/pm_controller.js

@@ -9,6 +9,14 @@ var callback = function(req, res, err, message, data){
 }
 
 module.exports = {
+    checkRight: function (req, res) {
+        var data = JSON.parse(req.body.data);
+        if (data.user_id) {
+            return data.user_id === req.session.userID;
+        } else {
+            return false;
+        }
+    },
     getProjects: function(req, res){
         var data = JSON.parse(req.body.data);
         ProjectsData.getUserProjects(data.user_id, function(err, message, projects){
@@ -27,13 +35,23 @@ module.exports = {
             } else {
                 callback(req, res, err, message, null);
             }
-        })
+        });
+    },
+    copyProjects: function (req, res) {
+        var data = JSON.parse(req.body.data);
+        ProjectsData.copyUserProjects(data.user_id, data.updateData, function (err, message, data) {
+            if (err === 0) {
+                callback(req, res, err, message, data);
+            } else {
+                callback(req, res, err, message, null);
+            }
+        });
     },
     rename: function (req, res) {
         var data = JSON.parse(req.body.data);
         ProjectsData.rename(data.user_id, data.id, data.newName, function (err, message) {
             callback(req, res, err, message, null);
-        })
+        });
     },
     getProject: function(req, res){
         var data = JSON.parse(req.body.data);
@@ -43,12 +61,18 @@ module.exports = {
             } else {
                 callback(req, res, err, message, null);
             }
-        })
+        });
     },
     beforeOpenProject: function (req, res) {
         var data = JSON.parse(req.body.data);
         ProjectsData.beforeOpenProject(data.user_id, data.proj_id, data.updateData, function (err, message, data) {
             callback(req, res, err, message, data);
-        })
+        });
+    },
+    getNewProjectID: function (req, res) {
+        var data = JSON.parse(req.body.data);
+        ProjectsData.getNewProjectID(data.count, function (err, message, data) {
+            callback(req, res, err, message, data);
+        });
     }
 }

+ 74 - 28
modules/pm/models/project.js

@@ -1,13 +1,17 @@
 /**
  * Created by Mai on 2017/1/18.
  */
+var counter = require("../../../public/counter/counter.js");
+
+var newProjController = require('../controllers/new_proj_controller');
+var copyProjController = require('../controllers/copy_proj_controller');
 
-//*/
 var mongoose = require("mongoose");
 
 var dbm = require("../../../config/db/db_manager");
 var db = dbm.getCfgConnection("usersManages");
 var Schema = mongoose.Schema;
+var deleteSchema = require('../../../public/models/deleteSchema');
 var ProjectSchema = new Schema({
     "ID": Number,
     "ParentID": Number,
@@ -17,36 +21,15 @@ var ProjectSchema = new Schema({
     "projType": String,
     "recentDateTime": Date,
     "createDateTime": Date,
-    "deleted": Boolean,
-    'deleteDateTime': Date,
+    "deleteInfo": deleteSchema,
     'fullFolder': Array
 });
 var Projects = db.model("projects", ProjectSchema);
 
-/*/
-var db = require('../db/pm_db');
-var Schema = db.mongoose.Schema;
- var ProjectSchema = new Schema({
- "name": String,
- "projType": String,
- "lastDateTime": String,
- "createDateTime": String,
- "id": Number,
- "parentId": Number,
- "nextId": Number,
- "userId": Number,
- "deleted": Boolean,
- 'deleteDateTime': String,
- 'deleteFullFolder': Array
- });
-
- var Projects = db.mongoose.model("projects", ProjectSchema);
-//*/
-
 var ProjectsDAO = function(){};
 
 ProjectsDAO.prototype.getUserProjects = function(userId, callback){
-    Projects.find({userID: userId, deleted: { $in: [false, null]}}, '-_id', function(err, templates){
+    Projects.find({'$or': [{'userID': userId, 'deleteInfo': null}, {'userID': userId, 'deleteInfo.deleted': {'$in': [null, false]}}]}, '-_id', function(err, templates){
         if (err) {
             callback(1, 'Error', null);
         } else {
@@ -66,7 +49,7 @@ ProjectsDAO.prototype.getUserProject = function (userId, ProjId, callback) {
 }
 
 ProjectsDAO.prototype.updateUserProjects = function(userId, datas, callback){
-    var data, project, updateLength = 0, hasError = false;
+    var data, project, updateLength = 0, hasError = false, deleteInfo = null, tempType = 1, i, newProject;
     var updateAll = function (err) {
             if (!err){
                 updateLength += 1;
@@ -79,7 +62,7 @@ ProjectsDAO.prototype.updateUserProjects = function(userId, datas, callback){
             }
         };
     if (datas){
-        for (var i = 0; i < datas.length && !hasError; i++){
+        for (i = 0; i < datas.length && !hasError; i++){
             data = datas[i];
             if (data.updateType === 'update') {
                 Projects.update({userID: userId, ID: data.updateData.ID}, data.updateData, updateAll)
@@ -89,10 +72,62 @@ ProjectsDAO.prototype.updateUserProjects = function(userId, datas, callback){
                     data.updateData['createDateTime'] = new Date();
                 }
                 newProject = new Projects(data.updateData);
-                newProject.save(updateAll);
+                newProject.save(function (err, result) {
+                    if (!err && result._doc.projType === 'Tender') {
+                        newProjController.copyTemplateData(tempType, newProject.ID, updateAll);
+                    } else {
+                        updateAll(err);
+                    }
+                });
             } else if (data.updateType === 'delete') {
-                data.updateData['deleteDateTime'] = new Date();
+                deleteInfo = {};
+                deleteInfo['deleted'] = true;
+                deleteInfo['deleteDateTime'] = new Date();
+                deleteInfo['deleteBy'] = userId;
+                data.updateData['deleteInfo'] = deleteInfo;
                 Projects.update({userID: userId, ID: data.updateData.ID}, data.updateData, updateAll);
+            } else {
+                hasError = true;
+                callback(1, '提交数据错误.', null);
+            }
+        }
+    }
+};
+ProjectsDAO.prototype.copyUserProjects = function (userId, datas, callback) {
+    var data, project, updateLength = 0, hasError = false, deleteInfo = null, tempType = 1, i;
+    var updateAll = function (err) {
+        if (!err){
+            updateLength += 1;
+            if (updateLength === datas.length) {
+                callback(0, '', datas);
+            }
+        } else {
+            hasError = true;
+            callback(1, '提交数据出错.', null);
+        }
+    };
+    if (datas) {
+        for (i = 0; i < datas.length && !hasError; i++) {
+            data = datas[i];
+            if (data.updateType === 'update') {
+                Projects.update({userID: userId, ID: data.updateData.ID}, data.updateData, updateAll)
+            } else if (data.updateType === 'copy') {
+                data.updateData['userID'] = userId;
+                if (data.updateData.projType === 'Tender') {
+                    data.updateData['createDateTime'] = new Date();
+                };
+                newProject = new Projects(data.updateData);
+                newProject['srcProjectId'] = data.srcProjectId;
+                newProject.save(function (err, result) {
+                    if (!err && result._doc.projType === 'Tender') {
+                        copyProjController.copyProjectData(this.newProject.srcProjectId, result._doc.ID, updateAll);
+                    } else {
+                        updateAll(err);
+                    }
+                });
+            } else {
+                haseError = true;
+                callback(1, '提交数据错误', null);
             }
         }
     }
@@ -119,4 +154,15 @@ ProjectsDAO.prototype.beforeOpenProject = function (userId, projectId, updateDat
     });
 };
 
+ProjectsDAO.prototype.getNewProjectID = function (count, callback) {
+    counter.counterDAO.getIDAfterCount(counter.moduleName.project, count, function (err, result) {
+        var highID = result.value.sequence_value;
+        if (!err) {
+            callback(0, '', {lowID: highID - count + 1, highID: highID});
+        } else {
+            callback(1, '获取主键失败', null);
+        }
+    });
+}
+
 module.exports = new ProjectsDAO();

+ 10 - 0
modules/pm/routes/pm_route.js

@@ -6,10 +6,20 @@ var express = require('express');
 var pmRouter = express.Router();
 var pmController = require('./../controllers/pm_controller');
 
+pmRouter.use(function (req, res, next) {
+    if (/\/getNewProjectID/.test(req.originalUrl) || pmController.checkRight(req, res)) {
+        next();
+    } else {
+        res.json({error: 1, message: '对不起,您无权限操作。', data: null});
+    }
+});
+
 pmRouter.post('/getProjects', pmController.getProjects);
 pmRouter.post('/updateProjects', pmController.updateProjects);
+pmRouter.post('/copyProjects', pmController.copyProjects);
 pmRouter.post('/renameProject', pmController.rename);
 pmRouter.post('/beforeOpenProject', pmController.beforeOpenProject);
 pmRouter.post('/getProject', pmController.getProject);
+pmRouter.post('/getNewProjectID', pmController.getNewProjectID);
 
 module.exports = pmRouter;

+ 0 - 15
modules/rationLib/models/rationRepository.js

@@ -1,15 +0,0 @@
-/**
- * Created by Tony on 2017/4/19.
- * 定额库分类,如重庆、广东等各个省的建筑定额,未来考虑与公路合并
- */
-var mongoose = require('mongoose');
-var dbm = require("../../../config/db/db_manager");
-var rationLibdb = dbm.getCfgConnection("rationLibs");
-var Schema = mongoose.Schema;
-
-var RationLibSchema = new Schema({
-    "ID" : String,
-    "dispName" : String,
-    "type" : String,
-    "descr" : String
-});

+ 75 - 0
modules/rationRepository/controllers/rationChapterTreeController.js

@@ -0,0 +1,75 @@
+/**
+ * Created by Tony on 2017/4/21.
+ */
+
+var rationChapterTreeData = require('../models/rationChapterTree');
+var callback = function(req,res,err,data){
+    if(data){
+        res.status(200)
+        res.json({success:true,data:data});
+    }
+    else
+    if(err){
+        res.status(500)
+        res.json({success:false,error:err});
+    }
+    else{
+        res.status(204);
+        res.json({success:true,data:null});
+    }
+}
+module.exports ={
+    getRationChapterTree:
+        function(req,res){
+            var libName = req.body.rationLibName;
+            rationChapterTreeData.getRationChapterTrees(libName,function(err,data){
+                callback(req,res,err,data)
+            })
+        },
+    createNewNode: function(req, res){
+        var libName = req.body.rationLibName;
+        var nodeData = JSON.parse(req.body.rawNodeData);
+        rationChapterTreeData.createNewNode(libName, nodeData, function(err,data){
+            callback(req,res,err,data)
+        });
+    },
+    updateNodes: function(req, res) {
+        var nodes = JSON.parse(req.body.nodes);
+        rationChapterTreeData.updateNodes(nodes, function(err,results){
+            callback(req,res, err, results)
+        });
+    },
+    deleteNodes: function(req, res) {
+        var nodes = JSON.parse(req.body.nodes);
+        var preNodeId = req.body.preNodeId;
+        var preNodeNextId = req.body.preNodeNextId;
+        rationChapterTreeData.removeNodes(nodes, preNodeId, preNodeNextId, function(err,results){
+            callback(req,res, err, results)
+        });
+    },
+    tempRationChapterTreeInsert:
+        function(req,res){
+            var DBName = req.body.rationName;
+            var rationTempTree = JSON.parse(req.body.rationTempTree);
+            rationChapterTreeData.tempRationChapterTreeInsert(DBName,rationTempTree,function(err,data){
+                callback(req,res,err,data)
+            })
+        },
+    sectionUpsert:
+        function(req,res){
+            var LibName = req.body.rationLibName;
+            var section = JSON.parse(req.body.rationSection);
+            rationChapterTreeData.sectionUpsert(LibName,section,function(err,data){
+                callback(req,res,err,data)
+            })
+        },
+    deleteSection:
+        function(req,res){
+            var LibName = req.body.rationLibName;
+            var sectionID = req.body.sectionID;
+            rationChapterTreeData.deleteSection(LibName,sectionID,function(err,data){
+                callback(req,res,err,data)
+            })
+        }
+
+}

+ 73 - 0
modules/rationRepository/controllers/rationRepositoryController.js

@@ -0,0 +1,73 @@
+/**
+ * Created by Tony on 2017/4/20.
+ */
+var rationRepository = require("../models/repositoryMap");
+
+var callback = function(req,res,err,data){
+    if(data){
+        res.status(200)
+        res.json({success:true,data:data});
+    }
+    else
+    if(err){
+        res.status(500)
+        res.json({success:false,error:err});
+    }
+    else{
+        res.status(204);
+        res.json({success:true});
+    }
+};
+
+module.exports = {
+    addRationRepository:function(req,res){
+        var rationObj = JSON.parse(req.body.rationRepObj);
+        rationRepository.addRationRepository(rationObj,function(err,data){
+            if (data) {
+                callback(req, res, err, data);
+            } else {
+                callback(req, res, err, null);
+            }
+        })
+    },
+    getDisPlayRationLibs: function(req, res){
+        rationRepository.getDisplayRationLibs(function(err, data){
+            if (data) {
+                callback(req, res, err, data);
+            } else {
+                callback(req, res, err, null);
+            }
+        });
+    },
+    getRealLibName:function(req,res){
+        var libName = req.body.rationName;
+        rationRepository.getRealLibName(libName,function(err,data){
+            if (data) {
+                callback(req, res, err, data);
+            } else {
+                callback(req, res, err, null);
+            }
+        })
+    },
+    deleteRationLib:function(req,res){
+        var rationName = req.body.rationName;
+        rationRepository.deleteRationLib(rationName,function(err,data){
+            if (data) {
+                callback(req, res, err, data);
+            } else {
+                callback(req, res, err,  null);
+            }
+        })
+    },
+    updateRationRepositoryName: function(req, res) {
+        var orgName = req.body.rationName;
+        var newName = req.body.newName;
+        rationRepository.updateName(orgName, newName, function(err, data){
+            if (data) {
+                callback(req, res, err, data);
+            } else {
+                callback(req, res, err, null);
+            }
+        });
+    }
+}

+ 134 - 0
modules/rationRepository/models/rationChapterTree.js

@@ -0,0 +1,134 @@
+/**
+ * Created by Tony on 2017/4/21.
+ */
+
+var mongoose = require("mongoose");
+var dbm = require("../../../config/db/db_manager");
+var chapterTreeDb = dbm.getCfgConnection("rationRepository")
+var async = require("async");
+var Schema = mongoose.Schema;
+
+var rationChapterTreeSchema = mongoose.Schema({//章节树  //生成唯一id改为sectionID  改成string
+    rationRepId: Number,
+    ID:Number,
+    ParentID:Number,
+    NextSiblingID:Number,
+    name: String,
+    isDeleted: Boolean
+});
+var rationChapterTreeModel = chapterTreeDb.model("rationChapterTrees",rationChapterTreeSchema, "rationChapterTrees")
+var repositoryMap = require('./repositoryMap');
+var counter = require('../../../public/counter/counter');
+
+var rationChapterTreeDAO = function(){};
+
+rationChapterTreeDAO.prototype.getRationChapterTrees = function(repositoryName,callback){
+    repositoryMap.getRealLibName(repositoryName, function(err, rst){
+        rationChapterTreeModel.find({"rationRepId": rst[0].ID, "$or": [{"isDeleted": null}, {"isDeleted": false} ]},function(err,data){
+            if(data.length) callback(false,data);
+            else  if(err) callback("获取定额树错误!",false)
+            else callback(false,false);
+        })
+    })
+}
+
+rationChapterTreeDAO.prototype.createNewNode = function(repositoryName,nodeData,callback){
+    var promise = repositoryMap.getRealLibName(repositoryName), libId;
+    if (promise) {
+        promise.then(function(rst){
+            libId = rst[0].ID;
+            return counter.counterDAO.getIDAfterCount(counter.moduleName.rationTree, 1, function(err, result){
+                nodeData.rationRepId = libId;
+                nodeData.ID = result.value.sequence_value;
+                var node = new rationChapterTreeModel(nodeData);
+                node.save(function (err, result) {
+                    if (err) {
+                        callback("章节树ID错误!", false);
+                    } else {
+                        callback(false, result);
+                    }
+                });
+            });
+        });
+    } else {
+        callback("定额库选择错误!", false);
+    }
+},
+
+rationChapterTreeDAO.prototype.tempRationChapterTreeInsert = function(repositoryName,rationTempTree,callback){
+    var db = dbm.getCfgConnection(repositoryName)
+    var rationChapterTreeModel = db.model("rationChapterTrees",rationChapterTreeSchema, "rationChapterTrees")
+    rationChapterTreeModel.collection.insert(rationTempTree,function(err,data){
+        if(err) callback("插入定额模板错误",false)
+        else callback(false,"ok")
+    })
+}
+
+rationChapterTreeDAO.prototype.removeNodes = function(nodeIds, preNodeId, preNodeNextId, callback){
+    var functions = [];
+    if (preNodeId != -1) {
+        functions.push((function(nodeId, nextId) {
+            return function(cb) {
+                rationChapterTreeModel.update({ID: nodeId}, {"NextSiblingID": nextId}, cb);
+            };
+        })(preNodeId, preNodeNextId));
+    }
+    for (var i=0; i < nodeIds.length; i++) {
+        functions.push((function(nodeId) {
+            return function(cb) {
+                rationChapterTreeModel.update({ID: nodeId}, {"isDeleted": true}, cb);
+            };
+        })(nodeIds[i]));
+    }
+    async.parallel(functions, function(err, results) {
+        callback(err, results);
+    });
+}
+
+rationChapterTreeDAO.prototype.updateNodes = function(nodes,callback){
+    var functions = [];
+    for (var i=0; i < nodes.length; i++) {
+        //var md = new rationChapterTreeModel(nodes[i]);
+        //md.isNew = false;
+        functions.push((function(doc) {
+            return function(cb) {
+                rationChapterTreeModel.update({ID: doc.ID}, doc, cb);
+            };
+        })(nodes[i]));
+    }
+    async.parallel(functions, function(err, results) {
+        callback(err, results);
+    });
+};
+
+rationChapterTreeDAO.prototype.sectionUpsert = function(repositoryName,section,callback){
+    var db = dbm.getCfgConnection(repositoryName);
+    var rationChapterTreeModel = db.model("rationChapterTrees",rationChapterTreeSchema, "rationChapterTrees");
+    rationChapterTreeModel.find({"sectionId": section.sectionId},function(err,data){
+        if(data.length){
+            rationChapterTreeModel.update({'sectionId':section.sectionId},section,function(err,data){
+                if(err){
+                    callback(" ",false);
+                }else
+                    callback(false,"ok");
+            });
+        }else{
+            var N = new rationChapterTreeModel(section).save(function(err){
+                if(err){
+                    callback(" ",false);
+                }else
+                    callback(false,"success!");
+            })
+        }
+    })
+}
+//待  ration模块完成
+rationChapterTreeDAO.prototype.deleteSection= function(repositoryName,sectionId,callback){
+    var db = dbm.getCfgConnection(repositoryName);
+    var rationChapterTreeModel = db.model("rationItems",rationChapterTreeSchema);
+    rationChapterTreeModel.find({"sectionId": sectionId},[],function(err,data){
+
+    })
+}
+
+module.exports = new rationChapterTreeDAO()

+ 95 - 0
modules/rationRepository/models/repositoryMap.js

@@ -0,0 +1,95 @@
+/**
+ * Created by Tony on 2017/4/24.
+ * 重新构造,不适宜生成多个定额库db,还是得统一在一个表
+ */
+var mongoose = require('mongoose');
+var dbm = require("../../../config/db/db_manager");
+//var stringUtil = require('../../../public/stringUtil');
+var rationLibdb = dbm.getCfgConnection("rationRepository");
+var Schema = mongoose.Schema;
+var RepositoryMapSchema = new Schema({
+    "ID": Number,
+    "dispName" : String,
+    "appType" : String, //如:"建筑" / "公路"
+    "localeType": String, //如 各个省份 / 部颁
+    "descr" : String,
+    "deleted": Boolean
+});
+var counter = require('../../../public/counter/counter');
+
+var rationRepository = rationLibdb.model("repositoryMap", RepositoryMapSchema, "repositoryMap");
+
+function createNewLibModel(rationLibObj){
+    var rst = {};
+    rst.dispName = rationLibObj.dispName;
+    rst.appType = rationLibObj.appType?rationLibObj.appType:'construct';
+    rst.localeType = rationLibObj.localeType?rationLibObj.localeType:'';
+    rst.descr = rationLibObj.descr;
+    rst.deleted = false;
+    return rst;
+}
+
+rationRepositoryDao = function(){};
+
+rationRepositoryDao.prototype.getRealLibName = function(dispName,callback){
+    if (callback) {
+        rationRepository.find({"dispName": dispName}, function(err,data){
+            if (err) {
+                callback('Error', null);
+            } else {
+                callback(0, data);
+            }
+        });
+    } else {
+        var rst = rationRepository.find({"dispName": dispName}).exec();
+        return rst;
+    }
+};
+
+rationRepositoryDao.prototype.addRationRepository = function( rationLibObj,callback){
+    counter.counterDAO.getIDAfterCount(counter.moduleName.rationMap, 1, function(err, result){
+        var rMap = createNewLibModel(rationLibObj);
+        rMap.ID = result.value.sequence_value;
+        new rationRepository(rMap).save(function(err) {
+            if (err) callback("Error", null)
+            else
+                callback(false, "ok");
+        });
+    });
+};
+
+rationRepositoryDao.prototype.getDisplayRationLibs = function(callback) {
+    rationRepository.find({"deleted": false}, function(err, data){
+        if (err) {
+            callback( 'Error', null);
+        } else {
+            callback( false, data);
+        }
+    });
+};
+
+rationRepositoryDao.prototype.updateName = function(orgName,newName,callback){
+    rationRepository.find({"dispName":newName, "deleted": false}, function(err, data){
+        if (data.length == 0) {
+            rationRepository.update({dispName:orgName},{$set:{dispName:newName}},function(err){
+                if(err) callback("err",false);
+                else callback(false,"ok")
+            })
+        } else
+            callback("不可重名!",false);
+    });
+}
+
+rationRepositoryDao.prototype.deleteRationLib = function(rationName,callback){
+    rationRepository.find({"dispName":rationName, "deleted": false}, function(err, data){
+        if (data.length == 1) {
+            rationRepository.update({dispName:rationName},{$set:{deleted: true}},function(err){
+                if(err) callback("err",false);
+                else callback(false,"ok")
+            })
+        } else
+            callback("删除失败!",false);
+    });
+}
+
+module.exports = new rationRepositoryDao();

+ 25 - 0
modules/rationRepository/routes/rationRepRoutes.js

@@ -0,0 +1,25 @@
+/**
+ * Created by Tony on 2017/4/20.
+ */
+var express = require("express");
+var apiRouter =express.Router();
+var _rootDir = __dirname;
+
+var rationRepositoryController = require("../controllers/rationRepositoryController");
+var rationChapterTreeController = require("../controllers/rationChapterTreeController");
+
+apiRouter.post("/getRationDisplayNames",rationRepositoryController.getDisPlayRationLibs);
+apiRouter.post("/editRationLibs",rationRepositoryController.updateRationRepositoryName);
+apiRouter.post("/addRationRepository",rationRepositoryController.addRationRepository);
+apiRouter.post("/deleteRationLibs",rationRepositoryController.deleteRationLib);
+apiRouter.post("/getRealLibName",rationRepositoryController.getRealLibName);
+
+apiRouter.post("/getRationTree",rationChapterTreeController.getRationChapterTree);
+apiRouter.post("/createNewNode",rationChapterTreeController.createNewNode);
+apiRouter.post("/updateNodes",rationChapterTreeController.updateNodes);
+apiRouter.post("/deleteNodes",rationChapterTreeController.deleteNodes);
+
+apiRouter.post("/addSection",rationChapterTreeController.sectionUpsert);
+apiRouter.post("/deleteSection",rationChapterTreeController.deleteSection);
+
+module.exports = apiRouter;

+ 1 - 6
modules/templates/controllers/bills_template_controller.js

@@ -3,7 +3,6 @@
  */
 var BillsTemplateData = require('../models/bills_template');
 
-//ͳһ»Øµ÷º¯Êý
 var callback = function(req, res, err, message, data){
     res.json({error: err, message: message, data: data});
 };
@@ -32,11 +31,7 @@ module.exports = {
     getNewBillsTemplateID: function (req, res) {
         var data = JSON.parse(req.body.data);
         BillsTemplateData.getNewBillsTemplateID(data.count, function (err, message, data) {
-            if (err === 0) {
-                callback(req, res, err, message, data);
-            } else {
-                callback(req, res, err, message, null);
-            }
+            callback(req, res, err, message, data);
         });
     }
 }

+ 13 - 7
modules/templates/models/bills_template.js

@@ -24,13 +24,19 @@ var BillsTemplates = templatesDB.model('temp_bills', BillsTemplateSchema);
 var BillsTemplateDAO = function(){};
 
 BillsTemplateDAO.prototype.getTemplate = function (type, callback) {
-    BillsTemplates.find({'$or': [{tempType: type, deleteInfo: null}, {tempType: type, 'deleteInfo.deleted': {$in: [null, false]}}]}, '-_id', function(err, template){
-        if (err) {
-            callback(1, '找不到模板', null);
-        } else {
-            callback(0, '', template);
-        }
-    });
+    if (callback) {
+        BillsTemplates.find({'$or': [{tempType: type, deleteInfo: null}, {tempType: type, 'deleteInfo.deleted': {$in: [null, false]}}]}, '-_id').exec()
+            .then(function (result, err) {
+                if (err) {
+                    callback(1, '找不到模板', null);
+                } else {
+                    callback(0, '', result);
+                }
+            });
+        return null;
+    } else {
+        return BillsTemplates.find({'$or': [{tempType: type, deleteInfo: null}, {tempType: type, 'deleteInfo.deleted': {$in: [null, false]}}]}, '-_id').exec();
+    }
 };
 BillsTemplateDAO.prototype.updateTemplate = function (userID, tempType, datas, callback) {
     var data, project, updateLength = 0, hasError = false, deleteInfo = null;

+ 4 - 1
public/counter/counter.js

@@ -20,7 +20,10 @@ const COUNTER_MODULE_NAME = {
     project: 'projects',
     user: 'users',
     bills: 'bills',
-    ration: 'rations',
+    ration: 'ration',
+    GLJ: 'glj',
+    rationMap: 'rationMaps',
+    rationTree: 'rationChapterTrees',
     report: 'rptTemplates',
     fee: 'fees',
     template_bills: 'temp_bills',

Файловите разлики са ограничени, защото са твърде много
+ 133 - 0
public/stringUtil.js


+ 34 - 0
public/web/common_ajax.js

@@ -0,0 +1,34 @@
+/**
+ * Created by Mai on 2017/4/20.
+ */
+
+var CommonAjax = {
+    post: function (url, data, successCallback, errorCallback) {
+        $.ajax({
+            type:"POST",
+            url: url,
+            data: {'data': JSON.stringify(data)},
+            dataType: 'json',
+            cache: false,
+            timeout: 50000,
+            success: function(result){
+                if (result.error === 0) {
+                    if (successCallback) {
+                        successCallback(result.data);
+                    }
+                } else {
+                    alert('error: ' + result.message);
+                    if (errorCallback) {
+                        errorCallback();
+                    }
+                }
+            },
+            error: function(jqXHR, textStatus, errorThrown){
+                alert('error ' + textStatus + " " + errorThrown);
+                if (errorCallback) {
+                    errorCallback();
+                }
+            }
+        });
+    }
+};

+ 58 - 15
public/web/idTree.js

@@ -7,7 +7,8 @@ var idTree = {
             id: 'id',
             pid: 'pid',
             nid: 'nid',
-            rootId: -1
+            rootId: -1,
+            autoUpdate: false
         };
 
         var _eventType = {
@@ -65,13 +66,18 @@ var idTree = {
                     nodes[i].nextSibling = (i === nodes.length - 1) ? null : nodes[i + 1];
                 }
             },
+<<<<<<< HEAD
             // ��nodes�У���iIndex����������ʼȫ���Ƴ�
+=======
+            // 在nodes中,从iIndex(包括)开始全部移除
+>>>>>>> bc0f5d2858a5b09273a8d6ed5620a4deb05293b2
             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;
+                    pre.setNextSibling(next);
+                    //pre.nextSibling = next;
                 }
                 if (next) {
                     next.preSibling = pre;
@@ -82,7 +88,11 @@ var idTree = {
                     children.splice(iIndex, children.length - iIndex);
                 }
             },
+<<<<<<< HEAD
             // ��nodes������addNodes, λ�ô�index��ʼ
+=======
+            // 在parent.children/tree.roots中增加nodes, 位置从index开始
+>>>>>>> bc0f5d2858a5b09273a8d6ed5620a4deb05293b2
             addNodes: function (tree, parent, nodes, iIndex) {
                 var children = parent ? parent.children : tree.roots;
                 var pre, next, i;
@@ -95,20 +105,20 @@ var idTree = {
                     next = null;
                 }
                 if (pre) {
-                    pre.nextSibling = nodes[0];
+                    pre.setNextSibling(nodes[0]);
                 }
                 nodes[0].preSibling = pre;
                 if (next) {
                     next.preSibling = nodes[nodes.length - 1];
                 }
-                nodes[nodes.length - 1].nextSibling = next;
+                nodes[nodes.length - 1].setNextSibling(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 ? parent : null;
+                    nodes[i].setParent(parent ? parent : null);
                 }
             },
             sortTreeItems: function (tree) {
@@ -135,7 +145,11 @@ var idTree = {
         };
 
         var Node = function (tree, data) {
+<<<<<<< HEAD
             // ���µ����ԣ�����Ԫ�������ֱ���޸�
+=======
+            // 以下的属性,本单元外均不可直接修改
+>>>>>>> bc0f5d2858a5b09273a8d6ed5620a4deb05293b2
             this.tree = tree;
             this.data = data;
             this.children = [];
@@ -148,9 +162,6 @@ var idTree = {
             this.visible = true;
 
             this.visible = true;
-
-            this.jobs = [];
-            this.items = [];
         };
 
         Node.prototype.getID = function () {
@@ -163,6 +174,19 @@ var idTree = {
             return this.nextSibling ? this.nextSibling.getID() : -1;
         };
 
+        Node.prototype.setParent = function (parent) {
+            this.parent = parent;
+            if (this.tree.setting.autoUpdate) {
+                this.data[this.tree.setting.pid] = this.getParentID();
+            }
+        };
+        Node.prototype.setNextSibling = function (nextSibling) {
+            this.nextSibling = nextSibling;
+            if (this.tree.setting.autoUpdate) {
+                this.data[this.tree.setting.nid] = this.getNextSiblingID();
+            }
+        }
+
         Node.prototype.firstChild = function () {
             return this.children.length === 0 ? null : this.children[0];
         };
@@ -323,12 +347,12 @@ var idTree = {
             var iIndex = this.siblingIndex(), belongArray = this.parent ? this.parent.children : this.tree.roots, orgPre = this.preSibling;
             if (this.canUpMove()) {
                 if (orgPre.preSibling) {
-                    orgPre.preSibling.nextSibling = this;
+                    orgPre.preSibling.setNextSibling(this);
                 }
-                orgPre.nextSibling = this.nextSibling;
+                orgPre.seNextSibling(this.nextSibling);
                 this.preSibling = orgPre.preSibling;
                 orgPre.preSibling = this;
-                this.nextSibling = orgPre;
+                this.setNextSibling(orgPre);
                 belongArray.splice(iIndex, 1);
                 belongArray.splice(iIndex - 1, 0, this);
                 tools.sortTreeItems(this.tree);
@@ -356,11 +380,11 @@ var idTree = {
             var iIndex = this.siblingIndex(), belongArray = this.parent ? this.parent.children : this.tree.roots, orgNext = this.nextSibling;
             if (this.canDownMove()) {
                 if (this.preSibling) {
-                    this.preSibling.nextSibling = orgNext;
+                    this.preSibling.setNextSibling(orgNext);
                 }
                 orgNext.preSibling = this.preSibling;
-                this.nextSibling = orgNext.nextSibling;
-                orgNext.nextSibling = this;
+                this.setNextSibling(orgNext.nextSibling);
+                orgNext.setNextSibling(this);
                 this.preSibling = orgNext;
                 belongArray.splice(iIndex, 1);
                 belongArray.splice(iIndex + 1, 0, this);
@@ -515,6 +539,25 @@ var idTree = {
             }
             return data;
         };
+        Tree.prototype.insertByData = function (data, parentID, nextSiblingID) {
+            var parent = parentID === -1 ? null : this.nodes[this.prefix + parentID];
+            var nextSibling = nextSiblingID === -1 ? null : this.nodes[this.prefix + nextSiblingID];
+            var node = this.nodes[this.prefix + data[this.setting.id]];
+            if (node) {
+                return node;
+            } else {
+                node = new Node(this, data);
+                if (nextSibling) {
+                    tools.addNodes(this, parent, [node], nextSibling.siblingIndex());
+                } else {
+                    tools.addNodes(this, parent, [node]);
+                }
+                this.nodes[this.prefix +  data[this.setting.id]] = node;
+                tools.sortTreeItems(this);
+                this.maxNodeID( data[this.setting.id]);
+                return node;
+            }
+        };
 
         Tree.prototype.delete = function (node) {
             var success = false, that = this;
@@ -528,7 +571,7 @@ var idTree = {
                 deleteIdIndex([node]);
                 //delete this.nodes[this.prefix + node.getID()];
                 if (node.preSibling) {
-                    node.preSibling.nextSibling = node.nextSibling;
+                    node.preSibling.setNextSibling(node.nextSibling);
                 }
                 if (node.nextSibling) {
                     node.nextSibling.preSibling = node.preSibling;

+ 14 - 9
public/web/scMathUtil.js

@@ -5,18 +5,17 @@
 var scMathUtil = {
     innerRoundTo: function(num, digit){
         var lFactor = Math.pow(10, digit);
-        var fOffSet;
-        if (num > 0){
-            fOffSet = 0.5;
+        var fOffSet = 0.5;
+        var sign = '';
+        if (num < 0){
+            sign = '-';
+            num = Math.abs(num);
         }
-        else{
-            fOffSet = -0.5;
-        };
         var result = Math.floor((num / lFactor) + fOffSet).toString();
         var iLength = result.length;
         var r1 = result.substring(0, iLength + digit);
         var r2 = result.substring(iLength + digit, iLength);
-        return Number(r1 + '.' + r2);
+        return Number(sign + r1 + '.' + r2);
     },
     floatToBin: function(num) {
         return num.toString(2);
@@ -24,6 +23,12 @@ var scMathUtil = {
     binToFloat: function(bin) {
         var result = 0;
         var iLength = bin.length;
+        var sign = '';
+        if (iLength > 0 && bin[0]==='-'){
+            sign = '-';
+            bin = bin.substring(1, iLength);
+        }
+        iLength = bin.length;
         var iDot = bin.indexOf('.');
         if (iDot >= 0) {
             for (var i = 0; i < iLength; i++) {
@@ -42,7 +47,7 @@ var scMathUtil = {
         else {
             result = parseInt(bin, 2);
         };
-        return result;
+        return sign + result;
     },
     incMantissa: function(bin){
         var result = bin;
@@ -66,4 +71,4 @@ var scMathUtil = {
         var me = this;
         return me.innerRoundTo(me.binToFloat(me.incMantissa(me.floatToBin(num))), digit);
     }
-}
+};

+ 2 - 12
public/web/tree_sheet_controller.js

@@ -18,18 +18,8 @@ var TREE_SHEET_CONTROLLER = {
             var that = this;
             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)));
+                that.setTreeSelected(that.tree.items[info.newSelections[0].row]);
             });
-
-            /*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 () {
@@ -57,7 +47,7 @@ var TREE_SHEET_CONTROLLER = {
                 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)));
+                        that.setTreeSelected(that.tree.items[sels[0].row]);
                     });
                 }
             }

+ 7 - 9
public/web/tree_sheet_helper.js

@@ -94,13 +94,11 @@ var TREE_SHEET_HELPER = {
                     }
                     return data;
                 };
-                cell.value(getFieldText2());
-                /*if (node.data[colSetting.data.field]) {
-                    cell.value(node.data[colSetting.data.field]);
+                if (colSetting.data.getText) {
+                    cell.value(colSetting.data.getText(node));
                 } else {
-                    cell.text('');
-                }*/
-                sheet.setTag(iRow, iCol, node.getID());
+                    cell.value(getFieldText2());
+                }
             });
             if (recursive) {
                 TREE_SHEET_HELPER.refreshTreeNodeData(setting, sheet, node.children, recursive);
@@ -165,7 +163,7 @@ var TREE_SHEET_HELPER = {
                     }
                 }
             }
-            var node = tree.findNode(options.sheet.getTag(options.row, options.col, options.SheetArea));
+            var node = tree.items[options.row];
             var showTreeLine = true;
 
             if (!node) { return; }
@@ -225,7 +223,7 @@ var TREE_SHEET_HELPER = {
         }
         TreeNodeCellType.prototype.processMouseDown = function (hitinfo) {
             var offset = -1;
-            var node = tree.findNode(hitinfo.sheet.getTag(hitinfo.row, hitinfo.col, hitinfo.sheetArea));
+            var node = tree.items[hitinfo.row];
             tree.selected = node;
             if (!node || node.children.length === 0) { return; }
             var centerX = hitinfo.cellRect.x + offset + node.depth() * indent + indent / 2;
@@ -236,7 +234,7 @@ var TREE_SHEET_HELPER = {
                 TREE_SHEET_HELPER.massOperationSheet(hitinfo.sheet, function () {
                     var iCount = node.posterityCount(), i, child;
                     for (i = 0; i < iCount; i++) {
-                        child = tree.findNode(hitinfo.sheet.getTag(hitinfo.row + i + 1, hitinfo.col, hitinfo.sheetArea));
+                        child = tree.items[hitinfo.row + i + 1];
                         hitinfo.sheet.setRowVisible(hitinfo.row + i + 1, child.visible, hitinfo.sheetArea);
                         //hitinfo.sheet.setRowVisible(hitinfo.row + i + 1, child.vis(), hitinfo.sheetArea);
                     }

+ 61 - 22
server.js

@@ -11,6 +11,8 @@ var path = require('path');
 var session = require('express-session');
 var DBStore = require('connect-mongo')(session);
 
+var URL = require('url')
+
 var app = express();
 var _rootDir = __dirname;
 app.use(express.static(_rootDir));
@@ -37,10 +39,11 @@ app.use(session({
 }));
 
 app.use(function (req, res, next) {
-    var url = req.originalUrl;
+    var url = req.originalUrl, referer;
     if (!/^\/login/.test(req.originalUrl) && !req.session.userAccount) {
-        if (req.headers.referer) {
-            return res.redirect('/login' + '?referer=' + req.headers.referer);
+        if (/\/api/.test(req.originalUrl)) {
+            referer = URL.parse(req.headers.referer);
+            return res.redirect('/login' + '?referer=' + referer.path);
         } else {
             return res.redirect("/login" + '?referer=' + req.originalUrl);
         }
@@ -52,39 +55,62 @@ app.use('/', require('./modules/users/routes/users_route'));
 app.use('/fees', require('./modules/fees/routes/fees_router'));
 
 app.get('/template/bills', function (req, res) {
-    res.render('templates/html/bills.html',
-        {userAccount: req.session.userAccount,
-            userID: req.session.userID});
+    var checkAdmin = function (userAccount) {
+        return true;
+    }
+    if (checkAdmin(req.session.userAccount)) {
+        res.render('templates/html/bills.html',
+            {userAccount: req.session.userAccount,
+                userID: req.session.userID});
+    } else {
+        res.redirect('/pm');
+    }
+});
+
+app.use('/template/bills/api', function (req, res, next) {
+    var checkAdmin = function (userAccount) {
+        return true;
+    }
+    if (checkAdmin(req.session.userAccount)) {
+        next();
+    } else {
+        res.json({error: 1, message: '对不起,您无权限操作清单模板。', data: null});
+    }
 });
 var billsTemplateRouter = require('./modules/templates/routes/bills_template_router');
-app.use('/template/bills', billsTemplateRouter);
+app.use('/template/bills/api', billsTemplateRouter);
 
 app.get('/pm', function(req, res){
     res.render('pm/html/project-management.html',
         {userAccount: req.session.userAccount,
             userID: req.session.userID});
 });
-
 var pmRouter = require('./modules/pm/routes/pm_route');
-app.use('/', pmRouter);
+app.use('/pm/api', pmRouter);
 
 app.get('/main',  function(req, res) {
-    if (!req.session.userAccount) {
-        res.redirect('/login');
+    var checkProjectRight = function (userID, projectID) {
+        return true;
     }
-    else {
+    if (checkProjectRight(req.session.userID, req.query.project)) {
         res.render('main/html/main.html',
             {
                 userAccount: req.session.userAccount,
                 userID: req.session.userID
             });
+    } else {
+        res.redirect('/pm');
     }
 });
 
+var project_Router = require('./modules/main/routes/project_route');
 var bills_Router = require('./modules/main/routes/bills_route');
-var rations_Router = require('./modules/main/routes/rations_route');
+var ration_Router = require('./modules/main/routes/ration_route');
+var GLJ_Router = require('./modules/main/routes/GLJ_route');
+app.use('/project', project_Router);
 app.use('/bills', bills_Router);
-app.use('/rations', rations_Router);
+app.use('/ration', ration_Router);
+app.use('/glj', GLJ_Router);
 
 var rpt_Router = require("./modules/reports/routes/report_router");
 app.get('/report',  function(req, res) {
@@ -99,14 +125,27 @@ app.get('/report',  function(req, res) {
 });
 app.use("/report_api", rpt_Router);
 
-//zhangenping add 2017.0.13-----------------------------------------begin
-app.use(express.static(_rootDir+"/web"));
-app.use(express.static(_rootDir+"/lib"));
-var rations_Router = require("./modules/rationLibEditor/routes/rationLibEditor_route");
-app.use("/rationLibEditor",rations_Router);
-//-----------------------------------------------------------------end
-//----------------
-
+//app.use(express.static(_rootDir+"/web"));
+//app.use(express.static(_rootDir+"/lib"));
+//var rations_Router = require("./modules/rationLibEditor/routes/rationLibEditor_route");
+//app.use("/rationLibEditor",rations_Router);
+
+var rationRepository_Router = require("./modules/rationRepository/routes/rationRepRoutes");
+app.get('/rationRepository/main', function(req, res) {
+    res.render('rationLibEditor/main.html',
+        {
+            userAccount: req.session.userAccount,
+            userID: req.session.userID
+        });
+});
+app.get('/rationRepository/ration', function(req, res) {
+    res.render('rationLibEditor/dinge.html',
+        {
+            userAccount: req.session.userAccount,
+            userID: req.session.userID
+        });
+});
+app.use("/rationRepository/api",rationRepository_Router);
 
 app.get("/stdBillsmain", function(req, res){
     if(!req.session.userAccount){

+ 6 - 23
test/tmp_data/bills_grid_setting.js

@@ -5,7 +5,7 @@ var BillsGridSetting = {
     cols: [
         {
             head: {
-                titleNames: ['编号'],
+                titleNames: ['项目编码'],
                 spanCols: [1],
                 spanRows: [2],
                 vAlign: [1, 1],
@@ -13,33 +13,16 @@ var BillsGridSetting = {
                 font: '9px Arial'
             },
             data: {
-                field: 'Code',
+                field: 'code',
                 vAlign: 1,
                 hAlign: 0,
                 font: '9px Arial'
             },
-            width: 150
-        },
-        {
-            head: {
-                titleNames: ['清单编号'],
-                spanCols: [1],
-                spanRows: [2],
-                vAlign: [1, 1],
-                hAlign: [1, 1],
-                font: '9px Arial'
-            },
-            data: {
-                field: 'B_Code',
-                vAlign: 1,
-                hAlign: 0,
-                font: '9px Arial'
-            },
-            width: 100
+            width: 200
         },
         {
             head: {
-                titleNames: ['名称'],
+                titleNames: ['项目名称'],
                 spanCols: [1],
                 spanRows: [2],
                 vAlign: [1, 1],
@@ -47,7 +30,7 @@ var BillsGridSetting = {
                 font: '9px Arial'
             },
             data: {
-                field: 'Name',
+                field: 'name',
                 vAlign: 1,
                 hAlign: 0,
                 font: '9px Arial'
@@ -64,7 +47,7 @@ var BillsGridSetting = {
                 font: '9px Arial'
             },
             data: {
-                field: 'Units',
+                field: 'unit',
                 vAlign: 1,
                 hAlign: 1,
                 font: '9px Arial'

Файловите разлики са ограничени, защото са твърде много
+ 46 - 0
test/tmp_data/test_project_1.js


+ 37 - 0
test/unit/public/testBatchInsertDocs.js

@@ -0,0 +1,37 @@
+/**
+ * Created by Tony on 2017/4/24.
+ */
+
+var test = require('tape');
+var mongoose = require('mongoose');
+var dbm = require("../../../config/db/db_manager");
+var testdb = dbm.getLocalConnection("Demo");
+var Schema = mongoose.Schema;
+//testBatchInsert
+var BatchInsertSchema = new Schema({
+    "ID": Number,
+    "dispName" : String
+});
+
+var testModel = testdb.model("testBatchInsert", BatchInsertSchema, "testBatchInsert");
+
+test('test batch insert docs', function(t){
+    var arr = [];
+    arr.push(new testModel({ID: 1, dispName: "name1"}));
+    arr.push(new testModel({ID: 2, dispName: "name2"}));
+    arr.push(new testModel({ID: 3, dispName: "name3"}));
+    testModel.collection.insert(arr, null, function(err, docs){
+        if (err) {
+            t.pass('pass with error');
+        } else {
+            t.pass('pass with: ' + docs.insertedCount + ' records were inserted!');
+        }
+        t.end();
+    })
+});
+
+test('finish', function (t) {
+    mongoose.disconnect();
+    t.pass('closing db connection');
+    t.end();
+});

+ 11 - 0
test/unit/public/testPinYin.js

@@ -0,0 +1,11 @@
+/**
+ * Created by Tony on 2017/4/20.
+ */
+var test = require('tape');
+var stringUtil = require('../../../public/stringUtil');
+
+test('测试汉字转拼音', function(t){
+    t.equal(stringUtil.getPinYinFullChars("重庆市建筑工程"), "ZONGHENGKEJI——123");
+    t.equal(stringUtil.getPinYinCamelChars("纵横科技"), "ZHKJ");
+    t.end();
+})

+ 1 - 1
test/unit/public/testScMath.js

@@ -5,6 +5,6 @@ var test = require('tape');
 var scMathUtil = require('../../../public/scMathUtil').getUtil();
 
 test('test smartcost math util for rounding', function(t){
-    t.equal(scMathUtil.roundTo(3.12345, -2), 3.12);
+    t.equal(scMathUtil.roundTo(-3.12345, -2), -3.12);
     t.end();
 })

+ 2 - 0
web/billsLib/scripts/dbController.js

@@ -237,6 +237,7 @@ var createObj = {
             });
             if(nodes){
                 nodes.forEach(function(node){
+                    tools.addAttr(node.jobs);
                     node.data.jobs.forEach(function(jobId){
                         if(me.jobs[me.prefix + jobId]){
                             node.jobs.push(me.jobs[me.prefix + jobId]);
@@ -293,6 +294,7 @@ var createObj = {
             });
             if(nodes){
                 nodes.forEach(function(node){
+                    tools.addAttr(node.items);
                     node.data.items.forEach(function(itemID){
                         if(me.items[me.prefix + itemID]){
                             node.items.push(me.items[me.prefix + itemID]);

+ 1 - 1
web/fees/feeRate.html

@@ -48,7 +48,7 @@
                 <span class="btn btn-link btn-sm new-msg">
                   <i class="fa fa-envelope-o" aria-hidden="true"></i>&nbsp;2
                 </span>
-                <button class="btn btn-link btn-sm">注销</button>
+                <button class="btn btn-link btn-sm" id="logout">注销</button>
             </div>
         </nav>
         <nav class="navbar navbar-toggleable-lg justify-content-between navbar-light p-0">

+ 11 - 5
web/fees/feeRate.js

@@ -1,4 +1,4 @@
-/**
+/**
  * Created by CSL on 2017-03-23.
  */
 var region = '重庆';
@@ -15,6 +15,10 @@ $(document).ready(function () {
     $("#projectFeeFile").click(function () {
         loadProjectFeeRates(feeRateFileID);
     });
+
+    $("#logout").click(function () {
+        location.href = '/logout';
+    });
 });
 
 function loadProjectFeeRates(fileID) {
@@ -75,10 +79,6 @@ function loadLibFeeRates(libID) {
 
 function createSpreadView(canEdit) {
     // 创建前先销毁旧树表。
-    //$('#divFee').empty();  // 清空不行,浏览器跟踪显示错误数狂飚:TypeError: G is null
-    //$('#divFee').remove(); // 删除可以,但是太山寨。
-    //$('#content').append($('<div class="grid" id="divFee"></div>'));
-    // 以下找到官方的处理方法,比较面向对象
     if (spreadView) {
         spreadView.destroy();
         spreadView = null;
@@ -173,8 +173,14 @@ function createSpreadView(canEdit) {
         }
     };
 
+    function rowClickFun(sender, args) {
+        alert(args.item.dataItem.rate);
+    }
+
     spreadView = new GC.Spread.Views.DataView($('#divFee')[0],
         dataSource, columns, new GC.Spread.Views.Plugins.GridLayout(options));
+ 
+    spreadView["rowDbClick"].addHandler(rowClickFun);
     spreadView.invalidate();
     document.querySelector('#divFee').focus();
 }

+ 35 - 6
web/main/html/main.html

@@ -517,10 +517,11 @@
     <script type="text/javascript" src="lib/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js"></script>
     <script>GC.Spread.Sheets.LicenseKey = "559432293813965#A0y3iTOzEDOzkjMyMDN9UTNiojIklkI1pjIEJCLi4TPB9mM5AFNTd4cvZ7SaJUVy3CWKtWYXx4VVhjMpp7dYNGdx2ia9sEVlZGOTh7NRlTUwkWR9wEV4gmbjBDZ4ElR8N7cGdHVvEWVBtCOwIGW0ZmeYVWVr3mI0IyUiwCMzETN8kzNzYTM0IicfJye&Qf35VfiEzRwEkI0IyQiwiIwEjL6ByUKBCZhVmcwNlI0IiTis7W0ICZyBlIsIyNyMzM5ADI5ADNwcTMwIjI0ICdyNkIsIibj9SbvNmL4N7bjRnch56ciojIz5GRiwiI8+Y9sWY9QmZ0Jyp96uL9v6L0wap9biY9qiq95q197Wr9g+89iojIh94Wiqi";</script>
     <!-- Model -->
+    <script type="text/javascript" src="web/main/js/models/mainConsts.js"></script>
     <script type="text/javascript" src="web/main/js/models/project.js"></script>
     <script type="text/javascript" src="web/main/js/models/bills.js"></script>
-    <script type="text/javascript" src="web/main/js/models/rations.js"></script>
-    <script type="text/javascript" src="web/main/js/models/gljs.js"></script>
+    <script type="text/javascript" src="web/main/js/models/ration.js"></script>
+    <script type="text/javascript" src="web/main/js/models/glj.js"></script>
 
     <script type="text/javascript" src="public/web/idTree.js"></script>
     <script type="text/javascript" src="web/main/js/models/cache_tree.js"></script>
@@ -529,11 +530,11 @@
     <script type="text/javascript" src="public/web/tree_sheet_helper.js"></script>
     <!-- Test Data -->
     <script type="text/javascript" src="test/tmp_data/bills_grid_setting.js"></script>
-    <script type="text/javascript" src="test/tmp_data/data_15690.js"></script>
-    <script type="text/javascript" src="test/tmp_data/drawing_data_10268.js"></script>
     <!-- view -->
     <script type="text/javascript" src="web/main/js/main_ajax.js"></script>
     <script type="text/javascript" src="web/main/js/main.js"></script>
+    <script type="text/javascript" src="/public/web/common_ajax.js"></script>
+    <script type="text/javascript" src="/public/web/urlUtil.js"></script>
     <SCRIPT type="text/javascript">
   		<!--
   		var setting = {
@@ -615,7 +616,7 @@
         billsSpread.options.scrollbarMaxAlign = true;
 
         // For Test
-        datas.forEach(function (data) {
+        /*datas.forEach(function (data) {
             data.fees = [];
             data.fees.push({fieldName: 'labour', unitFee: '1', totalFee: '2', tenderUnitFee: '3', tenderTotalFee: '4'});
             data.flags = [];
@@ -626,8 +627,9 @@
             data.fees.push({fieldName: 'machine', unitFee: '5', totalFee: '6', tenderUnitFee: '7', tenderTotalFee: '8'});
             data.flags = [];
             data.flags.push({fieldName: 'isPartGather', flag: false});
-        });
+        });*/
 
+<<<<<<< HEAD
         project = PROJECT.createInit();
         project.Bills.loadDatas(datas);
         project.Rations.loadDatas(drawing_data);
@@ -650,6 +652,33 @@
             showButton(tree.selected && tree.selected.canUpMove(), $('#upMove'));
             showButton(tree.selected && tree.selected.canDownMove(), $('#downMove'));
             showButton(tree.selected ? true : false, $('#delete'));
+=======
+        project = PROJECT.createNew();
+        CommonAjax.post('/bills/getData', {projectId: scUrlUtil.GetQueryString('project')}, function (bills) {
+            project.Bills.loadDatas(bills);
+            project.Ration.loadDatas([]);
+            //project.Rations.loadDatas(drawing_data);
+            project.loadMainTree();
+
+            controller = TREE_SHEET_CONTROLLER.createNew(project.mainTree, billsSpread.getActiveSheet(), BillsGridSetting);
+            //controller = TREE_SHEET_CONTROLLER.createNew(project.Bills.tree, billsSpread.getActiveSheet(), BillsGridSetting);
+
+            controller.showTreeData();
+            controller.bind('refreshBaseActn', function (tree) {
+                var showButton = function (show, btn) {
+                    if (show) {
+                        btn.show();
+                    } else {
+                        btn.hide();
+                    }
+                };
+                showButton(tree.selected && tree.selected.canUpLevel(), $('#upLevel'));
+                showButton(tree.selected && tree.selected.canDownLevel(), $('#downLevel'));
+                showButton(tree.selected && tree.selected.canUpMove(), $('#upMove'));
+                showButton(tree.selected && tree.selected.canDownMove(), $('#downMove'));
+                showButton(tree.selected ? true : false, $('#delete'));
+            });
+>>>>>>> bc0f5d2858a5b09273a8d6ed5620a4deb05293b2
         });
 
         $('#insert').click(function () {

+ 1 - 1
web/main/js/main_ajax.js

@@ -28,7 +28,7 @@ var PullData = function (url, data, successCallback, errorCallback) {
 var GetProject = function (proj_id, callback) {
     $.ajax({
         type:"POST",
-        url: '/getProject',
+        url: '/pm/api/getProject',
         data: {'data': JSON.stringify({"user_id": userID, "proj_id": proj_id})},
         dataType: 'json',
         cache: false,

+ 49 - 7
web/main/js/models/bills.js

@@ -11,39 +11,81 @@ var Bills = {
             rootId: -1
         };
 
+<<<<<<< HEAD
         // �û�����private����
         var tools = {};
 
         // ����ͨ��this���ʵ����ԣ�����Ӧ�ڴ˵�Ԫ�ⲿ����д�����
+=======
+        // 用户定义private方法
+        var tools = {};
+
+        // 所有通过this访问的属性,都不应在此单元外部进行写入操作
+>>>>>>> bc0f5d2858a5b09273a8d6ed5620a4deb05293b2
         var bills = function (proj) {
             this.project = proj;
             this.datas = null;
             this.tree = idTree.createInit(billsTreeSetting);
 
-            var sourceType = 'bills';
+            var sourceType = ModuleNames.bills;
             this.getSourceType = function () {
                 return sourceType;
             }
+            proj.registerModule(ModuleNames.bills, this);
         };
 
+<<<<<<< HEAD
         // prototype���ڶ���public����
         bills.prototype.loadDatas = function (datas) {
             this.datas = datas;
             // generate Fees & Flags Index��For View & Calculate
+=======
+        // 从后台获取数据
+        bills.prototype.pullData = function (){
+            this.project.pullData(
+                '/bills/getData',
+                {projectID: this.project.ID},
+                function(result){
+                    if (result.error ===0){
+                        this.loadDatas(result.data);
+                    }
+                    else {
+                        // to do: ?错误处理需要细化
+                        alert(result.message);
+                    }
+                },
+                function (){/* to do: 错误处理需要细化*/}
+            )
+        };
+
+        // prototype用于定义public方法
+        bills.prototype.loadDatas = function (datas) {
+            this.datas = datas;
+            // generate Fees & Flags Index, For View & Calculate
+>>>>>>> bc0f5d2858a5b09273a8d6ed5620a4deb05293b2
             this.datas.forEach(function (data) {
                 data.FeesIndex = {};
-                data.fees.forEach(function (fee) {
-                    data.FeesIndex[fee.fieldName] = fee;
-                });
+                if (data.fees) {
+                    data.fees.forEach(function (fee) {
+                        data.FeesIndex[fee.fieldName] = fee;
+                    });
+                }
                 data.FlagsIndex = {};
-                data.flags.forEach(function (flag) {
-                    data.FlagsIndex[flag.fieldName] = flag;
-                });
+                if (data.flags) {
+                    data.flags.forEach(function (flag) {
+                        data.FlagsIndex[flag.fieldName] = flag;
+                    });
+                }
             });
             // datas load to Tree
             this.tree.loadDatas(this.datas);
         };
 
+        // 提交数据后的错误处理方法
+        bills.prototype.doAfterUpdate = function(err, data){
+            // to do
+        };
+
         return new bills(project);
     }
 };

+ 49 - 0
web/main/js/models/glj.js

@@ -0,0 +1,49 @@
+/**
+ * Created by Mai on 2017/4/1.
+ */
+var GLJ = {
+    createNew: function (project) {
+        // 用户定义private方法
+        var tools = {};
+
+        // 所有通过this访问的属性,都不应在此单元外部进行写入操作
+        var glj = function (proj) {
+            this.project = proj;
+            this.datas = null;
+
+            var sourceType = ModuleNames.GLJ;
+            this.getSourceType = function () {
+                return sourceType;
+            }
+            proj.registerModule(ModuleNames.GLJ, this);
+        };
+
+        // 从后台获取数据
+        glj.prototype.pullData = function (){
+            this.project.pullData(
+                '/glj/getData',
+                {projectID: this.project.ID},
+                function(result){
+                    if (result.error ===0){
+                        this.loadDatas(result.data);
+                    }
+                    else {
+                        // to do: 错误处理需要细化
+                        alert(result.message);
+                    }
+                },
+                function (){/* to do: 错误处理需要细化*/}
+            )
+        };
+        // prototype用于定义public方法
+        glj.prototype.loadDatas = function (datas) {
+            this.datas = datas;
+        };
+
+        // 提交数据后的错误处理方法
+        glj.prototype.doAfterUpdate = function(err, data){
+            // to do
+        };
+        return new glj(project);
+    }
+};

+ 0 - 27
web/main/js/models/gljs.js

@@ -1,27 +0,0 @@
-/**
- * Created by Mai on 2017/4/1.
- */
-var GLJs = {
-    createNew: function (project) {
-        // 用户定义private方法
-        var tools = {};
-
-        // 所有通过this访问的属性,都不应在此单元外部进行写入操作
-        var gljs = function (proj) {
-            this.project = proj;
-            this.datas = null;
-
-            var sourceType = 'glj';
-            this.getSourceType = function () {
-                return sourceType;
-            }
-        };
-
-        // prototype用于定义public方法
-        gljs.prototype.loadDatas = function (datas) {
-            this.datas = datas;
-        };
-
-        return new gljs(project);
-    }
-};

+ 9 - 0
web/main/js/models/mainConsts.js

@@ -0,0 +1,9 @@
+/**
+ * Created by jimiz on 2017/4/19.
+ */
+const ModuleNames = {
+    bills: 'bills',
+    ration: 'ration',
+    GLJ: 'GLJ',
+    projectGLJ: 'projectGLJ'
+};

+ 127 - 3
web/main/js/models/project.js

@@ -2,27 +2,65 @@
  * Created by Mai on 2017/4/1.
  */
 var PROJECT = {
+<<<<<<< HEAD
     createNew: function () {
         // ����private����
         var tools = {};
 
         // ����ͨ��this���ʵ����ԣ�����Ӧ�ڴ˵�Ԫ�ⲿ����д�����
+=======
+    createNew: function (projectID, userID) {
+        // 定义private方法
+        var tools = {
+            _ID: projectID,
+            _userID: userID,
+            updateLock: 0,
+            updateData: [],
+            operation: '',
+            modules: {},
+
+            doAfterUpdate: function(result){
+                result.forEach(function(item){
+                    if (item.moduleName in this.modules){
+                        this.modules[item.moduleName].doAfterUpdate(item.err, item.data);
+                    }
+                });
+            }
+        };
+
+        // 所有通过this访问的属性,都不应在此单元外部进行写入操作
+>>>>>>> bc0f5d2858a5b09273a8d6ed5620a4deb05293b2
         var project = function () {
             this.mainTree = cacheTree.createInit(this);
 
+<<<<<<< HEAD
             this.Bills = Bills.createInit(this);
             this.Rations = Rations.createInit(this);
             this.GLJs = GLJs.createInit(this);
+=======
+            this.Bills = Bills.createNew(this);
+            this.Ration = Ration.createNew(this);
+            this.GLJ = GLJ.createNew(this);
+>>>>>>> bc0f5d2858a5b09273a8d6ed5620a4deb05293b2
 
 
             this.masterField = {ration: 'BillsID'};
         };
 
+<<<<<<< HEAD
         // prototype���ڶ���public����
+=======
+        // prototype用于定义public方法
+>>>>>>> bc0f5d2858a5b09273a8d6ed5620a4deb05293b2
         project.prototype.modify = function (modifyDatas, callback) {
             // To Do
         };
 
+        // prototype用于定义public方法
+        project.prototype.ID = function () {
+            return tools._ID;
+        };
+
         project.prototype.loadMainTree = function () {
             var that = this;
             var loadRationNode = function (rations, cacheNode) {
@@ -31,7 +69,7 @@ var PROJECT = {
                     if (ration[that.masterField.ration] && ration[that.masterField.ration] === cacheNode.source.getID()) {
                         newNode = that.mainTree.addNode(cacheNode);
                         newNode.source = ration;
-                        newNode.sourceType = that.Rations.getSourceType();
+                        newNode.sourceType = that.Ration.getSourceType();
                         newNode.data = ration;
                     }
                 });
@@ -45,7 +83,7 @@ var PROJECT = {
                     newNode.data = nodes[i].data;
 
                     if (nodes[i].children.length === 0) {
-                        loadRationNode(that.Rations.datas, newNode);
+                        loadRationNode(that.Ration.datas, newNode);
                     } else {
                         loadIdTreeNode(nodes[i].children, newNode);
                     }
@@ -53,7 +91,93 @@ var PROJECT = {
             };
             loadIdTreeNode(this.Bills.tree.roots, null);
             this.mainTree.sortTreeItems();
-        }
+        };
+
+        // 提供给各模块调用的统一从后台获取数据的方法
+        project.prototype.pullData = function (url, data, successCallback, errorCallback) {
+            $.ajax({
+                type:"POST",
+                url: url,
+                data: {'data': JSON.stringify(data)},
+                dataType: 'json',
+                cache: false,
+                timeout: 50000,
+                success: function(result){
+                    successCallback(result);
+                },
+                error: function(jqXHR, textStatus, errorThrown){
+                    alert('error ' + textStatus + " " + errorThrown);
+                    errorCallback();
+                }
+            });
+        };
+
+        // 所有模块在此从后台获取数据
+        project.prototype.loadDatas = function (){
+            this.Bills.pullData();
+            this.Ration.pullData();
+            this.GLJ.pullData();
+
+        };
+
+        project.prototype.beginUpdate = function(operation){
+            if (tools.updateLock === 0){
+                tools.operation = operation
+            }
+            tools.updateLock += 1;
+        };
+
+        project.prototype.endUpdate = function(){
+            if (tools.updateLock === 0){
+                throw "project can not endUpdate before beginUpdate";
+            }
+            tools.updateLock -= 1;
+            if (tools.updateLock === 0) {
+                $.ajax({
+                    type: "POST",
+                    url: '/project/save',
+                    data: {'data': JSON.stringify({
+                        "project_id": tools._ID,
+                        "user_id": tools._userID,
+                        "date": new Date,
+                        "operation": tools.operation,
+                        "update_data": tools.updateData
+                    })},
+                    dataType: 'json',
+                    cache: false,
+                    timeout: 50000,
+                    success: function (result) {
+                        if (result.error === 0) {
+                            tools.doAfterUpdate(result.data);
+                        } else {
+                            alert('error: ' + result.message);
+                        }
+                    },
+                    error: function(jqXHR, textStatus, errorThrown){
+                        alert('error ' + textStatus + " " + errorThrown);
+                    }
+                });
+                tools.updateData = [];
+                tools.operation = "";
+            }
+        };
+
+        project.prototype.push = function(moduleName, data){
+            if (tools.updateLock === 0){
+                throw "project can not push data before beginUpdate";
+            };
+            var moduleData = {
+                moduleName: moduleName,
+                data: data
+            };
+            tools.updateData.push(moduleData);
+        };
+
+        project.prototype.registerModule = function(moduleName, obj){
+            if (!tools.modules.hasOwnProperty(moduleName)){
+                tools.modules[moduleName] = obj;
+            }
+        };
 
         return new project();
     }

+ 62 - 0
web/main/js/models/ration.js

@@ -0,0 +1,62 @@
+/**
+ * Created by Mai on 2017/4/1.
+ */
+
+var Ration = {
+    createNew: function (project) {
+        // 用户定义private方法
+        var tools = {};
+
+        // 所有通过this访问的属性,都不应在此单元外部进行写入操作
+        var ration = function (proj) {
+            this.project = proj;
+            this.datas = null;
+
+            var sourceType = ModuleNames.ration;
+            this.getSourceType = function () {
+                return sourceType;
+            }
+            proj.registerModule(ModuleNames.ration, this);
+        };
+
+        // 从后台获取数据
+        ration.prototype.pullData = function (){
+            this.project.pullData(
+                '/ration/getData',
+                {projectID: this.project.ID},
+                function(result){
+                    if (result.error ===0){
+                        this.loadDatas(result.data);
+                    }
+                    else {
+                        // to do: 错误处理需要细化
+                        alert(result.message);
+                    }
+                },
+                function (){/* to do: 错误处理需要细化*/}
+            )
+        };
+        // prototype用于定义public方法
+        ration.prototype.loadDatas = function (datas) {
+            this.datas = datas;
+            // generate Fees & Flags Index,For View & Calculate
+            this.datas.forEach(function (data) {
+                data.FeesIndex = {};
+                data.fees.forEach(function (fee) {
+                    data.FeesIndex[fee.fieldName] = fee;
+                });
+                data.FlagsIndex = {};
+                data.flags.forEach(function (flag) {
+                    data.FlagsIndex[flag.fieldName] = flag;
+                });
+            });
+        };
+
+        // 提交数据后的错误处理方法
+        ration.prototype.doAfterUpdate = function(err, data){
+            // to do
+        };
+
+        return new ration(project);
+    }
+};

+ 0 - 39
web/main/js/models/rations.js

@@ -1,39 +0,0 @@
-/**
- * Created by Mai on 2017/4/1.
- */
-
-var Rations = {
-    createNew: function (project) {
-        // 用户定义private方法
-        var tools = {};
-
-        // 所有通过this访问的属性,都不应在此单元外部进行写入操作
-        var rations = function (proj) {
-            this.project = proj;
-            this.datas = null;
-
-            var sourceType = 'ration';
-            this.getSourceType = function () {
-                return sourceType;
-            }
-        };
-
-        // prototype用于定义public方法
-        rations.prototype.loadDatas = function (datas) {
-            this.datas = datas;
-            // generate Fees & Flags Index,For View & Calculate
-            this.datas.forEach(function (data) {
-                data.FeesIndex = {};
-                data.fees.forEach(function (fee) {
-                    data.FeesIndex[fee.fieldName] = fee;
-                });
-                data.FlagsIndex = {};
-                data.flags.forEach(function (flag) {
-                    data.FlagsIndex[flag.fieldName] = flag;
-                });
-            });
-        };
-
-        return new rations(project);
-    }
-};

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

@@ -457,6 +457,7 @@
     <script src="lib/global.js"></script>
     <script src="public/dateUtil.js"></script>
     <script src="web/scripts/tree_table.js"></script>
+    <script type="text/javascript" src="/public/web/common_ajax.js"></script>
     <script src="web/pm/js/pm_ajax.js"></script>
     <script src="web/pm/js/pm_main.js" charset="UTF-8"></script>
     <!-- zTree -->

+ 4 - 6
web/pm/js/pm_ajax.js

@@ -5,7 +5,7 @@
 var GetAllProjectData = function (callback) {
     $.ajax({
         type:"POST",
-        url: '/getProjects',
+        url: '/pm/api/getProjects',
         data: {'data': JSON.stringify({"user_id": userID})},
         dataType: 'json',
         cache: false,
@@ -27,7 +27,7 @@ var GetAllProjectData = function (callback) {
 var UpdateProjectData = function (updateData, callback) {
     $.ajax({
         type:"POST",
-        url: '/updateProjects',
+        url: '/pm/api/updateProjects',
         data: {'data': JSON.stringify({"user_id": userID, "updateData": updateData})},
         dataType: 'json',
         cache: false,
@@ -44,12 +44,11 @@ var UpdateProjectData = function (updateData, callback) {
         }
     });
 };
-
 // 重命名项目
 var RenameProject = function(projId, newName, callback) {
     $.ajax({
         type: "POST",
-        url: '/renameProject',
+        url: '/pm/api/renameProject',
         data: {'data': JSON.stringify({"user_id": userID, "id": projId, "newName": newName})},
         dataType: 'json',
         cache: false,
@@ -66,12 +65,11 @@ var RenameProject = function(projId, newName, callback) {
         }
     });
 };
-
 // 打开项目前,提交数据
 var BeforeOpenProject = function (projId, updateData, callback) {
     $.ajax({
         type: "POST",
-        url: '/beforeOpenProject',
+        url: '/pm/api/beforeOpenProject',
         data: {'data': JSON.stringify({"user_id": userID, "proj_id": projId, "updateData": updateData})},
         dataType: 'json',
         cache: false,

+ 65 - 51
web/pm/js/pm_main.js

@@ -130,13 +130,13 @@ var GetPreNodeUpdateData = function (pre, nid) {
     var data = {};
     data['updateType'] = 'update';
     data['updateData'] = {};
-    data.updateData[setting.tree.id] = pre.id();
-    data.updateData[setting.tree.nid] = nid;
+    data.updateData[Tree.setting.tree.id] = pre.id();
+    data.updateData[Tree.setting.tree.id] = nid;
     return data;
 }
 // 获取新建项目数据
-var GetAddProjUpdateData = function (parent, next, name) {
-    var datas = [], updateData, pre, newId = Tree.maxNodeId() + 1;
+var GetAddProjUpdateData = function (parent, next, name, newId) {
+    var datas = [], updateData, pre;
     updateData = {};
     updateData['updateType'] = 'new';
     updateData['updateData'] = {};
@@ -148,8 +148,8 @@ var GetAddProjUpdateData = function (parent, next, name) {
     datas.push(updateData);
     return datas;
 };
-var GetAddFolderProjUpdateData = function (parent, next, folderName1, folderName2, name) {
-    var datas = [], updateData, folderData1, folderData2, pre, newId = Tree.maxNodeId() + 1;
+var GetAddFolderProjUpdateData = function (parent, next, folderName1, folderName2, name, newId) {
+    var datas = [], updateData, folderData1, folderData2, pre;
     var addUpdateData = function (parentId, nextId, name, projType) {
         var data = {};
         data['updateType'] = 'new';
@@ -169,8 +169,8 @@ var GetAddFolderProjUpdateData = function (parent, next, folderName1, folderName
     return datas;
 };
 // 获取新建文件夹数据
-var GetAddForlderUpdateData = function (parent, next, folderName) {
-    var datas = [], updateData, pre, newId = Tree.maxNodeId() + 1;
+var GetAddForlderUpdateData = function (parent, next, folderName, newId) {
+    var datas = [], updateData, pre;
     updateData = {};
     updateData['updateType'] = 'new';
     updateData['updateData'] = {};
@@ -217,9 +217,8 @@ var GetDeleteUpdateData = function (node) {
             data['updateType'] = 'delete';
             data['updateData'] = {};
             data['updateData'][Tree.setting.tree.id] = node.id();
-            data['updateData']['deleted'] = true;
             if (node.data.projType === 'Tender') {
-                data['updateData']['FullFolder'] = GetfullFolder(node.parent);
+                data['updateData']['FullFolder'] = GetFullFolder(node.parent);
             }
             return data;
         },
@@ -258,12 +257,13 @@ var GetMoveUpdateData = function (node, parent, next) {
     return datas;
 };
 
-var GetCopyUpdateData = function (node, parent, next){
+var GetCopyUpdateData = function (node, parent, next, newId){
     var datas = [], updateData, pre;
     updateData = {};
-    updateData['updateType'] = 'new';
+    updateData['updateType'] = 'copy';
+    updateData['srcProjectId'] = node.id();
     updateData['updateData'] = {};
-    updateData['updateData'][Tree.setting.tree.id] = node.tree.maxNodeId() + 1;
+    updateData['updateData'][Tree.setting.tree.id] = newId + 1;
     updateData['updateData'][Tree.setting.tree.pid] = parent ? parent.id() : -1;
     updateData['updateData'][Tree.setting.tree.nid] = next ? next.id() : -1;
     updateData['updateData']['name'] = node.data.name;
@@ -358,7 +358,7 @@ $('#addFolderBtn').click(function () {
 $('#addFolderOk').click(function () {
     var form = $('#addFolder');
     var name = $('#folder-name-input').val();
-    var updateData, parent, next;
+    var parent, next;
     if (name) {
         if (Tree.selected()) {
             if (Tree.selected().children.length === 0 || Tree.selected().firstChild().data.projType === 'Folder') {
@@ -373,21 +373,24 @@ $('#addFolderOk').click(function () {
             next = Tree.firstNode();
         }
 
-        updateData = GetAddForlderUpdateData(parent, next, name);
-        UpdateProjectData(updateData, function(datas){
-            datas.forEach(function (data) {
-                if (data.updateType === 'new') {
-                    Tree.addNodeData(data.updateData, parent, next);
-                }
+        CommonAjax.post('/pm/api/getNewProjectID', {count: 1}, function (IDs) {
+            var updateData = GetAddForlderUpdateData(parent, next, name, IDs.lowID);
+            Tree.maxNodeId(IDs.lowID - 1);
+            UpdateProjectData(updateData, function(datas){
+                datas.forEach(function (data) {
+                    if (data.updateType === 'new') {
+                        Tree.addNodeData(data.updateData, parent, next);
+                    }
+                });
+                form.modal('hide');
             });
-            form.modal('hide');
         });
     }
 });
 
 // 新建工程
 var AddProj = function () {
-    var name = $('#tenderName').val(), updateData, parent, next;
+    var name = $('#tenderName').val();
     if (name !== '') {
         // if (Tree.selected()){
         //     if (Tree.selected().data.projType === 'Tender') {
@@ -405,34 +408,40 @@ var AddProj = function () {
         //     parent = Tree._root();
         //     next = Tree.firstNode();
         // }
-        updateData = GetAddProjUpdateData(Tree._root, Tree.firstNode(), name);
-        UpdateProjectData(updateData, function (datas) {
-            datas.forEach(function (data) {
-                var parent, next;
-                if (data.updateType === 'new') {
-                    parent = data.updateData.parentId === -1 ?  Tree._root : Tree.findNode(data.updateData.parentId);
-                    next = data.updateData.nextId === -1 ? null : Tree.findNode(data.updateData.nextId);
-                    Tree.addNodeData(data.updateData, parent, next);
-                }
+        CommonAjax.post('/pm/api/getNewProjectID', {count: 1}, function (IDs) {
+            var updateData = GetAddProjUpdateData(Tree._root, Tree.firstNode(), name, IDs.lowID);
+            Tree.maxNodeId(IDs.lowID - 1);
+            UpdateProjectData(updateData, function (datas) {
+                datas.forEach(function (data) {
+                    var parent, next;
+                    if (data.updateType === 'new') {
+                        parent = data.updateData.parentId === -1 ?  Tree._root : Tree.findNode(data.updateData.parentId);
+                        next = data.updateData.nextId === -1 ? null : Tree.findNode(data.updateData.nextId);
+                        Tree.addNodeData(data.updateData, parent, next);
+                    }
+                });
+                $('#addProj').modal('hide');
             });
-            $('#addProj').modal('hide');
         });
     }
 }
 var AddFolderProj = function () {
-    var nameB = $('#buildName').val(), nameX = $('#xiangName').val(), name = $('#tenderName').val(), updateData;
+    var nameB = $('#buildName').val(), nameX = $('#xiangName').val(), name = $('#tenderName').val();
     if (nameB !== '' && nameX !== '' && name !== '') {
-        updateData = GetAddFolderProjUpdateData(Tree._root, Tree.firstNode(), nameB, nameX, name);
-        UpdateProjectData(updateData, function (datas) {
-            datas.forEach(function (data) {
-                var parent, next;
-                if (data.updateType === 'new') {
-                    parent = data.updateData[Tree.setting.tree.pid] === -1 ?  Tree._root : Tree.findNode(data.updateData[Tree.setting.tree.pid]);
-                    next = data.updateData[Tree.setting.tree.nid] === -1 ? null : Tree.findNode(data.updateData[Tree.setting.tree.nid]);
-                    Tree.addNodeData(data.updateData, parent, next);
-                }
+        CommonAjax.post('/pm/api/getNewProjectID', {count: 3}, function (IDs) {
+            var updateData = GetAddFolderProjUpdateData(Tree._root, Tree.firstNode(), nameB, nameX, name, IDs.lowID);
+            Tree.maxNodeId(IDs.lowID - 1);
+            UpdateProjectData(updateData, function (datas) {
+                datas.forEach(function (data) {
+                    var parent, next;
+                    if (data.updateType === 'new') {
+                        parent = data.updateData[Tree.setting.tree.pid] === -1 ?  Tree._root : Tree.findNode(data.updateData[Tree.setting.tree.pid]);
+                        next = data.updateData[Tree.setting.tree.nid] === -1 ? null : Tree.findNode(data.updateData[Tree.setting.tree.nid]);
+                        Tree.addNodeData(data.updateData, parent, next);
+                    }
+                });
+                $('#addProj').modal('hide');
             });
-            $('#addProj').modal('hide');
         });
     }
 }
@@ -573,7 +582,7 @@ $('#copyto').on('show.bs.modal', function () {
     copytoZTree = ConvertTreeToZtree(Tree, $('#treeDemo2'));
 });
 $('#copytoOk').click(function() {
-    var updateData, form = $('#copyto'),
+    var form = $('#copyto'),
         target = GetTargetTreeNode($.fn.zTree.getZTreeObj('treeDemo2')),
         parent, next, cur = Tree.selected();
     if (target && (target.data.projType === 'Tender' || target.children.length === 0 || target.firstChild().data.projType === 'Tender')) {
@@ -586,13 +595,18 @@ $('#copytoOk').click(function() {
         }
 
         if (parent !== cur.parent || (next !== cur && next !== cur.nextSibling)){
-            updateData = GetCopyUpdateData(Tree.selected(), parent, next);
-            UpdateProjectData(updateData, function (data) {
-                form.modal('hide');
-                data.forEach(function (nodeData) {
-                    if (nodeData.updateType === 'new') {
-                        Tree.addNodeData(nodeData.updateData, parent, next);
-                    }
+            CommonAjax.post('/pm/api/getNewProjectID', {count: 1}, function (IDs) {
+                var updateData = GetCopyUpdateData(cur, parent, next, IDs.lowID);
+                Tree.maxNodeId(IDs.lowID - 1);
+                CommonAjax.post('/pm/api/copyProjects', {user_id: userID, updateData: updateData}, function (data) {
+                    form.modal('hide');
+                    data.forEach(function (nodeData) {
+                        if (nodeData.updateType === 'copy') {
+                            Tree.addNodeData(nodeData.updateData, parent, next);
+                        }
+                    });
+                }, function () {
+                    form.modal('hide');
                 });
             });
         } else {

+ 32 - 22
web/rationLibEditor/dinge.html

@@ -45,6 +45,12 @@
             <div class="container-fluid">
                 <div class="row">
                   <div class="main-side col-lg-3 p-0">
+                      <div class="tab-bar">
+                          <!--
+                          <a href="#" class="btn btn-secondary btn-sm">创建默认章节树</a>
+                          -->
+                          <a onclick="zTreeOprObj.addRootNode()" class="btn btn-secondary btn-sm">增加根节点</a>
+                      </div>
                     <div class="tab-content">
                       <ul id="treeDemo" class="ztree"></ul>
                     </div>
@@ -862,7 +868,7 @@
         </div>
     </div>
     <!-- JS. -->
-    <script src = "/lib/spreadjs/gc.spread.sheets.all.10.0.1.min.js"></script>
+    <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>
@@ -873,23 +879,24 @@
     <script type="text/javascript" src="/lib/ztree/jquery.ztree.exedit.js"></script>
     <script type="text/javascript" src="/web/rationLibEditor/_zSpread.js"></script>
     <script type="text/javascript" src="/web/rationLibEditor/js/dinge.js"></script>
+    <script type="text/javascript" src="/public/web/treeDataHelper.js"></script>
     <SCRIPT type="text/javascript">
 /*var rationName = getQueryString("rationname");*/
 var treeObj;
 var zNodes =[
-    { id:1, pId:0,nId:2, name:"第一章 土石方工程",isParent:true,children:[]},
-    { id:2, pId:0,nId:3, name:"第二章 挡墙、护坡工程",isParent:true,children:[]},
-    { id:3, pId:0,nId:4, name:"第三章 基础工程",isParent:true,children:[]},
-    { id:4, pId:0,nId:5, name:"第四章 脚手架工程",isParent:true,children:[]},
-    { id:5, pId:0,nId:6, name:"第五章 砌筑工程",isParent:true,children:[]},
-    { id:6, pId:0,nId:7, name:"第六章 混凝土及钢筋混凝土工程",isParent:true,children:[]},
-    { id:7, pId:0,nId:8, name:"第七章 金属工程",isParent:true,children:[]},
-    { id:8, pId:0,nId:9, name:"第八章 门窗、木结构",isParent:true,children:[]},
-    { id:9, pId:0,nId:10, name:"第九章 楼地面工程",isParent:true,children:[]},
-    { id:10, pId:0,nId:11, name:"第十章 层面工程",isParent:true,children:[]},
-    { id:11, pId:0,nId:12, name:"第十一章 防腐隔热保温工程",isParent:true,children:[]},
-    { id:12, pId:0,nId:13, name:"第十二章 装饰工程",isParent:true,children:[]},
-    { id:13, pId:0,nId:-1, name:"第十三章 其他工程",isParent:true,children:[]},
+    { id:1, pId:-1,nId:2, name:"第一章 土石方工程",isParent:true, items:[]},
+    { id:2, pId:-1,nId:3, name:"第二章 挡墙、护坡工程",isParent:true,items:[]},
+    { id:3, pId:-1,nId:4, name:"第三章 基础工程",isParent:true,items:[]},
+    { id:4, pId:-1,nId:5, name:"第四章 脚手架工程",isParent:true,items:[]},
+    { id:5, pId:-1,nId:6, name:"第五章 砌筑工程",isParent:true,items:[]},
+    { id:6, pId:-1,nId:7, name:"第六章 混凝土及钢筋混凝土工程",isParent:true,items:[]},
+    { id:7, pId:-1,nId:8, name:"第七章 金属工程",isParent:true,items:[]},
+    { id:8, pId:-1,nId:9, name:"第八章 门窗、木结构",isParent:true,items:[]},
+    { id:9, pId:-1,nId:10, name:"第九章 楼地面工程",isParent:true,items:[]},
+    { id:10, pId:-1,nId:11, name:"第十章 层面工程",isParent:true,items:[]},
+    { id:11, pId:-1,nId:12, name:"第十一章 防腐隔热保温工程",isParent:true,items:[]},
+    { id:12, pId:-1,nId:13, name:"第十二章 装饰工程",isParent:true,items:[]},
+    { id:13, pId:-1,nId:-1, name:"第十三章 其他工程",isParent:true,items:[]},
 ];
 var setting = {
     view: {
@@ -910,21 +917,25 @@ var setting = {
             leaf:true
         },
         key: {
-            children: "children"
+            children: "items"
         },
         simpleData: {
-            enable: true
+            enable: true,
+            idKey: "ID",
+            pIdKey: "ParentID",
+            rootPId: -1
         }
     },
     callback:{
-        onClick:SectionClick,
+        //onClick:SectionClick,
         beforeDrag: beforeDrag,
         beforeEditName: beforeEditName,
-        beforeRemove: beforeRemove,
+        //beforeRemove: beforeRemove,
         beforeRename: beforeRename,
-        beforeClick:beforeClick,
-        onRemove: onRemove,
-        onRename: onRename
+        //beforeClick:beforeClick,
+        beforeRemove: zTreeOprObj.onBeforeRemove,
+        //onRemove: onRemove,
+        onRename: zTreeOprObj.onRename
     }
 }; //ztree  setting
 var log, className = "dark";
@@ -995,7 +1006,6 @@ function removeSection(id){
 }
 function beforeRename(treeId, treeNode, newName, isCancel) {
     className = (className === "dark" ? "":"dark");
-  //  showLog((isCancel ? "<span style='color:red'>":"") + "[ "+getTime()+" beforeRename ]&nbsp;&nbsp;&nbsp;&nbsp; " + treeNode.name + (isCancel ? "</span>":""));
     if (newName.length == 0) {
         setTimeout(function() {
             var zTree = $.fn.zTree.getZTreeObj("treeDemo");

+ 125 - 168
web/rationLibEditor/js/dinge.js

@@ -16,150 +16,137 @@ $("#gongliao").click(function(){
 });
 //----------------------------------------------------页面初始化
 $(document).ready(function(){
-    initParam();
+    rationOprObj.initParam();
     mkRationItemSpread();
 });
-function initParam(){
-    var rationLibName = getQueryString("rationname");//获取定额库参数
-    if(rationLibName)
-        getRealLib(rationLibName);
-    else{
-        params = JSON.parse(getQueryString("params"));
-        getRationTree();
+
+var rationOprObj = {
+    initParam : function() {
+        var me = this, rationLibName = getQueryString("repository");//获取定额库参数
+        if (rationLibName) {
+            params.realLibName = rationLibName;
+            me.getRationTree();
+        } else{
+            params = JSON.parse(getQueryString("params"));
+            me.getRationTree();
+        }
+    },
+    getRationTree: function(){
+        var me = this;
+        $.ajax({
+            type:"POST",
+            url:"api/getRationTree",
+            data:{"rationLibName": params.realLibName},
+            dataType:"json",
+            cache:false,
+            timeout:20000,
+            success:function(result,textStatus,status){
+                if(status.status == 200) {
+                    me.createRationTree(result.data);
+                }
+            },
+            error:function(err){
+                alert(err.responseText.error)
+            }
+        })
+    },
+    createRationTree: function(sourceData){
+        var treeArr = tree_Data_Helper.buildTreeNodeDirectly(sourceData);
+        treeObj = $.fn.zTree.init($("#treeDemo"), setting, treeArr);
     }
 }
-function getRealLib(LibName){
-    $.ajax({
-        type:"POST",
-        url:"http://localhost:6060/rationLibEditor/getRealLibName",
-        data:{"rationName":LibName},
-        async:false,
-        dataType:"json",
-        cache:false,
-        timeout:1000,
-        success:function(result){
-            params.realLibName = result.data[0].dbName
-            getRationTree();
-        },
-        error:function(){}
-    })
-}
-//---------------------------------------------------初始化章节树界面
-function  getRationTree(){
-    $.ajax({
-        type:"POST",
-        url:"http://localhost:6060/rationLibEditor/getRationTree",
-        data:{"rationLibName": params.realLibName},
-        dataType:"json",
-        cache:false,
-        timeout:20000,
-        success:function(result,textStatus,status){
-            if(status.status == 200) createRationTree(result.data);//根据返回的全部定额章节对象,构架树。
-            else{
-                treeObj = $.fn.zTree.init($("#treeDemo"), setting, zNodes);
-                saveTempTree();
+
+var zTreeOprObj = {
+    addRootNode: function() {
+        var me = this, rawNode = {ParentID: -1, NextSiblingID: -1, name: "新增节点"};
+        me.addNewNode(rawNode, function(err, rst){
+            if (!(err)) {
+                var newNodes = [], isSilent = false;
+                newNodes.push({ rationRepId: rst.data.rationRepId, ID: rst.data.ID, ParentID:-1, NextSiblingID:-1, name:"新增节点",isParent:true, items:[]});
+                if (treeObj) {
+                    treeObj.addNodes(null, -1, newNodes, isSilent);
+                } else {
+                    treeObj = $.fn.zTree.init($("#treeDemo"), setting, newNodes);
+                }
             }
-        },
-        error:function(err){
-            alert(err.responseText.error)
-        }
-    })
-}
-//根据返回的节点集合构建树节点
-function createRationTree(obj){
-    var treeArr;
-    treeArr = makeNodes(obj);
-    var  maxIDNode = obj.reduce(function(a,b){
-        return (a.id> b.id)?a:b;
-    });
-    newCount = maxIDNode.id;
-    treeObj = $.fn.zTree.init($("#treeDemo"), setting, treeArr);
-}
-function makeNodes(obj){
-    var arr=[];
-    arr = obj.filter(function(x){
-        return x.parentId==0
-    })
-    arr.forEach(function(x){
-        x.id = x.sectionId;
-        x.pId = x.parentId;
-        x.nId = x.nextSiblingId;
-        x.name = x.name;
-        x.isParent = true
-        x.lev = 0
-    });
-    arr  =  sortArray(arr);
-    for(var i=0;i<arr.length;i++){
-        var L1 = [];
-        L1 = obj.filter(function(x){
-            return x.parentId ==arr[i].id;
         });
-        L1.forEach(function(x){
-            x.id = x.sectionId;
-            x.pId = x.parentId;
-            x.nId = x.nextSiblingId;
-            x.name = x.name;
-            x.isParent = true
-            x.lev = 1
+    },
+    addNewNode : function(rawNode, callback){
+        $.ajax({
+            type:"POST",
+            url:"api/createNewNode",
+            data:{"rationLibName":params.realLibName,"rawNodeData": JSON.stringify(rawNode)},
+            dataType:"json",
+            cache:false,
+            timeout:1000,
+            success: function(result,textStatus,status){
+                callback(false, result);
+            },
+            error:function(err){
+                callback(err);
+            }
+        })
+    },
+    onRename : function(e, treeId, treeNode, isCancel) {
+        var nodes = [];
+        nodes.push(treeNode);
+        zTreeOprObj.updateNodes(nodes);
+    },
+    onBeforeRemove: function(treeId, treeNode){
+        var nodeIds = [], preNode = treeNode.getPreNode(), preNodeId = -1;
+        if (preNode) {
+            preNodeId = preNode.ID;
+        }
+        nodeIds.push(treeNode.ID);
+        for (var i = 0; i < treeNode.items.length; i++) {
+            nodeIds.push(treeNode.items[i].ID);
+        }
+        $.ajax({
+            type:"POST",
+            url:"api/deleteNodes",
+            data:{"nodes": JSON.stringify(nodeIds), "preNodeId": preNodeId, "preNodeNextId": treeNode.NextSiblingID},
+            dataType:"json",
+            cache:false,
+            timeout:5000,
+            success:function(result,textStatus,status){
+                //if(result){
+                //    caseDeleteTreeNode(result.data)
+                //}
+            },
+            error:function(){
+            }
         });
-        L1=sortArray(L1);
-        for(var j=0; j<L1.length;j++){
-            var L2 = [];
-            L2 =obj.filter(function(x){
-                return x.parentId == L1[j].id;
-            })
-            L2.forEach(function(x){
-                x.id = x.sectionId;
-                x.pId = x.parentId;
-                x.nId = x.nextSiblingId;
-                x.name = x.name;
-                x.isParent = false;
-                x.lev = 2
+        return true;
+    },
+    updateNodes: function(nodes){
+        if (nodes && nodes.length > 0) {
+            var reqData = []
+            for (var i = 0; i < nodes.length; i++) {
+                var node = {};
+                node.rationRepId = nodes[i].rationRepId;
+                node.ID = nodes[i].ID;
+                node.ParentID = nodes[i].ParentID;
+                node.NextSiblingID = nodes[i].NextSiblingID;
+                node.name = nodes[i].name;
+                node.__v = nodes[i].__v + 1;
+                reqData.push(node);
+            }
+            $.ajax({
+                type:"POST",
+                url:"api/updateNodes",
+                data:{"nodes": JSON.stringify(reqData)},
+                dataType:"json",
+                cache:false,
+                timeout:5000,
+                success:function(result,textStatus,status){
+                    console.log(status + ' : ' + result);
+                },
+                error:function(){
+                }
             })
-            L2=sortArray(L2)
-            L1[j].children = L2;
         }
-        arr[i].children = L1;
     }
-    return arr;
-}
-function sortArray(arr){
-    var a = [];
-    for(var i=0;i<arr.length;i++)
-        if (arr[i].nextSiblingId == -1)
-            a.push(arr[i])
-    for(; a.length < arr.length;){
-        for(var j=0;j<arr.length;j++) {
-            if (arr[j].nextSiblingId == a[0].sectionId)
-            {a.unshift(arr[j]); break;}
-        }
-    }
-    return a ;
-}
-//新建的定额库保存模板节点
-function saveTempTree(){
-    var N = []
-    for(i=0;i<zNodes.length;i++){
-        var node ={}
-        node.sectionId = zNodes[i].id;
-        node.parentId = zNodes[i].pId;
-
-        node.nextSiblingId = zNodes[i].nId;
-        node.name =zNodes[i].name;
-        N.push(node);
-    }
-    var rationTempTree = JSON.stringify(N)
-    $.ajax({
-        type:"POST",
-        url:"http://localhost:6060/rationLibEditor/saveTempRationTree",
-        data:{"rationName":rationLibName,"rationTempTree":rationTempTree},
-        dataType:"json",
-        cache:false,
-        timeout:1000,
-        success:function(result,textStatus,status){},
-        error:function(){}
-    })
-}
+};
 //--------------------------------------------------------树处理事件
 var newCount = 13;
 //新增树节点
@@ -173,7 +160,7 @@ function addHoverDom(treeId, treeNode) {
     if (btn) btn.bind("click", function(){
         var zTree = $.fn.zTree.getZTreeObj("treeDemo");
         if((treeNode.level==0)){
-            var newNode = zTree.addNodes(treeNode, {id:(++newCount), pId:treeNode.id,nId:-1,isParent:true, name:"请输入章节名称",children:[]});
+            var newNode = zTree.addNodes(treeNode, {id:(++newCount), pId:treeNode.id,nId:-1,isParent:true, name:"请输入章节名称",items:[]});
 
         }
         else{
@@ -189,6 +176,7 @@ function addHoverDom(treeId, treeNode) {
         return false;
     });
 };
+
 //保存新增的节点
 function saveNewSection(n){
     var sec={};
@@ -199,7 +187,7 @@ function saveNewSection(n){
     var section = JSON.stringify(sec);
     $.ajax({
         type:"POST",
-        url:"http://localhost:6060/rationLibEditor/addSection",
+        url:"api/addSection",
         data:{"rationLibName":params.realLibName,"rationSection":section},
         dataType:"json",
         cache:false,
@@ -210,38 +198,7 @@ function saveNewSection(n){
         }
     })
 }
-//编辑树节点事件(添加节点到数据库)
-function onRename(e, treeId, treeNode, isCancel) {
-    saveNewSection(treeNode);
-}
-function onRemove(e, treeId, treeNode) {
-    var id = treeNode.id;
-    var pNodes = treeNode.getParentNode().children;
-    for(var i=0;i<pNodes.length;i++){
-        if(pNodes[i].nId==id){
-            pNodes[i].nId = -1;
-            saveNewSection(pNodes[i]);
-        }
-    }
-    $.ajax({
-        type:"POST",
-        url:"http://localhost:6060/rationLibEditor/deleteSection",
-        data:{"rationLibName":params.realLibName,"sectionID": treeNode.id},
-        dataType:"json",
-        cache:false,
-        timeout:1000,
-        success:function(result,textStatus,status){
-            //if(result){
-            //    caseDeleteTreeNode(result.data)
-            //}
-        },
-        error:function(){
-        }
-    })
-    removeSection(id)
-    $("#rationTbody").html("");
-    $("#rationGLJTbody").html("");
-}
+
 //--------------------------------------------------------定额spreadjs
 var spSetting_ration = {
     spType:"Ration",

+ 27 - 42
web/rationLibEditor/js/mainJ.js

@@ -5,15 +5,15 @@ $(function(){
     getRationLibs();
 })
 
-function addressdirect(){
+function addEvent_Addressdirect(){
     $("tr:gt(0)").each(function() {
         var td, a;
         td = $("td:eq(0)", $(this));
         a = $('a', td);
-        a.attr('href', "/rationLibEditor/rationLib" + "?rationname=" + a.text());
+        a.attr('href', "/rationRepository/ration" + "?repository=" + a.text());
     })
 }
-function deleteLib(){
+function addEvent_DeleteLib(){
     $("tr:gt(0)").each(function() {
         var td0, a1,td2,a2;
         td2 = $("td:eq(2)", $(this));
@@ -28,7 +28,7 @@ function deleteLib(){
     })
 }
 
-function editLib(){
+function addEvent_EditLib(){
     $("tr:gt(0)").each(function() {
         var td0, a1,td2,a2;
         td2 = $("td:eq(2)", $(this));
@@ -46,7 +46,7 @@ $("#deleteLib").click(function(){
     var rationLibName = $("#did").val();
     $.ajax({
         type:"POST",
-        url:"http://localhost:6060/rationLibEditor/deleteRationLibs",
+        url:"api/deleteRationLibs",
         dataType:"json",
         data:{"rationName": rationLibName},
         cache:false,
@@ -64,18 +64,18 @@ $("#deleteLib").click(function(){
 function getRationLibs(){
     $.ajax({
         type:"POST",
-        url:"http://localhost:6060/rationLibEditor/getRationDisplayNames",
+        url:"api/getRationDisplayNames",
         dataType:"json",
         cache:false,
-        timeout:50000,
+        timeout:5000,
         success:function(result){
             $("tbody tr").html("");
             for(var i=0;i<result.data.length;i++){
-                addLibTag(result.data[i].displayName);
+                addLibTag(result.data[i].dispName);
             }
-            addressdirect();
-            deleteLib();
-            editLib();
+            addEvent_Addressdirect();
+            addEvent_DeleteLib();
+            addEvent_EditLib();
         },
         error:function(iqXHR,textStatus,errorThrown){
             alert("error "+textStatus+" "+errorThrown);
@@ -90,21 +90,21 @@ function addLibTag(string){
     var a = $("a",$td0);
     var str = string;
     a.text(str);
-    var date = new Date().format("yyyy-MM-dd");
+    var date = new Date().Format("yyyy-MM-dd");
     $td1.text(date);
     $tr.appendTo("tbody");
 }
 
-function addRation(str) {
+function addRationRepository(rationObj) {
     $.ajax({
         type:"POST",
-        url:"http://localhost:6060/rationLibEditor/addRationLib",
+        url:"api/addRationRepository",
         dataType:"json",
-        data:{"rationDisPlayName": str},
+        data:{"rationRepObj": JSON.stringify(rationObj)},
         cache:false,
-        timeout:50000,
+        timeout:5000,
         success:function(result){
-
+            //
         },
         error:function(iqXHR,textStatus,errorThrown){
             alert("error "+textStatus+" "+errorThrown);
@@ -120,12 +120,16 @@ $("#rationAdd").click(function(){
     var a = $("a",$td0);
     var str = $("#addInput").val();
     a.text(str);
-    var date = new Date().format("yyyy-MM-dd");
+    var date = new Date().Format("yyyy-MM-dd");
     $td1.text(date);
     $tr.appendTo("tbody");
-    addRation(str);
-    addressdirect();
-    deleteLib();
+    var newRationRepObj = {};
+    newRationRepObj.dispName = str;
+    newRationRepObj.appType = "建筑";
+    newRationRepObj.descr = "";
+    addRationRepository(newRationRepObj);
+    addEvent_Addressdirect();
+    addEvent_DeleteLib();
 });
 
 $("#edtOK").click(function(){
@@ -133,7 +137,7 @@ $("#edtOK").click(function(){
     var newStr = $("#inputRation").val();
     $.ajax({
         type:"POST",
-        url:"http://localhost:6060/rationLibEditor/editRationLibs",
+        url:"api/editRationLibs",
         dataType:"json",
         data:{"rationName": str,"newName":newStr},
         cache:false,
@@ -148,24 +152,5 @@ $("#edtOK").click(function(){
     })
 
 });
-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;
-}
+
 autoFlashHeight();

+ 2 - 1
web/rationLibEditor/main.html

@@ -105,7 +105,7 @@
 
     <!--弹出删除-->
     <div class="modal fade" id="del" data-backdrop="static" style="display: none;" aria-hidden="true">
-        <input type="hidden" id="did" value="">
+        <input type="hidden" id="did" value="123">
         <div class="modal-dialog" role="document">
             <div class="modal-content">
                 <div class="modal-header">
@@ -130,6 +130,7 @@
     <script src="/lib/bootstrap/bootstrap.min.js"></script>
     <script src="/lib/global.js"></script>
     <!-- zTree -->
+    <script type="text/javascript" src="/public/dateUtil.js"></script>
   	<script type="text/javascript" src="/lib/ztree/jquery.ztree.core.js"></script>
   	<script type="text/javascript" src="/lib/ztree/jquery.ztree.excheck.js"></script>
     <script type="text/javascript" src="/web/rationLibEditor/js/mainJ.js"></script>

+ 8 - 4
web/scripts/tree_table.js

@@ -161,8 +161,12 @@
  					return _maxNodeId;
  				}
  			};
-			this.maxNodeId = function (){
-				return _maxNodeId;
+			this.maxNodeId = function (id){
+				if (arguments.length > 0) {
+					_maxNodeId = Math.max(id, _maxNodeId);
+				} else {
+					return _maxNodeId;
+				}
 			}
  		};
 
@@ -234,7 +238,7 @@
  					node = new Node(that, data);
  				}
  				node.data = data;
-				that.newNodeId(node.id());
+				that.maxNodeId(node.id());
 
 				if (!parent){
 					if (data[setting.tree.pid] === setting.tree.nullId) {
@@ -301,7 +305,7 @@
 			var pNode = parent ? parent : this._root;
 			if (!nextSibling || (nextSibling.parent === pNode && pNode.childIndex(nextSibling) > -1)) {
 				node = new Node(this, data);
-                this.newNodeId(data[this.setting.tree.id]);
+                this.maxNodeId(data[this.setting.tree.id]);
 				node.row = _view._makeRowDom(this.treeBodyObj, node);
 				this.move(node, pNode, nextSibling);
 			}

+ 2 - 1
web/templates/html/bills.html

@@ -99,7 +99,8 @@
 <!-- service -->
 <script type="text/javascript" src="/web/templates/js/bills.js"></script>
 <script type="text/javascript" src="/web/templates/js/tp_bills_setting.js"></script>
-<script type="text/javascript">
+<script type="text/javascript" src="/public/web/common_ajax.js"></script>
+<script>
     autoFlashHeight();
 </script>
 </html>

+ 30 - 53
web/templates/js/bills.js

@@ -3,32 +3,6 @@
  */
 $(document).ready(function () {
     var tempType = 3;
-    var PostData = function (url, data, successCallback, errorCallback) {
-        $.ajax({
-            type:"POST",
-            url: url,
-            data: {'data': JSON.stringify(data)},
-            dataType: 'json',
-            cache: false,
-            timeout: 50000,
-            success: function(result){
-                if (result.error === 0) {
-                    successCallback(result.data);
-                } else {
-                    alert('error: ' + result.message);
-                    if (errorCallback) {
-                        errorCallback();
-                    }
-                }
-            },
-            error: function(jqXHR, textStatus, errorThrown){
-                alert('error ' + textStatus + " " + errorThrown);
-                if (errorCallback) {
-                    errorCallback();
-                }
-            }
-        });
-    };
     var FormatUpdateData = function (data) {
         var updateData = {};
         updateData['user_id'] = userID;
@@ -52,16 +26,19 @@ $(document).ready(function () {
     }
     var RefreshBillsData = function (datas) {
         datas.forEach(function (data) {
-            bills.forEach(function (billsData) {
-                if (data.data.ID === billsData.ID) {
-                    $.extend(true, billsData, data.data);
-                }
-            })
-        })
-    }
+            var node = tree.findNode(data.data.ID);
+            if (node) {
+                $.extend(true, node.data, data.data);
+            }
+        });
+    };
 
+<<<<<<< HEAD
     var bills;
     var tree = idTree.createInit({id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1});
+=======
+    var tree = idTree.createNew({id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1, autoUpdate: true});
+>>>>>>> bc0f5d2858a5b09273a8d6ed5620a4deb05293b2
     var billsSpread = new GC.Spread.Sheets.Workbook($('#billsSpread')[0], { sheetCount: 1 });
     var controller = TREE_SHEET_CONTROLLER.createInit(tree, billsSpread.getActiveSheet(), TEMPLATE_BILLS_SETTING);
 
@@ -69,26 +46,32 @@ $(document).ready(function () {
 
     billsSpread.options.tabStripVisible = false;
     billsSpread.options.scrollbarMaxAlign = true;
+    billsSpread.options.cutCopyIndicatorVisible = false;
+    billsSpread.options.allowCopyPasteExcelStyle = false;
     controller.bind('refreshBaseActn', RefreshBaseActn);
 
     billsSpread.bind(GC.Spread.Sheets.Events.EditEnded, function (sender, info) {
-        var node = controller.tree.findNode(info.sheet.getTag(info.row, info.col));
+        var node = controller.tree.items[info.row];
         var fieldName = controller.setting.cols[info.col].data.field;
         var data = {type: 'update', data: {ID: node.getID()}};
         data.data[fieldName] = info.editingText;
         var updateData = FormatUpdateData([data]);
-        PostData('/template/bills/updateBillsTemplate', updateData, function (data) {
+        CommonAjax.post('/template/bills/api/updateBillsTemplate', updateData, function (data) {
             node.data[fieldName] = info.editingText;
             controller.refreshTreeNode([node], false);
         }, function () {
             controller.refreshTreeNode([node], false);
         });
     });
+    billsSpread.bind(GC.Spread.Sheets.Events.ClipboardPasting, function (sender, args) {
+        console.log("ClipboardPasting");
+    });
     billsSpread.bind(GC.Spread.Sheets.Events.ClipboardPasted, function (e, info) {
+        console.log("ClipboardPasted");
         var node, iRow, iCol, curRow, curCol, datas = [], data, fieldName, updateData;
         for (iRow = 0; iRow < info.cellRange.rowCount; iRow ++) {
             curRow = info.cellRange.row + iRow;
-            node = controller.tree.findNode(info.sheet.getTag(curRow, 0));
+            node = controller.tree.items[curRow];
             if (node) {
                 data = {type: 'update', data: {ID: node.getID()}};
                 for (iCol = 0; iCol < info.cellRange.colCount; iCol++) {
@@ -99,16 +82,16 @@ $(document).ready(function () {
                 datas.push(data);
             }
         };
-        PostData('/template/bills/updateBillsTemplate', FormatUpdateData(datas), function (data) {
+        CommonAjax.post('/template/bills/api/updateBillsTemplate', FormatUpdateData(datas), function (data) {
             RefreshBillsData(data);
             controller.showTreeData();
         }, function () {
             controller.showTreeData();
-        })
+        });
     });
 
-    PostData('/template/bills/getBillsTemplate', {tempType: tempType}, function (data) {
-        bills = data;
+    CommonAjax.post('/template/bills/api/getBillsTemplate', {tempType: tempType}, function (data) {
+        var bills = data;
         tree.loadDatas(bills);
         controller.showTreeData();
         RefreshBaseActn(tree);
@@ -118,7 +101,7 @@ $(document).ready(function () {
     });
 
     $('#insert').click(function () {
-        PostData('/template/bills/getNewBillsTemplateID', {count: 1}, function (data) {
+        CommonAjax.post('/template/bills/api/getNewBillsTemplateID', {count: 1}, function (data) {
             var selected = controller.tree.selected, updateData;
             controller.tree.maxNodeID(data.lowID - 1);
             controller.tree.rangeNodeID(data.highID);
@@ -128,9 +111,8 @@ $(document).ready(function () {
                 updateData = FormatUpdateData(controller.tree.getInsertData());
             }
             if (updateData.updateData.length > 0) {
-                PostData('/template/bills/updateBillsTemplate', updateData, function (data) {
+                CommonAjax.post('/template/bills/api/updateBillsTemplate', updateData, function (data) {
                     controller.insert();
-                    RefreshBillsData(data);
                     controller.showTreeData();
                 });
             } else {
@@ -142,9 +124,8 @@ $(document).ready(function () {
         var selected = controller.tree.selected, updateData;
         if (selected) {
             updateData = FormatUpdateData(controller.tree.getDeleteData(selected));
-            PostData('/template/bills/updateBillsTemplate', updateData, function (data) {
+            CommonAjax.post('/template/bills/api/updateBillsTemplate', updateData, function (data) {
                 controller.delete();
-                RefreshBillsData(data);
                 controller.showTreeData();
             });
         }
@@ -153,9 +134,8 @@ $(document).ready(function () {
         var selected = controller.tree.selected, updateData;
         if (selected) {
             updateData = FormatUpdateData(selected.getUpLevelData());
-            PostData('/template/bills/updateBillsTemplate', updateData, function (data) {
+            CommonAjax.post('/template/bills/api/updateBillsTemplate', updateData, function (data) {
                 controller.upLevel();
-                RefreshBillsData(data);
                 controller.showTreeData();
             });
         }
@@ -164,9 +144,8 @@ $(document).ready(function () {
         var selected = controller.tree.selected, updateData;
         if (selected) {
             updateData = FormatUpdateData(selected.getDownLevelData());
-            PostData('/template/bills/updateBillsTemplate', updateData, function (data) {
+            CommonAjax.post('/template/bills/api/updateBillsTemplate', updateData, function (data) {
                 controller.downLevel();
-                RefreshBillsData(data);
                 controller.showTreeData();
             });
         }
@@ -175,9 +154,8 @@ $(document).ready(function () {
         var selected = controller.tree.selected, updateData;
         if (selected) {
             updateData = FormatUpdateData(selected.getUpMoveData());
-            PostData('/template/bills/updateBillsTemplate', updateData, function (data) {
+            CommonAjax.post('/template/bills/api/updateBillsTemplate', updateData, function (data) {
                 controller.upMove();
-                RefreshBillsData(data);
                 controller.showTreeData();
             });
         }
@@ -186,9 +164,8 @@ $(document).ready(function () {
         var selected = controller.tree.selected, updateData;
         if (selected) {
             updateData = FormatUpdateData(selected.getDownMoveData());
-            PostData('/template/bills/updateBillsTemplate', updateData, function (data) {
+            CommonAjax.post('/template/bills/api/updateBillsTemplate', updateData, function (data) {
                 controller.downMove();
-                RefreshBillsData(data);
                 controller.showTreeData();
             });
         }

+ 24 - 3
web/templates/js/tp_bills_setting.js

@@ -120,7 +120,14 @@ var TEMPLATE_BILLS_SETTING = {
             "field":"ID",
             "vAlign":0,
             "hAlign":1,
-            "font":"14.6667px Calibri"
+            "font":"14.6667px Calibri"/*,
+            "getText": function (node) {
+                if (node) {
+                    return node.getID();
+                } else {
+                    return '';
+                }
+            }*/
         }
     }, {
         "width":50,
@@ -149,7 +156,14 @@ var TEMPLATE_BILLS_SETTING = {
             "field":"ParentID",
             "vAlign":0,
             "hAlign":1,
-            "font":"14.6667px Calibri"
+            "font":"14.6667px Calibri"/*,
+            "getText": function (node) {
+                if (node) {
+                    return node.getParentID();
+                } else {
+                    return '';
+                }
+            }*/
         }
     }, {
         "width":50,
@@ -178,7 +192,14 @@ var TEMPLATE_BILLS_SETTING = {
             "field":"NextSiblingID",
             "vAlign":0,
             "hAlign":1,
-            "font":"14.6667px Calibri"
+            "font":"14.6667px Calibri"/*,
+            "getText": function (node) {
+                if (node) {
+                    return node.getNextSiblingID();
+                } else {
+                    return '';
+                }
+            }*/
         }
     }]
 };