chore: sync local latest state and repository cleanup
This commit is contained in:
@@ -1,29 +1,16 @@
|
||||
import axios from 'axios'
|
||||
/**
|
||||
* 仪表盘服务
|
||||
* 使用 authFetch 替代 axios,与项目其他 service 保持一致
|
||||
*/
|
||||
import { authFetch, baseUrl } from './authHelper'
|
||||
|
||||
const baseURL = import.meta.env.VITE_API_BASE_URL ?? '/api'
|
||||
const apiBaseUrl = baseUrl || '/api/v1'
|
||||
|
||||
const dashboardApi = axios.create({
|
||||
baseURL,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
// 请求拦截器 - 添加认证头
|
||||
dashboardApi.interceptors.request.use(
|
||||
(config) => {
|
||||
const apiKey = localStorage.getItem('apiKey')
|
||||
if (apiKey) {
|
||||
config.headers['X-API-Key'] = apiKey
|
||||
}
|
||||
const token = localStorage.getItem('token')
|
||||
if (token) {
|
||||
config.headers['Authorization'] = `Bearer ${token}`
|
||||
}
|
||||
return config
|
||||
},
|
||||
(error) => Promise.reject(error)
|
||||
)
|
||||
interface ApiResponse<T> {
|
||||
code: number
|
||||
data: T
|
||||
message?: string
|
||||
}
|
||||
|
||||
export interface KpiData {
|
||||
label: string
|
||||
@@ -37,6 +24,7 @@ export interface ActivitySummary {
|
||||
name: string
|
||||
startTime?: string
|
||||
endTime?: string
|
||||
status?: string
|
||||
participants: number
|
||||
shares: number
|
||||
conversions: number
|
||||
@@ -66,72 +54,111 @@ export interface DashboardData {
|
||||
todos: Todo[]
|
||||
}
|
||||
|
||||
interface ApiResponse<T> {
|
||||
code: number
|
||||
data: T
|
||||
export interface RealtimeData {
|
||||
currentOnline: number
|
||||
todayVisits: number
|
||||
realtimeConversion: number
|
||||
apiRequests: number
|
||||
hourlyTrend: Array<{ hour: string; visits: number }>
|
||||
systemHealth: {
|
||||
backend: { status: string; message: string }
|
||||
database: { status: string; message: string }
|
||||
redis: { status: string; message: string }
|
||||
}
|
||||
recentEvents: Array<{ id: string; description: string; time: string }>
|
||||
timestamp: string
|
||||
}
|
||||
|
||||
export interface HistoryData {
|
||||
timeTrend: Array<{
|
||||
date: string
|
||||
views: number
|
||||
shares: number
|
||||
conversions: number
|
||||
newUsers: number
|
||||
}>
|
||||
comparison: {
|
||||
thisWeek: { views: number; conversions: number }
|
||||
lastWeek: { views: number; conversions: number }
|
||||
growth: { views: number; conversions: number }
|
||||
}
|
||||
timestamp: string
|
||||
}
|
||||
|
||||
export interface KpiConfig {
|
||||
kpiKey: string
|
||||
threshold: number
|
||||
warning: number
|
||||
updatedAt?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取仪表盘数据
|
||||
*/
|
||||
export async function getDashboard(): Promise<DashboardData> {
|
||||
const response = await dashboardApi.get<ApiResponse<DashboardData>>('/dashboard')
|
||||
return response.data.data
|
||||
const response = await authFetch(`${apiBaseUrl}/dashboard`)
|
||||
const result = await response.json() as ApiResponse<DashboardData>
|
||||
if (result.code !== 200) {
|
||||
throw new Error(result.message || '获取仪表盘数据失败')
|
||||
}
|
||||
return result.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取KPI数据
|
||||
*/
|
||||
export async function getKpis(): Promise<KpiData[]> {
|
||||
const response = await dashboardApi.get<ApiResponse<KpiData[]>>('/dashboard/kpis')
|
||||
return response.data.data
|
||||
const response = await authFetch(`${apiBaseUrl}/dashboard/kpis`)
|
||||
const result = await response.json() as ApiResponse<KpiData[]>
|
||||
if (result.code !== 200) {
|
||||
throw new Error(result.message || '获取KPI数据失败')
|
||||
}
|
||||
return result.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取活动统计
|
||||
*/
|
||||
export async function getActivitySummary() {
|
||||
const response = await dashboardApi.get('/dashboard/activities')
|
||||
return response.data
|
||||
const response = await authFetch(`${apiBaseUrl}/dashboard/activities`)
|
||||
const result = await response.json()
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取待办事项
|
||||
*/
|
||||
export async function getTodos(): Promise<Todo[]> {
|
||||
const response = await dashboardApi.get<ApiResponse<Todo[]>>('/dashboard/todos')
|
||||
return response.data.data
|
||||
const response = await authFetch(`${apiBaseUrl}/dashboard/todos`)
|
||||
const result = await response.json() as ApiResponse<Todo[]>
|
||||
if (result.code !== 200) {
|
||||
throw new Error(result.message || '获取待办事项失败')
|
||||
}
|
||||
return result.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出仪表盘数据
|
||||
*/
|
||||
export async function exportDashboard(format: string = 'csv'): Promise<Blob> {
|
||||
const response = await dashboardApi.get('/dashboard/export', {
|
||||
params: { format },
|
||||
responseType: 'blob'
|
||||
})
|
||||
return response as unknown as Blob
|
||||
const response = await authFetch(`${apiBaseUrl}/dashboard/export?format=${format}`)
|
||||
return response.blob()
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出KPI数据
|
||||
*/
|
||||
export async function exportKpis(): Promise<Blob> {
|
||||
const response = await dashboardApi.get('/dashboard/kpis/export', {
|
||||
responseType: 'blob'
|
||||
})
|
||||
return response as unknown as Blob
|
||||
const response = await authFetch(`${apiBaseUrl}/dashboard/kpis/export`)
|
||||
return response.blob()
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出活动数据
|
||||
*/
|
||||
export async function exportActivities(): Promise<Blob> {
|
||||
const response = await dashboardApi.get('/dashboard/activities/export', {
|
||||
responseType: 'blob'
|
||||
})
|
||||
return response as unknown as Blob
|
||||
const response = await authFetch(`${apiBaseUrl}/dashboard/activities/export`)
|
||||
return response.blob()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,6 +175,60 @@ export function downloadBlob(blob: Blob, filename: string) {
|
||||
window.URL.revokeObjectURL(url)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实时监控数据
|
||||
*/
|
||||
export async function getRealtimeData(): Promise<RealtimeData> {
|
||||
const response = await authFetch(`${apiBaseUrl}/dashboard/monitor/realtime`)
|
||||
const result = await response.json() as ApiResponse<RealtimeData>
|
||||
if (result.code !== 200) {
|
||||
throw new Error(result.message || '获取实时监控数据失败')
|
||||
}
|
||||
return result.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取历史图表数据
|
||||
*/
|
||||
export async function getHistoryData(days: number = 7, metric?: string): Promise<HistoryData> {
|
||||
let url = `${apiBaseUrl}/dashboard/monitor/history?days=${days}`
|
||||
if (metric) url += `&metric=${metric}`
|
||||
const response = await authFetch(url)
|
||||
const result = await response.json() as ApiResponse<HistoryData>
|
||||
if (result.code !== 200) {
|
||||
throw new Error(result.message || '获取历史图表数据失败')
|
||||
}
|
||||
return result.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置KPI阈值
|
||||
*/
|
||||
export async function configKpi(config: { kpiKey: string; threshold: number; warning: number }): Promise<KpiConfig> {
|
||||
const response = await authFetch(`${apiBaseUrl}/dashboard/kpis/config`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(config)
|
||||
})
|
||||
const result = await response.json() as ApiResponse<KpiConfig>
|
||||
if (result.code !== 200) {
|
||||
throw new Error(result.message || '配置KPI阈值失败')
|
||||
}
|
||||
return result.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取KPI阈值配置
|
||||
*/
|
||||
export async function getKpiConfig(): Promise<KpiConfig[]> {
|
||||
const response = await authFetch(`${apiBaseUrl}/dashboard/kpis/config`)
|
||||
const result = await response.json() as ApiResponse<KpiConfig[]>
|
||||
if (result.code !== 200) {
|
||||
throw new Error(result.message || '获取KPI阈值配置失败')
|
||||
}
|
||||
return result.data
|
||||
}
|
||||
|
||||
export default {
|
||||
getDashboard,
|
||||
getKpis,
|
||||
@@ -156,5 +237,9 @@ export default {
|
||||
exportDashboard,
|
||||
exportKpis,
|
||||
exportActivities,
|
||||
downloadBlob
|
||||
downloadBlob,
|
||||
getRealtimeData,
|
||||
getHistoryData,
|
||||
configKpi,
|
||||
getKpiConfig
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user