瀏覽代碼

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

Conflicts:
	package-lock.json
TonyKang 4 年之前
父節點
當前提交
b2d3ca389c
共有 49 個文件被更改,包括 4984 次插入3224 次删除
  1. 0 1
      config/gulpConfig.js
  2. 0 4
      gulpfile.js
  3. 2 1
      modules/all_models/bills.js
  4. 4 0
      modules/all_models/user.js
  5. 95 1
      modules/main/facade/info_price_facade.js
  6. 1 1
      modules/main/middleware/index.js
  7. 1 1
      modules/users/controllers/boot_controller.js
  8. 4 0
      modules/users/controllers/cld_controller.js
  9. 2 2
      modules/users/controllers/login_controller.js
  10. 6 3
      modules/users/controllers/user_controller.js
  11. 4 4
      modules/users/models/user_model.js
  12. 4380 2958
      package-lock.json
  13. 1 0
      package.json
  14. 2 2
      public/web/sheet/sheet_common.js
  15. 5 4
      public/web/tree_sheet/tree_sheet_helper.js
  16. 2 2
      web/building_saas/complementary_ration_lib/html/gongliao.html
  17. 8 0
      web/building_saas/css/custom.css
  18. 二進制
      web/building_saas/css/favicon.ico
  19. 5 2
      web/building_saas/glj/html/project_glj.html
  20. 二進制
      web/building_saas/img/vip.png
  21. 二進制
      web/building_saas/img/vip2.png
  22. 23 19
      web/building_saas/main/html/main.html
  23. 47 16
      web/building_saas/main/js/controllers/block_controller.js
  24. 16 1
      web/building_saas/main/js/models/bills.js
  25. 1 0
      web/building_saas/main/js/models/calc_program.js
  26. 1 1
      web/building_saas/main/js/models/exportStdInterfaceBase.js
  27. 5 3
      web/building_saas/main/js/models/project.js
  28. 0 1
      web/building_saas/main/js/views/billsElf.js
  29. 5 5
      web/building_saas/main/js/views/block_lib.js
  30. 22 16
      web/building_saas/main/js/views/glj_col.js
  31. 5 1
      web/building_saas/main/js/views/main_tree_col.js
  32. 37 10
      web/building_saas/main/js/views/project_glj_view.js
  33. 81 6
      web/building_saas/main/js/views/project_view.js
  34. 5 6
      web/building_saas/main/js/views/tender_price_view.js
  35. 2 2
      web/building_saas/main/js/views/zmhs_view.js
  36. 5 4
      web/building_saas/pm/js/pm_gc.js
  37. 5 4
      web/building_saas/pm/js/pm_newMain.js
  38. 5 4
      web/building_saas/pm/js/pm_share.js
  39. 1 1
      web/building_saas/unit_price_file/index.js
  40. 7 5
      web/common/html/header.html
  41. 7 0
      web/over_write/js/chongqing_2018.js
  42. 4 0
      web/over_write/js/guangdong_2018.js
  43. 1 1
      web/users/html/index.html
  44. 4 4
      web/users/html/login-sms.html
  45. 1 1
      web/users/html/login-ver.html
  46. 4 4
      web/users/html/login.html
  47. 22 21
      web/users/html/user-buy.html
  48. 二進制
      web/users/images/favicon.ico
  49. 146 102
      web/users/js/login.js

+ 0 - 1
config/gulpConfig.js

@@ -238,7 +238,6 @@ module.exports = {
         'web/building_saas/complementary_ration_lib/js/explanatory.js',
         'web/building_saas/complementary_ration_lib/js/jobContent.js',
         'web/building_saas/complementary_ration_lib/js/annotation.js',
-        'public/web/scMathUtil.js',
         'public/web/common_ajax.js',
         'public/web/ztree_common.js',
         'public/web/ration_glj_units.js',

+ 0 - 4
gulpfile.js

@@ -116,7 +116,6 @@ let compleRation_rationOptions = {
     injectList: [
         'web/dest/scripts/compleRation_ration.all.min.' + version + '.js',
         'web/dest/css/compleRation_ration.all.min.' + version + '.css',
-        'web/dest/scripts/common.all.min.'+version+'.js',
         'web/dest/css/common.all.min.' + version + '.css'
     ]
 };
@@ -133,7 +132,6 @@ let compleRation_gljOptions = {
     injectList: [
         'web/dest/scripts/compleRation_glj.all.min.' + version + '.js',
         'web/dest/scripts/compleRation_glj.all.min.' + version + '.css',
-        'web/dest/scripts/common.all.min.'+version+'.js',
         'web/dest/css/common.all.min.' + version + '.css'
     ]
 };
@@ -150,7 +148,6 @@ let compleRation_coeOptions = {
     injectList: [
         'web/dest/scripts/compleRation_coe.all.min.' + version + '.js',
         'web/dest/scripts/compleRation_coe.all.min.' + version + '.css',
-        'web/dest/scripts/common.all.min.'+version+'.js',
         'web/dest/css/common.all.min.' + version + '.css'
     ]
 };
@@ -167,7 +164,6 @@ let compleRation_instOptions = {
     injectList: [
         'web/dest/scripts/compleRation_inst.all.min.' + version + '.js',
         'web/dest/scripts/compleRation_inst.all.min.' + version + '.css',
-        'web/dest/scripts/common.all.min.'+version+'.js',
         'web/dest/css/common.all.min.' + version + '.css'
     ]
 }

+ 2 - 1
modules/all_models/bills.js

@@ -63,7 +63,8 @@ let billsSchema = new Schema({
     is_adjust_price: {type: Number,default: 0},
     installationKey:String,//用来记录安装增加费的关联字段
     deleteInfo: deleteSchema,
-    isEstimate:{type: Number,default:0},       // 1 true 0 false 是否暂估
+    isEstimate: { type: Number, default: 0 },       // 1 true 0 false 是否暂估
+    lockUnitPrice:{type:Schema.Types.Mixed,default:false},       //  true  false 锁定综合单价,true 为锁定
     mainBills:{type:Schema.Types.Mixed,default:false},//true 是,false否,null 不确定,三个状态
     //是否记取面积增加费
     areaIncreaseFee:{type:Schema.Types.Mixed,default:false},//true 是,false否,null 不确定,三个状态

+ 4 - 0
modules/all_models/user.js

@@ -34,6 +34,10 @@ let upgrade = mongoose.Schema({
         type:String,
         default: '',
     },
+    lock: { // 锁信息 1:借出;2:销售;
+        type: Number,
+        default: 0
+    }
 }, { _id: false })
 
 const userdList = mongoose.Schema({

+ 95 - 1
modules/main/facade/info_price_facade.js

@@ -15,6 +15,14 @@ let unitPriceModel = mongoose.model("unit_price");
 let _ = require("lodash");
 let gljUtil = require('../../../public/web/gljUtil');
 const scMathUtil = require('../../../public/scMathUtil').getUtil();
+// 载入模块
+var Segment = require('segment');
+// 创建实例
+var segment = new Segment();
+// 使用默认的识别模块及字典,载入字典文件需要1秒,仅初始化时执行一次即可
+segment.useDefault();
+
+
 async function getOptions(data,compilation){//data 是预留对象,暂时不用
   let compilationID = compilation._id;
   let areaMap={};
@@ -42,7 +50,27 @@ async function getOptions(data,compilation){//data 是预留对象,暂时不
 async function getDataByCondition(data,compilation){
   let result = {};
   data.condition["compilationID"] = compilation._id;
-  if(data.keyWord) data.condition.name = {"$regex":new RegExp(data.keyWord, "i")};
+  //特殊处理重庆的,地区选择非“通用”时,搜索范围应是当前选择的地区,加上“通用”中的信息价。
+  if (data.condition.commonInfoPriceID) { 
+    let idArray = [data.condition.areaID,data.condition.commonInfoPriceID];
+    data.condition.areaID = {$in: idArray}
+    delete data.condition.commonInfoPriceID;
+  }
+
+  //根据地区+期数+材料编号的前4位与信息价材料的分类编号匹配,如果有数据,则显示数据出来。
+  //先按编号匹配
+  if (data.code) { 
+    result = await getDataByCode(data.code, data);
+    if (result.totalSize > 0) return result;
+  }
+ 
+  //编号匹配不上的情况:
+  //有关键字的情况
+  if (data.keyWord) { 
+    return await getDataByKeyWord(data.keyWord,data);
+  } 
+
+  //查询所有的情况
   if(data.lastID){ //有最后一行说明是查询下一页
     data.condition["_id"] = {$gt:mongoose.Types.ObjectId(data.lastID)};
   }else{
@@ -52,6 +80,72 @@ async function getDataByCondition(data,compilation){
   return result;
 }
 
+
+async function getDataByCode(code, data) { 
+  let condition = { ...data.condition };
+  condition.code = code;
+  let totalSize = await infoItemsModel.find(condition).count();
+  if (data.lastID) { //有最后一行说明是查询下一页
+    condition["_id"] = {$gt:mongoose.Types.ObjectId(data.lastID)};
+  }
+  let items = [];
+  if (totalSize > 0) { 
+    items = await infoItemsModel.find(condition).lean().sort({"_id":1}).limit(50);
+  }
+   
+  return {totalSize,items}
+}
+
+
+async function getDataByKeyWord(keyword, data) {
+  let items = [];
+  let nameArray = [];
+  //混凝土 和 砼 认成一个
+ // keyword = keyword.replace(/混凝土/g, "砼");
+  if (keyword.length < 3) {
+    nameArray.push(keyword)
+  } else { 
+    nameArray = segment.doSegment(keyword, {
+      simple: true, //不返回词性
+      stripPunctuation: true //去除标点符号
+    });
+  }
+  let temArr = [];
+  for (let a of nameArray) { 
+    if (a == "混凝土") a = '砼';
+    if (a == '砼' || a.length > 1) temArr.push(a);
+  }
+  if (keyword.length == 1 && temArr.length == 0) temArr.push(keyword);
+  nameArray = temArr;
+  console.log(nameArray);
+
+  let allInfoPrice = await infoItemsModel.find(data.condition).lean().sort({"_id":1});
+
+  let maxNum = 0;//最大匹配数
+  let matchMap = {};//匹配储存
+
+  for (let info of allInfoPrice) { 
+    //specs
+    let mstring = info.name + info.spec;
+    mstring = mstring.replace(/混凝土/g, "砼");
+    let matchCount = 0;
+    for (let na of nameArray) { 
+      if (mstring.indexOf(na) != -1) { 
+        matchCount++;
+      }
+    }  
+    if (matchCount > 0) { 
+      matchMap[matchCount] ? matchMap[matchCount].push(info) : matchMap[matchCount] = [info];
+      if (matchCount > maxNum) maxNum = matchCount;
+    }
+  }
+  
+  if (maxNum > 0) items = matchMap[maxNum];
+  totalSize = items.length
+  return {totalSize,items}
+}
+
+
 async function mutiApplyInfoPrice(data,compilation){
   data.condition["compilationID"] = compilation._id;
   let infoPrices = await infoItemsModel.find(data.condition).lean();

+ 1 - 1
modules/main/middleware/index.js

@@ -55,7 +55,7 @@ function isAjax(req) {
 // 登录状态全局判断
 async function stateChecking(req, res, next) {
     const url = req.originalUrl;
-    if (url=="\/"|| /^\/login/.test(url) || /\.map|\.ico$/.test(url) || /^\/sms/.test(url) || /^\/cld/.test(url) || /^\/captcha/.test(url)) {
+    if (url=="\/"|| /^\/login/.test(url) || /\.map|\.ico$/.test(url) || /^\/sms/.test(url) || /^\/captcha/.test(url)) {
         // 如果是登录页面或短信接口或cld接口则忽略判断数据
         next();
     } else {

+ 1 - 1
modules/users/controllers/boot_controller.js

@@ -32,7 +32,7 @@ class BootController extends BaseController {
             // 判断当前用户的是使用免费版还是专业版
             compilationVersion = await userModel.getVersionFromUpgrade(sessionUser.ssoId, compilationId);
             request.session.compilationVersion = compilationVersion.version;
-            request.session.sessionUser.compilationDeadline = compilationVersion.deadline;
+            request.session.sessionUser.compilationLock = compilationVersion.lock;
             request.session.sessionCompilation = compilationData;
             if(sessionUser.latest_used !== compilationId) userModel.updateLatestUsed(sessionUser.id,compilationId);
         }

+ 4 - 0
modules/users/controllers/cld_controller.js

@@ -88,6 +88,8 @@ class CLDController {
                     });
                     if (oneCompilationIndex !== -1) {
                         compilationList[oneCompilationIndex].isUpgrade = userUpgradeList[i].isUpgrade;
+                        compilationList[oneCompilationIndex].deadline = userUpgradeList[i].deadline;
+                        compilationList[oneCompilationIndex].lock = userUpgradeList[i].lock;
                     }
                 }
             }
@@ -110,6 +112,7 @@ class CLDController {
         let deadline = request.body.deadline || '';
         let status = parseInt(request.body.status); // 1.升级、2.降级、3.续期
         let smssend = parseInt(request.body.smssend);
+        let lock = parseInt(request.body.lock);// 0.默认、1.借出(借用)、2.销售(购买)
         try {
 
             let userModel = new UserModel();
@@ -135,6 +138,7 @@ class CLDController {
                 isUpgrade: status !== 2,
                 remark: '',
                 deadline: deadline,
+                lock: lock,
             };
 
             if (upgradeIndex === -1) {

+ 2 - 2
modules/users/controllers/login_controller.js

@@ -108,7 +108,7 @@ class LoginController {
                     // 判断当前用户的是使用免费版还是专业版
                     let compilationVersion = await userModel.getVersionFromUpgrade(sessionUser.ssoId, preferenceSetting.select_version);
                     request.session.compilationVersion = compilationVersion.version;
-                    request.session.sessionUser.compilationDeadline = compilationVersion.deadline;
+                    request.session.sessionUser.compilationLock = compilationVersion.lock;
                     request.session.sessionCompilation = compilationData;
                     if(request.session.sessionUser.latest_used !== preferenceSetting.select_version) await userModel.updateLatestUsed(request.session.sessionUser.id,preferenceSetting.select_version);
                 }
@@ -297,7 +297,7 @@ class LoginController {
                 let compilationVersion = await userModel.getVersionFromUpgrade(sessionUser.ssoId, preferenceSetting.select_version);
                 console.log("当前用户的是使用免费版还是专业版 完成------------------");
                 request.session.compilationVersion = compilationVersion.version;
-                request.session.sessionUser.compilationDeadline = compilationVersion.deadline;
+                request.session.sessionUser.compilationLock = compilationVersion.lock;
                 request.session.sessionCompilation = compilationData;
                 if(request.session.sessionUser.latest_used !== preferenceSetting.select_version) await userModel.updateLatestUsed(request.session.sessionUser.id,preferenceSetting.select_version);
             }

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

@@ -30,7 +30,7 @@ class UserController extends BaseController {
         let sessionUser = request.session.sessionUser;
 
         let userModel = new UserModel();
-        let userData = await userModel.findDataByName(sessionUser.username);
+        let userData = await userModel.findDataBySsoId(sessionUser.ssoId);
         userData = Object.keys(userData).length <= 0 ? [] : userData;
 
         let renderData = {
@@ -95,8 +95,10 @@ class UserController extends BaseController {
         try {
             // 获取当前用户信息
             let sessionUser = request.session.sessionUser;
+            console.log(sessionUser);
             let userModel = new UserModel();
-            userData = await userModel.findDataByName(sessionUser.username);
+            userData = await userModel.findDataBySsoId(sessionUser.ssoId);
+            console.log(userData);
 
             let page = request.query.page === undefined ? 1 : request.query.page;
 
@@ -155,6 +157,7 @@ class UserController extends BaseController {
                     if (oneCompilationIndex !== -1) {
                         compilationList[oneCompilationIndex].isUpgrade = userUpgradeList[index].isUpgrade;
                         compilationList[oneCompilationIndex].deadline = userUpgradeList[index].deadline;
+                        compilationList[oneCompilationIndex].lock = userUpgradeList[index].lock;
                     }
                 }
             }
@@ -237,7 +240,7 @@ class UserController extends BaseController {
                 let userModel = new UserModel();
                 let compilationVersion = await userModel.getVersionFromUpgrade(sessionUserData.ssoId, compilationData._id);
                 request.session.compilationVersion = compilationVersion.version;
-                request.session.sessionUser.compilationDeadline = compilationVersion.deadline;
+                request.session.sessionUser.compilationLock = compilationVersion.lock;
                 request.session.sessionCompilation = compilationData;
             }
         } catch (error) {

+ 4 - 4
modules/users/models/user_model.js

@@ -350,7 +350,7 @@ class UserModel extends BaseModel {
      */
     async getVersionFromUpgrade(ssoId, compilationId){
         let version = '大司空云计价(免费公用版)';
-        let deadline = '';
+        let lock = 0;
         let userData = await this.findDataBySsoId(ssoId);
         if (userData.upgrade_list !== undefined) {
             let compilationInfo = userData.upgrade_list.find(function (item) {
@@ -358,12 +358,12 @@ class UserModel extends BaseModel {
             });
             if (compilationInfo !== undefined && compilationInfo.isUpgrade === true) {
                 version = '大司空云计价(专业版)';
-                if (compilationInfo.deadline !== undefined && compilationInfo.deadline !== '') {
-                    deadline = compilationInfo.deadline;
+                if (compilationInfo.lock !== undefined && compilationInfo.lock !== '') {
+                    lock = compilationInfo.lock;
                 }
             }
         }
-        return {version: version, deadline: deadline};
+        return {version: version, lock: lock};
     }
 
     /**

File diff suppressed because it is too large
+ 4380 - 2958
package-lock.json


+ 1 - 0
package.json

@@ -50,6 +50,7 @@
     "pdfkit": "^0.8.2",
     "qiniu": "^7.1.1",
     "request-promise": "^4.2.5",
+    "segment": "^0.1.3",
     "socket.io": "2.0.3",
     "ua-parser-js": "^0.7.14",
     "uuid": "^3.1.0",

+ 2 - 2
public/web/sheet/sheet_common.js

@@ -1422,7 +1422,7 @@ var sheetCommonObj = {
         ctx.restore();
     },
     drawLine : function (ctx, x1, y1, x2, y2, color) {
-        let l_color = color?color:"gray";
+        let l_color = color?color:"#ababab";
         ctx.save();
         ctx.translate(0.5, 0.5);
         ctx.beginPath();
@@ -1461,7 +1461,7 @@ var sheetCommonObj = {
         let t_step = step?step:6;
         offset += t_step;
         ctx.save();
-        ctx.strokeStyle = "gray";
+        ctx.strokeStyle = "#ababab";
         ctx.translate(0.5, 0.5);
         ctx.beginPath();
         ctx.moveTo(x + offset, y);

+ 5 - 4
public/web/tree_sheet/tree_sheet_helper.js

@@ -386,19 +386,20 @@ var TREE_SHEET_HELPER = {
             let x1 = centerX + indent / 2;
             let centerY = Math.floor((y + (y + h)) / 2);
             let y1;
+            const lineColor = '#ababab';
             // Draw Sibling Line
             if (showTreeLine) {
                 // Draw Horizontal Line
                 if (centerX < x + w) {
-                    drawLine(ctx, centerX, centerY, Math.min(x1, x + w), centerY, 'gray');
+                    drawLine(ctx, centerX, centerY, Math.min(x1, x + w), centerY, lineColor);
                 }
                 // Draw Vertical Line
                 if (centerX < x + w) {
                     y1 = node.isLast() ? centerY : y + h;
                     if (node.isFirst() && !node.parent) {
-                        drawLine(ctx, centerX, centerY, centerX, y1, 'gray');
+                        drawLine(ctx, centerX, centerY, centerX, y1, lineColor);
                     } else {
-                        drawLine(ctx, centerX, y, centerX, y1, 'gray');
+                        drawLine(ctx, centerX, y, centerX, y1, lineColor);
                     }
                 }
             }
@@ -412,7 +413,7 @@ var TREE_SHEET_HELPER = {
                 while (parent) {
                     if (!parent.isLast()) {
                         if (parentCenterX < x + w) {
-                            drawLine(ctx, parentCenterX, y, parentCenterX, y + h, 'gray');
+                            drawLine(ctx, parentCenterX, y, parentCenterX, y + h, lineColor);
                         }
                     }
                     parent = parent.parent;

+ 2 - 2
web/building_saas/complementary_ration_lib/html/gongliao.html

@@ -11,9 +11,9 @@
     <link rel="stylesheet" href="/web/building_saas/css/main.css">
     <link rel="stylesheet" href="/lib/font-awesome/font-awesome.min.css">
     <link rel="stylesheet" href="/lib/spreadjs/sheets/css/gc.spread.sheets.sc.css" type="text/css">
+    <!--endinject-->
     <!--zTree-->
   	<link rel="stylesheet" href="/lib/ztree/css/zTreeStyle.css" type="text/css">
-    <!--endinject-->
     <link rel="shortcut icon" href="/web/building_saas/css/favicon.ico">
     <link rel="icon" type="image/gif" href="/web/building_saas/css/animated_favicon1.gif">
     <style type="text/css">
@@ -226,13 +226,13 @@
         </div>
     </div>
     <!-- JS. -->
-    <script src="/public/web/PerfectLoad.js"></script>
     <script src = "/lib/spreadjs/sheets/gc.spread.sheets.all.11.1.2.min.js"></script>
     <script>GC.Spread.Sheets.LicenseKey =  '<%- LicenseKey %>';</script>
     <script type="text/javascript" src="/lib/ztree/jquery.ztree.core.js"></script>
     <script type="text/javascript" src="/lib/ztree/jquery.ztree.excheck.js"></script>
     <script type="text/javascript" src="/lib/ztree/jquery.ztree.exedit.js"></script>
     <!--inject:js-->
+    <script src="/public/web/PerfectLoad.js"></script>
     <script type="text/javascript" src="/web/building_saas/complementary_ration_lib/js/global.js"></script>
     <!-- zTree -->
     <script type="text/javascript" src="/public/web/common_ajax.js"></script>

+ 8 - 0
web/building_saas/css/custom.css

@@ -505,4 +505,12 @@ margin-right: 100px !important;
 
 .info-checkbox {
   margin-right: 20px;
+}
+
+.top-msg{
+  top:35px !important;
+}
+
+.fee_detail_height{
+  height:270px
 }

二進制
web/building_saas/css/favicon.ico


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

@@ -95,7 +95,7 @@
             <a class="nav-link " id="ration-nav" data-toggle="tab" href="#ph_div" role="tab"
               aria-selected="true">相关定额</a>
           </li>
-          <li class="nav-item">
+          <li class="nav-item" id="info-nav-li">
             <a class="nav-link" id="info-nav" data-toggle="tab" data-name="info" href="#info_price_div"
               role="tab">信息价</a>
           </li>
@@ -147,8 +147,11 @@
               </select>
               &nbsp;
               <input type="text" class="form-control form-control-sm" id="info_search_name">
-              <button type="button" class="btn btn-outline-primary btn-sm mr-auto" id="info_search_btn"><i
+              <button type="button" class="btn btn-outline-primary btn-sm" id="info_search_btn"><i
                   class="fa fa-search" aria-hidden="true"></i></button>
+              <label class="mr-auto" id = "info-warning"></label>    
+              <input type="hidden" class="form-control form-control-sm" id="info_glj_name">
+              <input type="hidden" class="form-control form-control-sm" id="info_glj_code">       
               <button type="button" class="btn btn-primary  btn-sm" id="muti_apply_info">批量套用</button>
             </div>
             <div class="main-data-bottom" id="info_price_sheet"> </div>

二進制
web/building_saas/img/vip.png


二進制
web/building_saas/img/vip2.png


+ 23 - 19
web/building_saas/main/html/main.html

@@ -104,20 +104,6 @@
                     data-target="#import">导入广联达算量Excel清单</a>
                 </div>
               </span>
-              <% if (region === '重庆市' || region === '广东省') { %>
-              <span id="exportSpan" class="btn btn-light btn-sm" data-toggle="tooltip" data-original-title="数据接口"
-                data-placement="bottom">
-                <a class="dropdown-toggle" href="#" data-toggle="dropdown"><i class="fa  fa-code-fork"></i></a>
-                <div class="dropdown-menu" id="exportMenu">
-                  <a class="dropdown-item" href="#export" data-toggle="modal"
-                    data-target="#export">导出<%= region %>电子招投标数据文件</a>
-                  <% if (region !== '广东省') { %>
-                  <a class="dropdown-item" href="#exportIndex" data-toggle="modal"
-                    data-target="#exportIndex">导出<%= region %>指标成果文件</a>
-                  <% } %>
-                </div>
-              </span>
-              <% } %>
               <!--<a href="javascript:void(0)" class="btn btn-light btn-sm" id="insertRation" data-toggle="tooltip" data-placement="bottom" data-original-title="插入定额"><i class="fa fa-sign-in" aria-hidden="true"></i></a>-->
               <a href="javascript:void(0)" class="btn btn-light btn-sm" id="delete" data-toggle="tooltip"
                 data-placement="bottom" data-original-title="删除"><i class="fa fa-remove" aria-hidden="true"></i></a>
@@ -150,6 +136,22 @@
                   </div>
                   <a href="javascript:void(0);" id="ZLFB_btn" class="dropdown-item" data-placement="bottom"
                     style="display: none;"><i class="fa fa-retweet" aria-hidden="true"></i> 整理分部</a>
+                  <% if (region === '重庆市' || region === '广东省') { %>
+                  <a id="interface-dropdown" href="javascript:void(0);" data-toggle="dropdown"
+                    class="dropdown-item dropdown-toggle"><i class="fa fa-list-ol"></i> 数据接口...</a>
+                    <div style="position: relative;">
+                      <div id="interface-dropdown-sub" class="dropdown-menu dropdown-menu-left"
+                      style="min-width: 6.5rem; position: absolute; transform: translate3d(158px, 3px, 0px); top: -40px; left: 0px; will-change: transform;"
+                      x-placement="right-start">
+                      <a class="dropdown-item btn-sm" href="#export" data-toggle="modal"
+                      data-target="#export">导出<%= region %>电子招投标数据文件</a>
+                      <% if (region !== '广东省') { %>
+                      <a class="dropdown-item btn-sm" href="#exportIndex" data-toggle="modal"
+                      data-target="#exportIndex">导出<%= region %>指标成果文件</a>
+                       <% } %>
+                    </div>
+                    </div>
+                  <% } %>
                   <% if (projectData.property.lockBills == true) { %>
                   <a href="javascript:void(0)" class="dropdown-item" name="lockBills"> <i class="fa fa-unlock-alt"
                       aria-hidden="true"></i> 解锁清单</a>
@@ -165,6 +167,9 @@
                       class="fa fa-database" aria-hidden="true"></i> 指标信息</a>
                 </div>
               </div>
+              <a href="javascript:void(0)" class="btn btn-light btn-sm" id="locate-sub">分项</a>
+              <a href="javascript:void(0)" class="btn btn-light btn-sm" id="locate-measure">措施</a>
+              <a href="javascript:void(0)" class="btn btn-light btn-sm" id="locate-other">其他</a>
               <!--   <span class="btn btn-light btn-sm">
                       <a href="" data-toggle="dropdown"><span data-placement="bottom"><i class="fa fa-list-ol"></i></span> 显示至...</a>
                       <div class="dropdown-menu dropdown-menu-left" style="min-width: 6.5rem">
@@ -1838,8 +1843,8 @@
             <span aria-hidden="true">&times;</span>
           </button>
         </div>
-        <div class="modal-body">
-          <div class="row" style="height:250px">
+        <div class="modal-body" style="padding-top: 0px;padding-bottom: 0px;">
+          <div class="row" style="height:210px">
             <!--sjs id设置在这个div-->
             <div class=" col-8" style="overflow: hidden" id="feeItemSheet">
             </div>
@@ -1865,10 +1870,9 @@
               </div>
             </div>
           </div>
-          <br>
-          <div class="row" style="height:400px">
+          <div class="row" style="height:270px; margin-top: 5px">
             <!--sjs id设置在这个div-->
-            <div class="col-12" style="overflow: hidden" id="feeDetailSheet"></div>
+            <div class="col-12 fee_detail_height" style="overflow: hidden" id="feeDetailSheet"></div>
           </div>
         </div>
         <div class="modal-footer">

+ 47 - 16
web/building_saas/main/js/controllers/block_controller.js

@@ -29,8 +29,22 @@ let BlockController = {
         if(blockData == null){
             return true;
         }
-        if(blockData.firstNodeType != blockType.RATION && blockData.isFBFX !=  Bills.isFBFX(selected)){//除了复制定额外,焦点行和复制的块不是来自同一个地方(分部分项工其它)
-            return true;
+        if(blockData.firstNodeType != blockType.RATION ){//复制的不是定额
+          //&& blockData.isFBFX !=  Bills.isFBFX(selected)  
+          if (this.blockIsFB(blockData.firstNodeType) && !Bills.isFBFX(selected)) return true; //第一层是分部,不允许复制到非分部分项
+          //分项\补项不允许粘贴到“施工组织措施项目”下
+          if (this.blockIsFXorBX(blockData.firstNodeType) && Bills.isOrgMeasure(selected)) return true;
+          
+          if (blockData.firstNodeType == blockType.BILL && Bills.isFBFX(selected) ) { //如果是清单 到分部分项          
+            for (let d of blockData.datas) { 
+               //如果清单有多层,不允许复制 
+              if (!this.blockIsLeaveBills(d)) return true;
+              ///如果有清单基数,不允许复制
+              if (this.ifCalcBase(d.calcBase)) return true;
+               //如果清单有费率引用,不允许复制
+              if (gljUtil.isNotEmpty(d.feeRateID)) return true;
+            }
+          }
         }
         if(this.blockIsFXorBX(blockData.firstNodeType) && this.isFB(selected)){//复制块的第一层是分项或补项,焦点行是分部,且分部有子项并且子项不是分项或补项,则无效。
             if(selected.children.length && !this.isFXorBX(selected.children[0])){
@@ -80,10 +94,13 @@ let BlockController = {
         return false;
     },
     haveCalcBase : function (node) {
-        if(node.data.calcBase ==null||node.data.calcBase ==undefined|| node.data.calcBase == ""){
-            return false;
-        }
-        return true;
+      return this.ifCalcBase(node.data.calcBase);
+    },
+    ifCalcBase: function (calcBase) {
+      if (calcBase == null || calcBase == undefined || calcBase == "") {
+        return false;
+      }
+      return true;
     },
     isDXFYorMainEq:function (node) {//焦点行是大项费用或定额下的主材设备
         if(node.sourceType == ModuleNames.bills && node.data.type == billType.DXFY){//焦点行是大项费用则无效;
@@ -227,8 +244,8 @@ let BlockController = {
                 //默认为当前行的后项,可选前项,子项灰显不可选。
                 setRadioProp('sub_node',{checked:false,disabled:true});
             }
-            //复制块的第一层是分项,焦点行是分部,且分部下无子项或者子项是分项
-            if(this.blockIsFXorBX(blockData.firstNodeType)&& this.isFB(selected)){
+            //复制块的第一层是分项,清单,焦点行是分部,且分部下无子项或者子项是分项
+            if((blockData.firstNodeType ==blockType.BILL||  this.blockIsFXorBX(blockData.firstNodeType))&& this.isFB(selected)){
                 if(selected.children.length == 0 || this.isFXorBX(selected.children[0])){
                     return 'sub';//不弹出选择窗口,直接粘贴为子项。
                 }
@@ -315,7 +332,7 @@ let BlockController = {
                 billUpdate = {type:blockData.datas[0].sourceType,query:{ID:pre.getID()},doc:{NextSiblingID:blockData.datas[0].ID}};
             }
         }
-        let dataMap = this.preparePasteData(blockData.datas,billsIDMap,firstParentID,lastNextID);
+        let dataMap = this.preparePasteData(blockData.datas,billsIDMap,firstParentID,lastNextID,selected);
         if(billUpdate){
             billUpdate.doc.NextSiblingID = billsIDMap[billUpdate.doc.NextSiblingID];
             updateData.push(billUpdate);
@@ -456,7 +473,7 @@ let BlockController = {
 
     },
 
-    preparePasteData : function (datas,billsIDMap,firstParentID,lastNextID) {
+    preparePasteData : function (datas,billsIDMap,firstParentID,lastNextID,selected) {
         let me = this;
         me.datas = _.cloneDeep(projectObj.project.Bills.datas);
         let bills = [],rations=[],ration_gljs = [],ration_coes = [],quantity_details = [],ration_installations = [],ration_templates=[];
@@ -469,7 +486,7 @@ let BlockController = {
                     lastBillID =  datas[i].ID
                 }
             }
-            eachData(datas[i]);
+            eachData(datas[i],selected);
         }
         for(let f of firstBillIDs){
             firstIDMap[billsIDMap[f]]  = f //反向映射
@@ -491,9 +508,9 @@ let BlockController = {
 
         return {bills:bills,rations:rations,ration_gljs:ration_gljs,ration_coes:ration_coes,quantity_details:quantity_details,ration_installations:ration_installations,ration_templates:ration_templates};
 
-        function eachData(data) {
+        function eachData(data,selected) {
             if(data.sourceType == 'bills'){
-                let tem_b = createBillsData(data);
+                let tem_b = createBillsData(data,selected);
                 bills.push(tem_b);
                 for(let d of data.quantity_details){
                     quantity_details.push(createQuantityDetails(d,tem_b,'bills'));
@@ -598,7 +615,8 @@ let BlockController = {
 
         }
 
-        function createBillsData(billsData) { //ID、重新生成code
+      function createBillsData(billsData, selected) { //ID、重新生成code
+            let Bills = projectObj.project.Bills;
             let temData = _.cloneDeep(billsData);
             //删除旧数据
             if(temData.children && temData.children.length>0){//如果是有子项,说明是计算得到的,要删除重新计算,没有子项,但是fees有值,说明是自已输入的,值要一起粘贴
@@ -611,8 +629,12 @@ let BlockController = {
             delete  temData.__v;
             delete  temData.sourceType;
             delete  temData.quantityCoe;
-            delete  temData.rationQuantityCoe;
-
+            delete temData.rationQuantityCoe;
+            //从分项、补项 到清单
+            if ((temData.type == billType.FX || temData.type == billType.BX) && !Bills.isFBFX(selected)) temData.type = billType.BILL;
+            //从清单到分部分项
+            if (temData.type == billType.BILL && Bills.isFBFX(selected)) temData.type = billType.FX;
+          
             temData.projectID = projectObj.project.ID();
             let newID = uuid.v1(); //新的清单ID
             billsIDMap[temData.ID] = newID;
@@ -709,9 +731,18 @@ let BlockController = {
     isFXorBX:function (selected) {//是分项或者补项
         return projectObj.project.Bills.isFXorBX(selected);
     },
+    blockIsFB: function (type) { 
+      return type == blockType.FB
+    },
     blockIsFXorBX: function (type) {
         return type == blockType.FX||type == blockType.BX;
     },
+    blockIsLeaveBills: function (bills) { 
+      if (bills.children && bills.children.length > 0) { 
+        return bills.children[0].sourceType == "ration" //如果子节点是定额,则说明是页子清单
+      }
+      return true;
+    },
     removeBlock:function () {
         removeLocalCache('project_block');
     }

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

@@ -622,7 +622,22 @@ var Bills = {
                 }
             }
             return techMeasureCheck(node);
-        };
+    };
+    bills.prototype.isOrgMeasure = function (node) {//判读是否属于施工组织措施项目部分
+      let OrgMeasureCheck = function (checkNode) {
+          if(isFlag(checkNode.data)&&checkNode.data.flagsIndex.fixed.flag==fixedFlag.CONSTRUCTION_ORGANIZATION){
+              return true;
+          }else {
+              if(checkNode.parent){
+                  return OrgMeasureCheck(checkNode.parent);
+              }else {
+                  return false;
+              }
+          }
+      }
+      return OrgMeasureCheck(node);
+    };
+
         // 相关固定类别清单部分,【不】允许清单自身计算得到合价: “数量 * 单价 = 合价”
         // 删除【不】允许通过自身数据计算的清单的定额时,该清单价格【会清空】
         // 这种清单的单价和合价都是只读的

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

@@ -1740,6 +1740,7 @@ class CalcProgram {
 
     // 只计算treeNode自身。changedArr: 外部传来的一个数组,专门存储发生变动的节点。
     innerCalc(treeNode, changedArr, tenderType){
+        if (treeNode.data.lockUnitPrice == true) return;
         if (treeNode.sourceType === ModuleNames.ration_glj) return;             // 仅用作树节点显示的工料机不能参与计算。
 
         let me = this;

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

@@ -319,7 +319,7 @@ const XML_EXPORT_BASE = (() => {
     function isDef(v) {
         return typeof v !== 'undefined' && v !== null;
     }
-    function hasValue(v) {
+    function /*  */hasValue(v) {
         // v是否有值,不为undefined、null、''
         return typeof v !== 'undefined' && v !== null && v !== '';
     }

+ 5 - 3
web/building_saas/main/js/models/project.js

@@ -425,7 +425,7 @@ var PROJECT = {
             })
 
         };
-        project.prototype.updateCasCadeBills = function(node,newval,fieldName){
+        project.prototype.updateCasCadeBills = function(node,newval,fieldName,needSetParent = true){
             let datas = [];
             let data =  {
                 type:node.sourceType,
@@ -434,7 +434,7 @@ var PROJECT = {
             setData(data.data,newval,fieldName);
             datas.push(data);
             setChildren(node,newval,datas);//同步设置所有子项
-            setParent(node,newval,datas);//设置父节点
+            if(needSetParent) setParent(node,newval,datas);//设置父节点
             $.bootstrapLoading.start();
             this.updateNodes(datas,function () {
                 let nodes = [];
@@ -448,7 +448,9 @@ var PROJECT = {
                         nodes.push(node)
                     }
                 }
-                projectObj.mainController.refreshTreeNode(nodes);
+              projectObj.mainController.refreshTreeNode(nodes);
+              //取消锁定,则自动重新计算。
+              if(fieldName == "lockUnitPrice" && newval == false) projectObj.project.calcProgram.calcAllNodesAndSave();
                 $.bootstrapLoading.end();
             });
 

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

@@ -315,7 +315,6 @@ const BillsSub = (function() {
     //建表
     //@param {Object}module @return {void}
     function buildSheet(cmodule) {
-        console.log(cmodule);
         if(!cmodule.workBook){
             cmodule.workBook = new GC.Spread.Sheets.Workbook(cmodule.dom[0], {sheetCount: 1});
             sheetCommonObj.spreadDefaultStyle(cmodule.workBook);

+ 5 - 5
web/building_saas/main/js/views/block_lib.js

@@ -222,11 +222,11 @@ var blockLibObj = {
             let x1 = centerX + indent / 2;
             let centerY = Math.floor((y + (y + h)) / 2);
             let y1;
-
+            const lineColor = '#ababab';
             // Draw Horizontal Line、Image、sibling Vertical Line
             if (centerX < x + w) {
                 // Draw Horizontal Line
-                drawLine(ctx, centerX, centerY, Math.min(x1, x + w), centerY, 'gray');
+                drawLine(ctx, centerX, centerY, Math.min(x1, x + w), centerY, lineColor);
 
                 // Draw Image
                 let imgId;
@@ -241,9 +241,9 @@ var blockLibObj = {
                 // Draw Vertical Line
                 y1 = node.isLast() ? centerY : y + h;
                 if (node.isFirst() && !node.parent/*.parent*/) {
-                    drawLine(ctx, centerX, centerY, centerX, y1, 'gray');
+                    drawLine(ctx, centerX, centerY, centerX, y1, lineColor);
                 } else {
-                    drawLine(ctx, centerX, y, centerX, y1, 'gray');
+                    drawLine(ctx, centerX, y, centerX, y1, lineColor);
                 }
             }
 
@@ -257,7 +257,7 @@ var blockLibObj = {
             while (curNode) {
                 if (!curNode.isLast()) {
                     if (parentCenterX < x + w) {
-                        drawLine(ctx, parentCenterX, y, parentCenterX, y + h, 'gray');
+                        drawLine(ctx, parentCenterX, y, parentCenterX, y + h, lineColor);
                     }
                 }
                 curNode = curNode.parent;

+ 22 - 16
web/building_saas/main/js/views/glj_col.js

@@ -2,7 +2,8 @@
  * Created by zhang on 2018/7/3.
  */
 let gljCol = {
-    showTaxRate:false,
+    showTaxRate: false,
+    hideInfoPrice:true,
     ration_glj_setting: {
         header: [
             {headerName: "编码", headerWidth: 110, dataCode: "code", dataType: "String", formatter: "@"},
@@ -63,7 +64,7 @@ let gljCol = {
             {headerName: "质量等级", headerWidth: 80, dataCode: "qualityGrace", hAlign: "left", dataType: "String",spanRows: [2]},
             {headerName: "品牌", headerWidth: 80, dataCode: "brand", hAlign: "left", dataType: "String",spanRows: [2]},
             {headerName: "备注", headerWidth: 100, dataCode: "remark", hAlign: "left", dataType: "String",spanRows: [2]},
-            {headerName: "不调价", headerWidth: 55, dataCode: "is_adjust_price", dataType: "String",cellType: "checkBox",spanRows: [2], visible: false},
+            {headerName: "不调价", headerWidth: 55, dataCode: "is_adjust_price", dataType: "String",cellType: "checkBox",spanRows: [2], visible: true},
             {headerName: ["调价后","市场价"], headerWidth: 75, dataCode: "tenderPrice", hAlign: "right", dataType: "Number",validator:"number",spanCols: [2,1], visible: false},
             {headerName: ["","总消耗量"], headerWidth: 90, dataCode: "tenderQuantity", hAlign: "right", dataType: "Number",decimalField:'glj.quantity',spanCols: [0,1], visible: false}
         ],
@@ -249,21 +250,26 @@ let gljCol = {
             setting.view.lockColumns = newArray;
         }
     },
-    initGljCol:function (showAdjustPrice, showTenderFields) {
-        let me = gljCol;
-        if(showAdjustPrice !== true){
-            me.removeCol('adjustPrice',me.ration_glj_setting);
-            me.removeCol('adjustPrice',me.project_glj_setting);
-            me.removeCol('adjustPrice',me.mixRatio_Setting);
-        };
-        if(me.showTaxRate == false)  me.removeCol('taxRate',me.project_glj_setting);
-        me.showTenderFields(showTenderFields, false);
+    initGljCol: function (showAdjustPrice, showTenderFields) {
+      let me = gljCol;
+      if (showAdjustPrice !== true) {
+        me.removeCol('adjustPrice', me.ration_glj_setting);
+        me.removeCol('adjustPrice', me.project_glj_setting);
+        me.removeCol('adjustPrice', me.mixRatio_Setting);
+      };
+      if (me.showTaxRate == false) me.removeCol('taxRate', me.project_glj_setting);
+      if (me.hideInfoPrice == true) { 
+        $("#info-nav-li").hide();
+        me.removeCol('priceFrom', me.project_glj_setting);
+      } 
+      
+      me.showTenderFields(showTenderFields, false);
 
-        gljOprObj.setting = me.ration_glj_setting;
-        projectGljObject.projectGljSetting = me.project_glj_setting;
-        projectGljObject.mixRatioSetting = me.mixRatio_Setting;
-        me.setScopeFormater();
-        gljOprObj.scopeSetting = me.scopeSetting;
+      gljOprObj.setting = me.ration_glj_setting;
+      projectGljObject.projectGljSetting = me.project_glj_setting;
+      projectGljObject.mixRatioSetting = me.mixRatio_Setting;
+      me.setScopeFormater();
+      gljOprObj.scopeSetting = me.scopeSetting;
     },
     showTenderFields: function (showFields = false, needRefresh = false){
         let me = gljCol;

+ 5 - 1
web/building_saas/main/js/views/main_tree_col.js

@@ -417,7 +417,11 @@ let MainTreeCol = {
         },
         mainBills:function (node) {
             if(MainTreeCol.mainBillsEnable(node)) return sheetCommonObj.getCheckBox(true);
-        },
+      },
+      lockUnitPrice: function (node) {
+          //仅未使用基数计算的清单有效
+          if(!(node.data.calcBase&&node.data.calcBase!="")) return sheetCommonObj.getCheckBox();
+      },
         mainNodeCheckBox:function (node,setting,field) {//分部分项、措施项目下的清单、定额
             let Bills = projectObj.project.Bills;
             if((Bills.isFBFX(node)||Bills.isMeasure(node)) && node.sourceType != ModuleNames.ration_glj){

+ 37 - 10
web/building_saas/main/js/views/project_glj_view.js

@@ -4,6 +4,7 @@
 let projectGljObject = {
   showTag: 'ration', //mixRatio/machine
   showMixRatioMark: '',
+  commonInfoPriceID:'',
   displayType: filterType.ALL,
   mixRatioType: [gljType.CONCRETE, gljType.MORTAR, gljType.MIX_RATIO, gljType.MAIN_MATERIAL],
   machineType: [gljType.GENERAL_MACHINE],
@@ -221,7 +222,7 @@ let projectGljObject = {
     sheetCommonObj.spreadDefaultStyle(this.infoPriceSpread);
     this.infoPriceSheet = this.infoPriceSpread.getSheet(0);
     this.initSheet(this.infoPriceSheet, this.infoPriceSetting);
-    this.infoPriceSheet.bind(GC.Spread.Sheets.Events.TopRowChanged, _.debounce(this.onInfoTopRowChanged, 100));
+    this.infoPriceSheet.bind(GC.Spread.Sheets.Events.TopRowChanged, _.debounce(this.onInfoTopRowChanged, 100)); 
     this.infoPriceSheet.bind(GC.Spread.Sheets.Events.CellDoubleClick, this.onInfoPriceDoubleClick);
     this.infoPriceSheet.name('infoPriceSheet');
     this.infoPriceSheet.setRowCount(0);
@@ -534,6 +535,15 @@ let projectGljObject = {
     sheetCommonObj.showData(me.infoPriceSheet, me.infoPriceSetting, datas);
     me.infoPriceSheet.setRowCount(datas.length);
   },
+  autoShowInfoPriceData: function () { 
+    if (!$('#info-nav').hasClass('active')) return;
+    let projectGLJData = this.getProjectGLJSelected();
+    $('#info_search_name').val(projectGLJData.name);
+    let code = projectGLJData.code.substr(0, 4);
+    $('#info_glj_name').val(projectGLJData.name);
+    $('#info_glj_code').val(code);
+    this.searchInfoPrice(null);
+  },
   getMixRatioSheetData: function (glj) {
     let data = {
       id: glj.id,
@@ -647,6 +657,7 @@ let projectGljObject = {
     sel.colCount = 1;
     me.showMixRatioData();
     me.showRelatedRationDatas();
+    me.autoShowInfoPriceData();
   },
   rightClickCallback: function (row) {
     let me = projectGljObject;
@@ -1625,6 +1636,7 @@ let projectGljObject = {
     for (let o of opts) {
       if (isArea == true) {
         str += `<option value="${o.ID}">${o.name}</option>`
+        if (o.name == "通用") this.commonInfoPriceID = o.ID;
       } else {
         str += `<option value="${o}">${o}</option>`
       }
@@ -1642,16 +1654,17 @@ let projectGljObject = {
       }
       console.log(bottomRow);
       me.infoPriceLastLoadingRow = me.infoPriceData.length;
-      me.searchInfoPrice(me.infoPriceData[me.infoPriceData.length - 1]._id)
+      //只有在空的搜索条件下才执行分页查询,其它情况无法分页
+      if ($('#info_search_name').val() == "") me.searchInfoPrice(me.infoPriceData[me.infoPriceData.length - 1]._id)
     }
-
-
   },
   searchInfoPrice: async function (objectID) {
     let year = $('#info_year').val();
     let month = $('#info_month').val();
     let areaID = $('#info_area').val();
     let keyWord = $('#info_search_name').val();
+    let name =  $('#info_glj_name').val();
+    let code =  $('#info_glj_code').val();
     let me = projectGljObject;
     try {
       if (year != "" && month != "" && areaID != "") {
@@ -1659,11 +1672,14 @@ let projectGljObject = {
           period: year + "-" + month,
           areaID: areaID
         }
+        if (projectGljObject.addCommonInfoPriceID) projectGljObject.addCommonInfoPriceID(condition);
         let data = {
           condition: condition
         };
         if (keyWord != "") data.keyWord = keyWord;
+        if (name !="") data.keyWord = name;
         if (objectID) data.lastID = objectID;
+        if (code !="" ) data.code = code;
         let result = await ajaxPost("/infoPrice/getDataByCondition", data);
         if (objectID) { //分页查询
           sheetCommonObj.appendData(me.infoPriceSheet, me.infoPriceData.length, 0, me.infoPriceSetting, result.items);
@@ -1672,6 +1688,11 @@ let projectGljObject = {
           me.infoPriceTotalSize = result.totalSize;
           me.infoPriceLastLoadingRow = 0;
           me.showInforPriceData(result.items);
+          if (result.totalSize == 0) {
+            $("#info-warning").text("当前材料没有信息价! ");
+          } else { 
+            $("#info-warning").text("");
+          }
         }
       } else { //当有任意一个为空时,都清空表格
         me.infoPriceTotalSize = 0;
@@ -1727,6 +1748,10 @@ let projectGljObject = {
   getInfoMarketPrice: function (info) {
     let taxType = projectObj.project.property.taxType; //1: 一般计税 2: 简易计税
     return gljUtil.getInfoMarketPrice(info, taxType);
+  },
+  refreshInfoPrice: function () { 
+    $('#info_price_sheet').height($("#mix_ratio_sheet").height() - $("#infoToolDiv").height()-10);
+    projectGljObject.initInfoPriceSpread();
   }
 };
 
@@ -1787,8 +1812,6 @@ function loadProjectGljSize() {
         //信息价相关
         $('#info_price_sheet').height($("#mix_ratio_sheet").height() - $("#infoToolDiv").height());
         if ($('#info_price_sheet').is(':visible')) me.initInfoPriceSpread();
-
-
       });
     }
 
@@ -1845,6 +1868,7 @@ $(function () {
   SlideResize.verticalSlide(pojGljResizeEles.eleObj, pojGljResizeEles.limit, function () {
     projectGljObject.projectGljSpread.refresh();
     projectGljObject.mixRatioSpread ? projectGljObject.mixRatioSpread.refresh() : '';
+    projectGljObject.refreshInfoPrice();
   });
 
   let tr = getConficMaterialResizeEles();
@@ -2109,10 +2133,8 @@ $(function () {
     projectGljObject.showRelatedRationDatas();
   });
   $("#info-nav").on('shown.bs.tab', function () {
-    $('#info_price_sheet').height($("#mix_ratio_sheet").height() - $("#infoToolDiv").height());
-    projectGljObject.initInfoPriceSpread();
-    /*  
-     projectGljObject.showRelatedRationDatas(); */
+    projectGljObject.refreshInfoPrice();
+    projectGljObject.autoShowInfoPriceData(); 
   });
   $('#info_year').change(function () {
     let periodMap = projectGljObject.infoPriceOptions.periodMap;
@@ -2135,12 +2157,17 @@ $(function () {
     projectGljObject.searchInfoPrice();
   });
   $('#info_search_name').on('keypress', function (e) {
+    $("#info-warning").text("");
     if (e.keyCode === 13) {
+      $('#info_glj_name').val("");
+      $('#info_glj_code').val("");
       projectGljObject.searchInfoPrice();
     }
   });
 
   $('#info_search_btn').on('click', function (e) {
+    $('#info_glj_name').val("");
+    $('#info_glj_code').val("");
     projectGljObject.searchInfoPrice();
   });
 

+ 81 - 6
web/building_saas/main/js/views/project_view.js

@@ -25,6 +25,7 @@ var projectObj = {
         let project = projectObj.project;
         let mainSheet = projectObj.mainController.sheet;
         let init = true;
+        locateToCache(node);
         //设置选中行底色和恢复前选中行底色
         let refreshNodes = [node];
         if(!project.mainTree.preSelected){
@@ -2004,7 +2005,7 @@ var projectObj = {
             projectObj.onIsEstimateClick(node,info);
         }else if(fieldName == "evaluationProject"){
             projectObj.onEvaluationProjectClic(node,info);
-        }else if(fieldName == "mainBills"||fieldName == "outPutMaxPrice"||fieldName=="areaIncreaseFee"){
+        }else if(fieldName == "mainBills"||fieldName == "outPutMaxPrice"||fieldName=="areaIncreaseFee"||fieldName == "lockUnitPrice"){
             projectObj.onCasCadeButtonClick(node,info,fieldName);
         }
     },
@@ -2056,8 +2057,8 @@ var projectObj = {
         }
         if(fieldName == "areaIncreaseFee"){
             areaIncreaseFeeObj.casCadeUpdate(node,newval,fieldName);
-        }else {
-            projectObj.project.updateCasCadeBills(node,newval,fieldName);
+        } else {
+            projectObj.project.updateCasCadeBills(node,newval,fieldName,fieldName != "lockUnitPrice");
         }
     },
     onSubcontractClick:function (node) {//点击分包费checkbox
@@ -2468,6 +2469,9 @@ $('body').click(function () {
 });
 let enterDisplayA = false;
 //鼠标移到显示至,自动弹出子菜单
+$('#displayA').click(function () {
+    return false;
+});
 $('#displayA').mouseenter(function (e) {
     enterDisplayA = true;
     $('#subDisplay').addClass('show');
@@ -2475,12 +2479,29 @@ $('#displayA').mouseenter(function (e) {
 $('#displayA').mouseleave(function () {
     enterDisplayA = false;
 });
+
+let enterInterfaceDropdown = false;
+$('#interface-dropdown').mouseenter(function () {
+    enterInterfaceDropdown = true;
+    $('#interface-dropdown-sub').addClass('show');
+});
+$('#interface-dropdown').mouseleave(function () {
+    enterInterfaceDropdown = false;
+});
+$('#interface-dropdown').click(function() {
+    return false;
+});
+
 $('#moreMenu > a').mouseenter(function () {
-   if (!enterDisplayA) {
-       $('#subDisplay').removeClass('show');
-   }
+    if (!enterDisplayA) {
+        $('#subDisplay').removeClass('show');
+    }
+    if (!enterInterfaceDropdown) {
+        $('#interface-dropdown-sub').removeClass('show');
+    }
 });
 
+
 $('#displayDXFY').click(function () {
    displayLevel(projectObj.project.mainTree.items, 0, 'DXFY')
 });
@@ -3586,5 +3607,59 @@ $('#menu_index_info').click(function () {
     $('#tab_index').click();
 });
 
+// 快速定位
+const FastLocateType = {
+    SUB_ENGINERRING: 'subEnginerring',
+    MEASURE: 'measure',
+    OTHER: 'other',
+};
+const locateCache = {
+    [FastLocateType.SUB_ENGINERRING]: null,
+    [FastLocateType.MEASURE]: null,
+    [FastLocateType.OTHER]: null,
+};
+
+// 变更焦点行时,将焦点节点存至对应部分的locateCache中,用于快速定位功能
+function locateToCache(node) {
+    if (!node) {
+        return;
+    }
+    if (node.isBelongToFlags([fixedFlag.SUB_ENGINERRING])) {
+        locateCache[FastLocateType.SUB_ENGINERRING] = node;
+    } else if (node.isBelongToFlags([fixedFlag.MEASURE])) {
+        locateCache[FastLocateType.MEASURE] = node;
+    } else if (node.isBelongToFlags([fixedFlag.OTHER])) {
+        locateCache[FastLocateType.OTHER] = node;
+    }
+}
+
+// “分项”、“措施”、“其他”,用于快速定位至对应部分上次的焦点行
+function fastLocate(type) {
+    let locatedNode;
+    if (type === FastLocateType.SUB_ENGINERRING) {
+        locatedNode = locateCache[type] || projectObj.project.mainTree.roots.find(node => node.getFlag() === fixedFlag.SUB_ENGINERRING);
+    } else if (type === FastLocateType.MEASURE) {
+        locatedNode = locateCache[type] || projectObj.project.mainTree.roots.find(node => node.getFlag() === fixedFlag.MEASURE);
+    } else {
+        locatedNode = locateCache[type] || projectObj.project.mainTree.roots.find(node => node.getFlag() === fixedFlag.OTHER);
+    }
+    if (locatedNode && locatedNode !== projectObj.project.mainTree.selected) {
+        const locateRow = locatedNode.serialNo();
+        const sheet = projectObj.mainController.sheet;
+        projectObj.loadFocusLocation(locateRow, sheet.getActiveColumnIndex());
+    }
+}
+
+$('#locate-sub').click(() => {
+    fastLocate(FastLocateType.SUB_ENGINERRING);
+});
+$('#locate-measure').click(() => {
+    fastLocate(FastLocateType.MEASURE);
+});
+$('#locate-other').click(() => {
+    fastLocate(FastLocateType.OTHER);
+});
+
+
 //导出接口
 ExportView.exportListener();

+ 5 - 6
web/building_saas/main/js/views/tender_price_view.js

@@ -10,11 +10,10 @@ let tender_obj={
     tenderSetting:{
         header:[
             {headerName: "项目编码", headerWidth: 170, dataCode: "code", dataType: "String",spanRows: [2],getText:'getText.code'},
-            {headerName: "类别", headerWidth: 50, dataCode: "subType", hAlign: "center", dataType: "String",spanRows: [2],getText:'getText.subType'},
+            // {headerName: "类别", headerWidth: 50, dataCode: "subType", hAlign: "center", dataType: "String",spanRows: [2],getText:'getText.subType'},
             {headerName: "项目名称", headerWidth: 200, dataCode: "name",showHint:true, hAlign: "left", dataType: "String",spanRows: [2]},
             {headerName: "计量\n单位", headerWidth: 60, dataCode: "unit", hAlign: "center", dataType: "String",spanRows: [2]},
             {headerName: "工程量", headerWidth: 70, dataCode: "quantity", hAlign: "right", dataType: "Number",validator:"number",spanRows: [2],getText:'getText.quantity'},
-            // {headerName: "不调价", headerWidth: 55, dataCode: "is_adjust_price", hAlign: "center", cellType : "checkBox",dataType: "Number",spanRows: [2]},
             {headerName: ["初始报价","综合单价"], headerWidth: 100, dataCode: "feesIndex.common.unitFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [2,1]},
             {headerName: ["","综合合价"], headerWidth: 100, dataCode: "feesIndex.common.totalFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
             {headerName: ["目标造价","综合单价"], headerWidth: 100, dataCode: "targetUnitFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [2,1]},
@@ -29,8 +28,8 @@ let tender_obj={
             {headerName: "子目工程量\n调整系数", headerWidth: 80, dataCode: "rationQuantityCoe", hAlign: "right", dataType: "Number",spanRows: [2],validator:"number"}
         ],
         view: {
-            // lockColumns: [0,1,2,3,4,6,7,10,11]
-            lockColumns: [0,1,2,3,4,5,6,9,10]
+            // lockColumns: [0,1,2,3,4,5,6,9,10]
+            lockColumns: [0,1,2,3,4,5,8,9]
         }
     },
     tenderTreeSetting:{
@@ -227,12 +226,12 @@ let tender_obj={
     },
     onEnterCell : function (sender,args) {
         let me = tender_obj, row = args.row, col = args.col, lock = false;
-        if ([7, 8].includes(col)){                                  // 目标单价、目标合价
+        if ([6, 7].includes(col)){                                  // 目标单价、目标合价
             let treeNode = me.tenderTree.items[row];
             if (calcTools.isCalcBaseBill(treeNode))                   // 公式结点只读
                 lock = true;
 
-            if ((col = 7) && calcTools.isParentBill(treeNode))
+            if ((col = 6) && calcTools.isParentBill(treeNode))
                 lock = true;
 
             if (lock)

+ 2 - 2
web/building_saas/main/js/views/zmhs_view.js

@@ -10,8 +10,8 @@ let zmhs_obj = {
     coeSetting: {
         header: [
             {headerName: "调整", headerWidth: 35, dataCode: "isAdjust", dataType: "String", cellType: "checkBox"},
-            {headerName: "条件", headerWidth: 180, dataCode: "name", dataType: "String", cellType: "button",getText:'forName'},
-            {headerName: "内容", headerWidth: 70, dataCode: "content", dataType: "String", hAlign: "left",getText:'forContent',cellType:'tipsCell'}
+            {headerName: "条件", headerWidth: 140, dataCode: "name", dataType: "String", cellType: "button",getText:'forName'},
+            {headerName: "内容", headerWidth: 110, dataCode: "content", dataType: "String", hAlign: "left",getText:'forContent',cellType:'tipsCell'}
         ],
         view: {
             lockColumns:[0,1,2],

+ 5 - 4
web/building_saas/pm/js/pm_gc.js

@@ -252,10 +252,11 @@ const gcTreeObj = {
             let centerY = Math.floor((y + (y + h)) / 2);
             let y1;
             // Draw Sibling Line
+            const lineColor = '#ababab';
             if (showTreeLine) {
                 // Draw Horizontal Line
                 if (centerX < x + w) {
-                    drawLine(ctx, centerX, centerY, Math.min(x1, x + w), centerY, 'gray');
+                    drawLine(ctx, centerX, centerY, Math.min(x1, x + w), centerY, lineColor);
                     let img;
                     if(node.data.projType === projectType.folder){
                         img = document.getElementById('folder_open_pic');
@@ -279,9 +280,9 @@ const gcTreeObj = {
                 if (centerX < x + w) {
                     y1 = node.isLast() ? centerY : y + h;
                     if (node.isFirst() && !node.parent.parent) {
-                        drawLine(ctx, centerX, centerY, centerX, y1, 'gray');
+                        drawLine(ctx, centerX, centerY, centerX, y1, lineColor);
                     } else {
-                        drawLine(ctx, centerX, y, centerX, y1, 'gray');
+                        drawLine(ctx, centerX, y, centerX, y1, lineColor);
                     }
                 }
             }
@@ -295,7 +296,7 @@ const gcTreeObj = {
                 while (parent.parent) {
                     if (!parent.isLast()) {
                         if (parentCenterX < x + w) {
-                            drawLine(ctx, parentCenterX, y, parentCenterX, y + h, 'gray');
+                            drawLine(ctx, parentCenterX, y, parentCenterX, y + h, lineColor);
                         }
                     }
                     parent = parent.parent;

+ 5 - 4
web/building_saas/pm/js/pm_newMain.js

@@ -1024,10 +1024,11 @@ const projTreeObj = {
             let centerY = Math.floor((y + (y + h)) / 2);
             let y1;
             // Draw Sibling Line
+            const lineColor = '#ababab';
             if (showTreeLine) {
                 // Draw Horizontal Line
                 if (centerX < x + w) {
-                    drawLine(ctx, centerX, centerY, Math.min(x1, x + w), centerY, 'gray');
+                    drawLine(ctx, centerX, centerY, Math.min(x1, x + w), centerY, lineColor);
                     let img;
                     if(node.data.projType === projectType.folder){
                         img = document.getElementById('folder_open_pic');
@@ -1052,9 +1053,9 @@ const projTreeObj = {
                 if (centerX < x + w) {
                     y1 = node.isLast() ? centerY : y + h;
                     if (node.isFirst() && !node.parent.parent) {
-                        drawLine(ctx, centerX, centerY, centerX, y1, 'gray');
+                        drawLine(ctx, centerX, centerY, centerX, y1, lineColor);
                     } else {
-                        drawLine(ctx, centerX, y, centerX, y1, 'gray');
+                        drawLine(ctx, centerX, y, centerX, y1, lineColor);
                     }
                 }
             }
@@ -1068,7 +1069,7 @@ const projTreeObj = {
                 while (parent.parent) {
                     if (!parent.isLast()) {
                         if (parentCenterX < x + w) {
-                            drawLine(ctx, parentCenterX, y, parentCenterX, y + h, 'gray');
+                            drawLine(ctx, parentCenterX, y, parentCenterX, y + h, lineColor);
                         }
                     }
                     parent = parent.parent;

+ 5 - 4
web/building_saas/pm/js/pm_share.js

@@ -280,11 +280,12 @@ const pmShare = (function () {
             let x1 = centerX + indent / 2;
             let centerY = Math.floor((y + (y + h)) / 2);
             let y1;
+            const lineColor = '#ababab';
             // Draw Sibling Line
             if (showTreeLine) {
                 // Draw Horizontal Line
                 if (centerX < x + w) {
-                    drawLine(ctx, centerX, centerY, Math.min(x1, x + w), centerY, 'gray');
+                    drawLine(ctx, centerX, centerY, Math.min(x1, x + w), centerY, lineColor);
                     let img;
                     if(node.data.projType === projectType.folder){
                         img = document.getElementById('folder_open_pic');
@@ -308,9 +309,9 @@ const pmShare = (function () {
                 if (centerX < x + w) {
                     y1 = node.isLast() ? centerY : y + h;
                     if (node.isFirst() && !node.parent.parent) {
-                        drawLine(ctx, centerX, centerY, centerX, y1, 'gray');
+                        drawLine(ctx, centerX, centerY, centerX, y1, lineColor);
                     } else {
-                        drawLine(ctx, centerX, y, centerX, y1, 'gray');
+                        drawLine(ctx, centerX, y, centerX, y1, lineColor);
                     }
                 }
             }
@@ -324,7 +325,7 @@ const pmShare = (function () {
                 while (parent.parent) {
                     if (!parent.isLast()) {
                         if (parentCenterX < x + w) {
-                            drawLine(ctx, parentCenterX, y, parentCenterX, y + h, 'gray');
+                            drawLine(ctx, parentCenterX, y, parentCenterX, y + h, lineColor);
                         }
                     }
                     parent = parent.parent;

+ 1 - 1
web/building_saas/unit_price_file/index.js

@@ -253,7 +253,7 @@ let unitPriceObj = {
   },
   showSubDatas:function(){
     let parentData = this.getSelectedUnitPrice();
-    this.mixRatioList = mixRatioMap[gljUtil.getIndex(parentData)];
+    this.mixRatioList = parentData?mixRatioMap[gljUtil.getIndex(parentData)]:[];
     this.mixRatioList = this.mixRatioList?this.mixRatioList:[];
     this.setMixRatioData(this.mixRatioList);
     let sel = this.subSheet.getSelections()[0];

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

@@ -54,10 +54,10 @@
             <% if (!versionName.includes('免费')) {%>
               <li class="nav-item">
                 <a href="/user/buy" target="_blank">
-                    <% if (sessionUser.compilationDeadline !== '') { %>
-                    <img src="/web/building_saas/img/vip2.png" data-toggle="tooltip" data-placement="bottom" data-original-title="年限版用户">
-                    <% } else { %>
-                    <img src="/web/building_saas/img/vip.png" data-toggle="tooltip" data-placement="bottom" data-original-title="专业版用户">
+                    <% if (sessionUser.compilationLock === 1) { %>
+                    <img width="38" src="/web/building_saas/img/vip2.png" data-toggle="tooltip" data-placement="bottom" data-original-title="借用">
+                    <% } else if (sessionUser.compilationLock === 2) { %>
+                    <img width="38" src="/web/building_saas/img/vip.png" data-toggle="tooltip" data-placement="bottom" data-original-title="购买">
                     <% } %>
                 </a>
               </li>
@@ -80,7 +80,9 @@
                     <!--<a class="dropdown-item" href="/web/common/html/pdfViewer.html?type=userGuide" target="_blank">用户手册</a>
                     <a class="dropdown-item" href="/web/common/html/pdfViewer.html?type=upgradeGuide" target="_blank">升级说明</a>-->
                     <a class="dropdown-item" href="http://doc.zhzdwd.com/docs/dsk_yhsc" target="_blank">用户手册</a>
-                    <a class="dropdown-item" href="http://doc.zhzdwd.com/docs/dasikongupdate/dasikongupdate-1c6lsks1552q8" target="_blank">升级说明</a>
+                    <a class="dropdown-item" href="http://doc.zhzdwd.com/docs/dhjc" target="_blank">动画教学</a>
+                    <a class="dropdown-item" href="http://yun.zhzdwd.com/docs" target="_blank">常见问题解答</a>
+                    <a class="dropdown-item" href="http://doc.zhzdwd.com/docs/dasikongupdate" target="_blank">升级说明</a>
                     <a class="dropdown-item" href="http://zhzdwk.com/special/detail/36" target="_blank">计价依据</a>
                     <a class="dropdown-item" href="https://smartcost.com.cn/" target="_blank">纵横官网</a>
                     <!--  <a class="dropdown-item" href="#">动画教程</a>-->

+ 7 - 0
web/over_write/js/chongqing_2018.js

@@ -10,6 +10,9 @@ if(typeof projectGljObject !== 'undefined'){
         {ID:'MAIN_MATERIAL',text:'主材'}
     ];
     $('#menu_index_info').show();
+  projectGljObject.addCommonInfoPriceID = function (condition) { 
+    if(condition.areaID != projectGljObject.commonInfoPriceID) condition.commonInfoPriceID = projectGljObject.commonInfoPriceID;
+  }
 }
 if(typeof gljUtil !== 'undefined'){
     gljUtil.hasCompMachine = [301,304];//有组成物的机械
@@ -321,6 +324,10 @@ if(typeof figureClassTemplate !== 'undefined'){
     figureClassTemplate['ADDED_VALUE_TAX'] = {flag: fixedFlag.ADDED_VALUE_TAX, filter: ['SJ', 'ZZS', 'SQGCZJ']}
 };
 
+if(typeof gljCol !== 'undefined'){
+  gljCol.hideInfoPrice = false;
+};
+
 //这个文档浏览器库和服务器端共用,所以这个文件中用到的变量都要记得做undefined判断,不然后端读取时会有问题
 //=================================================== 前后端分割线 ======================================================================
 if(typeof module !== 'undefined'){

+ 4 - 0
web/over_write/js/guangdong_2018.js

@@ -475,6 +475,10 @@ if (typeof commonConstants !== 'undefined') {
     };
 }
 
+if(typeof gljCol !== 'undefined'){
+  gljCol.hideInfoPrice = false;
+};
+
 if(typeof module !== 'undefined'){
     module.exports = {
         getBillsCalcMode: getBillsCalcMode,

+ 1 - 1
web/users/html/index.html

@@ -33,7 +33,7 @@
       <!--banner-->
       <div class="hero bg-dark section " style="background-image: url(/web/users/images/bg_01.png);" id="home">
          <div class="container text-center">
-            <h1 class="text-white mb-4 f-50 ">大司空市政云计价,正版软件永久免费</h1>
+            <h1 class="text-white mb-4 f-50 ">市政计价免费公用版,永久免费</h1>
             <p class="lead text-white mb-5">跨平台,打开浏览器即可使用,全新在线计价体验。
             <div class="btn_hero">
                <a href="/login" class="btn btn-danger mr-2">登录软件</a>

+ 4 - 4
web/users/html/login-sms.html

@@ -36,10 +36,10 @@
                     <strong>登录失败</strong> <span id="message"></span>
                 </div>
             </div>
-            <div class="form-group">
-                <div id="captcha-box"></div>
-            </div>
-            <div class="form-group btn-area" style="display: none;">
+            <!--<div class="form-group">-->
+                <!--<div id="captcha-box"></div>-->
+            <!--</div>-->
+            <div class="form-group btn-area">
                 <button id="login" type="button" class="btn btn-primary btn-block">登录</button>
             </div>
         </form>

+ 1 - 1
web/users/html/login-ver.html

@@ -26,7 +26,7 @@
             <div class="">
             <div class="row  modal-auto-height">
                 <% for (const ver of versionData) { %>
-                        <div class="col-sm-6">
+                        <div class="col-sm-4 mb-3">
                             <div class="card card-block">
                                 <div class="card-body">
                                     <h3 class="card-title"><%= ver.name %></h3>

+ 4 - 4
web/users/html/login.html

@@ -47,10 +47,10 @@
                     <strong>登录失败</strong> <span id="message"></span>
                 </div>
             </div>
-            <div class="form-group">
-                <div id="captcha-box"></div>
-            </div>
-            <div class="form-group btn-area" style="display: none">
+            <!--<div class="form-group">-->
+                <!--<div id="captcha-box"></div>-->
+            <!--</div>-->
+            <div class="form-group btn-area">
                 <button id="login" type="button" class="btn btn-primary btn-block">登录</button>
             </div>
             <div class="pt-1 d-flex justify-content-between">

+ 22 - 21
web/users/html/user-buy.html

@@ -51,7 +51,7 @@
                             <div class="col-sm-5 mb-5">
                                 <div class="card free-version">
                                   <div class=" card-body">
-                                    <h3 class="card-title">免费版 </h3>
+                                    <h3 class="card-title">免费公用版 </h3>
                                       <!--<p class="card-text">-->
                                     <!--  <ul class="pl-3">
                                           <li>只可创建 50 个单位工程</li>
@@ -75,12 +75,16 @@
                             </div>
                             <div class="col-sm-5 mb-5">
                                 <div class="card pro-version">
-                                  <div class="card-body">
-                                    <h3 class="card-title">
-                                        专业版
-                                        <img src="/web/building_saas/img/vip.png" data-toggle="tooltip" data-placement="bottom" data-original-title="专业版用户">
-                                        <img src="/web/building_saas/img/vip2.png" data-toggle="tooltip" data-placement="bottom" data-original-title="年限版用户">
-                                    </h3>
+                                    <div class="card-body d-flex justify-content-between">
+                                        <h3 class="card-title">专业版</h3>
+                                        <div>
+                                            <div class="d-inline-block mr-3">
+                                                <img width="24" src="/web/building_saas/img/vip.png">购买
+                                            </div>
+                                            <div class="d-inline-block">
+                                                <img width="24" src="/web/building_saas/img/vip2.png">借用
+                                            </div>
+                                        </div>
                                       <!--<p class="card-text">-->
                                       <!--&lt;!&ndash;<ul class="pl-3">-->
                                           <!--<li>创建单位工程无限制</li>-->
@@ -94,27 +98,24 @@
                                         <li class="list-group-item d-flex justify-content-between">
                                             <div class="col-6">
                                                 <%= compilation.name %>
-                                                <% if (compilation.isUpgrade !== undefined && compilation.isUpgrade === true && compilation.deadline !== undefined && compilation.deadline !== '') { %>
-                                                <img src="/web/building_saas/img/vip2.png" data-toggle="tooltip" data-placement="bottom" data-original-title="年限版用户">
-                                                <% } else if (compilation.isUpgrade !== undefined && compilation.isUpgrade === true && (compilation.deadline === undefined || compilation.deadline === '')) { %>
-                                                <img src="/web/building_saas/img/vip.png" data-toggle="tooltip" data-placement="bottom" data-original-title="专业版用户">
+                                                <% if (compilation.lock !== undefined && compilation.lock === 1) { %>
+                                                <img width="38" src="/web/building_saas/img/vip2.png" data-toggle="tooltip" data-placement="bottom" data-original-title="借用">
+                                                <% } else if (compilation.lock !== undefined && compilation.lock === 2) { %>
+                                                <img width="38" src="/web/building_saas/img/vip.png" data-toggle="tooltip" data-placement="bottom" data-original-title="购买">
                                                 <% } %>
                                             </div>
                                             <div class="ml-auto text-right">
-                                            <% if (compilation.isUpgrade === undefined || compilation.isUpgrade !== true) { %>
-                                            <a href="javascript:void(0);" class="btn btn-primary btn-sm getcategory" data-upgrade="<%= compilation.isUpgrade %>" data-category="<%= compilation.categoryID %>">立即激活</a>
-                                            <% } else { %>
-                                            <a href="javascript:void(0);" class="btn btn-outline-secondary btn-sm getcategory" data-title="<%= compilation.name %>" data-upgrade="<%= compilation.isUpgrade %>" data-category="<%= compilation.categoryID %>"><i class="fa fa-check"></i> 已激活</a>
-                                            <% if (compilation.deadline !== undefined && compilation.deadline !== '') { %><span class="d-block text-muted">到期:<%= compilation.deadline %></span><% } %>
-                                            <% } %>
+                                                <% if (compilation.isUpgrade === undefined || compilation.isUpgrade !== true) { %>
+                                                <a href="javascript:void(0);" class="btn btn-primary btn-sm getcategory" data-upgrade="<%= compilation.isUpgrade %>" data-category="<%= compilation.categoryID %>">立即激活</a>
+                                                <% if (compilation.deadline !== undefined && compilation.deadline !== '') { %><span class="d-block text-danger">已到期:<%= compilation.deadline %></span><% } %>
+                                                <% } else { %>
+                                                <a href="javascript:void(0);" class="btn btn-outline-secondary btn-sm getcategory" data-title="<%= compilation.name %>" data-upgrade="<%= compilation.isUpgrade %>" data-category="<%= compilation.categoryID %>"><i class="fa fa-check"></i> 已激活</a>
+                                                <% if (compilation.deadline !== undefined && compilation.deadline !== '') { %><span class="d-block text-muted">到期:<%= compilation.deadline %></span><% } %>
+                                                <% } %>
                                             </div>
                                         </li>
                                         <% }) %>
                                         <% } %>
-                                        <!--<li class="list-group-item d-flex justify-content-between">-->
-                                        <!--重庆(2015)-->
-                                        <!--<a class="btn btn-outline-secondary btn-sm" href="activ2" data-toggle="modal" data-target="#activ2"><i class="fa fa-check"></i> 已激活</a>-->
-                                        <!--</li>-->
                                     </ul>
                                 </div>
                             </div>

二進制
web/users/images/favicon.ico


+ 146 - 102
web/users/js/login.js

@@ -9,42 +9,42 @@ $(document).ready(function () {
     let referer = scUrlUtil.GetQueryString('referer');
 
     // 载入时先获取相关参数
-    $.ajax({
-        url: '/captcha',
-        type: 'get',
-        data: '',
-        timeout: 5000,
-        error: function() {
-            $("#captcha-box").html('验证码加载失败');
-        },
-        beforeSend: function() {
-            $("#captcha-box").html('正在加载验证码');
-        },
-        success: function(response) {
-            $("#captcha-box").html('');
-            if (response.success === 0) {
-                alert('验证码初始化失败!');
-                return false;
-            }
-
-            initGeetest({
-                // 以下配置参数来自服务端 SDK
-                gt: response.gt,
-                challenge: response.challenge,
-                offline: !response.success,
-                new_captcha: response.new_captcha,
-                width: '100%'
-            }, handler);
-        }
-    });
+    // $.ajax({
+    //     url: '/captcha',
+    //     type: 'get',
+    //     data: '',
+    //     timeout: 5000,
+    //     error: function() {
+    //         $("#captcha-box").html('验证码加载失败');
+    //     },
+    //     beforeSend: function() {
+    //         $("#captcha-box").html('正在加载验证码');
+    //     },
+    //     success: function(response) {
+    //         $("#captcha-box").html('');
+    //         if (response.success === 0) {
+    //             alert('验证码初始化失败!');
+    //             return false;
+    //         }
+    //
+    //         initGeetest({
+    //             // 以下配置参数来自服务端 SDK
+    //             gt: response.gt,
+    //             challenge: response.challenge,
+    //             offline: !response.success,
+    //             new_captcha: response.new_captcha,
+    //             width: '100%'
+    //         }, handler);
+    //     }
+    // });
 
-    const handler = function(captchaObj) {
-        captchaObj.appendTo('#captcha-box');
-        captchaObj.onSuccess(function () {
-            $(".btn-area").slideDown("fast");
-            // $('#login').click();
-            // captchaObj.getValidate();
-        });
+    // const handler = function(captchaObj) {
+    //     captchaObj.appendTo('#captcha-box');
+    //     captchaObj.onSuccess(function () {
+    //         $(".btn-area").slideDown("fast");
+    //         // $('#login').click();
+    //         // captchaObj.getValidate();
+    //     });
 
         $("#login").click(function () {
             if (!valid()) {
@@ -53,14 +53,14 @@ $(document).ready(function () {
             if ($('#changeLogin').attr('data-status') === 'user') {
                 let account = $("#inputEmail").val();
                 if(/^1[3456789]\d{9}$/.test(account) || /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(account)) {
-                    login(captchaObj);
+                    login();
                 } else {
                     $('#emailHelp').text('您输入的 邮箱/手机 格式不对');
                 }
             } else {
                 let account = $("#mobileLogin").val();
                 if(/^1[3456789]\d{9}$/.test(account)) {
-                    login(captchaObj);
+                    login();
                 } else {
                     $('#phoneHelp').text('您输入的 手机 格式不对');
                 }
@@ -142,7 +142,7 @@ $(document).ready(function () {
                 }
             })
         });
-    };
+    // };
 
     $("input").blur(function () {
         cleanError();
@@ -265,73 +265,117 @@ $(document).ready(function () {
     });
 });
 
-function login(captchaObj) {
-    $('#login').attr('disabled', true);
-    let geetest_challenge = $('input[name="geetest_challenge"]').val();
-    let geetest_validate = $('input[name="geetest_validate"]').val();
-    let geetest_seccode = $('input[name="geetest_seccode"]').val();
+function login() {
+    $.ajax({
+        url: '/captcha?t='+ (new Date()).getTime(),
+        type: 'get',
+        dataType: 'json',
+        timeout: 5000,
+        error: function() {
+            // $("#captcha-box").html('验证码加载失败');
+        },
+        beforeSend: function() {
+            // $("#captcha-box").html('正在加载验证码');
+        },
+        success: function(response) {
+            $("#captcha-box").html('');
+            if (response.success === 0) {
+                alert('验证码初始化失败!');
+                return false;
+            }
 
-    const postData = {
-        geetest_challenge: geetest_challenge,
-        geetest_validate: geetest_validate,
-        geetest_seccode: geetest_seccode,
-    };
-    if ($('#changeLogin').attr('data-status') === 'user') {
-        let account = $("#inputEmail").val();
-        let pw = $("#inputPassword").val();
-        postData.account = account;
-        postData.pw = pw;
-    } else {
-        let mobile = $('#mobileLogin').val();
-        let code = $("#codeLogin").val();
-        postData.mobile = mobile;
-        postData.code = code;
-    }
+            initGeetest({
+                // 以下配置参数来自服务端 SDK
+                gt: response.gt,
+                challenge: response.challenge,
+                offline: !response.success,
+                new_captcha: response.new_captcha,
+                // width: '100%',
+                product: "bind"
+            }, function (catpchaObj) {
+                catpchaObj.onReady(function () {
+                    catpchaObj.verify();
+                }).onClose(function () {
+                }).onSuccess(function () {
+                    /* 延迟到动画结束后再alert */
+                    var lastUTC = new Date(), duration = 1100;
+                    function _alert(msg) {
+                        var elapsed = new Date() - lastUTC;
+                        if (elapsed >= duration) { return alert(msg) }
+                        setTimeout(function () { alert(msg) }, duration - elapsed);
+                    }
+                    var result = catpchaObj.getValidate();
+                    if (!result) {return alert('请完成验证');}
+                    $('#login').attr('disabled', true);
+                    let geetest_challenge = $('input[name="geetest_challenge"]').val();
+                    let geetest_validate = $('input[name="geetest_validate"]').val();
+                    let geetest_seccode = $('input[name="geetest_seccode"]').val();
 
-    $.ajax({
-        url: '/login',
-        type: 'post',
-        data: postData,
-        success: function (response) {
-            if (response.error === 0) {
-                // $('#phonepass').modal('hide');
-                const url = response.last_page !== null && response.last_page !== undefined && response.last_page !== '' ?
-                    response.last_page : '/pm';
-                if (response.login_ask === 0) {
-                    location.href = url;
-                } else {
-                    response.compilation_list = response.compilation_list === undefined || response.compilation_list === '' ?
-                        null : JSON.parse(response.compilation_list);
-                    if (response.compilation_list === null || response.compilation_list.length <= 0) {
-                        location.href = url;
-                        return false;
+                    const postData = {
+                        geetest_challenge: geetest_challenge,
+                        geetest_validate: geetest_validate,
+                        geetest_seccode: geetest_seccode,
+                    };
+                    if ($('#changeLogin').attr('data-status') === 'user') {
+                        let account = $("#inputEmail").val();
+                        let pw = $("#inputPassword").val();
+                        postData.account = account;
+                        postData.pw = pw;
+                    } else {
+                        let mobile = $('#mobileLogin').val();
+                        let code = $("#codeLogin").val();
+                        postData.mobile = mobile;
+                        postData.code = code;
                     }
-                    console.log(response.compilation_list);
-                    setVersion(response.compilation_list);
-                    $('#ver').modal('show');
-                }
-            } else if(response.error === 2) {
-                // $('#phonepass').modal('hide');
-                // captchaObj.reset();
-                $('#check_ssoId').val(response.ssoId);
-                $('#phone').modal('show');
-                $('#login').removeAttr('disabled');
-            } else if(response.error === 3) {
-                // captchaObj.reset();
-                $('#phonepass').modal('show');
-                $('#mobileLogin').val(response.data);
-                $('#login').removeAttr('disabled');
-            } else {
-                // $('#phonepass').modal('hide');
-                let msg = response.msg !== undefined ? response.msg : '未知错误';
-                showError(msg, $("input"));
-                $('#login').removeAttr('disabled');
-                // captchaObj.reset();
-            }
-        },
-        error: function (result) {
-            showError('内部程序错误', null);
-            $('#login').removeAttr('disabled');
+
+                    $.ajax({
+                        url: '/login',
+                        type: 'post',
+                        data: postData,
+                        success: function (response) {
+                            if (response.error === 0) {
+                                // $('#phonepass').modal('hide');
+                                const url = response.last_page !== null && response.last_page !== undefined && response.last_page !== '' ?
+                                    response.last_page : '/pm';
+                                if (response.login_ask === 0) {
+                                    location.href = url;
+                                } else {
+                                    response.compilation_list = response.compilation_list === undefined || response.compilation_list === '' ?
+                                        null : JSON.parse(response.compilation_list);
+                                    if (response.compilation_list === null || response.compilation_list.length <= 0) {
+                                        location.href = url;
+                                        return false;
+                                    }
+                                    console.log(response.compilation_list);
+                                    setVersion(response.compilation_list);
+                                    $('#ver').modal('show');
+                                }
+                            } else if(response.error === 2) {
+                                // $('#phonepass').modal('hide');
+                                // captchaObj.reset();
+                                $('#check_ssoId').val(response.ssoId);
+                                $('#phone').modal('show');
+                                $('#login').removeAttr('disabled');
+                            } else if(response.error === 3) {
+                                // captchaObj.reset();
+                                $('#phonepass').modal('show');
+                                $('#mobileLogin').val(response.data);
+                                $('#login').removeAttr('disabled');
+                            } else {
+                                // $('#phonepass').modal('hide');
+                                let msg = response.msg !== undefined ? response.msg : '未知错误';
+                                showError(msg, $("input"));
+                                $('#login').removeAttr('disabled');
+                                // captchaObj.reset();
+                            }
+                        },
+                        error: function (result) {
+                            showError('内部程序错误', null);
+                            $('#login').removeAttr('disabled');
+                        }
+                    });
+                })
+            });
         }
     });
 }