Browse Source

feat:页面融合

wangxiaogang 3 years ago
parent
commit
2f29334c74

+ 18 - 0
src/api/modules/potential.js

@@ -66,3 +66,21 @@ export function followClientList (data) {
     data
   })
 }
+
+export function claimchecked (data) {
+  return request({
+    baseURL: '/entnicheNew',
+    url: '/customer/claimcheck',
+    method: 'POST',
+    data
+  })
+}
+
+export function custAttention (data) {
+  return request({
+    baseURL: '/entnicheNew',
+    url: '/customer/attention',
+    method: 'POST',
+    data
+  })
+}

+ 8 - 0
src/api/modules/user.js

@@ -1,6 +1,14 @@
 import request from '@/api'
 import qs from 'qs'
 
+export function getEntApi () {
+  return request({
+    baseURL: '/entnicheNew',
+    url: '/buy/whetherbuy',
+    method: 'post'
+  })
+}
+
 export function getUserPower () {
   return request({
     url: '/use/isAdd',

BIN
src/assets/images/icon/renling-01.png


BIN
src/assets/images/icon/renling-active.png


BIN
src/assets/images/icon/tip.png


+ 491 - 0
src/components/common/Popper.vue

@@ -0,0 +1,491 @@
+<template>
+  <div class="tags-box">
+    <div class="tags-inputs">
+      <div class="tag-input">
+        <div class="tag-labels"></div>
+        <input type="text" class="clear-input" maxlength="5" oninput="this.value=this.value.replace(/\s+/g,'')">
+        <div class="tag-placeholder">新增标签回车保存</div>
+      </div>
+      <div class="add-tag-button">添加并使用</div>
+    </div>
+    <div class="tags-list clearfix"></div>
+    <div class="tags-footer">
+      <div class="tags-button button-confirm">确认添加</div>
+      <div class="tags-button button-cancel">暂不添加</div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      datas: []
+    }
+  },
+  mounted() {
+    this.initCollectEvent()
+  },
+  methods: {
+    showTip (text, duration) {
+      if (duration) {
+        duration = 1000
+      }
+      var _html = ''
+      _html += '<div class="custom-toast"><div class="mask" style="background-color: transparent;"></div><div class="toast-container">'
+      _html += '<span>' + text + '</span></div></div>'
+      $('body').append(_html)
+      setTimeout(function () {
+        $('.custom-toast').fadeOut().remove()
+      }, duration)
+    },
+    tagsShow(data) {
+      this.datas = data.data
+      var top = data.liHeight * (data.i + 1) + 'px'
+      if (data.show) {
+        $('.tags-box').slideToggle(function () {
+          window.activeTags = []
+          $('.tag-labels').empty()
+          $('.clear-input').val('')
+          $('.tags-list').find('.tags-item').removeClass('tags-active')
+          $('.tag-placeholder').show()
+        }).css({
+          top: top,
+          right: 0
+        })
+      }
+      
+    },
+    initCollectEvent () {
+      const _this = this
+      function toastFn (text, duration) {
+        _this.showTip(text, duration)
+      }
+      // 自定义标签
+      // 标签输入框事件
+      $('.tags-box').click(function (e) {
+        e.stopPropagation()
+      })
+
+      $('.tag-input').click(function (e) {
+        e.stopPropagation()
+        $(this).children('.tag-placeholder').hide()
+        $(this).children('input').focus()
+      })
+      // 标签输入框回车事件
+      $('.tag-input .clear-input').keydown(function (event) {
+        event.stopPropagation()
+        if (event.keyCode == 13) {
+          if (!$('.tags-box').is(':hidden')) {
+            $('.tags-inputs .add-tag-button').trigger('click')
+          }
+        }
+      })
+      // 标签输入框失去焦点事件
+      $('.tag-input .clear-input').blur(function () {
+        if ($('.tag-labels').children().length == 0 && $(this).val() == '') {
+          $('.tag-placeholder').show()
+        }
+      })
+      // 添加标签按钮事件
+      $('.tags-inputs .add-tag-button').on('click', function () {
+        var input = $('.tag-input .clear-input')
+        if (input.val().length >= 2 && input.val().length < 6) {
+          // ajax提交自定义标签
+          addTagsAjax(input.val())
+        }
+      })
+      // 点击确定按钮,绑定标签
+      $('.tags-footer .button-confirm').on('click', function () {
+        if (!$('.tags-box').is(':hidden')) {
+          var lids = ''
+          var lname = ''
+          $('.tags-item.tags-active').each(function () {
+            if ($(this).attr('data-id')) {
+              if (lids != '') {
+                lids += ','
+              }
+              if (lname != '') {
+                lname += ','
+              }
+              lids += $(this).attr('data-id')
+              lname += $(this).text()
+            }
+          })
+          var params = {
+            name: _this.datas,
+            mold: 1,
+            D: false,
+            label: lids
+          }
+          // 执行保存绑定标签操作
+          // if (params.label !== '') {
+            saveChooseTags(params, function () {
+              $('.tags-footer .button-cancel').trigger('click')
+            })
+          // }
+        }
+      })
+
+      $('.tags-footer .button-cancel').on('click', function () {
+        $('.tags-box').slideToggle(function () {
+          // 标签弹框消失时 清除上次选择的标签分类
+          activeTags = []
+          $('.tag-labels').empty()
+          $('.clear-input').val('')
+          $('.tags-list').find('.tags-item').removeClass('tags-active')
+          $('.tag-placeholder').show()
+        })
+      })
+
+      window.activeTags = [] // 选中的自定义标签 作为全局变量使用
+      // 解绑自定义标签
+      function deleteInputTag (item) {
+        var index = $(item).parent().attr('data-index')
+        var id = $(item).parent().attr('data-id')
+        activeTags.splice(index, 1)
+        inputTagList()
+        $('.tags-item[data-id="' + id + '"]').removeClass('tags-active')
+      }
+
+      window.deleteInputTag = deleteInputTag
+
+      function inputTagList () {
+        var ht = ''
+        $('.tag-labels').html(ht)
+        activeTags.forEach(function (v, i) {
+          ht += '<span class="tag-label" data-index=' + i + ' data-id="' + v.lid + '">'
+          ht += '<em>' + v.lname + '</em>'
+          ht += '<i class="tag-close" onclick="deleteInputTag(this)"></i>'
+          ht += '</span>'
+        })
+        $('.tag-labels').html(ht)
+        if ($('.tag-labels').children('.tag-label').length > 0) {
+          $('.tag-placeholder').hide()
+        }
+        checkTagDisabled()
+      }
+
+      // 渲染标签列表数据
+      function renderTagsList (data) {
+        if (data && data.length > 0) {
+          var ht = ''
+          data.forEach(function (v, i) {
+            ht += '<span class="tags-item" data-count=' + v.count + ' data-id=' + v.lid + '>' + v.lanme + '</span>'
+          })
+          $('.tags-list').html(ht)
+          activeTags.forEach(function (s, j) {
+            $('.tags-list .tags-item[data-id="' + s.lid + '"]').addClass('tags-active')
+          })
+          $('.tags-item').click(function (e) {
+            e.stopPropagation()
+            if ($(this).hasClass('disabled')) return
+            var id = $(this).attr('data-id')
+            var name = $(this).text()
+            $(this).toggleClass('tags-active')
+            if ($(this).hasClass('tags-active')) {
+              activeTags.push({
+                lid: id,
+                lname: name
+              })
+              inputTagList()
+            } else {
+              var newArr = activeTags.filter(function (item) {
+                return item.lid != id
+              })
+              activeTags = newArr
+              console.log(activeTags, newArr, 'quxiao')
+              inputTagList()
+            }
+          })
+        }
+        inputTagList()
+      }
+
+      // 获取用户自定义标签
+      function getUserTags () {
+        $.ajax({
+          type: 'post',
+          url: '/entnicheNew/customer/getLabel?t=' + Date.now(),
+          success: function (r) {
+            if (r.error_code == 0 && $.isArray(r.data)) {
+              renderTagsList(r.data.reverse())
+            }
+          }
+        })
+      }
+
+      window.getUserTags = getUserTags
+      // 添加标签后认领接口
+      function saveChooseTags (params, callback) {
+        $.ajax({
+          type: 'post',
+          url: '/entnicheNew/customer/attention',
+          contentType: 'application/json',
+          data: JSON.stringify(params),
+          dataType: 'json',
+          success: function (r) {
+            if (r.error_code == 0 && r.data) {
+              _this.$toast('认领成功!')
+              _this.$emit('getClientList', true)
+              callback && callback()
+            } else {
+              if (r.error_msg) {
+                _this.$toast(r.error_msg, 3000)
+              }
+            }
+          }
+        })
+      }
+
+      // 新增标签
+      function addTagsAjax (name) {
+        $.ajax({
+          type: 'post',
+          url: '/entnicheNew/customer/addLabel',
+          data: {
+            name: name
+          },
+          dataType: 'json',
+          success: function (r) {
+            if (r.data) {
+              $('.tag-input .clear-input').val('')
+              // 添加标签成功后 绑定标签
+              if (activeTags.length < 3) {
+                activeTags.push({
+                  lid: r.data,
+                  lname: name
+                })
+              }
+              getUserTags()
+            } else {
+              // toastFn(r.error_msg, 1000)
+              toastFn('标签已经存在,无需添加', 1000)
+            }
+          }
+        })
+      }
+
+      function checkTagDisabled () {
+        if (activeTags.length >= 3) {
+          // 禁用标签
+          $('.tags-list').find('.tags-item:not(.tags-active)').addClass('disabled')
+        } else {
+          // 解除禁用
+          $('.tags-list').find('.disabled').removeClass('disabled')
+        }
+      }
+
+      function baiduEvent (str) {
+        try {
+          // eslint-disable-next-line no-undef
+          _hmt.push(['_trackEvent', '大会员-pc', 'click', str])
+        } catch (e) {
+          console.log('未初始化百度统计')
+        }
+      }
+      getUserTags()
+    },
+  }
+}
+</script>
+
+<style>
+.tags-box {
+  display: none;
+  position: absolute;
+  top: 0;
+  right: 0;
+  width: 332px;
+  padding: 20px 16px;
+  background: #FFFFFF;
+  border: 1px solid #ECECEC;
+  box-sizing: border-box;
+  border-radius: 8px;
+  box-shadow: 0px 0px 28px 0px rgba(0, 0, 0, 0.08);
+  z-index: 99;
+}
+
+.tags-box .tags-inputs {
+  position: relative;
+  width: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.tags-box .tags-inputs .tag-input {
+  width: 100%;
+  padding: 0;
+  min-height: 34px;
+  max-height: 74px;
+  overflow-y: scroll;
+  display: inline-block;
+  border: 1px solid #ccc;
+  border-radius: 4px;
+  background-color: #fff;
+  cursor: text;
+}
+
+.tags-inputs .tag-input::-webkit-scrollbar {
+  width: 8px;
+}
+
+.tags-inputs .tag-input::-webkit-scrollbar-thumb {
+  border-radius: 4px;
+  background-color: #ECECEC;
+}
+
+.tag-input > .tag-labels {
+  display: inline;
+  vertical-align: middle;
+}
+
+.tag-input > .clear-input {
+  display: inline-block;
+  padding: 0 10px;
+  width: 100%;
+  height: 36px;
+  line-height: 1;
+  background: #fff;
+  border-radius: 2px;
+  vertical-align: middle;
+  border: none;
+  background-color: transparent;
+  box-shadow: none;
+  box-sizing: border-box;
+  font-size: 14px;
+  color: #1d1d1d;
+}
+
+.tag-input > .tag-labels > .tag-label {
+  display: inline-block;
+  padding: 5px 12px;
+  font-size: 14px;
+  line-height: 1.2;
+  margin: 5px;
+  cursor: pointer;
+  border: 1px solid #ECECEC;
+  box-sizing: border-box;
+  border-radius: 4px;
+  background: #F5F6F7;
+  color: #1D1D1D;
+}
+
+.tag-close {
+  display: inline-block;
+  width: 16px;
+  height: 16px;
+  margin-left: 8px;
+  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAEwSURBVHgB7ZWxDYMwEEXPER1NRmEFJggUiJpJQiahRhSECViBUdzQIYgdgYQIPnwXmkT+DcbY/s9n3wHg5PTPKoriejRGYB+rqrpP0xT1fR9mWSaBaO77fiuEeCZJ8gAqwGyez68dBWIxV83gbSJEboK47HXWda1DF626Ar2gTUi35lo6iqbxuwBxHEvP80JF3lEg9sxhjp5pDnoHdCSGYWjVDj4W3B4HZo4dHQpgC8E1twI4gtANrrk1AAYxP1nmJAAEArjmZIADiI5TsC5AlJRS5zWcJVIEDLd9LXIUrCNgSjVqsWIBYHnOqZhrHR6BTZGhVEwSAKXCcSHEGebfQBjvAKe8cv6iRgC1i4ZijkHotUxz0TtQlmWuFrpxKtxyHOM4Nmma5sAVJaednH5SLxmyS6JIrGjkAAAAAElFTkSuQmCC);
+  background-position: center 2px;
+  background-repeat: no-repeat;
+  background-size: contain;
+}
+
+.tag-placeholder {
+  position: absolute;
+  top: 12px;
+  left: 16px;
+  color: #bbb;
+  font-size: 14px;
+}
+
+.tags-box .tags-list {
+  margin-top: 12px;
+  overflow-y: auto;
+  height: 220px;
+}
+
+.tags-box .tags-list::-webkit-scrollbar {
+  width: 8px;
+}
+
+.tags-box .tags-list::-webkit-scrollbar-thumb {
+  border-radius: 4px;
+  background-color: #ECECEC;
+}
+
+.tags-box .tags-list .tags-item {
+  float: left;
+  min-width: 44px;
+  padding: 0 8px;
+  margin: 10px 8px 0 0;
+  height: 24px;
+  line-height: 24px;
+  border-radius: 4px;
+  border: 1px solid #ECECEC;
+  box-sizing: border-box;
+  color: #1D1D1D;
+  text-align: center;
+  font-size: 14px;
+  background: #F5F6F7;
+  cursor: pointer;
+}
+
+.tags-box .tags-list .tags-active {
+  padding: 0 8px 0 24px !important;
+  background: #2CB7CA url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAADPSURBVHgB7ZNREcIwDIYjYRImYRLmZHPAHAwHlUAdIAEJSKiESgjpEY7Qg7uFdXnKd5eXdMmfpX8BHMdxDEDEgSJQ9GANiU4UGZ9cwBISXPFNGWIAKyrxZLr+suq/xdkwV4oFlFBNR3ET4veS0zaJosGoqOtZ8EVUi4tGWbM+rklC/Ax7KH++dY18ZbmZuGi8iKbhxzdTJT5DSyo/LNXZSZxljV80A3T4aayR86vIJTzyjX8xZTATF0NIU24y5xFDSFNGU3ExxNzsmTmO4zAPYEiZdz83IV0AAAAASUVORK5CYII=) no-repeat 6px center !important;
+  color: #fff !important;
+  background-size: 16px !important;
+  border: 0 !important;
+}
+
+.tags-item.disabled {
+  color: #8E8E8E !important;
+  border-color: #ECECEC!important;
+  cursor: not-allowed!important;
+}
+
+.tag-label em {
+  font-style: normal;
+}
+
+.add-tag-button {
+  margin-left: 16px;
+  color: #2cb7ca;
+  font-size: 14px;
+  line-height: 22px;
+  white-space: nowrap;
+  cursor: pointer;
+}
+
+.tags-footer {
+  margin-top: 20px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.tags-button {
+  padding: 3px 17px;
+  color: #1d1d1d;
+  font-size: 14px;
+  line-height: 22px;
+  border-radius: 4px;
+  border: 1px solid #e0e0e0;
+  text-shadow: 0px 0px 28px 0px rgba(0, 0, 0, 0.08);
+  cursor: pointer;
+}
+
+.button-confirm {
+  margin-right: 16px;
+  color: #fff;
+  background: #2cb7ca;
+  border-color: #2cb7ca;
+}
+
+.custom-toast .toast-container{
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  width: auto;
+  padding: 16px 32px;
+  font-size: 16px;
+  background: rgba(0, 0, 0, 0.65);
+  border-radius: 8px;
+  color: #fff;
+  transform: translateX(-50%) translateY(-50%);
+  z-index: 99;
+}
+</style>

+ 1 - 1
src/components/common/TabHeader.vue

@@ -7,7 +7,7 @@
       </div>
       <div class="tab-content" v-else-if="actived === 'cor' || actived === 'client'">
         <router-link class="tab-link" :class="actived === 'cor' ? 'active' : ''" to="/potential_cor_list/c" replace>潜在客户挖掘</router-link>
-        <router-link class="tab-link" :class="actived === 'client' ? 'active' : ''" to="/my_client" replace>我关注的客户</router-link>
+        <router-link class="tab-link" :class="actived === 'client' ? 'active' : ''" to="/my_client" replace>客户监控</router-link>
       </div>
     </div>
   </div>

+ 62 - 0
src/components/common/Tips.vue

@@ -0,0 +1,62 @@
+<template>
+  <div class="more-ent">
+    <div class="l-words"><i class="el-icon-jy-tip"></i>解锁关注更多企业</div>
+    <el-button class="r-btn" type="plain" @click="openCustomer">联系客服</el-button>
+  </div>
+</template>
+
+<script>
+import { Button } from 'element-ui'
+export default {
+  components: {
+    [Button.name]: Button
+  },
+  mounted () {
+    window.openCustomer = this.openCustomer
+  },
+  methods: {
+    openCustomer () {
+      // eslint-disable-next-line
+      $('.help-slide-zx.open-customer').trigger('click')
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+@include diy-icon('tip', 18, 18);
+.more-ent {
+  display: flex;
+  align-items: center;
+  width: 100%;
+  height: 40px;
+  padding: 0 20px;
+  background: rgba(51,182,202,0.1);
+  border-radius: 4px;
+  .l-words {
+    display: flex;
+    align-items: center;
+    font-size: 14px;
+    color: #2CB7CA;
+    line-height: 22px;
+    .el-icon-jy-tip {
+      margin-right: 9px;
+    }
+  }
+  ::v-deep .r-btn {
+    margin-left: 83px;
+    padding: 3px 20px;
+    border: 1px solid #2CB7CA;
+    background: none;
+    span {
+      display: block;
+      font-size: 14px;
+      color: #2CB7CA;
+      line-height: 22px;
+    }
+  }
+  .r-btn:hover {
+    background: rgba(44,183,202,0.10);
+  }
+}
+</style>

+ 81 - 0
src/components/common/noPass.vue

@@ -0,0 +1,81 @@
+<template>
+  <el-dialog
+    title="暂无权限"
+    :visible.sync="passVisible"
+    width="380px"
+    :show-close="false"
+    :lock-scroll="false"
+    custom-class="no-pass-alert"
+    center>
+    <span>您尚未购买此服务,如需使用,您可拨打客服电话 400-108-6670 或在线<i @click="openCustomer">联系客服</i>,谢谢!</span>
+    <span slot="footer" class="dialog-footer">
+      <el-button type="primary" @click="passVisible = false">我知道了</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+import { Dialog, Button } from 'element-ui'
+export default {
+  components: {
+    [Dialog.name]: Dialog,
+    [Button.name]: Button
+  },
+  data () {
+    return {
+      passVisible: false
+    }
+  },
+  mounted () {
+    window.openCustomer = this.openCustomer
+  },
+  methods: {
+    openCustomer () {
+      // eslint-disable-next-line
+      $('.help-slide-zx.open-customer').trigger('click')
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+::v-deep .no-pass-alert {
+  padding: 0;
+  padding: 32px;
+  .el-dialog__header {
+    padding: 0;
+    .el-dialog__title {
+      font-size: 18px;
+      color: $color-input--default;
+      line-height: 28px;
+    }
+  }
+  .el-dialog__body {
+    text-align: center;
+    padding: 0;
+    padding: 20px 0 32px 0;
+    span {
+      font-size: 14px;
+      color: #686868;
+      line-height: 22px;
+      i {
+        color: $color_main;
+        cursor: pointer;
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .el-button--primary {
+      background: $color_main;
+      padding: 8px 34px;
+      border: none;
+      span {
+        font-size: 16px;
+        line-height: 20px;
+        color: #fff;
+      }
+    }
+  }
+}
+</style>

+ 12 - 1
src/components/forecast/ForeCast.vue

@@ -4,6 +4,9 @@
       <strong style="font-weight:bold;font-size: 18px;color: #1d1d1d">企业列表</strong>
       <span style="font-size:14px;color:#686868;">(可关注 {{myDataObj.maxCount}} 个企业,已关注 <em style="color:#2CB7CA;">{{myDataObj.initTotal}}</em> 个)</span>
     </div>
+    <div class="tip_title" v-if="type=='entintel'">
+      <Tips></Tips>
+    </div>
     <div class="listData_title" v-else>{{ title }}</div>
     <!-- 中标企业预测-->
     <ul class="listData_ul" v-if="type=='bidfor'">
@@ -272,6 +275,7 @@
 import { Pagination, Progress, Message, Tooltip, Dialog, Button } from 'element-ui'
 import { mapState } from 'vuex'
 import { mixinVisited } from '@/utils/mixins/visited'
+import Tips from '@/components/common/Tips.vue'
 import Empty from '@/components/common/Empty.vue'
 import GroupCard from '@/components/selector/GroupSelector.vue'
 import { moneyUnit, dateFormatter } from '@/utils'
@@ -288,7 +292,8 @@ export default {
     [Dialog.name]: Dialog,
     [Button.name]: Button,
     Empty,
-    GroupCard
+    GroupCard,
+    Tips
   },
   data () {
     return {
@@ -752,6 +757,12 @@ export default {
     color: #1d1d1d;
     line-height: 28px;
   }
+  .tip_title {
+    padding-left: 40px;
+    padding-right: 40px;
+    margin-top: 24px;
+    margin-bottom: -10px;
+  }
   .entintel-thead{
     display: flex;
     align-items: center;

+ 9 - 2
src/components/push-list/ProjectProgressList.vue

@@ -6,6 +6,7 @@
         <el-button @click="goManage" class="unfollow-btn" type="plain">批量取消关注30天无更新的项目</el-button>
       </div>
     </div>
+    <Tips></Tips>
     <div class="info-list" v-loading="listState.loading">
       <PoverTimeLine
         v-for="(item, index) in listState.list"
@@ -52,6 +53,7 @@
 
 <script>
 import { Pagination, Card, Button } from 'element-ui'
+import Tips from '@/components/common/Tips.vue'
 import Empty from '@/components/common/Empty.vue'
 import ArticleItem from '@/components/article-item/ArticleItem.vue'
 import { dateFromNow, dateFormatter, replaceKeyword } from '@/utils/'
@@ -66,6 +68,7 @@ export default {
     [Card.name]: Card,
     [Button.name]: Button,
     ArticleItem,
+    Tips,
     Empty,
     PoverTimeLine
   },
@@ -343,11 +346,14 @@ export default {
   ::v-deep {
     .el-card__header {
       margin: 0 40px;
+      border-bottom: none;
       padding-left: 0;
       padding-right: 0;
+      padding-bottom: 16px;
+      padding-top: 20px;
     }
     .el-card__body {
-      padding: 20px 40px;
+      padding: 0 40px 20px 40px;
     }
     .get-more {
       display: flex;
@@ -431,7 +437,8 @@ export default {
       font-size: 18px;
       color: #1d1d1d;
       font-weight: 700;
-
+      display: block;
+      line-height: 34px;
       .title-tips{
         font-size: 14px;
         color:#666666;

+ 1 - 1
src/components/time-line/PoverTimeLine.vue

@@ -45,7 +45,7 @@ export default {
   },
   methods: {
     show () {
-      this.$emit('show')
+      // this.$emit('show')
     }
   }
 }

+ 10 - 0
src/router/router.js

@@ -22,6 +22,16 @@ const router = new Router({
   }
 })
 
+router.beforeEach((to, from, next) => {
+  // 标题设置
+  if (to.meta.title) {
+    document.title = to.meta.title
+  } else {
+    document.title = '剑鱼标讯'
+  }
+  next()
+})
+
 const originalPush = Router.prototype.push
 Router.prototype.push = function push (location) {
   return originalPush.call(this, location).catch(err => err)

+ 12 - 3
src/router/routers.js

@@ -115,7 +115,10 @@ export default [
   {
     path: '/pro_follow_detail',
     name: 'pro_follow_detail',
-    component: () => import('@/views/project/ProjectInfo.vue')
+    component: () => import('@/views/project/ProjectInfo.vue'),
+    meta: {
+      title: '项目进度监控'
+    }
   },
   // 投标决策分析结果页
   {
@@ -145,13 +148,19 @@ export default [
   {
     path: '/my_client',
     name: 'my_client',
-    component: () => import('@/views/ent-intel/MyClient.vue')
+    component: () => import('@/views/ent-intel/MyClient.vue'),
+    meta: {
+      title: '客户监控'
+    }
   },
   // 项目进度监控
   {
     path: '/free/project_progress',
     name: 'project_progress',
-    component: () => import('@/views/ProjectProgress.vue')
+    component: () => import('@/views/ProjectProgress.vue'),
+    meta: {
+      title: '项目进度监控'
+    }
   },
   // 广东客户-搜索列表
   {

+ 18 - 0
src/store/user.js

@@ -1,5 +1,6 @@
 import { recoveryPageData, defaultLocalPageData } from '@/utils/'
 import {
+  getEntApi,
   getUserPower,
   getBigMemberInfo
 } from '@/api/modules'
@@ -8,6 +9,8 @@ import { formatKeywordsList } from '@/utils/format'
 export default {
   namespaced: true,
   state: () => ({
+    // 新版商机管理判断
+    isNewEnt: recoveryPageData('is-login-new-ent', []),
     power: recoveryPageData('bigmember-login-clear-power', []),
     info: recoveryPageData('bigmember-login-clear-info', {}),
     // 业务范围
@@ -24,6 +27,10 @@ export default {
     visitedList: defaultLocalPageData('visited-path-list', [])
   }),
   mutations: {
+    setNewEnt (state, data) {
+      state.isNewEnt = data
+      localStorage.setItem('is-login-new-ent', JSON.stringify(data))
+    },
     setUserInfo (state, info) {
       state.info = info
       localStorage.setItem('bigmember-login-clear-info', JSON.stringify(info))
@@ -73,6 +80,17 @@ export default {
     }
   },
   actions: {
+    async getNewEnt ({ commit, state }, payload) {
+      try {
+        const { data, error_code: code } = await getEntApi()
+        if (code === 0 && data) {
+          commit('setNewEnt', data)
+        }
+        return data || {}
+      } catch (error) {
+        return {}
+      }
+    },
     async getUserPower ({ commit, state }, payload) {
       try {
         const { data, error_code: code } = await getUserPower()

+ 1 - 1
src/views/PotentialList.vue

@@ -102,7 +102,7 @@ export default {
           if (!(res && res.error_code === 0 && res.data)) {
             this.$toast(res.error_msg)
           } else {
-            this.$toast('关注成功,可前往“我关注的客户”中查看')
+            this.$toast('关注成功,可前往“客户监控”中查看')
           }
           this.$refs.pushList.doQuery(this.filters)
         })

+ 141 - 17
src/views/ProjectProgress.vue

@@ -11,6 +11,13 @@
           <div class="flex-r-c center sb top-title-box">
             <h4 class="progress_cost">筛选条件</h4>
           </div>
+          <div class="select-group" v-if="isNewEnt.isNew">
+            <span>认领分类:</span>
+            <button v-for="(item, i) in fenData" :key="999-i"
+              class="j-button-item bgc"
+              :class="{'is-active': isDistri == i}"
+              @click="changeState(item, i)">{{ item.n }}</button>
+          </div>
           <div class="search_area">
             <!-- <div class="area_title">项目地区:</div> -->
             <AreaSelector
@@ -33,21 +40,22 @@
           </div>
         </div>
         <div class="content-list-box">
-          <ProjectProgressList @goDetail="goDetail"
-                          @follow="changeFollow"
-                          @remove="changeRemove"
-                          @delete="changeDelete"
-                          :filters="filters" ref="pushList"
-                          :showMore="false"
-                          :projectNum="projectNum"
-                          :projectAllNum="projectAllNum"
-                          :dataList="showDataList"
-                          :areaItem="areaItem"
-                          :nullProjectTips="projectTipsType"
-                          @showTips="showTips"
-                          @reloadArea="reloadArea"
-                          @reloadData="reloadData"
-                           />
+          <ProjectProgressList
+            @goDetail="goDetail"
+            @follow="changeFollow"
+            @remove="changeRemove"
+            @delete="changeDelete"
+            :filters="filters" ref="pushList"
+            :showMore="false"
+            :projectNum="projectNum"
+            :projectAllNum="projectAllNum"
+            :dataList="showDataList"
+            :areaItem="areaItem"
+            :nullProjectTips="projectTipsType"
+            @showTips="showTips"
+            @reloadArea="reloadArea"
+            @reloadData="reloadData"
+          />
         </div>
       </div>
     </forLayOut>
@@ -111,7 +119,12 @@ export default {
       areaList: [], // 筛选地区列表
       areaItem: '全国', // 选中的地区
       areaTagsList: ['全国'], // 筛选地区多选
-
+      isDistri: 0,
+      fenData: [
+        { v: 0, n: '全部' },
+        { v: 1, n: '已认领' },
+        { v: 2, n: '未认领' }
+      ],
       projectTipsType: false // 筛选内容状态,false为有内容,true为没有内容
     }
   },
@@ -125,6 +138,81 @@ export default {
     }
   },
   methods: {
+    // 认领筛选
+    changeState (item, i) {
+      this.isDistri = i
+      this.searchContent = this.inputValue
+      let thisList = []
+      let thisTitle = ''
+      let thisType = ''
+      let renType = 0
+      this.areaTagsList.forEach(itemA => {
+        if (this.areaItem !== '全国' && this.searchContent === '' && this.isDistri === 0) {
+          this.dataList.forEach(item => {
+            if (item.area === itemA) {
+              thisList.push(item)
+            }
+          })
+        } else if (this.areaItem !== '全国' && this.searchContent !== '' && this.isDistri !== 0) {
+          this.dataList.forEach(item => {
+            thisTitle = item.title
+            thisType = thisTitle.indexOf(this.searchContent)
+            renType = item.isClaim
+            if (thisType !== -1 && item.area === itemA && renType === this.isDistri) {
+              thisList.push(item)
+            }
+          })
+        } else if (this.areaItem !== '全国' && this.searchContent !== '' && this.isDistri === 0) {
+          this.dataList.forEach(item => {
+            thisTitle = item.title
+            thisType = thisTitle.indexOf(this.searchContent)
+            renType = item.isClaim
+            if (thisType !== -1 && item.area === itemA) {
+              thisList.push(item)
+            }
+          })
+        } else if (this.areaItem !== '全国' && this.searchContent === '' && this.isDistri !== 0) {
+          this.dataList.forEach(item => {
+            renType = item.isClaim
+            if (item.area === itemA && renType === this.isDistri) {
+              thisList.push(item)
+            }
+          })
+        } else if (this.areaItem === '全国' && this.searchContent === '' && this.isDistri === 0) {
+          thisList = this.dataList
+        } else if (this.areaItem === '全国' && this.searchContent === '' && this.isDistri !== 0) {
+          this.dataList.forEach(item => {
+            renType = item.isClaim
+            if (renType === this.isDistri) {
+              thisList.push(item)
+            }
+          })
+        } else if (this.areaItem === '全国' && this.searchContent !== '' && this.isDistri === 0) {
+          this.dataList.forEach(item => {
+            thisTitle = item.title
+            thisType = thisTitle.indexOf(this.searchContent)
+            if (thisType !== -1) {
+              thisList.push(item)
+            }
+          })
+        } else if (this.areaItem === '全国' && this.searchContent !== '' && this.isDistri !== 0) {
+          this.dataList.forEach(item => {
+            thisTitle = item.title
+            thisType = thisTitle.indexOf(this.searchContent)
+            renType = item.isClaim
+            if (thisType !== -1 && renType === this.isDistri) {
+              thisList.push(item)
+            }
+          })
+        }
+      })
+      this.showDataList = thisList
+      if (this.showDataList.length) {
+        this.projectTipsType = false
+      } else {
+        this.projectTipsType = true
+      }
+    },
     // 搜索输入框获取焦点
     thisFocus () {
       this.focusInput = true
@@ -435,6 +523,7 @@ export default {
   },
   computed: {
     ...mapState({
+      isNewEnt: state => state.user.isNewEnt,
       scope: state => state.user.scope,
       isDeleteAllScope: state => state.user.isDeleteAllScope
     }),
@@ -458,6 +547,7 @@ export default {
     this.changeBusiness([])
   },
   async created () {
+    this.$store.dispatch('user/getNewEnt')
     if (!this.isDeleteAllScope) {
       await this.$store.dispatch('user/getKeywordsList')
     }
@@ -511,13 +601,45 @@ export default {
         color: #fff;
         background-color: #2cb7ca;
       }
+      ::v-deep .selector-card.s-line .selector-card-header {
+        min-width: auto;
+        margin-right: 15px;
+      }
+      .select-group {
+        display: flex;
+        flex-wrap: wrap;
+        align-items: center;
+        background: #fff;
+        padding: 0 40px;
+        font-size: 14px;
+        span {
+          margin-right: 15px;
+        }
+        .j-button-item {
+          display: flex;
+          align-items: center;
+          margin: 6px 5px;
+          padding: 2px 6px;
+          line-height: 20px;
+          border-radius: 4px;
+          font-size: 14px;
+          text-align: center;
+          background-color: #fff;
+          border: 1px solid rgba(0, 0, 0, 0.05);
+          cursor: pointer;
+        }
+        .is-active {
+          background: #2CB7CA;
+          color: #fff;
+        }
+      }
     }
     .content-list-box {
       margin-top: 16px;
     }
     .top-title-box {
       padding: 40px;
-      padding-bottom: 12px;
+      padding-bottom: 24px;
       box-sizing: border-box;
       background-color: #fff;
       h4 {
@@ -549,6 +671,7 @@ export default {
   background-color: #fff;
   display: flex;
   justify-content: flex-start;
+  font-size: 14px;
 }
 .area_title {
   white-space:nowrap;
@@ -593,6 +716,7 @@ export default {
   display: flex;
   justify-content: flex-start;
   align-items: center;
+  font-size: 14px;
 }
 .search_input {
   margin-left: 20px;

+ 159 - 12
src/views/ent-intel/MyClient.vue

@@ -6,6 +6,13 @@
       <template v-slot:main>
         <div class="filter-container">
           <div class="filter-title">筛选条件</div>
+          <div class="select-group" v-if="isNewEnt.isNew">
+            <span>认领分类:</span>
+            <button v-for="(item, i) in renData" :key="999-i"
+              class="j-button-item bgc"
+              :class="{'is-active': isRen == item.v}"
+              @click="changeState(item)">{{ item.n }}</button>
+          </div>
           <div class="filter-item">
             <span class="item-label">客户名称:</span>
             <div style="display:flex;align-items: center;">
@@ -44,9 +51,21 @@
                     </div>
                   </div>
                   <div class="item-time w-100">{{item.followdate}}</div>
-                  <div class="item-handle w-100" @click="cancelFollow(item)">取消关注</div>
+                  <div class="item-handle w-100" v-if="isNewEnt.isNew">
+                    <p @click="cancelFollow(item)">取消关注</p>
+                    <div class="action-follow" @click="clickRenButton(item, index)" v-if="item.name">
+                      <span class="spa1" :class="{
+                        'el-icon-jy-renling-active': item.claim1,
+                        'el-icon-jy-renling-01': !item.claim1
+                      }"></span>
+                      <span class="text">{{ item.claim1 ? '取消认领' : '认领' }}</span>
+                    </div>
+                  </div>
+                  <div class="item-handle w-100" @click="cancelFollow(item)" v-else>取消关注</div>
                 </li>
               </ul>
+              <!-- 认领添加标签 -->
+              <v-popper ref="popperRef" @getClientList="getClientList"></v-popper>
               <div class="el-pagination-container">
                 <el-pagination
                   background
@@ -83,10 +102,11 @@
 import { Input, Button, Pagination } from 'element-ui'
 import forLayOut from '@/components/forecast/ForLayout.vue'
 import TabHeader from '@/components/common/TabHeader.vue'
+import vPopper from '@/components/common/Popper.vue'
 import Empty from '@/components/common/Empty.vue'
 import { mixinVisited } from '@/utils/mixins/visited'
 import { mapState } from 'vuex'
-import { followClientList, setStatusCustomer } from '@/api/modules'
+import { followClientList, claimchecked, custAttention, setStatusCustomer } from '@/api/modules'
 export default {
   name: 'ent-intel',
   mixins: [mixinVisited],
@@ -96,7 +116,8 @@ export default {
     [Pagination.name]: Pagination,
     forLayOut,
     TabHeader,
-    Empty
+    Empty,
+    vPopper
   },
   data () {
     return {
@@ -108,11 +129,18 @@ export default {
         list: [],
         pageSize: 10,
         pageNum: 1
-      }
+      },
+      isRen: 999,
+      renData: [
+        {v: 999, n: '全部'},
+        {v: 1, n: '已认领'},
+        {v: 0, n: '未认领'}
+      ]
     }
   },
   computed: {
     ...mapState({
+      isNewEnt: state => state.user.isNewEnt,
       power: state => state.user.power
     }),
     maxCount () {
@@ -129,19 +157,34 @@ export default {
       return this.client.list.length === 0 && !this.loading
     }
   },
-  created () {},
+  created () {
+    this.$store.dispatch('user/getNewEnt')
+  },
   mounted () {
     this.getClientList()
   },
   methods: {
     getClientList (p = 0) {
-      followClientList({
-        pagesize: 10,
-        pageno: p,
-        keyword: this.value
-      }).then(res => {
+      let obj = {}
+      if (this.isNewEnt.isNew) {
+        obj = {
+          pagesize: 10,
+          pageno: p,
+          keyword: this.value,
+          isCliam: this.isRen
+        }
+      } else {
+        obj = {
+          pagesize: 10,
+          pageno: p,
+          keyword: this.value
+        }
+      }
+      followClientList(obj).then(res => {
         if (res.error_code === 0 && res.data) {
+          const arrs = []
           res.data.list.forEach(v => {
+            arrs.push(v.name)
             if (v.followdate) {
               v.followdate = v.followdate.replace(/\//g, '-')
             }
@@ -153,13 +196,36 @@ export default {
             )
             this.$set(v, 'visited', visited)
           })
-          this.client.list = res.data.list
-          this.client.total = res.data.count
+          if (res.data.list.length === 0) {
+            this.client.list = []
+          } else {
+            this.client.followTotal = res.data.count
+            this.claimcheck(arrs.join(','), res.data.list)
+          }
           this.client.followTotal = res.data.total
         }
         this.loading = false
       })
     },
+    // 是否认领企业
+    claimcheck(name, arrs) {
+      claimchecked({
+        names: name
+      }).then(res => {
+        if (res.error_code === 0 && res.data) {
+          arrs.forEach(v => {
+            let renName = res.data.names.join(',')
+            if (renName.indexOf(v.name) > -1) {
+              v.claim1 = true
+            } else {
+              v.claim1 = false
+            }
+          })
+          this.client.list = arrs
+          this.client.total = arrs.length
+        }
+      })
+    },
     enterKeydown () {
       this.getClientList()
     },
@@ -168,6 +234,11 @@ export default {
         this.getClientList()
       }
     },
+    // 认领筛选
+    changeState (item) {
+      this.isRen = item.v
+      this.getClientList()
+    },
     // 搜索
     searchHandle () {
       this.getClientList()
@@ -207,6 +278,35 @@ export default {
         }
       })
     },
+    // 认领、取消认领
+    clickRenButton (item, index) {
+      if (item.claim1) {
+        custAttention({
+          name: item.name,
+          mold: 1,
+          D: true,
+          label: ''
+        }).then(res => {
+          if (res.error_code == 0 && res.data) {
+            this.getClientList()
+            this.$toast('取消认领成功!')
+          } else {
+            if (res.error_msg) {
+              this.$toast(res.error_msg)
+            } else {
+              this.$toast('取消认领失败!')
+            }
+          }
+        })
+      } else {
+        this.$refs.popperRef.tagsShow({
+          liHeight: 95,
+          show: true,
+          data: item.name,
+          i: index
+        })
+      }
+    },
     goFollowClient () {
       this.$router.replace('/potential_cor_list/c')
     }
@@ -215,6 +315,8 @@ export default {
 </script>
 
 <style lang="scss" scoped>
+@include diy-icon('renling-01', 20, 20);
+@include diy-icon('renling-active', 20, 20);
 .my-client{
   ::v-deep .for_main{
     margin-top: -148px;
@@ -229,6 +331,35 @@ export default {
       font-size: 18px;
       color: #1d1d1d;
     }
+    .select-group {
+      display: flex;
+      flex-wrap: wrap;
+      align-items: center;
+      background: #fff;
+      font-size: 14px;
+      span {
+        min-width: 80px;
+        margin-right: 7px;
+        text-align: right;
+      }
+      .j-button-item {
+        display: flex;
+        align-items: center;
+        margin: 6px 5px;
+        padding: 2px 6px;
+        line-height: 20px;
+        border-radius: 4px;
+        font-size: 14px;
+        text-align: center;
+        background-color: #fff;
+        border: 1px solid rgba(0, 0, 0, 0.05);
+        cursor: pointer;
+      }
+      .is-active {
+        background: #2CB7CA;
+        color: #fff;
+      }
+    }
     .filter-item{
       display: flex;
       align-items: center;
@@ -296,6 +427,9 @@ export default {
         color:#686868;
       }
     }
+    .l-tbody {
+      position: relative;
+    }
     .l-thead{
       margin-top: 26px;
       height: 48px;
@@ -350,6 +484,19 @@ export default {
       .item-handle{
         color: #2CB7CA;
         cursor: pointer;
+        .action-follow {
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          margin-top: 6px;
+          cursor: pointer;
+          .text {
+            margin-left: 4px;
+            color: #2CB7CA;
+            font-size: 14px;
+            line-height: 24px;
+          }
+        }
       }
     }
     .w-800{

+ 2 - 2
src/views/portrayal/UnitPortrayal.vue

@@ -4,7 +4,7 @@
       <div class="unit-type">
         <div class="u-top-container">
           <div class="u-name">{{ info.buyerName }}</div>
-          <div class="u-follow" @click="setFollow" v-if="conf7">
+          <div class="u-follow" @click="setFollow">
             <span :class="{ icon_heart_red: follow.followed, icon_heart_gray: !follow.followed }"></span>
             <span class="follow-text">{{ follow.followed ? '已关注' : '关注' }}</span>
           </div>
@@ -632,7 +632,7 @@ export default {
           } else {
             // 关注操作返回
             this.follow.followed = true
-            this.$toast(res.error_msg || '关注成功,可前往“我关注的客户”中查看')
+            this.$toast(res.error_msg || '关注成功,可前往“客户监控”中查看')
           }
         } else {
           this.$toast(res.error_msg)

+ 45 - 9
src/views/project/ProjectInfo.vue

@@ -60,6 +60,8 @@
           </div>
         </el-card>
       </div>
+      <!-- 暂无权限弹窗 -->
+      <no-pass ref="passRef"></no-pass>
     </div>
   </ContentLayout>
 </template>
@@ -67,9 +69,11 @@
 <script>
 import { Card, Button, Link } from 'element-ui'
 import ContentLayout from '@/components/common/ContentLayout.vue'
+import noPass from '@/components/common/noPass.vue'
 import TimeLine from '@/components/time-line/TimeLine.vue'
 import { getFollowProjectDetail, followProjectAdd, followProjectCancel, getProjectReport } from '@/api/modules/'
 import { replaceKeyword, dateFormatter } from '@/utils'
+import { powerCheck } from '@/utils/bigmember/'
 import { mapState } from 'vuex'
 
 export default {
@@ -79,7 +83,8 @@ export default {
     [Button.name]: Button,
     [Link.name]: Link,
     ContentLayout,
-    TimeLine
+    TimeLine,
+    noPass
   },
   data () {
     return {
@@ -241,18 +246,49 @@ export default {
       this.showAction = !r
     },
     toForecast () {
-      const { sid, fid } = this
-      this.$router.push({
+      const to = {
         path: '/ai_add',
-        query: {
-          pid: fid,
-          sid: sid
+        name: 'ai_add'
+      }
+      const { pass, anchor } = powerCheck(this.info, this.power, to)
+      if (pass) {
+        const { sid, fid } = this
+        this.$router.push({
+          path: '/ai_add',
+          query: {
+            pid: fid,
+            sid: sid
+          }
+        })
+      } else {
+        if (anchor && this.info.memberStatus > 0) {
+          this.$refs.passRef.passVisible = true
+        } else {
+          location.href = '/big/page/zb'
         }
-      })
+      }
     },
     toPolicy () {
-      const { sid } = this
-      this.$router.push(`/analysis_result?sid=${sid}`)
+      const to = {
+        path: '/analysis_result',
+        name: 'analysis_result'
+      }
+      const { pass, anchor } = powerCheck(this.info, this.power, to)
+      if (pass) {
+        const { sid } = this
+        this.$router.push({
+          path: '/analysis_result',
+          query: {
+            sid: sid
+          }
+        })
+      } else {
+        if (anchor && this.info.memberStatus > 0) {
+          this.$refs.passRef.passVisible = true
+        } else {
+          location.href = '/big/page/tb'
+        }
+      }
     },
     toUnitportrayal () {
       const { buyer } = this.projectInfo

+ 1 - 1
src/views/work-desktop/WorkDesktop.vue

@@ -521,7 +521,7 @@ export default {
           if (!(res && res.error_code === 0 && res.data)) {
             this.$toast(res.error_msg)
           } else {
-            this.$toast('关注成功,可前往“我关注的客户”中查看')
+            this.$toast('关注成功,可前往“客户监控”中查看')
           }
           this.initPotenPerList()
           this.$forceUpdate()

+ 6 - 0
vue.config.js

@@ -70,6 +70,12 @@ module.exports = {
         // target: 'http://127.0.0.1:829',
         changeOrigin: true,
         logLevel: 'debug'
+      },
+      '^/entnicheNew': {
+        target: 'https://jybx2-webtest.jydev.jianyu360.com',
+        // target: 'http://127.0.0.1:829',
+        changeOrigin: true,
+        logLevel: 'debug'
       }
     },
     headers: {