Przeglądaj źródła

Merge branch 'master' of http://192.168.1.12:3000/SmartCost/ConstructionCost

TonyKang 7 lat temu
rodzic
commit
ba9fecb7e9
48 zmienionych plików z 4002 dodań i 184 usunięć
  1. 30 0
      config/gulpConfig.js
  2. 139 0
      gulpfile.js
  3. 1 0
      modules/complementary_glj_lib/models/schemas.js
  4. 45 0
      modules/glj/controllers/glj_controller.js
  5. 1 0
      modules/glj/routes/glj_router.js
  6. 86 0
      modules/options/controllers/optionsController.js
  7. 13 0
      modules/options/models/optionTypes.js
  8. 38 0
      modules/options/models/optionsModel.js
  9. 18 0
      modules/options/models/schemas.js
  10. 17 0
      modules/options/routes/routes.js
  11. 3 2
      modules/pm/models/project_model.js
  12. 1 1
      modules/users/routes/boot_route.js
  13. 25 1
      package.json
  14. 1 1
      public/web/tree_sheet/tree_sheet_helper.js
  15. 0 1
      web/building_saas/complementary_glj_lib/html/tools-gongliaoji.html
  16. 39 60
      web/building_saas/complementary_glj_lib/js/components.js
  17. 19 20
      web/building_saas/complementary_glj_lib/js/glj.js
  18. 3 3
      web/building_saas/complementary_glj_lib/js/gljComponent.js
  19. 25 2
      web/building_saas/complementary_glj_lib/js/sheetOpr.js
  20. 3 2
      web/building_saas/css/main.css
  21. 26 2
      web/building_saas/glj/html/glj_index.html
  22. 41 0
      web/building_saas/glj/js/project_glj.js
  23. 10 14
      web/building_saas/js/global.js
  24. 1 1
      web/building_saas/js/message.js
  25. 53 13
      web/building_saas/main/html/main.html
  26. 48 22
      web/building_saas/main/js/calc/bills_calc.js
  27. 2 10
      web/building_saas/main/js/controllers/project_controller.js
  28. 24 1
      web/building_saas/main/js/models/bills.js
  29. 1 1
      web/building_saas/main/js/models/calc_program.js
  30. 1 1
      web/building_saas/main/js/models/fee_rate.js
  31. 1 1
      web/building_saas/main/js/models/ration.js
  32. 1 0
      web/building_saas/main/js/models/ration_glj.js
  33. 1 11
      web/building_saas/main/js/views/calc_program_view.js
  34. 1 1
      web/building_saas/main/js/views/glj_view.js
  35. 3 3
      web/building_saas/main/js/views/main_tree_col.js
  36. 72 0
      web/building_saas/main/js/views/options_view.js
  37. 9 3
      web/building_saas/main/js/views/project_info.js
  38. 0 1
      web/building_saas/main/js/views/sub_view.js
  39. 3 2
      web/building_saas/pm/js/pm_main.js
  40. 0 0
      web/building_saas/pm/js/pm_main_bak.bak
  41. 3 3
      web/common/html/header.html
  42. BIN
      web/dest/css/fonts/FontAwesome.otf
  43. BIN
      web/dest/css/fonts/fontawesome-webfont.eot
  44. 2671 0
      web/dest/css/fonts/fontawesome-webfont.svg
  45. BIN
      web/dest/css/fonts/fontawesome-webfont.ttf
  46. BIN
      web/dest/css/fonts/fontawesome-webfont.woff
  47. 523 0
      web/src/html/pm/project-management.html
  48. 0 1
      web/users/html/login-infoinput.html

+ 30 - 0
config/gulpConfig.js

@@ -0,0 +1,30 @@
+/**
+ * Created by zhang on 2017/9/27.
+ */
+
+module.exports = {
+    version:'1.0.1',
+    common_jspaths:[
+        'lib/jquery/jquery.min.js',
+        'lib/tether/tether.min.js',
+        'lib/bootstrap/bootstrap.min.js',
+        'web/building_saas/js/*.js'
+    ],
+    common_css:[
+        'lib/bootstrap/css/bootstrap.min.css',
+        'web/building_saas/css/main.css',
+        'lib/font-awesome/font-awesome.min.css'
+    ],
+    login_jspaths:[
+        'public/web/url_util.js',
+        'web/users/js/login.js'
+    ],
+    pm_css:['lib/ztree/css/zTreeStyle.css'],
+    pm_jspaths:[
+        'public/web/date_util.js',
+        'public/web/tree_table/tree_table.js',
+        'public/web/common_ajax.js',
+        'web/building_saas/pm/js/**/*.js',
+        'lib/ztree/*.js'
+    ]
+}

+ 139 - 0
gulpfile.js

@@ -0,0 +1,139 @@
+/**
+ * Created by chen on 2017/9/26.
+ */
+
+let gulp =require( 'gulp');
+let gulpLoadPlugins = require('gulp-load-plugins');
+let del = require('del');
+let uglify = require('gulp-uglify-es').default;
+let config = require("./config/gulpConfig.js");
+let  runSequence = require('run-sequence');
+
+const $ = gulpLoadPlugins();
+let common_jspaths=config.common_jspaths;
+let common_css=config.common_css;
+let pm_jspaths=config.pm_jspaths;
+let pm_csspaths=config.pm_css;
+let login_jspaths=config.login_jspaths;
+let main_jspaths=config.main_jspaths;
+let main_csspaths=config.main_css;
+let version=config.version;
+
+let taskObject={};
+function task_init(options) {
+    taskObject=options;
+    taskObject.version=version;
+    taskObject.scriptsDest='web/dest/scripts';
+}
+
+gulp.task('minify', function (){
+    if(taskObject.jspaths){
+        return gulp.src(taskObject.jspaths)
+            .pipe($.plumber())
+            .pipe(uglify())
+            .pipe($.concat(taskObject.concatName+"."+version+".js"))
+            .pipe(gulp.dest(taskObject.scriptsDest));
+    }
+   return;
+});
+
+
+gulp.task('copy',function () {
+    return gulp.src(taskObject.srcHtml)
+            .pipe($.plumber())
+            .pipe(gulp.dest(taskObject.htmlDest));
+})
+
+gulp.task('inject',['copy','minify','css'], function () {
+    var target = gulp.src(taskObject.htmlDest+'/'+taskObject.htmlName);
+    var sources = gulp.src(taskObject.injectList, {read: false});
+
+    return target.pipe($.plumber())
+         .pipe($.inject(sources))
+         .pipe(gulp.dest(taskObject.htmlDest));
+});
+
+gulp.task('htmlmin',function () {
+    return gulp.src(taskObject.htmlDest+'/*.html')
+      //  .pipe($.htmlmin({collapseWhitespace: true}))
+        .pipe(gulp.dest(taskObject.htmlDest));
+})
+
+gulp.task('css',function () {
+    if(taskObject.pm_csspaths){
+        return gulp.src(taskObject.pm_csspaths)
+            .pipe($.plumber())
+            .pipe($.cssnano())
+            .pipe($.concat(taskObject.concatName+"."+version+".css"))
+            .pipe(gulp.dest(taskObject.cssDest));
+    }
+    return;
+})
+
+gulp.task('common', function (){
+    let options = {
+        jspaths:common_jspaths,
+        pm_csspaths:common_css,
+        concatName:'common.all.min',
+        cssDest:'web/dest/css'
+    }
+    task_init(options);
+    runSequence('minify','css');
+});
+
+gulp.task('header', function (){
+    let options = {
+        concatName:'header.all.min',
+        srcHtml:'web/src/html/common/header.html',
+        htmlDest:'web/common/html',
+        htmlName:'header.html',
+        injectList:['web/dest/scripts/common.all.min.'+version+'.js']
+    };
+    task_init(options);
+    runSequence('inject','htmlmin');
+});
+
+
+gulp.task('login', function (){
+    let options = {
+        jspaths:login_jspaths,
+        concatName:'login.all.min',
+        srcHtml:'web/src/html/login/login.html',
+        htmlDest:'web/users/html',
+        htmlName:'login.html',
+        injectList:[  'web/dest/scripts/common.all.min.'+version+'.js',
+                        'web/dest/scripts/login.all.min.'+version+'.js',
+                        'web/dest/css/common.all.min.'+version+'.css']
+    }
+    task_init(options);
+    runSequence('inject','htmlmin');
+});
+
+gulp.task('pm', function (){
+    let options = {
+        jspaths:pm_jspaths,
+        pm_csspaths:pm_csspaths,
+        concatName:'pm.all.min',
+        cssDest:'web/dest/css',
+        srcHtml:'web/src/html/pm/*.html',
+        htmlDest:'web/building_saas/pm/html',
+        htmlName:'project-management.html',
+        injectList:['web/dest/scripts/pm.all.min.'+version+'.js',
+                      'web/dest/css/common.all.min.'+version+'.css',
+                      'web/dest/css/pm.all.min.'+version+'.css']
+    }
+    task_init(options);
+    runSequence('inject','htmlmin');
+});
+
+gulp.task('main',function () {
+    let options ={
+        jspaths:main_jspaths,
+        pm_csspaths:main_csspaths,
+        concatName:'main.all.min',
+    }
+    task_init(options);
+    runSequence('inject','htmlmin');
+
+})
+

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

@@ -6,6 +6,7 @@ import mongoose from "mongoose";
 let Schema = mongoose.Schema;
 let gjlComponentSchema = mongoose.Schema(
     {
+       // module: String, //"stdGlj"标准工料机 "complementaryGlj"
         ID: Number,
         consumeAmt: Number
     },

+ 45 - 0
modules/glj/controllers/glj_controller.js

@@ -352,6 +352,51 @@ class GLJController extends BaseController {
     }
 
     /**
+     * 单价文件另存为
+     *
+     * @param {object} request
+     * @param {object} response
+     * @return {void}
+     */
+    async unitPriceSaveAs(request, response) {
+        let responseData = {
+            err: 0,
+            msg: ''
+        };
+        let projectId = request.body.project_id;
+        let name = request.body.name;
+        try {
+            // 当前单价文件id
+            let currentUnitPriceId = await ProjectModel.getUnitPriceFileId(projectId);
+
+            // 新增单价文件信息
+            let unitPriceFileModel = new UnitPriceFileModel();
+            let insertData = {
+                name: name,
+                project_id: projectId
+            };
+            let addResult = await unitPriceFileModel.add(insertData);
+            if (!addResult) {
+                throw '单价文件另存为失败';
+            }
+
+            // 查找对应单价文件的项目工料机数据
+            let unitPriceModel = new UnitPriceModel();
+            let copyResult = await unitPriceModel.copyNotExist(currentUnitPriceId, addResult.id);
+            // 复制成功后更改project数据
+            if (!copyResult) {
+                throw '复制数据失败';
+            }
+
+        } catch (error) {
+            responseData.err = 1;
+            responseData.msg = error;
+        }
+
+        response.json(responseData);
+    }
+
+    /**
      * 模拟定额插入
      *
      * @param {object} request

+ 1 - 0
modules/glj/routes/glj_router.js

@@ -19,6 +19,7 @@ router.post('/get-ratio', gljController.init, gljController.getRatio);
 router.post('/delete-ratio', gljController.init, gljController.deleteMixRatio);
 router.post('/get-project-info', gljController.init, gljController.getProjectInfo);
 router.post('/change-file', gljController.init, gljController.changeUnitPriceFile);
+router.post('/save-as', gljController.init, gljController.unitPriceSaveAs);
 
 router.get('/test', gljController.init, gljController.test);
 router.get('/testModify', gljController.init, gljController.testModify);

+ 86 - 0
modules/options/controllers/optionsController.js

@@ -0,0 +1,86 @@
+/**
+ * Created by Zhong on 2017/9/28.
+ */
+
+import BaseController from '../../common/base/base_controller';
+import OptionsDao from '../models/optionsModel';
+import optionsTypes from '../models/optionTypes';
+
+let optionsDao = new OptionsDao();
+class OptionController extends BaseController {
+    //获得所有选项类型的选项
+    async getOptions(req, res){
+        let resJson = {error: null, message: '', data: []};
+        let user_id = req.session.sessionUser.id,
+            compilation_id = req.session.sessionCompilation._id;
+        let defaultOpts = {
+            GENERALOPTS: {
+                rationQuanACToBillsQuan: true,//自动根据清单工程量填写定额工程量
+                rationQuanACToRationUnit: true//自动根据定额单位转换定额工程量
+            }
+        };
+        try{
+            resJson.data = await optionsDao.getOptions(user_id, compilation_id);
+            if(!resJson.data){
+                resJson.data = await optionsDao.saveOptions(user_id, compilation_id, optionsTypes.GENERALOPTS, defaultOpts.GENERALOPTS);
+            }
+        }
+        catch (err){
+            resJson.error = true;
+            resJson.message = '获取失败';
+            resJson.data = null;
+        }
+        res.json(resJson);
+    }
+    //获得特定选项类型的选项
+    async getOptionsByType(req, res){
+        let resJson = {error: null, message: '', data: null};
+        let user_id = req.session.sessionUser.id,
+            compilation_id = req.session.sessionCompilation._id,
+            optsType = req.body.optsType;
+        try{
+            let hasThisOpts = false;
+            for(let i in optionsTypes){
+                if(optionsTypes[i] === optsType){
+                    hasThisOpts = true;
+                    break;
+                }
+            }
+            if(!hasThisOpts) throw '不存在此选项类';
+            resJson.data = await optionsDao.getOptionsByType(user_id, compilation_id, optsType);
+        }
+        catch (err){
+            resJson.error = true;
+            resJson.message = '获取失败';
+            resJson.data = null;
+        }
+        res.json(resJson);
+    }
+
+    async saveOptions(req, res){
+        let resJson = {error: null, message: '', data: null};
+        let user_id = req.session.sessionUser.id,
+            compilation_id = req.session.sessionCompilation._id,
+            optsType = req.body.optsType,
+            opts = JSON.parse(req.body.opts);
+        try{
+            let hasThisOpts = false;
+            for(let i in optionsTypes){
+                if(optionsTypes[i] == optsType){
+                    hasThisOpts = true;
+                    break;
+                }
+            }
+            if(!hasThisOpts) throw '不存在此选项类';
+            resJson.data = await optionsDao.saveOptions(user_id, compilation_id, optsType, opts);
+        }
+        catch (err){
+            resJson.error = true;
+            resJson.message = '保存失败';
+            resJson.data = null;
+        }
+        res.json(resJson);
+    }
+}
+
+export default OptionController;

+ 13 - 0
modules/options/models/optionTypes.js

@@ -0,0 +1,13 @@
+/**
+ * Created by Zhong on 2017/9/28.
+ */
+
+/*
+* 用户选项设置的选项类型,目前有常规选项
+* */
+
+const optionsTypes = {
+    GENERALOPTS: 'GENERALOPTS'//常规选项:1.自动根据清单工程量填写定额工程量 2.自动根据定额单位转换定额工程量
+};
+
+export default optionsTypes;

+ 38 - 0
modules/options/models/optionsModel.js

@@ -0,0 +1,38 @@
+/**
+ * Created by Zhong on 2017/9/28.
+ */
+
+import optionsModel from '../models/schemas';
+
+class OptionsDao {
+    async getOptions(user_id, compilation_id){
+        let rst = await optionsModel.find({user_id: user_id, compilation_id: compilation_id});
+        rst = rst.length > 0 && typeof rst[0].options !== 'undefined' ? rst[0].options : null;
+        return rst;
+    }
+
+    async getOptionsByType(user_id, compilation_id, optsType){
+        let rst = await optionsModel.find({user_id: user_id, compilation_id: compilation_id});
+        if(rst.length > 0){
+            let opts = rst[0].options;
+            for(let i = 0, len = opts.length; i < len; i++){
+                if(opts[i].type === optsType){
+                    return opts[i];
+                }
+            }
+        }
+        return null;
+    }
+
+    async saveOptions(user_id, compilation_id, opsType, opts){
+        let optionsData = await optionsModel.find({user_id: user_id, compilation_id: compilation_id});
+        if(optionsData.length === 0){
+            await optionsModel.create({user_id: user_id, compilation_id: compilation_id, options: [{type: opsType, opts: opts}]});
+        }
+        await optionsModel.update({user_id: user_id, compilation_id: compilation_id, 'options.type': opsType}, {$set: {'options.$.opts': opts}});
+        let rst = await optionsModel.find({user_id: user_id, compilation_id: compilation_id});
+        return rst;
+    }
+}
+
+export default OptionsDao;

+ 18 - 0
modules/options/models/schemas.js

@@ -0,0 +1,18 @@
+/**
+ * Created by Zhong on 2017/9/28.
+ */
+import mongoose from 'mongoose';
+
+/*
+* 此选项设置针对绑定用户,对用户该编办下所有项目有效的全局选项
+* */
+let Schema = mongoose.Schema;
+let optionSchema = new Schema({
+    user_id: String,
+    compilation_id: String,
+    options: Array
+}, {versionKey: false});
+
+let optionsModel = mongoose.model('options', optionSchema);
+
+export default optionsModel;

+ 17 - 0
modules/options/routes/routes.js

@@ -0,0 +1,17 @@
+/**
+ * Created by Zhong on 2017/9/28.
+ */
+import express from 'express';
+import OptionsController from '../controllers/optionsController';
+
+let router = express.Router();
+let optionsController = new OptionsController();
+
+module.exports = function (app) {
+    router.post('/getOptions', optionsController.init, optionsController.getOptions);
+    router.post('/getOptionsByType', optionsController.init, optionsController.getOptionsByType);
+    router.post('/saveOptions', optionsController.init, optionsController.saveOptions);
+
+
+    app.use('/options', router);
+};

+ 3 - 2
modules/pm/models/project_model.js

@@ -160,7 +160,7 @@ ProjectsDAO.prototype.rename = async function (userId, data, callback){
         if (data.newName === undefined || data.newName === '') {
             throw '请填写名称!';
         }
-
+        data.newName = data.newName.trim();
         // 查找同级是否存在同名数据
         let exist = await this.isExist(data.newName, data.parentID);
         if (exist) {
@@ -226,7 +226,8 @@ ProjectsDAO.prototype.isExist = async function(name, parentID) {
     if (name === '' || isNaN(parentID)) {
         return true;
     }
-    let count = await Projects.count({ParentID: parentID, name: name});
+    let condition = {ParentID: parentID, name: name, "$or":[{deleteInfo: null}, {"deleteInfo.deleted": false}]};
+    let count = await Projects.count(condition);
     return count > 0;
 };
 

+ 1 - 1
modules/users/routes/boot_route.js

@@ -13,6 +13,6 @@ module.exports=function (app){
     let bootController = new BootController();
 
 // 引导页面
-    router.get('/:compilation', bootController.boot);
+    router.get('/:compilation', bootController.init, bootController.boot);
     app.use('/boot', router);
 };

+ 25 - 1
package.json

@@ -30,7 +30,31 @@
     "uuid": "^3.1.0",
     "ioredis":"^3.1.4",
     "log4js":"~2.3.3",
-    "pdfkit": "^0.8.2"
+    "pdfkit": "^0.8.2",
+    "del": "^1.1.1",
+    "gulp": "^3.9.0",
+    "gulp-autoprefixer": "^3.0.1",
+    "gulp-babel": "^6.1.1",
+    "babel-core": "^6.4.0",
+    "gulp-cache": "^0.2.8",
+    "gulp-cssnano": "^2.0.0",
+    "gulp-eslint": "^0.13.2",
+    "gulp-htmlmin": "^1.3.0",
+    "gulp-if": "^1.2.5",
+    "gulp-imagemin": "^2.2.1",
+    "gulp-load-plugins": "^0.10.0",
+    "gulp-plumber": "^1.0.1",
+    "gulp-sass": "^2.0.0",
+    "gulp-size": "^1.2.1",
+    "gulp-sourcemaps": "^1.5.0",
+    "gulp-uglify": "^1.1.0",
+    "gulp-useref": "^3.0.0",
+    "gulp-inject":"^4.3.0",
+    "gulp-concat": "^2.6.1",
+    "main-bower-files": "^2.5.0",
+    "wiredep": "^2.2.2",
+    "gulp-uglify-es":"^0.1.3",
+    "run-sequence":"^2.2.0"
   },
   "scripts": {
     "start": "C:\\Users\\mai\\AppData\\Roaming\\npm\\babel-node.cmd server.js"

+ 1 - 1
public/web/tree_sheet/tree_sheet_helper.js

@@ -336,7 +336,7 @@ var TREE_SHEET_HELPER = {
                 $(this._toolTipElement).show("fast");
             }
         };
-        TipCellType.prototype.processMouseLeave = function (hininfo) {
+        TipCellType.prototype.processMouseLeave = function (hitinfo) {
             if (this._toolTipElement) {
                 document.body.removeChild(this._toolTipElement);
                 this._toolTipElement = null;

+ 0 - 1
web/building_saas/complementary_glj_lib/html/tools-gongliaoji.html

@@ -132,7 +132,6 @@
                                   <input type="radio" class="glj-radio" name="glj" value="allGljs">所有工料机&nbsp;&nbsp;
                                   <input type="radio" class="glj-radio" name="glj" value="stdGljs">标准工料机&nbsp;&nbsp;
                                   <input type="radio" class="glj-radio" name="glj" value="complementaryGljs">补充工料机&nbsp;&nbsp;
-                                  <input type="radio" class="glj-radio" name="glj" value="selectedGljs">已选工料机机&nbsp;&nbsp;
                                  <!-- <div class="form-group"><input id="searchGlj" type="text" class="form-control-sm" placeholder="查询工料机"></div>-->
                               </div>
                               <div class="modal-auto-height col-12" style="overflow: hidden" id="componentSheet">

+ 39 - 60
web/building_saas/complementary_glj_lib/js/components.js

@@ -20,10 +20,7 @@ let componentOprObj = {
             {headerName:"计量单位",headerWidth:80,dataCode:"unit", dataType: "String", hAlign: "center", vAlign: "center"},
             {headerName:"单价",headerWidth:80,dataCode:"basePrice", dataType: "Number", formatter: "0.00", hAlign: "right", vAlign: "center"},
             {headerName:"类型",headerWidth:80,dataCode:"gljType", dataType: "String",  hAlign: "center", vAlign: "center"}
-        ],
-        view: {
-            lockedCells: [1, 2, 3]
-        }
+        ]
     },
     buildSheet: function (container) {
         let me = componentOprObj;
@@ -32,24 +29,20 @@ let componentOprObj = {
         me.workBook.getSheet(0).setFormatter(-1, 1, "@", GC.Spread.Sheets.SheetArea.viewport);
         me.workBook.getSheet(0).options.isProtected = true;
         me.workBook.bind(GC.Spread.Sheets.Events.ButtonClicked, me.onButtonClicked);//复选框点击事件
-        //sheetOpr.cleanSheet(me.workBook.getSheet(0), me.setting, -1);
         me.componentsBtnOpr($('#componentsConf'));
         me.radiosChange();
-        //me.searchChange();
     },
     onButtonClicked: function (sender, args) {
         let me = componentOprObj, re = repositoryGljObj;
         let val = args.sheet.getValue(args.row, args.col);
         let thisComponent = me.currentCache[args.row];
         thisComponent.isChecked = val;
-        console.log(val);
         if(args.sheet.isEditing()){
             args.sheet.endEdit(true);
         }
         else{
             //维护选中组成物列表
             if(val === true){
-                //解决复选框编辑状态的暂时方法todo
                 let isExist = false;
                 for(let i = 0, len = me.selectedList.length; i < len; i++){
                     if(me.selectedList[i].ID === thisComponent.ID){
@@ -68,7 +61,7 @@ let componentOprObj = {
                         break;
                     }
                 }
-                if($("input[name='glj']:checked").val() === 'selectedGljs'){//radio为已选工料机时
+            /*    if($("input[name='glj']:checked").val() === 'selectedGljs'){//radio为已选工料机时
                     me.showGljList = [];
                     me.setShowGljList(me.selectedList, false);
                     re.sortGlj(me.showGljList);
@@ -80,16 +73,17 @@ let componentOprObj = {
                     } else {
                         me.currentCache = me.getCache();
                     }
-                }
+                }*/
             }
         }
     },
     setShowGljList: function (gljList, clearChecked) {
-        //初始为所有工料机,机械类型可添加机械组成物,混凝土,砂浆、配合比可添加普通材料
+        //初始为所有工料机,机械类型可添加机械组成物、机上人工,混凝土,砂浆、配合比可添加普通材料
+        let machineArr = [302, 303];
         let materialArr = [202, 203, 204];//混凝土、砂浆、配合比, 201普通材料
         let that = repositoryGljObj, me = componentOprObj;
             for(let i = 0; i < gljList.length; i++){
-                if(that.currentGlj.gljType === 301 && gljList[i].gljType === 302 ||
+                if(that.currentGlj.gljType === 301 && machineArr.indexOf(gljList[i].gljType) !== -1 ||
                     materialArr.indexOf(that.currentGlj.gljType) !== -1 && gljList[i].gljType === 201){
                     //去除与已添加的组成物重复的条目
                     let isExist = false;
@@ -101,17 +95,13 @@ let componentOprObj = {
                     }
                     if(!isExist){
                         if(clearChecked){
-                            gljList[i].isChecked = false;//切换的时候清空选择
+                            gljList[i].isChecked = false;
                         }
-                       /* if(isSelected){//已选择工料机显示
-                            if(gljList[i].isChecked === true){
-                                me.showGljList.push(gljList[i]);
-                            }
-                        }*/
-                   //     else{
-                            me.showGljList.push(gljList[i]);
-                      //  }
                     }
+                    else {
+                        gljList[i].isChecked = true;
+                    }
+                    me.showGljList.push(gljList[i]);
                 }
             }
     },
@@ -120,7 +110,7 @@ let componentOprObj = {
         let that = repositoryGljObj, me = componentOprObj;
         $('#searchGlj').val('');//恢复搜索文本
         //初始化组成物列表
-        me.selectedList = [];
+        me.selectedList = [].concat(that.currentComponent);
         //默认radio所有工料机
         if(typeof $("input[name='glj']:checked")[0] !== 'undefined'){
             $("input[name='glj']:checked")[0].checked = false;
@@ -156,11 +146,6 @@ let componentOprObj = {
             else if(me.radiosSelected === 'complementaryGljs'){
                 me.setShowGljList(re.complementaryGljList);
             }
-            else if(me.radiosSelected === 'selectedGljs'){
-                /*me.setShowGljList(re.stdGljList, false, true);
-                me.setShowGljList(re.complementaryGljList, false, true);*/
-                me.setShowGljList(me.selectedList, false);
-            }
             re.sortGlj(me.showGljList);
             //重新显示
             me.showGljItems(me.showGljList, me.gljCurTypeId);
@@ -177,31 +162,7 @@ let componentOprObj = {
             }
         });
     },
-    //实时模糊搜索
-    searchChange: function () {
-        let me = componentOprObj, re = repositoryGljObj;
-        let interval = null;
-        function search(){
-            console.log($('#searchGlj').val());
-        }
-        $('#searchGlj').focus(function () {
-            interval = setInterval(search, 500);
-        }).blur(function () {
-            clearInterval(interval);
-        });
-    },
-  /*  //切换分类树时,记住当前分类的选择, value = true、false、null
-    setComponentChecked: function (sheet) {
-        let me = componentOprObj;
-        for(let i = 0; i < sheet.getRowCount(); i ++){
-            if(sheet.getValue(i, 0) === true){//选择了
-                me.preCache[i].isChecked = true;
-            }
-            else if(sheet.getValue(i, 0) === false){//避免value为null
-                me.preCache[i].isChecked = false;
-            }
-        }
-    },*/
+
     //获得选择的组成物
     getComponents: function () {
         let rst = [];
@@ -249,7 +210,8 @@ let componentOprObj = {
             sheetOpr.cleanSheet(me.workBook.getSheet(0), me.setting, -1);
             sheetOpr.showData(me.workBook.getSheet(0), me.setting, cacheSection, re.distTypeTree);
             me.workBook.getSheet(0).options.isProtected = true;
-            me.workBook.getSheet(0).setRowCount(cacheSection);
+            me.workBook.getSheet(0).setRowCount(cacheSection.length);
+            sheetOpr.setLockCols(me.workBook.getSheet(0), [4], true);
             cacheSection = null;
         }
     },
@@ -257,16 +219,33 @@ let componentOprObj = {
     componentsBtnOpr: function (conf) {//确定、取消、关闭按钮
         let me = componentOprObj, that = gljComponentOprObj, re = repositoryGljObj;
         conf.click(function () {
-           //添加选择添加的组成物
+            //添加选择添加的组成物
             let updateArr = [];
-            if(me.selectedList.length > 0){
-                for(let i = 0, len = me.selectedList.length; i < len; i++){
-                    re.currentGlj.component.push({ID: me.selectedList[i].ID, consumeAmt: 0});
+            let newComponent = [];
+            //re.currentGlj.component = [];
+            for(let i = 0, len = me.selectedList.length; i < len; i++){
+                let isExist = false;
+                for(let j = 0, jLen = re.currentGlj.component.length; j < jLen; j++){
+                    if(me.selectedList[i].ID === re.currentGlj.component[j].ID){
+                        newComponent.push({ID: me.selectedList[i].ID, consumeAmt: re.currentGlj.component[j].consumeAmt});
+                        isExist = true;
+                        break;
+                    }
+                }
+                if(!isExist){
+                    newComponent.push({ID: me.selectedList[i].ID, consumeAmt: 0});
                 }
-                updateArr.push(re.currentGlj);
-                that.updateComponent(updateArr);
+                //re.currentGlj.component.push({ID: me.selectedList[i].ID, consumeAmt: 0});
             }
-
+            re.currentGlj.component = newComponent;
+            let gljBasePrc = that.reCalGljBasePrc(re.getCurrentComponent(re.currentGlj.component));
+            if(gljBasePrc !== re.currentGlj.basePrice){
+                re.currentGlj.basePrice = gljBasePrc;
+                re.reshowGljBasePrc(re.currentGlj);
+                //updateBasePrc.push({gljId: that.currentGlj.ID, gljType: that.currentGlj.gljType, basePrice: that.currentGlj.basePrice});
+            }
+            updateArr.push(re.currentGlj);
+            that.updateComponent(updateArr);
         });
     }
 };

+ 19 - 20
web/building_saas/complementary_glj_lib/js/glj.js

@@ -45,7 +45,7 @@ let repositoryGljObj = {
             {headerName:"编码",headerWidth:140,dataCode:"code", dataType: "String", formatter: "@", hAlign: "left", vAlign: "center"},
             {headerName:"名称",headerWidth:280,dataCode:"name", dataType: "String", hAlign: "left", vAlign: "center"},
             {headerName:"规格型号",headerWidth:180,dataCode:"specs", dataType: "String", hAlign: "left", vAlign: "center"},
-            {headerName:"计量单位",headerWidth:120,dataCode:"unit", dataType: "String", hAlign: "center", vAlign: "center"},
+            {headerName:"单位",headerWidth:120,dataCode:"unit", dataType: "String", hAlign: "center", vAlign: "center"},
             {headerName:"基价单价",headerWidth:120,dataCode:"basePrice", dataType: "Number", formatter: "0.00", hAlign: "right", vAlign: "center"},
             {headerName:"类型",headerWidth:120,dataCode:"gljType", dataType: "String", hAlign: "center", vAlign: "center"},
             {headerName:"是否新增",headerWidth:80,dataCode:"isComplementary", hAlign: "center", vAlign: "center"}
@@ -182,7 +182,7 @@ let repositoryGljObj = {
                     cacheSection.push(data[i]);
                 }
             }
-            sheetOpr.cleanSheet(me.workBook.getSheet(0), me.setting, -1);
+            sheetOpr.cleanData(me.workBook.getSheet(0), me.setting, -1);
             sheetOpr.showData(me.workBook.getSheet(0), me.setting, cacheSection, me.distTypeTree);
 
             cacheSection = null;
@@ -296,6 +296,7 @@ let repositoryGljObj = {
             sheetOpr.cleanSheet(that.workBook.getSheet(0), that.setting, -1);
             me.workBook.focus(true);
             me.currentComponent = [];
+            that.workBook.getSheet(0).setRowCount(5);
             if(row < me.currentCache.length){
                 //标记当前工料机
                 me.currentGlj = me.currentCache[row];
@@ -335,19 +336,19 @@ let repositoryGljObj = {
                 let focusToCol;
                 function getFocusToCol (me){
                     if(!me.addGljObj[me.setting.header[0].dataCode]){
-                        $('#alertGljTxt').text('编号不能为空,是否取消增加工料机?');
+                        $('#alertGljTxt').text('编号不能为空,继续增加工料机?');
                         return 0;
                     }
                     else if(!me.addGljObj[me.setting.header[1].dataCode]){
-                        $('#alertGljTxt').text('名称不能为空,是否取消增加工料机?');
+                        $('#alertGljTxt').text('名称不能为空,继续增加工料机?');
                         return 1;
                     }
                     else if(!me.addGljObj[me.setting.header[3].dataCode]){
-                        $('#alertGljTxt').text('计量单位不能为空,是否取消增加工料机?');
+                        $('#alertGljTxt').text('计量单位不能为空,继续增加工料机?');
                         return 3;
                     }
                     else if(!me.addGljObj[me.setting.header[5].dataCode]){
-                        $('#alertGljTxt').text('类型不能为空,是否取消增加工料机?');
+                        $('#alertGljTxt').text('类型不能为空,继续增加工料机?');
                         return 5;
                     }
                     else {
@@ -362,7 +363,7 @@ let repositoryGljObj = {
                     $('#gljAlertBtn').click();
                     //me.workBook.getSheet(0).options.isProtected = true;
                     sheetOpr.lockAllCells(args.sheet);
-                    $('#aleCanceBtn').click(function () {
+                    $('#aleConfBtn').click(function () {
                         // me.workBook.getSheet(0).options.isProtected = false;
                         sheetOpr.unLockAllCells(args.sheet);
                         sheetOpr.reLockSomeCodes(args.sheet, 0, repositoryGljObj.currentCache.length);
@@ -374,25 +375,22 @@ let repositoryGljObj = {
                         sheetOpr.reLockSomeCodes(args.sheet, 0, repositoryGljObj.currentCache.length);
                         me.workBook.getSheet(0).setActiveCell(me.editingRowIdx, focusToCol);
                     });
-                    $('#aleConfBtn').click(function () {
+                    $('#aleCanceBtn').click(function () {
                         // me.workBook.getSheet(0).options.isProtected = false;
                         sheetOpr.unLockAllCells(args.sheet);
                         sheetOpr.reLockSomeCodes(args.sheet, 0, repositoryGljObj.currentCache.length);
                         me.addGljObj = null;
+                        me.workBook.getSheet(0).suspendPaint();
+                        me.workBook.getSheet(0).suspendEvent();
                         for(let col=0; col<me.setting.header.length; col++){
-                            let field = me.setting.header[col].dataCode;
-                            if(field === 'gljType'){
-                                me.workBook.getSheet(0).getCell(me.editingRowIdx, col).value(
-                                    typeof me.currentEditingGlj[field] !== 'undefined'?
-                                    me.distTypeTree.distTypes[me.distTypeTree.prefix + me.currentEditingGlj[field]].data.fullName
-                                    : '');
-                            }
-                            else{
+                            if(col === 0){
                                 me.workBook.getSheet(0).getCell(me.editingRowIdx, 0).formatter("@");
-                                me.workBook.getSheet(0).getCell(me.editingRowIdx, col).value(me.currentEditingGlj[me.setting.header[col].dataCode]);
                             }
+                            me.workBook.getSheet(0).getCell(me.editingRowIdx, col).value('');
                         }
                         me.workBook.getSheet(0).setActiveCell(me.editingRowIdx, 0);
+                        me.workBook.getSheet(0).resumePaint();
+                        me.workBook.getSheet(0).resumeEvent();
                     });
                 }
             }
@@ -441,7 +439,7 @@ let repositoryGljObj = {
                                 if(me.componentGljType.indexOf(me.currentEditingGlj.gljType) !== -1 &&
                                     !(me.currentEditingGlj.gljType === 302 && rObj.gljType === 303) && !(me.currentEditingGlj.gljType === 303 && rObj.gljType === 302)){//修改了原本是组成物的工料机
                                     //寻找所有引用了此组成物的工料机,并从组成物中删去此工料机,并重算单价
-                                    let updateGljs = me.getUpdateGljs(rObj);
+                                    let updateGljs = me.getUpdateGljs(rObj, true);
                                     if(updateGljs.updateArr.length > 0 || updateGljs.updateBasePrcArr.length > 0){
                                         for(let i = 0; i < updateGljs.updateArr.length; i++){
                                             updateArr.push(updateGljs.updateArr[i]);
@@ -451,6 +449,8 @@ let repositoryGljObj = {
                                         }
                                     }
                                 }
+                            sheetOpr.cleanData(that.workBook.getSheet(0), that.setting, 5);
+                            that.isLocked = me.allowComponent.indexOf(rObj.gljType) !== -1 ? false : true;
                         }
                         else if(rObj.basePrice !== me.currentEditingGlj.basePrice){//修改了单价,可修改单价的必为可成为组成物的
                             //寻找所有引用了此组成物的工料机,并从组成物中删去此工料机,并重算单价
@@ -470,7 +470,6 @@ let repositoryGljObj = {
                     }
                     else{
                         if(me.setting.header[args.col].dataCode === 'gljType'){
-                            console.log(me.distTypeTree);
                             let distTypeVal =  me.distTypeTree.distTypes[me.distTypeTree.prefix + me.currentEditingGlj[me.setting.header[args.col].dataCode]].data.fullName;
                             args.sheet.setValue(args.row, args.col, distTypeVal);
                         }
@@ -1052,7 +1051,7 @@ let gljTypeTreeOprObj = {
         //消除新增到一半的数据
         me.addGljObj = null;
         //me.currentCache = me.getCache();
-        sheetOpr.cleanSheet(that.workBook.getSheet(0), that.setting, 5);
+        sheetOpr.cleanData(that.workBook.getSheet(0), that.setting, 5);
         that.workBook.getSheet(0).getRange(-1, 0 , -1, 1, GC.Spread.Sheets.SheetArea.viewport).locked(true);
         that.workBook.getSheet(0).getRange(-1, 4 , -1, 1, GC.Spread.Sheets.SheetArea.viewport).locked(true);
         me.workBook.getSheet(0).getRange(-1, 6 , -1, 1, GC.Spread.Sheets.SheetArea.viewport).locked(true);

+ 3 - 3
web/building_saas/complementary_glj_lib/js/gljComponent.js

@@ -23,7 +23,7 @@ let gljComponentOprObj = {
         me.workBook.getSheet(0).setColumnWidth(0, 20, GC.Spread.Sheets.SheetArea.rowHeader);
         me.workBook.getSheet(0).setFormatter(-1, 0, "@", GC.Spread.Sheets.SheetArea.viewport);
         me.workBook.getSheet(0).options.isProtected = true;
-        sheetOpr.cleanSheet(me.workBook.getSheet(0), me.setting, -1);
+        sheetOpr.cleanData(me.workBook.getSheet(0), me.setting, -1);
 
         me.onContextmenuOpr();//右键菜单
         me.gljComponentDelOpr();
@@ -468,11 +468,11 @@ let gljComponentOprObj = {
             success: function (result) {
                 if(!result.error){
                         that.currentComponent =  that.getCurrentComponent(result.data[0].component);
-                        sheetOpr.cleanSheet(me.workBook.getSheet(0), me.setting, -1);
+                        sheetOpr.cleanData(me.workBook.getSheet(0), me.setting, -1);
                         sheetOpr.showData(me.workBook.getSheet(0), me.setting, that.currentComponent);
                 }
                 else{
-                    sheetOpr.cleanSheet(me.workBook.getSheet(0), me.setting, -1);
+                    sheetOpr.cleanData(me.workBook.getSheet(0), me.setting, -1);
                 }
                 $('#componentsCacnel').click();
             }

+ 25 - 2
web/building_saas/complementary_glj_lib/js/sheetOpr.js

@@ -80,6 +80,14 @@ let sheetOpr = {
         sheet.resumeEvent();
         sheet.resumePaint();
     },
+    cleanData: function(sheet, setting, rowCount) {
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        sheet.clear(-1, 0, -1, setting.header.length, GC.Spread.Sheets.SheetArea.viewport, GC.Spread.Sheets.StorageType.data);
+        if (rowCount > 0) sheet.setRowCount(rowCount);
+        sheet.resumeEvent();
+        sheet.resumePaint();
+    },
     setAreaAlign: function(area, hAlign, vAlign){
         if (!(hAlign) || hAlign === "left") {
             area.hAlign(GC.Spread.Sheets.HorizontalAlign.left);
@@ -324,11 +332,15 @@ let sheetOpr = {
         sheet.resumeEvent();
     },
     unLockAllCells: function (sheet) {
+        sheet.suspendPaint();
+        sheet.suspendEvent();
         let defaultStyle = new GC.Spread.Sheets.Style();
         defaultStyle.locked = false;
         sheet.setDefaultStyle(defaultStyle, GC.Spread.Sheets.SheetArea.viewport);
         sheet.setStyle(-1, 0, defaultStyle);
         sheet.options.isProtected = false;
+        sheet.resumePaint();
+        sheet.resumeEvent();
     },
     lockAllCells: function (sheet) {
         sheet.suspendPaint();
@@ -344,13 +356,13 @@ let sheetOpr = {
         sheet.resumeEvent();
     },
     lockSomeCodes: function (sheet, beginRow, endRow) {
+        sheet.suspendPaint();
+        sheet.suspendEvent();
         let defaultStyle = new GC.Spread.Sheets.Style();
         defaultStyle.locked = false;
         sheet.setDefaultStyle(defaultStyle, GC.Spread.Sheets.SheetArea.viewport);
         let style = new  GC.Spread.Sheets.Style();
         style.locked = true;
-        sheet.suspendPaint();
-        sheet.suspendEvent();
         for(let i = beginRow; i < endRow; i++){
             sheet.setStyle(i, 0, style);
         }
@@ -358,6 +370,17 @@ let sheetOpr = {
         sheet.resumePaint();
         sheet.resumeEvent();
     },
+    setLockCols: function (sheet, cols, locked) {
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        for(let i = 0, len = cols.length; i < len; i++){
+            for(let row = 0, rLen = sheet.getRowCount(); row < rLen; row++){
+                sheet.getCell(row, cols[i]).locked(locked);
+            }
+        }
+        sheet.resumePaint();
+        sheet.resumeEvent();
+    },
     lockCodeCells: function (sheet, rowCount) {
         let sheetRowCount = sheet.getRowCount();
         let defaultStyle = new GC.Spread.Sheets.Style();

+ 3 - 2
web/building_saas/css/main.css

@@ -305,6 +305,7 @@ body {
   background:#fff;
   border-bottom:1px solid #ddd
 }
-.gc-column-header-cell{
-    text-align: center!important;
+.navbar-crumb span{
+  max-width: 200px;
+  display: inline-block;
 }

+ 26 - 2
web/building_saas/glj/html/glj_index.html

@@ -1,5 +1,5 @@
 <style type="text/css">
-    .copy{
+    .copy,#save-as-tips{
         display: none;
     }
 </style>
@@ -7,7 +7,7 @@
     <div class="form-inline py-1">
         <label class="mx-2">当前使用:<span id="used-name"></span>(<a href="#" id="pop-dj" data-original-title="" title=""><span id="used-count">0</span> 单位工程使用</a>)
             <a class="btn btn-sm ml-1" href="#" data-toggle="modal" data-target="#change-dj"><i class="fa fa-exchange"></i> 选择其他</a>
-            <a class="btn btn-sm ml-1" href="#" data-toggle="modal" data-target="#copy-dj"><i class="fa fa-files-o"></i> 另存单独用</a></label>
+            <a class="btn btn-sm ml-1" href="#" data-toggle="modal" data-target="#file-save-as-dialog"><i class="fa fa-files-o"></i> 另存单独用</a></label>
     </div>
 </div>
 <div class="container-fluid">
@@ -95,6 +95,30 @@
         </div>
     </div>
 </div>
+<!--弹出 另存新文件-->
+<div class="modal fade" id="file-save-as-dialog" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">另存新费率文件</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <div class="form-group">
+                    <label>单价文件名称</label>
+                    <input class="form-control" id="save-as-name" value="">
+                    <small class="form-text text-danger" id="save-as-tips">已存在同名单价文件。</small>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                <a href="javascript:void(0);" class="btn btn-primary" id="save-as-confirm">确定</a>
+            </div>
+        </div>
+    </div>
+</div>
 <script type="text/javascript" src="/web/building_saas/glj/js/project_glj.js"></script>
 <script type="text/javascript" src="/web/building_saas/glj/js/composition.js"></script>
 <script type="text/javascript" src="/web/building_saas/glj/js/common_spread.js"></script>

+ 41 - 0
web/building_saas/glj/js/project_glj.js

@@ -79,6 +79,47 @@ $(document).ready(function () {
         });
     });
 
+    // 单价文件另存为弹框
+    $("#file-save-as-dialog").on('shown.bs.modal', function() {
+        // 获取当前建设项数据
+        $("#save-as-name").val(usedUnitPriceInfo.name + '(复件)');
+    });
+
+    // 单价文件另存为操作
+    $("#save-as-confirm").click(function() {
+        let name = $("#save-as-name").val();
+        if (name === '') {
+            $("#save-as-tips").text('请填写单价文件名称').show();
+            return false;
+        }
+        if (isChanging) {
+            return false;
+        }
+
+        $.ajax({
+            url: '/glj/save-as',
+            type: 'post',
+            data: {name: name, project_id: scUrlUtil.GetQueryString('project')},
+            dataType: 'json',
+            error: function() {
+                isChanging = false;
+            },
+            beforeSend: function() {
+                isChanging = true;
+            },
+            success: function(response) {
+                isChanging = false;
+                if (response.err === 1) {
+                    let msg = response.msg !== undefined && response.msg !== '' ? response.msg : '另存为失败!';
+                    $("#save-as-tips").text(msg).show();
+                    return false;
+                }
+                $("#file-save-as-dialog").modal("hide");
+            }
+        });
+
+    });
+
     // 从其他建设项目中复制 选择建设项目
     $("#other-project").change(function() {
         let projectId = $(this).val();

+ 10 - 14
web/building_saas/js/global.js

@@ -21,11 +21,11 @@ function autoFlashHeight(){
 $(window).resize(autoFlashHeight);
 /*全局自适应高度结束*/
 $(function(){
-    /*侧滑*/
-    $(".open-sidebar").click(function(){
-        $(".slide-sidebar").animate({width:"800"}).addClass("open");
-    });
-    $("body").click(function(event){
+/*侧滑*/
+$(".open-sidebar").click(function(){
+    $(".slide-sidebar").animate({width:"800"}).addClass("open");
+});
+$("body").click(function(event){
         var e = event || window.event; //浏览器兼容性
         if(!$(event.target).is('a')) {
             var elem = event.target || e.srcElement;
@@ -39,13 +39,9 @@ $(function(){
         }
 
     });
-    /*侧滑*/
-    /*工具提示*/
-    $(function () {
-        $('[data-toggle="tooltip"]').tooltip()
-    });
-    /*工具提示*/
-    $(function () {
-        $('[data-toggle="popover"]').popover()
-    });
+/*侧滑*/
+/*工具提示*/
+$(function () {
+  $('[data-toggle="tooltip"]').tooltip()
+});
 });

+ 1 - 1
web/building_saas/js/message.js

@@ -92,7 +92,7 @@ $(document).ready(function() {
                 }
                 $("#message-content .title").text(messageData.message.title);
                 $("#message-content .time").text('发布:' + moment(messageData.message.release_time).format('YYYY-MM-DD HH:mm:ss'));
-                $("#message-content .content").html(messageData.message.content);
+                $("#message-content .content-area").html(messageData.message.content);
                 $("#message-content").show();
             }
         });

+ 53 - 13
web/building_saas/main/html/main.html

@@ -16,8 +16,6 @@
     <link rel="stylesheet" href="/lib/spreadjs/views/gc.spread.views.dataview.10.0.0.css">
     <!-- jquery.contextmenu -->
     <link rel="stylesheet" href="/lib/jquery-contextmenu/jquery.contextMenu.css" type="text/css">
-    <script src="/lib/jquery/jquery.min.js"></script>
-    <script src="/web/building_saas/js/global.js"></script>
     <script>
         // 这里的变量供页面调用
         var userAccount = '<%- userAccount %>';
@@ -42,7 +40,8 @@
                     <a class="nav-link" href="#" aria-expanded="false" data-toggle="modal" data-target="#poj-set"><i class="fa fa-cube"></i> 项目属性</a>
                 </li>
                 <li class="nav-item">
-                    <a class="nav-link" href="#" aria-haspopup="true" aria-expanded="false"><i class="fa fa-sliders"></i> 选项</a>
+                    <a class="nav-link" href="#" aria-expanded="false" data-toggle="modal" data-target="#opts-set"><i class="fa fa-sliders"></i> 选项</a>
+                    <!--<a class="nav-link" href="#" aria-haspopup="true" aria-expanded="false"><i class="fa fa-sliders"></i> 选项</a>-->
                 </li>
                 <li class="nav-item dropdown">
                     <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-wrench"></i> 工具</a>
@@ -480,7 +479,7 @@
                                         <select class="col-4 form-control form-control-sm"><option>渝建[2016]71号</option><option>渝建[2017]78号</option></select>
                                     </div>
                                     <div style="height:8px;"></div>
-                                    <div class="modal-auto-height" id="labourCoeSpread" />
+                                    <div class="modal-auto-height" id="labourCoeSpread"></div>
                                 </div>
                             </div>
                         </div>
@@ -493,6 +492,51 @@
             </div>
         </div>
     </div>
+    <!--弹出选项-->
+    <div class="modal fade" id="opts-set" data-backdrop="static">
+        <div class="modal-dialog modal-lg" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h5 class="modal-title">选项</h5>
+                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">&times;</span>
+                    </button>
+                </div>
+                <div class="modal-body">
+                    <div class="row">
+                        <div class="col-3">
+                            <ul class="nav flex-column nav-pills" role="tablist">
+                                <li class="nav-item"><a class="nav-link active" data-toggle="pill" href="#opts-general" role="tab">常规选项</a></li>
+                            </ul>
+                        </div>
+                        <div class="col-9">
+                            <div class="tab-content">
+                                <!--常规选项-->
+                                <div class="tab-pane fade show active" id="opts-general" role="tabpanel">
+                                    <div class="modal-auto-height">
+                                        <fieldset class="form-group">
+                                            <div class="form-check">
+                                                <label class="form-check-label">
+                                                    <input class="form-check-input" name="opts-general-radios" id="generalOpts1" value="opt1" type="checkbox">
+                                                    自动根据清单工程量填写定额工程量
+                                                </label>
+                                            </div>
+                                            <div class="form-check">
+                                                <label class="form-check-label">
+                                                    <input class="form-check-input" name="opts-general-radios" id="generalOpts2" value="opt2" type="checkbox">
+                                                    自动根据定额单位转换定额工程量
+                                                </label>
+                                            </div>
+                                        </fieldset>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
     <!--弹出列设置-->
     <div class="modal fade" id="column" data-backdrop="static">
         <div class="modal-dialog modal-lg" role="document">
@@ -512,19 +556,19 @@
         </div>
     </div>
     <!-- JS. -->
+    <script src="/lib/jquery/jquery.min.js"></script>
+    <script src="/lib/tether/tether.min.js"></script>
+    <script src="/lib/bootstrap/bootstrap.min.js"></script>
+    <script src="/web/building_saas/js/global.js"></script>
     <script type="text/javascript">
         autoFlashHeight();
     </script>
-
-    <script src="/lib/tether/tether.min.js"></script>
-    <script src="/lib/bootstrap/bootstrap.min.js"></script>
     <!--expression calculate-->
     <script src="/lib/JSExpressionEval_src/Date.js"></script>
     <script src="/lib/JSExpressionEval_src/Stack.js"></script>
     <script src="/lib/JSExpressionEval_src/Tokanizer.js"></script>
     <script src="/lib/JSExpressionEval_src/Evaluator.js"></script>
     <!--end expression calculate-->
-    <!--<script type="text/javascript" src="/lib/bootstrap/bootstrap-select.min.js"></script>-->
     <script type="text/javascript" src="/lib/jquery-contextmenu/jquery.contextMenu.js"></script>
     <script type="text/javascript" src="/lib/jquery-contextmenu/jquery.ui.position.js"></script>
     <script type="text/javascript" src="/lib/lodash/lodash.js"></script>
@@ -569,15 +613,11 @@
     <script type="text/javascript" src="/public/web/tree_sheet/tree_sheet_helper.js"></script>
     <script type="text/javascript" src="/public/web/sheet/sheet_data_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/test_bills_calc/bills_grid_setting_test_calc.js"></script>
-    <script type="text/javascript" src="/test/tmp_data/test_bills_calc/bills_data_15690.js"></script>
-    <script type="text/javascript" src="/test/tmp_data/test_bills_calc/drawing_data_10268.js"></script>-->
     <!-- view -->
     <script type="text/javascript" src="/web/building_saas/main/js/views/main_tree_col.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/views/project_info.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/views/project_view.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/views/options_view.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/main_ajax.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/main.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/controllers/project_controller.js"></script>

+ 48 - 22
web/building_saas/main/js/calc/bills_calc.js

@@ -11,25 +11,25 @@ let rationContentCalcFields = [
     {'type': 'common', 'unitFeeFlag': rationContentUnitFeeFlag, 'totalFeeFlag': totalFeeFlag},
     {'type': 'labour', 'unitFeeFlag': rationContentUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
     {'type': 'material', 'unitFeeFlag': rationContentUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
-    {'type': 'machine', 'unitFeeFlag': rationContentUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
+    {'type': 'machine', 'unitFeeFlag': rationContentUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag}
 ];
 let rationPriceCalcFields = [
     {'type': 'common', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': totalFeeFlag},
     {'type': 'labour', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
     {'type': 'material', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
-    {'type': 'machine', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
+    {'type': 'machine', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag}
 ];
 let rationPriceConverseCalcFields = [
     {'type': 'common', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
     {'type': 'labour', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
     {'type': 'material', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
-    {'type': 'machine', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
+    {'type': 'machine', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag}
 ];
 let billsPriceCalcFields = [
     {'type': 'common', 'unitFeeFlag': billsPriceUnitFeeFlag, 'totalFeeFlag': totalFeeFlag},
     {'type': 'labour', 'unitFeeFlag': billsPriceUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
     {'type': 'material', 'unitFeeFlag': billsPriceUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
-    {'type': 'machine', 'unitFeeFlag': billsPriceUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
+    {'type': 'machine', 'unitFeeFlag': billsPriceUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag}
 ];
 
 let nodeCalcObj = {
@@ -40,7 +40,11 @@ let nodeCalcObj = {
     sumTotalFee: function() {
         let result = 0, child;
         for (child of this.node.children) {
-            result += this.getFee(child.data, this.field.totalFee);
+            let value = this.getFee(child.data, this.field.totalFee);
+            if (Object.prototype.toString.apply(value) === "[object String]") {
+                value = parseFloat(value);
+            }
+            result += value;
         }
         return result;
     },
@@ -48,6 +52,9 @@ let nodeCalcObj = {
         let result = 0, child, qty;
         result = this.sumTotalFee(this.field);
         qty = this.getFee(this.node.data, 'quantity');
+        if (Object.prototype.toString.apply(qty) === "[object String]") {
+            qty = parseFloat(qty);
+        }
         if (qty !== 0) {
             result = result / qty;
         }
@@ -58,11 +65,22 @@ let nodeCalcObj = {
     },
     rationContentUnitFee: function () {
         let result = 0, child, qty = this.getFee(this.node.data, 'quantity');
+        if (Object.prototype.toString.apply(qty) === "[object String]") {
+            qty = parseFloat(qty);
+        }
         if (qty === 0) {
             qty = 1;
         }
         for (child of this.node.children) {
-            result += (this.getFee(child.data, this.field.unitFee) * this.getFee(child.data, 'quantity') / qty).toDecimal(this.digit);
+            let childUnitFee = this.getFee(child.data, this.field.unitFee);
+            if (Object.prototype.toString.apply(childUnitFee) === "[object String]") {
+                childUnitFee = parseFloat(childUnitFee);
+            }
+            let childQuantity = this.getFee(child.data, 'quantity');
+            if (Object.prototype.toString.apply(childQuantity) === "[object String]") {
+                childQuantity = parseFloat(childQuantity);
+            }
+            result += (childUnitFee * childQuantity / qty).toDecimal(this.digit);
         }
         return result;
     }
@@ -220,21 +238,26 @@ class BillsCalcHelper {
     constructor (project, CalcFlag) {
         this.project = project;
         this.CalcFlag = CalcFlag;
-        switch (this.CalcFlag) {
-            case rationContent:
-                this.calcField = rationContentCalcFields;
-                break;
-            case rationPrice:
-                this.calcField = rationPriceCalcFields;
-                break;
-            case rationPriceConverse:
-                this.calcField = rationPriceConverseCalcFields;
-                break;
-            case billsPrice:
-                this.calcField = billsPriceCalcFields;
-                break;
-            default:
-                this.calcField = [];
+        this.calcField = JSON.parse(JSON.stringify(feeType));
+        for (let field of this.calcField) {
+            // unitFeeCalcFlag
+            if (this.calcFlag === rationContent) {
+                field.unitFeeFlag = rationContentUnitFeeFlag;
+            } else if ( this.calcFlag === billsPrice) {
+                field.unitFeeFlag = billsPriceUnitFeeFlag;
+            } else {
+                field.unitFeeFlag = averageQtyUnitFeeFlag;
+            }
+            // totalFeeCalcFlag
+            if (field.type === 'common') {
+                if (this.CalcFlag === rationPriceConverse) {
+                    field.totalFeeFlag = sumTotalFeeFlag;
+                } else {
+                    field.totalFeeFlag = totalFeeFlag;
+                }
+            } else {
+                field.totalFeeFlag = sumTotalFeeFlag;
+            }
         }
         this.InitFields(this.calcField);
     };
@@ -289,7 +312,10 @@ class BillsCalcHelper {
         }
     };
     calcVolumePriceLeaf (node, fields) {
-
+        let total = 0;
+        for (let child of this.node.children) {
+            total += this.getFee(child.data, 'feesIndex.common.totalFee');
+        }
     };
     calcParent (node, fields) {
         nodeCalcObj.node = node;

+ 2 - 10
web/building_saas/main/js/controllers/project_controller.js

@@ -104,18 +104,10 @@ ProjectController = {
         }
     },
     calculateAll: function (project, sheetController, CalcType) {
-        let date0 = new Date();
-        let ration_calc = new RationCalcHelper(project);
-        ration_calc.calculateAll();
-        let date1 = new Date();
-        console.log(date1 - date0);
         let calc = new BillsCalcHelper(project, CalcType);
         calc.calcAll();
-        calc = null;
-        let date2 = new Date();
-        console.log(date2 - date1);
         sheetController.showTreeData();
-        let date3 = new Date();
-        console.log(date3 - date1);
+        project.Bills.updateAll();
+        calc = null;
     }
 }

+ 24 - 1
web/building_saas/main/js/models/bills.js

@@ -74,6 +74,10 @@ var Bills = {
                 data.feesIndex = {};
                 if (data.fees) {
                     data.fees.forEach(function (fee) {
+                        fee.unitFee = parseFloat(fee.unitFee);
+                        fee.totalFee = parseFloat(fee.totalFee);
+                        fee.tenderUnitFee = parseFloat(fee.tenderUnitFee);
+                        fee.tenderTotalFee = parseFloat(fee.tenderTotalFee);
                         data.feesIndex[fee.fieldName] = fee;
                     });
                 }
@@ -110,7 +114,7 @@ var Bills = {
             }
             var controller = projectObj.mainController;
             var selected = controller.sheet.getSelections();
-            var col =   _.findIndex(BillsGridSetting.cols,function (col) {
+            var col =   _.findIndex(project.projSetting.main_tree_col.cols,function (col) {
                 return col.data.field ==fieldName;
             });
             controller.sheet.getCell(selected[0].row,col).value(data[fieldName]);
@@ -236,6 +240,25 @@ var Bills = {
             this.project.pushNow('updateBills', this.getSourceType(), updateData);
         };
 
+        bills.prototype.updateAll = function () {
+            let updateData = [];
+            for (let data of this.datas) {
+                let uData = JSON.parse(JSON.stringify(data));
+                delete uData.feesIndex;
+                delete uData.flagsIndex;
+                if (uData.fees) {
+                    for (let fee of uData.fees) {
+                        fee.unitFee = fee.unitFee.toFixed(2);
+                        fee.totalFee = fee.totalFee.toFixed(2);
+                        fee.tenderUnitFee = fee.tenderUnitFee.toFixed(2);
+                        fee.tenderTotalFee = fee.tenderTotalFee.toFixed(2);
+                    }
+                }
+                updateData.push({'updateType': 'ut_update', 'updateData': data});
+            }
+            this.project.pushNow('updateAllBills', this.getSourceType(), updateData);
+        }
+
         return new bills(project);
     }
 };

+ 1 - 1
web/building_saas/main/js/models/calc_program.js

@@ -3615,6 +3615,6 @@ class CalcProgram {
     calculate(treeNode){
         treeNode.data.gljList = this.project.ration_glj.getGljArrByRation(treeNode.data.ID);
         this.calc.calculate(treeNode);
-        projectObj.mainController.showTreeData();
+        projectObj.mainController.refreshTreeNode([treeNode]);
     };
 }

+ 1 - 1
web/building_saas/main/js/models/fee_rate.js

@@ -207,7 +207,7 @@ var FeeRate = {
             }
             var data={
                 "user_id":userID,
-                "rootProjectID":rootProjectID,
+                "rootProjectID":rootProjectID
             };
             CommonAjax.post('/feeRates/getChangeInfo', data, function (data) {
                 callback(data);

+ 1 - 1
web/building_saas/main/js/models/ration.js

@@ -82,7 +82,7 @@ var Ration = {
             }
             var controller = projectObj.mainController;
             var selected = controller.sheet.getSelections();
-            var col =   _.findIndex(BillsGridSetting.cols,function (col) {
+            var col =   _.findIndex(project.projSetting.main_tree_col.cols,function (col) {
                 return col.data.field ==fieldName;
             });
             controller.sheet.getCell(selected[0].row,col).value(data[fieldName]);

+ 1 - 0
web/building_saas/main/js/models/ration_glj.js

@@ -91,6 +91,7 @@ var ration_glj = {
                 } else {
                     this.refreshAfterSave(data);
                 }
+                projectObj.project.projectGLJ.loadData();
             }
         };
         ration_glj.prototype.refreshAfterSave=function(data){

+ 1 - 11
web/building_saas/main/js/views/calc_program_view.js

@@ -171,17 +171,7 @@ let calcProgramSetting ={
                 "field":"type",
                 "vAlign":1,
                 "hAlign":0,
-                "font":"Arial",
-                "getText": function (record) {
-                    if (record.type) {
-                        for (let ft of feeType) {
-                            if (ft.type === record.type) {
-                                return ft.name;
-                            }
-                        }
-                    }
-                    return '';
-                }
+                "font":"Arial"
             }
         },
         {

+ 1 - 1
web/building_saas/main/js/views/glj_view.js

@@ -479,7 +479,7 @@ var gljOprObj = {
         this.sheetData=gljList;
     },
     combineWithProjectGlj:function (ration_gljs) {
-        var projectGljs = projectObj.project.projectGLJ.datas;
+        var projectGljs = projectObj.project.projectGLJ.datas.gljList;
         if(ration_gljs&&ration_gljs.length>0&&projectGljs&&projectGljs.length>0){
             ration_gljs.forEach(function (a) {
                 var glj = _.find(projectGljs,{id:a.projectGLJID});

+ 3 - 3
web/building_saas/main/js/views/main_tree_col.js

@@ -40,10 +40,10 @@ let MainTreeCol = {
         },
         forCalcBase: function (node) {
             // to do according to billsParentType
-            return MainTreeCol.readOnly.billsParent(node) && MainTreeCol.readOnly.non_bills(node);
+            return MainTreeCol.readOnly.billsParent(node) || MainTreeCol.readOnly.non_bills(node);
         },
         forUnitFee: function (node) {
-            return MainTreeCol.readOnly.ration(node) && MainTreeCol.readOnly.billsParent(node);
+            return MainTreeCol.readOnly.ration(node) || MainTreeCol.readOnly.billsParent(node);
         }
     },
     cellType: {
@@ -139,4 +139,4 @@ $('#column').on('hide.bs.modal', function () {
     }
     SheetDataHelper.refreshColumnVisible(projectObj.project.projSetting.mainGridSetting, projectObj.mainSpread.getActiveSheet());
     projectObj.project.pushNow('editColSetting', projectObj.project.projSetting.moduleName, {projectID: projectObj.project.ID(), main_tree_col: projectObj.project.projSetting.main_tree_col});
-})
+});

+ 72 - 0
web/building_saas/main/js/views/options_view.js

@@ -0,0 +1,72 @@
+/**
+ * Created by Zhong on 2017/9/28.
+ */
+let optionsOprObj = {
+    options: null,
+    optionsTypes: {GENERALOPTS: 'GENERALOPTS'},
+    rationQuanACToBillsQuan: $('#generalOpts1'),
+    rationQuanACToRationUnit: $('#generalOpts2'),
+    getOptions: function () {
+        let me = this;
+        $.ajax({
+            type: 'post',
+            url: '/options/getOptions',
+            dataType: 'json',
+            success: function (result) {
+                if(!result.error){
+                   me.options = result.data;
+                    for(let i = 0, len = me.options.length; i < len; i++){
+                        let optsType = me.options[i].type,
+                            opts = me.options[i].opts;
+                        if(optsType === me.optionsTypes.GENERALOPTS){
+                            for(let attr in opts){
+                                me[attr][0].checked = opts[attr];
+                            }
+                        }
+                    }
+                }
+            }
+        });
+    },
+    saveOptions: function (optsType, opts) {
+        $.ajax({
+            type: 'post',
+            url: '/options/saveOptions',
+            data: {optsType: optsType, opts: JSON.stringify(opts)},
+            dataType: 'json',
+            success: function (result) {
+
+            }
+        })
+    },
+    //更新optionsOprObj对象options数据
+    updateOptions: function (options, updateObj) {
+        for(let i = 0, len = options.length; i < len; i++){
+            if(options[i].type === updateObj.type){
+                options[i].opts[updateObj.opt] = updateObj.value;
+                break;
+            }
+        }
+    },
+    getOptsByType: function (options, type) {
+        let rst = null;
+        for(let i = 0, len = options.length; i < len; i++){
+            if(options[i].type === type){
+                rst = options[i].opts;
+            }
+        }
+        return rst;
+    }
+};
+
+optionsOprObj.getOptions();
+optionsOprObj.rationQuanACToBillsQuan.click(function () {
+    let value = this.checked;
+    optionsOprObj.updateOptions(optionsOprObj.options, {type: optionsOprObj.optionsTypes.GENERALOPTS, opt: 'rationQuanACToBillsQuan', value: value});
+    optionsOprObj.saveOptions(optionsOprObj.optionsTypes.GENERALOPTS, optionsOprObj.getOptsByType(optionsOprObj.options, optionsOprObj.optionsTypes.GENERALOPTS));
+});
+optionsOprObj.rationQuanACToRationUnit.click(function () {
+    let value = this.checked;
+    optionsOprObj.updateOptions(optionsOprObj.options, {type: optionsOprObj.optionsTypes.GENERALOPTS, opt: 'rationQuanACToRationUnit', value: value});
+    optionsOprObj.saveOptions(optionsOprObj.optionsTypes.GENERALOPTS, optionsOprObj.getOptsByType(optionsOprObj.options, optionsOprObj.optionsTypes.GENERALOPTS));
+});

+ 9 - 3
web/building_saas/main/js/views/project_info.js

@@ -5,13 +5,19 @@
 var projectInfoObj = {
     projectInfo: null,
     getFullPathHtml: function (proj) {
-        var fullPath = [], i, pm = '<a href="/pm">项目管理</a>', angleRight = '<i class="fa fa-angle-right fa-fw"></i>';
+        let fullPath = [], i, pm = '<span class="text-truncate"><a href="/pm">项目管理</a></span>', angleRight = '<span class="text-truncate"><i class="fa fa-angle-right fa-fw"></i></span>';
         fullPath.push(pm);
         if (proj && proj.fullFolder) {
             for (i = 0; i < proj.fullFolder.length; i++) {
-                fullPath.push(angleRight, proj.fullFolder[i]);
+                if (i <= proj.fullFolder.length - 3) {
+                    fullPath.push(angleRight, '<span class="text-truncate" data-toggle="tooltip" data-placement="bottom" title="', proj.fullFolder[i], '"><i class="fa fa-folder-open-o"></i></span>');
+                } else if (i === proj.fullFolder.length - 2) {
+                    fullPath.push(angleRight, '<span class="text-truncate" data-toggle="tooltip" data-placement="bottom" title="' + proj.fullFolder[i] + '"><i class="fa fa-cubes"></i>' + proj.fullFolder[i] + '</span>');
+                } else if (i === proj.fullFolder.length - 1) {
+                    fullPath.push(angleRight, '<span class="text-truncate" data-toggle="tooltip" data-placement="bottom" title="' + proj.fullFolder[i] + '"><i class="fa fa-cube"></i>' + proj.fullFolder[i] + '</span>');
+                }
             }
-            fullPath.push(angleRight, proj.name);
+            fullPath.push(angleRight, '<span class="text-truncate" data-toggle="tooltip" data-placement="bottom" title="' + proj.name + '"><i class="fa fa-sticky-note-o"></i>' + proj.name + '</span>');
         }
         return fullPath.join('');
     },

+ 0 - 1
web/building_saas/main/js/views/sub_view.js

@@ -133,7 +133,6 @@ let subViewObj = {
             if (node.sourceType === projectObj.project.Bills.getSourceType()) {
                 $('#comments>textarea').val(node.data.comments)
             } else if (node.sourceType === projectObj.project.Ration.getSourceType()) {
-                console.log(node.data);
                 $('#comments>textarea').val(node.data.content);
             }
         }

+ 3 - 2
web/building_saas/pm/js/pm_main.js

@@ -576,7 +576,7 @@ function init() {
 function AddProject() {
     let name = $('#project-name').val();
     if (name === '') {
-        alert('请填写工程');
+        alert('请填写建设项目名称');
         return false;
     }
     let valuation = $("#valuation").val();
@@ -714,6 +714,7 @@ function AddTender() {
         }
 
         let engineering = $("#tender-engineering").val();
+        console.log(engineering);
         if (engineering === '') {
             throw '请选择工程专业';
         }
@@ -1023,7 +1024,7 @@ function GetTargetTreeNode(zTreeObj) {
  * @return {String}
  */
 function getEngineeringHtml(engineeringList) {
-    let result = '<option>请选择对应的工程专业</option>';
+    let result = '<option value="">请选择对应的工程专业</option>';
     if (engineeringList.length <= 0) {
         return result;
     }

web/building_saas/pm/js/pm_main_bak.js → web/building_saas/pm/js/pm_main_bak.bak


+ 3 - 3
web/common/html/header.html

@@ -1,8 +1,8 @@
 <nav class="navbar navbar-toggleable-lg navbar-light bg-faded p-0 justify-content-between">
     <span class="header-logo px-2">Smartcost</span>
-    <div class="navbar-text" id="fullpath">
+    <div class="navbar-text navbar-crumb p-0" id="fullpath">
         <% if (action !== 'index' || controller !== 'pm') {%>
-        <a href="/pm">项目管理</a>
+        <span class="text-truncate"><a href="/pm">项目管理</a></span>
         <% } %>
     </div>
     <div class="float-lg-right navbar-text pt-0">
@@ -48,7 +48,7 @@
                     <a href="javascript:void(0);" class="back">返回</a>
                     <h4 class="text-center title"></h4>
                     <p class="text-center time"></p>
-                    <div class="mx-3 mb-5 content"></div>
+                    <div class="mx-3 mb-5 content-area"></div>
                 </div>
             </div>
             <div class="modal-footer">

BIN
web/dest/css/fonts/FontAwesome.otf


BIN
web/dest/css/fonts/fontawesome-webfont.eot


Plik diff jest za duży
+ 2671 - 0
web/dest/css/fonts/fontawesome-webfont.svg


BIN
web/dest/css/fonts/fontawesome-webfont.ttf


BIN
web/dest/css/fonts/fontawesome-webfont.woff


+ 523 - 0
web/src/html/pm/project-management.html

@@ -0,0 +1,523 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta http-equiv="x-ua-compatible" content="ie=edge">
+    <title>项目管理-Smartcost</title>
+    <!-- inject:css -->
+    <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css">
+    <link rel="stylesheet" href="/web/building_saas/css/main.css">
+    <link rel="stylesheet" href="/lib/font-awesome/font-awesome.min.css">
+    <!--zTree-->
+    <link rel="stylesheet" href="/lib/ztree/css/zTreeStyle.css" type="text/css">
+    <!-- endinject -->
+
+    <script>
+        // 这里的变量供页面调用
+        var userAccount = '<%- userAccount %>';
+        var userID = '<%- userID %>';
+    </script>
+    <style type="text/css">
+        .hidden-area{
+            display: none;
+        }
+        #summary-engineering,#summary-project{
+            display: none;
+        }
+    </style>
+</head>
+
+<body>
+<div class="header">
+    <div class="top-msg clearfix">
+        <div class="alert alert-warning mb-0 py-0" role="alert">
+            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
+                <span aria-hidden="true">&times;</span>
+            </button>
+            <strong>注意!</strong> 这是一条消息通知 <a href="#">链接</a>
+        </div>
+    </div>
+    <%include ../../../common/html/header.html %>
+    <nav class="navbar navbar-toggleable-lg justify-content-between navbar-light p-0">
+        <ul class="nav navbar-nav px-1">
+            <li class="nav-item dropdown">
+                <a class="nav-link dropdown-toggle" href="http://example.com" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">文件</a>
+                <div class="dropdown-menu" aria-labelledby="supportedContentDropdown">
+                    <a class="dropdown-item" href="#">Action</a>
+                    <a class="dropdown-item" href="#">Another action</a>
+                    <a class="dropdown-item" href="#">Something else here</a>
+                </div>
+            </li>
+            <li class="nav-item dropdown">
+                <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">编辑</a>
+                <div class="dropdown-menu">
+                    <a class="dropdown-item" href="#">Action</a>
+                    <a class="dropdown-item" href="#">Another action</a>
+                    <a class="dropdown-item" href="#">Something else here</a>
+                </div>
+            </li>
+            <li class="nav-item dropdown">
+                <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">工具</a>
+                <div class="dropdown-menu">
+                    <a class="dropdown-item" href="#">定额库编辑器</a>
+                    <a class="dropdown-item" href="/complementaryGlj">工料机库编辑器</a>
+                </div>
+            </li>
+            <li class="nav-item dropdown">
+                <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-question-circle-o"></i> 帮助</a>
+                <div class="dropdown-menu">
+                    <a class="dropdown-item" href="#">帮助</a>
+                    <a class="dropdown-item" href="#">升级说明</a>
+                    <a class="dropdown-item" href="#">重庆市2008定额说明</a>
+                    <a class="dropdown-item" href="#">纵横官网</a>
+                    <a class="dropdown-item" href="#">动画教程</a>
+                    <a class="dropdown-item" href="#">联系客服</a>
+                    <a class="dropdown-item" href="#">关于</a>
+                </div>
+            </li>
+        </ul>
+        <form class="form-inline">
+            <input class="form-control form-control-sm mr-1" type="text" placeholder="告诉我你想做什么">
+        </form>
+    </nav>
+</div>
+    <div class="main">
+        <div class="poj-manage container-fluid">
+            <div class="row">
+                <div class="col-lg-2">
+                    <div class="poj-cate">
+                        <input type="text" class="my-2 form-control form-control-sm" placeholder="搜索所有工程">
+                        <ul class="nav nav-pills flex-column">
+                            <li class="nav-item">
+                                <a class="nav-link active" href="#">全部</a>
+                            </li>
+                            <li class="nav-item">
+                                <a class="nav-link" href="#">最近使用</a>
+                            </li>
+                            <li class="nav-item">
+                                <a class="nav-link" href="#">共享</a>
+                            </li>
+                            <li class="nav-item">
+                                <a class="nav-link" href="#">协同工作</a>
+                            </li>
+                            <li class="nav-item">
+                                <a class="nav-link" href="#">归档</a>
+                            </li>
+                            <li class="nav-item">
+                                <a class="nav-link" href="#">回收站</a>
+                            </li>
+                        </ul>
+                    </div>
+                </div>
+                <div class="col-lg-10">
+                <div class="toolsbar">
+                    <div class="tools-btn btn-group align-top">
+                        <a href="javascript:void(0);" class="btn btn-sm" id="add-project-btn"><i class="fa fa-cubes"></i>&nbsp;新建建设项目</a>
+                        <a href="javascript:void(0);" class="btn btn-sm" id="add-engineering-btn"><i class="fa fa-cube"></i>&nbsp;新建单项工程</a>
+                        <a href="javascript:void(0);" class="btn btn-sm" id="add-tender-btn"><i class="fa fa-sticky-note-o"></i>&nbsp;新建单位工程</a>
+                        <a href="javascript:void(0);" class="btn btn-sm" id="add-folder-btn"><i class="fa fa-folder-o"></i>&nbsp;新建文件夹</a>
+                        <a href="javascript:void(0);" class="btn btn-sm" id="rename-btn">重命名</a>
+                        <a href="javascript:void(0);" class="btn btn-sm" id="del-btn">删除</a>
+                        <a href="javascript:void(0);" class="btn btn-sm" id="move-to-btn">移动到...</a>
+                        <a href="javascript:void(0);" class="btn btn-sm" id="copy-to-btn">复制到...</a>
+                        <a href="" class="btn btn-sm" id="share-btn">共享</a>
+                        <a href="" class="btn btn-sm" id="cooperate-btn">协同</a>
+                    </div>
+                </div>
+                <div class="poj-list">
+                    <legend>全部</legend>
+                    <table class="table table-hover table-sm" id="ProjTree">
+                        <thead>
+                        <tr>
+                            <th width="40"></th>
+                            <th width="78%">工程列表</th>
+                            <th width="10%">最近使用</th>
+                            <th width="10%">创建日期</th>
+                        </tr>
+                        </thead>
+                        <tbody>
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="slide-sidebar">
+        <div class="side-content">
+            <!--建设项目汇总-->
+            <div class="p-3" id="summary-project">
+                <legend><span id="summary-project-name">船体生产车间</span> 汇总</legend>
+                <table class="table table-bordered table-hover table-sm" id="summary-project-table">
+                    <thead>
+                    <tr>
+                        <th rowspan="2"></th>
+                        <th rowspan="2">序号</th>
+                        <th rowspan="2">单位工程名称</th>
+                        <th rowspan="2">金额(元)</th>
+                        <th colspan="3">其中</th>
+                    </tr>
+                    <tr>
+                        <th>暂估价(元)</th>
+                        <th>安全文明施工费(元)</th>
+                        <th>规费(元)</th>
+                    </tr>
+                    </thead>
+                    <tbody></tbody>
+                </table>
+                <div class="row">
+                    <div class="col-md-6">
+                        <legend>单价文件</legend>
+                        <table class="table table-bordered table-hover table-sm" id="summary-project-unit-price-table">
+                            <thead><th></th><th>名称</th></thead>
+                            <tbody>
+                            <tr><td>1</td><td>A单价文件</td></tr>
+                            <tr><td>2</td><td>B单价文件</td></tr>
+                            <tr><td>3</td><td>C单价文件</td></tr>
+                            </tbody>
+                        </table>
+                    </div>
+                    <div class="col-md-6">
+                        <legend>费率文件</legend>
+                        <table class="table table-bordered table-hover table-sm" id="summary-project-fee-table">
+                            <thead><th></th><th>名称</th></thead>
+                            <tbody>
+                            <tr><td>1</td><td>A费率文件</td></tr>
+                            <tr><td>2</td><td>B费率文件</td></tr>
+                            <tr><td>3</td><td>C费率文件</td></tr>
+                            </tbody>
+                        </table>
+                    </div>
+                </div>
+            </div>
+            <!--单项工程汇总-->
+            <div class="p-3" id="summary-engineering">
+                <legend><span id="summary-engineering-name">6号生产车间</span> 汇总</legend>
+                <table class="table table-bordered table-hover table-sm" id="summary-engineering-table">
+                    <thead>
+                    <tr>
+                        <th rowspan="2"></th>
+                        <th rowspan="2">序号</th>
+                        <th rowspan="2">单位工程名称</th>
+                        <th rowspan="2">金额(元)</th>
+                        <th colspan="3">其中</th>
+                    </tr>
+                    <tr>
+                        <th>暂估价(元)</th>
+                        <th>安全文明施工费(元)</th>
+                        <th>规费(元)</th>
+                    </tr>
+                    </thead>
+                    <tbody>
+                    <tr>
+                        <td>1</td>
+                        <td>1</td>
+                        <td>建筑工程3</td>
+                        <td>12345.67</td>
+                        <td>5436.87</td>
+                        <td>54345.68</td>
+                        <td>514.54</td>
+                    </tr>
+                    <tr>
+                        <td>2</td>
+                        <td>2</td>
+                        <td>建筑工程4</td>
+                        <td>12345.67</td>
+                        <td>5436.87</td>
+                        <td>54345.68</td>
+                        <td>514.54</td>
+                    </tr>
+                    <tr>
+                        <td>3</td>
+                        <td>3</td>
+                        <td>建筑工程5</td>
+                        <td> </td>
+                        <td> </td>
+                        <td> </td>
+                        <td> </td>
+                    </tr>
+                    <tr>
+                        <td>4</td>
+                        <td> </td>
+                        <td>合计</td>
+                        <td>110789.36</td>
+                        <td>5971.32</td>
+                        <td>58900.46</td>
+                        <td>1049.41
+
+                        </td>
+                    </tr>
+                    </tbody>
+                </table>
+            </div>
+        </div>
+    </div>
+</div>
+<!--弹出新建建设项目-->
+<div class="modal fade" id="add-project-dialog" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title"><i class="fa fa-cubes"></i>&nbsp;新建建设项目</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <!--没有点击任何节点-->
+                <form>
+                    <div class="form-group">
+                        <label>建设项目</label>
+                        <input type="text" class="form-control" placeholder="输入建设项目名称" id="project-name">
+                    </div>
+                    <div class="form-group">
+                        <label>计价方式</label>
+                        <div>
+                            <label class="custom-control custom-radio">
+                                <input name="valuation_type" type="radio" class="custom-control-input" value="bill">
+                                <span class="custom-control-indicator"></span>
+                                <span class="custom-control-description">清单计价</span>
+                            </label>
+                            <label class="custom-control custom-radio">
+                                <input name="valuation_type" type="radio" class="custom-control-input" value="ration">
+                                <span class="custom-control-indicator"></span>
+                                <span class="custom-control-description">定额计价</span>
+                            </label>
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label>计价规则</label>
+                        <select class="form-control" id="valuation"><option value="">请选择计价规则</option></select>
+                    </div>
+                </form>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                <a href="javacript:void(0);" class="btn btn-primary" id='addProjOk'>确定</a>
+            </div>
+        </div>
+    </div>
+</div>
+<!--弹出新建单项工程-->
+<div class="modal fade" id="add-engineering-dialog" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title"><i class="fa fa-cube"></i>&nbsp;新建单项工程</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <!--没有点击任何节点-->
+                <form>
+                    <div class="form-group">
+                        <label>单项工程</label>
+                        <input type="text" class="form-control" placeholder="输入单项工程名称" id="engineering-name">
+                    </div>
+                </form>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                <a href="javascript:void(0);" class="btn btn-primary" id="add-engineering-confirm">确定</a>
+            </div>
+        </div>
+    </div>
+</div>
+<!--弹出新建单位工程-->
+<div class="modal fade" id="add-tender-dialog" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title"><i class="fa fa-sticky-note-o"></i>&nbsp;新建单位工程</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <!--没有点击任何节点-->
+                <form>
+                    <div class="form-group">
+                        <label>单位工程</label>
+                        <input type="text" class="form-control" placeholder="输入单位工程名称" id="tender-name">
+                    </div>
+                    <div class="form-group">
+                        <label>工程专业</label>
+                        <select class="form-control" id="tender-engineering"><option>建筑工程</option></select>
+                    </div>
+                    <div class="form-group hidden-area">
+                        <label>单价文件</label>
+                        <select class="form-control" id="unit-price"><option value="">新建单价文件</option></select>
+                    </div>
+                    <div class="form-group hidden-area">
+                        <label>费率文件</label>
+                        <select class="form-control" id="tender-fee-rate"><option value="">新建费率文件</option></select>
+                    </div>
+                    <div class="form-group">
+                        <label>计价方式</label>
+                        <div>
+                            <label class="custom-control custom-radio">
+                                <input name="tender_valuation_type" type="radio" class="custom-control-input" value="bill" checked="checked">
+                                <span class="custom-control-indicator"></span>
+                                <span class="custom-control-description">清单计价</span>
+                            </label>
+                            <label class="custom-control custom-radio">
+                                <input name="tender_valuation_type" type="radio" class="custom-control-input" value="ration" disabled="disabled">
+                                <span class="custom-control-indicator"></span>
+                                <span class="custom-control-description">定额计价</span>
+                            </label>
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label>计价规则</label>
+                        <select class="form-control" id="tender-valuation" disabled><option>重庆[2008]调整人工单价</option></select>
+                    </div>
+                </form>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                <a href="javascript:void(0);" class="btn btn-primary" id="add-tender-confirm">确定</a>
+            </div>
+        </div>
+    </div>
+</div>
+<!--弹出新建文件夹-->
+<div class="modal fade" id="add-folder-dialog" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">新建文件夹</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <form>
+                    <div class="form-group">
+                        <label>文件夹</label>
+                        <input type="text" class="form-control" placeholder="输入文件夹名称" id="folder-name">
+                        <span class="form-text text-muted">Smartcost目前最多支持3层文件夹。</span>
+                    </div>
+                </form>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                <a href="javascript:void(0);" class="btn btn-primary" id="add-folder-confirm">确定</a>
+            </div>
+        </div>
+    </div>
+</div>
+<!--弹出重命名-->
+<div class="modal fade" id="rename-dialog" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">重命名</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <form>
+                    <div class="form-group">
+                        <input type="text" class="form-control" placeholder="输入名称" id="rename-name">
+                    </div>
+                </form>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                <a href="javascript:void(0);" class="btn btn-primary" id="rename-confirm">确定</a>
+            </div>
+        </div>
+    </div>
+</div>
+<!--弹出删除-->
+<div class="modal fade" id="del" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">删除确认</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <h5 class="text-danger" id="tenderHint">删除 "建筑工程" ?</h5>
+                <h5 class="text-danger" id="folderHint">删除 "XX项目文件夹" 以及它包含的子项?</h5>
+                <p class="" id = 'restoreHint'>删除后,你可以在回收站找到它。</p>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                <a href="javascript:void(0);" class="btn btn-danger" id="delete-confirm">删除</a>
+            </div>
+        </div>
+    </div>
+</div>
+<!--弹出移动到-->
+<div class="modal fade" id="move-to-dialog" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">移动到...</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <ul id="treeDemo" class="ztree"></ul>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                <a href="javacript:void(0);" class="btn btn-primary" id="move-to-confirm">确定</a>
+            </div>
+        </div>
+    </div>
+</div>
+<!--弹出复制到-->
+<div class="modal fade" id="copy-to-dialog" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">复制到...</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <ul id="treeDemo2" class="ztree"></ul>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                <a href="javacript:void(0);" class="btn btn-primary" id="copy-to-confirm">确定</a>
+            </div>
+        </div>
+    </div>
+</div>
+<!-- JS. -->
+<!-- inject:js -->
+<script src="/lib/tether/tether.min.js"></script>
+<script src="/lib/bootstrap/bootstrap.min.js"></script>
+<script src="/web/building_saas/js/global.js"></script>
+<script src="/public/web/date_util.js"></script>
+<script src="/public/web/tree_table/tree_table.js"></script>
+<script type="text/javascript" src="/public/web/common_ajax.js"></script>
+<script src="/web/building_saas/pm/js/pm_ajax.js"></script>
+<script src="/web/building_saas/pm/js/pm_main.js" charset="UTF-8"></script>
+
+
+<!-- zTree -->
+<script type="text/javascript" src="/lib/ztree/jquery.ztree.core.js"></script>
+<script type="text/javascript" src="/lib/ztree/jquery.ztree.excheck.js"></script>
+<!-- endinject -->
+
+</body>
+<script type="text/javascript">
+    autoFlashHeight();
+</script>
+<script type="text/javascript">
+    let billValuation = '<%- billValuation %>';
+    let rationValuation = '<%- rationValuation %>';
+    let engineeringList = '<%- engineeringList %>';
+</script>
+</html>

+ 0 - 1
web/users/html/login-infoinput.html

@@ -61,7 +61,6 @@
                         </div>
                     </div>
                     <div class="form-group">
-                        <input type="hidden" name="version" value="<%= version %>"/>
                         <button class="btn btn-primary btn-block" type="submit">下一步</button>
                     </div>
                 </div>