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>
|