Browse Source

feat: 完善 quick-monitor,支持缓存复用

zhangyuhan 1 year ago
parent
commit
2faa8c0ef7

+ 54 - 0
apps/bigmember_pc/src/composables/quick-monitor/README.md

@@ -0,0 +1,54 @@
+# useQuickMonitorModel
+> 监控(项目监控、企业监控、客户监控)业务,需要配合 @jy/data-models/quick-monitor/model 使用
+
+## 前置要求
+
+* 引入 @jy/data-models
+
+
+## 业务模型使用
+```vue
+// 导入组件
+import QuickMonitor from '@/composables/quick-monitor/component/QuickMonitor.vue'
+
+<quick-monitor
+  class="action-item"
+  type="project"
+  :params="contentId"
+/>
+```
+
+### QuickMonitor
+#### Props 参数文档
+
+|      参数       |  描述   |                        类型                         |     默认值      |
+|:-------------:|:-----:|:-------------------------------------------------:|:------------:|
+| cache  |            是否缓存数据,开启后,当数据变化时,会重新获取数据            | Boolean | false |
+|  type  | 用于监控的类型 (project - 项目 / ent - 企业 / client - 客户) | String | - |
+| params |               对应的监控项目ID、企业ID、客户ID               | String | - |
+|  auto  |                 是否自动获取当前监控状态信息                  | Boolean | true |
+
+
+
+#### 单例模式
+> 用于页面存在多个监控按钮,但是对应同一个 type + id 时。实现数据共享,避免重复请求。
+
+```
+// 第一个监控按钮,调用接口
+<quick-monitor
+  class="action-item"
+  :cache="true"
+  :auto="true"
+  type="project"
+  :params="contentId"
+/>
+
+// 第二个监控按钮,不调用接口获取数据
+<quick-monitor
+  class="action-item"
+  :cache="true"
+  :auto="false"
+  type="project"
+  :params="contentId"
+/>
+```

+ 18 - 4
apps/bigmember_pc/src/composables/quick-monitor/component/QuickMonitor.vue

@@ -2,11 +2,21 @@
 import commonDialog from '@/components/dialog/Dialog.vue'
 import CollectInfo from '@/components/collect-info/CollectInfo.vue'
 import MonitorPopover from '@/components/common/MonitorPopover.vue'
-import useQuickMonitorModel from '@/composables/quick-monitor'
+import { useQuickMonitorModel } from '@/composables/quick-monitor'
 
 const props = defineProps({
   type: String,
-  params: String
+  params: String,
+  // 如果需要多个监控复用一个 model,需要传递 true
+  cache: {
+    type: Boolean,
+    default: false
+  },
+  // 自动调用 doFetch 获取状态接口
+  auto: {
+    type: Boolean,
+    default: true
+  }
 })
 
 const {
@@ -24,10 +34,13 @@ const {
   collectElement
 } = useQuickMonitorModel({
   type: props.type,
-  id: props.params
+  id: props.params,
+  cache: props.cache
 })
 
-doFetch()
+if (props.auto) {
+  doFetch()
+}
 </script>
 <template>
   <div class="quick-monitor" v-if="model.canFollow">
@@ -93,6 +106,7 @@ doFetch()
   position: relative;
 }
 .action-icon {
+  cursor: pointer;
   .iconfont {
     font-size: 18px;
     color: #9b9ca3;

+ 37 - 5
apps/bigmember_pc/src/composables/quick-monitor/index.js

@@ -1,11 +1,43 @@
 import useProjectQuickMonitorModel from './use/porject'
 import useEntQuickMonitorModel from './use/ent'
 
-export default function useQuickMonitorModel(params) {
-  if (params.type === 'project') {
-    return useProjectQuickMonitorModel(params)
+const GlobalModelCache = {}
+
+export function removeGlobalCache(key = 'all') {
+  if (key === 'all') {
+    Object.keys(GlobalModelCache).forEach((key) => {
+      delete GlobalModelCache[key]
+    })
+    return true
+  } else {
+    delete GlobalModelCache[key]
+    return true
+  }
+}
+
+export function useQuickMonitorModel(params) {
+  const { type, cache = false, id = '' } = params
+  const useSingleModel = cache === true
+
+  let createModel = () => ({})
+  switch (type) {
+    case 'project':
+      createModel = useProjectQuickMonitorModel
+      break
+    case 'ent':
+      createModel = useEntQuickMonitorModel
+      break
+    default:
+      break
   }
-  if (params.type === 'ent') {
-    return useEntQuickMonitorModel(params)
+
+  if (useSingleModel) {
+    const key = `${type}-${id}`
+    if (!GlobalModelCache[key]) {
+      GlobalModelCache[key] = createModel(params)
+    }
+    return GlobalModelCache[key]
+  } else {
+    return createModel(params)
   }
 }

+ 4 - 1
apps/bigmember_pc/src/composables/quick-monitor/use/ent.js

@@ -141,7 +141,7 @@ function useEntQuickMonitorModel({ type, id }) {
       await doChange().then((res) => {
         if (res.success) {
           // 判断是否开启推送提醒
-          if (res.data?.msg_open) {
+          if (!res.data?.msg_open) {
             doOpenDialog('success-monitor')
           } else {
             that.$toast(DialogDataMap['success-toast'])
@@ -182,12 +182,15 @@ function useEntQuickMonitorModel({ type, id }) {
         doCloseDialog()
         break
       case 'doOpenCustomer':
+        doCloseDialog()
         doOpenCustomer()
         break
       case 'doOpenPushSetting':
+        doCloseDialog()
         doOpenPushSetting()
         break
       case 'doRemoveFollow':
+        doCloseDialog()
         doChange().then((res) => {
           that.$toast(res.msg)
         })

+ 3 - 1
apps/bigmember_pc/src/composables/quick-monitor/use/porject.js

@@ -182,15 +182,17 @@ function useProjectQuickMonitorModel({ type, id }) {
         doCloseDialog()
         break
       case 'doOpenCustomer':
+        doCloseDialog()
         doOpenCustomer()
         break
       case 'doOpenPushSetting':
+        doCloseDialog()
         doOpenPushSetting()
         break
       case 'doRemoveFollow':
+        doCloseDialog()
         doChange().then((res) => {
           that.$toast(res.msg)
-          doCloseDialog()
         })
         break
       case 'cancel':

+ 6 - 1
apps/bigmember_pc/src/views/article-content/components/ContentHeader.vue

@@ -83,7 +83,12 @@ const contentId = params.id.replace('.html', '')
           </el-popover>
         </div>
 
-        <quick-monitor class="action-item" type="project" :params="contentId" />
+        <quick-monitor
+          class="action-item"
+          :cache="true"
+          type="project"
+          :params="contentId"
+        />
 
         <div class="action-item">
           <span class="iconfont icon-canbiao"></span>

+ 2 - 3
apps/bigmember_pc/src/views/article-content/components/RecommendEnt.vue

@@ -1,5 +1,6 @@
 <script setup>
 import { SummaryModel } from '@/views/article-content/composables/useContentStore'
+import QuickMonitor from '@/composables/quick-monitor/component/QuickMonitor.vue'
 import { computed, ref, watch } from 'vue'
 import { ajaxGetMiniEntInfo } from '@/api/modules/detail'
 import { formatMoney } from '@/utils'
@@ -88,9 +89,7 @@ function doOpen(item) {
           </span>
           <h3>{{ item.name }}</h3>
           <div class="monitor-action">
-            <span class="iconfont icon-jiankong"></span>
-            <span class="iconfont icon-yijiankong"></span>
-            监控
+            <quick-monitor class="action-item" type="ent" :params="item.id" />
           </div>
         </div>
         <span class="type-info-time">数据统计范围:{{ item.time }}</span>

+ 26 - 13
apps/bigmember_pc/src/views/article-content/pages/Article.vue

@@ -13,6 +13,7 @@ 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 '@/composables/quick-monitor/component/QuickMonitor.vue'
 import {
   useContentStore,
   ContentModel
@@ -27,19 +28,19 @@ const contentTabs = [
   },
   {
     label: '公告正文'
-  },
-  {
-    label: '招标/采购进度'
-  },
-  {
-    label: '投标服务'
-  },
-  {
-    label: '商机推荐'
-  },
-  {
-    label: '客户推荐'
   }
+  // {
+  //   label: '招标/采购进度'
+  // },
+  // {
+  //   label: '投标服务'
+  // },
+  // {
+  //   label: '商机推荐'
+  // }
+  // {
+  //   label: '客户推荐'
+  // }
 ]
 
 function scrollToTop(element, diff = 0) {
@@ -295,7 +296,18 @@ const contentId = useRoute().params.id.replace('.html', '')
       </div>
 
       <div class="content-card watch-tab-content" name="招标/采购进度">
-        <div class="content-block-header">招标/采购进度</div>
+        <div class="flex flex-(row items-center justify-between)">
+          <div class="content-block-header">招标/采购进度</div>
+          <div>
+            <quick-monitor
+              class="action-item"
+              :cache="true"
+              :auto="false"
+              type="project"
+              :params="contentId"
+            />
+          </div>
+        </div>
         <TimeLine :stepList="timeLineList" />
       </div>
 
@@ -729,6 +741,7 @@ const contentId = useRoute().params.id.replace('.html', '')
 
   .content-tab-label {
     flex: 1;
+    max-width: 200px;
     height: 100%;
     display: flex;
     align-items: center;