|
|
@@ -732,6 +732,7 @@ export default {
|
|
|
pendingTasks: 0,
|
|
|
pollInterval: null,
|
|
|
timer: null,
|
|
|
+ eventSource: null, // SSE 连接对象
|
|
|
selectedRole: '',
|
|
|
permissions: [] // 存储权限数据
|
|
|
}
|
|
|
@@ -833,6 +834,8 @@ export default {
|
|
|
_this.loadRolePermissions()
|
|
|
localStorage.removeItem('menulink')
|
|
|
_this.link = ''
|
|
|
+ // 登录成功后建立 SSE 连接
|
|
|
+ _this.initEventSource()
|
|
|
_this.$router.push({ name: 'web_index' })
|
|
|
window.setTimeout(() => {
|
|
|
location.reload()
|
|
|
@@ -857,6 +860,8 @@ export default {
|
|
|
},
|
|
|
Logout () {
|
|
|
var _this = this
|
|
|
+ // 登出时关闭 SSE 连接
|
|
|
+ _this.closeEventSource()
|
|
|
_this.authin = '0'
|
|
|
_this.login_name = ''
|
|
|
LocalStorage.remove('auth')
|
|
|
@@ -1006,12 +1011,104 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
handleTimer () {
|
|
|
+ // 保留此方法作为备用,但不再使用轮询
|
|
|
getauth('/wms/inboundBills/?bound_status=0').then((res) => {
|
|
|
this.ERPTasks = res.count
|
|
|
})
|
|
|
getauth('/wms/outboundBills/?bound_status=0').then((res) => {
|
|
|
this.ERPOutTasks = res.count
|
|
|
})
|
|
|
+ },
|
|
|
+ // 初始化 SSE 连接
|
|
|
+ initEventSource () {
|
|
|
+ var _this = this
|
|
|
+
|
|
|
+ // 如果已经存在连接,先关闭
|
|
|
+ if (_this.eventSource) {
|
|
|
+ _this.eventSource.close()
|
|
|
+ }
|
|
|
+
|
|
|
+ // 只有在已登录的情况下才建立连接
|
|
|
+ if (!LocalStorage.has('auth') || LocalStorage.getItem('auth') !== '1') {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建 SSE URL(确保路径正确)
|
|
|
+ let baseUrl = baseurl
|
|
|
+ // 如果 baseurl 以 /api 结尾,移除它
|
|
|
+ if (baseUrl.endsWith('/api')) {
|
|
|
+ baseUrl = baseUrl.slice(0, -4)
|
|
|
+ } else if (baseUrl.endsWith('/api/')) {
|
|
|
+ baseUrl = baseUrl.slice(0, -5)
|
|
|
+ }
|
|
|
+ // 确保 baseUrl 不以 / 结尾
|
|
|
+ baseUrl = baseUrl.replace(/\/+$/, '')
|
|
|
+ const sseUrl = `${baseUrl}/wms/tasks/stream/`
|
|
|
+
|
|
|
+ // 创建 EventSource 连接
|
|
|
+ try {
|
|
|
+ _this.eventSource = new EventSource(sseUrl)
|
|
|
+
|
|
|
+ // 监听消息
|
|
|
+ _this.eventSource.onmessage = function (event) {
|
|
|
+ try {
|
|
|
+ const data = JSON.parse(event.data)
|
|
|
+ _this.ERPTasks = data.inbound_tasks || 0
|
|
|
+ _this.ERPOutTasks = data.outbound_tasks || 0
|
|
|
+ } catch (e) {
|
|
|
+ console.error('解析 SSE 数据失败:', e)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 监听心跳事件
|
|
|
+ _this.eventSource.addEventListener('heartbeat', function (event) {
|
|
|
+ try {
|
|
|
+ const data = JSON.parse(event.data)
|
|
|
+ console.log('SSE 心跳:', data.message, new Date(data.timestamp * 1000).toLocaleTimeString())
|
|
|
+ } catch (e) {
|
|
|
+ console.log('SSE 心跳收到')
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ // 处理错误
|
|
|
+ _this.eventSource.onerror = function (error) {
|
|
|
+ console.error('SSE 连接错误:', error)
|
|
|
+
|
|
|
+ // 连接断开后,延迟重连(避免频繁重连)
|
|
|
+ setTimeout(() => {
|
|
|
+ if (_this.eventSource && _this.eventSource.readyState === EventSource.CLOSED) {
|
|
|
+ _this.initEventSource()
|
|
|
+ }
|
|
|
+ }, 5000)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 连接成功
|
|
|
+ _this.eventSource.onopen = function () {
|
|
|
+ console.log('SSE 连接已建立')
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.error('创建 SSE 连接失败:', e)
|
|
|
+ // 如果 SSE 不支持,回退到轮询
|
|
|
+ _this.fallbackToPolling()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 回退到轮询模式
|
|
|
+ fallbackToPolling () {
|
|
|
+ var _this = this
|
|
|
+ _this.timer = setInterval(() => {
|
|
|
+ _this.handleTimer()
|
|
|
+ }, 30000) // 30秒轮询一次作为备用
|
|
|
+ },
|
|
|
+ // 关闭 SSE 连接
|
|
|
+ closeEventSource () {
|
|
|
+ if (this.eventSource) {
|
|
|
+ this.eventSource.close()
|
|
|
+ this.eventSource = null
|
|
|
+ }
|
|
|
+ if (this.timer) {
|
|
|
+ clearInterval(this.timer)
|
|
|
+ this.timer = null
|
|
|
+ }
|
|
|
}
|
|
|
},
|
|
|
created () {
|
|
|
@@ -1043,21 +1140,26 @@ export default {
|
|
|
mounted () {
|
|
|
var _this = this
|
|
|
_this.warehouseOptionsGet()
|
|
|
- _this.handleTimer()
|
|
|
_this.link = localStorage.getItem('menulink')
|
|
|
Bus.$on('needLogin', (val) => {
|
|
|
_this.isLoggedIn()
|
|
|
})
|
|
|
_this.loadRolePermissions()
|
|
|
|
|
|
- _this.timer = setInterval(() => {
|
|
|
- _this.handleTimer()
|
|
|
- }, 1000000)
|
|
|
+ // 初始化时先获取一次数据
|
|
|
+ _this.handleTimer()
|
|
|
+
|
|
|
+ // 使用 SSE 替代轮询
|
|
|
+ if (_this.authin === '1') {
|
|
|
+ _this.initEventSource()
|
|
|
+ }
|
|
|
},
|
|
|
// 修改时间 :10000
|
|
|
updated () {},
|
|
|
beforeDestroy () {
|
|
|
Bus.$off('needLogin')
|
|
|
+ // 组件销毁时关闭 SSE 连接
|
|
|
+ this.closeEventSource()
|
|
|
},
|
|
|
destroyed () {},
|
|
|
watch: {
|