Compare commits
5 Commits
9805d29df3
...
1a5749bab2
Author | SHA1 | Date | |
---|---|---|---|
|
1a5749bab2 | ||
|
7e2c6fe665 | ||
|
8d0aa21332 | ||
|
006b875d12 | ||
|
a6e380a64c |
43
src/App.vue
43
src/App.vue
@ -1,46 +1,25 @@
|
||||
<script setup>
|
||||
import { ref, watch, computed } from "vue";
|
||||
import { ref, onMounted } from "vue";
|
||||
import MainPage from "./MainPage.vue";
|
||||
import Slider from "./components/Slider.vue";
|
||||
import Client from "./utils/ws";
|
||||
import useWebsocket from "./utils/useWebsocket";
|
||||
import { useWsStore } from "./store";
|
||||
|
||||
const store = useWsStore();
|
||||
|
||||
const url = "ws://192.168.1.101:8082/QbMonitoring/websocket";
|
||||
// use websocket
|
||||
let urlPath = document.location.pathname;
|
||||
if (urlPath === "/") {
|
||||
urlPath = "/1-1";
|
||||
}
|
||||
new Client(
|
||||
{
|
||||
url: url + urlPath,
|
||||
name: urlPath,
|
||||
},
|
||||
(message) => {
|
||||
try {
|
||||
const data = JSON.parse(message.data);
|
||||
console.log("message", JSON.parse(message.data));
|
||||
useWebsocket(store, urlPath);
|
||||
|
||||
if ("specificationChanges" in data) {
|
||||
console.log("[*] setting data1");
|
||||
// 分屏推送1数据
|
||||
store.updateData("1", data);
|
||||
} else if ("deliveryNotification" in data) {
|
||||
// 分屏推送3数据
|
||||
console.log("[*] setting data3");
|
||||
store.updateData("3", data);
|
||||
} else {
|
||||
// 分屏推送2数据
|
||||
console.log("[*] setting data2");
|
||||
store.updateData("2", data);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log("[x] 未解析的ws数据: ", err);
|
||||
}
|
||||
}
|
||||
);
|
||||
// size setting
|
||||
const size = ref(80);
|
||||
onMounted(() => {
|
||||
setSize(size.value);
|
||||
});
|
||||
|
||||
// style update
|
||||
const styles = ref({});
|
||||
function setSize(value) {
|
||||
const v = (value / 100).toFixed(2);
|
||||
@ -56,7 +35,7 @@ function setSize(value) {
|
||||
<template>
|
||||
<div id="app-container">
|
||||
<MainPage :style="styles" />
|
||||
<Slider @size-change="setSize" />
|
||||
<Slider :size="size" @size-change="setSize" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -106,8 +106,8 @@ const props = defineProps({
|
||||
}
|
||||
|
||||
.container-body {
|
||||
background: #ffffff33;
|
||||
backdrop-filter: blur(1px);
|
||||
background: #ffffff11;
|
||||
backdrop-filter: blur(2px);
|
||||
flex: 1;
|
||||
padding: 20px;
|
||||
}
|
||||
|
@ -1,10 +1,13 @@
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import Container from './Base/Container.vue';
|
||||
import { useWsStore } from '../store'
|
||||
import { ref, onMounted } from "vue";
|
||||
import * as echarts from "echarts";
|
||||
import Container from "./Base/Container.vue";
|
||||
import { useWsStore } from "../store";
|
||||
import charSetup from "./HourChartOptions";
|
||||
|
||||
const store = useWsStore();
|
||||
const chartChart = ref(null);
|
||||
const chart = ref(null);
|
||||
// 小时数据
|
||||
const hourData = ref([]);
|
||||
// store.$subscribe((mutation, state) => {
|
||||
@ -19,28 +22,8 @@ const hourData = ref([]);
|
||||
// });
|
||||
|
||||
onMounted(() => {
|
||||
chartChart.value.classList.add('h-full');
|
||||
const mc = echarts.init(chartChart.value);
|
||||
mc.setOption({
|
||||
grid: {
|
||||
top: 24,
|
||||
bottom: 24,
|
||||
left: 24,
|
||||
right: 24,
|
||||
},
|
||||
tooltip: {},
|
||||
xAxis: {
|
||||
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'],
|
||||
},
|
||||
yAxis: {},
|
||||
series: [
|
||||
{
|
||||
name: '销量',
|
||||
type: 'bar',
|
||||
data: [5, 20, 36, 10, 10, 20],
|
||||
},
|
||||
],
|
||||
});
|
||||
chartChart.value.classList.add("h-full");
|
||||
chart.value = echarts.init(chartChart.value);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
40
src/components/HourChartOptions.js
Normal file
40
src/components/HourChartOptions.js
Normal file
@ -0,0 +1,40 @@
|
||||
export const options = {
|
||||
grid: {
|
||||
top: "5%",
|
||||
bottom: "5%",
|
||||
left: "3%",
|
||||
right: "3%",
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: [],
|
||||
axisLabel: {
|
||||
fontSize: 24,
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
axisLabel: {
|
||||
fontSize: 24,
|
||||
},
|
||||
minInterval: 1,
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [],
|
||||
type: "bar",
|
||||
showBackground: true,
|
||||
backgroundStyle: {
|
||||
color: "rgba(180, 180, 180, 0.2)",
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default function setup(echartInstance, timeArr, dataArr) {
|
||||
const options = { ...options };
|
||||
options.xAxis.data = timeArr;
|
||||
options.series[0].data = dataArr;
|
||||
echartInstance.setOption(options);
|
||||
}
|
@ -1,35 +1,115 @@
|
||||
<!-- 货物情况 -->
|
||||
|
||||
<!-- 实时数据图表 -->
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import Container from './Base/Container.vue';
|
||||
|
||||
import { ref, onMounted } from "vue";
|
||||
import * as echarts from "echarts";
|
||||
import Container from "./Base/Container.vue";
|
||||
import { useWsStore } from "../store";
|
||||
const cargoChart = ref(null);
|
||||
|
||||
onMounted(() => {
|
||||
cargoChart.value.classList.add('h-full');
|
||||
const mc = echarts.init(cargoChart.value);
|
||||
mc.setOption({
|
||||
const chart = ref(null);
|
||||
const options = {
|
||||
color: ["#99D66C", "#5B9BFF"],
|
||||
grid: {
|
||||
top: 24,
|
||||
bottom: 24,
|
||||
left: 24,
|
||||
right: 24,
|
||||
top: 72,
|
||||
bottom: 72,
|
||||
left: 112,
|
||||
right: 88,
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "shadow",
|
||||
},
|
||||
},
|
||||
tooltip: {},
|
||||
xAxis: {
|
||||
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'],
|
||||
type: "value",
|
||||
position: "top",
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
type: "dashed",
|
||||
color: "#ccc8",
|
||||
},
|
||||
yAxis: {},
|
||||
series: [
|
||||
},
|
||||
axisLabel: {
|
||||
fontSize: 24,
|
||||
color: "#fff",
|
||||
},
|
||||
minInterval: 1,
|
||||
},
|
||||
yAxis: {
|
||||
type: "category",
|
||||
axisLine: { show: false },
|
||||
axisLabel: { show: false },
|
||||
axisTick: { show: false },
|
||||
splitLine: { show: false },
|
||||
data: ["废片", "阶段成品"],
|
||||
axisLabel: {
|
||||
fontSize: 24,
|
||||
color: "#fff",
|
||||
},
|
||||
},
|
||||
title: [
|
||||
{
|
||||
name: '销量',
|
||||
type: 'bar',
|
||||
data: [5, 20, 36, 10, 10, 20],
|
||||
text: 0 + "片",
|
||||
left: "50%",
|
||||
textAlign: "center",
|
||||
top: "82%",
|
||||
textStyle: {
|
||||
fontSize: 32,
|
||||
color: "#fff",
|
||||
},
|
||||
},
|
||||
{
|
||||
text: 0 + "片",
|
||||
left: "50%",
|
||||
textAlign: "center",
|
||||
top: "44%",
|
||||
textStyle: {
|
||||
fontSize: 32,
|
||||
color: "#fff",
|
||||
},
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: "数量",
|
||||
type: "bar",
|
||||
stack: "Total",
|
||||
showBackground: true,
|
||||
barWidth: "32",
|
||||
colorBy: "data",
|
||||
data: [
|
||||
{ value: 0, label: { fontSize: 28 } },
|
||||
{ value: 0, label: { fontSize: 28 } },
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
function updateChartOption(product, scrap) {
|
||||
if (!chart.value) chart.value = echarts.init(cargoChart.value);
|
||||
else {
|
||||
chart.value.dispose();
|
||||
chart.value = echarts.init(cargoChart.value);
|
||||
}
|
||||
options.title[0].text = product + "片";
|
||||
options.title[1].text = scrap + "片";
|
||||
options.series[0].data[0].value = product;
|
||||
options.series[0].data[1].value = scrap;
|
||||
chart.value.setOption(options);
|
||||
}
|
||||
|
||||
const productAmount = ref(0);
|
||||
const scrapAmount = ref(0);
|
||||
const store = useWsStore();
|
||||
store.$subscribe((mutation, state) => {
|
||||
productAmount.value = state.data1.realTimeData?.product || 0;
|
||||
scrapAmount.value = state.data1.realTimeData?.scrap || 0;
|
||||
updateChartOption(productAmount.value, scrapAmount.value);
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
cargoChart.value.classList.add("h-full");
|
||||
updateChartOption(productAmount.value, scrapAmount.value);
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -46,10 +126,6 @@ onMounted(() => {
|
||||
align-self: self-end;
|
||||
}
|
||||
|
||||
.cargo-inner {
|
||||
background: #0f0;
|
||||
}
|
||||
|
||||
.cargo-chart {
|
||||
height: 100%;
|
||||
}
|
||||
|
@ -1,44 +1,42 @@
|
||||
<!-- 实时数据表格 -->
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { useWsStore } from '../store';
|
||||
import { ref } from "vue";
|
||||
import { useWsStore } from "../store";
|
||||
|
||||
const listData = ref([]);
|
||||
const store = useWsStore();
|
||||
store.$subscribe((mutation, state) => {
|
||||
listData.value = state.data2.lineDetailData.map((item, index) => ({
|
||||
productLine: item.productLine,
|
||||
mbt: item.edgingInput,
|
||||
mbb: item.edgingOutput,
|
||||
dkt: item.drillingInput,
|
||||
dkb: item.drillingOutput,
|
||||
dmt: item.coatingInput,
|
||||
dmb: item.coatingOutput,
|
||||
syt: item.silkInput,
|
||||
syb: item.silkOutput,
|
||||
ght: item.solidificationInput,
|
||||
ghb: item.solidificationOutput,
|
||||
gh1: item.temperingInput,
|
||||
gh2: item.temperingOutput,
|
||||
bzt: item.finalInput,
|
||||
bzb: item.finalOutput,
|
||||
}));
|
||||
listData.value = (state.data2.lineDetailData || Array(3).fill({})).map(
|
||||
(item, index) => ({
|
||||
productLine: item.productLine || "---",
|
||||
mbt: item.edgingInput || "---",
|
||||
mbb: item.edgingOutput || "---",
|
||||
dkt: item.drillingInput || "---",
|
||||
dkb: item.drillingOutput || "---",
|
||||
dmt: item.coatingInput || "---",
|
||||
dmb: item.coatingOutput || "---",
|
||||
syt: item.silkInput || "---",
|
||||
syb: item.silkOutput || "---",
|
||||
ght: item.solidificationInput || "---",
|
||||
ghb: item.solidificationOutput || "---",
|
||||
gh1: item.temperingInput || "---",
|
||||
gh2: item.temperingOutput || "---",
|
||||
bzt: item.finalInput || "---",
|
||||
bzb: item.finalOutput || "---",
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
const tableData = [
|
||||
{ productLine: '00A', mbt: '---', mbb: '---', dkt: '---', dkb: '---', dmt: '---', dmb: '---', syt: '---', syb: '---', ght: '---', ghb: '---', gh1: '---', gh2: '---', bzt: '---', bzb: '---' },
|
||||
{ productLine: '00B', mbt: '---', mbb: '---', dkt: '---', dkb: '---', dmt: '---', dmb: '---', syt: '---', syb: '---', ght: '---', ghb: '---', gh1: '---', gh2: '---', bzt: '---', bzb: '---' },
|
||||
{ productLine: '00C', mbt: '---', mbb: '---', dkt: '---', dkb: '---', dmt: '---', dmb: '---', syt: '---', syb: '---', ght: '---', ghb: '---', gh1: '---', gh2: '---', bzt: '---', bzb: '---' },
|
||||
{ productLine: '00D', mbt: '---', mbb: '---', dkt: '---', dkb: '---', dmt: '---', dmb: '---', syt: '---', syb: '---', ght: '---', ghb: '---', gh1: '---', gh2: '---', bzt: '---', bzb: '---' },
|
||||
{ productLine: '00E', mbt: '---', mbb: '---', dkt: '---', dkb: '---', dmt: '---', dmb: '---', syt: '---', syb: '---', ght: '---', ghb: '---', gh1: '---', gh2: '---', bzt: '---', bzb: '---' },
|
||||
{ productLine: '00F', mbt: '---', mbb: '---', dkt: '---', dkb: '---', dmt: '---', dmb: '---', syt: '---', syb: '---', ght: '---', ghb: '---', gh1: '---', gh2: '---', bzt: '---', bzb: '---' },
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="realtime-table">
|
||||
<el-table class="dark-table" :data="listData" :show-overflow-tooltip="true" row-class-name="dark-row"
|
||||
header-row-class-name="dark-header">
|
||||
<el-table
|
||||
class="dark-table"
|
||||
:data="listData"
|
||||
:show-overflow-tooltip="true"
|
||||
row-class-name="dark-row"
|
||||
header-row-class-name="dark-header"
|
||||
>
|
||||
<el-table-column prop="productLine" label="产线"></el-table-column>
|
||||
<el-table-column prop="mbt" label="磨边上"></el-table-column>
|
||||
<el-table-column prop="mbb" label="磨边下"></el-table-column>
|
||||
@ -59,10 +57,9 @@ const tableData = [
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.realtime-table {
|
||||
background: #00f3;
|
||||
height: 240px;
|
||||
height: 160px;
|
||||
width: 80%;
|
||||
align-self: self-start;
|
||||
}
|
||||
@ -70,4 +67,8 @@ const tableData = [
|
||||
.dark-table {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.dark-table >>> .el-table__inner-wrapper::before {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,34 +1,42 @@
|
||||
<script setup>
|
||||
import { ref, watch, onMounted } from 'vue';
|
||||
|
||||
const emit = defineEmits(['size-change']);
|
||||
const size = ref(100);
|
||||
const slider = ref(null);
|
||||
|
||||
// watchers
|
||||
watch(size, (value) => {
|
||||
if (value == null) return;
|
||||
emit('size-change', value);
|
||||
import { ref, watch, computed, onMounted } from "vue";
|
||||
const props = defineProps({
|
||||
size: {
|
||||
type: Number,
|
||||
default: 60,
|
||||
},
|
||||
});
|
||||
const emit = defineEmits(["size-change"]);
|
||||
|
||||
const slider = ref(null);
|
||||
const innerSize = ref(props.size);
|
||||
|
||||
// watch
|
||||
watch(
|
||||
() => innerSize.value,
|
||||
(value) => {
|
||||
emit("size-change", value);
|
||||
}
|
||||
);
|
||||
|
||||
// handlers
|
||||
function keydownHandler(e) {
|
||||
if (e.shiftKey && e.key === 'L') {
|
||||
if (e.shiftKey && e.key === "L") {
|
||||
if (slider.value) {
|
||||
slider.value.classList.toggle('show');
|
||||
slider.value.classList.toggle("show");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// hooks
|
||||
onMounted(() => {
|
||||
document.addEventListener('keydown', keydownHandler);
|
||||
document.addEventListener("keydown", keydownHandler);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="slider" class="slider">
|
||||
<input type="range" min="0" max="100" v-model="size" />
|
||||
<input type="range" min="0" max="100" v-model="innerSize" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -1,11 +1,28 @@
|
||||
<!-- 公告页面 -->
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
const emit = defineEmits(['home']);
|
||||
const content = ref('公告加载中...');
|
||||
import { ref } from "vue";
|
||||
import { useWsStore } from "../store";
|
||||
const emit = defineEmits(["home"]);
|
||||
|
||||
// load 公告
|
||||
const vertical_content = ref("公告加载中...");
|
||||
const horizontal_content = ref("公告加载中...");
|
||||
const store = useWsStore();
|
||||
store.$subscribe((mutation, state) => {
|
||||
vertical_content.value =
|
||||
(state.data3.deliveryNotification || [])
|
||||
.map((item) => item.deliveryContent || "")
|
||||
.join("")
|
||||
.replaceAll(/<br(\s?)\/>/g, "") || "暂无公告";
|
||||
horizontal_content.value =
|
||||
(state.data2.deliveryMsg || [])
|
||||
.map((item) => item.deliveryContent || "")
|
||||
.join("\t") || "暂无公告";
|
||||
});
|
||||
|
||||
// handlers
|
||||
const handleClose = () => {
|
||||
emit('home');
|
||||
emit("home");
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -14,7 +31,7 @@ const handleClose = () => {
|
||||
<h1 class="announcement-title">公告栏</h1>
|
||||
<main class="announcement-content">
|
||||
<ScrollText :vertical="true" :duration="10" :pause-on-hover="true">
|
||||
{{ content }}
|
||||
<div v-html="vertical_content"></div>
|
||||
</ScrollText>
|
||||
</main>
|
||||
<div class="announcement-footer">
|
||||
@ -24,7 +41,7 @@ const handleClose = () => {
|
||||
>
|
||||
返回
|
||||
</button>
|
||||
<ScrollText> 数据加载异常 </ScrollText>
|
||||
<ScrollText> {{ horizontal_content }} </ScrollText>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -54,6 +71,8 @@ const handleClose = () => {
|
||||
padding: 8px 80px;
|
||||
font-size: 72px;
|
||||
font-family: serif;
|
||||
overflow: hidden;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.announcement-footer {
|
||||
@ -64,5 +83,6 @@ const handleClose = () => {
|
||||
line-height: 128px;
|
||||
font-family: sans-serif;
|
||||
position: relative;
|
||||
user-select: none;
|
||||
}
|
||||
</style>
|
||||
|
55
src/utils/useWebsocket.js
Normal file
55
src/utils/useWebsocket.js
Normal file
@ -0,0 +1,55 @@
|
||||
import Client from "./ws";
|
||||
|
||||
export default function useWebsocket(store, path) {
|
||||
connect0(store);
|
||||
connectPath(store, path);
|
||||
}
|
||||
|
||||
const url = "ws://192.168.1.101:8082/QbMonitoring/websocket";
|
||||
function connectPath(store, path) {
|
||||
new Client(
|
||||
{
|
||||
url: url + path,
|
||||
name: path,
|
||||
},
|
||||
(message) => {
|
||||
try {
|
||||
const data = JSON.parse(message.data);
|
||||
console.log("message", JSON.parse(message.data));
|
||||
|
||||
if ("specificationChanges" in data) {
|
||||
console.log("[*] setting data1");
|
||||
// 分屏推送1数据
|
||||
store.updateData("1", data);
|
||||
} else if ("deliveryNotification" in data) {
|
||||
// 分屏推送3数据
|
||||
console.log("[*] setting data3");
|
||||
store.updateData("3", data);
|
||||
} else {
|
||||
// 分屏推送2数据
|
||||
console.log("[*] setting data2");
|
||||
store.updateData("2", data);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log("[x] 未解析的ws数据: ", err);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function connect0(store) {
|
||||
new Client(
|
||||
{
|
||||
url: url + "/0",
|
||||
name: "/0",
|
||||
},
|
||||
(message) => {
|
||||
try {
|
||||
const data = JSON.parse(message.data);
|
||||
console.log("message --- 0 ---> ", JSON.parse(message.data));
|
||||
} catch (err) {
|
||||
console.log("[x] 未解析的ws数据: ", err);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue
Block a user