fix
This commit is contained in:
17
src/api/kb/review.ts
Normal file
17
src/api/kb/review.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { request } from "@/api/request";
|
||||||
|
|
||||||
|
export type ReviewStatsResourceType = "all" | "document" | "faq";
|
||||||
|
|
||||||
|
/** 审核统计接口返回的 data 字段 */
|
||||||
|
export interface ReviewStatsPayload {
|
||||||
|
need_my_review_document?: number;
|
||||||
|
need_my_review_faq?: number;
|
||||||
|
need_my_review_total?: number;
|
||||||
|
need_my_review_unreviewed_document?: number;
|
||||||
|
need_my_review_unreviewed_faq?: number;
|
||||||
|
need_my_review_unreviewed_total?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 按当前登录用户统计需要本人审核的数量(不含本人为作者的稿件) */
|
||||||
|
export const fetchReviewStats = (params?: { resource_type?: ReviewStatsResourceType }) =>
|
||||||
|
request.get("/Kb/v1/review/stats", params ? { params } : undefined);
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
<div class="stat-card-header">
|
<div class="stat-card-header">
|
||||||
<div class="stat-title">
|
<div class="stat-title">
|
||||||
<span class="stat-name">{{ card.title }}</span>
|
<span class="stat-name">{{ card.title }}</span>
|
||||||
<a-tag v-if="card.title === '警告' || card.title === '工单'" size="small" class="stat-tag">
|
<a-tag v-if="card.title === '警告' || card.title === '工单' || card.title === '审核'" size="small" class="stat-tag">
|
||||||
待处理/总数
|
待处理/总数
|
||||||
</a-tag>
|
</a-tag>
|
||||||
<a-tag v-else size="small" class="stat-tag">在线/总数</a-tag>
|
<a-tag v-else size="small" class="stat-tag">在线/总数</a-tag>
|
||||||
@@ -135,6 +135,7 @@ import {
|
|||||||
IconWifi,
|
IconWifi,
|
||||||
IconExclamationCircle,
|
IconExclamationCircle,
|
||||||
IconFile,
|
IconFile,
|
||||||
|
IconCheckCircle,
|
||||||
IconBarChart,
|
IconBarChart,
|
||||||
IconInfoCircle,
|
IconInfoCircle,
|
||||||
IconRight
|
IconRight
|
||||||
@@ -152,6 +153,7 @@ import dayjs from 'dayjs';
|
|||||||
import { fetchAlertCount, fetchHistories } from '@/api/ops/alertHistory';
|
import { fetchAlertCount, fetchHistories } from '@/api/ops/alertHistory';
|
||||||
import { fetchCollectorStatistics } from '@/api/ops/dcControl';
|
import { fetchCollectorStatistics } from '@/api/ops/dcControl';
|
||||||
import { fetchFeedbackTicketStatistics } from '@/api/ops/feedbackTicket';
|
import { fetchFeedbackTicketStatistics } from '@/api/ops/feedbackTicket';
|
||||||
|
import { fetchReviewStats } from '@/api/kb/review';
|
||||||
|
|
||||||
// 注册必要的 ECharts 组件
|
// 注册必要的 ECharts 组件
|
||||||
use([
|
use([
|
||||||
@@ -166,8 +168,8 @@ const router = useRouter();
|
|||||||
const month = ref('2025年3月');
|
const month = ref('2025年3月');
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
const chartLoading = ref(false);
|
const chartLoading = ref(false);
|
||||||
const numberAnimated = ref([false, false, false, false, false]);
|
const numberAnimated = ref([false, false, false, false, false, false]);
|
||||||
const animatedNumbers = ref([0, 0, 0, 0, 0]);
|
const animatedNumbers = ref([0, 0, 0, 0, 0, 0]);
|
||||||
|
|
||||||
// 统计数据
|
// 统计数据
|
||||||
const statistics = reactive({
|
const statistics = reactive({
|
||||||
@@ -175,7 +177,8 @@ const statistics = reactive({
|
|||||||
cluster: { pending: 0, total: 0 },
|
cluster: { pending: 0, total: 0 },
|
||||||
network: { pending: 0, total: 0 },
|
network: { pending: 0, total: 0 },
|
||||||
alert: { pending: 0, total: 0 },
|
alert: { pending: 0, total: 0 },
|
||||||
ticket: { pending: 0, total: 0 }
|
ticket: { pending: 0, total: 0 },
|
||||||
|
review: { pending: 0, total: 0 }
|
||||||
});
|
});
|
||||||
|
|
||||||
const pendingAlerts = ref<any[]>([]);
|
const pendingAlerts = ref<any[]>([]);
|
||||||
@@ -221,6 +224,14 @@ const statCards = computed(() => [
|
|||||||
lightColor: 'rgba(114, 46, 209, 0.1)',
|
lightColor: 'rgba(114, 46, 209, 0.1)',
|
||||||
darkColor: 'rgba(114, 46, 209, 0.15)',
|
darkColor: 'rgba(114, 46, 209, 0.15)',
|
||||||
iconColor: '#722ED1'
|
iconColor: '#722ED1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '审核',
|
||||||
|
pending: statistics.review.pending,
|
||||||
|
total: statistics.review.total,
|
||||||
|
lightColor: 'rgba(19, 194, 194, 0.1)',
|
||||||
|
darkColor: 'rgba(19, 194, 194, 0.15)',
|
||||||
|
iconColor: '#13C2C2'
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -440,7 +451,8 @@ const getIconComponent = (title: string) => {
|
|||||||
'集群采集': IconCloud,
|
'集群采集': IconCloud,
|
||||||
'网络设备': IconWifi,
|
'网络设备': IconWifi,
|
||||||
'警告': IconExclamationCircle,
|
'警告': IconExclamationCircle,
|
||||||
'工单': IconFile
|
'工单': IconFile,
|
||||||
|
'审核': IconCheckCircle
|
||||||
};
|
};
|
||||||
return iconMap[title] || IconDesktop;
|
return iconMap[title] || IconDesktop;
|
||||||
};
|
};
|
||||||
@@ -462,7 +474,8 @@ const handleCardClick = (cardTitle: string) => {
|
|||||||
'集群采集': '/ops/monitor/collector',
|
'集群采集': '/ops/monitor/collector',
|
||||||
'网络设备': '/ops/monitor/network',
|
'网络设备': '/ops/monitor/network',
|
||||||
'警告': '/alert/tackle',
|
'警告': '/alert/tackle',
|
||||||
'工单': '/ops/ticket'
|
'工单': '/ops/ticket',
|
||||||
|
'审核': '/kb/review'
|
||||||
};
|
};
|
||||||
const route = routeMap[cardTitle];
|
const route = routeMap[cardTitle];
|
||||||
if (route) {
|
if (route) {
|
||||||
@@ -505,11 +518,12 @@ const loadStatistics = async () => {
|
|||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
|
||||||
// 并行请求所有统计接口和待处理告警
|
// 并行请求所有统计接口和待处理告警
|
||||||
const [alertData, collectorData, ticketData, alertListData] = await Promise.allSettled([
|
const [alertData, collectorData, ticketData, alertListData, reviewStatsData] = await Promise.allSettled([
|
||||||
fetchAlertCount().catch(e => ({ error: e, success: false })),
|
fetchAlertCount().catch(e => ({ error: e, success: false })),
|
||||||
fetchCollectorStatistics().catch(e => ({ error: e, success: false })),
|
fetchCollectorStatistics().catch(e => ({ error: e, success: false })),
|
||||||
fetchFeedbackTicketStatistics().catch(e => ({ error: e, success: false })),
|
fetchFeedbackTicketStatistics().catch(e => ({ error: e, success: false })),
|
||||||
fetchHistories({ page: 1, page_size: 5, status: 'pending' }).catch(e => ({ error: e, success: false }))
|
fetchHistories({ page: 1, page_size: 5, status: 'pending' }).catch(e => ({ error: e, success: false })),
|
||||||
|
fetchReviewStats({ resource_type: 'all' }).catch(e => ({ error: e, success: false }))
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 处理服务器及PC统计数据
|
// 处理服务器及PC统计数据
|
||||||
@@ -550,6 +564,22 @@ const loadStatistics = async () => {
|
|||||||
console.warn('工单统计数据加载失败:', ticketData.status === 'rejected' ? ticketData.reason : ticketData.value?.error);
|
console.warn('工单统计数据加载失败:', ticketData.status === 'rejected' ? ticketData.reason : ticketData.value?.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 审核统计数据(待处理=尚未审核,总数=需本人审核)
|
||||||
|
if (reviewStatsData.status === 'fulfilled' && reviewStatsData.value?.success !== false) {
|
||||||
|
const reviewPayload = reviewStatsData.value?.data ?? reviewStatsData.value?.details;
|
||||||
|
if (reviewPayload != null && 'need_my_review_total' in reviewPayload) {
|
||||||
|
statistics.review = {
|
||||||
|
pending: Number(reviewPayload.need_my_review_unreviewed_total) || 0,
|
||||||
|
total: Number(reviewPayload.need_my_review_total) || 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn(
|
||||||
|
'审核统计数据加载失败:',
|
||||||
|
reviewStatsData.status === 'rejected' ? reviewStatsData.reason : reviewStatsData.value?.error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// 设置待处理告警列表
|
// 设置待处理告警列表
|
||||||
if (alertListData.status === 'fulfilled' && alertListData.value?.success !== false) {
|
if (alertListData.status === 'fulfilled' && alertListData.value?.success !== false) {
|
||||||
pendingAlerts.value = alertListData.value?.details?.data || [];
|
pendingAlerts.value = alertListData.value?.details?.data || [];
|
||||||
@@ -559,7 +589,14 @@ const loadStatistics = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 启动数字动画
|
// 启动数字动画
|
||||||
const values = [statistics.serverPc.pending, statistics.cluster.pending, statistics.network.pending, statistics.alert.pending, statistics.ticket.pending];
|
const values = [
|
||||||
|
statistics.serverPc.pending,
|
||||||
|
statistics.cluster.pending,
|
||||||
|
statistics.network.pending,
|
||||||
|
statistics.alert.pending,
|
||||||
|
statistics.ticket.pending,
|
||||||
|
statistics.review.pending
|
||||||
|
];
|
||||||
values.forEach((value, index) => {
|
values.forEach((value, index) => {
|
||||||
animateNumber(index, value);
|
animateNumber(index, value);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user