# Conflicts:
#	vite.config.ts
main
zch 4 weeks ago
commit 9fd6441271

@ -18,7 +18,8 @@ VITE_APP_SNAILJOB_ADMIN = '/snail-job'
VITE_APP_BASE_API = '/prod-api'
# ws地址
VITE_WEBSOCKET_ADDRESS = 'ws://127.0.0.1:7181/ws'
# VITE_WEBSOCKET_ADDRESS = 'ws://127.0.0.1:7181/ws'
VITE_WEBSOCKET_ADDRESS = 'ws://172.21.7.199:7181/ws'
# 是否在打包时开启压缩,支持 gzip 和 brotli
VITE_BUILD_COMPRESS = gzip

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 KiB

After

Width:  |  Height:  |  Size: 480 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

@ -13,19 +13,19 @@
</div>
</div>
<div class="title">RFID中间件监控平台</div>
<div class="title1">成功率</div>
<div class="title2">告警统计</div>
<div class="title1">告警统计</div>
<div class="topTitle" style="left: 13%">设备数量:</div>
<div class="topTitle" style="left: 37.5%">在线数量:</div>
<div class="topTitle" style="left: 62%">离线数量:</div>
<div class="topTitle" style="left: 86.5%">告警数量:</div>
<div class="topNum" style="left: 17%; color: #127feb">{{ overview.deviceTotal }}</div>
<div class="topNum" style="left: 41.5%; color: #49e1f5">{{ overview.onlineCount }}</div>
<div class="topNum" style="left: 66%; color: #d8ee30">{{ overview.offlineCount }}</div>
<div class="topNum" style="left: 90.5%; color: #901f43">{{ overview.alarmCount }}</div>
<div class="successRate">
<Chart ref="successRateRef"></Chart>
</div>
<div class="topNum" style="left: 17%; color: #127feb">{{ Object.keys(deviceData).length }}</div>
<div class="topNum" style="left: 41.5%; color: #49e1f5">{{ Object.values(deviceData).filter((e) => e.status).length }}</div>
<div class="topNum" style="left: 66%; color: #d8ee30">{{ Object.values(deviceData).filter((e) => !e.status).length }}</div>
<div class="topNum" style="left: 90.5%; color: #901f43">{{ 0 }}</div>
<!-- <div class="topNum" style="left: 17%; color: #127feb">{{ overview.deviceTotal }}</div>-->
<!-- <div class="topNum" style="left: 41.5%; color: #49e1f5">{{ overview.onlineCount }}</div>-->
<!-- <div class="topNum" style="left: 66%; color: #d8ee30">{{ overview.offlineCount }}</div>-->
<!-- <div class="topNum" style="left: 90.5%; color: #901f43">{{ overview.alarmCount }}</div>-->
<div class="menu">
<el-menu active-text-color="#ffd04b" background-color="#062852" class="el-menu-vertical-demo" default-active="2" text-color="#fff">
<template v-for="(i, index) in treeData" :key="i.id">
@ -69,7 +69,7 @@
</vue3ScrollSeamless>
</div>
<div class="center" ref="scrollNodeRef" @mouseenter="mouseenter" @mouseleave="mouseleave">
<div v-masonry style="width: 100%; height: 100%" ref="masonryRef">
<div v-masonry style="width: 100%; text-align: center" ref="masonryRef">
<TreeItem v-masonry-tile :data="i" v-for="i in centerData" :key="i.id" :deviceData="deviceData" :copy="false" />
</div>
<div v-masonry style="width: 100%; height: 100%">
@ -79,7 +79,7 @@
</div>
</template>
<script setup lang="jsx">
import Chart from '@/components/Chart/chart.vue';
import { ElMessageBox } from 'element-plus';
import thbg from '@/assets/chart/thbg.png';
import trbg from '@/assets/chart/trbg.png';
import TreeItem from './treeItem.vue';
@ -114,9 +114,8 @@ function findParentsWithLocationType3(arr) {
if (hasChildWith3) {
result.push(item);
console.log(item);
item.children.forEach((v) => {
deviceData.value[v.deviceId] = {
deviceData.value[v.deviceName] = {
code: '',
status: v.onlineStatus === '1',
time: parseTime(new Date(), '{m}-{d} {h}:{i}')
@ -175,9 +174,8 @@ const time = ref(timeFun());
const masonryRef = ref(null);
const scrollSeamlessRef = ref(null);
const scrollNodeRef = ref(null);
const successRateRef = ref(null);
const hover = ref(false);
const tableData = ref();
const tableData = ref([]);
const treeData = ref();
const centerData = ref([]);
const deviceData = ref({});
@ -256,102 +254,6 @@ const scrollToId = (id) => {
}
};
const getData = () => {
getSuccessRateTrends().then((res) => {
successRateRef.value.setData({
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(0,0,0,.6)',
borderWidth: 0,
textStyle: {
color: '#fff'
},
formatter: function (params) {
let tooltipContent = '';
//
let axisValue = params[0].axisValueLabel; // x
//
tooltipContent += `${axisValue}<br/>`;
params.forEach(function (param) {
// `%`
tooltipContent += `${param.marker} ${param.seriesName}: ${param.value ? param.value + '%' : '无数据'}<br/>`;
});
return tooltipContent;
}
},
legend: {
top: '',
icon: 'path://M512.798285 0.399142C230.604561 0.399142 1.895927 229.107776 1.895927 511.301501s228.708634 510.902358 510.902358 510.902358 510.902358-228.708634 510.902358-510.902358S794.992009 0.399142 512.798285 0.399142z m0 878.712142C309.634769 879.111284 144.988501 714.465017 144.988501 511.301501S309.634769 143.491717 512.798285 143.491717s367.809784 164.646268 367.809784 367.809784-164.646268 367.809784-367.809784 367.809783z',
itemWidth: 10,
itemHeight: 10,
itemGap: 10,
textStyle: {
color: '#fff',
fontSize: 8
}
},
xAxis: {
type: 'category',
data: res.data.map((item) => item.timePoint),
axisLabel: {
show: true,
color: '#7ae7f8'
},
axisLine: {
show: false
}
},
grid: {
top: 30,
left: 30,
right: 30,
bottom: 30
},
yAxis: {
name: '%',
nameTextStyle: {
color: '#7ae7f8'
},
splitLine: {
show: false
},
type: 'value',
axisLabel: {
show: true,
color: '#7ae7f8'
}
},
series: [
{
name: '今日',
data: res.data.map((item) => item.successRate),
type: 'line',
symbol: 'circle',
symbolSize: 5,
itemStyle: {
color: '#368CDC'
},
lineStyle: {
color: '#368CDC'
}
},
{
name: '昨日',
data: res.data.map((item) => item.yesterdaySuccessRate),
type: 'line',
symbol: 'circle',
symbolSize: 5,
itemStyle: {
color: '#39FFF4'
},
lineStyle: {
color: '#39FFF4'
}
}
]
});
});
getRealtimeStats().then((res) => {
overview.value = res.data?.overview || {};
tableData.value = res.data?.alarmStats || [];
@ -406,59 +308,27 @@ const getSocket = () => {
socket.addEventListener('message', (event) => {
let data = JSON.parse(event.data);
if (data?.deviceStatus === 1) {
deviceData.value[data.deviceId] = {
status: true,
code: data.epcStr || '',
time: parseTime(new Date(), '{m}-{d} {h}:{i}')
// time: parseTime(data.recordTime, '{m}-{d} {h}:{i}')
};
} else {
deviceData.value[data.deviceId] = {
status: false,
code: data.epcStr || '',
time: parseTime(new Date(), '{m}-{d} {h}:{i}')
// time: parseTime(data.recordTime, '{m}-{d} {h}:{i}')
};
}
if (data?.dataType === '1') {
}
if (data?.alarmFlag === '1') {
let list = data.Readers || [];
list.forEach((item) => {
if (item.ConnectionStatus !== 1) {
ElMessageBox.alert(`设备${item.Id}离线`, '离线报警', {
type: 'warning',
confirmButtonText: '确定'
}).catch(() => undefined);
tableData.value.push({
time: parseTime(new Date(), '{m}-{d} {h}:{i}'),
// alarmTime: parseTime(data.recordTime, '{m}-{d} {h}:{i}'),
deviceName: deviceData.value[data.deviceId]?.epcStr?.trimStart() || '',
location: centerData.value.flatMap((item) => item.children || []).find((child) => child.deviceId === targetDeviceId)?.locationAlias || '',
alarmAction: data.alarmAction
alarmTime: parseTime(new Date(), '{m}-{d} {h}:{i}'),
deviceName: item.Id,
location: '',
alarmAction: '设备离线'
});
}
// if (data?.deviceStatus === '1') {
// deviceData.value[data.deviceId] = data;
// }
// if (data?.deviceStatus === '2' && data?.alarmFlag === '1') {
// tableData.value.push({
// alarmTime: parseTime(data.recordTime),
// deviceName: deviceData.value[data.deviceId]?.epcStr.trimStart() || '',
// location: centerData.value.flatMap((item) => item.children || []).find((child) => child.deviceId === targetDeviceId)?.locationAlias || '',
// alarmAction: data.alarmAction
// });
// if (data.dataType === '2') {
// deviceData.value[data.deviceId] = data;
// }
// }
// if (data?.deviceStatus === '3' && data?.alarmFlag === '1') {
// tableData.value.push({
// alarmTime: parseTime(data.recordTime),
// deviceName: deviceData.value[data.deviceId]?.epcStr.trimStart() || '',
// location: centerData.value.flatMap((item) => item.children || []).find((child) => child.deviceId === targetDeviceId)?.locationAlias || '',
// alarmAction: data.alarmAction
// });
// if (data.dataType === '2') {
// deviceData.value[data.deviceId] = data;
// }
// }
deviceData.value[item.Id] = {
status: item.ConnectionStatus === 1,
time: parseTime(new Date(), '{m}-{d} {h}:{i}')
};
});
scrollToId(list?.[0]?.Id);
});
socket.addEventListener('close', () => {
@ -475,7 +345,7 @@ let timer1 = null;
onMounted(() => {
getData();
nextTick(() => {
scrollToBottom(scrollNodeRef.value, 2);
scrollToBottom(scrollNodeRef.value, 1);
});
getLocationTree().then((res) => {
@ -484,11 +354,10 @@ onMounted(() => {
});
getDeviceLatestRecords().then((res) => {
res.data.forEach((item) => {
if (deviceData.value[item.deviceId]) {
deviceData.value[item.deviceId].code = item.latestBarcode;
if (deviceData.value[item.deviceName]) {
deviceData.value[item.deviceName].code = item.latestBarcode;
}
});
console.log(deviceData.value);
});
getSocket();
timer1 = setInterval(() => {
@ -620,14 +489,6 @@ onBeforeMount(() => {
letter-spacing: 0.2vw;
}
.successRate {
position: absolute;
top: 30.7%;
left: 75.6%;
width: 20.6%;
height: 28.5%;
}
.menu {
position: absolute;
top: 24%;
@ -645,10 +506,10 @@ onBeforeMount(() => {
.scrollTable {
position: absolute;
top: 64.7%;
top: 30.7%;
left: 75.6%;
width: 20.6%;
height: 28.5%;
height: 62.5%;
}
.th {
@ -681,6 +542,7 @@ onBeforeMount(() => {
height: 69%;
display: flex;
flex-wrap: wrap;
justify-content: center;
overflow-y: auto;
transition: all 1s;

@ -12,16 +12,17 @@
:id="copy ? '' : `tree${child.id}`"
v-for="(child, index) in data.children"
:key="index"
:class="deviceData[child.deviceId]?.status ? 'child-item' : 'child-item1'"
:class="deviceData[child.deviceName]?.status ? 'child-item' : 'child-item1'"
:ref="(el) => (childRefs[index] = el)"
>
<div :class="deviceData[child.deviceId]?.status ? 'child-icon' : 'child-icon1'"></div>
<div :class="deviceData[child.deviceName]?.status ? 'child-icon' : 'child-icon1'"></div>
<div class="child-info">
<div class="child-name">
工位名称: <span style="font-size: 0.8vw">{{ child.locationAlias }}</span>
</div>
<div class="child-code">总装码{{ deviceData[child.deviceId]?.code?.trimStart() }}</div>
<div class="child-time">时间{{ parseTime(deviceData[child.deviceId]?.time, '{m}-{d} {h}:{i}') }}</div>
<!-- <div class="child-code">总装码{{ deviceData[child.deviceId]?.code?.trimStart() }}</div>-->
<div class="child-code">状态{{ deviceData[child.deviceName]?.status ? '在线' : '离线' }}</div>
<!-- <div class="child-time">时间{{ parseTime(deviceData[child.deviceName]?.time, '{m}-{d} {h}:{i}') }}</div>-->
</div>
</div>
</div>
@ -102,14 +103,13 @@ watchEffect(() => {
.node {
color: #fff;
font-size: 0.6vw;
width: 346px;
width: 316px;
position: relative;
vertical-align: top;
display: flex;
align-items: stretch;
break-inside: avoid;
margin-bottom: 12px;
margin-left: 12px;
margin: 0 12px 12px 0; /* 🟩 去掉 margin-left左右对称 */
}
/* 主节点 */
@ -146,7 +146,7 @@ watchEffect(() => {
/* 子节点列表 */
.children {
display: inline-block;
width: 246px;
width: calc(7vw + 74px + 20px + 12px);
}
.child-item {
@ -156,6 +156,7 @@ watchEffect(() => {
position: relative;
//height: 75px;
padding-bottom: 12px;
padding-right: 12px;
margin-left: 20px;
background-image: url('@/assets/chart/efc42f5a4ed9491a16f6817d7fbe2336.png');
background-size: 100% 100%;
@ -168,6 +169,7 @@ watchEffect(() => {
border-radius: 6px;
margin-bottom: 8px;
position: relative;
padding-right: 12px;
//height: 75px;
padding-bottom: 12px;
margin-left: 20px;
@ -215,22 +217,24 @@ watchEffect(() => {
//position: absolute;
margin-top: 10px;
margin-left: 74px;
width: 150px;
width: 7vw;
}
.child-name {
//position: absolute;
//top: 10px;
//left: 74px;
font-size: 0.8vw;
width: 150px;
width: 7vw;
text-align: left;
//white-space: nowrap;
}
.child-code,
.child-time {
text-align: left;
opacity: 0.9;
white-space: nowrap;
width: 150px;
width: 7vw;
}
.child-code {

@ -26,7 +26,7 @@ export default defineConfig(({ mode, command }) => {
proxy: {
[env.VITE_APP_BASE_API]: {
// target: 'http://192.168.100.100:8080''',
target: 'http://localhost:9081',
target: 'http://192.168.0.8:9081',
changeOrigin: true,
ws: true,
rewrite: (path) => path.replace(new RegExp('^' + env.VITE_APP_BASE_API), '')

Loading…
Cancel
Save