feat: websocket优化
This commit is contained in:
@@ -73,7 +73,7 @@ class DvadminWebSocket(AsyncJsonWebsocketConsumer):
|
|||||||
unread_count = await _get_message_unread(self.user_id)
|
unread_count = await _get_message_unread(self.user_id)
|
||||||
if unread_count == 0:
|
if unread_count == 0:
|
||||||
# 发送连接成功
|
# 发送连接成功
|
||||||
await self.send_json(set_message('system', 'SYSTEM', '连接成功'))
|
await self.send_json(set_message('system', 'SYSTEM', '您已上线'))
|
||||||
else:
|
else:
|
||||||
await self.send_json(
|
await self.send_json(
|
||||||
set_message('system', 'SYSTEM', "请查看您的未读消息~",
|
set_message('system', 'SYSTEM', "请查看您的未读消息~",
|
||||||
|
|||||||
@@ -59,12 +59,6 @@ onBeforeMount(() => {
|
|||||||
setIntroduction.cssCdn();
|
setIntroduction.cssCdn();
|
||||||
// 设置批量第三方 js
|
// 设置批量第三方 js
|
||||||
setIntroduction.jsCdn();
|
setIntroduction.jsCdn();
|
||||||
//websockt 模块
|
|
||||||
try {
|
|
||||||
//websocket.init(wsReceive)
|
|
||||||
} catch (e) {
|
|
||||||
console.log('websocket错误');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
// 页面加载时
|
// 页面加载时
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -93,6 +87,14 @@ watch(
|
|||||||
() => route.path,
|
() => route.path,
|
||||||
() => {
|
() => {
|
||||||
other.useTitle();
|
other.useTitle();
|
||||||
|
if (!websocket.websocket) {
|
||||||
|
//websockt 模块
|
||||||
|
try {
|
||||||
|
websocket.init(wsReceive)
|
||||||
|
} catch (e) {
|
||||||
|
console.log('websocket错误');
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true,
|
deep: true,
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ export default {
|
|||||||
title4: '消息',
|
title4: '消息',
|
||||||
title5: '开全屏',
|
title5: '开全屏',
|
||||||
title6: '关全屏',
|
title6: '关全屏',
|
||||||
|
retry: '重试上线',
|
||||||
|
onlinePrompt: '当前离线状态,是否重试上线?',
|
||||||
dropdownLarge: '大型',
|
dropdownLarge: '大型',
|
||||||
dropdownDefault: '默认',
|
dropdownDefault: '默认',
|
||||||
dropdownSmall: '小型',
|
dropdownSmall: '小型',
|
||||||
@@ -75,7 +77,7 @@ export default {
|
|||||||
},
|
},
|
||||||
noAccess: {
|
noAccess: {
|
||||||
accessTitle: '您未被授权,没有操作权限~',
|
accessTitle: '您未被授权,没有操作权限~',
|
||||||
accessMsg: '联系方式:加QQ群探讨 665452019',
|
accessMsg: '请联系管理员',
|
||||||
accessBtn: '重新授权',
|
accessBtn: '重新授权',
|
||||||
},
|
},
|
||||||
layout: {
|
layout: {
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ export default {
|
|||||||
},
|
},
|
||||||
noAccess: {
|
noAccess: {
|
||||||
accessTitle: '您未被授權,沒有操作許可權~',
|
accessTitle: '您未被授權,沒有操作許可權~',
|
||||||
accessMsg: '聯繫方式:加QQ群探討665452019',
|
accessMsg: '請聯系管理員',
|
||||||
accessBtn: '重新授權',
|
accessBtn: '重新授權',
|
||||||
},
|
},
|
||||||
layout: {
|
layout: {
|
||||||
|
|||||||
@@ -57,9 +57,33 @@
|
|||||||
:class="!state.isScreenfull ? 'icon-fullscreen' : 'icon-tuichuquanping'"
|
:class="!state.isScreenfull ? 'icon-fullscreen' : 'icon-tuichuquanping'"
|
||||||
></i>
|
></i>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<span v-if="!isSocketOpen">
|
||||||
|
<el-popconfirm
|
||||||
|
width="250"
|
||||||
|
ref="onlinePopoverRef"
|
||||||
|
:confirm-button-text="$t('message.user.retry')"
|
||||||
|
:icon="InfoFilled"
|
||||||
|
trigger="hover"
|
||||||
|
icon-color="#626AEF"
|
||||||
|
:title="$t('message.user.onlinePrompt')"
|
||||||
|
@confirm="onlineConfirmEvent"
|
||||||
|
>
|
||||||
|
<template #reference>
|
||||||
|
<el-badge is-dot class="item" :class="{'online-status': isSocketOpen,'online-down':!isSocketOpen}">
|
||||||
|
<img :src="userInfos.avatar || headerImage" class="layout-navbars-breadcrumb-user-link-photo mr5" />
|
||||||
|
</el-badge>
|
||||||
|
</template>
|
||||||
|
</el-popconfirm>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<el-dropdown :show-timeout="70" :hide-timeout="50" @command="onHandleCommandClick">
|
<el-dropdown :show-timeout="70" :hide-timeout="50" @command="onHandleCommandClick">
|
||||||
<span class="layout-navbars-breadcrumb-user-link">
|
<span class="layout-navbars-breadcrumb-user-link">
|
||||||
<img :src="userInfos.avatar || headerImage" class="layout-navbars-breadcrumb-user-link-photo mr5" />
|
<span v-if="isSocketOpen">
|
||||||
|
<el-badge is-dot class="item" :class="{'online-status': isSocketOpen,'online-down':!isSocketOpen}">
|
||||||
|
<img :src="userInfos.avatar || headerImage" class="layout-navbars-breadcrumb-user-link-photo mr5" />
|
||||||
|
</el-badge>
|
||||||
|
</span>
|
||||||
{{ userInfos.username === '' ? 'common' : userInfos.username }}
|
{{ userInfos.username === '' ? 'common' : userInfos.username }}
|
||||||
<el-icon class="el-icon--right">
|
<el-icon class="el-icon--right">
|
||||||
<ele-ArrowDown />
|
<ele-ArrowDown />
|
||||||
@@ -79,7 +103,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="layoutBreadcrumbUser">
|
<script setup lang="ts" name="layoutBreadcrumbUser">
|
||||||
import { defineAsyncComponent, ref, computed, reactive, onMounted } from 'vue';
|
import { defineAsyncComponent, ref, computed, reactive, onMounted, unref, watch } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { ElMessageBox, ElMessage } from 'element-plus';
|
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||||
import screenfull from 'screenfull';
|
import screenfull from 'screenfull';
|
||||||
@@ -91,6 +115,8 @@ import other from '/@/utils/other';
|
|||||||
import mittBus from '/@/utils/mitt';
|
import mittBus from '/@/utils/mitt';
|
||||||
import { Session, Local } from '/@/utils/storage';
|
import { Session, Local } from '/@/utils/storage';
|
||||||
import headerImage from '/@/assets/img/headerImage.png';
|
import headerImage from '/@/assets/img/headerImage.png';
|
||||||
|
import websocket from '/@/utils/websocket';
|
||||||
|
import { InfoFilled } from '@element-plus/icons-vue'
|
||||||
// 引入组件
|
// 引入组件
|
||||||
const UserNews = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/userNews.vue'));
|
const UserNews = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/userNews.vue'));
|
||||||
const Search = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/search.vue'));
|
const Search = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/search.vue'));
|
||||||
@@ -118,6 +144,21 @@ const layoutUserFlexNum = computed(() => {
|
|||||||
else num = '';
|
else num = '';
|
||||||
return num;
|
return num;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 定义变量内容
|
||||||
|
const { isSocketOpen } = storeToRefs(useUserInfo());
|
||||||
|
|
||||||
|
// websocket状态
|
||||||
|
const onlinePopoverRef = ref()
|
||||||
|
const onlineConfirmEvent = () => {
|
||||||
|
if (!isSocketOpen.value) {
|
||||||
|
websocket.is_reonnect = true
|
||||||
|
websocket.reconnect_current = 1
|
||||||
|
websocket.reconnect()
|
||||||
|
}
|
||||||
|
// 手动隐藏弹出
|
||||||
|
unref(onlinePopoverRef).popperRef?.delayHide?.()
|
||||||
|
}
|
||||||
// 全屏点击时
|
// 全屏点击时
|
||||||
const onScreenfullClick = () => {
|
const onScreenfullClick = () => {
|
||||||
if (!screenfull.isEnabled) {
|
if (!screenfull.isEnabled) {
|
||||||
@@ -256,5 +297,29 @@ const messageCenter = messageCenterStore();
|
|||||||
:deep(.el-badge__content.is-fixed) {
|
:deep(.el-badge__content.is-fixed) {
|
||||||
top: 12px;
|
top: 12px;
|
||||||
}
|
}
|
||||||
|
.online-status{
|
||||||
|
cursor: pointer;
|
||||||
|
:deep .el-badge__content.is-fixed {
|
||||||
|
top: 30px;
|
||||||
|
font-size: 14px;
|
||||||
|
left: 5px;
|
||||||
|
height: 12px;
|
||||||
|
width: 12px;
|
||||||
|
padding: 0;
|
||||||
|
background-color: #18bc9c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.online-down{
|
||||||
|
cursor: pointer;
|
||||||
|
:deep .el-badge__content.is-fixed {
|
||||||
|
top: 30px;
|
||||||
|
font-size: 14px;
|
||||||
|
left: 5px;
|
||||||
|
height: 12px;
|
||||||
|
width: 12px;
|
||||||
|
padding: 0;
|
||||||
|
background-color: #979b9c;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<div class="upgrade-content">
|
<div class="upgrade-content">
|
||||||
{{ getThemeConfig.globalTitle }} {{ $t('message.upgrade.msg') }}
|
{{ getThemeConfig.globalTitle }} {{ $t('message.upgrade.msg') }}
|
||||||
<div class="mt5">
|
<div class="mt5">
|
||||||
<el-link type="primary" class="font12" href="https://gitee.com/lyt-top/vue-next-admin/blob/master/CHANGELOG.md" target="_black">
|
<el-link type="primary" class="font12" href=https://gitee.com/huge-dream/django-vue3-admin/blob/master/CHANGELOG.md" target="_black">
|
||||||
CHANGELOG.md
|
CHANGELOG.md
|
||||||
</el-link>
|
</el-link>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ export interface UserInfosState {
|
|||||||
}
|
}
|
||||||
export interface UserInfosStates {
|
export interface UserInfosStates {
|
||||||
userInfos: UserInfosState;
|
userInfos: UserInfosState;
|
||||||
|
isSocketOpen: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
// 路由缓存列表
|
// 路由缓存列表
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export const useUserInfo = defineStore('userInfo', {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
isSocketOpen: false
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
async updateUserInfos() {
|
async updateUserInfos() {
|
||||||
@@ -57,6 +58,9 @@ export const useUserInfo = defineStore('userInfo', {
|
|||||||
Session.set('userInfo', this.userInfos);
|
Session.set('userInfo', this.userInfos);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async setWebSocketState(socketState: boolean) {
|
||||||
|
this.isSocketOpen = socketState;
|
||||||
|
},
|
||||||
async getApiUserInfo() {
|
async getApiUserInfo() {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/system/user/user_info/',
|
url: '/api/system/user/user_info/',
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import {Session} from "/@/utils/storage";
|
|||||||
import {getWsBaseURL} from "/@/utils/baseUrl";
|
import {getWsBaseURL} from "/@/utils/baseUrl";
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import socket from '@/types/api/socket'
|
import socket from '@/types/api/socket'
|
||||||
|
import {useUserInfo} from "/@/stores/userInfo";
|
||||||
const websocket: socket = {
|
const websocket: socket = {
|
||||||
websocket: null,
|
websocket: null,
|
||||||
connectURL: getWsBaseURL(),
|
connectURL: getWsBaseURL(),
|
||||||
@@ -42,6 +42,7 @@ const websocket: socket = {
|
|||||||
}
|
}
|
||||||
websocket.websocket.onclose = (e: any) => {
|
websocket.websocket.onclose = (e: any) => {
|
||||||
websocket.socket_open = false
|
websocket.socket_open = false
|
||||||
|
useUserInfo().setWebSocketState(websocket.socket_open);
|
||||||
// 需要重新连接
|
// 需要重新连接
|
||||||
if (websocket.is_reonnect) {
|
if (websocket.is_reonnect) {
|
||||||
websocket.reconnect_timer = setTimeout(() => {
|
websocket.reconnect_timer = setTimeout(() => {
|
||||||
@@ -49,6 +50,8 @@ const websocket: socket = {
|
|||||||
if (websocket.reconnect_current > websocket.reconnect_count) {
|
if (websocket.reconnect_current > websocket.reconnect_count) {
|
||||||
clearTimeout(websocket.reconnect_timer)
|
clearTimeout(websocket.reconnect_timer)
|
||||||
websocket.is_reonnect = false
|
websocket.is_reonnect = false
|
||||||
|
websocket.socket_open = false
|
||||||
|
useUserInfo().setWebSocketState(websocket.socket_open);
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 记录重连次数
|
// 记录重连次数
|
||||||
@@ -60,6 +63,7 @@ const websocket: socket = {
|
|||||||
// 连接成功
|
// 连接成功
|
||||||
websocket.websocket.onopen = function () {
|
websocket.websocket.onopen = function () {
|
||||||
websocket.socket_open = true
|
websocket.socket_open = true
|
||||||
|
useUserInfo().setWebSocketState(websocket.socket_open);
|
||||||
websocket.is_reonnect = true
|
websocket.is_reonnect = true
|
||||||
// 开启心跳
|
// 开启心跳
|
||||||
websocket.heartbeat()
|
websocket.heartbeat()
|
||||||
@@ -85,17 +89,21 @@ const websocket: socket = {
|
|||||||
callback && callback()
|
callback && callback()
|
||||||
} else {
|
} else {
|
||||||
clearInterval(websocket.hearbeat_timer)
|
clearInterval(websocket.hearbeat_timer)
|
||||||
message({
|
// message({
|
||||||
type: 'warning',
|
// type: 'warning',
|
||||||
message: 'socket链接已断开',
|
// message: 'socket链接已断开',
|
||||||
duration: 1000,
|
// duration: 1000,
|
||||||
})
|
// })
|
||||||
|
websocket.socket_open = false
|
||||||
|
useUserInfo().setWebSocketState(websocket.socket_open);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
close: () => {
|
close: () => {
|
||||||
websocket.is_reonnect = false
|
websocket.is_reonnect = false
|
||||||
websocket.websocket.close()
|
websocket.websocket.close()
|
||||||
websocket.websocket = null;
|
websocket.websocket = null;
|
||||||
|
websocket.socket_open = false
|
||||||
|
useUserInfo().setWebSocketState(websocket.socket_open);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 重新连接
|
* 重新连接
|
||||||
|
|||||||
Reference in New Issue
Block a user