Forráskód Böngészése

未读消息数量

zhangjie 1 éve
szülő
commit
801a8a6238

+ 5 - 0
src/api/my-workbenches.js

@@ -5,6 +5,11 @@ export const getMyMessages = (data) =>
     url: '/api/sys/message/pageByTypes',
     params: data,
   });
+export const getMyMessagesCount = (types) =>
+  request({
+    url: '/api/sys/message/countByTypes',
+    params: { types },
+  });
 
 export const getMyWaits = (data) =>
   request({

+ 16 - 1
src/layout/children-menu.vue

@@ -11,8 +11,17 @@
         <template v-if="menu.meta.icon" #icon>
           <svg-icon :name="menu.meta.icon"></svg-icon>
         </template>
-        {{ menu.meta.title }}
+        <span>
+          {{ menu.meta.title }}
+        </span>
+        <span
+          v-if="menu.meta?.alias && counts[menu.meta.alias]"
+          class="t-menu__count"
+        >
+          {{ counts[menu.meta?.alias] }}
+        </span>
       </t-menu-item>
+      <!-- 下面这个目前是用不上了 -->
       <t-submenu v-else :value="menu.name">
         <template v-if="menu.meta.icon" #icon>
           <svg-icon :name="menu.meta.icon"></svg-icon>
@@ -30,10 +39,16 @@
 
 <script setup name="ChildrenMenu">
 import { useRouter } from 'vue-router';
+import { useWorkStore } from '@/store';
+import { computed } from 'vue';
 
 defineProps({ modelValue: Array });
 
 const router = useRouter();
+const workStore = useWorkStore();
+
+const counts = computed(() => workStore.counts);
+
 const routerPush = (menu) => {
   if (menu.meta && menu.meta.type === 'L') {
     window.open(menu.path);

+ 39 - 2
src/layout/index.vue

@@ -53,8 +53,8 @@
 </template>
 
 <script setup name="Layout" lang="jsx">
-import { ref, onMounted } from 'vue';
-import { useUserStore } from '@/store';
+import { ref, onMounted, watch } from 'vue';
+import { useUserStore, useWorkStore } from '@/store';
 import { useRouter, useRoute } from 'vue-router';
 import LeftMenu from './left-menu.vue';
 import { moduleMap } from '@/router/asyncRoutes';
@@ -63,6 +63,8 @@ import { ChevronDownIcon } from 'tdesign-icons-vue-next';
 const router = useRouter();
 const route = useRoute();
 const userStore = useUserStore();
+const workStore = useWorkStore();
+
 const moduleChange = (name) => {
   userStore.setCurPageModule(name);
   router.push({ name });
@@ -86,6 +88,24 @@ const clickHandler = (data) => {
     userStore.logout();
   }
 };
+
+watch(
+  () => userStore.curPageModule,
+  (val) => {
+    if (val !== 'MyWorkbenches') return;
+    workStore.updateWorkCounts();
+  },
+  {
+    immediate: true,
+  }
+);
+watch(
+  () => route.name,
+  () => {
+    if (userStore.curPageModule !== 'MyWorkbenches') return;
+    workStore.updateWorkCounts();
+  }
+);
 </script>
 
 <style lang="less" scoped>
@@ -206,6 +226,23 @@ const clickHandler = (data) => {
         }
       }
     }
+    :deep(.t-menu__content) {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      flex-grow: 2;
+    }
+    :deep(.t-menu__count) {
+      color: #fff;
+      padding: 0 3px;
+      background-color: var(--td-error-color);
+      line-height: 20px;
+      height: 20px;
+      border-radius: 3px;
+      min-width: 20px;
+      text-align: center;
+      font-size: 12px;
+    }
     :deep(.t-menu__item .svg-icon) {
       margin-right: 8px;
     }

+ 2 - 1
src/store/index.js

@@ -1,9 +1,10 @@
 import { createPinia } from 'pinia';
 import useAppStore from './modules/app';
 import useUserStore from './modules/user';
+import useWorkStore from './modules/work';
 import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
 
 const pinia = createPinia();
 pinia.use(piniaPluginPersistedstate);
-export { useAppStore, useUserStore };
+export { useAppStore, useUserStore, useWorkStore };
 export default pinia;

+ 51 - 0
src/store/modules/work.js

@@ -0,0 +1,51 @@
+import { defineStore } from 'pinia';
+
+import { getMyMessagesCount, getMyWaits } from '@/api/my-workbenches';
+import { MESSAGE_TYPE } from '@/config/constants';
+
+const useWorkStore = defineStore('work', {
+  state: () => ({
+    counts: {
+      message: 0,
+      work: 0,
+      notice: 0,
+    },
+  }),
+  actions: {
+    async updateWorkCounts() {
+      const task = [
+        {
+          type: 'message',
+          func: () => getMyMessagesCount(Object.keys(MESSAGE_TYPE).join()),
+        },
+        {
+          type: 'work',
+          func: async () => {
+            const data = await getMyWaits({
+              flowTaskTypeEnum: 'ALL',
+              pageNumber: 1,
+              pageSize: 1,
+            });
+
+            return data ? data.total : 0;
+          },
+        },
+        {
+          type: 'notice',
+          func: () => getMyMessagesCount('SYSTEM'),
+        },
+      ];
+      let countAll = task.map((item) => item.func());
+      const data = await Promise.all(countAll).catch(() => {});
+      if (!data) return;
+
+      let counts = {};
+      data.forEach((count, index) => {
+        counts[task[index].type] = count;
+      });
+      this.counts = counts;
+    },
+  },
+});
+
+export default useWorkStore;

+ 20 - 0
src/style/global.less

@@ -124,6 +124,7 @@ body {
   transition: all 0.2s linear;
   touch-action: manipulation;
   text-decoration: none;
+  position: relative;
 
   height: var(--td-comp-size-xl);
   font: var(--td-font-body-large);
@@ -138,6 +139,20 @@ body {
     color: var(--td-brand-color);
     background-color: #e8f3ff;
   }
+  &.is-mark {
+    &::after {
+      content: '';
+      display: block;
+      position: absolute;
+      width: 8px;
+      height: 8px;
+      background: var(--td-error-color);
+      border-radius: 50%;
+      top: 50%;
+      margin-top: -4px;
+      right: 8px;
+    }
+  }
   &:not(.is-active):hover {
     background-color: var(--td-gray-color-3);
   }
@@ -208,6 +223,11 @@ body {
     margin-top: 20px;
   }
 }
+.box-justify {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
 
 .text-indent {
   text-indent: 2em;

+ 9 - 1
src/views/my-workbenches/workbenches/message-reminder/index.vue

@@ -4,7 +4,13 @@
       <div
         v-for="item in tabs"
         :key="item.value"
-        :class="['page-tab', { 'is-active': params.status === item.value }]"
+        :class="[
+          'page-tab',
+          {
+            'is-active': params.status === item.value,
+            'is-mark': item.value === 'false' && workStore.counts.notice,
+          },
+        ]"
         @click="switchTab(item)"
         >{{ item.label }}</div
       >
@@ -34,7 +40,9 @@ import { getMyMessages } from '@/api/my-workbenches';
 import { MESSAGE_TYPE } from '@/config/constants';
 import { dictToOptionList } from '@/utils/tool';
 import MessageList from './message-list.vue';
+import { useWorkStore } from '@/store';
 
+const workStore = useWorkStore();
 const tabs = [
   {
     label: '全部',

+ 10 - 1
src/views/my-workbenches/workbenches/notice/index.vue

@@ -4,7 +4,13 @@
       <div
         v-for="item in tabs"
         :key="item.value"
-        :class="['page-tab', { 'is-active': params.status === item.value }]"
+        :class="[
+          'page-tab',
+          {
+            'is-active': params.status === item.value,
+            'is-mark': item.value === 'false' && workStore.counts.notice,
+          },
+        ]"
         @click="switchTab(item)"
         >{{ item.label }}</div
       >
@@ -55,6 +61,9 @@ import { getMyMessages } from '@/api/my-workbenches';
 import NoticeList from './notice-list.vue';
 import { omit } from 'lodash';
 import { dateFormat } from '@/utils/tool';
+import { useWorkStore } from '@/store';
+
+const workStore = useWorkStore();
 
 const curNotice = ref({});
 const visible = ref(false);