diff --git a/src/api/kb/review.ts b/src/api/kb/review.ts new file mode 100644 index 0000000..3cc025a --- /dev/null +++ b/src/api/kb/review.ts @@ -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); diff --git a/src/views/ops/pages/overview/index.vue b/src/views/ops/pages/overview/index.vue index 8528d03..1bf4ba3 100644 --- a/src/views/ops/pages/overview/index.vue +++ b/src/views/ops/pages/overview/index.vue @@ -13,7 +13,7 @@
{{ card.title }} - + 待处理/总数 在线/总数 @@ -135,6 +135,7 @@ import { IconWifi, IconExclamationCircle, IconFile, + IconCheckCircle, IconBarChart, IconInfoCircle, IconRight @@ -152,6 +153,7 @@ import dayjs from 'dayjs'; import { fetchAlertCount, fetchHistories } from '@/api/ops/alertHistory'; import { fetchCollectorStatistics } from '@/api/ops/dcControl'; import { fetchFeedbackTicketStatistics } from '@/api/ops/feedbackTicket'; +import { fetchReviewStats } from '@/api/kb/review'; // 注册必要的 ECharts 组件 use([ @@ -166,8 +168,8 @@ const router = useRouter(); const month = ref('2025年3月'); const loading = ref(true); const chartLoading = ref(false); -const numberAnimated = ref([false, false, false, false, false]); -const animatedNumbers = ref([0, 0, 0, 0, 0]); +const numberAnimated = ref([false, false, false, false, false, false]); +const animatedNumbers = ref([0, 0, 0, 0, 0, 0]); // 统计数据 const statistics = reactive({ @@ -175,7 +177,8 @@ const statistics = reactive({ cluster: { pending: 0, total: 0 }, network: { 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([]); @@ -221,6 +224,14 @@ const statCards = computed(() => [ lightColor: 'rgba(114, 46, 209, 0.1)', darkColor: 'rgba(114, 46, 209, 0.15)', 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, '网络设备': IconWifi, '警告': IconExclamationCircle, - '工单': IconFile + '工单': IconFile, + '审核': IconCheckCircle }; return iconMap[title] || IconDesktop; }; @@ -462,7 +474,8 @@ const handleCardClick = (cardTitle: string) => { '集群采集': '/ops/monitor/collector', '网络设备': '/ops/monitor/network', '警告': '/alert/tackle', - '工单': '/ops/ticket' + '工单': '/ops/ticket', + '审核': '/kb/review' }; const route = routeMap[cardTitle]; if (route) { @@ -505,11 +518,12 @@ const loadStatistics = async () => { 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 })), fetchCollectorStatistics().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统计数据 @@ -550,6 +564,22 @@ const loadStatistics = async () => { 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) { 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) => { animateNumber(index, value); });