更新
This commit is contained in:
parent
e91fcab0c8
commit
1a1a3a9129
@ -37,7 +37,9 @@ export default {
|
|||||||
this.outputData.push(item.outputNum)
|
this.outputData.push(item.outputNum)
|
||||||
this.goodRateData.push(item.goodRate)
|
this.goodRateData.push(item.goodRate)
|
||||||
})
|
})
|
||||||
|
this.$nextTick(()=>{
|
||||||
this.initChart();
|
this.initChart();
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -1,17 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref='dataBoardBoxB' class='dataBoardBoxB'>
|
<div ref="dataBoardBoxB" class="dataBoardBoxB">
|
||||||
<div id="dataBoardBox" class='dataBoardBox' style="width: 1920px;height: 1080px;" :style="{ transform: 'scale(' + scaleNum + ')' }">
|
<div
|
||||||
|
id="dataBoardBox"
|
||||||
|
class="dataBoardBox"
|
||||||
|
style="width: 1920px; height: 1080px"
|
||||||
|
:style="{ transform: 'scale(' + scaleNum + ')' }">
|
||||||
<DataBoardHeader
|
<DataBoardHeader
|
||||||
:is-full-screen="isFullScreen"
|
:is-full-screen="isFullScreen"
|
||||||
@screenfullChange="screenfullChange"
|
@screenfullChange="screenfullChange" />
|
||||||
/>
|
<LeftTop :dataObj="dataObj" />
|
||||||
<LeftTop :dataObj='dataObj'/>
|
<LeftBottom :dataObj="dataObj" />
|
||||||
<LeftBottom :dataObj='dataObj'/>
|
<CenterTop :scaleNum="scaleNum" :dataObj="dataObj" />
|
||||||
<CenterTop :scaleNum='scaleNum' :dataObj='dataObj'/>
|
<CenterBottomL :dataObj="dataObj" />
|
||||||
<CenterBottomL :dataObj='dataObj'/>
|
<CenterBottomR :dataObj="dataObj" />
|
||||||
<CenterBottomR :dataObj='dataObj'/>
|
<RightTop :dataObj="dataObj" />
|
||||||
<RightTop :dataObj='dataObj'/>
|
<RightBottom :dataObj="dataObj" />
|
||||||
<RightBottom :dataObj='dataObj'/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -28,34 +31,43 @@ import RightBottom from './components/RightBottom.vue';
|
|||||||
import { debounce } from '@/utils/debounce';
|
import { debounce } from '@/utils/debounce';
|
||||||
import screenfull from 'screenfull';
|
import screenfull from 'screenfull';
|
||||||
import { getAccessToken } from '@/utils/auth';
|
import { getAccessToken } from '@/utils/auth';
|
||||||
import store from "@/store";
|
import store from '@/store';
|
||||||
export default {
|
export default {
|
||||||
name: 'DataBoard',
|
name: 'DataBoard',
|
||||||
components: { DataBoardHeader,LeftTop,LeftBottom,CenterTop,CenterBottomL,CenterBottomR,RightTop,RightBottom },
|
components: {
|
||||||
|
DataBoardHeader,
|
||||||
|
LeftTop,
|
||||||
|
LeftBottom,
|
||||||
|
CenterTop,
|
||||||
|
CenterBottomL,
|
||||||
|
CenterBottomR,
|
||||||
|
RightTop,
|
||||||
|
RightBottom,
|
||||||
|
},
|
||||||
props: {},
|
props: {},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isFullScreen: false,
|
isFullScreen: false,
|
||||||
scaleNum: 0.8,
|
scaleNum: 0.8,
|
||||||
dataObj:{},
|
dataObj: {},
|
||||||
sseReader: null, // 保存流读取器
|
sseReader: null, // 保存流读取器
|
||||||
abortController: null, // 用于中止 fetch 请求
|
abortController: null, // 用于中止 fetch 请求
|
||||||
retryCount: 0, // 当前重试次数
|
retryCount: 0, // 当前重试次数
|
||||||
isDestroyed: false // 标记组件是否已销毁
|
isDestroyed: false, // 标记组件是否已销毁
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.init()
|
this.init();
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.boxReset = debounce(() => {
|
this.boxReset = debounce(() => {
|
||||||
this.resetSize()
|
this.resetSize();
|
||||||
}, 300)
|
}, 300);
|
||||||
this.boxReset()
|
this.boxReset();
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
this.boxReset()
|
this.boxReset();
|
||||||
})
|
});
|
||||||
this.getData()
|
this.getData();
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.closeSSE();
|
this.closeSSE();
|
||||||
@ -65,23 +77,28 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
sidebarOpened() {
|
sidebarOpened() {
|
||||||
return this.$store.state.app.sidebar.opened
|
return this.$store.state.app.sidebar.opened;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
sidebarOpened(newVal, oldVal) {
|
sidebarOpened(newVal, oldVal) {
|
||||||
this.boxReset()
|
this.boxReset();
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async getData() {
|
async getData() {
|
||||||
let _this = this;
|
let _this = this;
|
||||||
if (_this.isDestroyed) return;
|
if (_this.isDestroyed) return;
|
||||||
const url = process.env.VUE_APP_BASE_API+'/admin-api/monitoring/message/subscribe/'+store.getters.userId+'-'+Date.now();
|
const url =
|
||||||
const token = getAccessToken()
|
process.env.VUE_APP_BASE_API +
|
||||||
|
'/admin-api/monitoring/message/subscribe/' +
|
||||||
|
store.getters.userId +
|
||||||
|
'-' +
|
||||||
|
Date.now();
|
||||||
|
const token = getAccessToken();
|
||||||
const headers = new Headers({
|
const headers = new Headers({
|
||||||
'Authorization': `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
'Content-Type': 'text/event-stream'
|
'Content-Type': 'text/event-stream',
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
// 创建中止控制器
|
// 创建中止控制器
|
||||||
@ -90,12 +107,14 @@ export default {
|
|||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: headers,
|
headers: headers,
|
||||||
signal: _this.abortController.signal // 绑定中止信号
|
signal: _this.abortController.signal, // 绑定中止信号
|
||||||
});
|
});
|
||||||
|
|
||||||
// 获取流读取器
|
// 获取流读取器
|
||||||
_this.sseReader = response.body.getReader();
|
_this.sseReader = response.body.getReader();
|
||||||
const decoder = new TextDecoder();
|
const decoder = new TextDecoder();
|
||||||
|
let buffer = '';
|
||||||
|
let receivedBytes = 0;
|
||||||
|
|
||||||
// 持续读取流数据
|
// 持续读取流数据
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -105,13 +124,34 @@ export default {
|
|||||||
_this.handleReconnect(); // 触发重连
|
_this.handleReconnect(); // 触发重连
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// 处理 SSE 事件数据
|
// const data = decoder.decode(value);
|
||||||
const data = decoder.decode(value);
|
// console.log('收到消息:', data);
|
||||||
console.log('收到消息:', data);
|
|
||||||
if (_this.isValidData(data)){
|
receivedBytes += value.length;
|
||||||
_this.upDateMsg(data);
|
console.log(
|
||||||
|
`收到数据块: ${value.length} 字节, 累计: ${receivedBytes} 字节`
|
||||||
|
);
|
||||||
|
const chunk = decoder.decode(value, { stream: true });
|
||||||
|
buffer += chunk;
|
||||||
|
|
||||||
|
// 处理完整的消息
|
||||||
|
const messages = buffer.split('\n\n'); // SSE 消息以双换行分隔
|
||||||
|
buffer = messages.pop() || ''; // 保留最后一个不完整的消息
|
||||||
|
|
||||||
|
for (const message of messages) {
|
||||||
|
if (_this.isValidData(message)) {
|
||||||
|
// console.log('完整 SSE 消息:', message);
|
||||||
|
_this.upDateMsg(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理 SSE 事件数据
|
||||||
|
// const data = decoder.decode(value);
|
||||||
|
// console.log('收到消息:', data);
|
||||||
|
// if (_this.isValidData(data)){
|
||||||
|
// _this.upDateMsg(data);
|
||||||
|
// }
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 主动中止的请求不报错
|
// 主动中止的请求不报错
|
||||||
if (error.name === 'AbortError') return;
|
if (error.name === 'AbortError') return;
|
||||||
@ -144,7 +184,7 @@ export default {
|
|||||||
console.error('SSE 重连次数已达上限');
|
console.error('SSE 重连次数已达上限');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
isValidData (data) {
|
isValidData(data) {
|
||||||
return data.trim().startsWith('data:{') && !data.includes('heartbeat');
|
return data.trim().startsWith('data:{') && !data.includes('heartbeat');
|
||||||
},
|
},
|
||||||
upDateMsg(data) {
|
upDateMsg(data) {
|
||||||
@ -153,73 +193,73 @@ export default {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const dataObj = JSON.parse(jsonStr);
|
const dataObj = JSON.parse(jsonStr);
|
||||||
this.dataObj = dataObj
|
this.dataObj = dataObj;
|
||||||
console.log('dataObj',this.dataObj)
|
console.log('dataObj', this.dataObj);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('JSON 解析失败:', e);
|
console.error('JSON 解析失败:', e);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
change() {
|
change() {
|
||||||
this.isFullScreen = screenfull.isFullscreen
|
this.isFullScreen = screenfull.isFullscreen;
|
||||||
},
|
},
|
||||||
init() {
|
init() {
|
||||||
if (!screenfull.isEnabled) {
|
if (!screenfull.isEnabled) {
|
||||||
this.$message({
|
this.$message({
|
||||||
message: 'you browser can not work',
|
message: 'you browser can not work',
|
||||||
type: 'warning'
|
type: 'warning',
|
||||||
})
|
});
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
screenfull.on('change', this.change)
|
screenfull.on('change', this.change);
|
||||||
},
|
},
|
||||||
destroy() {
|
destroy() {
|
||||||
if (!screenfull.isEnabled) {
|
if (!screenfull.isEnabled) {
|
||||||
this.$message({
|
this.$message({
|
||||||
message: 'you browser can not work',
|
message: 'you browser can not work',
|
||||||
type: 'warning'
|
type: 'warning',
|
||||||
})
|
});
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
screenfull.off('change', this.change)
|
screenfull.off('change', this.change);
|
||||||
},
|
},
|
||||||
// 全屏
|
// 全屏
|
||||||
screenfullChange() {
|
screenfullChange() {
|
||||||
if (!screenfull.isEnabled) {
|
if (!screenfull.isEnabled) {
|
||||||
this.$message({
|
this.$message({
|
||||||
message: 'you browser can not work',
|
message: 'you browser can not work',
|
||||||
type: 'warning'
|
type: 'warning',
|
||||||
})
|
});
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
screenfull.toggle(this.$refs.dataBoardBoxB)
|
screenfull.toggle(this.$refs.dataBoardBoxB);
|
||||||
},
|
},
|
||||||
resetSize() {
|
resetSize() {
|
||||||
const dataBoardBox = document.getElementById('dataBoardBox')
|
const dataBoardBox = document.getElementById('dataBoardBox');
|
||||||
const rw = parseFloat(window.innerWidth)
|
const rw = parseFloat(window.innerWidth);
|
||||||
const rh = parseFloat(window.innerHeight)
|
const rh = parseFloat(window.innerHeight);
|
||||||
const bw = parseFloat(dataBoardBox.style.width)
|
const bw = parseFloat(dataBoardBox.style.width);
|
||||||
const bh = parseFloat(dataBoardBox.style.height)
|
const bh = parseFloat(dataBoardBox.style.height);
|
||||||
let wx = 0
|
let wx = 0;
|
||||||
let hy = 0
|
let hy = 0;
|
||||||
if (screenfull.isFullscreen) {
|
if (screenfull.isFullscreen) {
|
||||||
wx = rw / bw
|
wx = rw / bw;
|
||||||
hy = rh / bh
|
hy = rh / bh;
|
||||||
} else {
|
} else {
|
||||||
if (this.$store.state.app.sidebar.opened) {
|
if (this.$store.state.app.sidebar.opened) {
|
||||||
wx = (rw - 283) / bw
|
wx = (rw - 283) / bw;
|
||||||
} else {
|
} else {
|
||||||
wx = (rw - 88) / bw
|
wx = (rw - 88) / bw;
|
||||||
}
|
}
|
||||||
hy = (rh - 150) / bh
|
hy = (rh - 150) / bh;
|
||||||
}
|
}
|
||||||
this.scaleNum = wx < hy ? wx : hy
|
this.scaleNum = wx < hy ? wx : hy;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.dataBoardBoxB {
|
.dataBoardBoxB {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: calc(100vh - 150px);
|
height: calc(100vh - 150px);
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -235,5 +275,5 @@ export default {
|
|||||||
background-position: 0 0;
|
background-position: 0 0;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
Reference in New Issue
Block a user