From b32dee58866e80f7e69f8a03a3edb9eda9d19100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=99=E8=BF=90=E6=A8=A1?= <1724894114@qq.com> Date: Sat, 13 Jul 2024 15:46:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=81=E8=A3=85=E5=AF=BC=E5=87=BA=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 4 +- src/api/model/system.js | 7 + src/assets/icons/Download.vue | 4 +- src/assets/icons/Finish.vue | 13 ++ src/assets/icons/index.js | 1 + src/components/scExport/index.vue | 102 +++++++++++++++ src/layout/index.vue | 13 +- src/scui.js | 4 + src/utils/websocket.js | 194 ++++++++++++++++++++++++++++ src/views/setting/company/index.vue | 8 +- 10 files changed, 343 insertions(+), 7 deletions(-) create mode 100644 src/assets/icons/Finish.vue create mode 100644 src/components/scExport/index.vue create mode 100644 src/utils/websocket.js diff --git a/.env.development b/.env.development index f6a8a1a..7e2a07d 100644 --- a/.env.development +++ b/.env.development @@ -10,8 +10,8 @@ VUE_APP_API_BASEURL = https://xwapi.dev.dwoodauto.com/api/v1 VUE_APP_API_DEV = https://xwapi.dev.dwoodauto.com # WS地址 -VUE_APP_WS_URL = wss://api.dev.dwoodauto.com/wss -VUE_APP_WSS_URL = wss://api.dev.dwoodauto.com/wss +VUE_APP_WS_URL = wss://xwapi.dev.dwoodauto.com/wss +VUE_APP_WSS_URL = wss://xwapi.dev.dwoodauto.com/wss # 本地端口 VUE_APP_PORT = 2801 diff --git a/src/api/model/system.js b/src/api/model/system.js index 9e2170d..997ff2c 100644 --- a/src/api/model/system.js +++ b/src/api/model/system.js @@ -212,6 +212,13 @@ export default { post: async function (params) { return await http.post(this.url,params); } + }, + export:{ + url: `${config.API_URL}/organization.export`, + name: "公司资料导出", + post: async function (params) { + return await http.post(this.url,params); + } } }, dept: { diff --git a/src/assets/icons/Download.vue b/src/assets/icons/Download.vue index 3b139da..6698cca 100644 --- a/src/assets/icons/Download.vue +++ b/src/assets/icons/Download.vue @@ -1,3 +1,3 @@ \ No newline at end of file + + diff --git a/src/assets/icons/Finish.vue b/src/assets/icons/Finish.vue new file mode 100644 index 0000000..f3d7da8 --- /dev/null +++ b/src/assets/icons/Finish.vue @@ -0,0 +1,13 @@ + + + + + diff --git a/src/assets/icons/index.js b/src/assets/icons/index.js index 5d26759..184bbae 100644 --- a/src/assets/icons/index.js +++ b/src/assets/icons/index.js @@ -21,6 +21,7 @@ export { default as Secure } from './Secure.vue' export { default as UserLog } from './Log.vue' export { default as WechartRound } from './WechartRound.vue' export { default as Cost } from './Cost.vue' +export { default as Finish } from './Finish.vue' // 列表按钮 export { default as Delete } from './Delete.vue' diff --git a/src/components/scExport/index.vue b/src/components/scExport/index.vue new file mode 100644 index 0000000..c41751c --- /dev/null +++ b/src/components/scExport/index.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/src/layout/index.vue b/src/layout/index.vue index 696dd13..6ddc38b 100644 --- a/src/layout/index.vue +++ b/src/layout/index.vue @@ -242,9 +242,18 @@ created() { this.onLayoutResize(); window.addEventListener('resize', this.onLayoutResize); - var menu = this.$router.sc_getMenu(); + const menu = this.$router.sc_getMenu(); this.menu = this.filterUrl(menu); - this.showThis() + this.showThis(); + + let token = this.$TOOL.cookie.get('TOKEN'); + if (token && token != null) { + let global_callback = function () {}; + this.$socketApi.createWebSocket(global_callback); + + // 获取新消息 + // this.$socketApi.getSock(this.getWsResult); + } }, watch: { $route() { diff --git a/src/scui.js b/src/scui.js index 459a5d2..8fad5f2 100644 --- a/src/scui.js +++ b/src/scui.js @@ -26,6 +26,7 @@ import scMultipleSelect from "./components/scMultipleSelect"; import scInput from "./components/scInput"; import scVgInput from "./components/scInput/inputVague"; import scSearch from "./components/scSearch"; +import scExport from "./components/scExport"; import scStatusIndicator from './components/scMini/scStatusIndicator' import scTrend from './components/scMini/scTrend' @@ -40,6 +41,7 @@ import errorHandler from './utils/errorHandler' import * as elIcons from '@element-plus/icons-vue' import * as scIcons from './assets/icons' +import * as socketApi from "@/utils/websocket"; export default { install(app) { @@ -50,6 +52,7 @@ export default { app.config.globalProperties.$API = api; app.config.globalProperties.$AUTH = permission; app.config.globalProperties.$ROLE = rolePermission; + app.config.globalProperties.$socketApi = socketApi; //注册全局组件 app.component('scTable', scTable); @@ -76,6 +79,7 @@ export default { app.component('scInput', scInput); app.component('scVgInput', scVgInput); app.component('scSearch', scSearch); + app.component('scExport', scExport); //注册全局指令 app.directive('auth', auth) diff --git a/src/utils/websocket.js b/src/utils/websocket.js new file mode 100644 index 0000000..19413c1 --- /dev/null +++ b/src/utils/websocket.js @@ -0,0 +1,194 @@ +//@eslint-disable + +import tool from '@/utils/tool'; +import systemConfig from '@/config'; +import api from '../api'; +import router from "@/router"; +import {ElNotification} from 'element-plus'; +// import store from "../store"; + +let websocket = null; +let global_callback = function () {}; +let timeoutObj = null; +let timeout = 28 * 1000; //30秒一次心跳 +let serverTimeoutObj = 60; //心跳倒计时 +let timeOutNum = 60; //断开 重连倒计时 +let lockReconnect = false; //是否真正建立连接 +const wsUri = systemConfig.WS_URL; +let showNot = null; + +function networkDes() { + ElNotification.error({ + title: '网络已断开', + message: '网络已断开,正在重连……' + }) +} + +function reConnect() {//重新连接 + if (lockReconnect) { + return; + } + lockReconnect = true; + //没连接上会一直重连,设置延迟避免请求过多 + timeOutNum && clearTimeout(timeOutNum); + timeOutNum = setTimeout(function () { + //新连接 + createWebSocket(global_callback); + lockReconnect = false; + }, 5000); +} + +function startHeartbeat() { + //清除时间 + clearTimeout(timeoutObj); + clearTimeout(serverTimeoutObj); + start(); +} + +function start() {//开启心跳 + timeoutObj && clearTimeout(timeoutObj); + serverTimeoutObj && clearTimeout(serverTimeoutObj); + timeoutObj = setTimeout(function () { + //这里发送一个心跳,后端收到后,返回一个心跳消息, + if (websocket.readyState === 1) {//如果连接正常 + const heart = {type: "heart"} + websocket.send(JSON.stringify(heart)); + } else {//否则重连 + reConnect(); + } + serverTimeoutObj = setTimeout(function () { + //超时关闭 + closeSock(false); + }, timeout); + }, timeout) +} + +function createWebSocket(callback, token) { + if (websocket == null || typeof websocket !== WebSocket) { + initWebSocket(callback, token); + } +} + +function initWebSocket(callback, token) { + global_callback = callback; + // 初始化websocket + let reToken = token === undefined ? tool.cookie.get('TOKEN') : token; + if(!reToken) return // 没有token 不执行ws创建 + websocket = new WebSocket(wsUri + "?token=Bearer " + reToken); + websocket.onmessage = function (e) { + webSocketOnMessage(e); + }; + websocket.onclose = function (e) { + webSocketClose(e); + }; + websocket.onopen = function () { + websocketOpen(); + }; + + // 连接发生错误的回调方法 + websocket.onerror = function () { + networkDes() + reConnect() + }; +} + +// 实际调用的方法 +function sendSock(agentData) { + if (websocket.readyState === websocket.OPEN) { + // 若是ws开启状态 + webSocketSend(agentData); + } else if (websocket.readyState === websocket.CONNECTING) { + // 若是 正在开启状态,则等待1s后重新调用 + setTimeout(function () { + sendSock(agentData); + }, 1000); + } else { + // 若未开启 ,则等待1s后重新调用 + setTimeout(function () { + sendSock(agentData); + }, 1000); + } +} + +function closeSock(active) { + lockReconnect = active; // 主动断开时不重连 + websocket.close(); +} + +// 数据接收 +function webSocketOnMessage(msg) { + // 收到信息为Blob类型时 + let result = null; + // debugger + // 二进制文件 + if (msg.data instanceof Blob) { + const reader = new FileReader(); + reader.readAsText(msg.data, "UTF-8"); + reader.onload = () => { + result = JSON.parse(reader.result); + global_callback(result); + }; + } else { + if(msg.type === "") return + result = JSON.parse(msg.data); + // if(result.type == 13){ + // store.commit("SET_WS_Msg_NUM", result.data.todo_msg_count); + // } + if(global_callback){ + global_callback(result); + } + } + if (result.type == -1 || result.type == 8 || result.type == 9) { + if(result.type == -1){ + if(result.data && result.data.token){ + tool.cookie.set("TOKEN", result.data.token); + } + }else{ + showNot = ElNotification.error({ + title: '系统退出', + message: result.msg, + duration:0 + }); + handleError('系统退出', result.msg); + } + } + + if(result.type == 'init'){ + if(showNot && showNot.close){ + showNot.close(); + } + } + startHeartbeat() +} + +function handleError() { + api.system.user.logout.post().then(); + router.replace({ path: "/login" }).then(); + closeSock(true); +} + +function getSock(callback) { + global_callback = callback +} + +// 数据发送 +function webSocketSend(agentData) { + websocket.send(agentData); +} + +// 关闭 +function webSocketClose() { + reConnect() +} + +function websocketOpen() { + start() +} + +export { + sendSock, + createWebSocket, + closeSock, + getSock, + reConnect, +}; diff --git a/src/views/setting/company/index.vue b/src/views/setting/company/index.vue index 01d915e..23a4082 100644 --- a/src/views/setting/company/index.vue +++ b/src/views/setting/company/index.vue @@ -6,7 +6,7 @@ 批量导入
- 下载 +
@@ -206,6 +206,12 @@ export default { delete row.$switch_yx; }, 500); }, + async exportData() { + const res = await this.$API.system.company.export.post(); + if(res.code == 200){ + this.$message.success('开始导出'); + } + }, upSearch(){ this.$refs.table.upData(this.params); },