feat: 轮询查询未读消息
This commit is contained in:
12
src/App.vue
12
src/App.vue
@ -5,14 +5,16 @@
|
|||||||
</a-config-provider>
|
</a-config-provider>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup>
|
||||||
import { useUserStore } from '@/stores';
|
import { useUserStore } from '@/stores';
|
||||||
|
|
||||||
import { getUserEnterpriseInfo } from '@/utils/user';
|
import { getUserEnterpriseInfo } from '@/utils/user';
|
||||||
|
import { useSidebarStore } from '@/stores/modules/side-bar';
|
||||||
|
|
||||||
import zhCN from '@arco-design/web-vue/es/locale/lang/zh-cn';
|
import zhCN from '@arco-design/web-vue/es/locale/lang/zh-cn';
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const sidebarStore = useSidebarStore();
|
||||||
|
|
||||||
const redTheme = {
|
const redTheme = {
|
||||||
token: {
|
token: {
|
||||||
@ -20,7 +22,6 @@ const redTheme = {
|
|||||||
colorLink: '#f5222d', // 链接色
|
colorLink: '#f5222d', // 链接色
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
// 初始化企业信息
|
|
||||||
|
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
const { isLogin, getUserInfo } = userStore;
|
const { isLogin, getUserInfo } = userStore;
|
||||||
@ -28,6 +29,10 @@ const init = async () => {
|
|||||||
if (isLogin) {
|
if (isLogin) {
|
||||||
await getUserInfo(); // 初始化用户信息
|
await getUserInfo(); // 初始化用户信息
|
||||||
await getUserEnterpriseInfo();
|
await getUserEnterpriseInfo();
|
||||||
|
|
||||||
|
sidebarStore.startUnreadInfoPolling();
|
||||||
|
} else {
|
||||||
|
sidebarStore.stopUnreadInfoPolling();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -40,6 +45,9 @@ onMounted(() => {
|
|||||||
console.error(`发现catch报错:${event.reason}`);
|
console.error(`发现catch报错:${event.reason}`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
sideBarStore.stopUnreadInfoPolling();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
@ -33,3 +33,13 @@ export const deleteTask = (id: string) => {
|
|||||||
export const getTaskStatus = (id: string) => {
|
export const getTaskStatus = (id: string) => {
|
||||||
return Http.get(`/v1/tasks/${id}/status`);
|
return Http.get(`/v1/tasks/${id}/status`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 任务中心-获取未读任务
|
||||||
|
export const getTaskUnread = () => {
|
||||||
|
return Http.get(`/v1/tasks/unread`);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 任务中心-已读
|
||||||
|
export const patchTaskRead = (params = {}) => {
|
||||||
|
return Http.patch('/v1/tasks/read', params);
|
||||||
|
};
|
||||||
@ -1,11 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="right-wrap">
|
<div class="right-wrap">
|
||||||
<SvgIcon
|
<div class="relative mr-12px" @click="sideBarStore.removeTaskUnreadInfo">
|
||||||
name="svg-taskCenter"
|
<SvgIcon
|
||||||
size="16"
|
name="svg-taskCenter"
|
||||||
class="cursor-pointer color-#737478 hover:color-#6D4CFE mr-12px"
|
size="16"
|
||||||
@click="openDownloadCenter"
|
class="cursor-pointer color-#737478 hover:color-#6D4CFE"
|
||||||
/>
|
@click="openDownloadCenter"
|
||||||
|
/>
|
||||||
|
<div class="w-4px h-4px rounded-50% bg-#F64B31 absolute top-1px right-1px" v-if="hasUnreadInfo"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<a-dropdown trigger="click" class="layout-avatar-dropdown">
|
<a-dropdown trigger="click" class="layout-avatar-dropdown">
|
||||||
<a-avatar class="cursor-pointer" :size="32">
|
<a-avatar class="cursor-pointer" :size="32">
|
||||||
@ -70,6 +73,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import router from '@/router';
|
import router from '@/router';
|
||||||
import { useEnterpriseStore } from '@/stores/modules/enterprise';
|
import { useEnterpriseStore } from '@/stores/modules/enterprise';
|
||||||
|
import { useSidebarStore } from '@/stores/modules/side-bar';
|
||||||
import { useUserStore } from '@/stores';
|
import { useUserStore } from '@/stores';
|
||||||
|
|
||||||
import ExitAccountModal from '@/components/_base/exit-account-modal';
|
import ExitAccountModal from '@/components/_base/exit-account-modal';
|
||||||
@ -81,6 +85,9 @@ import icon3 from '@/assets/change.svg';
|
|||||||
|
|
||||||
const enterpriseStore = useEnterpriseStore();
|
const enterpriseStore = useEnterpriseStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const sideBarStore = useSidebarStore();
|
||||||
|
|
||||||
|
const hasUnreadInfo = computed(() => sideBarStore.unreadInfo.length)
|
||||||
|
|
||||||
const exitAccountModalRef = ref(null);
|
const exitAccountModalRef = ref(null);
|
||||||
const downloadCenterModalRef = ref(null);
|
const downloadCenterModalRef = ref(null);
|
||||||
|
|||||||
@ -7,18 +7,22 @@ import router from '@/router';
|
|||||||
import type { RouteLocationNormalized } from 'vue-router';
|
import type { RouteLocationNormalized } from 'vue-router';
|
||||||
import { MENU_LIST } from './constants';
|
import { MENU_LIST } from './constants';
|
||||||
import { useEnterpriseStore } from '@/stores/modules/enterprise';
|
import { useEnterpriseStore } from '@/stores/modules/enterprise';
|
||||||
|
import { getTaskUnread, patchTaskRead } from '@/api/all/common';
|
||||||
|
|
||||||
interface sidebarState {
|
interface sidebarState {
|
||||||
activeMenuId: number | null;
|
activeMenuId: number | null;
|
||||||
menuList: any[];
|
menuList: any[];
|
||||||
allowAccessRoutes: any[];
|
allowAccessRoutes: any[];
|
||||||
|
unreadInfo: number[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let unreadInfoTimer: number | null = null;
|
||||||
|
|
||||||
export const useSidebarStore = defineStore('sidebar', {
|
export const useSidebarStore = defineStore('sidebar', {
|
||||||
state: (): sidebarState => ({
|
state: (): sidebarState => ({
|
||||||
activeMenuId: null,
|
activeMenuId: null, //
|
||||||
menuList: [],
|
menuList: [], // 菜单信息
|
||||||
|
unreadInfo: [], // 未读消息
|
||||||
allowAccessRoutes: [], // 允许访问的路由列表
|
allowAccessRoutes: [], // 允许访问的路由列表
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
@ -42,17 +46,13 @@ export const useSidebarStore = defineStore('sidebar', {
|
|||||||
setActiveMenuIdByRoute(route: RouteLocationNormalized) {
|
setActiveMenuIdByRoute(route: RouteLocationNormalized) {
|
||||||
const appRoutes = router.options?.routes ?? [];
|
const appRoutes = router.options?.routes ?? [];
|
||||||
|
|
||||||
// 查找当前路由所属的菜单组
|
|
||||||
const findMenuGroup = (routes: any[]): number | null => {
|
const findMenuGroup = (routes: any[]): number | null => {
|
||||||
for (const routeItem of routes) {
|
for (const routeItem of routes) {
|
||||||
// 检查子路由
|
|
||||||
if (routeItem.children?.length > 0) {
|
if (routeItem.children?.length > 0) {
|
||||||
// 检查当前路由是否是这个父路由的子路由
|
|
||||||
const isChildRoute = routeItem.children.some((child: any) => child.name === route.name);
|
const isChildRoute = routeItem.children.some((child: any) => child.name === route.name);
|
||||||
if (isChildRoute) {
|
if (isChildRoute) {
|
||||||
return routeItem.meta?.id || null;
|
return routeItem.meta?.id || null;
|
||||||
}
|
}
|
||||||
// 递归检查更深层的子路由
|
|
||||||
const childResult = findMenuGroup(routeItem.children);
|
const childResult = findMenuGroup(routeItem.children);
|
||||||
if (childResult !== null) {
|
if (childResult !== null) {
|
||||||
return routeItem.meta?.id || childResult;
|
return routeItem.meta?.id || childResult;
|
||||||
@ -71,5 +71,32 @@ export const useSidebarStore = defineStore('sidebar', {
|
|||||||
this.activeMenuId = menuId;
|
this.activeMenuId = menuId;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async getTaskUnreadInfo() {
|
||||||
|
const { code, data } = await getTaskUnread();
|
||||||
|
if (code === 200) {
|
||||||
|
this.unreadInfo = data;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询未读信息
|
||||||
|
startUnreadInfoPolling() {
|
||||||
|
if (unreadInfoTimer) return;
|
||||||
|
this.getTaskUnreadInfo();
|
||||||
|
unreadInfoTimer = window.setInterval(() => {
|
||||||
|
this.getTaskUnreadInfo();
|
||||||
|
}, 30000);
|
||||||
|
},
|
||||||
|
stopUnreadInfoPolling() {
|
||||||
|
this.unreadInfo = [];
|
||||||
|
if (unreadInfoTimer) {
|
||||||
|
clearInterval(unreadInfoTimer);
|
||||||
|
unreadInfoTimer = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async removeTaskUnreadInfo() {
|
||||||
|
console.log('removeTaskUnreadInfo');
|
||||||
|
patchTaskRead({ ids: this.unreadInfo });
|
||||||
|
this.unreadInfo = [];
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -47,7 +47,7 @@ export const useUserStore = defineStore('user', {
|
|||||||
slsWithCatch('accessToken', this.token);
|
slsWithCatch('accessToken', this.token);
|
||||||
},
|
},
|
||||||
|
|
||||||
deleteToken() {
|
clearToken() {
|
||||||
this.token = '';
|
this.token = '';
|
||||||
rlsWithCatch('accessToken');
|
rlsWithCatch('accessToken');
|
||||||
},
|
},
|
||||||
|
|||||||
@ -12,13 +12,13 @@ import { useSidebarStore } from '@/stores/modules/side-bar';
|
|||||||
export function goUserLogin(query?: any) {
|
export function goUserLogin(query?: any) {
|
||||||
router.push({ name: 'UserLogin', query });
|
router.push({ name: 'UserLogin', query });
|
||||||
}
|
}
|
||||||
// 初始化企业信息、navbar菜单、允许访问的路由
|
|
||||||
export const getUserEnterpriseInfo = async () => {
|
export const getUserEnterpriseInfo = async () => {
|
||||||
const enterpriseStore = useEnterpriseStore();
|
const enterpriseStore = useEnterpriseStore();
|
||||||
const sidebarStore = useSidebarStore();
|
const sidebarStore = useSidebarStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|
||||||
await enterpriseStore.getEnterpriseInfo();
|
await enterpriseStore.getEnterpriseInfo(); // 初始化企业信息
|
||||||
sidebarStore.getUserNavbarMenuList(); // 初始化navbar菜单
|
sidebarStore.getUserNavbarMenuList(); // 初始化navbar菜单
|
||||||
userStore.getUserAllowAccessRoutes(); // 初始化允许访问的路由
|
userStore.getUserAllowAccessRoutes(); // 初始化允许访问的路由
|
||||||
};
|
};
|
||||||
@ -26,9 +26,11 @@ export const getUserEnterpriseInfo = async () => {
|
|||||||
// 登录处理
|
// 登录处理
|
||||||
export async function handleUserLogin() {
|
export async function handleUserLogin() {
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const sidebarStore = useSidebarStore();
|
||||||
|
|
||||||
await userStore.getUserInfo(); // 初始化用户信息
|
await userStore.getUserInfo(); // 初始化用户信息
|
||||||
await getUserEnterpriseInfo();
|
await getUserEnterpriseInfo(); // 初始化企业信息、navbar菜单、允许访问的路由
|
||||||
|
sidebarStore.startUnreadInfoPolling(); // 初始化未读信息
|
||||||
|
|
||||||
handleUserHome();
|
handleUserHome();
|
||||||
}
|
}
|
||||||
@ -38,18 +40,19 @@ export function handleUserHome() {
|
|||||||
router.push({ name: 'Home' });
|
router.push({ name: 'Home' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 登出处理
|
||||||
export function handleUserLogout() {
|
export function handleUserLogout() {
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const enterpriseStore = useEnterpriseStore();
|
const enterpriseStore = useEnterpriseStore();
|
||||||
const sidebarStore = useSidebarStore();
|
const sidebarStore = useSidebarStore();
|
||||||
|
|
||||||
userStore.clearUserInfo();
|
userStore.clearUserInfo(); // 清除用户信息
|
||||||
enterpriseStore.clearUserEnterpriseInfo();
|
userStore.clearToken(); // 清除token
|
||||||
sidebarStore.clearUserNavbarMenuList();
|
enterpriseStore.clearUserEnterpriseInfo(); // 清除企业信息
|
||||||
userStore.clearUserAllowAccessRoutes();
|
sidebarStore.clearUserNavbarMenuList(); // 清除navbar菜单信息
|
||||||
|
userStore.clearUserAllowAccessRoutes(); // 清除权限路由列表
|
||||||
sidebarStore.clearActiveMenuId();
|
sidebarStore.stopUnreadInfoPolling(); // 清除未读消息
|
||||||
userStore.deleteToken();
|
sidebarStore.clearActiveMenuId(); // 清除active菜单id
|
||||||
|
|
||||||
goUserLogin();
|
goUserLogin();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user