浏览代码

feat: 完善企业认证服务悬浮窗

zhangyuhan 1 年之前
父节点
当前提交
d6fc08a08f

+ 10 - 0
apps/bigmember_pc/src/api/modules/detail.js

@@ -98,3 +98,13 @@ export function ajaxSetSearchFilterForSession(data) {
     data: qs.stringify(data)
     data: qs.stringify(data)
   })
   })
 }
 }
+
+// 三方认证悬浮窗信息
+export function ajaxGetThirdPopoverInfo(data) {
+  return request({
+    url: '/commercial/customer/info',
+    method: 'get',
+    noToast: true,
+    params: data
+  })
+}

+ 8 - 1
apps/bigmember_pc/src/components/collect-info/CollectInfo.vue

@@ -550,6 +550,7 @@ export default {
         peugeot_view_infor: '请留下联系方式,我们会尽快联系您体验大会员全部功能!',
         peugeot_view_infor: '请留下联系方式,我们会尽快联系您体验大会员全部功能!',
         pc_article_BidPreparation: ' ',
         pc_article_BidPreparation: ' ',
         pc_article_certificateServices: ' ',
         pc_article_certificateServices: ' ',
+        'certificateServices-pc-biddingDetailPage-content': ' ',
         pc_article_BidDecision: '请升级大会员,为您分析同类项目采购明细,帮助投标人员编制标书、投标报价参考,辅助投标决策。',
         pc_article_BidDecision: '请升级大会员,为您分析同类项目采购明细,帮助投标人员编制标书、投标报价参考,辅助投标决策。',
         pc_article_CustomerRecommend: '请升级大会员,为您推荐潜在业务需求客户并提供联系方式。',
         pc_article_CustomerRecommend: '请升级大会员,为您推荐潜在业务需求客户并提供联系方式。',
         pc_article_ent_more: '请升级大会员,可实时监控最多500个企业中标动态,帮助你了解竞争对手和合作伙伴的动向。',
         pc_article_ent_more: '请升级大会员,可实时监控最多500个企业中标动态,帮助你了解竞争对手和合作伙伴的动向。',
@@ -607,6 +608,7 @@ export default {
         pc_article_CustomerRecommend: '申请客户推荐权限',
         pc_article_CustomerRecommend: '申请客户推荐权限',
         pc_article_ent_more: '申请监控更多企业',
         pc_article_ent_more: '申请监控更多企业',
         pc_article_ent_limit: '申请监控更多企业',
         pc_article_ent_limit: '申请监控更多企业',
+        'certificateServices-pc-biddingDetailPage-content': '请留下您的信息,我们会尽快和您联系',
       },
       },
       isRefresh: false
       isRefresh: false
     }
     }
@@ -687,7 +689,7 @@ export default {
         return '我们会尽快联系您完成供应商报名,请耐心等待。'
         return '我们会尽快联系您完成供应商报名,请耐心等待。'
       } else if (this.source.indexOf('jyarticle_see3_plus_pc') > -1) {
       } else if (this.source.indexOf('jyarticle_see3_plus_pc') > -1) {
         return '您已获得无限次免费查看标讯的权益,如需查看超前项目请联系客服:400-108-6670'
         return '您已获得无限次免费查看标讯的权益,如需查看超前项目请联系客服:400-108-6670'
-      } else if (this.source === 'pc_article_BidPreparation' || this.source === 'pc_article_certificateServices') {
+      } else if (this.source === 'pc_article_BidPreparation' || this.source === 'pc_article_certificateServices' || this.source === 'certificateServices-pc-biddingDetailPage-content') {
         return '专业老师将尽快和您联系!'
         return '专业老师将尽快和您联系!'
       } else {
       } else {
         return '我们会尽快联系您并预约演示时间,请耐心等待~您将获得免费体验大会员全部功能!'
         return '我们会尽快联系您并预约演示时间,请耐心等待~您将获得免费体验大会员全部功能!'
@@ -762,6 +764,11 @@ export default {
           this.moduleShow.tip = false
           this.moduleShow.tip = false
           break
           break
         }
         }
+        case 'certificateServices-pc-biddingDetailPage-content': {
+          this.moduleShow.job = false
+          this.moduleShow.tip = false
+          break
+        }
         case 'jyarticle_see3_plus_pc': {
         case 'jyarticle_see3_plus_pc': {
           this.moduleShow.companyType = true
           this.moduleShow.companyType = true
           this.moduleShow.job = true
           this.moduleShow.job = true

+ 31 - 15
apps/bigmember_pc/src/components/time-line/PoverTimeLine.vue

@@ -5,8 +5,8 @@
     @mouseleave="isHover = false"
     @mouseleave="isHover = false"
   >
   >
     <el-popover
     <el-popover
-      popper-class="poverStep"
-      placement="bottom-start"
+      :popper-class="poperClass"
+      :placement="poperPlacement"
       :open-delay="300"
       :open-delay="300"
       :append-to-body="false"
       :append-to-body="false"
       :width="poperWidth"
       :width="poperWidth"
@@ -15,17 +15,19 @@
       v-model="popoverShow"
       v-model="popoverShow"
     >
     >
       <slot name="content" slot="reference"></slot>
       <slot name="content" slot="reference"></slot>
-      <el-card class="project-content" v-show="stepList.length !== 0">
-        <div slot="header" class="p-h-title">{{ title }}</div>
-        <div class="p-c-main">
-          <TimeLine
-            poverType="card"
-            :custom-event="customEvent"
-            :stepList="stepList"
-            @open="$emit('open', $event)"
-          />
-        </div>
-      </el-card>
+      <slot name="main">
+        <el-card class="project-content" v-show="stepList.length !== 0">
+          <div slot="header" class="p-h-title">{{ title }}</div>
+          <div class="p-c-main">
+            <TimeLine
+              poverType="card"
+              :custom-event="customEvent"
+              :stepList="stepList"
+              @open="$emit('open', $event)"
+            />
+          </div>
+        </el-card>
+      </slot>
     </el-popover>
     </el-popover>
   </div>
   </div>
 </template>
 </template>
@@ -62,6 +64,18 @@ export default {
         return '720'
         return '720'
       }
       }
     },
     },
+    poperClass: {
+      type: String,
+      default() {
+        return 'poverStep fixed-left'
+      }
+    },
+    poperPlacement: {
+      type: String,
+      default() {
+        return 'bottom-start'
+      }
+    },
     customEvent: {
     customEvent: {
       type: Boolean,
       type: Boolean,
       default: false
       default: false
@@ -91,8 +105,10 @@ export default {
 .el-popover.poverStep {
 .el-popover.poverStep {
   padding: 0;
   padding: 0;
   border: 0;
   border: 0;
-  .popper__arrow {
-    left: 100px !important;
+  &.fixed-left {
+    .popper__arrow {
+      left: 100px !important;
+    }
   }
   }
 }
 }
 </style>
 </style>

+ 43 - 5
apps/bigmember_pc/src/views/article-content/components/ContentThirdPopover.vue

@@ -1,3 +1,33 @@
+<script setup>
+import { ajaxGetThirdPopoverInfo } from '@/api/modules/detail'
+import { onMounted, ref } from 'vue'
+
+const emit = defineEmits(['open-collect'])
+function doOpenCollect() {
+  emit('open-collect', 'certificateServices-pc-biddingDetailPage-content')
+}
+
+const popoverInfo = ref({
+  tel: '',
+  img: ''
+})
+
+function getInfo() {
+  ajaxGetThirdPopoverInfo({
+    module: 'tripartiteAuth'
+  }).then((res) => {
+    if (res && res.data) {
+      popoverInfo.value.tel = res.data.phone
+      // /common-module/bidedoc/image/third-party-verify-customer.png
+      popoverInfo.value.img = res.data.wxCodeImg
+    }
+  })
+}
+
+onMounted(() => {
+  getInfo()
+})
+</script>
 <template>
 <template>
   <div class="third-party-popover-content-template">
   <div class="third-party-popover-content-template">
     <div class="third-party popover-content-header">
     <div class="third-party popover-content-header">
@@ -19,13 +49,13 @@
       </div>
       </div>
     </div>
     </div>
     <div class="third-party popover-content-main bidcontent">
     <div class="third-party popover-content-main bidcontent">
-      <div class="bid_tel">
+      <div class="bid_tel flex">
         <img
         <img
           src="@/assets/images/tel.png"
           src="@/assets/images/tel.png"
           alt=""
           alt=""
-          style="width: 20px; height: 20px"
+          style="width: 20px; height: 20px; margin-right: 2px"
         />
         />
-        <span class="bid_phonetext">咨询 $tel 了解更多</span>
+        <span class="bid_phonetext">咨询 {{ popoverInfo.tel }} 了解更多</span>
       </div>
       </div>
       <div class="p-c-m-content">
       <div class="p-c-m-content">
         <div class="p-c-m-content-l bid_classfun">
         <div class="p-c-m-content-l bid_classfun">
@@ -58,7 +88,7 @@
         </div>
         </div>
         <div class="p-c-m-content-r">
         <div class="p-c-m-content-r">
           <div class="t-p-verify-customer-qr" title="客服企业微信二维码">
           <div class="t-p-verify-customer-qr" title="客服企业微信二维码">
-            <img alt="客服企业微信二维码" />
+            <img :src="popoverInfo.img" alt="客服企业微信二维码" />
           </div>
           </div>
           <div class="p-c-m-c-r-text">添加客服微信<br />备注认证服务</div>
           <div class="p-c-m-c-r-text">添加客服微信<br />备注认证服务</div>
         </div>
         </div>
@@ -71,7 +101,10 @@
         target="_blank"
         target="_blank"
         >了解详情</a
         >了解详情</a
       >
       >
-      <div class="bid_button_confirm bid_btn third-party-apply-for-button">
+      <div
+        class="bid_button_confirm bid_btn third-party-apply-for-button"
+        @click="doOpenCollect"
+      >
         申请认证
         申请认证
       </div>
       </div>
     </div>
     </div>
@@ -119,6 +152,7 @@
   width: 623px;
   width: 623px;
   background-color: #fff;
   background-color: #fff;
   padding: 24px;
   padding: 24px;
+  border-radius: 12px;
 
 
   .center-card-container {
   .center-card-container {
     display: flex;
     display: flex;
@@ -169,6 +203,10 @@
     text-decoration: none;
     text-decoration: none;
   }
   }
 
 
+  .bid_button_cancel:hover {
+    text-decoration: none !important;
+  }
+
   .lead-btn .join {
   .lead-btn .join {
     margin-left: 0;
     margin-left: 0;
     width: unset;
     width: unset;

+ 31 - 8
apps/bigmember_pc/src/views/article-content/composables/useHoverElementClientRect.js

@@ -5,19 +5,31 @@ import { ref, onMounted, onUnmounted, computed } from 'vue'
  * @param event
  * @param event
  * @param hasClass
  * @param hasClass
  * @param maxDepth - 最大查询层级
  * @param maxDepth - 最大查询层级
+ * @param onCustomClass - 自定义判断函数
  */
  */
 
 
-function checkAncestorClass(event, hasClass, maxDepth = 3) {
+function checkAncestorClass(
+  event,
+  hasClass,
+  maxDepth = 3,
+  onCustomClass = null
+) {
   let target = event.target
   let target = event.target
   let depth = 0 // 添加一个深度计数器
   let depth = 0 // 添加一个深度计数器
 
 
   while (target && target.nodeType === Node.ELEMENT_NODE && depth < maxDepth) {
   while (target && target.nodeType === Node.ELEMENT_NODE && depth < maxDepth) {
-    if (target.className.indexOf(hasClass) !== -1) {
-      return {
-        status: true,
-        target
-      }
+    let result = {
+      status: target.className.indexOf(hasClass) !== -1,
+      target
+    }
+
+    if (typeof onCustomClass === 'function') {
+      result.status = onCustomClass(target.className)
+    }
+    if (result.status) {
+      return result
     }
     }
+
     target = target.parentNode
     target = target.parentNode
     depth++ // 每次循环增加深度计数
     depth++ // 每次循环增加深度计数
   }
   }
@@ -39,6 +51,7 @@ function checkAncestorClass(event, hasClass, maxDepth = 3) {
 export function useHoverHighlightTextPopover({
 export function useHoverHighlightTextPopover({
   parentSelector,
   parentSelector,
   hasClass,
   hasClass,
+  onCustomClass = null,
   onChangeHover = () => {},
   onChangeHover = () => {},
   onClick = () => {}
   onClick = () => {}
 }) {
 }) {
@@ -72,7 +85,12 @@ export function useHoverHighlightTextPopover({
   })
   })
 
 
   const handleClick = (event) => {
   const handleClick = (event) => {
-    const { status, target } = checkAncestorClass(event, hasClass, 3)
+    const { status, target } = checkAncestorClass(
+      event,
+      hasClass,
+      3,
+      onCustomClass
+    )
     if (status) {
     if (status) {
       tranElementInfo(target)
       tranElementInfo(target)
       onClick(target)
       onClick(target)
@@ -86,7 +104,12 @@ export function useHoverHighlightTextPopover({
   }
   }
 
 
   const handleMouseOver = (event) => {
   const handleMouseOver = (event) => {
-    const { status, target } = checkAncestorClass(event, hasClass, 3)
+    const { status, target } = checkAncestorClass(
+      event,
+      hasClass,
+      3,
+      onCustomClass
+    )
     if (status) {
     if (status) {
       // 检测到指定的类名
       // 检测到指定的类名
       const activeElement = target
       const activeElement = target

+ 46 - 3
apps/bigmember_pc/src/views/article-content/pages/Article.vue

@@ -48,6 +48,7 @@ import PoverTimeLine from '@/components/time-line/PoverTimeLine.vue'
 import { useHoverHighlightTextPopover } from '@/views/article-content/composables/useHoverElementClientRect'
 import { useHoverHighlightTextPopover } from '@/views/article-content/composables/useHoverElementClientRect'
 import attachmentDownload from '@/composables/attachment-download/component/AttachmentDownload.vue'
 import attachmentDownload from '@/composables/attachment-download/component/AttachmentDownload.vue'
 import ContentRightTimeLine from '@/views/article-content/components/ContentRightTimeLine.vue'
 import ContentRightTimeLine from '@/views/article-content/components/ContentRightTimeLine.vue'
+import ContentThirdPopover from '@/views/article-content/components/ContentThirdPopover.vue'
 
 
 useContentStore()
 useContentStore()
 // 判断在哪个容器
 // 判断在哪个容器
@@ -268,7 +269,6 @@ const canShowMask = computed(() => {
 })
 })
 
 
 const popoverElement = ref(null)
 const popoverElement = ref(null)
-const popoverTriggerElement = ref(null)
 
 
 // 招标、采购进度
 // 招标、采购进度
 const winnerTimeLineList = computed(() => {
 const winnerTimeLineList = computed(() => {
@@ -296,6 +296,11 @@ const popoverElementType = computed(() => {
   if (elementState.value.className.indexOf('winner-name') !== -1) {
   if (elementState.value.className.indexOf('winner-name') !== -1) {
     return 'winner-name'
     return 'winner-name'
   }
   }
+  if (
+    elementState.value.className.indexOf('third-party-verify-button') !== -1
+  ) {
+    return 'third-verify'
+  }
   return ''
   return ''
 })
 })
 
 
@@ -303,6 +308,8 @@ const popoverElementType = computed(() => {
 const popoverTimeLine = computed(() => {
 const popoverTimeLine = computed(() => {
   if (popoverElementType.value === 'project-name') {
   if (popoverElementType.value === 'project-name') {
     return {
     return {
+      width: '720',
+      contentType: 'time-line',
       title: '项目公告',
       title: '项目公告',
       list: timeLineList.value
       list: timeLineList.value
     }
     }
@@ -313,11 +320,23 @@ const popoverTimeLine = computed(() => {
     popoverElementType.value === 'winner-name'
     popoverElementType.value === 'winner-name'
   ) {
   ) {
     return {
     return {
+      width: '720',
+      contentType: 'time-line',
       title: '企业最新信息',
       title: '企业最新信息',
       list: winnerTimeLineList.value
       list: winnerTimeLineList.value
     }
     }
   }
   }
+  if (popoverElementType.value === 'third-verify') {
+    return {
+      width: '623',
+      contentType: 'third-verify',
+      title: '',
+      list: []
+    }
+  }
   return {
   return {
+    width: '',
+    contentType: '',
     title: '',
     title: '',
     list: []
     list: []
   }
   }
@@ -326,6 +345,17 @@ const popoverTimeLine = computed(() => {
 const { elementState, useElementListener } = useHoverHighlightTextPopover({
 const { elementState, useElementListener } = useHoverHighlightTextPopover({
   parentSelector: '.content-main-container',
   parentSelector: '.content-main-container',
   hasClass: 'keyword-underline',
   hasClass: 'keyword-underline',
+  onCustomClass: (className) => {
+    // 项目名称
+    if (className.indexOf('keyword-underline') !== -1) {
+      return true
+    }
+    // 认证服务
+    if (className.indexOf('third-party-verify-button') !== -1) {
+      return true
+    }
+    return false
+  },
   onChangeHover: debounce((isHover) => {
   onChangeHover: debounce((isHover) => {
     popoverElement.value.doChangePopover(isHover)
     popoverElement.value.doChangePopover(isHover)
   }, 150),
   }, 150),
@@ -343,7 +373,7 @@ const { elementState, useElementListener } = useHoverHighlightTextPopover({
 
 
 // 事件延迟绑定
 // 事件延迟绑定
 const canAddContentMainEvent = computed(() => {
 const canAddContentMainEvent = computed(() => {
-  const result = ContentPageLoading.value && tabContentShow.value['公告正文']
+  const result = !ContentPageLoading.value && tabContentShow.value['公告正文']
   if (result) {
   if (result) {
     useElementListener()
     useElementListener()
   }
   }
@@ -440,7 +470,10 @@ function doClickFreeView() {
                 name="公告正文"
                 name="公告正文"
                 v-if="tabContentShow['公告正文']"
                 v-if="tabContentShow['公告正文']"
               >
               >
-                <div class="content-main-container">
+                <div
+                  class="content-main-container"
+                  :data-content="canAddContentMainEvent"
+                >
                   <div class="content-block-header">公告正文</div>
                   <div class="content-block-header">公告正文</div>
                   <div
                   <div
                     class="content-detail-container"
                     class="content-detail-container"
@@ -528,14 +561,24 @@ function doClickFreeView() {
     </el-skeleton>
     </el-skeleton>
     <!--  hover 项目、企业名称时展示 popover 最新标讯  -->
     <!--  hover 项目、企业名称时展示 popover 最新标讯  -->
     <pover-time-line
     <pover-time-line
+      class="article-content-popover"
       trigger="manual"
       trigger="manual"
+      poperClass="poverStep"
+      poperPlacement="bottom"
       :title="popoverTimeLine.title"
       :title="popoverTimeLine.title"
       :custom-event="true"
       :custom-event="true"
       @open="doOpenArticlePage"
       @open="doOpenArticlePage"
       :stepList="popoverTimeLine.list"
       :stepList="popoverTimeLine.list"
+      :poper-width="popoverTimeLine.width"
       ref="popoverElement"
       ref="popoverElement"
     >
     >
       <div slot="content" :style="elementState.style"></div>
       <div slot="content" :style="elementState.style"></div>
+      <div slot="main" v-if="popoverTimeLine.contentType === 'third-verify'">
+        <!--  认证服务悬浮弹窗  -->
+        <content-third-popover
+          @open-collect="doOpenCollectDialog"
+        ></content-third-popover>
+      </div>
     </pover-time-line>
     </pover-time-line>
     <!--  留资弹窗  -->
     <!--  留资弹窗  -->
     <collect-info ref="collectElement"></collect-info>
     <collect-info ref="collectElement"></collect-info>

+ 1 - 0
configs/proxy/dev-proxy.js

@@ -29,6 +29,7 @@ const ProxyPrefixes = [
   '/jyMerge',
   '/jyMerge',
   '/leadGeneration',
   '/leadGeneration',
   '/member',
   '/member',
+  '/commercial',
   // 静态资源代理
   // 静态资源代理
   '/commonFunctions',
   '/commonFunctions',
   '/common-module',
   '/common-module',