|
@@ -53,36 +53,103 @@
|
|
range-separator="至"
|
|
range-separator="至"
|
|
start-placeholder="开始日期"
|
|
start-placeholder="开始日期"
|
|
end-placeholder="结束日期"
|
|
end-placeholder="结束日期"
|
|
- :default-value="[defaultStartDate, defaultEndDate]"
|
|
|
|
- @change="handleDateChange"
|
|
|
|
|
|
+ @change="getAlarmStatistics"
|
|
size="small"
|
|
size="small"
|
|
- style="margin-left: 10px; width: 240px"
|
|
|
|
|
|
+ style="max-width: 200px"
|
|
|
|
+ :clearable="false"
|
|
/>
|
|
/>
|
|
</div>
|
|
</div>
|
|
<VueUiXy v-if="dataset4?.length" :config="config4" :dataset="dataset4" />
|
|
<VueUiXy v-if="dataset4?.length" :config="config4" :dataset="dataset4" />
|
|
<VueUiSkeleton v-else :config="{ type: 'bar' }" />
|
|
<VueUiSkeleton v-else :config="{ type: 'bar' }" />
|
|
</el-card>
|
|
</el-card>
|
|
<el-card shadow="nover">
|
|
<el-card shadow="nover">
|
|
- <div class="title">告警增长趋势</div>
|
|
|
|
- <VueUiSkeleton :config="{ type: 'bar' }" />
|
|
|
|
|
|
+ <div class="title">
|
|
|
|
+ 告警增长趋势
|
|
|
|
+ <el-date-picker
|
|
|
|
+ v-model="analyzeTrendDate"
|
|
|
|
+ type="month"
|
|
|
|
+ @change="getAnalyzeTrend"
|
|
|
|
+ size="small"
|
|
|
|
+ style="max-width: 100px"
|
|
|
|
+ :clearable="false"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <VueUiDonut v-if="dataset5?.length" :config="config5" :dataset="dataset5" />
|
|
|
|
+ <VueUiSkeleton v-else :config="{ type: 'donut' }" />
|
|
</el-card>
|
|
</el-card>
|
|
<el-card shadow="nover">
|
|
<el-card shadow="nover">
|
|
- <div class="title">部门告警分析</div>
|
|
|
|
- <VueUiSkeleton :config="{ type: 'bar' }" />
|
|
|
|
|
|
+ <div class="title">
|
|
|
|
+ 部门告警分析
|
|
|
|
+ <el-date-picker
|
|
|
|
+ v-model="deptAlarmDate"
|
|
|
|
+ type="daterange"
|
|
|
|
+ range-separator="至"
|
|
|
|
+ start-placeholder="开始日期"
|
|
|
|
+ end-placeholder="结束日期"
|
|
|
|
+ @change="getDeptAlarm"
|
|
|
|
+ size="small"
|
|
|
|
+ style="max-width: 200px"
|
|
|
|
+ :clearable="false"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <VueUiXy v-if="dataset6?.length" :config="config6" :dataset="dataset6" />
|
|
|
|
+ <VueUiSkeleton v-else :config="{ type: 'bar' }" />
|
|
</el-card>
|
|
</el-card>
|
|
</div>
|
|
</div>
|
|
<div class="flex-row" style="gap: 12px">
|
|
<div class="flex-row" style="gap: 12px">
|
|
<el-card shadow="nover">
|
|
<el-card shadow="nover">
|
|
- <div class="title">告警状态</div>
|
|
|
|
- <VueUiSkeleton :config="{ type: 'bar' }" />
|
|
|
|
|
|
+ <div class="title">
|
|
|
|
+ 告警状态
|
|
|
|
+ <el-date-picker
|
|
|
|
+ v-model="alarmStatusDate"
|
|
|
|
+ type="daterange"
|
|
|
|
+ range-separator="至"
|
|
|
|
+ start-placeholder="开始日期"
|
|
|
|
+ end-placeholder="结束日期"
|
|
|
|
+ @change="getAlarmStatus"
|
|
|
|
+ size="small"
|
|
|
|
+ style="max-width: 200px"
|
|
|
|
+ :clearable="false"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <VueUiXy v-if="dataset7?.length" :config="config7" :dataset="dataset7" />
|
|
|
|
+ <VueUiSkeleton v-else :config="{ type: 'bar' }" />
|
|
</el-card>
|
|
</el-card>
|
|
<el-card shadow="nover">
|
|
<el-card shadow="nover">
|
|
- <div class="title">告警等级</div>
|
|
|
|
- <VueUiSkeleton :config="{ type: 'bar' }" />
|
|
|
|
|
|
+ <div class="title">
|
|
|
|
+ 告警等级
|
|
|
|
+ <el-date-picker
|
|
|
|
+ v-model="alarmLevelDate"
|
|
|
|
+ type="daterange"
|
|
|
|
+ range-separator="至"
|
|
|
|
+ start-placeholder="开始日期"
|
|
|
|
+ end-placeholder="结束日期"
|
|
|
|
+ @change="getAlarmLevel"
|
|
|
|
+ size="small"
|
|
|
|
+ style="max-width: 200px"
|
|
|
|
+ :clearable="false"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <VueUiXy v-if="dataset9?.length" :config="config9" :dataset="dataset9" />
|
|
|
|
+ <VueUiSkeleton v-else :config="{ type: 'bar' }" />
|
|
</el-card>
|
|
</el-card>
|
|
<el-card shadow="nover">
|
|
<el-card shadow="nover">
|
|
- <div class="title">告警类型</div>
|
|
|
|
- <VueUiSkeleton :config="{ type: 'bar' }" />
|
|
|
|
|
|
+ <div class="title">
|
|
|
|
+ 告警类型
|
|
|
|
+ <el-date-picker
|
|
|
|
+ v-model="alarmTypeDate"
|
|
|
|
+ type="daterange"
|
|
|
|
+ range-separator="至"
|
|
|
|
+ start-placeholder="开始日期"
|
|
|
|
+ end-placeholder="结束日期"
|
|
|
|
+ @change="getAlarmType"
|
|
|
|
+ size="small"
|
|
|
|
+ style="max-width: 200px"
|
|
|
|
+ :clearable="false"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <VueUiXy v-if="dataset8?.length" :config="config8" :dataset="dataset8" />
|
|
|
|
+ <VueUiSkeleton v-else :config="{ type: 'bar' }" />
|
|
</el-card>
|
|
</el-card>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@@ -92,7 +159,12 @@
|
|
import { unref, reactive, getCurrentInstance, ref } from "vue";
|
|
import { unref, reactive, getCurrentInstance, ref } from "vue";
|
|
import { VueUiXy, VueUiDonut, VueUiSkeleton } from "vue-data-ui";
|
|
import { VueUiXy, VueUiDonut, VueUiSkeleton } from "vue-data-ui";
|
|
import "vue-data-ui/style.css";
|
|
import "vue-data-ui/style.css";
|
|
-import { getBarData, getLineData, getPieData } from "/@/utils/dataUiOptions";
|
|
|
|
|
|
+import {
|
|
|
|
+ getBarData,
|
|
|
|
+ getLineData,
|
|
|
|
+ getPieData,
|
|
|
|
+ getPieSmallData,
|
|
|
|
+} from "/@/utils/dataUiOptions";
|
|
import api from "/@/api/alarm";
|
|
import api from "/@/api/alarm";
|
|
import { useThemeChange } from "/@/hooks/useCommon";
|
|
import { useThemeChange } from "/@/hooks/useCommon";
|
|
import dayjs from "dayjs";
|
|
import dayjs from "dayjs";
|
|
@@ -104,38 +176,24 @@ function typeFormat(type: string) {
|
|
return proxy.selectDictLabel(unref(alarm_type), type);
|
|
return proxy.selectDictLabel(unref(alarm_type), type);
|
|
}
|
|
}
|
|
|
|
|
|
-//#region 线图
|
|
|
|
-
|
|
|
|
-// 获取默认图形配置数据
|
|
|
|
-const chartData = getLineData({
|
|
|
|
- xAxis: [],
|
|
|
|
- legend: [" "],
|
|
|
|
- datas: [[]],
|
|
|
|
- responsive: true,
|
|
|
|
-});
|
|
|
|
-
|
|
|
|
const config = ref<any>({});
|
|
const config = ref<any>({});
|
|
const config2 = ref<any>({});
|
|
const config2 = ref<any>({});
|
|
const config4 = ref<any>({});
|
|
const config4 = ref<any>({});
|
|
-const dataset = ref<any[]>([]);
|
|
|
|
|
|
+const config5 = ref<any>({});
|
|
|
|
+const config6 = ref<any>({});
|
|
|
|
+const config7 = ref<any>({});
|
|
|
|
+const config8 = ref<any>({});
|
|
|
|
+const config9 = ref<any>({});
|
|
const dataset2 = ref<any[]>([]);
|
|
const dataset2 = ref<any[]>([]);
|
|
const dataset4 = ref<any[]>([]);
|
|
const dataset4 = ref<any[]>([]);
|
|
-
|
|
|
|
-//#endregion
|
|
|
|
-
|
|
|
|
-//#region 饼图
|
|
|
|
-
|
|
|
|
-// 获取默认图形配置数据
|
|
|
|
-const pieData = getPieData({
|
|
|
|
- legend: [" "],
|
|
|
|
- datas: [[]],
|
|
|
|
-});
|
|
|
|
-
|
|
|
|
-const pieConfig = ref<any>(pieData.config);
|
|
|
|
-const pieDataset = ref<any[]>(pieData.dataset);
|
|
|
|
|
|
+const dataset5 = ref<any[]>([]);
|
|
|
|
+const dataset6 = ref<any[]>([]);
|
|
|
|
+const dataset7 = ref<any[]>([]);
|
|
|
|
+const dataset8 = ref<any[]>([]);
|
|
|
|
+const dataset9 = ref<any[]>([]);
|
|
|
|
|
|
// 监听暗黑模式变化,将 vue-data-ui 的 config 传进来,就能自动更新主题
|
|
// 监听暗黑模式变化,将 vue-data-ui 的 config 传进来,就能自动更新主题
|
|
-useThemeChange([config, pieConfig]);
|
|
|
|
|
|
+useThemeChange([config, config2, config4, config5, config6, config7, config8, config9]);
|
|
|
|
|
|
const todayCount = reactive({
|
|
const todayCount = reactive({
|
|
currentDayCount: "-",
|
|
currentDayCount: "-",
|
|
@@ -147,10 +205,23 @@ const alarmNewList = ref<any[]>([]);
|
|
const defaultStartDate = dayjs().subtract(7, "day").toDate();
|
|
const defaultStartDate = dayjs().subtract(7, "day").toDate();
|
|
const defaultEndDate = dayjs().toDate();
|
|
const defaultEndDate = dayjs().toDate();
|
|
const dateRange = ref([defaultStartDate, defaultEndDate]);
|
|
const dateRange = ref([defaultStartDate, defaultEndDate]);
|
|
-
|
|
|
|
-const handleDateChange = () => {
|
|
|
|
- getAlarmStatistics();
|
|
|
|
-};
|
|
|
|
|
|
+const analyzeTrendDate = ref(dayjs().format("YYYY-MM"));
|
|
|
|
+const deptAlarmDate = ref([
|
|
|
|
+ dayjs().subtract(7, "day").format("YYYY-MM-DD"),
|
|
|
|
+ dayjs().format("YYYY-MM-DD"),
|
|
|
|
+]);
|
|
|
|
+const alarmStatusDate = ref([
|
|
|
|
+ dayjs().subtract(7, "day").format("YYYY-MM-DD"),
|
|
|
|
+ dayjs().format("YYYY-MM-DD"),
|
|
|
|
+]);
|
|
|
|
+const alarmTypeDate = ref([
|
|
|
|
+ dayjs().subtract(7, "day").format("YYYY-MM-DD"),
|
|
|
|
+ dayjs().format("YYYY-MM-DD"),
|
|
|
|
+]);
|
|
|
|
+const alarmLevelDate = ref([
|
|
|
|
+ dayjs().subtract(7, "day").format("YYYY-MM-DD"),
|
|
|
|
+ dayjs().format("YYYY-MM-DD"),
|
|
|
|
+]);
|
|
|
|
|
|
getData();
|
|
getData();
|
|
|
|
|
|
@@ -171,6 +242,16 @@ function getData() {
|
|
});
|
|
});
|
|
// 告警统计
|
|
// 告警统计
|
|
getAlarmStatistics();
|
|
getAlarmStatistics();
|
|
|
|
+ // 告警趋势统计
|
|
|
|
+ getAnalyzeTrend();
|
|
|
|
+ // 部门告警统计
|
|
|
|
+ getDeptAlarm();
|
|
|
|
+ // 告警状态统计
|
|
|
|
+ getAlarmStatus();
|
|
|
|
+ // 告警类型统计
|
|
|
|
+ getAlarmType();
|
|
|
|
+ // 告警等级统计
|
|
|
|
+ getAlarmLevel();
|
|
// 告警设备top10
|
|
// 告警设备top10
|
|
api.dashboard.getDeviceAlarmTop10().then((res: any) => {
|
|
api.dashboard.getDeviceAlarmTop10().then((res: any) => {
|
|
const list = res || [];
|
|
const list = res || [];
|
|
@@ -194,7 +275,6 @@ function getAlarmStatistics() {
|
|
endDate: dayjs(dateRange.value[1]).format("YYYY-MM-DD"),
|
|
endDate: dayjs(dateRange.value[1]).format("YYYY-MM-DD"),
|
|
})
|
|
})
|
|
.then((res: any) => {
|
|
.then((res: any) => {
|
|
- console.log(res);
|
|
|
|
const list = res || [];
|
|
const list = res || [];
|
|
const chartData = getBarData({
|
|
const chartData = getBarData({
|
|
xAxis: list.map((item: any) => item.alarmDate),
|
|
xAxis: list.map((item: any) => item.alarmDate),
|
|
@@ -205,11 +285,136 @@ function getAlarmStatistics() {
|
|
modulo: 3,
|
|
modulo: 3,
|
|
responsive: true,
|
|
responsive: true,
|
|
});
|
|
});
|
|
- console.log(chartData);
|
|
|
|
config4.value = chartData.config;
|
|
config4.value = chartData.config;
|
|
dataset4.value = chartData.dataset;
|
|
dataset4.value = chartData.dataset;
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+function getAnalyzeTrend() {
|
|
|
|
+ api.dashboard
|
|
|
|
+ .getAnalyzeTrend({
|
|
|
|
+ searchMonth: analyzeTrendDate.value,
|
|
|
|
+ })
|
|
|
|
+ .then((res: any) => {
|
|
|
|
+ const list = res || [];
|
|
|
|
+ console.log({
|
|
|
|
+ legend: list.map((item: any) => item.month),
|
|
|
|
+ datas: list.map((item: any) => [item.alarmCount]),
|
|
|
|
+ width: 300,
|
|
|
|
+ height: 300,
|
|
|
|
+ responsive: false,
|
|
|
|
+ });
|
|
|
|
+ const chartData = getPieSmallData({
|
|
|
|
+ legend: list.map((item: any) => item.month),
|
|
|
|
+ datas: list.map((item: any) => [item.alarmCount]),
|
|
|
|
+ width: 300,
|
|
|
|
+ height: 300,
|
|
|
|
+ responsive: false,
|
|
|
|
+ });
|
|
|
|
+ config5.value = chartData.config;
|
|
|
|
+ dataset5.value = chartData.dataset;
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function getDeptAlarm() {
|
|
|
|
+ api.dashboard
|
|
|
|
+ .getDeptAlarm({
|
|
|
|
+ startDate: deptAlarmDate.value[0],
|
|
|
|
+ endDate: deptAlarmDate.value[1],
|
|
|
|
+ })
|
|
|
|
+ .then((res: any) => {
|
|
|
|
+ console.log(res);
|
|
|
|
+ const list = res || [];
|
|
|
|
+ const chartData = getBarData({
|
|
|
|
+ xAxis: list.map((item: any) => item.deptName),
|
|
|
|
+ legend: ["部门告警"],
|
|
|
|
+ datas: [list.map((item: any) => item.alarmCount)],
|
|
|
|
+ width: 300,
|
|
|
|
+ height: 300,
|
|
|
|
+ modulo: 3,
|
|
|
|
+ responsive: true,
|
|
|
|
+ });
|
|
|
|
+ config6.value = chartData.config;
|
|
|
|
+ dataset6.value = chartData.dataset;
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function getAlarmStatus() {
|
|
|
|
+ api.dashboard
|
|
|
|
+ .getAlarmStatus({
|
|
|
|
+ startDate: alarmStatusDate.value[0],
|
|
|
|
+ endDate: alarmStatusDate.value[1],
|
|
|
|
+ })
|
|
|
|
+ .then((res: any) => {
|
|
|
|
+ console.log(res);
|
|
|
|
+ const list = res || [];
|
|
|
|
+ const chartData = getBarData({
|
|
|
|
+ xAxis: list.map((item: any) => (item.status ? "已处理" : "未处理")),
|
|
|
|
+ legend: ["告警状态"],
|
|
|
|
+ datas: [list.map((item: any) => item.alarmCount)],
|
|
|
|
+ width: 300,
|
|
|
|
+ height: 300,
|
|
|
|
+ modulo: 3,
|
|
|
|
+ responsive: true,
|
|
|
|
+ });
|
|
|
|
+ config7.value = chartData.config;
|
|
|
|
+ dataset7.value = chartData.dataset;
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function getAlarmType() {
|
|
|
|
+ api.dashboard
|
|
|
|
+ .getAlarmType({
|
|
|
|
+ startDate: alarmTypeDate.value[0],
|
|
|
|
+ endDate: alarmTypeDate.value[1],
|
|
|
|
+ })
|
|
|
|
+ .then((res: any) => {
|
|
|
|
+ console.log(res);
|
|
|
|
+ const list = res || [];
|
|
|
|
+ console.log({
|
|
|
|
+ legend: list.map((item: any) =>
|
|
|
|
+ item.alarmType === "1" ? "规则告警" : "自助上报告警"
|
|
|
|
+ ),
|
|
|
|
+ datas: list.map((item: any) => [item.alarmCount]),
|
|
|
|
+ width: 300,
|
|
|
|
+ height: 300,
|
|
|
|
+ responsive: true,
|
|
|
|
+ });
|
|
|
|
+ const chartData = getPieSmallData({
|
|
|
|
+ legend: list.map((item: any) =>
|
|
|
|
+ item.alarmType === "1" ? "规则告警" : "自助上报告警"
|
|
|
|
+ ),
|
|
|
|
+ datas: list.map((item: any) => [item.alarmCount]),
|
|
|
|
+ width: 300,
|
|
|
|
+ height: 300,
|
|
|
|
+ responsive: true,
|
|
|
|
+ });
|
|
|
|
+ config8.value = chartData.config;
|
|
|
|
+ dataset8.value = chartData.dataset;
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function getAlarmLevel() {
|
|
|
|
+ api.dashboard
|
|
|
|
+ .getAlarmLevel({
|
|
|
|
+ startDate: alarmLevelDate.value[0],
|
|
|
|
+ endDate: alarmLevelDate.value[1],
|
|
|
|
+ })
|
|
|
|
+ .then((res: any) => {
|
|
|
|
+ const list = res || [];
|
|
|
|
+ const chartData = getBarData({
|
|
|
|
+ xAxis: list.map((item: any) => item.levelName),
|
|
|
|
+ legend: ["告警等级"],
|
|
|
|
+ datas: [list.map((item: any) => item.alarmCount)],
|
|
|
|
+ width: 300,
|
|
|
|
+ height: 300,
|
|
|
|
+ modulo: 3,
|
|
|
|
+ responsive: true,
|
|
|
|
+ });
|
|
|
|
+ config9.value = chartData.config;
|
|
|
|
+ dataset9.value = chartData.dataset;
|
|
|
|
+ });
|
|
|
|
+}
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
<style scoped lang="scss">
|
|
@@ -232,6 +437,9 @@ function getAlarmStatistics() {
|
|
color: #333;
|
|
color: #333;
|
|
font-weight: 500;
|
|
font-weight: 500;
|
|
line-height: 1;
|
|
line-height: 1;
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: space-between;
|
|
}
|
|
}
|
|
|
|
|
|
.flex-row {
|
|
.flex-row {
|
|
@@ -250,6 +458,7 @@ function getAlarmStatistics() {
|
|
justify-content: space-between;
|
|
justify-content: space-between;
|
|
|
|
|
|
.vue-ui-xy,
|
|
.vue-ui-xy,
|
|
|
|
+ .vue-ui-donut,
|
|
.vue-ui-skeleton {
|
|
.vue-ui-skeleton {
|
|
flex: 1;
|
|
flex: 1;
|
|
height: 100%;
|
|
height: 100%;
|