Prechádzať zdrojové kódy

feat: [bigmemer-pc] 调整监控组件、业务调用

zhangyuhan 1 rok pred
rodič
commit
1b1e6c8e08

+ 152 - 0
apps/bigmember_pc/src/components/common/MonitorPopover.vue

@@ -0,0 +1,152 @@
+<template>
+  <div class="monitor-popover-content">
+    <ul class="monitor-ul">
+      <li class="first-bottom" v-if="showTip">{{ textConfig.tip }}</li>
+      <li
+        :class="{ 'border-2': !showTip }"
+        v-if="showMore"
+        @click="$emit('click', 'more')"
+      >
+        {{ textConfig.more }}
+      </li>
+      <li v-if="showList">
+        <div class="list-top" @click="$emit('click', 'list')">
+          <span>{{ textConfig.list }}</span>
+          <i class="el-icon-arrow-right"></i>
+        </div>
+        <div class="list-center">
+          <slot>
+            {{ textConfig.listNumTip }}
+            <span style="color: #2abed1; font-weight: 700">{{
+              alreadyNum
+            }}</span>
+            个,剩余
+            <span style="color: #2abed1; font-weight: 700">{{
+              remainNum
+            }}</span>
+            个
+          </slot>
+        </div>
+        <div class="list-bottom" @click="$emit('click', 'apply')">
+          {{ textConfig.apply }}
+        </div>
+      </li>
+      <li @click="$emit('click', 'cancel')" v-if="showCancel">
+        {{ textConfig.cancel }}
+      </li>
+    </ul>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    alreadyNum: {
+      type: Number,
+      default: 0
+    },
+    // 剩余
+    remainNum: {
+      type: Number,
+      default: 0
+    },
+    // 是否展示对应模块
+    showTip: {
+      type: Boolean,
+      default: false
+    },
+    showMore: {
+      type: Boolean,
+      default: false
+    },
+    showList: {
+      type: Boolean,
+      default: false
+    },
+    showCancel: {
+      type: Boolean,
+      default: false
+    },
+    // 文案配置
+    config: {
+      type: Object,
+      default: () => {}
+    },
+    textType: {
+      type: String,
+      default: 'unit'
+    }
+  },
+  computed: {
+    textConfig() {
+      const textConfigMap = {
+        ent: {
+          tip: '监控业主一旦发布与“我的订阅”相关的招标动态,会推送业主的招标项目、时间等公告信息。',
+          more: '查看监控动态',
+          list: '查看监控列表',
+          listNumTip: '已监控',
+          apply: '申请监控更多业主',
+          cancel: '取消监控'
+        },
+        project: {
+          tip: '招标/采购进度实时监控,包含项目招标、中标等最新动态,及时跟踪项目。',
+          more: '查看监控动态',
+          list: '查看监控列表',
+          listNumTip: '已监控',
+          apply: '申请监控更多项目',
+          cancel: '取消监控'
+        }
+      }
+      return Object.assign(textConfigMap[this.textType] || {}, this.config)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.monitor-popover-content {
+  .monitor-ul {
+    li {
+      padding: 12px 0;
+      border-top: 1px solid #ececec;
+      font-size: 16px;
+      color: #1d1d1d;
+      cursor: pointer;
+      &:first-child {
+        border: none;
+        padding: 0 0 12px;
+        font-size: 14px;
+        color: #686868;
+      }
+      &:last-child {
+        padding: 12px 0 0;
+      }
+      &.border-2 {
+        border: none;
+      }
+      .list-top {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        color: #2abed1;
+      }
+      .list-center {
+        margin: 8px 0;
+        color: #686868;
+        font-size: 14px;
+      }
+      .list-bottom {
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        width: 100%;
+        height: 32px;
+        color: #2abed1;
+        font-size: 14px;
+        background-color: #eaf8fa;
+        border-radius: 4px;
+      }
+    }
+  }
+}
+</style>

+ 4 - 0
apps/bigmember_pc/src/views/article-content/components/ContentHeader.vue

@@ -1,6 +1,7 @@
 <script setup>
 import shareBox from '@/components/shareBox/index.vue'
 import powerPerson from '@/components/subscribe-manager/powerPerson.vue'
+import QuickMonitor from '@/views/article-content/components/QuickMonitor.vue'
 import { ContentModel } from '@/views/article-content/composables/useContentStore'
 import { computed, getCurrentInstance, onMounted, ref } from 'vue'
 import { useRoute } from 'vue-router/composables'
@@ -34,6 +35,7 @@ const { openShare, useShareRef } = useShare()
 // 分发
 const { doSubmitDistribute, openDistribute, usePowerRef } = useDistribute()
 // 监控
+const contentId = params.id.replace('.html', '')
 </script>
 
 <template>
@@ -81,6 +83,8 @@ const { doSubmitDistribute, openDistribute, usePowerRef } = useDistribute()
           </el-popover>
         </div>
 
+        <quick-monitor class="action-item" type="project" :params="contentId" />
+
         <div class="action-item">
           <span class="iconfont icon-canbiao"></span>
         </div>

+ 135 - 102
apps/bigmember_pc/src/views/article-content/components/QuickMonitor.vue

@@ -1,56 +1,9 @@
-<template>
-  <div>
-    <el-popover placement="left" width="224" trigger="click">
-      <div
-        slot="reference"
-        class="flex-r-c center"
-        @click.stop="changeFollow()"
-      >
-        <i
-          class="icon iconfont"
-          :class="{
-            'icon-yijiankong': follow,
-            'icon-jiankong': !follow
-          }"
-        ></i>
-        <span>{{ follow ? '取消' : '' }}监控</span>
-      </div>
-      <monitor
-        @showNeedSubmit="showNeedSubmit"
-        @show="monitorInfo.showD4 = true"
-        :already-num="monitorInfo.alreadyNum"
-        :remain-num="monitorInfo.remainNum"
-        :show-list="monitorInfo.showList"
-      ></monitor>
-    </el-popover>
-    <common-dialog
-      center
-      custom-class="monitor-class"
-      width="380px"
-      :visible="dialog.show"
-      :title="dialog.title"
-    >
-      <template #footer>
-        <button
-          v-for="(item, index) in dialog.footerActions"
-          :key="index"
-          class="action-button"
-          :class="item.class"
-          @click="doClickAction(item)"
-        >
-          {{ item.label }}
-        </button>
-      </template>
-      {{ dialog.content }}
-    </common-dialog>
-    <CollectInfo ref="collectRef"></CollectInfo>
-  </div>
-</template>
-
-<script>
+<script setup>
 import commonDialog from '@/components/dialog/Dialog.vue'
 import CollectInfo from '@/components/collect-info/CollectInfo.vue'
-import monitor from '@/components/common/Monitor.vue'
+import MonitorPopover from '@/components/common/MonitorPopover.vue'
+import { computed, ref, defineProps, reactive } from 'vue'
+import useQuickMonitor from '@jy/data-models/modules/quick-monitor/model'
 
 // 监控 + 监控成功
 // 未监控 + 取消监控
@@ -118,63 +71,143 @@ const dialogDataMap = {
     ]
   }
 }
+const collectElement = ref(null)
+const follow = ref(false)
+const dialogShow = ref(false)
+const dialogConfig = computed(() => dialogDataMap['monitor-success'])
 
-export default {
-  name: 'QuickMonitor',
-  components: {
-    monitor,
-    CollectInfo,
-    commonDialog
-  },
-  data() {
-    return {
-      follow: false,
-      monitorInfo: {
-        showD1: false,
-        showD2: false,
-        showD3: false,
-        showD4: false,
-        showList: [1, 3],
-        remainNum: 0,
-        alreadyNum: 0
-      }
-    }
-  },
-  computed: {
-    dialog() {
-      return {
-        show: false,
-        title: '1',
-        content: '1',
-        footerActions: [
-          {
-            label: '去开启',
-            class: 'confirm',
-            action: '1'
-          },
-          {
-            label: '暂不开启',
-            class: 'cancel',
-            action: '2'
-          }
-        ]
-      }
-    }
-  },
-  methods: {
-    changeFollow() {},
-    // 显示留资弹窗
-    showNeedSubmit() {
-      this.$refs.collectRef.noCallApiFn('pc_buyer_monitor_more', true)
-    },
-    setMonitorConfirm() {},
-    setMonitorCancel() {},
-    doClickAction() {}
+// monitor-popover click emit
+function doClickMonitorActions(type) {
+  switch (type) {
+    case 'more':
+      break
+    case 'list':
+      break
+    case 'apply':
+      break
+    case 'cancel':
+      break
   }
 }
+
+function doClickAction() {}
+function changeFollow() {}
+
+const props = defineProps({
+  type: String,
+  params: String,
+  config: {
+    type: Object,
+    default: () => ({
+      default: '监控',
+      follow: '已监控'
+    })
+  }
+})
+
+const useMonitor = reactive(
+  useQuickMonitor({
+    type: props.type,
+    params: {
+      id: props.params
+    }
+  })
+)
+
+console.log(useMonitor)
+const { doFetch, doChange } = useMonitor
+
+const model = computed(() => {
+  return useMonitor.model
+})
+
+const monitorPopoverConfig = computed(() => {
+  return {
+    showTip: !model.value.follow,
+    showMore: model.value.follow,
+    showList: true,
+    showCancel: model.value.follow,
+    alreadyNum: model.value.expands.alreadyNum,
+    remainNum: model.value.expands.remainNum,
+    textType: props.type
+  }
+})
+
+doFetch()
 </script>
+<template>
+  <div class="quick-monitor" v-if="model.canFollow">
+    <!--  icon + popover  -->
+    <div class="quick-monitor-popover">
+      <el-popover
+        popper-class="monitor-popover"
+        placement="bottom"
+        :append-to-body="false"
+        width="224"
+        trigger="click"
+      >
+        <div
+          slot="reference"
+          class="flex-r-c center action-icon"
+          @click.stop="changeFollow()"
+        >
+          <i
+            class="icon iconfont"
+            :class="{
+              'icon-yijiankong': model.follow,
+              'icon-jiankong': !model.follow
+            }"
+          ></i>
+          <span>{{ model.follow ? config.follow : config.default }}</span>
+        </div>
+        <monitor-popover
+          v-bind="monitorPopoverConfig"
+          @click="doClickMonitorActions"
+        ></monitor-popover>
+      </el-popover>
+    </div>
+    <!-- 提示弹窗 -->
+    <common-dialog
+      center
+      custom-class="monitor-class"
+      width="380px"
+      :visible="dialogShow"
+      :title="dialogConfig.title"
+    >
+      <template #footer>
+        <button
+          v-for="(item, index) in dialogConfig.footerActions"
+          :key="index"
+          class="action-button"
+          :class="item.class"
+          @click="doClickAction(item)"
+        >
+          {{ item.label }}
+        </button>
+      </template>
+      {{ dialogConfig.content }}
+    </common-dialog>
+    <!-- 留资 -->
+    <collect-info ref="collectElement"></collect-info>
+  </div>
+</template>
 
 <style lang="scss" scoped>
+.quick-monitor-popover {
+  position: relative;
+}
+.action-icon {
+  .iconfont {
+    font-size: 18px;
+    color: #9b9ca3;
+    &.icon-yijiankong {
+      color: #ff9f40;
+    }
+    & + span {
+      margin-left: 2px;
+    }
+  }
+}
 ::v-deep {
   .monitor-class {
     padding: 32px;

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

@@ -1,6 +1,7 @@
 <script setup>
 import ContentHeader from '@/views/article-content/components/ContentHeader.vue'
 import { ref, onMounted, onBeforeMount } from 'vue'
+import { useRoute } from 'vue-router/composables'
 import Reward from '@/views/article-content/components/Reward.vue'
 import TimeLine from '@/components/time-line/TimeLine.vue'
 import ArticleItem from '@/components/article-item/ArticleItem.vue'
@@ -12,7 +13,6 @@ import RecommendCustomersList from '@/views/article-content/components/Recommend
 import { throttle } from 'lodash'
 import ContentSummary from '@/views/article-content/components/ContentSummary.vue'
 import RecommendEnt from '@/views/article-content/components/RecommendEnt.vue'
-import QuickMonitor from '@/views/article-content/components/QuickMonitor.vue'
 import {
   useContentStore,
   ContentModel
@@ -214,11 +214,12 @@ onMounted(() => {
 onBeforeMount(() => {
   window.removeEventListener('scroll', handleScroll)
 })
+
+const contentId = useRoute().params.id.replace('.html', '')
 </script>
 <template>
   <ContentLayout :need-ad="true">
     <div class="article-container">
-      <quick-monitor />
       <content-header></content-header>
 
       <div class="content-header-tip" v-if="ContentModel.isSelfSite">