瀏覽代碼

Merge branch 'main' into feature/v1.0.45

123456 1 年之前
父節點
當前提交
cfae6357d3
共有 32 個文件被更改,包括 527 次插入107 次删除
  1. 17 0
      apps/bigmember_pc/src/api/modules/common.js
  2. 1 0
      apps/bigmember_pc/src/api/modules/index.js
  3. 1 0
      apps/bigmember_pc/src/components/subscribe-manager/KeyConfig.vue
  4. 20 2
      apps/bigmember_pc/src/views/medical-field/Credentials.vue
  5. 36 17
      apps/bigmember_pc/src/views/portrayal/components/DataExportTip.vue
  6. 4 2
      apps/bigmember_pc/src/views/search/bidding/model/base.js
  7. 0 1
      apps/bigmember_pc/src/views/search/components/search-schema-filter.vue
  8. 1 1
      apps/bigmember_pc/vite.config.js
  9. 16 0
      apps/mobile/src/api/modules/user.js
  10. 二進制
      apps/mobile/src/assets/image/icon/kf-blue.png
  11. 7 2
      apps/mobile/src/components/ad/Side.vue
  12. 64 0
      apps/mobile/src/components/customer/index.vue
  13. 16 25
      apps/mobile/src/components/dataExport/popupDataexport.vue
  14. 1 0
      apps/mobile/src/components/home/list.vue
  15. 11 5
      apps/mobile/src/views/article/content.vue
  16. 18 3
      apps/mobile/src/views/create-order/CreateOrderLayout.vue
  17. 17 22
      apps/mobile/src/views/dataexport/LimitPreviewData.vue
  18. 8 2
      apps/mobile/src/views/search/result/bidding/index.vue
  19. 13 4
      apps/mobile/src/views/tabbar/Home.vue
  20. 8 2
      apps/mobile/src/views/tabbar/Subscribe.vue
  21. 13 1
      apps/work-bench/src/App.vue
  22. 15 0
      apps/work-bench/src/api/modules/user.js
  23. 二進制
      apps/work-bench/src/assets/img/icon/dianhua.png
  24. 二進制
      apps/work-bench/src/assets/img/icon/help.png
  25. 二進制
      apps/work-bench/src/assets/img/icon/kefu.png
  26. 二進制
      apps/work-bench/src/assets/img/icon/qiwei.png
  27. 二進制
      apps/work-bench/src/assets/img/icon/wenhao.png
  28. 3 0
      apps/work-bench/src/brace/index.js
  29. 219 0
      apps/work-bench/src/components/CustomServiceCorner.vue
  30. 3 0
      apps/work-bench/src/store/modules/customer.js
  31. 15 15
      apps/work-bench/src/store/modules/work-bench.js
  32. 0 3
      packages/work-bench-frame/packages/layout/work-bench/index.vue

+ 17 - 0
apps/bigmember_pc/src/api/modules/common.js

@@ -0,0 +1,17 @@
+import request from '@/api'
+import qs from 'qs'
+
+/**
+ * 获取客服二维码
+ * @param data { type: "kf" } 只获取客服的二维码,
+ * 不传参根据用户权限判断是否返回客成二维码
+ * @returns {*}
+ */
+export function getCustomInfo (data) {
+  data = qs.stringify(data)
+  return request({
+    url: '/bigmember/use/getCustom',
+    method: 'POST',
+    data
+  })
+}

+ 1 - 0
apps/bigmember_pc/src/api/modules/index.js

@@ -32,3 +32,4 @@ export * from './business'
 export * from './docs'
 export * from './search'
 export * from './nzj'
+export * from './common'

+ 1 - 0
apps/bigmember_pc/src/components/subscribe-manager/KeyConfig.vue

@@ -199,6 +199,7 @@ export default {
       height: 18px;
       margin: 0 7px 0 8px;
       cursor: pointer;
+      background:none;
     }
     .add-classify {
       width: 110px;

+ 20 - 2
apps/bigmember_pc/src/views/medical-field/Credentials.vue

@@ -26,7 +26,7 @@
               <p class="cred_desc">方式1:扫描二维码获得专属客户服务</p>
               <div class="qr_box">
                 <img
-                  src="@/assets/images/medical-field/qrcode-814.png"
+                  :src="kefuInfo.wxer"
                   alt=""
                   class="qr_img"
                 />
@@ -233,6 +233,8 @@ import {
   domainUsersave
 } from '@/api/modules/medicalField.js'
 import informationSuccess from '@/components/common/informationSuccess.vue'
+import { getCustomInfo } from '@/api/modules/'
+import qrCode from '@/assets/images/medical-field/qrcode-814.png'
 export default {
   name: 'Credentials',
   components: {
@@ -358,10 +360,14 @@ export default {
       jobData: [], // 职位数据
       branchData: [], // 部门数据
       source: 'Credentials',
-      list_choose: false
+      list_choose: false,
+      kefuInfo: {
+        wxer: qrCode
+      }
     }
   },
   created() {
+    this.getKefuInfo()
     this.getAllFunctions({ vm: this })
     this.jobData = jobJson.map((item) => {
       return {
@@ -593,6 +599,18 @@ export default {
     },
     otherFocus() {
       this.$refs.ruleForm.clearValidate(['job'])
+    },
+    // 获取客服二维码信息
+    getKefuInfo () {
+      const params = {
+        type: 'kf'
+      }
+      getCustomInfo(params).then(res => {
+        const { error_code: code, data } = res
+        if(code === 0 && data) {
+          this.kefuInfo = Object.assign(this.kefuInfo, data)
+        }
+      })
     }
   }
 }

+ 36 - 17
apps/bigmember_pc/src/views/portrayal/components/DataExportTip.vue

@@ -12,7 +12,7 @@
         进行定制化导出
       </p>
       <div class="export-dialog-wx">
-        <img :src="getWxCustom" alt="" />
+        <img :src="kefuInfo.wxer" alt="" />
       </div>
       <p class="wx-code-label">客服微信</p>
       <el-button @click="$emit('setExport')" class="export-continue-btn"
@@ -27,7 +27,8 @@
 
 <script>
 import { Button, Checkbox } from 'element-ui'
-import { mapState } from 'vuex'
+// import { mapState } from 'vuex'
+import { getCustomInfo } from '@/api/modules/'
 export default {
   name: 'export-dialog-container',
   components: {
@@ -36,30 +37,48 @@ export default {
   },
   data() {
     return {
-      agreement: false
+      agreement: false,
+      kefuInfo: {}
     }
   },
+  created () {
+    this.getKefuInfo()
+  },
   watch: {
     agreement(newval) {
       this.$emit('checkBoxChange', newval)
     }
   },
   computed: {
-    ...mapState({
-      info: (state) => state.user.info
-    }),
-    getWxCustom() {
-      const customers = this.info.customers
-      if (customers && customers.length > 0) {
-        const getWxCode = customers.filter((v) => v.name === '高静')
-        if (getWxCode && getWxCode.length > 0) {
-          return getWxCode[0].wxer
-        } else {
-          return ''
-        }
-      } else {
-        return ''
+    // ...mapState({
+    //   info: (state) => state.user.info
+    // }),
+    // getWxCustom() {
+    //   const customers = this.info.customers
+    //   if (customers && customers.length > 0) {
+    //     const getWxCode = customers.filter((v) => v.name === '高静')
+    //     if (getWxCode && getWxCode.length > 0) {
+    //       return getWxCode[0].wxer
+    //     } else {
+    //       return ''
+    //     }
+    //   } else {
+    //     return ''
+    //   }
+    // }
+  },
+  methods: {
+    // 获取客服二维码信息
+    getKefuInfo () {
+      const params = {
+        type: 'kf'
       }
+      getCustomInfo(params).then(res => {
+        const { error_code: code, data } = res
+        if(code === 0 && data) {
+          this.kefuInfo = data
+        }
+      })
     }
   }
 }

+ 4 - 2
apps/bigmember_pc/src/views/search/bidding/model/base.js

@@ -1354,9 +1354,9 @@ export default function () {
 
         // 获取已存筛选条件的列表
         getFilterHistoryList(null,function (arr) {
-          if(isVip.value) {
+          if(isVip.value && !jParams) {
             // 付费用户,优先恢复本地缓存,本地无缓存,则恢复已存筛选第一条数据
-            if(!jParams && Array.isArray(arr) && arr.length > 0){
+            if(Array.isArray(arr) && arr.length > 0) {
               const expandFilter = {}
               if(urlSelectType) {
                 expandFilter.selectType = urlSelectType.split(',')
@@ -1365,6 +1365,8 @@ export default function () {
                 expandFilter.input = urlKeywords
               }
               restoreFilter(arr[0], 'saveBack', expandFilter)
+            } else {
+              firstSearch()
             }
           }
         })

+ 0 - 1
apps/bigmember_pc/src/views/search/components/search-schema-filter.vue

@@ -106,7 +106,6 @@ const getPrefix = {
   &.use-style-col {
     .search-schema-filter-item {
       display: flex;
-      align-items: start;
       & + .search-schema-filter-item {
         margin-top: 16px;
       }

+ 1 - 1
apps/bigmember_pc/vite.config.js

@@ -137,7 +137,7 @@ export default defineConfig({
   },
   server: {
     port: 8081,
-    proxy: useServerProxy('web'),
+    proxy: useServerProxy('web2'),
     host: '0.0.0.0'
   }
 })

+ 16 - 0
apps/mobile/src/api/modules/user.js

@@ -1,4 +1,5 @@
 import request from '@/api'
+import qs from 'qs'
 
 export function ajaxSetLogin(data) {
   return request({
@@ -7,3 +8,18 @@ export function ajaxSetLogin(data) {
     data
   })
 }
+
+/**
+ * 获取客服二维码
+ * @param data { type: "kf" } 只获取客服的二维码,
+ * 不传参根据用户权限判断是否返回客成二维码
+ * @returns {*}
+ */
+export function getCustomInfo (data) {
+  data = qs.stringify(data)
+  return request({
+    url: '/bigmember/use/getCustom',
+    method: 'POST',
+    data
+  })
+}

二進制
apps/mobile/src/assets/image/icon/kf-blue.png


+ 7 - 2
apps/mobile/src/components/ad/Side.vue

@@ -27,6 +27,10 @@ export default {
       type: Boolean,
       default: false
     },
+    bottomPosition: {
+      type: String,
+      default: ''
+    },
     config: {
       type: Object,
       default() {
@@ -56,7 +60,8 @@ export default {
           : '',
         height: this.config?.extend?.height
           ? px2viewport(this.config?.extend?.height)
-          : ''
+          : '',
+        bottom: this.bottomPosition || ''
       }
     }
   },
@@ -85,7 +90,7 @@ export default {
   position: fixed;
   z-index: 1;
   right: 0;
-  bottom: 15%;
+  bottom: 22%;
   transition: all 0.2s;
   &.van-image {
     max-width: 88px;

+ 64 - 0
apps/mobile/src/components/customer/index.vue

@@ -0,0 +1,64 @@
+<template>
+  <div class="customer-corner" :class="{ fadeOutRight: !scrollStatus }" :style="{bottom: bottomPosition || ''}">
+    <div class="content" @click="jumpCustomerPage">
+      <img src="@/assets/image/icon/kf-blue.png" alt="">
+      <p>客服</p>
+    </div>
+  </div>
+</template>
+
+<script>
+ export default {
+   props: {
+     scrollStatus: {
+       type: Boolean,
+       default: false
+     },
+     bottomPosition: {
+       type: String,
+       default: ''
+     }
+   },
+   data () {
+     return {
+       show: false
+     }
+   },
+   created () {},
+   methods: {
+     jumpCustomerPage () {
+       location.href = `/jyapp/free/customer`
+     }
+   }
+ }
+</script>
+
+<style lang="scss" scoped>
+  .customer-corner{
+    position: fixed;
+    padding-top:4px;
+    width: 42px;
+    height: 42px;
+    bottom: 16%;
+    right: 12px;
+    background: #fff;
+    border-radius: 50%;
+    z-index: 99;
+    box-shadow: 0 0 16px rgba(0,0,0,0.16);
+    font-size: 9px;
+    line-height: 10px;
+    color: #2ABED1;
+    &.fadeOutRight {
+      transform: translateX(98%);
+      opacity: 0.2;
+    }
+    .content{
+      height:100%;
+      text-align: center;
+    }
+    img{
+      width: 24px;
+      height: 24px;
+    }
+  }
+</style>

+ 16 - 25
apps/mobile/src/components/dataExport/popupDataexport.vue

@@ -13,7 +13,7 @@
             >,或添加<span class="blue">客服微信</span>进行定制化导出。
           </div>
           <div class="qr_box">
-            <img :src="img" alt="" />
+            <img :src="kefuInfo.wxer" alt="" />
           </div>
           <div class="desc">客服微信</div>
           <div class="btn_box">
@@ -35,25 +35,23 @@
 </template>
 <script>
 import { Popup } from 'vant'
-import { mapState, mapActions } from 'vuex'
 import { callPhone } from '@/utils/callFn'
 import { debounce } from 'lodash'
-import { setDontPromptAgain, getDontPromptAgain } from '@/api/modules'
+import { setDontPromptAgain, getDontPromptAgain, getCustomInfo } from '@/api/modules'
 export default {
   name: 'popupDataexport',
   components: {
     [Popup.name]: Popup
   },
   props: {},
-  computed: {
-    ...mapState('user', ['power'])
-  },
+  computed: {},
   data() {
     return {
       show: false,
       choose: false,
       img: '',
-      isPrompt: true
+      isPrompt: true,
+      kefuInfo: {}
     }
   },
   created() {
@@ -65,10 +63,9 @@ export default {
     })
   },
   mounted() {
-    this.getQRimg()
+    this.getKefuInfo()
   },
   methods: {
-    ...mapActions('user', ['getPower']),
     btnClick() {
       this.choose = !this.choose
       this.setDontPrompt()
@@ -92,23 +89,17 @@ export default {
     next() {
       this.$emit('next', { choose: this.choose })
     },
-    async getQRimg() {
-      if (this.power) {
-        if (this.power.customers && this.power.customers.length > 0) {
-          let customer = this.power.customers
-          customer.forEach((e) => {
-            if (e.remark === '客户经理') {
-              this.img = e.wxer
-            }
-          })
-          if (this.img == '') {
-            this.img = customer[0].wxer
-          }
-        }
-      } else {
-        await this.getPower()
-        this.getQRimg()
+    // 获取客服二维码信息
+    getKefuInfo () {
+      const params = {
+        type: 'kf'
       }
+      getCustomInfo(params).then(res => {
+        const { error_code: code, data } = res
+        if(code === 0 && data) {
+          this.kefuInfo = data
+        }
+      })
     }
   }
 }

+ 1 - 0
apps/mobile/src/components/home/list.vue

@@ -528,6 +528,7 @@ export default {
           } = data || {}
 
           this.showTip = data.showTip
+          this.$emit('bottomSetTip', data.showTip === 2)
           this.info.vSwitch = data.subFlag
           this.info.hasSubscribe = hasSubKeys
           this.info.hasHistory = hasHistory

+ 11 - 5
apps/mobile/src/views/article/content.vue

@@ -118,6 +118,8 @@
         </div>
       </div>
     </van-skeleton>
+    <!--    客服-->
+    <customer-corner v-if="isLogin"  :scroll-status="scrollStatus" bottom-position="12%"/>
     <ThirdPartyVerifyPopup
       v-model="popup.thirdPartyVerify"
       :beforeLeavePage="beforeLeavePage"
@@ -166,6 +168,7 @@ import FreeUserBiddingMask from '@/views/article/components/FreeUserBiddingMask.
 import FreeUserAdvancedMask from '@/views/article/components/FreeUserAdvancedMask.vue'
 import ThirdPartyVerifyPopup from '@/views/article/components/ThirdPartyVerifyPopup.vue'
 import CheckUserDialog from '@/views/identity/components/CheckUserDialog'
+import CustomerCorner from '@/components/customer/index'
 import { throttle } from 'lodash'
 import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
 import { getArticleShareInfo, getContentShareEncrypt } from '@/api/modules/article'
@@ -197,7 +200,8 @@ export default {
     CheckUserDialog,
     NpsCard,
     TabActions,
-    AdSingle
+    AdSingle,
+    CustomerCorner
   },
   data() {
     return {
@@ -266,7 +270,8 @@ export default {
       pageState: {
         id: '',
         tabActive: ''
-      }
+      },
+      scrollStatus: true
     }
   },
   computed: {
@@ -588,8 +593,8 @@ export default {
         link += `openid=${openid}&`
       }
       link += 'source=wx_infocontentshare'
-      
-      
+
+
       this.shareConf.title = title
       this.shareConf.content = content
       this.shareConf.link = link
@@ -640,9 +645,10 @@ export default {
       // this.shareConf.link = link
       this.refreshShareLink()
     },
-    onScroll: throttle(function () {
+    onScroll: throttle(function (e) {
       this.checkNpsView()
       this.saveScrollTop()
+      this.scrollStatus = e.target.scrollTop < 60
     }, 300),
     saveScrollTop() {
       const scrollWrapper = this.$refs.scrollWrapper

+ 18 - 3
apps/mobile/src/views/create-order/CreateOrderLayout.vue

@@ -7,7 +7,7 @@
         v-if="pageLayout.header"
       ></router-view>
     </div>
-    <div class="j-main create-order-content">
+    <div class="j-main create-order-content" @scroll="onScroll">
       <router-view name="default" class="create-order-default"></router-view>
       <router-view
         name="activity"
@@ -32,19 +32,31 @@
         :key="productId"
       ></router-view>
     </div>
+    <customer-corner v-show="showCustomer" :scroll-status="scrollTop < 60" bottom-position="18%"></customer-corner>
   </div>
 </template>
 <script>
 import { mapGetters, mapActions, mapMutations } from 'vuex'
 import { openAppOrWxPage } from '@/utils'
+import CustomerCorner from '@/components/customer/index'
 export default {
   name: 'CreateOrderLayout',
+  components: {
+    CustomerCorner
+  },
   computed: {
-    ...mapGetters('createOrder', ['productId', 'pageLayout', 'loadingStatus'])
+    ...mapGetters('createOrder', ['productId', 'pageLayout', 'loadingStatus']),
+    ...mapGetters('user', [
+      'isLogin'
+    ]),
+    showCustomer () {
+      return this.$route.path.indexOf('dataexport') > -1 && this.isLogin
+    }
   },
   data() {
     return {
-      loading: null
+      loading: null,
+      scrollTop: 0
     }
   },
   watch: {
@@ -94,6 +106,9 @@ export default {
         type: 'replace',
         query
       })
+    },
+    onScroll (e) {
+      this.scrollTop = e.target.scrollTop
     }
   }
 }

+ 17 - 22
apps/mobile/src/views/dataexport/LimitPreviewData.vue

@@ -243,8 +243,8 @@
               >客服微信</span
             >
           </div>
-          <div class="qr-box">
-            <img :src="img" alt="" class="qr" />
+          <div class="qr-box" v-if="kefuInfo.wxer">
+            <img :src="kefuInfo.wxer" alt="" class="qr" />
           </div>
           <p class="text">微信扫一扫</p>
         </div>
@@ -255,11 +255,10 @@
 </template>
 <script>
 import { Tab, Tabs, Overlay, Icon } from 'vant'
-import { mapState } from 'vuex'
 import Progress from '@/views/order/components/dataexport/DataExportProgress'
 import QuestionTip from '@/views/order/components/datapack/QuestionTip'
 import { AppEmpty } from '@/ui'
-import { getPreview } from '@/api/modules'
+import { getPreview, getCustomInfo } from '@/api/modules'
 import html2canvas from 'html2canvas'
 export default {
   name: 'limit-previewData',
@@ -286,7 +285,8 @@ export default {
     isWxFixed: false,
     exportInfo: {
       step: 1
-    }
+    },
+    kefuInfo: {}
   }),
   created() {
     if (this.$route.query.type === 'senior') {
@@ -301,7 +301,7 @@ export default {
   mounted() {
     this.getStickyOffset()
     window.addEventListener('scroll', this.getScroll, true)
-    this.getQRimg()
+    this.getKefuInfo()
   },
   watch: {
     isFixed(newval, oldval) {
@@ -312,25 +312,20 @@ export default {
       }
     }
   },
-  computed: {
-    ...mapState('user', ['power'])
-  },
+  computed: {},
 
   methods: {
-    getQRimg() {
-      if (this.power) {
-        if (this.power.customers && this.power.customers.length > 0) {
-          let customer = this.power.customers
-          customer.forEach((e) => {
-            if (e.remark === '客户经理') {
-              this.img = e.wxer
-            }
-          })
-          if (this.img == '') {
-            this.img = customer[0].wxer
-          }
-        }
+    // 获取客服二维码信息
+    getKefuInfo () {
+      const params = {
+        type: 'kf'
       }
+      getCustomInfo(params).then(res => {
+        const { error_code: code, data } = res
+        if(code === 0 && data) {
+          this.kefuInfo = data
+        }
+      })
     },
     // 监听滚动
     getScroll() {

+ 8 - 2
apps/mobile/src/views/search/result/bidding/index.vue

@@ -394,6 +394,8 @@
         <div class="right action clickable" @click="toSubThisKey">直接订阅</div>
       </div>
     </div>
+    <!--    客服-->
+    <customer-corner v-show="isLogin"  :scroll-status="scrollStatus" bottom-position="12%"/>
     <SearchFilterHistoryDialog
       v-model="pageState.saveFilterDialog"
       :beforeClose="beforeFilterHistoryDialogClose"
@@ -422,6 +424,7 @@ import SearchFilterHistoryDialog from '@/components/search/bidding/filterHistory
 import OneKeySubscribeDialog from '@/components/search/bidding/oneKeySubscribeDialog'
 import RecommendCard from '@/components/recommend/'
 import popupDataexport from '@/components/dataExport/popupDataexport.vue'
+import CustomerCorner from '@/components/customer/index'
 import { AppIcon, AppEmpty, ProjectCell } from '@/ui'
 import { setUserSubInfo, getFreeSubscribeInfo } from '@/api/modules/public'
 import { leadGetDate } from '@/api/modules/leadGeneration'
@@ -484,7 +487,8 @@ export default {
     AdSingle,
     RecommendCard,
     bidStatusNode,
-    popupDataexport
+    popupDataexport,
+    CustomerCorner
   },
   inject: {
     topSearch: {
@@ -680,7 +684,8 @@ export default {
       toggleSearchBlurData: {
         show: false,
         count: ''
-      }
+      },
+      scrollStatus: true
     }
   },
   computed: {
@@ -2537,6 +2542,7 @@ export default {
       } else {
         this.pageState.tabSwitchShow = true
       }
+      this.scrollStatus = scrollTop < 60
     },
     // 定制化分析报告&&超前项目推荐数据请求
     async getCustomReportData(keyWords) {

+ 13 - 4
apps/mobile/src/views/tabbar/Home.vue

@@ -4,7 +4,7 @@
     @scroll="onScroll"
     @click.capture="doSave"
     ref="home-page"
-    :class="{ 'app-header-top': appHeaderTop }"
+    :class="{ 'app-header-top': appHeaderTop}"
   >
     <!-- 头部广告位 -->
     <div class="header-exposure" v-if="isLogin"></div>
@@ -46,10 +46,12 @@
       <!-- 消息 -->
       <message-card></message-card>
       <!-- 最新标讯 -->
-      <home-list ref="list"></home-list>
+      <home-list ref="list" @bottomSetTip="bottomSetTip"></home-list>
     </div>
     <!-- 侧边广告位 -->
-    <ad-side :config="AD.side" :scroll-status="sideStatus"></ad-side>
+    <ad-side :config="AD.side" :scroll-status="sideStatus" :bottom-position="hasBottomSetTip ? '22%' :'18%'"></ad-side>
+    <!--客服-->
+    <customer-corner v-show="isLogin" :scroll-status="sideStatus" :bottom-position="hasBottomSetTip ? '16%' :'12%'"/>
     <!-- 弹窗广告位 -->
     <AdPopScreen
       v-if="AD.full.pic"
@@ -92,6 +94,7 @@ import {
   ajaxSetNewUserADRead
 } from '@/api/modules'
 import MessageCard from '@/components/message/message-card'
+import CustomerCorner from '@/components/customer/index'
 import { adConfigFormatter } from '@/utils/format/modules/ad-formatter'
 import CheckUserDialog from '@/views/identity/components/CheckUserDialog'
 import {
@@ -125,6 +128,7 @@ export default {
     Swipe,
     SwipeFloor,
     CheckUserDialog,
+    CustomerCorner,
     [Side.name]: Side,
     [Button.name]: Button,
     [Cell.name]: Cell,
@@ -186,7 +190,8 @@ export default {
     newUserPopConfig: {
       showNextFullPop: false,
       showBottomPop: false
-    }
+    },
+    hasBottomSetTip: false
   }),
   computed: {
     ...mapGetters('user', ['isLogin']),
@@ -591,6 +596,10 @@ export default {
       } catch (e) {
         console.warn(e)
       }
+    },
+    // 有无订阅关键词设置提示,影响侧边广告、客服距离底部高度
+    bottomSetTip (show) {
+      this.hasBottomSetTip = show
     }
   }
 }

+ 8 - 2
apps/mobile/src/views/tabbar/Subscribe.vue

@@ -465,6 +465,8 @@
         >您未设置关键词,设置后接收信息更精准!
       </NoticeBar>
     </footer>
+    <!--    客服-->
+    <customer-corner v-show="isLogin"  :scroll-status="scrollStatus" bottom-position="12%"/>
     <DataReportTip
       v-model="dataReport.tip"
       :vSwitch="vSwitch"
@@ -502,6 +504,7 @@ import RecommendCard from '@/components/recommend/'
 import Ad from '@/components/ad/Ad'
 import popupDataexport from '@/components/dataExport/popupDataexport.vue'
 import CheckUserDialog from '@/views/identity/components/CheckUserDialog'
+import CustomerCorner from '@/components/customer/index'
 import { LINKS, vtMap, AdCode } from '@/data'
 import { wxShareMixin } from '@/utils/mixins/modules/wx-share'
 import { iosBackRefresh } from '@/utils/utils'
@@ -573,7 +576,8 @@ export default {
     RecommendCard,
     bidStatusNode,
     popupDataexport,
-    AreaThreeSidebar
+    AreaThreeSidebar,
+    CustomerCorner
   },
   data() {
     return {
@@ -811,7 +815,8 @@ export default {
       popupHeight: 'height: 440px',
       projectCellInfo: {},
       mergedKeywords: [],
-      alreadyLeave: false // 免费用户是否已经留资. true为已留资,false为未留资或者留资信息不全
+      alreadyLeave: false, // 免费用户是否已经留资. true为已留资,false为未留资或者留资信息不全
+      scrollStatus: true
     }
   },
   provide() {
@@ -2643,6 +2648,7 @@ export default {
       } else {
         this.pageState.tabSwitchShow = true
       }
+      this.scrollStatus = scrollTop < 60
     },
     appTabShow() {
       // app端绑定touchstart事件显示底部菜单

+ 13 - 1
apps/work-bench/src/App.vue

@@ -2,17 +2,29 @@
   <router-view>
     <template v-slot:nav-user-info="{ info }">
       <nav-user-info :info="info"></nav-user-info>
+      <custom-service-corner ></custom-service-corner>
     </template>
   </router-view>
 </template>
 
 <script>
 import NavUserInfo from '@/components/NavUserInfo'
+import CustomServiceCorner from '@/components/CustomServiceCorner.vue'
+import { mapActions } from 'vuex'
 
 export default {
   name: 'App',
   components: {
-    NavUserInfo
+    NavUserInfo,
+    CustomServiceCorner
+  },
+  computed: {},
+  created () {
+    // 获取客服信息
+    this.getCustomerInfo()
+  },
+  methods: {
+    ...mapActions('work-bench', ['getCustomerInfo'])
   }
 }
 </script>

+ 15 - 0
apps/work-bench/src/api/modules/user.js

@@ -51,3 +51,18 @@ export function ajaxSwitchUserIdentity (data) {
     data
   })
 }
+
+/**
+ * 获取客服二维码
+ * @param data { type: "kf" } 只获取客服的二维码,
+ * 不传参根据用户权限判断是否返回客成二维码
+ * @returns {*}
+ */
+export function getCustomInfo (data) {
+  data = qs.stringify(data)
+  return request({
+    url: '/bigmember/use/getCustom',
+    method: 'POST',
+    data
+  })
+}

二進制
apps/work-bench/src/assets/img/icon/dianhua.png


二進制
apps/work-bench/src/assets/img/icon/help.png


二進制
apps/work-bench/src/assets/img/icon/kefu.png


二進制
apps/work-bench/src/assets/img/icon/qiwei.png


二進制
apps/work-bench/src/assets/img/icon/wenhao.png


+ 3 - 0
apps/work-bench/src/brace/index.js

@@ -35,6 +35,9 @@ Vue.prototype.$BRACE.$on('click-dialog-customer', () => {
 Vue.prototype.$BRACE.$on('open-customer', () => {
   store.dispatch('customer/open')
 })
+Vue.prototype.$BRACE.$on('close-customer', () => {
+  store.dispatch('customer/close')
+})
 /**
  * 监听菜单匹配事件、统一处理外部链接
  */

+ 219 - 0
apps/work-bench/src/components/CustomServiceCorner.vue

@@ -0,0 +1,219 @@
+<!--桌面右下角客服-->
+<template>
+  <div class="custom-service-corner">
+    <el-popover
+      ref="customServiceCorner"
+      placement="left-end"
+      width="132"
+      trigger="click"
+      :visible-arrow="false"
+      @show="onShowPopover"
+      popper-class="custom-popover-menu">
+      <div class="self-card">
+        <div class="self-row" @click="onClickCustomer">
+          <img src="@/assets/img/icon/kefu.png" alt="">
+          <span>在线客服</span>
+        </div>
+        <el-tooltip
+          trigger="click"
+          placement="left"
+          effect="light"
+          :visible-arrow="false"
+          popper-class="kf-phone-tooltip"
+        >
+          <div slot="content" class="kf-phone">客服热线:400-108-6670<br>服务时间:工作日 9:00-17:40</div>
+          <div class="self-row">
+            <img src="@/assets/img/icon/dianhua.png" alt="">
+            <span>客服热线</span>
+          </div>
+        </el-tooltip>
+
+        <el-tooltip
+          trigger="click"
+          placement="left"
+          effect="light"
+          :visible-arrow="false"
+          popper-class="qw-qrcode-tooltip"
+          v-if="hasExclusiveCustomer"
+        >
+          <div slot="content" class="qw-qrcode">
+            <img :src="exclusiveCustomerInfo.qrcode" alt="">
+            <p class="text">微信扫一扫</p>
+          </div>
+          <div class="self-row">
+            <img src="@/assets/img/icon/qiwei.png" alt="">
+            <span>客服企微</span>
+          </div>
+        </el-tooltip>
+        <div class="self-row" v-else>
+          <img src="@/assets/img/icon/qiwei.png" alt="">
+          <span>客服企微</span>
+        </div>
+        <div class="self-row" @click="jumpHelpPage">
+          <img src="@/assets/img/icon/help.png" alt="">
+          <span>帮助中心</span>
+        </div>
+      </div>
+      <div class="custom-btn" slot="reference">
+        <img src="@/assets/img/icon/wenhao.png" alt="">
+      </div>
+    </el-popover>
+  </div>
+</template>
+<script>
+import { Popover } from 'element-ui'
+import { mapGetters } from 'vuex'
+export default {
+  components: {
+    [Popover.name]: Popover
+  },
+  data () {
+    return {
+    }
+  },
+  computed: {
+    ...mapGetters('work-bench/user', [
+      'hasExclusiveCustomer',
+      'exclusiveCustomerInfo'
+    ])
+  },
+  created () {},
+  methods: {
+    // 显示的时候触发
+    onShowPopover () {
+      this.$BRACE.$emit('close-customer')
+    },
+    // 在线客服
+    onClickCustomer () {
+      try {
+        this.$BRACE.$emit('open-customer')
+        if (this.$refs.customServiceCorner) {
+          this.$refs.customServiceCorner.doClose()
+        }
+      } catch (e) {
+      }
+    },
+    // 跳转到帮助中心
+    jumpHelpPage () {
+      if (this.$refs.customServiceCorner) {
+        this.$refs.customServiceCorner.doClose()
+      }
+      window.open('/helpCenter/index', '_blank')
+    }
+  }
+}
+</script>
+<style lang="scss">
+  .custom-popover-menu.el-popover{
+    box-sizing: border-box;
+    width: 132px;
+    min-width:132px;
+    height: 168px;
+    background: #fff;
+    border: none;
+    box-shadow: 0 0 16px rgba(0,0,0,0.16);
+    border-radius: 8px;
+    padding: 8px;
+    .self-card{
+      color: #1d1d1d;
+      font-size:14px;
+      line-height: 22px;
+      .self-row{
+        display: flex;
+        align-items: center;
+        height:38px;
+        padding-left:8px;
+        cursor: pointer;
+        border-radius: 4px;
+        &:hover{
+          background: #EAF8FA;
+        }
+        img {
+          width:20px;
+          height:20px;
+          margin-right:8px;
+        }
+      }
+    }
+  }
+  .kf-phone-tooltip.el-tooltip__popper.is-light{
+    border: 2px solid #FFFFFF;
+    box-shadow: 0px 0px 20px rgba(8, 31, 38, 0.12);
+    font-size: 14px;
+    line-height: 22px;
+    left: -240px;
+    color: #1D1D1D;
+    padding: 12px 20px;
+    border-radius: 8px;
+    box-sizing: border-box;
+  }
+  .qw-qrcode-tooltip.el-tooltip__popper.is-light{
+    border:none;
+    width:144px;
+    height: 154px;
+    border-radius: 8px;
+    padding: 12px 20px;
+    box-shadow: 0px 0px 20px rgba(8, 31, 38, 0.12);
+    img{
+      width: 104px;
+      height: 104px;
+    }
+    .text{
+      text-align: center;
+      font-size:14px;
+      line-height: 22px;
+    }
+  }
+</style>
+<style lang="scss" scoped>
+.custom-service-corner{
+  .custom-btn{
+    position: fixed;
+    bottom: 50px;
+    right: 32px;
+    width:40px;
+    height:40px;
+    border-radius: 50%;
+    background: #fff;
+    text-align: center;
+    line-height: 40px;
+    box-shadow: 0 0 16px rgba(0,0,0,0.16);
+    cursor: pointer;
+    z-index:10;
+    img {
+      width: 24px;
+      height: 24px;
+    }
+  }
+
+  //.kf-phone {
+  //  font-size: 14px;
+  //  line-height: 22px;
+  //  left: -240px;
+  //  color: #1D1D1D;
+  //  padding: 12px 20px;
+  //  border-radius: 8px;
+  //  box-sizing: border-box;
+  //}
+}
+.mini-custom{
+  display: none;
+  position: fixed;
+  right: 84px;
+  bottom: 80px;
+  max-height: 674px;
+  min-height: 400px;
+  width: 460px;
+  height: calc(100% - 40px);
+  box-shadow: 0 0 20px 0 rgba(8, 31, 38, 0.12);
+  border-radius: 8px;
+  overflow: hidden;
+  z-index: 9999;
+}
+@media screen and (max-height: 800px) {
+  .mini-custom{
+    bottom: 20px;
+  }
+}
+
+</style>

+ 3 - 0
apps/work-bench/src/store/modules/customer.js

@@ -29,6 +29,9 @@ export default {
           commit('setCustomerStatus', true)
         }
       })
+    },
+    close ({ commit }) {
+      commit('setCustomerStatus', false)
     }
   },
   getters: {

+ 15 - 15
apps/work-bench/src/store/modules/work-bench.js

@@ -5,7 +5,8 @@ import {
   ajaxGetPower,
   ajaxGetUserInfo, ajaxSetClickMessages,
   ajaxSetMenuType, ajaxSetReadMessages,
-  ajaxSetSignOut, ajaxNavbarConvergeSearch
+  ajaxSetSignOut, ajaxNavbarConvergeSearch,
+  getCustomInfo
 } from '../../api/modules'
 import { storeModules } from '@jy/work-bench-frame'
 import { clearStorage, replaceKeyword } from '@/utils'
@@ -246,8 +247,6 @@ export default {
           commit('user/changePower', data || {})
           // 根据用户权益调整顶部导航搜索类型相关信息
           dispatch('setNavSearch')
-          // 根据用户权限设置客服二维码
-          dispatch('setCustomerInfo', data || {})
         }
       } catch (error) {
       }
@@ -305,22 +304,23 @@ export default {
       // 更新 frame store 配置
       commit('navbar-search/setSearchTypes', BaseNavbarSearchInfo)
     },
+    /**
+     * 获取客服二维码,不传参服务端会根据用户身份返回客成或者客服二维码
+     * @param dispatch
+     * @returns {Promise<void>}
+     */
+    async getCustomerInfo ({ dispatch }) {
+      const { error_code: code, data } = await getCustomInfo()
+      if (code === 0 && data) {
+        dispatch('setCustomerInfo', data || {})
+      }
+    },
     /**
      * 根据用户权限设置客服二维码
      * 商机管理或者大会员用户展示带有vip字段的二维码
      */
-    setCustomerInfo ({ commit }, payload) {
-      if (payload && Array.isArray(payload.customers)) {
-        const { memberStatus, entniche, customers } = payload
-        let target
-        if (memberStatus > 0 || entniche) {
-          // 商机管理或者大会员用户展示vip
-          target = customers.find(c => c.vip)
-        } else {
-          target = customers.find(c => !c.vip)
-        }
-        commit('user/changeCustomerInfo', target || {})
-      }
+    setCustomerInfo ({ commit }, data) {
+      commit('user/changeCustomerInfo', data || {})
     },
     /**
      * 导航栏聚合查询

+ 0 - 3
packages/work-bench-frame/packages/layout/work-bench/index.vue

@@ -31,9 +31,6 @@ export default {
     }
   },
   computed: {
-    ...mapGetters('work-bench/dialog', [
-      'dialogOptions'
-    ]),
     showMenu () {
       return this.nowTryMenuStatus && this.$route.query.aside !== '0'
     }