Browse Source

Merge branch 'master' of http://192.168.1.41:3000/SmartCost/YangHuCost

TonyKang 6 năm trước cách đây
mục cha
commit
e319041b6d
37 tập tin đã thay đổi với 1378 bổ sung545 xóa
  1. 1 0
      .gitignore
  2. 2 0
      lib/qiniu/qiniu.min.js
  3. 1 0
      modules/all_models/com_electrovalence.js
  4. 20 0
      modules/all_models/import_logs.js
  5. 2 2
      modules/all_models/material_calc.js
  6. 27 1
      modules/glj/controllers/glj_controller.js
  7. 27 14
      modules/glj/facade/glj_facade.js
  8. 9 5
      modules/glj/models/glj_list_model.js
  9. 1 22
      modules/glj/models/unit_price_file_model.js
  10. 1 4
      modules/glj/models/unit_price_model.js
  11. 2 0
      modules/glj/routes/glj_router.js
  12. 2 4
      modules/import/controllers/import_controller.js
  13. 40 22
      modules/pm/controllers/pm_controller.js
  14. 113 9
      modules/pm/facade/pm_facade.js
  15. 3 1
      modules/pm/routes/pm_route.js
  16. 1 0
      modules/users/controllers/login_controller.js
  17. 3 1
      modules/users/controllers/user_controller.js
  18. 1 1
      modules/users/models/log_model.js
  19. 3 1
      package.json
  20. 45 10
      public/web/gljUtil.js
  21. 8 0
      public/web/sheet/sheet_common.js
  22. 440 260
      web/building_saas/css/main.css
  23. 2 2
      web/building_saas/glj/html/project_glj.html
  24. 71 13
      web/building_saas/main/js/models/project_glj.js
  25. 247 8
      web/building_saas/main/js/views/electrovalence_view.js
  26. 2 1
      web/building_saas/main/js/views/glj_view.js
  27. 141 87
      web/building_saas/main/js/views/material_calc_view.js
  28. 1 0
      web/building_saas/pm/html/project-management.html
  29. 78 50
      web/building_saas/pm/js/pm_newMain.js
  30. 2 0
      web/common/html/dataStatistics.html
  31. 11 5
      web/common/html/header.html
  32. 25 1
      web/over_write/js/zhejiang_2005.js
  33. 1 1
      web/users/html/login.html
  34. 3 3
      web/users/html/user-buy.html
  35. 32 7
      web/users/html/user-info.html
  36. 9 9
      web/users/html/user-safe.html
  37. 1 1
      web/users/html/user-set.html

+ 1 - 0
.gitignore

@@ -2,6 +2,7 @@ node_modules/
 .git/
 dist/
 .idea/
+.vscode/
 tmp/*.xlsx
 tmp/*.pdf
 tmp/*.jsp

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 2 - 0
lib/qiniu/qiniu.min.js


+ 1 - 0
modules/all_models/com_electrovalence.js

@@ -10,6 +10,7 @@ let gljListSchema =new Schema({
     GLJID:Number,
     projectGLJID:Number,
     name:String,
+    displayName:String,
     code:String,
     specs:String,
     unit:String,

+ 20 - 0
modules/all_models/import_logs.js

@@ -0,0 +1,20 @@
+/**
+ * Created by zhang on 2019/12/27.
+ */
+import mongoose from "mongoose";
+
+let Schema = mongoose.Schema;
+let collectionName = 'import_logs';
+
+let modelSchema = {
+    // 日志类型
+    key: {type: String, index: true},
+    // 日志内容
+    userID: String,
+    // 关联用户id
+    status:String,
+    // 创建时间
+    create_time: Number,
+    errorMsg:""
+};
+mongoose.model(collectionName, new Schema(modelSchema, {versionKey: false, collection: collectionName}));

+ 2 - 2
modules/all_models/material_calc.js

@@ -104,7 +104,7 @@ let originalSchema = {
 mongoose.model("original_calc", new Schema(originalSchema, {versionKey: false, collection: "original_calc"}));
 
 
-let userfreightSchema = {
+let userfreightSchema = mongoose.Schema({
     ID:String,
     unit_price_file_id: Number,
     connect_key: String,// 关联项目工料机的key 不能关联id,因为单价文件导入别的项目后项目工料机id不同
@@ -121,7 +121,7 @@ let userfreightSchema = {
     ration_gljs:[ration_glj],
     calcType:String,//计算方式
     materialType:String//材料类型
-};
+}, { _id: false });
 
 let user_freights = {
     ID:{type:String,index: true},

+ 27 - 1
modules/glj/controllers/glj_controller.js

@@ -431,6 +431,32 @@ class GLJController extends BaseController {
        response.json(result);
    }
 
+    async insertElectrovalence(request, response){
+        let result={error:0};
+        try {
+            let data = JSON.parse(request.body.data);
+            result.data = await glj_facade.insertElectrovalence(data,request.session.sessionCompilation._id);
+        }catch (err){
+            logger.err(err);
+            result.error=1;
+            result.message = err.message;
+        }
+        response.json(result);
+    }
+
+    async updateElectrovalence(request, response){
+        let result={error:0};
+        try {
+            let data = JSON.parse(request.body.data);
+            result.data = await glj_facade.updateElectrovalence(data);
+        }catch (err){
+            logger.err(err);
+            result.error=1;
+            result.message = err.message;
+        }
+        response.json(result);
+    }
+
     async updateUserFreight(request, response){
         let result={error:0};
         try {
@@ -877,7 +903,7 @@ async function getGLJListByProjectID(projectId){
         //if(!responseData.data.com_electrovalence) responseData.data.com_electrovalence = {};
         // 先获取对应标段的项目工料机数据
         let gljListModel = new GLJListModel();
-        let [gljList, mixRatioConnectData,mixRatioMap,unitPriceMap] = await gljListModel.getListByProjectId(projectId, unitPriceFileId,responseData.data.freightList,responseData.data.originalList);
+        let [gljList, mixRatioConnectData,mixRatioMap,unitPriceMap] = await gljListModel.getListByProjectId(projectId, unitPriceFileId,responseData.data.freightList,responseData.data.originalList,responseData.data.com_electrovalence);
         responseData.data.gljList = gljList;
         responseData.data.mixRatioConnectData = mixRatioConnectData;
         responseData.data.mixRatioMap = mixRatioMap;

+ 27 - 14
modules/glj/facade/glj_facade.js

@@ -10,7 +10,8 @@ module.exports={ //先导出后require可以解决循环引用问题
     updateMaterialCalcTasks:updateMaterialCalcTasks,
     updateUserFreight:updateUserFreight,
     getUserFreights:getUserFreights,
-    insertElectrovalence:insertElectrovalence
+    insertElectrovalence:insertElectrovalence,
+    updateElectrovalence:updateElectrovalence
 };
 
 const mongoose = require('mongoose');
@@ -26,6 +27,7 @@ let freight_calc_model = mongoose.model('freight_calc');
 let unit_price_model = mongoose.model('unit_price');
 let user_freights_model = mongoose.model('user_freights');
 let std_glj_lib_model = mongoose.model('std_glj_lib_map');
+let com_electrovalence_model = mongoose.model('com_electrovalence');
 
 let ration_glj = require('../../ration_glj/facade/ration_glj_facade');
 const uuidV1 = require('uuid/v1');
@@ -44,7 +46,7 @@ async function changeUnitFile(projectData,unitFile,type,userID) {
 
         let insertData = null;
         if (type > 0) {
-            let currentUnitPrice = await unitPriceFileModel.findDataByCondition({id: changeUnitPriceId});
+            let currentUnitPrice = await unitPriceFileModel.model.findOne({id: changeUnitPriceId}).lean();
             if (currentUnitPrice === null) {
                 throw '不存在对应单价文件';
             }
@@ -52,13 +54,12 @@ async function changeUnitFile(projectData,unitFile,type,userID) {
             let projectData = await ProjectModel.getProject(projectId);
             let rootProjectId = projectData.property.rootProjectID !== undefined ? projectData.property.rootProjectID : 0;
 
-            insertData = JSON.parse(JSON.stringify(currentUnitPrice));
+            insertData = currentUnitPrice;
             insertData.root_project_id = rootProjectId;
             newName?insertData.name = newName:'';
             insertData.user_id = userID;
             delete insertData._id;
-            delete insertData.ID;
-            currentUnitPriceId = changeUnitPriceId; //从其它建设项目复制时,这个ID要变成被选中的来源的单价文件ID
+            delete insertData.id;
 
         }
         // 获取即将更改的单价文件信息
@@ -70,12 +71,9 @@ async function changeUnitFile(projectData,unitFile,type,userID) {
 
         // 查找对应单价文件的项目工料机数据
         let unitPriceModel = new UnitPriceModel();
-   /*     if(type ===1){//从其它项目复制,则先复制一份数据。 后面会做复制操作了,
-            let needCopyList = await unitPriceModel.findDataByCondition({unit_price_file_id: changeUnitPriceId}, null, false);
+        if(type ===1){//从其它项目复制,则先复制一份数据。
+            let needCopyList = await unitPriceModel.model.find({unit_price_file_id: changeUnitPriceId}).lean();
             if(needCopyList){
-                // 过滤mongoose格式
-                needCopyList = JSON.stringify(needCopyList);
-                needCopyList = JSON.parse(needCopyList);
                 let copyList = [];
                 for(let n of needCopyList){
                     delete n._id;  // 删除原有id信息
@@ -85,7 +83,7 @@ async function changeUnitFile(projectData,unitFile,type,userID) {
                 }
                 copyList.length>0 ? await unitPriceModel.add(copyList):'';
             }
-        }*/
+        }
         let copyResult = await unitPriceModel.copyNotExist(currentUnitPriceId, targetUnitPriceFile.id,projectId);
         // 复制成功后更改project数据
         if (!copyResult) {
@@ -162,10 +160,10 @@ async function handleVvTaxForChang(unitFileID,newVvTaxFileID) {//切换车船税
 async function addMixRatioForNew(projectID,unitFileId,engineerID,ext){
 /*    1050001机械工	工日	机上人工/ 3003001	重油	kg	普通材料/ 3003002 汽油	93号	kg	普通材料
     3003003	柴油	0号,-10号,-20号	kg	普通材料/  3003004	丙烷	kg	普通材料/ 3005001	煤	t	普通材料
-    3005002	电	kW·h	普通材料/  3005004	水	m3	普通材料/ 3005005	液化天然气	m3	普通材料
+    3005002	电	kW·h   267 电 kW·h (浙江2005编号不同)	   普通材料/  3005004	水	m3	普通材料/ 3005005	液化天然气	m3	普通材料
      02JXF	折旧费	元	机械组成物/ 03WHF	检修费	元	机械组成物/    04ACFZF	维护费	元	机械组成物
   05QT	安拆辅助费	元	机械组成物/ 80CCS	车船税	元	机械组成物*/
-    let mixCodes = ['1051001','3003001','3003002','3003003','3003004','3005001','3005002','3005004','3005005','02JXF','03WHF','04ACFZF','05QT','80CCS'];
+    let mixCodes = ['1051001','3003001','3003002','3003003','3003004','3005001','3005002','3005004','3005005','02JXF','03WHF','04ACFZF','05QT','80CCS','267'];
     let libID = await ration_glj.getGLJLibByEngineerID(engineerID);
     let stdGljs = await std_glj_lib_gljList_model.find({'repositoryId':libID,'code':{'$in':mixCodes}});
     let projectGljModel = new GLJListModel();
@@ -229,6 +227,21 @@ async function insertElectrovalence(data,compilationID) {
     return result;
 }
 
+//更新或新建综合电价信息
+async function updateElectrovalence(data) {
+    let elec = data["electrovalence"];
+    if(elec){
+        let actionType = elec.actionType;
+        if(actionType == "add"){
+            await com_electrovalence_model.create(elec.doc);
+        }else if(actionType == "update"){
+            await com_electrovalence_model.updateOne({'ID':elec.ID},elec.doc);
+        }
+    }
+    if(data["unitPrice"]) await updateUnitPrice(data["unitPrice"]);
+
+}
+
 
 async function updateMaterialCalcTasks(data) {
     let freightTasks = [];
@@ -243,7 +256,7 @@ async function updateMaterialCalcTasks(data) {
             genTasks(pu,priceTasks);
         }
     }
-
+    console.log(priceTasks)
     if(freightTasks.length > 0) await freight_calc_model.bulkWrite(freightTasks);
     if(priceTasks.length > 0) await original_calc_model.bulkWrite(priceTasks);
     if(data["unitPrice"]) await updateUnitPrice(data["unitPrice"]);

+ 9 - 5
modules/glj/models/glj_list_model.js

@@ -79,13 +79,14 @@ class GLJListModel extends BaseModel {
      * @param {Number} unitPriceFileId
      * @return {Promise}
      */
-    async getListByProjectId(projectId, unitPriceFileId,freightList,originalList) {
+    async getListByProjectId(projectId, unitPriceFileId,freightList,originalList,com_electrovalence) {
         let gljData = null;
         /*let decimal =await decimal_facade.getProjectDecimal(projectId);
         let quantity_decimal = decimal&&decimal.glj.quantity?decimal.glj.quantity:6;//取消耗量保留小数据位,默认6位*/
         let mixRatioConnectData = {};
         let mixRationMap={};
         let keyMap={};
+        let ekeyMap={};
         let unitPriceList={};
         try {
             // 首先获取对应标段下所有的项目工料机数据
@@ -100,12 +101,14 @@ class GLJListModel extends BaseModel {
                 if(this.ownCompositionTypes.indexOf(tmp.type)!=-1){
                     connect_keys.push(c_key);
                 }
-                keyMap[c_key] = tmp; //工料机连接key和工料机的对照表;
+                keyMap[c_key] = tmp; //项目工料机连接key和工料机的对照表;
             }
 
             //检查自采材料和综合电价功能在共享单价文件时,项目文件中可能会缺少项目工料机的情况,如果缺少,则自动插入
             if(freightList && freightList.length > 0)  await this.materialCalcProjectGLJChecking(freightList,keyMap,gljData,connect_keys,projectId,unitPriceFileId);
             if(originalList && originalList.length > 0) await this.materialCalcProjectGLJChecking(originalList,keyMap,gljData,connect_keys,projectId,unitPriceFileId);
+            if(com_electrovalence) await this.materialCalcProjectGLJChecking([com_electrovalence],keyMap,gljData,connect_keys,projectId,unitPriceFileId,"gljList");
+
             // 没有数据则直接返回空
             if (gljData.length <= 0) {
                 throw '无数据';
@@ -161,11 +164,12 @@ class GLJListModel extends BaseModel {
         return [gljData, mixRatioConnectData,mixRationMap,unitPriceList];
     }
 
-    async materialCalcProjectGLJChecking(materialList,keyMap,gljData,connect_keys,projectId,unitPriceFileId){
+    async materialCalcProjectGLJChecking(materialList,keyMap,gljData,connect_keys,projectId,unitPriceFileId,listKey){
         let missGLJs = [];
+        let pkey = listKey?listKey:"ration_gljs";
         for(let m of materialList){
-            if(m.ration_gljs){
-                for(let rg of m.ration_gljs){
+            if(m[pkey]){
+                for(let rg of m[pkey]){
                     let key = this.getIndex(rg);
                     if(keyMap[key])  continue; //如果已经存在,则跳过,不用添加
                     missGLJs.push(rg)

+ 1 - 22
modules/glj/models/unit_price_file_model.js

@@ -40,26 +40,6 @@ class UnitPriceFileModel extends BaseModel {
     }
 
     /**
-     * 新增单价文件
-     *
-     * @param {object} data
-     * @return {Promise}
-     */
-    async add(data) {
-        let result = false;
-        try {
-            if (Object.keys(data).length <= 0) {
-                throw '数据为空';
-            }
-            result = await this.db.create(data);
-        } catch (error) {
-            result = false;
-        }
-
-        return result;
-    }
-
-    /**
      * 根据项目id获取单价文件数据
      *
      * @param {Number} projectId
@@ -102,7 +82,7 @@ class UnitPriceFileModel extends BaseModel {
     }
 
     /**
-     * 新增单条工料机数据
+     * 新增单价文件
      *
      * @param {object} data
      * @return {Promise}
@@ -115,7 +95,6 @@ class UnitPriceFileModel extends BaseModel {
         let counterModel = new CounterModel();
         data.id = await counterModel.getId(collectionName);
 
-        this.setScene('add');
         let result = await this.db.create(data);
         return result;
     }

+ 1 - 4
modules/glj/models/unit_price_model.js

@@ -416,13 +416,10 @@ class UnitPriceModel extends BaseModel {
     async copyNotExist(currentUnitPriceId, changeUnitPriceId,projectId) {
         let result = false;
         // 首先查找原单价文件id下的数据
-        let currentUnitList = await this.findDataByCondition({unit_price_file_id: currentUnitPriceId}, null, false);
+        let currentUnitList = await this.model.find({unit_price_file_id: currentUnitPriceId}).lean();
         if (currentUnitList === null) {
             return result;
         }
-        // 过滤mongoose格式
-        currentUnitList = JSON.stringify(currentUnitList);
-        currentUnitList = JSON.parse(currentUnitList);
 
         let gljList = await gljListModel.find({'project_id':projectId});
         let gljMap = {};//用来记录glj的映射表,本项目有使用的工料机才需要copy过去

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

@@ -33,6 +33,8 @@ router.post('/changeVvTaxFile',gljController.init, gljController.changeVvTaxFile
 router.post('/changeAssistProductionFeeRate',gljController.init, gljController.changeAssistProductionFeeRate);
 router.post('/updateMaterialCalc',gljController.init, gljController.updateMaterialCalc);
 router.post('/updateMaterialCalcTasks',gljController.init, gljController.updateMaterialCalcTasks);
+router.post('/insertElectrovalence',gljController.init, gljController.insertElectrovalence);
+router.post('/updateElectrovalence',gljController.init, gljController.updateElectrovalence);
 router.post('/updateUserFreight',gljController.init, gljController.updateUserFreight);
 
 router.get('/getVvTaxList', gljController.init, gljController.getVvTaxList);

+ 2 - 4
modules/import/controllers/import_controller.js

@@ -8,10 +8,8 @@ let logger = require("../../../logs/log_helper").logger;
 let pm_facade = require('../../pm/facade/pm_facade');
 let controller = {
     importProject:async function (req){
-        let data = req.body.data;
-        let sessionInfo = {session:req.body.session};
-        let fields = req.body.fields;
-        return await pm_facade.importProject(data,sessionInfo,fields);
+        let data = req.body;
+        return await pm_facade.downLoadProjectFile(data);
     },
     exportProject:async function(req){
         let result={

+ 40 - 22
modules/pm/controllers/pm_controller.js

@@ -716,30 +716,48 @@ module.exports = {
             result.message = err.message;
         }
         res.json(result);
-
     },
     importProject:async function(req,res){
-        let form = new multiparty.Form({uploadDir: './tmp'});
-        form.parse(req, async function (err, fields, files) {
-            let path = "";
-            try {
-                console.log(fields);
-                const file = typeof files.file !== 'undefined' ? files.file[0] : null;
-                if (err || !file) {
-                    throw '上传失败。';
-                };
-                path = file.path;
-                let data = fs.readFileSync(file.path,'utf-8');
-                let body = {data: data, fields:fields, session:req.session};
-                let result = await redirectToImportServer(body,"importProject",req);
-                res.json(result);
-            }catch (e){
-                console.log(e);
-                res.json({error:1,msg:"导入失败请检查文件!"})
-            }finally {
-                fs.unlinkSync(path);
-            }
-        })
+        let data = JSON.parse(req.body.data);
+        let result={
+            error:0
+        };
+        try {
+            data.session = req.session;
+            result = await redirectToImportServer(data,"importProject",req);
+        }catch (err){
+            console.log(err);
+            result.error=1;
+            result.message = err.message;
+        }
+        res.json(result);
+    },
+    importProcessChecking:async function (req,res) {
+        let result={
+            error:0
+        };
+        try{
+            let data = JSON.parse(req.body.data);
+            result.data = await pm_facade.importProcessChecking(data);
+        } catch (err){
+            console.log(err);
+            result.error=1;
+            result.message = err.message;
+        }
+        res.json(result);
+    },
+    getUploadToken:function (req,res) {
+        let result={
+            error:0
+        };
+        try {
+            result =pm_facade.uploadToken();
+        }catch (err){
+            console.log(err);
+            result.error=1;
+            result.message = err.message;
+        }
+        res.json(result);
     }
 };
 

+ 113 - 9
modules/pm/facade/pm_facade.js

@@ -29,7 +29,10 @@ module.exports={
     checkFiles:checkFiles,
     copyForSectionError: copyForSectionError,
     exportProject:exportProject,
-    importProject:importProject
+    importProject:importProject,
+    uploadToken:uploadToken,
+    downLoadProjectFile:downLoadProjectFile,
+    importProcessChecking:importProcessChecking
 };
 
 
@@ -54,6 +57,7 @@ let unitPriceFileModel = mongoose.model("unit_price_file");
 let mixRatioModel = mongoose.model("mix_ratio");
 let freightModel = mongoose.model("freight_calc");
 let originalModel = mongoose.model("original_calc");
+let comElectrovalenceModel = mongoose.model("com_electrovalence");
 let unitPriceModel = mongoose.model("unit_price");
 let installationFeeModel = mongoose.model("installation_fee");
 let rationGLJModel = mongoose.model('ration_glj');
@@ -65,6 +69,8 @@ let userModel = mongoose.model('user');
 let compleGljSectionModel = mongoose.model('complementary_glj_section');
 let compleGljSectionTModel = mongoose.model('complementary_glj_section_templates');
 let progressiveModel = mongoose.model('std_progressive_lib');
+let importLogsModel = mongoose.model("import_logs");
+
 
 let featureLibModel =  mongoose.model("std_project_feature_lib");
 let scMathUtil = require('../../../public/scMathUtil').getUtil();
@@ -72,11 +78,25 @@ let counter = require('../../../public/counter/counter');
 import SectionTreeDao from '../../complementary_ration_lib/models/sectionTreeModel';
 let sectionTreeDao = new SectionTreeDao();
 import CounterModel from "../../glj/models/counter_model";
-import moment from 'moment';
+import moment from 'moment-timezone';
 import billsFlags from '../../common/const/bills_fixed';
 const notDeleted = [{deleteInfo: null}, {'deleteInfo.deleted': false}];
 let cipher = require('../../../public/cipher');
 const compilationModel = mongoose.model('compilation');
+let qiniu = require("qiniu");
+let fs = require("fs");
+let path = require("path");
+let request = require("request");
+
+let qiniu_config = {
+    "AccessKey": "_gR1ed4vi1vT2G2YITGSf4_H0fJu_nRS9Tzk3T4z",
+    "SecretKey": "ty4zd0FHqgEDaiVzSLC8DfHlai99aS7bspLkw6s6",
+    "Bucket": "yun-update",
+    "Domain": "http://serverupdate.smartcost.com.cn"
+};
+let mac = new qiniu.auth.digest.Mac(qiniu_config.AccessKey, qiniu_config.SecretKey);
+
+
 
 
 //拷贝例题项目
@@ -178,13 +198,13 @@ async function copyProject(userID, compilationID,data,newProjectID = null) {
     //费率文件、单价文件重名检查
     let feeRate =  await feeRateFileModel.findOne({rootProjectID:originalProperty.rootProjectID,name:originalProperty.feeFile.name,deleteInfo:null});
     if(feeRate){//存在重名的文件
-        newFeeName = originalProperty.feeFile.name + '(' + moment(Date.now()).format('MM-DD HH:mm:ss') + '复制)';
+        newFeeName = originalProperty.feeFile.name + '(' + moment(Date.now()).tz("Asia/Shanghai").format('MM-DD HH:mm:ss') + '复制)';
         projectMap['copy'].document.property.feeFile.name = newFeeName;
     }
 
     let unitPriceFile =  await unitPriceFileModel.findOne({root_project_id: originalProperty.rootProjectID,name:originalProperty.unitPriceFile.name,deleteInfo: null});
     if(unitPriceFile){//存在重名的文件
-        newUnitName = originalProperty.unitPriceFile.name + '(' + moment(Date.now()).format('MM-DD HH:mm:ss') + '复制)';
+        newUnitName = originalProperty.unitPriceFile.name + '(' + moment(Date.now()).tz("Asia/Shanghai").format('MM-DD HH:mm:ss') + '复制)';
         projectMap['copy'].document.property.unitPriceFile.name = newUnitName;
     }
 
@@ -383,6 +403,7 @@ async function copyUnitPriceFile(newProjectID,rootProjectID,userID,originaluUnit
         copySubList(originaluUnitPriceFileID,unitPriceFileID,mixRatioModel),
         copySubList(originaluUnitPriceFileID,unitPriceFileID,freightModel,true),
         copySubList(originaluUnitPriceFileID,unitPriceFileID,originalModel,true),
+        copySubList(originaluUnitPriceFileID,unitPriceFileID,comElectrovalenceModel,true),
         copySubList(originaluUnitPriceFileID,unitPriceFileID,unitPriceModel)
     ];
 
@@ -1074,6 +1095,7 @@ async function exportUnitFiles(rootProjectID){
          tem.mixRatios = await mixRatioModel.find({unit_price_file_id:f.id});
          tem.freights = await freightModel.find({unit_price_file_id:f.id});
          tem.originals = await originalModel.find({unit_price_file_id:f.id});
+         tem.com_electrovalence = await comElectrovalenceModel.find({unit_price_file_id:f.id});
          unitFiles.push(tem);
     }
     return unitFiles;
@@ -1112,8 +1134,72 @@ async function exportTenderData(data){
     return cipher.aesEncrypt(JSON.stringify(result));
 }
 
+async function downLoadProjectFile(info) {
+    let result = {error:0};
+    let bucketManager2 = new qiniu.rs.BucketManager(mac, null);
+    let publicBucketDomain = qiniu_config.Domain;// "http://serverupdate.smartcost.com.cn";//这里不支持https
+    let deadline = parseInt(Date.now() / 1000) + 3600; // 1小时过期
+    let privateDownloadUrl = bucketManager2.privateDownloadUrl(publicBucketDomain, info.key, deadline);
+
+    let data = {
+        key:info.key,
+        userID:info.session.sessionUser.id,
+        status:"start",
+        create_time:+new Date()
+    };
+    await importLogsModel.create(data);
+    doDownLoadAndImport(privateDownloadUrl,info);
+    return result;
+}
+
+
+async function doDownLoadAndImport(privateDownloadUrl,info) {
+    let stream = fs.createWriteStream(path.join(__dirname, "../../../tmp/"+info.key));//
+    request(privateDownloadUrl).pipe(stream).on("close", async function (err) {
+        console.log("文件[" + info.key + "]下载完毕");
+        let doc = {status:"finish"};
+        try {
+            let data = fs.readFileSync(stream.path,'utf-8');
+            let result = await importProject(data,{session:info.session},info.updateData);
+            if(result.error == 1){
+                doc.errorMsg = result.msg;
+                doc.status = "error";
+            }
+        }catch (error){
+            console.log(error);
+            doc.errorMsg = "导入失败,请检查文件!";
+            doc.status = "error";
+        }finally {
+            await importLogsModel.update({key:info.key},doc);
+            fs.unlinkSync(stream.path);
+        }
+    });
+}
+
+async function importProcessChecking(data){
+    let result = {error:0};
+    let log = await importLogsModel.findOne({key:data.key});
+    if(log){
+        if(log.status == "finish"){
+            result.status = "complete";
+            await importLogsModel.remove({key:data.key});
+        }else if(log.status == "start"){
+            result.status = "processing";
+        }else if(log.status == "error"){
+            result.error = 1;
+            result.msg = log.errorMsg;
+            await importLogsModel.remove({key:data.key});
+        }
+    }else {
+        result.error = 1;
+        result.msg = `导入过程中发生错误!`;
+    }
+    return result;
 
-async function importProject(data,req,fields) {
+}
+
+
+async function importProject(data,req,updateData) {
     let result = {error:0};
     let stringArr = data.split("|----|");
     let datas = [];
@@ -1132,7 +1218,7 @@ async function importProject(data,req,fields) {
              result.error = 1;
              result.msg = `导入失败:您要导入的文件是由“${fileCompilationName}”导出,当前软件是“${curCompilationName}”,请选择正确的编制办法再进行操作!`;
          }else {
-            let [projectIDMap,labourCoeFileIDMap,calcProgramFileIDMap] = await handleMainProjectDatas(mainData,JSON.parse(fields.updateData[0]),req.session.sessionUser.id);
+            let [projectIDMap,labourCoeFileIDMap,calcProgramFileIDMap] = await handleMainProjectDatas(mainData,updateData,req.session.sessionUser.id);
             if(datas.length > 1 ){
                 for(let i = 1;i<datas.length;i++){
                     await handleEachProject(datas[i],projectIDMap,labourCoeFileIDMap,calcProgramFileIDMap)
@@ -1274,7 +1360,7 @@ async function handleMainProjectDatas(mainData,updateData,userID) {
             }
             //查看是否重名;
             let temp = await projectModel.findOne({userID:userID,ParentID:p.ParentID,name:p.name});
-            if(temp) p.name = p.name + '(' + moment(Date.now()).format('MM-DD HH:mm:ss') + '导入)';
+            if(temp) p.name = p.name + '(' + moment(Date.now()).tz("Asia/Shanghai").format('MM-DD HH:mm:ss') + '导入)';
         }else {
             p.ParentID = projectIDMap[p.ParentID];
             p.NextSiblingID = projectIDMap[p.NextSiblingID];
@@ -1306,9 +1392,9 @@ async function handleMainProjectDatas(mainData,updateData,userID) {
 
 async function importUnitPriceFiles(mainData,projectIDMap,unitPriceFileIDMap,userID) {
     if(!mainData.files.unitFiles) return;
-    let unitFiles = [],unitPrices =[],mixRatios=[],freights=[],originals=[];
+    let unitFiles = [],unitPrices =[],mixRatios=[],freights=[],originals=[],com_electrovalences=[];
     for(let f of mainData.files.unitFiles){
-        let file = f.unitFile,prices = f.unitPrices,mixs = f.mixRatios,fres = f.freights,ors = f.originals;
+        let file = f.unitFile,prices = f.unitPrices,mixs = f.mixRatios,fres = f.freights,ors = f.originals,ec=f.com_electrovalence;
         //生成单价文件
         delete file._id;
         file.id = unitPriceFileIDMap[file.id]?unitPriceFileIDMap[file.id]:await getCounterID("unit_price_file");
@@ -1322,12 +1408,14 @@ async function importUnitPriceFiles(mainData,projectIDMap,unitPriceFileIDMap,use
         if(mixs) await setSubList(mixs,mixRatios,file.id,mixRatioModel);
         if(fres) await setSubList(fres,freights,file.id,freightModel,true);
         if(ors) await setSubList(ors,originals,file.id,originalModel,true);
+        if(ec) await setSubList(ec,com_electrovalences,file.id,comElectrovalenceModel,true);
     }
     if(unitFiles.length > 0) await insertMany(unitFiles,unitPriceFileModel);
     if(unitPrices.length > 0) await insertMany(unitPrices,unitPriceModel);
     if(mixRatios.length > 0) await insertMany(mixRatios,mixRatioModel);
     if(freights.length > 0) await insertMany(freights,freightModel);
     if(originals.length > 0) await insertMany(originals,originalModel);
+    if(com_electrovalences.length > 0) await insertMany(com_electrovalences,comElectrovalenceModel);
 
     async function setSubList(oList,nList,fileID,model,UUID=false) {
         for(let o of oList){
@@ -1429,3 +1517,19 @@ async function checkFiles(projects) {
     }
     await Promise.all(task);
 }
+
+function uploadToken() {
+    let options = {
+        scope: qiniu_config.Bucket,
+        deleteAfterDays: 1,
+        returnBody:
+            '{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)","name":"$(x:name)"}'
+    };
+    let putPolicy = new qiniu.rs.PutPolicy(options);
+    let token = putPolicy.uploadToken(mac);
+    let result = {
+            uptoken: token,
+            domain: qiniu_config.Domain
+        }
+    return result
+}

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

@@ -12,7 +12,7 @@ module.exports = function (app) {
     app.get('/pm', baseController.init, pmController.index);
 
     let pmRouter = express.Router();
-
+    pmRouter.get('/getUploadToken', pmController.getUploadToken);
     pmRouter.use(function (req, res, next) {
         if (/\/getNewProjectID/.test(req.originalUrl)||/\/importProject/.test(req.originalUrl) || pmController.checkRight(req, res)) {
             next();
@@ -63,6 +63,8 @@ module.exports = function (app) {
     pmRouter.post('/changeFile', pmController.changeFile);
     pmRouter.post('/exportProject', pmController.exportProject);
     pmRouter.post('/importProject', pmController.importProject);
+    pmRouter.post('/importProcessChecking', pmController.importProcessChecking);
+
 
     app.use('/pm/api', pmRouter);
 };

+ 1 - 0
modules/users/controllers/login_controller.js

@@ -230,6 +230,7 @@ class LoginController {
 
             let sessionUser = {
                 ssoId: userData.id,
+                company: userInfo.company,
                 username: userData.username,
                 email: userData.useremail,
                 mobile: userData.mobile,

+ 3 - 1
modules/users/controllers/user_controller.js

@@ -57,7 +57,9 @@ class UserController extends BaseController {
                 real_name: request.body.real_name,
                 province: request.body.province,
                 company: request.body.company,
-                version: request.body.version
+                version: request.body.version,
+                company_type: request.body.company_type,
+                company_scale: request.body.company_scale,
             };
             let sessionUser = request.session.sessionUser;
             // 切换验证场景

+ 1 - 1
modules/users/models/log_model.js

@@ -60,7 +60,7 @@ class LogModel extends BaseModel {
      */
     async addLoginLog(userId, request) {
         let ip = request.connection.remoteAddress;
-        ip = ip.split(':');
+        ip = ip?ip.split(':'):[];
         ip = ip[3] === undefined ? '' : ip[3];
 
         // let ipInfo = '127.0.0.1';//await this.getIpInfoFromApi(ip);

+ 3 - 1
package.json

@@ -48,6 +48,7 @@
     "lz-string": "^1.4.4",
     "main-bower-files": "^2.5.0",
     "moment": "^2.18.1",
+    "moment-timezone": "^0.5.27",
     "multiparty": "^4.1.3",
     "node-schedule": "^1.3.0",
     "node-xlsx": "^0.11.2",
@@ -56,7 +57,8 @@
     "socket.io": "2.0.3",
     "ua-parser-js": "^0.7.14",
     "uuid": "^3.1.0",
-    "wiredep": "^2.2.2"
+    "wiredep": "^2.2.2",
+    "qiniu": "^7.1.1"
   },
   "scripts": {
     "start": "C:\\Users\\mai\\AppData\\Roaming\\npm\\babel-node.cmd server.js",

+ 45 - 10
public/web/gljUtil.js

@@ -5,8 +5,7 @@
 
 let gljUtil = {
     calcProjectGLJQuantity:function (projectGLJDatas,rationGLJDatas,rationDatas,billsDatas,q_decimal,_,scMathUtil,isTender) {
-        let project_gljs = projectGLJDatas.gljList;
-        let mixRatioMap = projectGLJDatas.mixRatioMap;
+        let project_gljs = projectGLJDatas.gljList, mixRatioMap = projectGLJDatas.mixRatioMap, com_electrovalence = projectGLJDatas.com_electrovalence;
         let rations = rationDatas;
         let rationMap = _.indexBy(rations,'ID');
         let quantityMap={};
@@ -19,6 +18,9 @@ let gljUtil = {
         let qField = isTender==true?"tenderQuantity":"quantity";
         let mField = "materialQuantity"; //材料计算的工料机消耗量
 
+        let elecIndex = "";//记住电的标识
+
+
         for(let pglj of project_gljs ){
             let pg_index = this.getIndex(pglj,this.gljKeyArray);
             pglj[qField] = 0;
@@ -27,6 +29,7 @@ let gljUtil = {
             let result = this.getQuantityPerGLJ(gljGroup,rations,rationMap,pglj,billIDs,tech_billIDS,q_decimal,_,scMathUtil,isTender);
             pglj[qField] = result.quantity;
             quantityMap[pg_index] = pglj;
+            if(pglj.code == gljUtil.getElecCode() && pglj.name == '电' && pglj.unit == "kW·h") elecIndex = pg_index;
         }
         //计算做为组成物的消耗量
         for(let pkey in mixRatioMap){
@@ -61,6 +64,33 @@ let gljUtil = {
             }
         }
 
+        //计算综合电价中,电网电和机械台班的消耗量 - 电有可能做为组成物存在,计算综合电价的各消耗量时,要以电的总消耗量为基础,所以这步要放在最后,即电都计算完成以后
+        if(com_electrovalence && com_electrovalence.gljList && quantityMap[elecIndex]){
+            for(let cg of com_electrovalence.gljList){
+                //网电的消耗量=电的总消耗量×加权系数
+                let eq = scMathUtil.roundForObj(quantityMap[elecIndex][qField] * parseFloat(cg.coe),q_decimal);
+                if(cg.name == '电网电'){
+                    quantityMap[this.getIndex(cg)][qField] = eq;
+                }else {
+                    let tquantity = 0;
+                    let w = parseInt(cg.name);
+                    if(w) tquantity = scMathUtil.roundForObj(eq/w,6);
+                    tquantity = scMathUtil.roundForObj(tquantity * this.getElecCoe(),q_decimal);
+                    let ekey = this.getIndex(cg);
+                    quantityMap[ekey][qField] = tquantity;
+                    //计算机械台班下的组成物的消耗量
+                    if(mixRatioMap[ekey]){
+                        for(let m of mixRatioMap[ekey]){
+                            let cmkey = this.getIndex(m);
+                            if(quantityMap[cmkey] && tquantity > 0){//混凝土、砂浆、配合比组成物的消耗量在定额下已经有体现了,不用再计算进去
+                                let c_m_quantity = scMathUtil.roundForObj(tquantity * parseFloat(m.consumption),6);
+                                quantityMap[cmkey][qField] =  scMathUtil.roundForObj(parseFloat(quantityMap[cmkey][qField])+c_m_quantity,q_decimal);
+                            }
+                        }
+                    }
+                }
+            }
+        }
         //计算经过场外运输损耗后的总消耗量
         for(let pglj of project_gljs ){
             let offSiteTransportLossRate = this.getOffSiteTransportLossRate(pglj);
@@ -345,6 +375,7 @@ let gljUtil = {
         t_index = k_arr.join("|-|");
         return t_index;
     },
+
     getMainType:function (type) {
         let str = type + "";
         return parseInt(str.substr(0,1));
@@ -382,7 +413,7 @@ let gljUtil = {
     },
     //是否从混凝土改成商品混凝土,并且混凝土的定额消耗量不为空,则原混凝土的自定义消耗改成0,插入一条新的商品混凝土自定义消耗量为原自定义或定额消耗
     isAddCommercialForReplace:function (oldType,newType,rationItemQuantity) {
-        return gljUtil.isConcreteToCommercialConcrete(oldType,newType)&&rationItemQuantity&&rationItemQuantity!='0';
+        return this.isConcreteToCommercialConcrete(oldType,newType)&&rationItemQuantity&&rationItemQuantity!='0';
     },
     isMaterialType:function (type) {
        let materialType = [gljType.GENERAL_MATERIAL,gljType.GREEN_SEEDLING,gljType.PURCHASE_COMPONENT,gljType.COMMERCIAL_CONCRETE,gljType.COMMERCIAL_MORTAR];//可以添加材料计算的类型普通材料”、“绿化苗木”、“外购砼构件”、“商品混凝土”、“商品砂浆”
@@ -393,9 +424,9 @@ let gljUtil = {
     },
     hasComposition:function (ration_glj,isRationType) {//判断是否有组成物,有则返回true   现在主材类型的工料机也有可能有组成物。
         let type = isRationType==true? ration_glj.subType:ration_glj.type;
-        if(gljUtil.notEditType.indexOf(type)!=-1||type==gljType.MAIN_MATERIAL){
+        if(this.notEditType.indexOf(type)!=-1||type==gljType.MAIN_MATERIAL){
             let keyArray = isRationType==true? rationKeyArray:gljKeyArray;
-            let con_key = gljUtil.getIndex(ration_glj,keyArray);
+            let con_key = this.getIndex(ration_glj,keyArray);
             var mixRatioMap = projectObj.project.projectGLJ.datas.mixRatioMap;
             if(mixRatioMap[con_key]&&mixRatioMap[con_key].length>0){
                 return true;
@@ -437,16 +468,16 @@ let gljUtil = {
         let directFee = 0;//直接费
         let rationQuantity = scMathUtil.roundForObj(ration.quantity,ration_quantity_decimal);
         for(let g of ration_gljs){
-            let result = gljUtil.getGLJPrice(pMap[g.projectGLJID],projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,false,_,scMathUtil);
+            let result = this.getGLJPrice(pMap[g.projectGLJID],projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,false,_,scMathUtil);
             g.marketPrice = result.marketPrice;
             g.basePrice = result.basePrice;
             let quantity = scMathUtil.roundForObj(g.quantity,glj_quantity_decimal);
             let t = scMathUtil.roundForObj(quantity * g.marketPrice * rationQuantity,process_decimal);//市场价
             let rt = scMathUtil.roundForObj(quantity * g.basePrice * rationQuantity,process_decimal);//定额价
-            if(g.type == gljUtil.gljType.LABOUR){
+            if(g.type == this.gljType.LABOUR){
                 rationLaberFee = scMathUtil.roundForObj(rationLaberFee+t,process_decimal);
                 rationLaberFee_b = scMathUtil.roundForObj(rationLaberFee_b+rt,process_decimal);
-            }else if(gljUtil.getMainType(g.type) == 3){
+            }else if(this.getMainType(g.type) == 3){
                 rationMachineFee = scMathUtil.roundForObj(rationMachineFee+t,process_decimal);
                 rationMachineFee_b = scMathUtil.roundForObj(rationMachineFee_b+rt,process_decimal);
             }
@@ -460,8 +491,12 @@ let gljUtil = {
         //let hs = scMathUtil.roundForObj(tt*hightFeeRate,process_decimal);//(人工定额消耗量*定额价*定额工程量+机械定额消耗量*定额价*定额工程量)*高原取费类别费率
 
     },
-
-
+    getElecCoe:function () {
+        return 0.15;
+    },
+    getElecCode:function () {
+        return '3005002';
+    },
     fixedFlag : {
         // 分部分项工程
         SUB_ENGINERRING: 1,

+ 8 - 0
public/web/sheet/sheet_common.js

@@ -1227,5 +1227,13 @@ var sheetCommonObj = {
                 break;
         }
         return result;
+    },
+    getSelectedRecode:function (sheet,datas) {
+        let sel = sheet.getSelections()[0];
+        let srow = sel.row == -1||sel.row == ""?0:sel.row;
+        if(gljUtil.isDef(srow) && datas.length>srow){
+            return datas[srow];
+        }
+        return null;
     }
 }

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 440 - 260
web/building_saas/css/main.css


+ 2 - 2
web/building_saas/glj/html/project_glj.html

@@ -286,9 +286,9 @@
             <div class="modal-footer">
                 <div style="width: 70%">
                     <button type="button" class="btn btn-danger" id="removeElectrovalencec">删除</button>
-                    <label >综合电价:</label>
+                    <label id="electrovalenceLabel">综合电价:</label>
                 </div>
-                <button type="button" class="btn btn-primary" id="electrovalencecConfirm">确定</button>
+                <button type="button" class="btn btn-primary" data-dismiss="modal" id="electrovalencecConfirm">确定</button>
                 <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
             </div>
         </div>

+ 71 - 13
web/building_saas/main/js/models/project_glj.js

@@ -631,14 +631,6 @@ ProjectGLJ.prototype.updateMaterialCalc = async function (datas) {
 
 };
 
-ProjectGLJ.prototype.updateFreightCalc = async function (datas,pgljID){
-    let updateMap = {};
-    for(let d of datas){
-        updateMap[d.ID] = d.doc;
-    }
-    await this.updateMaterialCalcTasks(pgljID,updateMap,"update","freight");
-};
-
 ProjectGLJ.prototype.updateMaterialCalcTasks =async function(pgljID,dataMap,actionType,model){
     //为了统一接口, 参数dataMap 在添加操作时是一个数组,在修改的时候是一个ID - doc 映射表;
     try {
@@ -706,6 +698,26 @@ ProjectGLJ.prototype.getUserFreights = async function () {//初始化车船税
     }
 };
 
+ProjectGLJ.prototype.refreshEctrovalenceCache = function (updateMap) {
+    let elec = updateMap["electrovalence"];
+    if(elec){
+        let actionType = elec.actionType;
+        if(actionType == "add"){
+            projectObj.project.projectGLJ.datas.com_electrovalence = elec.doc;
+        }else if(actionType == "update"){
+            projectObj.project.projectGLJ.datas.com_electrovalence.gljList = elec.doc.gljList;
+        }
+    }
+
+    if(updateMap["unitPrice"]) {
+        if(Array.isArray(updateMap["unitPrice"])){
+            this.m_updateUnitPrice(updateMap["unitPrice"]);
+        }else {
+            this.m_updateUnitPrice([updateMap["unitPrice"]]);
+        }
+    }
+};
+
 
 ProjectGLJ.prototype.refreshMaterialCalcCache = function (updateMap){
    if(updateMap["freight"]) updateList(this.datas.freightList,updateMap["freight"]);
@@ -757,6 +769,15 @@ ProjectGLJ.prototype.addFreightCalc = async function (datas,pgljID) {
     await this.updateMaterialCalcTasks(pgljID,datas,"add","freight");
 };
 
+ProjectGLJ.prototype.updateFreightCalc = async function (datas,pgljID){
+    let updateMap = {};
+    for(let d of datas){
+        updateMap[d.ID] = d.doc;
+    }
+    await this.updateMaterialCalcTasks(pgljID,updateMap,"update","freight");
+};
+
+
 ProjectGLJ.prototype.addMaterialRation = async function (code,type,parentID,connect_key){
         let libIDs = rationLibObj.getStdRationLibIDs();
         let defaultLibID = rationLibObj.getDefaultStdRationLibID();
@@ -866,11 +887,15 @@ ProjectGLJ.prototype.calcEachFreightOrPrice = function (temp,type,priceMap) {//
         for(let pg of this.datas.gljList){
             pgljMap[gljUtil.getIndex(pg)] = pg
         }
-        for(let g of temp.ration_gljs){
-            gljMap[g.rationID]?gljMap[g.rationID].push(g):gljMap[g.rationID]=[g];
+        if(temp.ration_gljs){
+            for(let g of temp.ration_gljs){
+                gljMap[g.rationID]?gljMap[g.rationID].push(g):gljMap[g.rationID]=[g];
+            }
         }
-        for(let r of temp.rations){
-            sum = scMathUtil.roundForObj(sum + calcRation(r,gljMap[r.ID],pgljMap,priceMap),6);
+        if(temp.rations) {
+            for(let r of temp.rations){
+                sum = scMathUtil.roundForObj(sum + calcRation(r,gljMap[r.ID],pgljMap,priceMap),6);
+            }
         }
         sum = scMathUtil.roundForObj(sum,decimal)+"";
         if(type == "freight" && temp.unitFreight!= sum) return {ID:temp.ID,doc:{unitFreight:sum}};
@@ -996,7 +1021,7 @@ ProjectGLJ.prototype.calcMaterialRation = function(ID,type){//计算带定额的
 ProjectGLJ.prototype.deletePriceCalc = async function (ID,pgljID) {
     let map = {};
     map[ID] = true;
-    await this.updateMaterialCalcTasks(pgljID,ID,"delete","price");
+    await this.updateMaterialCalcTasks(pgljID,map,"delete","price");
 };
 
 ProjectGLJ.prototype.deleteFreightCalc = async function (ID,pgljID) {
@@ -1649,4 +1674,37 @@ ProjectGLJ.prototype.calcTenderQuantity  = function (){
     let rationDatas = projectObj.project.Ration.datas;
     let billsDatas = projectObj.project.Bills.datas;
     gljUtil.calcProjectGLJQuantity(this.datas,rationGLJDatas,rationDatas,billsDatas,getDecimal("glj.quantity"),_,scMathUtil,true);
+};
+
+ProjectGLJ.prototype.loadNewProjectGLJToCaches = function (datas) {
+    for (let d of datas){
+        this.loadNewProjectGLJToCache(d);
+    }
+};
+
+ProjectGLJ.prototype.loadNewProjectGLJToCache = function (data) {//把新插入的项目工料机数据增加至缓存中
+    let project_gljs = this.datas.gljList;
+    let unitPriceMap = this.datas.unitPriceMap;
+    let mixRatioMap = this.datas.mixRatioMap;
+    let mixRatioConnectData = this.datas.mixRatioConnectData;
+    let tem =  _.find(project_gljs,{'id':data.id});
+    if(tem) return tem; //判断该工料机是否已经存在,是的话不用再次添加
+    //查看是否有组成物,有组成物的话先添加组成物信息
+    data.ratio_data=[];
+    if(data.subList && data.subList.length){
+        for(let s of data.subList){
+            let ratio = s.ratio_data;
+            data.ratio_data.push(ratio);
+            mixRatioMap[ratio.connect_key]?mixRatioMap[ratio.connect_key].push(ratio):mixRatioMap[ratio.connect_key] = [ratio];
+            let rIndex = gljUtil.getIndex(ratio);
+            mixRatioConnectData[rIndex]?mixRatioConnectData[rIndex].push(ratio.connect_key):mixRatioConnectData[rIndex] = [ratio.connect_key];
+            this.loadNewProjectGLJToCache(s);
+        }
+        delete data.subList;
+    }
+    //添加unitPriceMap
+    let uIndex = gljUtil.getIndex(data.unit_price);
+    if(!unitPriceMap[uIndex])  unitPriceMap[uIndex] = data.unit_price;
+    this.datas.gljList.push(data);
+    return data;
 };

+ 247 - 8
web/building_saas/main/js/views/electrovalence_view.js

@@ -5,10 +5,10 @@ let electrovalenceObj = {
     setting:{
         header:[
             {headerName: "代号", headerWidth: 70, dataCode: "code", dataType: "String"},
-            {headerName: "名称", headerWidth: 150, dataCode: "name",dataType: "String"},
-            {headerName: "规格", headerWidth: 60, dataCode: "specs", dataType: "Number",validator:"number"},
-            {headerName: "预算价", headerWidth: 75, dataCode: "marketPrice", hAlign: "right", dataType: "Number",validator:"number"},
-            {headerName: "加权系数", headerWidth: 60, dataCode: "coe", hAlign: "right", dataType: "Number",validator:"number"}
+            {headerName: "名称", headerWidth: 150, dataCode: "displayName",dataType: "String"},
+            {headerName: "规格", headerWidth: 70, dataCode: "specs", dataType: "Number",validator:"number"},
+            {headerName: "预算价", headerWidth: 75, dataCode: "electPrice", hAlign: "right", dataType: "Number",validator:"number"},
+            {headerName: "加权系数", headerWidth: 80, dataCode: "coe", hAlign: "right", dataType: "Number",validator:"number"}
         ],
         view: {
             lockColumns: ["code","specs"],
@@ -19,25 +19,264 @@ let electrovalenceObj = {
     spread:null,
     sheet:null,
     datas:[],
+    total:0,
+    options:[
+        {code:"3005003",name:"电网电",specs:"",unit:"kW·h",type:"201"},
+        {code:"8017001",name:"5kW以内柴油发电机组",specs:"5GF1",unit:"台班",type:"301"},
+        {code:"8017002",name:"15kW以内柴油发电机组",specs:"12GF1",unit:"台班",type:"301"},
+        {code:"8017003",name:"30kW以内柴油发电机组",specs:"30GFY-2",unit:"台班",type:"301"},
+        {code:"8017004",name:"50kW以内柴油发电机组",specs:"50GFY-2",unit:"台班",type:"301"},
+        {code:"8017005",name:"75kW以内柴油发电机组",specs:"75GFY-4",unit:"台班",type:"301"},
+        {code:"8017006",name:"100kW以内柴油发电机组",specs:"90GFZ",unit:"台班",type:"301"},
+        {code:"8017007",name:"120kW以内柴油发电机组",specs:"120GFY-4",unit:"台班",type:"301"},
+        {code:"8017008",name:"160kW以内柴油发电机组",specs:"160GF",unit:"台班",type:"301"},
+        {code:"8017009",name:"200kW以内柴油发电机组",specs:"200GF",unit:"台班",type:"301"},
+        {code:"8017010",name:"250kW以内柴油发电机组",specs:"250GF4-4",unit:"台班",type:"301"},
+        {code:"8017011",name:"320kW以内柴油发电机组",specs:"320GF-2",unit:"台班",type:"301"}
+    ],
     initSpread:function () {
-        if(this.spread) return;
+        if(this.spread) return this.spread.refresh();
         this.spread = SheetDataHelper.createNewSpread($("#electrovalence_sheet")[0]);
         sheetCommonObj.spreadDefaultStyle(this.spread);
         this.sheet = this.spread.getSheet(0);
         sheetCommonObj.initSheet(this.sheet, this.setting, 30);
-    /*    this.materialSheet.bind(GC.Spread.Sheets.Events.ValueChanged, this.onMaterialValueChange);
-        this.materialSheet.bind(GC.Spread.Sheets.Events.SelectionChanged,this.onMaterialSelectionChange);
-        this.materialSheet.bind(GC.Spread.Sheets.Events.EditStarting,this.onMaterialEditStarting);*/
+        this.sheet.bind(GC.Spread.Sheets.Events.SelectionChanged,this.onElectrovalenceSelectionChange);
+        this.sheet.bind(GC.Spread.Sheets.Events.ValueChanged, this.onElectrovalenceValueChange);
+        this.sheet.bind(GC.Spread.Sheets.Events.EditStarting,this.onElectrovalenceEditStarting);
+    /*
+        ;*/
         this.sheet.name('electrovalence_sheet');
         if(projectReadOnly){
             disableSpread(this.spread);
         }
+    },
+    showDatas:function (datas) {
+        let sel = this.sheet.getSelections()[0];
+        let oldData = sel.row<this.datas.length?this.datas[sel.row]:"";
+        this.sheet.setRowCount(0);
+        this.datas = datas?datas:this.getElectrovalenceDatas();
+        this.calcPertElectrovalenceMarketPrice(this.datas);
+        sheetCommonObj.showData(this.sheet, this.setting,this.datas);
+        this.sheet.setRowCount(this.datas.length+1);
+        let nameCol = _.findIndex(this.setting.header,{'dataCode':'displayName'});
+        let nameOptions = this.getElectrovalenceOptions();
+        sheetCommonObj.setComboBox(-1,nameCol,this.sheet,nameOptions,false,false,5);
+        sel.row =  oldData?_.findIndex(this.datas,{'ID':oldData.ID}):sel.row ;
+        this.sheet.setSelection(sel.row==-1?0:sel.row,sel.col,sel.rowCount,sel.colCount);
+    },
+    getElectrovalenceDatas:function () {
+        let datas = [];
+        let pgljMap = {};
+        let com_electrovalence = projectObj.project.projectGLJ.datas.com_electrovalence;
+        for(let pg of projectObj.project.projectGLJ.datas.gljList){
+            pgljMap[gljUtil.getIndex(pg)] = pg;
+        }
+        if(com_electrovalence && com_electrovalence.gljList){
+            for (let g of com_electrovalence.gljList){
+                let t = this.createNewElectrovalenceData(g);
+                let tg = pgljMap[gljUtil.getIndex(g)];
+                if(tg) gljOprObj.setGLJPrice(t,tg);
+                datas.push(t);
+            }
+        }
+        return datas;
+    },
+    createNewElectrovalenceData:function (g) {//只是拷贝一份
+        let t = {
+            ID:g.ID,
+            GLJID:g.GLJID,
+            projectGLJID:g.projectGLJID,
+            name:g.name,
+            displayName:g.displayName,
+            code:g.code,
+            specs:g.specs,
+            unit:g.unit,
+            type:g.type,
+            coe: g.coe,
+            from:g.from
+        };
+        return t;
+    },
+
+    calcPertElectrovalenceMarketPrice:function (datas) {
+        let total = 0;
+        for(let d of datas){
+            if(d.name == "电网电"){
+                d.electPrice = d.marketPrice;
+            }else {
+                let w = parseInt(d.name);
+                if(!w) continue;
+                let t = scMathUtil.roundForObj(d.marketPrice/w,getDecimal("process"));
+                d.electPrice = scMathUtil.roundForObj(t * gljUtil.getElecCoe(),getDecimal("glj.unitPriceHasMix"));
+            }
+            let et = scMathUtil.roundForObj(d.electPrice * d.coe,getDecimal("process"));
+            total = scMathUtil.roundForObj(et + total,getDecimal("process"));
+        }
+        this.total = scMathUtil.roundForObj(total,getDecimal("glj.unitPrice"));
+        $("#electrovalenceLabel").text(`综合电价:${this.total}`);
+    },
+    getElectrovalenceOptions:function () {
+        return _.map(this.options,"name")
+    },
+    onElectrovalenceSelectionChange:function (sender,args) {
+        args.sheet.repaint();
+    },
+    onElectrovalenceEditStarting:function (sender,args) {
+        let me = electrovalenceObj;
+        let dataCode = me.setting.header[args.col].dataCode;
+        if(dataCode == "electPrice" ){//除电网电外,不可修改
+            let cancel = true;
+            if(me.datas[args.row] && me.datas[args.row].name == "电网电") cancel  = false;
+            args.cancel = cancel;
+        }
+    },
+
+
+    onElectrovalenceValueChange:function (sender,args) {
+        let me = electrovalenceObj;
+        let dataCode = me.setting.header[args.col].dataCode;
+        let value = args.newValue;
+        if(dataCode == "displayName" && args.row >= me.datas.length) {//新增
+             me.addElectrovalence(value);
+        }else { //修改
+            let tem = me.datas[args.row];
+            if (value&&!sheetCommonObj.checkData(args.col,me.setting,value)) {
+                alert('输入的数据类型不对,请重新输入!');
+                return  me.showDatas(me.datas);
+            }
+            if(dataCode == 'coe' || dataCode == 'electPrice'){
+                let dec = dataCode == 'coe' ?getDecimal("process"):getDecimal("glj.unitPrice");
+                if(value){
+                    value = scMathUtil.roundForObj(value,dec);
+                }
+                tem[dataCode] = value;
+                if(dataCode == 'electPrice') tem.marketPrice = value;
+            }else if(dataCode == 'displayName'){//下拉替换
+                me.editElectrovalence(value,args.row,"replace");
+            }
+            me.showDatas(me.datas);
+        }
+    },
+    addElectrovalence:async function (name) {
+        this.editElectrovalence(name);
+    },
+    editElectrovalence:async function (name,row,type="add") {
+        //新建项目的时候,电已经默认生成了,所以不用考考虑电没有的情况
+        try {
+            let glj = _.find(this.options,{name:name});
+            if(glj){
+                let tem = {displayName:glj.name,code:glj.code,specs:glj.specs,unit:glj.unit,type:glj.type,projectID : projectObj.project.ID()};
+                tem.ID = uuid.v1();
+                $.bootstrapLoading.start();
+                let result =  await ajaxPost('/glj/insertElectrovalence',tem);
+                //插入项目工料机列表
+                let newProjectPGJ = projectObj.project.projectGLJ.loadNewProjectGLJToCache(result.projetcGLJData);
+                //加入综合电价显示列表缓存
+                tem.GLJID = result.projetcGLJData.glj_id;
+                tem.projectGLJID = result.projetcGLJData.id;
+                tem.name =  result.projetcGLJData.name;
+                tem.coe = 0;
+                tem.from = "std";
+                gljOprObj.setGLJPrice(tem,newProjectPGJ);
+
+                if(type == "add"){
+                    this.datas.push(tem);
+                }else { //除了添加的就是替换
+                    if(this.datas[row])this.datas[row]=tem;
+                }
+                this.showDatas(this.datas);
+            }
+        }catch (e){
+            console.log(e)
+        }finally {
+            //materialCalcObj.showDatas();
+            $.bootstrapLoading.end();
+        }
+    },
+    getGljListFromDatas:function (datas) {
+        let gljList = [];
+        for(let d of datas){
+            gljList.push(this.createNewElectrovalenceData(d));
+        }
+        return gljList;
+    },
+    updateElectrovalence:function () {
+        let updateMap = {};
+        let dwd = null;//电网电
+        let com_electrovalence = projectObj.project.projectGLJ.datas.com_electrovalence;
+        if(com_electrovalence){//存在则是更新
+            updateMap['electrovalence'] = {
+                actionType:'update',
+                ID:com_electrovalence.ID,
+                doc:{gljList:this.getGljListFromDatas(this.datas)}
+            };
+        }else { //不存在则是新增
+            updateMap['electrovalence'] = {
+                actionType:'add',
+                doc:{
+                    unit_price_file_id:projectObj.project.property.unitPriceFile.id,
+                    gljList:this.getGljListFromDatas(this.datas)
+                }
+            };
+            updateMap['electrovalence']['doc'].ID = uuid.v1();
+        }
+        for(let t of this.datas){
+            if(t.name == '电网电'){
+                dwd = t;
+            }
+        }
+        let unitPrices = [];
+        for(let g of projectObj.project.projectGLJ.datas.gljList){
+            if(dwd && g.id == dwd.projectGLJID){
+                if(g.unit_price.market_price != dwd.electPrice+''){
+                  let  t_unitPrice = {projectGLJID:g.id,id:g.unit_price.id,'unit_price_file_id':g.unit_price.unit_price_file_id,doc:{'market_price':dwd.electPrice+""}};
+                    unitPrices.push(t_unitPrice);
+                }
+            }
+            if(g.code == gljUtil.getElecCode() && g.name == "电" && g.unit == "kW·h"){//更新电价
+                if(g.unit_price.market_price != this.total+''){
+                    let  d_unitPrice = {projectGLJID:g.id,id:g.unit_price.id,'unit_price_file_id':g.unit_price.unit_price_file_id,doc:{'market_price':this.total+''}};
+                    unitPrices.push(d_unitPrice);
+                }
+            }
+        }
+        if(unitPrices.length > 0)updateMap["unitPrice"] =  unitPrices;
+        this.submitElectrovalenceChange(updateMap)
+    },
+    submitElectrovalenceChange:async function (updateMap) {
+        try {
+            if(!_.isEmpty(updateMap)){
+                $.bootstrapLoading.start();
+                let result =  await ajaxPost('/glj/updateElectrovalence',updateMap);
+                projectObj.project.projectGLJ.refreshEctrovalenceCache(updateMap);
+            }
+        }catch (e){
+            console.log(e)
+        }finally {
+            $.bootstrapLoading.end();
+        }
+
     }
+
+
 };
 
 $(function () {
 
     $("#electrovalenceDiv").on('shown.bs.modal', function () {
         electrovalenceObj.initSpread();
+        electrovalenceObj.showDatas();
     });
+
+    $("#removeElectrovalencec").click(function(){
+        let record = sheetCommonObj.getSelectedRecode(electrovalenceObj.sheet,electrovalenceObj.datas);
+        if(record){
+            _.remove(electrovalenceObj.datas,{'ID':record.ID});
+            electrovalenceObj.showDatas(electrovalenceObj.datas);
+        }
+    });
+
+    $("#electrovalencecConfirm").click(function () {
+        electrovalenceObj.updateElectrovalence();
+    })
 });

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

@@ -726,7 +726,8 @@ var gljOprObj = {
                     }
                     if(ration) gljOprObj.getTotalQuantity(ration_gljs[i], ration);
                 }else {
-                    console.log("没有找到工料机:"+ration_gljs[i].name)
+                    //计算程序中量价也会放到这里进来,量价是没有对应的项目工料机的
+                    if(ration_gljs[i].type != rationType.volumePrice) console.log("没有找到工料机:"+ration_gljs[i].name)
                 }
             }
         }

+ 141 - 87
web/building_saas/main/js/views/material_calc_view.js

@@ -128,6 +128,7 @@ materialCalcObj = {
         this.freightSheet.bind(GC.Spread.Sheets.Events.ValueChanged, this.onFreightValueChange);
         this.freightSheet.bind(GC.Spread.Sheets.Events.SelectionChanged,this.onFreightSelectionChange);
         this.freightSheet.bind(GC.Spread.Sheets.Events.EditStarting,this.onFreightEditStarting);
+        this.freightSheet.bind(GC.Spread.Sheets.Events.RangeChanged, this.onFreightPriceRangeChange);
         this.freightSheet.name('freight_calc');
         if(projectReadOnly){
             disableSpread(this.freightSpread);
@@ -172,6 +173,7 @@ materialCalcObj = {
         sheetCommonObj.spreadDefaultStyle(this.priceSpread);
         this.priceSheet = this.priceSpread.getSheet(0);
         sheetCommonObj.initSheet(this.priceSheet, this.priceSetting, 30);
+        this.priceSheet.bind(GC.Spread.Sheets.Events.RangeChanged, this.onFreightPriceRangeChange);
         this.priceSheet.bind(GC.Spread.Sheets.Events.ValueChanged, this.onPriceValueChange);
         this.priceSheet.bind(GC.Spread.Sheets.Events.SelectionChanged,this.onPriceSelectionChange);
         this.priceSheet.bind(GC.Spread.Sheets.Events.EditStarting,this.onPriceEditStarting);
@@ -189,12 +191,12 @@ materialCalcObj = {
         this.freightSheet.setRowCount(0);
         this.freightDatas = this.getFreightDatas();
         sheetCommonObj.showData(this.freightSheet, this.freightSetting,this.freightDatas);
-        this.freightSheet.setRowCount(this.freightDatas+20);
+        this.freightSheet.setRowCount(this.freightDatas.length+20);
         let convCol = _.findIndex(this.freightSetting.header,{'dataCode':'conveyance'});
         sheetCommonObj.setComboBox(-1,convCol,this.freightSheet,this.conveyanceOptions,false);
         let startCol = _.findIndex(this.freightSetting.header,{'dataCode':'start'});
         let startOptions = this.getUserFreightOptions();
-        sheetCommonObj.setComboBox(-1,startCol,this.freightSheet,startOptions,false,true);
+        sheetCommonObj.setComboBox(-1,startCol,this.freightSheet,startOptions,false,true,5);
         sel.row =  oldData?_.findIndex(this.freightDatas,{'ID':oldData.ID}):sel.row ;
         this.freightSheet.setSelection(sel.row==-1?0:sel.row,sel.col,sel.rowCount,sel.colCount);
         this.refreshRationView();
@@ -382,6 +384,7 @@ materialCalcObj = {
         let me = materialCalcObj;
         let dataCode = me.rationSetting.header[args.col].dataCode;
         let datas = type == "freight"?me.freightRations:me.priceRations;
+        if(type ==  'price' && !gljUtil.isDef(me.getSelectedPrice()))   args.cancel = true;//没有选中原价,不可编辑
         if(args.row > datas.length){
             args.cancel = true;
         }else if(args.row == datas.length && dataCode != "code"){
@@ -456,6 +459,7 @@ materialCalcObj = {
                 if(key == "connect_key") doc[key] = gljUtil.getIndex(material);
                 if(key == "unit_price_file_id") doc[key] = material.unit_price.unit_price_file_id;
             }
+            delete doc._id;
             return doc;
         }
     },
@@ -469,69 +473,100 @@ materialCalcObj = {
         }
         return t;
     },
+    onFreightPriceRangeChange:function (sender,args) {
+        let me = materialCalcObj;
+        let dataMap={};
+        let sheetName = args.sheet.name();
+        for(let c of args.changedCells){
+            let info = {row:c.row,col:c.col,cancel:false};
+            sheetName == 'price_calc'?me.onPriceEditStarting(sender,info): me.onFreightEditStarting(sender,info);
+            if(info.cancel) return me.showDatas();
+            let value=  args.sheet.getCell(c.row, c.col).text();
+            if(dataMap[c.row]){
+                dataMap[c.row][c.col]=value;
+            }else{
+                dataMap[c.row] ={};
+                dataMap[c.row][c.col] = value;
+            }
+        }
+        sheetName == 'price_calc'?me.addOrUpdatePriceCalc(dataMap):me.addOrUpdateFreightCalc(dataMap);
+    },
     onFreightValueChange:function (sender,args) {
         let me = materialCalcObj;
-        let dataCode = me.freightSetting.header[args.col].dataCode;
-        let value = args.newValue;
+        let dataMap = {};
+        dataMap[args.row]={};
+        dataMap[args.row][args.col] = args.newValue;
+        me.addOrUpdateFreightCalc(dataMap);
+    },
+    addOrUpdateFreightCalc:function (dataMap) {//{2:{col:value}}
+        let me = materialCalcObj;
         let material = me.getMaterialSelected();
-        if (value&&!sheetCommonObj.checkData(args.col,me.freightSetting,value)) {
-            alert('输入的数据类型不对,请重新输入!');
-            me.showDatas();
-            return;
-        }
-        if(dataCode != 'start'&&dataCode != 'conveyance'&&dataCode != 'calcType'&&dataCode != 'materialType'){
-            value = value?scMathUtil.roundForObj(value,getDecimal("glj.unitPrice"))+'':'0'//4舍五入加默认为0
-        }
-        if(args.row >= me.freightDatas.length){//新增
+        let addDatas=[],updateDatas=[];
+        for(let row in dataMap) {
+            let t = dataMap[row];
             let newData = {};
-            let tempFreight = null;
-            if(dataCode == "start"){
-                tempFreight = me.getSavedFreight(value,material);
-            }
-            if(tempFreight){
-                newData = tempFreight;
-            }else {
-                newData = me.getNewFreightData(material);
-                newData[dataCode] = value;
-            }
-            projectObj.project.projectGLJ.addFreightCalc([newData],material.id);
-        }else {//修改
-            let recode = me.freightDatas[args.row];
-            if(recode[dataCode] == value) return;
             let doc = {};
-            doc[dataCode] = value;
-            if(dataCode == "conveyance"){//如果运输方式从自办运输切换成其它的东西时,要把底下挂的定额和定额工料机都清空
-                if(args.oldValue == "自办运输"){
-                    doc["rations"] = [];
-                    doc["ration_gljs"] = [];
+            let recode = me.freightDatas[row];
+            for (let col in t) {
+                let value = t[col];
+                let dataCode = me.freightSetting.header[col].dataCode;
+                if (value && !sheetCommonObj.checkData(col, me.freightSetting, value)) {
+                    alert('输入的数据类型不对,请重新输入!');
+                    return me.showDatas();
                 }
-                if(value == "自办运输"){//当运输工具下拉选择“自办运输”时,“Km运距”、“装卸费单价”、“装卸次数”、“运价增加率(%)”列数据归0,且灰选不可编辑
-                    doc["kmDistance"] = '0';
-                    doc["unitLoadingFee"] ='0';
-                    doc["loadingTimes"] = '0';
-                    doc["freightIncreaseRate"] = '0';
+                if (dataCode != 'start' && dataCode != 'conveyance' && dataCode != 'calcType' && dataCode != 'materialType') {
+                    value = value ? scMathUtil.roundForObj(value, getDecimal("glj.unitPrice")) + '' : '0'//4舍五入加默认为0
                 }
-                if(args.oldValue =="汽车") doc["materialType"] = "";//当运输方式从汽车切换成其它方式时,清空材料类型
+                if (parseInt(row) >= me.freightDatas.length) {//新增
+                    let tempFreight = null;
+                    if (dataCode == "start") {
+                        tempFreight = me.getSavedFreight(value, material);
+                    }
+                    if (tempFreight) {
+                        newData = tempFreight;
+                    } else {
+                        if(_.isEmpty(newData)) newData = me.getNewFreightData(material);
+                        newData[dataCode] = value;
+                    }
+                } else {//修改
+                    if (recode[dataCode] == value) continue;
+                    doc[dataCode] = value;
+                    if (dataCode == "conveyance") {//如果运输方式从自办运输切换成其它的东西时,要把底下挂的定额和定额工料机都清空
+                        if (recode[dataCode] == "自办运输") {//没改之前的值
+                            doc["rations"] = [];
+                            doc["ration_gljs"] = [];
+                        }
+                        if (value == "自办运输") {//当运输工具下拉选择“自办运输”时,“Km运距”、“装卸费单价”、“装卸次数”、“运价增加率(%)”列数据归0,且灰选不可编辑
+                            doc["kmDistance"] = '0';
+                            doc["unitLoadingFee"] = '0';
+                            doc["loadingTimes"] = '0';
+                            doc["freightIncreaseRate"] = '0';
+                        }
+                        if (recode[dataCode] == "汽车") doc["materialType"] = "";//当运输方式从汽车切换成其它方式时,清空材料类型
 
-            }
-          /*  if(dataCode == "calcType"){
-                if(value == "全国") doc["materialType"] = "";
-                if(value == "内蒙古"){
-                    doc["materialType"] = "地方材料";
-                    doc["unitFreight"] = me.calcNeiMengUnitFreight(recode.kmDistance,"地方材料");
-                }
-            }*/
+                    }
 
-            if(dataCode == "materialType" && value!="") doc["unitFreight"] = me.calcNeiMengUnitFreight(recode.kmDistance,value);
-            if(dataCode == "kmDistance" && gljUtil.isDef(recode.materialType)&&recode.materialType!="") doc["unitFreight"] = me.calcNeiMengUnitFreight(value,recode.materialType);
+                    if (dataCode == "materialType" && value != "") doc["unitFreight"] = me.calcNeiMengUnitFreight(recode.kmDistance, value);
+                    if (dataCode == "kmDistance" && gljUtil.isDef(recode.materialType) && recode.materialType != "") doc["unitFreight"] = me.calcNeiMengUnitFreight(value, recode.materialType);
 
-            if(dataCode == "start"){
-               let t_f = me.getSavedFreight(value,material);
-               if(t_f) doc = t_f;
+                    if (dataCode == "start") {
+                        let t_f = me.getSavedFreight(value, material);
+                        if (t_f) doc = t_f;
+                    }
 
+                }
             }
-            projectObj.project.projectGLJ.updateFreightCalc([{ID:recode.ID,doc:doc}],material.id);
+            if (!_.isEmpty(newData)) addDatas.push(newData);
+            if (!_.isEmpty(doc)) updateDatas.push({ID:recode.ID,doc:doc});
+        }
+        if(addDatas.length > 0 && updateDatas.length > 0) {
+            alert("不能同时增加和更新操作");
+            return me.showDatas();
         }
+        if(addDatas.length > 0)  projectObj.project.projectGLJ.addFreightCalc(addDatas,material.id);
+        if(updateDatas.length > 0)  projectObj.project.projectGLJ.updateFreightCalc(updateDatas,material.id);
+
+
     },
     calcNeiMengUnitFreight:function (tkmDistance,tmaterialType) {
         if(!tkmDistance||tkmDistance == '0') return "0";
@@ -631,39 +666,61 @@ materialCalcObj = {
         }
 
     },
-    onPriceValueChange:function(sender,args){
+    addOrUpdatePriceCalc:function (dataMap) {
         let me = materialCalcObj;
-        let dataCode = me.priceSetting.header[args.col].dataCode;
-        let value = args.newValue;
         let material = me.getMaterialSelected();
-        //输入有效性判断, to do
-        if (value&&!sheetCommonObj.checkData(args.col,me.priceSetting,value)) {
-            alert('输入的数据类型不对,请重新输入!');
-            me.showDatas();
-            return;
-        }
-        if(dataCode == 'coe'||dataCode == 'supplyPrice'){
-            let decimal = dataCode == 'supplyPrice'?getDecimal("glj.unitPriceHasMix"):getDecimal("glj.unitPrice");
-            value = value?scMathUtil.roundForObj(value,decimal)+'':'0'//4舍五入加默认为0
-        }
-        if(args.row >= me.priceDatas.length){//新增
-            let newData = {
-                ID:uuid.v1(),
-                supplyLocation:"",
-                supplyPrice:'0',
-                coe:'1',
-                connect_key:gljUtil.getIndex(material),
-                unit_price_file_id:material.unit_price.unit_price_file_id
-            };
-            newData[dataCode] = value;
-            projectObj.project.projectGLJ.addPriceCalc([newData],material.id);
-        }else {//修改
-            let recode = me.priceDatas[args.row];
-            if(recode[dataCode] == value) return;
+        let addDatas=[],updateDatas=[];
+        for(let row in dataMap) {
+            let t = dataMap[row];
             let doc = {};
-            doc[dataCode] = value;
-            projectObj.project.projectGLJ.updatePriceCalc([{ID:recode.ID,doc:doc}],material.id);
+            let recode = me.priceDatas[row];
+            let newData = {};
+            for (let col in t) {
+                let value = t[col];
+                let dataCode =  me.priceSetting.header[col].dataCode;;
+                if (value && !sheetCommonObj.checkData(col, me.priceSetting, value)) {
+                    alert('输入的数据类型不对,请重新输入!');
+                    return me.showDatas();
+                }
+                if(dataCode == 'coe'||dataCode == 'supplyPrice'){
+                    let decimal = dataCode == 'supplyPrice'?getDecimal("glj.unitPriceHasMix"):getDecimal("glj.unitPrice");
+                    value = value?scMathUtil.roundForObj(value,decimal)+'':'0'//4舍五入加默认为0
+                }
+                if(parseInt(row) >= me.priceDatas.length){//新增
+                    if(_.isEmpty(newData)) newData = me.getNewPriceData(material);
+                    newData[dataCode] = value;
+                }else {//修改
+                    if(recode[dataCode] == value) continue;
+                    doc[dataCode] = value;
+                }
+            }
+            if (!_.isEmpty(newData)) addDatas.push(newData);
+            if (!_.isEmpty(doc)) updateDatas.push({ID:recode.ID,doc:doc});
+        }
+        if(addDatas.length > 0 && updateDatas.length > 0) {
+            alert("不能同时增加和更新操作");
+            return me.showDatas();
         }
+        if(addDatas.length > 0)  projectObj.project.projectGLJ.addPriceCalc(addDatas,material.id);
+        if(updateDatas.length > 0)  projectObj.project.projectGLJ.updatePriceCalc(updateDatas,material.id);
+    },
+    getNewPriceData:function (material) {
+        let newData = {
+            ID:uuid.v1(),
+            supplyLocation:"",
+            supplyPrice:'0',
+            coe:'1',
+            connect_key:gljUtil.getIndex(material),
+            unit_price_file_id:material.unit_price.unit_price_file_id
+        };
+        return newData;
+    },
+    onPriceValueChange:function(sender,args){
+        let me = materialCalcObj;
+        let dataMap = {};
+        dataMap[args.row]={};
+        dataMap[args.row][args.col] = args.newValue;
+        me.addOrUpdatePriceCalc(dataMap);
     },
     deleteMaterialCal:function (row) {
         let record = this.materialDatas[row];//修改材料计算标记的同时还要删除原价计算,运费计算等
@@ -711,6 +768,7 @@ materialCalcObj = {
             let user_freight = {rootProjectID:projectObj.project.projectInfo.property.rootProjectID};
             let f = {};
             for(let key in record){
+                if(key == "_id") continue;
                 f[key] = record[key];
                 if(key =="ration" || key == "ration_gljs")f[key] = [];//下面的定额和工料机不用保存
             }
@@ -729,6 +787,7 @@ materialCalcObj = {
         t.rootProjectID = projectObj.project.projectInfo.property.rootProjectID;
         let f = {};
         for(let key in record){
+            if(key == "_id") continue;
             f[key] = record[key];
             if(key =="ration" || key == "ration_gljs")f[key] = [];//下面的定额和工料机不用保存
         }
@@ -922,12 +981,7 @@ materialCalcObj = {
        return this.getSelectedRecode(this.priceSheet,this.priceDatas)
     },
     getSelectedRecode:function (sheet,datas) {
-        let sel = sheet.getSelections()[0];
-        let srow = sel.row == -1||sel.row == ""?0:sel.row;
-        if(gljUtil.isDef(srow) && datas.length>srow){
-            return datas[srow];
-        }
-        return null;
+        return sheetCommonObj.getSelectedRecode(sheet,datas);
     }
 
 };

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

@@ -687,6 +687,7 @@
 <!-- JS. -->
 <script src = "/lib/spreadjs/sheets/gc.spread.sheets.all.11.1.2.min.js"></script>
 <script src = "/lib/fileSaver/FileSaver.min.js"></script>
+<script src="/lib/qiniu/qiniu.min.js"></script>
 <script>GC.Spread.Sheets.LicenseKey = '<%- LicenseKey %>';</script>
 <!-- inject:js -->
 <script src="/web/building_saas/js/global.js"></script>

+ 78 - 50
web/building_saas/pm/js/pm_newMain.js

@@ -404,8 +404,11 @@ const projTreeObj = {
                 return true;
             },
             callback: function (key, opt) {
-                //获取当前节点的建设项目ID
+
+
+                $("#confirm-import").hide();
                 $("#import").modal('show');
+                projTreeObj.getUploadToken();
             }
         }
     },
@@ -1588,6 +1591,11 @@ const projTreeObj = {
         }
         updateData["self"] ={ParentID:parent.id(),NextSiblingID:next?next.id():-1};
         return updateData;
+    },
+    getUploadToken:async function () {
+        let result =await ajaxGet("/pm/api/getUploadToken");
+        $("#confirm-import").show();
+        projTreeObj.uptoken=result.uptoken;
     }
 
 };
@@ -3785,58 +3793,78 @@ $("#confirm-import").click(function() {
         return;
     }
     STATE.importing = true;
-    const self = $(this);
-    try {
-        let formData = new FormData();
-        let file = $("input[name='import_project_data']")[0];
-        if (file.files.length <= 0) {
-            throw '请选择文件!';
-        }
-        formData.append('file', file.files[0]);
-        formData.append('userID', userID);
-        formData.append("updateData",JSON.stringify(projTreeObj.getImportProjectDate()));
-        $('#import').modal("hide");
-        $.bootstrapLoading.progressStart("导入建设项目",true);
-        $.ajax({
-            url: '/pm/api/importProject',
-            type: 'POST',
-            data: formData,
-            cache: false,
-            contentType: false,
-            processData: false,
-            timeout:300000,
-            beforeSend: function() {
-                self.attr('disabled', 'disabled');
-                self.text('上传中...');
-            },
-            success: function(response){
-                STATE.importing = false;
-                self.text('确定导入');
-                $.bootstrapLoading.progressEnd();
-                if(response.error == 1){
-                    alert(response.msg);
-                    setTimeout(function () {
-                        $.bootstrapLoading.progressEnd();//不做这个的话太快,页面不会自动关闭
-                    },500)
-                }else {
-                    refreshAllPage();
-                }
 
-            },
-            error: function(){
-                STATE.importing = false;
-                setTimeout(function () {
-                    self.text('确定导入');
-                    $.bootstrapLoading.progressEnd();
-                    alert("导入失败,请检查文件!");
-                },1000)
+    let input = $("input[name='import_project_data']")[0];
+    if (input.files.length <= 0) {
+        throw '请选择文件!';
+    }
+    let token = projTreeObj.uptoken;
+    $('#import').modal("hide");
+    $.bootstrapLoading.progressStart("上传文件中",true);
+    let file = input.files[0];
+    let key = uuid.v1() + ".ybp"; //file.name;
+    if (file) {
+        let config = {
+            useCdnDomain: true,
+            disableStatisticsReport: false,
+            retryCount: 6,
+            region: qiniu.region.z2
+        };
+        let putExtra = {
+            fname: "",
+            params: {"x:name":key.split(".")[0]},
+            mimeType: null
+        };
+        // 添加上传dom面板
+        let observable = qiniu.upload(file, key, token, putExtra, config);
+         observable.subscribe({
+             next:function (reponse) {
+                 console.log(reponse);
+             },
+             error:function (err) {
+                 console.log(err);
+             },
+             complete:function(res){
+                 console.log("complete")
+                 $("#progress_modal_body").text("正在导入建设项目");
+                 startImportProject(key);
+                 projTreeObj.uptoken = null;
+             }
+         });
+    }
+
+    async function  startImportProject(key) {
+        try {
+            console.log("start Import");
+            let result = await ajaxPost("/pm/api/importProject",{key:key,updateData:projTreeObj.getImportProjectDate()});
+            setTimeout(importProcessChecking,2000);
+        }catch (error){
+            alert(error);
+            $.bootstrapLoading.end();
+        }finally {
+            STATE.importing = false;
+        }
+    }
+
+    async function importProcessChecking() {
+        let result = await ajaxPost("/pm/api/importProcessChecking",{key:key,user_id:userID});
+        if(result.error == 1){
+            let message = result.msg?result.msg:result.message;
+            setTimeout(function () {
+                $.bootstrapLoading.progressEnd();//不做这个的话太快,页面不会自动关闭
+            },500);
+            alert(message)
+        }else if(result.error == 0){
+            if(result.status == "processing"){
+                setTimeout(importProcessChecking,2000);
+            }else if(result.status == "complete"){
+                $.bootstrapLoading.progressEnd();
+                refreshAllPage();
             }
-        });
-    } catch(error) {
-        STATE.importing = false;
-        alert(error);
-        $.bootstrapLoading.end();
+        }
     }
+    
+    
 });
 
 $("#import_project_data").change(function(){

+ 2 - 0
web/common/html/dataStatistics.html

@@ -0,0 +1,2 @@
+
+<script type="text/javascript">var cnzz_protocol = (("https:" == document.location.protocol) ? "https://" : "http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_1278513339'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "v1.cnzz.com/stat.php%3Fid%3D1278513339%26show%3Dpic1' type='text/javascript'%3E%3C/script%3E"));</script>

+ 11 - 5
web/common/html/header.html

@@ -1,5 +1,5 @@
 <img id="f_btn" src="/web/dest/css/img/feeRate_btn.jpg" alt="" style="display: none" />
-<nav class="navbar navbar-expand-lg p-0 d-flex">
+<nav class="navbar navbar-expand-lg p-0 d-flex <%= versionName.includes('免费') ? 'free-version' : 'pro-version' %>">
     <% if(controller === 'boot' || controller === 'pm'){ %>
     <!--<a style="text-decoration: none" href="javascript:void(0);" class="header-logo">-->
     <% }else { %>
@@ -18,9 +18,10 @@
         <!--大屏菜单-->
         <ul class="nav navbar-nav" id="fluid-menu">
             <li class="nav-item dropdown">
-                <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" id="link_userName"><%= sessionUser.real_name === '' ? sessionUser.mobile : sessionUser.real_name %></a>
+                <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" id="link_userName"><%= sessionUser.company ? sessionUser.company : sessionUser.real_name ? sessionUser.real_name : sessionUser.mobile %></a>
                 <div class="dropdown-menu dropdown-menu-right">
-                    <a class="dropdown-item" href="/user/info" target="_blank">账号资料</a>
+                    <a class="dropdown-item" href="/user/info" target="_blank">企业资料</a>
+                    <a class="dropdown-item" href="/user/safe" target="_blank">账号安全</a>
                     <a class="dropdown-item" href="/user/buy" target="_blank">产品激活</a>
                     <a class="dropdown-item" href="/user/preferences" target="_blank">登录设置</a>
                     <div class="dropdown-divider"></div>
@@ -66,9 +67,10 @@
                 </a>
                 <div class="dropdown-menu dropdown-menu-right">
                     <div class="dropdown dropleft dropdown-submenu">
-                        <button class="dropdown-item dropdown-toggle" type="button" data-toggle="dropdown"><%= sessionUser.real_name === '' ? sessionUser.mobile : sessionUser.real_name %></button>
+                        <button class="dropdown-item dropdown-toggle" type="button" data-toggle="dropdown"><%= sessionUser.company ? sessionUser.company : sessionUser.real_name ? sessionUser.real_name : sessionUser.mobile %></button>
                         <div class="dropdown-menu">
-                            <a class="dropdown-item" href="/user/info" target="_blank">账号资料</a>
+                            <a class="dropdown-item" href="/user/info" target="_blank">企业资料</a>
+                            <a class="dropdown-item" href="/user/safe" target="_blank">账号安全</a>
                             <a class="dropdown-item" href="/user/buy" target="_blank">产品激活</a>
                             <a class="dropdown-item" href="/user/preferences" target="_blank">登录设置</a>
                             <div class="dropdown-divider"></div>
@@ -266,6 +268,10 @@
         </div>
     </div>
 </div>
+<div style="display: none">
+    <%include dataStatistics.html %>
+</div>
+
 <!-- inject:js -->
 <script src="/lib/jquery/jquery-3.2.1.min.js"></script>
 <script type="text/javascript" src="/lib/jquery-ui/jquery-ui.min.js"></script>

+ 25 - 1
web/over_write/js/zhejiang_2005.js

@@ -188,7 +188,31 @@ if (typeof gljOprObj !== 'undefined') {
 }
 
 if(typeof gljUtil !== 'undefined'){
-    gljUtil.getCodeSortMath = getCodeSortMath
+    gljUtil.getCodeSortMath = getCodeSortMath;
+    gljUtil.getElecCoe = function () {
+        return 0.24;
+    }
+    gljUtil.getElecCode = function () {
+        return "267";
+    }
+}
+
+
+if(typeof electrovalenceObj !== 'undefined'){
+    electrovalenceObj.options = [
+        {code:"270",name:"电网电",specs:"",unit:"kW·h",type:"201"},
+        {code:"905",name:"5kW以内柴油发电机组",specs:"",unit:"台班",type:"301"},
+        {code:"906",name:"15kW以内柴油发电机组",specs:"",unit:"台班",type:"301"},
+        {code:"907",name:"30kW以内柴油发电机组",specs:"",unit:"台班",type:"301"},
+        {code:"908",name:"50kW以内柴油发电机组",specs:"",unit:"台班",type:"301"},
+        {code:"909",name:"75kW以内柴油发电机组",specs:"",unit:"台班",type:"301"},
+        {code:"910",name:"100kW以内柴油发电机组",specs:"",unit:"台班",type:"301"},
+        {code:"911",name:"120kW以内柴油发电机组",specs:"",unit:"台班",type:"301"},
+        {code:"912",name:"160kW以内柴油发电机组",specs:"",unit:"台班",type:"301"},
+        {code:"913",name:"200kW以内柴油发电机组",specs:"",unit:"台班",type:"301"},
+        {code:"914",name:"250kW以内柴油发电机组",specs:"",unit:"台班",type:"301"},
+        {code:"915",name:"320kW以内柴油发电机组",specs:"",unit:"台班",type:"301"}
+    ]
 }
 
 if(typeof materialCalcObj !== 'undefined'){

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
web/users/html/login.html


+ 3 - 3
web/users/html/user-buy.html

@@ -24,7 +24,7 @@
                     <div class="mt-3">
                         <ul class="nav nav-pills flex-column">
                             <li class="nav-item">
-                                <a class="nav-link" href="/user/info">账号资料</a>
+                                <a class="nav-link" href="/user/info">企业资料</a>
                             </li>
                             <li class="nav-item">
                                 <a class="nav-link" href="/user/safe">账号安全</a>
@@ -49,7 +49,7 @@
                         <legend class=" mb-4">激活专业版</legend>
                         <div class="row">
                             <div class="col-sm-4 mb-5">
-                                <div class="card">
+                                <div class="card free-version">
                                   <div class=" card-body">
                                     <h3 class="card-title">免费版 </h3>
                                       <p class="card-text">
@@ -74,7 +74,7 @@
                                 </div>
                             </div>
                             <div class="col-sm-4 mb-5">
-                                <div class="card">
+                                <div class="card pro-version">
                                   <div class=" card-body">
                                     <h3 class="card-title">专业版</h3>
                                       <p class="card-text">

+ 32 - 7
web/users/html/user-info.html

@@ -1,3 +1,8 @@
+<!--
+ * @Descripttion: 
+ * @Author: Zhong
+ * @Date: 2019-12-04 12:04:48
+ -->
     <!DOCTYPE html>
 <html lang="zh-CN">
 
@@ -5,7 +10,7 @@
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
     <meta http-equiv="x-ua-compatible" content="ie=edge">
-    <title>账号资料-纵横公路养护造价</title>
+    <title>企业资料-纵横公路养护造价</title>
     <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">
@@ -24,7 +29,7 @@
                 <div class="mt-3">
                     <ul class="nav nav-pills flex-column">
                         <li class="nav-item">
-                            <a class="nav-link active" href="/user/info">账号资料</a>
+                            <a class="nav-link active" href="/user/info">企业资料</a>
                         </li>
                         <li class="nav-item">
                             <a class="nav-link" href="/user/safe">账号安全</a>
@@ -40,13 +45,9 @@
             </div>
             <div class="col-lg-10">
                 <div class="col-lg-4">
-                    <legend class="my-3">账号资料</legend>
+                    <legend class="my-3">企业资料</legend>
                     <form id="info-form" method="post" action="/user/info">
                         <div class="form-group">
-                            <label class="form-control-label">您的姓名</label>
-                            <input class="form-control" value="<%= userData.real_name %>" placeholder="输入您的姓名" id="name" name="real_name" autocomplete="off">
-                        </div>
-                        <div class="form-group">
                             <label class="form-control-label">企业名称</label>
                             <input class="form-control" value="<%= userData.company %>" placeholder="输入您的企业名称" id="company" name="company" autocomplete="off">
                         </div>
@@ -58,6 +59,30 @@
                                 <% })%>
                             </select>
                         </div>
+                        <div class="form-group">
+                            <label class="form-control-label">企业类型</label>
+                            <select class="form-control" name="company_type">
+                                <% companyTypeList.forEach(function(company_type, index) {%>
+                                <option value="<%= index %>" <% if(index === userData.company_type) {%>selected="selected"<% } %>><%= company_type %></option>
+                                <% })%>
+                            </select>
+                        </div>
+                        <div class="form-group">
+                            <label class="form-control-label">企业规模</label>
+                            <select class="form-control" name="company_scale">
+                                <% companyScaleList.forEach(function(company_scale, index) {%>
+                                <option value="<%= index %>" <% if(index === userData.company_scale) {%>selected="selected"<% } %>><%= company_scale %></option>
+                                <% })%>
+                            </select>
+                        </div>
+                        <div class="form-group">
+                            <label class="form-control-label">联系人</label>
+                            <input class="form-control" value="<%= userData.real_name %>" placeholder="输入您的姓名" id="name" name="real_name" autocomplete="off">
+                        </div>
+                        <div class="form-group">
+                            <label class="form-control-label">当前管理账号(登录账号)</label>
+                            <input class="form-control" value="<%= userData.mobile %>" readonly>
+                        </div>
                     <!--    <div class="form-group">
                             <label class="form-control-label">企业类型</label>
                             <select class="form-control" name="company_type">

+ 9 - 9
web/users/html/user-safe.html

@@ -24,7 +24,7 @@
                 <div class="mt-3">
                     <ul class="nav nav-pills flex-column">
                         <li class="nav-item">
-                            <a class="nav-link" href="/user/info">账号资料</a>
+                            <a class="nav-link" href="/user/info">企业资料</a>
                         </li>
                         <li class="nav-item">
                             <a class="nav-link active" href="/user/safe">账号安全</a>
@@ -43,10 +43,9 @@
                     <legend class="my-3">账号安全</legend>
                     <from>
                         <div class="form-group">
-                            <label class="form-control-label">登录密码</label>
-                            <div class="form-control-static">
-                                <a class="btn btn-outline-primary btn-sm" href="https://sso.smartcost.com.cn/chpasswd" target="_blank">修改密码</a>
-                            </div>
+                            <label class="form-control-label">手机号码(登录账号)</label>
+                            <p class="form-control-static mb-0"><%= userData.mobile %> <span class="badge badge-success">已验证</span></p>
+                            <a class="btn btn-outline-primary btn-sm" href="https://sso.smartcost.com.cn/changeMobile" target="_blank">更换手机</a>
                         </div>
                         <div class="form-group">
                             <label class="form-control-label">邮箱地址</label>
@@ -55,7 +54,7 @@
                                     class="badge badge-default">未验证</span><% } else { %><span
                                     class="badge badge-success">已验证</span><% } %></p>
                             <% if (userData.isUserActive === 0) { %><a class="btn btn-outline-primary btn-sm" target="_blank" href="https://sso.smartcost.com.cn/profile">验证邮箱</a>
-                            <a class="btn btn-outline-primary btn-sm" target="_blank" href="https://sso.smartcost.com.cn/nactchm">更换邮箱</a>
+                            <a class="btn btn-secondary btn-sm" target="_blank" href="https://sso.smartcost.com.cn/nactchm">更换邮箱</a>
                             <% } else { %>
                             <a class="btn btn-outline-primary btn-sm" href="https://sso.smartcost.com.cn/changeMail" target="_blank">更换邮箱</a>
                             <% } %>
@@ -64,9 +63,10 @@
                             <% } %>
                         </div>
                         <div class="form-group">
-                            <label class="form-control-label">手机号码</label>
-                            <p class="form-control-static mb-0"><%= userData.mobile %> <span class="badge badge-success">已验证</span></p>
-                            <a class="btn btn-outline-primary btn-sm" href="https://sso.smartcost.com.cn/changeMobile" target="_blank">更换手机</a>
+                            <label class="form-control-label">登录密码</label>
+                            <div class="form-control-static">
+                                <a class="btn btn-outline-primary btn-sm" href="https://sso.smartcost.com.cn/chpasswd" target="_blank">修改密码</a>
+                            </div>
                         </div>
                         <div class="form-group">
                             <label class="form-control-label">异常登录提醒</label>

+ 1 - 1
web/users/html/user-set.html

@@ -25,7 +25,7 @@
                     <div class="mt-3">
                         <ul class="nav nav-pills flex-column">
                             <li class="nav-item">
-                                <a class="nav-link" href="/user/info">账号资料</a>
+                                <a class="nav-link" href="/user/info">企业资料</a>
                             </li>
                             <li class="nav-item">
                                 <a class="nav-link" href="/user/safe">账号安全</a>