407 lines
13 KiB
Vue
407 lines
13 KiB
Vue
<script setup lang="ts">
|
||
|
||
|
||
|
||
import HomeApi from "@/api/home.ts";
|
||
import type {AppServeDataResponse} from "@/interface/api/AppServeDataResponse.ts";
|
||
import type {ISystemInfoVo} from "@/interface/page/home/ISystemInfoVo.ts";
|
||
import {AppServeResponseCodeEnum} from "@/constant/enums/AppServeResponseCodeEnum.ts";
|
||
import {computed, onMounted, onUnmounted, ref} from "vue";
|
||
import {AlarmClock, Coin, Cpu, Location, Monitor, SetUp, Stopwatch, Tickets} from "@element-plus/icons-vue";
|
||
import type {ISystemEventVo} from "@/interface/page/home/ISystemEventVo.ts";
|
||
import MessageUtils from "@/utils/MessageUtils.ts";
|
||
import type {ISystemNotificationVo} from "@/interface/page/home/ISystemNotificationVo.ts";
|
||
import {useI18n} from "vue-i18n";
|
||
import ChartPie from "@/components/charts/ChartPie.vue";
|
||
import ChartBar from "@/components/charts/ChartBar.vue";
|
||
import type {IBarPieLineDataItem} from "@/model/charts/IBarPieLineDataItem.ts";
|
||
import ChartLine from "@/components/charts/ChartLine.vue";
|
||
import type {IMultilineLineDataItem} from "@/model/charts/IMultilineLineDataItem.ts";
|
||
|
||
const { t } = useI18n();
|
||
const props = defineProps(['isFull']);
|
||
const isFull = computed(() => {
|
||
return props.isFull ?? false;
|
||
});
|
||
|
||
let interval: number | undefined = undefined;
|
||
let eventSource: EventSource | undefined = undefined;
|
||
const systemInfo = ref<ISystemInfoVo>();
|
||
const eventInfo = ref<ISystemEventVo[]>([{
|
||
eventTime: '-',
|
||
eventMsg: '欢迎使用仓库控制系统'
|
||
}]); // 事件日志显示
|
||
|
||
const queryData = () => {
|
||
querySystemInfo(); // 查询系统信息
|
||
queryStockUsage(); // 查询库存使用率
|
||
queryStockInOut(); // 获取今日出入库数量
|
||
queryStockErrorDay7(); // 查询近七天设备故障数量
|
||
queryStockInOutDay7(); // 获取近七天出入库数量
|
||
};
|
||
|
||
// 查询系统信息
|
||
const querySystemInfo = () => {
|
||
HomeApi.queryServeData().then(res => {
|
||
const stringify = JSON.stringify(res.data);
|
||
const response = JSON.parse(stringify) as AppServeDataResponse<ISystemInfoVo>;
|
||
if(response && response.code == AppServeResponseCodeEnum.SUCCESS && response.data != undefined) {
|
||
systemInfo.value = response.data;
|
||
return;
|
||
}
|
||
console.log(res);
|
||
}).catch(() => {});
|
||
};
|
||
|
||
// 查询库存占用率
|
||
const queryStockUsage = () => {
|
||
HomeApi.queryStockOccupancyRate().then(res => {
|
||
const response = JSON.parse(JSON.stringify(res.data)) as AppServeDataResponse<IBarPieLineDataItem[]>;
|
||
if(response && response.code == AppServeResponseCodeEnum.SUCCESS && response.data != undefined) {
|
||
setStockUsageChartOptionData(response.data);
|
||
return;
|
||
}
|
||
console.log(res);
|
||
}).catch(() => {});
|
||
};
|
||
|
||
// 查询库存出入库数量
|
||
const queryStockInOut = () => {
|
||
HomeApi.queryTodayInOutStock().then(res => {
|
||
const response = JSON.parse(JSON.stringify(res.data)) as AppServeDataResponse<IBarPieLineDataItem[]>;
|
||
if(response && response.code == AppServeResponseCodeEnum.SUCCESS && response.data != undefined) {
|
||
setTodayStockInOutChartOptionData(response.data);
|
||
return;
|
||
}
|
||
console.log(res);
|
||
}).catch(() => {});
|
||
};
|
||
|
||
// 查询七日设备故障数量
|
||
const queryStockErrorDay7 = () => {
|
||
HomeApi.querySevenDaysDeviceFailure().then(res => {
|
||
const response = JSON.parse(JSON.stringify(res.data)) as AppServeDataResponse<IBarPieLineDataItem[]>;
|
||
if(response && response.code == AppServeResponseCodeEnum.SUCCESS && response.data != undefined) {
|
||
setStockErrorLineChartOptionData(response.data);
|
||
return;
|
||
}
|
||
console.log(res);
|
||
}).catch(() => {});
|
||
};
|
||
|
||
// 查询近七日出入库数量
|
||
const queryStockInOutDay7 = () => {
|
||
HomeApi.querySevenDaysInOutStock().then(res => {
|
||
const response = JSON.parse(JSON.stringify(res.data)) as AppServeDataResponse<IMultilineLineDataItem>;
|
||
if(response && response.code == AppServeResponseCodeEnum.SUCCESS && response.data != undefined) {
|
||
setStockInOutLineChartOptionData(response.data);
|
||
return;
|
||
}
|
||
console.log(res);
|
||
}).catch(() => {});
|
||
}
|
||
|
||
|
||
// 创建连接 --- 已经弃用
|
||
const createConnect = () => {
|
||
if(eventSource) {
|
||
eventSource.close();
|
||
}
|
||
eventSource = HomeApi.createNoticeConnect();
|
||
eventSource.onmessage = (event) => {
|
||
console.log('SSE接收到数据:' + event.data);
|
||
};
|
||
eventSource.onopen = () => {
|
||
console.log('SSE连接成功');
|
||
};
|
||
eventSource.onerror = () => {
|
||
console.log('SSE连接失败或者断开连接');
|
||
};
|
||
eventSource.addEventListener('RUNNING_INFO', (event) => {
|
||
const response = JSON.parse(event.data) as ISystemEventVo;
|
||
if(eventInfo.value.length > 500) {
|
||
eventInfo.value.pop();
|
||
}
|
||
eventInfo.value.unshift({
|
||
eventTime: response.eventTime ?? '-',
|
||
eventMsg: response.eventMsg ?? '-'
|
||
});
|
||
});
|
||
eventSource.addEventListener('SYSTEM_INFO', (event) => {
|
||
const response = JSON.parse(event.data) as ISystemNotificationVo;
|
||
MessageUtils.showNotification(response.title ?? '-', response.message ?? '-', response.type ?? 'info', response.duration ?? 3000);
|
||
});
|
||
}
|
||
|
||
|
||
onMounted(() => {
|
||
queryData();
|
||
interval = setInterval(() => {
|
||
queryData();
|
||
}, 3000);
|
||
//createConnect(); // 创建SSE连接
|
||
console.log('主页组件已经挂载');
|
||
});
|
||
|
||
onUnmounted(() => {
|
||
if(interval) {
|
||
clearInterval(interval);
|
||
}
|
||
// eventSource?.close();
|
||
});
|
||
|
||
// 设置仓库利用率饼图数据
|
||
const setStockUsageChartOptionData = (data: IBarPieLineDataItem[]) => {
|
||
stockUsageChartOption.value.series[0].data = data;
|
||
};
|
||
// 设置今日出入库数量柱状图数据
|
||
const setTodayStockInOutChartOptionData = (data: IBarPieLineDataItem[]) => {
|
||
let xName = [];
|
||
let yData = [];
|
||
for (let i = 0; i < data.length; i++) {
|
||
xName.push(data[i].name);
|
||
yData.push(data[i].value);
|
||
}
|
||
stockInOutChartOption.value.xAxis.data = xName;
|
||
stockInOutChartOption.value.series[0].data = yData;
|
||
};
|
||
// 设置近七日设备故障折线图数据
|
||
const setStockErrorLineChartOptionData = (data: IBarPieLineDataItem[]) => {
|
||
let xName = [];
|
||
let yData = [];
|
||
for (let i = 0; i < data.length; i++) {
|
||
xName.push(data[i].name);
|
||
yData.push(data[i].value);
|
||
}
|
||
stockErrorLineChartOption.value.xAxis.data = xName.reverse();
|
||
stockErrorLineChartOption.value.series[0].data = yData.reverse();
|
||
};
|
||
// 设置近七天出入库数量折线图数据
|
||
const setStockInOutLineChartOptionData = (data: IMultilineLineDataItem) => {
|
||
let xName = [];
|
||
for (let i = 0; i < data.xDataList.length; i++) {
|
||
xName.push(data.xDataList[i]);
|
||
}
|
||
const yDataList = data.yDataList;
|
||
let yData = [];
|
||
for (let i = 0; i < yDataList.length; i++) {
|
||
const item = {
|
||
name: yDataList[i].name,
|
||
data: yDataList[i].data.reverse(),
|
||
type: 'line',
|
||
smooth: true,
|
||
};
|
||
yData.push(item);
|
||
}
|
||
stockInOutLineChartOptionDays7.value.xAxis.data = xName.reverse();
|
||
stockInOutLineChartOptionDays7.value.series = yData;
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
|
||
// 仓库使用率配置
|
||
const stockUsageChartOption = ref({
|
||
title: {
|
||
text: '仓库使用率',
|
||
textStyle: {fontSize: 12}
|
||
},
|
||
color: ['#67c817', '#f5a407'],
|
||
tooltip: {
|
||
trigger: 'item',
|
||
formatter: '{a} <br/> {b}: {c} ({d}%)'
|
||
},
|
||
legend: {orient: 'vertical', left: 'left'},
|
||
label: {
|
||
show: true,
|
||
formatter: '{b} \n{d}%'
|
||
},
|
||
series: [
|
||
{
|
||
name: '仓库使用率', type: 'pie', radius: '50%',
|
||
labelLine: {
|
||
length: 5, // 第一段指示线长度
|
||
length2: 8 // 第二段指示线长度
|
||
},
|
||
data: [
|
||
{name: '占用', value: 1000 },
|
||
{name: '空闲', value: 800 },
|
||
]
|
||
}
|
||
]
|
||
});
|
||
// 今日出入库数量柱状图配置
|
||
const stockInOutChartOption = ref({
|
||
title: {
|
||
text: '今日出入库数量',
|
||
textStyle: {fontSize: 12}
|
||
},
|
||
tooltip: {trigger: 'item'},
|
||
legend: {orient: 'vertical', left: 'left'},
|
||
xAxis: {
|
||
type: 'category',
|
||
data: ['入库', '出库', "移库"]
|
||
},
|
||
yAxis: {type: 'value'},
|
||
series: [
|
||
{
|
||
data: [1000, 800, 400],
|
||
type: 'bar'
|
||
}
|
||
]
|
||
});
|
||
// 近七日设备故障折线图配置
|
||
const stockErrorLineChartOption = ref({
|
||
title: {
|
||
text: '近七日设备故障数量折线图',
|
||
textStyle: {fontSize: 12}
|
||
},
|
||
tooltip: {formatter: '({b}) {c}'},
|
||
xAxis: {
|
||
type: 'category',
|
||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
||
},
|
||
yAxis: {type: 'value'},
|
||
series: [
|
||
{
|
||
data: [820, 932, 901, 934, 1290, 1330, 1320],
|
||
type: 'line',
|
||
smooth: true
|
||
}
|
||
]
|
||
});
|
||
// 七日出入库数量
|
||
const stockInOutLineChartOptionDays7 = ref({
|
||
title: {
|
||
text: '近七日出入库数量折线图',
|
||
textStyle: {fontSize: 12}
|
||
},
|
||
tooltip: {
|
||
trigger: 'axis'
|
||
},
|
||
legend: {orient: 'horizontal', left: 'left'},
|
||
xAxis: {
|
||
type: 'category',
|
||
data: ['1-1', '1-2', '1-3', '1-4', '1-5', '1-6', '1-7']
|
||
},
|
||
yAxis: {type: 'value'},
|
||
series: [
|
||
{
|
||
data: [82, 93, 90, 93, 129, 133, 132],
|
||
type: 'line',
|
||
smooth: true,
|
||
name: '入库数量'
|
||
},
|
||
{
|
||
data: [92, 69, 70, 102, 89, 120, 170],
|
||
type: 'line',
|
||
smooth: true,
|
||
name: '出库数量'
|
||
},
|
||
{
|
||
data: [24, 12, 13, 32, 11, 21, 32],
|
||
type: 'line',
|
||
smooth: true,
|
||
name: '移库数量'
|
||
}
|
||
]
|
||
});
|
||
|
||
</script>
|
||
|
||
<template>
|
||
<div :style="{marginLeft: '10px',marginTop: '10px', width: isFull ? 'calc(100vw - 20px)' : 'calc(100vw - 280px)' }">
|
||
<!-- 系统基本资料-->
|
||
<el-card style="margin-top: 10px">
|
||
<el-descriptions class="margin-top" :column="3" size="default" border>
|
||
<el-descriptions-item>
|
||
<template #label>
|
||
<div class="cell-item"><el-icon style="translate: 0 2px; margin-right: 5px"><AlarmClock /></el-icon>{{ t('mainPage.systemRunningTime') + ':'}}</div>
|
||
</template>
|
||
{{systemInfo?.systemRunningTime ?? "-"}}
|
||
</el-descriptions-item>
|
||
<el-descriptions-item>
|
||
<template #label>
|
||
<div class="cell-item"><el-icon style="translate: 0 2px; margin-right: 5px"><Cpu /></el-icon>{{ t('mainPage.cpuUsage') + ':'}}</div>
|
||
</template>
|
||
{{systemInfo?.cpuData?.totalUseRatio ?? "-"}}%
|
||
</el-descriptions-item>
|
||
<el-descriptions-item>
|
||
<template #label>
|
||
<div class="cell-item"><el-icon style="translate: 0 2px; margin-right: 5px"><Coin /></el-icon>{{ t('mainPage.memoryUsageSize') + ':'}}</div>
|
||
</template>
|
||
{{systemInfo?.memoryData?.used ?? "-"}}
|
||
</el-descriptions-item>
|
||
<el-descriptions-item>
|
||
<template #label>
|
||
<div class="cell-item"><el-icon style="translate: 0 2px; margin-right: 5px"><Stopwatch /></el-icon>{{ t('mainPage.memoryUsage') + ':'}}</div>
|
||
</template>
|
||
{{systemInfo?.memoryData?.usage ?? "-"}}%
|
||
</el-descriptions-item>
|
||
<el-descriptions-item>
|
||
<template #label>
|
||
<div class="cell-item"><el-icon style="translate: 0 2px; margin-right: 5px"><Monitor /></el-icon>{{ t('mainPage.serverName') + ':'}}</div>
|
||
</template>
|
||
{{systemInfo?.serveData?.serveName ?? "-"}}
|
||
</el-descriptions-item>
|
||
<el-descriptions-item>
|
||
<template #label>
|
||
<div class="cell-item"><el-icon style="translate: 0 2px; margin-right: 5px"><Tickets /></el-icon>{{ t('mainPage.serverSystemName') + ':'}}</div>
|
||
</template>
|
||
{{systemInfo?.serveData?.systemName ?? "-"}}
|
||
</el-descriptions-item>
|
||
<el-descriptions-item>
|
||
<template #label>
|
||
<div class="cell-item"><el-icon style="translate: 0 2px; margin-right: 5px"><Location /></el-icon>{{ t('mainPage.serverIp') + ':'}}</div>
|
||
</template>
|
||
{{systemInfo?.serveData?.serveIp ?? "-"}}
|
||
</el-descriptions-item>
|
||
<el-descriptions-item>
|
||
<template #label>
|
||
<div class="cell-item"><el-icon style="translate: 0 2px; margin-right: 5px"><SetUp /></el-icon>{{ t('mainPage.serverSystemVersion') + ':'}}</div>
|
||
</template>
|
||
{{systemInfo?.serveData?.systemVersion ?? "-"}}
|
||
</el-descriptions-item>
|
||
|
||
</el-descriptions>
|
||
</el-card>
|
||
<el-card style="margin-top: 10px;">
|
||
<el-scrollbar>
|
||
<el-row style="width: calc(100vw - 330px)">
|
||
<el-col :span="6">
|
||
<el-scrollbar>
|
||
<ChartPie style="width: 300px; height: calc(300px - 40px)" :option="stockUsageChartOption" />
|
||
</el-scrollbar>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-scrollbar>
|
||
<ChartBar style="width: 300px; height: calc(300px - 40px)" :option="stockInOutChartOption" />
|
||
</el-scrollbar>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-scrollbar>
|
||
<ChartLine :key="1" style="width: 350px; height: calc(300px - 40px)" :option="stockErrorLineChartOption" />
|
||
</el-scrollbar>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-scrollbar>
|
||
<ChartLine :key="2" style="width: 300px; height: calc(300px - 40px)" :option="stockInOutLineChartOptionDays7" />
|
||
</el-scrollbar>
|
||
</el-col>
|
||
</el-row>
|
||
</el-scrollbar>
|
||
</el-card>
|
||
<!-- <el-card style="margin-top: 10px; height: calc(100vh - 200px)">-->
|
||
<!-- <el-table :data="eventInfo" stripe border style="width: 100%" height="calc(100vh - 240px)">-->
|
||
<!-- <el-table-column prop="eventTime" label="时间" width="180" align="center"/>-->
|
||
<!-- <el-table-column prop="eventMsg" label="内容" show-overflow-tooltip/>-->
|
||
<!-- </el-table>-->
|
||
<!-- </el-card>-->
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped>
|
||
|
||
</style> |