Browse Source

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

TonyKang 8 years ago
parent
commit
5f4e284ce5
37 changed files with 746 additions and 246 deletions
  1. 6 6
      modules/fees/models/fees_db.js
  2. 47 0
      modules/main/controllers/GLJ_controller.js
  3. 4 14
      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. 29 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. 16 1
      modules/pm/controllers/copy_proj_controller.js
  20. 10 0
      modules/pm/controllers/pm_controller.js
  21. 41 2
      modules/pm/models/project.js
  22. 1 0
      modules/pm/routes/pm_route.js
  23. 2 1
      public/counter/counter.js
  24. 14 9
      public/web/scMathUtil.js
  25. 6 2
      server.js
  26. 46 0
      test/tmp_data/test_project_1.js
  27. 1 1
      test/unit/public/testScMath.js
  28. 2 24
      web/fees/feeRate.js
  29. 6 6
      web/main/html/main.html
  30. 25 1
      web/main/js/models/bills.js
  31. 49 0
      web/main/js/models/glj.js
  32. 0 27
      web/main/js/models/gljs.js
  33. 9 0
      web/main/js/models/mainConsts.js
  34. 116 10
      web/main/js/models/project.js
  35. 62 0
      web/main/js/models/ration.js
  36. 0 39
      web/main/js/models/rations.js
  37. 20 14
      web/pm/js/pm_main.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 - 14
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 {
@@ -19,20 +19,10 @@ 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();

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

@@ -44,8 +44,8 @@ var bills = db.model("bills", billsSchema);
 
 var billsDAO = function(){};
 
-billsDAO.prototype.getBills = function(projectId, callback){
-    bills.find({projectId: projectId}, function(err, datas){
+billsDAO.prototype.getData = function(projectID, callback){
+    bills.find({projectID: projectID}, function(err, datas){
         if (!err) {
             callback(0, '', datas);
         } else {
@@ -54,11 +54,28 @@ billsDAO.prototype.getBills = function(projectId, 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.updateBills = function(datas, callback){
+billsDAO.prototype.save = function(datas, callback){
     var data, errList = [], updateLength = 0;
     var updateFunc = function (err, errData) {
         if (err){
@@ -80,27 +97,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;

+ 16 - 1
modules/pm/controllers/copy_proj_controller.js

@@ -2,4 +2,19 @@
  * Created by Mai on 2017/4/24.
  */
 
-var billsData = require('../../main/models/bills');
+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);
+        });
+    }
+};

+ 10 - 0
modules/pm/controllers/pm_controller.js

@@ -29,6 +29,16 @@ module.exports = {
             }
         });
     },
+    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) {

+ 41 - 2
modules/pm/models/project.js

@@ -29,7 +29,7 @@ var Projects = db.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 {
@@ -49,7 +49,7 @@ ProjectsDAO.prototype.getUserProject = function (userId, ProjId, callback) {
 }
 
 ProjectsDAO.prototype.updateUserProjects = function(userId, datas, callback){
-    var data, project, updateLength = 0, hasError = false, deleteInfo = null, tempType = 1, i;
+    var data, project, updateLength = 0, hasError = false, deleteInfo = null, tempType = 1, i, newProject;
     var updateAll = function (err) {
             if (!err){
                 updateLength += 1;
@@ -93,6 +93,45 @@ ProjectsDAO.prototype.updateUserProjects = function(userId, datas, callback){
         }
     }
 };
+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);
+            }
+        }
+    }
+};
 
 ProjectsDAO.prototype.rename = function (userId, projectId, newName, callback){
     Projects.update({userID: userId, ID: projectId}, {name: newName}, function(err){

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

@@ -8,6 +8,7 @@ var pmController = require('./../controllers/pm_controller');
 
 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);

+ 2 - 1
public/counter/counter.js

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

+ 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);
     }
-}
+};

+ 6 - 2
server.js

@@ -81,10 +81,14 @@ app.get('/main',  function(req, res) {
     }
 });
 
+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) {

File diff suppressed because it is too large
+ 46 - 0
test/tmp_data/test_project_1.js


+ 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 - 24
web/fees/feeRate.js

@@ -173,36 +173,14 @@ function createSpreadView(canEdit) {
         }
     };
 
-    function showObjs(arr){
-        var s = '';
-        for (var i = 0; i < arr.length; i++) {
-            s = s + JSON.stringify(arr[i]) + "\n";
-        }
-        alert(s);
-    }
-
-    function showObjs2(obj) {
-        var str = "";
-        var spr = "";
-        for (var x in obj) {
-            if (obj.hasOwnProperty(x)) {
-                if(str == ''){ spr = '' } else { spr = ', '};
-                str += spr + x + ':' + obj[x];
-            }
-        }
-        return str;
-    }
-
     function rowClickFun(sender, args) {
-        //var arr = [args.event, args.hitInfo, args.item.dataItem];
-        //showObjs(arr);
-        alert(showObjs2(spreadView.getItem(4).item));
+        alert(args.item.dataItem.rate);
     }
 
     spreadView = new GC.Spread.Views.DataView($('#divFee')[0],
         dataSource, columns, new GC.Spread.Views.Plugins.GridLayout(options));
  
-    spreadView["rowClick"].addHandler(rowClickFun);
+    spreadView["rowDbClick"].addHandler(rowClickFun);
     spreadView.invalidate();
     document.querySelector('#divFee').focus();
 }

+ 6 - 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,12 +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 = {
@@ -630,9 +630,9 @@
         });*/
 
         project = PROJECT.createNew();
-        CommonAjax.post('/bills/getBills', {}, function (bills) {
+        CommonAjax.post('/bills/getData', {projectId: scUrlUtil.GetQueryString('project')}, function (bills) {
             project.Bills.loadDatas(bills);
-            project.Rations.loadDatas([]);
+            project.Ration.loadDatas([]);
             //project.Rations.loadDatas(drawing_data);
             project.loadMainTree();
 

+ 25 - 1
web/main/js/models/bills.js

@@ -20,10 +20,29 @@ var Bills = {
             this.datas = null;
             this.tree = idTree.createNew(billsTreeSetting);
 
-            var sourceType = 'bills';
+            var sourceType = ModuleNames.bills;
             this.getSourceType = function () {
                 return sourceType;
             }
+            proj.registerModule(ModuleNames.bills, this);
+        };
+
+        // 从后台获取数据
+        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方法
@@ -48,6 +67,11 @@ var Bills = {
             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'
+};

+ 116 - 10
web/main/js/models/project.js

@@ -2,27 +2,47 @@
  * Created by Mai on 2017/4/1.
  */
 var PROJECT = {
-    createNew: function () {
-        // 定义private方法
-        var tools = {};
+    createNew: function (projectID, userID) {
+        // 瀹氫箟private鏂规硶
+        var tools = {
+            _ID: projectID,
+            _userID: userID,
+            updateLock: 0,
+            updateData: [],
+            operation: '',
+            modules: {},
 
-        // 所有通过this访问的属性,都不应在此单元外部进行写入操作
+            doAfterUpdate: function(result){
+                result.forEach(function(item){
+                    if (item.moduleName in this.modules){
+                        this.modules[item.moduleName].doAfterUpdate(item.err, item.data);
+                    }
+                });
+            }
+        };
+
+        // 所有通过this访问的属性,都不应在此单元外部进行写入操作
         var project = function () {
             this.mainTree = cacheTree.createNew(this);
 
             this.Bills = Bills.createNew(this);
-            this.Rations = Rations.createNew(this);
-            this.GLJs = GLJs.createNew(this);
+            this.Ration = Ration.createNew(this);
+            this.GLJ = GLJ.createNew(this);
 
 
             this.masterField = {ration: 'BillsID'};
         };
 
-        // prototype用于定义public方法
+        // prototype鐢ㄤ簬瀹氫箟public鏂规硶
         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 +51,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 +65,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 +73,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);
-    }
-};

+ 20 - 14
web/pm/js/pm_main.js

@@ -130,8 +130,8 @@ 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;
 }
 // 获取新建项目数据
@@ -218,7 +218,7 @@ var GetDeleteUpdateData = function (node) {
             data['updateData'] = {};
             data['updateData'][Tree.setting.tree.id] = node.id();
             if (node.data.projType === 'Tender') {
-                data['updateData']['FullFolder'] = GetfullFolder(node.parent);
+                data['updateData']['FullFolder'] = GetFullFolder(node.parent);
             }
             return data;
         },
@@ -257,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;
@@ -581,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')) {
@@ -594,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('/getNewProjectID', {count: 1}, function (IDs) {
+                var updateData = GetCopyUpdateData(cur, parent, next, IDs.lowID);
+                Tree.maxNodeId(IDs.lowID - 1);
+                CommonAjax.post('/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 {