SourceTermAnalysisSystem_vue/src/pages/largeScreen1/index.vue
2026-05-15 10:13:06 +08:00

492 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang='ts'>
import { useI18n } from 'vue-i18n';
import { getEmailList, getRecentEmailDatas, getRecentEmailDatasMonth, getTaskHisSta, getTaskStatsDay, getTaskStatsMonth } from '@/utils/axios/sjtbJcfx/index';
import DataAnalysis from './dataAnalysis.vue';
import HisCumulative from './hisCumulative.vue';
import StackChart from './stackChart.vue';
const { t } = useI18n();
interface SampleItem {
name: string;
value: number;
}
// 历史累计同步数据
const hisCumulativeList = ref<SampleItem[]>([]);
// ---------- 1. 定义StackChart需要的图表数据结构 ----------
interface StackChartData {
xList: string[]; // x轴分类小时/日期)
seriesList: {
name: string;
data: number[];
}[]; // 系列数据
}
// 初始化StackChart的数据源对应你提供的接口数据
const stackChartData = ref<StackChartData>({
xList: [],
seriesList: [],
});
// 同步数据分析数据供DataAnalysis子组件使用
const chartData = ref({
xList: [],
seriesList: [],
});
// 同步数据分析ref实例
const dataAnalysisRef = ref<InstanceType<typeof DataAnalysis> | null>(null);
const analysisList = ref<any>([]);
// 邮箱图表ref实例
const stackChartRef = ref<InstanceType<typeof StackChart> | null>(null);
function switchActive(index: any) {
analysisList.value.forEach((item: any) => {
item.active = false;
});
analysisList.value[index].active = true;
const activeTab = stackChartRef?.value?.activeTab || 'day';
const activeEmailId = analysisList.value.find((item: any) => item.active)?.id || '';
if (!activeEmailId)
return;
if (activeTab === 'day') {
getRecentEmailDatas(activeEmailId, (res) => {
formatStackChartData(res, 'day');
});
}
else {
getRecentEmailDatasMonth(activeEmailId, (res) => {
formatStackChartData(res, 'month');
});
}
}
// ---------- 2. 格式化StackChart的接口数据 ----------
function formatStackChartData(res: any, type: 'day' | 'month') {
if (!res)
return;
stackChartData.value.xList = res.categories || [];
// 按维度区分系列名称和数据
if (type === 'day') {
stackChartData.value.seriesList = [
{ name: '今日报警', data: res.series.todayAlarm || [] },
{ name: '今日处理', data: res.series.todayProcess || [] },
{ name: '昨日报警', data: res.series.yesterdayAlarm || [] },
{ name: '昨日处理', data: res.series.yesterdayProcess || [] },
];
}
else {
stackChartData.value.seriesList = [
{ name: '本月报警', data: res.series.alarm || [] },
{ name: '本月处理', data: res.series.process || [] },
// 若月维度有其他字段,补充对应名称
];
}
}
// ---------- 3. 核心数据格式化工具函数原DataAnalysis用 ----------
function formatChartData(res: any) {
const { dateTimes = [], taskStatsInfos = [] } = res;
const seriesList: any = [];
taskStatsInfos.forEach((task: any) => {
const { taskName, taskStats = [] } = task;
const data = Array.from({ length: dateTimes.length }).fill(0);
taskStats.forEach((stat: any) => {
const { dateTime, syncNum } = stat;
const dateIndex = dateTimes.indexOf(dateTime);
if (dateIndex > -1) {
data[dateIndex] = Number(syncNum) || 0;
}
});
seriesList.push({
name: taskName,
data,
});
});
return {
xList: dateTimes,
seriesList,
};
}
// ---------- 4. 完善查询数据逻辑 ----------
async function getData() {
// 1. 查询历史累计数据
getTaskHisSta((res) => {
hisCumulativeList.value = res.map((item: any) => ({
name: item.taskName,
value: Number(item.syncNum) || 0,
}));
});
// 2. 获取DataAnalysis子组件Tab维度
const activeTab = dataAnalysisRef?.value?.activeTab || 'day';
if (activeTab === 'day') {
getTaskStatsDay(true, (res) => {
chartData.value = formatChartData(res);
});
}
else {
getTaskStatsMonth(true, (res) => {
chartData.value = formatChartData(res);
});
}
// 3. 获取StackChart子组件Tab维度并请求数据
const activeTab2 = stackChartRef?.value?.activeTab || 'day';
const activeEmailId = analysisList.value.find((item: any) => item.active)?.id || '';
if (!activeEmailId)
return;
if (activeTab2 === 'day') {
getRecentEmailDatas(activeEmailId, (res) => {
console.log('StackChart日维度数据', res);
formatStackChartData(res, 'day'); // 格式化并赋值
});
}
else {
getRecentEmailDatasMonth(activeEmailId, (res) => {
console.log('StackChart月维度数据', res);
formatStackChartData(res, 'month'); // 格式化并赋值
});
}
}
// ---------- 5. 生命周期与定时器 ----------
onMounted(() => {
// 获取邮箱列表
getEmailList((res) => {
analysisList.value = res.map((item: any) => ({
id: item.sourceId,
label: item.sourceName,
active: false,
}));
analysisList.value[0].active = true;
nextTick(() => {
getData();
});
});
const timer = setInterval(() => {
getData();
}, 10000);
onUnmounted(() => {
clearInterval(timer);
});
});
// ---------- 6. 监听DataAnalysis Tab切换 ----------
watch(() => dataAnalysisRef?.value?.activeTab, () => {
const activeTab = dataAnalysisRef?.value?.activeTab || 'day';
if (activeTab === 'day') {
getTaskStatsDay(false, (res) => {
chartData.value = formatChartData(res);
});
}
else {
getTaskStatsMonth(false, (res) => {
chartData.value = formatChartData(res);
});
}
}, { immediate: false });
// ---------- 7. 监听StackChart Tab切换 ----------
watch(() => stackChartRef?.value?.activeTab, () => {
const activeTab = stackChartRef?.value?.activeTab || 'day';
const activeEmailId = analysisList.value.find((item: any) => item.active)?.id || '';
if (!activeEmailId)
return;
if (activeTab === 'day') {
getRecentEmailDatas(activeEmailId, (res) => {
formatStackChartData(res, 'day');
});
}
else {
getRecentEmailDatasMonth(activeEmailId, (res) => {
formatStackChartData(res, 'month');
});
}
}, { immediate: false });
</script>
<template>
<div class="largeScreen1">
<div class="header">
<div class="logoDom">
<div class="logo">
<SvgIcon name="logo" width="50" height="50" />
<div class="title">
{{ t('analysisTitle') }}
</div>
</div>
</div>
</div>
<div class="contnetBg">
<div class="content">
<div class="IDCHeader">
<div class="left">
IDC数据同步状态
</div>
<div class="right" />
</div>
<div class="topChart">
<div class="left">
<div class="topChartHeader">
<div class="title">
同步数据分析
</div>
<div class="status">
同步异常:网络断开
</div>
</div>
<div class="dataAnalysisDom">
<DataAnalysis ref="dataAnalysisRef" :chart-data="chartData" />
</div>
</div>
<div class="right">
<div class="topChartHeader">
<div class="title">
历史累积同步
</div>
<div class="status" />
</div>
<div class="hisCumulativeDom">
<HisCumulative :list="hisCumulativeList" />
</div>
</div>
</div>
<div class="bottomChart">
<div class="bottomChartHeader">
<div class="left">
<div v-for="(v, i) in analysisList" :key="i" class="analysisItem" :class="{ active: v.active }"
@click="switchActive(i)">
{{ v.label }}
</div>
</div>
<div class="right">
<span>连接状态:</span>
<span class="status">连接中</span>
</div>
</div>
<div class="stackChartDom">
<StackChart ref="stackChartRef" :chart-data="stackChartData" />
</div>
</div>
</div>
</div>
</div>
</template>
<style scoped lang='less'>
.largeScreen1 {
width: 100%;
background: url('@/assets/img/largeScreenBg.png') no-repeat center center;
background-size: 100% 100%;
.header {
width: 100%;
height: 74px;
background: url('@/assets/img/largeScreenHeader.png') no-repeat center center;
background-size: 100% 100%;
position: relative;
display: flex;
align-items: center;
justify-content: center;
.logoDom {
min-width: 50px;
height: 74px;
display: flex;
align-items: flex-start;
justify-content: center;
padding-top: 5px;
.logo {
display: flex;
align-items: center;
justify-content: space-between;
}
.title {
margin-left: 9px;
letter-spacing: 9px;
font-size: 28px;
color: #ffffff;
}
}
}
.contnetBg {
width: 100%;
height: calc(100vh - 74px);
background: url('@/assets/img/largeScreenContentBg.png') no-repeat center center;
background-size: 100% 100%;
padding: 30px 27px;
.content {
width: 100%;
height: 100%;
.IDCHeader {
width: 100%;
height: 39px;
border-top: 1px solid rgb(7, 84, 75);
border-bottom: 4px solid rgb(7, 84, 75);
display: flex;
justify-content: space-between;
align-items: center;
padding-right: 50px;
margin-bottom: 15px;
.left {
width: 186px;
height: 40px;
font-size: 18px;
background: rgba(12, 235, 201, 0.05);
color: rgb(12, 235, 201);
display: flex;
align-items: center;
justify-content: center;
}
.right {
width: 83px;
height: 16px;
background: url('@/assets/img/IDCBg.png') no-repeat center center;
background-size: 100% 100%;
}
}
.topChart {
width: 100%;
height: 416px;
margin-bottom: 22px;
display: flex;
justify-content: space-between;
align-items: center;
.left {
width: 1333px;
height: 100%;
.topChartHeader {
width: 100%;
height: 40px;
background-color: rgba(12, 235, 201, 0.08);
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 12px;
.title {
color: rgb(173, 230, 238);
}
.status {
color: rgb(255, 75, 75);
}
}
.dataAnalysisDom {
width: 100%;
height: calc(100% - 40px);
}
}
.right {
width: 501px;
height: 100%;
.topChartHeader {
width: 100%;
height: 40px;
background-color: rgba(12, 235, 201, 0.08);
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 12px;
.title {
color: rgb(173, 230, 238);
}
.status {
color: rgb(255, 75, 75);
}
}
.hisCumulativeDom {
width: 100%;
height: calc(100% - 40px);
}
}
}
.bottomChart {
width: 100%;
height: calc(100% - 416px - 22px - 39px - 15px);
.bottomChartHeader {
width: 100%;
height: 40px;
background-color: rgba(12, 235, 201, 0.08);
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 12px;
.left {
display: flex;
align-items: center;
.analysisItem {
width: auto;
height: 30px;
margin-right: 10px;
color: #c9f6f6;
background: url('@/assets/img/tabsBtn_default.png') no-repeat center center;
background-size: 100% 100%;
display: flex;
justify-content: center;
align-items: center;
padding: 0 15px;
cursor: pointer;
}
.analysisItem.active {
background: url('@/assets/img/tabsBtn_active.png') no-repeat center center;
background-size: 100% 100%;
}
}
.right {
color: #ade6ee;
.status {
color: #35eb4e;
}
}
}
.stackChartDom {
width: 100%;
height: calc(100% - 40px);
}
}
}
}
}
</style>