From 21e2779d28878417b2c098a5deaaddbf4d2261bf Mon Sep 17 00:00:00 2001 From: ctwj <908504609@qq.com> Date: Mon, 21 Jul 2025 21:24:50 +0800 Subject: [PATCH] =?UTF-8?q?update:=20=E4=BC=98=E5=8C=96api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/composables/useApi.ts | 733 +++------------------------- web/composables/useApiFetch.ts | 37 ++ web/nuxt.config.ts | 2 +- web/pages/admin/categories.vue | 46 +- web/pages/admin/cks.vue | 18 +- web/pages/admin/index.vue | 16 +- web/pages/admin/ready-resources.vue | 5 +- web/pages/admin/resources.vue | 5 +- web/pages/admin/system-config.vue | 7 +- web/pages/admin/tags.vue | 61 +-- web/pages/hot-dramas.vue | 16 +- web/pages/index.vue | 46 +- web/pages/monitor.vue | 8 +- web/server/api/pans.get.ts | 2 +- web/server/api/resources.get.ts | 2 +- web/server/api/stats.get.ts | 2 +- web/server/api/system-config.get.ts | 2 +- web/server/api/version.get.ts | 4 +- 18 files changed, 180 insertions(+), 832 deletions(-) create mode 100644 web/composables/useApiFetch.ts diff --git a/web/composables/useApi.ts b/web/composables/useApi.ts index 70b97d1..45ead9a 100644 --- a/web/composables/useApi.ts +++ b/web/composables/useApi.ts @@ -1,3 +1,6 @@ +import { useApiFetch } from './useApiFetch' +import { useUserStore } from '~/stores/user' + // 统一响应解析函数 export const parseApiResponse = (response: any): T => { console.log('parseApiResponse - 原始响应:', response) @@ -37,700 +40,112 @@ export const parseApiResponse = (response: any): T => { return response } -// 使用 $fetch 替代 axios,更好地处理 SSR export const useResourceApi = () => { - const config = useRuntimeConfig() - - const getAuthHeaders = () => { - const userStore = useUserStore() - return userStore.authHeaders - } - - const getResources = async (params?: any) => { - const response = await $fetch('/resources', { - baseURL: config.public.apiBase, - params, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const getResource = async (id: number) => { - const response = await $fetch(`/resources/${id}`, { - baseURL: config.public.apiBase, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const createResource = async (data: any) => { - const response = await $fetch('/resources', { - baseURL: config.public.apiBase, - method: 'POST', - body: data, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const updateResource = async (id: number, data: any) => { - const response = await $fetch(`/resources/${id}`, { - baseURL: config.public.apiBase, - method: 'PUT', - body: data, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const deleteResource = async (id: number) => { - const response = await $fetch(`/resources/${id}`, { - baseURL: config.public.apiBase, - method: 'DELETE', - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const searchResources = async (params: any) => { - const response = await $fetch('/search', { - baseURL: config.public.apiBase, - params, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const getResourcesByPan = async (panId: number, params?: any) => { - const response = await $fetch('/resources', { - baseURL: config.public.apiBase, - params: { ...params, pan_id: panId }, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - return { - getResources, - getResource, - createResource, - updateResource, - deleteResource, - searchResources, - getResourcesByPan, - } + const getResources = (params?: any) => useApiFetch('/resources', { params }).then(parseApiResponse) + const getResource = (id: number) => useApiFetch(`/resources/${id}`).then(parseApiResponse) + const createResource = (data: any) => useApiFetch('/resources', { method: 'POST', body: data }).then(parseApiResponse) + const updateResource = (id: number, data: any) => useApiFetch(`/resources/${id}`, { method: 'PUT', body: data }).then(parseApiResponse) + const deleteResource = (id: number) => useApiFetch(`/resources/${id}`, { method: 'DELETE' }).then(parseApiResponse) + const searchResources = (params: any) => useApiFetch('/search', { params }).then(parseApiResponse) + const getResourcesByPan = (panId: number, params?: any) => useApiFetch('/resources', { params: { ...params, pan_id: panId } }).then(parseApiResponse) + return { getResources, getResource, createResource, updateResource, deleteResource, searchResources, getResourcesByPan } } -// 认证相关API export const useAuthApi = () => { - const config = useRuntimeConfig() - - const login = async (data: any) => { - const response = await $fetch('/auth/login', { - baseURL: config.public.apiBase, - method: 'POST', - body: data - }) - return parseApiResponse(response) - } - - const register = async (data: any) => { - const response = await $fetch('/auth/register', { - baseURL: config.public.apiBase, - method: 'POST', - body: data - }) - return parseApiResponse(response) - } - - const getProfile = async () => { - const token = localStorage.getItem('token') - const response = await $fetch('/auth/profile', { - baseURL: config.public.apiBase, - headers: token ? { Authorization: `Bearer ${token}` } : {} - }) - return parseApiResponse(response) - } - - return { - login, - register, - getProfile, + const login = (data: any) => useApiFetch('/auth/login', { method: 'POST', body: data }).then(parseApiResponse) + const register = (data: any) => useApiFetch('/auth/register', { method: 'POST', body: data }).then(parseApiResponse) + const getProfile = () => { + const token = typeof window !== 'undefined' ? localStorage.getItem('token') : '' + return useApiFetch('/auth/profile', { headers: token ? { Authorization: `Bearer ${token}` } : {} }).then(parseApiResponse) } + return { login, register, getProfile } } -// 分类相关API export const useCategoryApi = () => { - const config = useRuntimeConfig() - - const getAuthHeaders = () => { - const userStore = useUserStore() - return userStore.authHeaders - } - - const getCategories = async () => { - const response = await $fetch('/categories', { - baseURL: config.public.apiBase, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const createCategory = async (data: any) => { - const response = await $fetch('/categories', { - baseURL: config.public.apiBase, - method: 'POST', - body: data, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const updateCategory = async (id: number, data: any) => { - const response = await $fetch(`/categories/${id}`, { - baseURL: config.public.apiBase, - method: 'PUT', - body: data, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const deleteCategory = async (id: number) => { - const response = await $fetch(`/categories/${id}`, { - baseURL: config.public.apiBase, - method: 'DELETE', - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - return { - getCategories, - createCategory, - updateCategory, - deleteCategory, - } + const getCategories = () => useApiFetch('/categories').then(parseApiResponse) + const createCategory = (data: any) => useApiFetch('/categories', { method: 'POST', body: data }).then(parseApiResponse) + const updateCategory = (id: number, data: any) => useApiFetch(`/categories/${id}`, { method: 'PUT', body: data }).then(parseApiResponse) + const deleteCategory = (id: number) => useApiFetch(`/categories/${id}`, { method: 'DELETE' }).then(parseApiResponse) + return { getCategories, createCategory, updateCategory, deleteCategory } } -// 平台相关API export const usePanApi = () => { - const config = useRuntimeConfig() - - const getAuthHeaders = () => { - const userStore = useUserStore() - return userStore.authHeaders - } - - const getPans = async () => { - const response = await $fetch('/pans', { - baseURL: config.public.apiBase, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const getPan = async (id: number) => { - const response = await $fetch(`/pans/${id}`, { - baseURL: config.public.apiBase, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const createPan = async (data: any) => { - const response = await $fetch('/pans', { - baseURL: config.public.apiBase, - method: 'POST', - body: data, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const updatePan = async (id: number, data: any) => { - const response = await $fetch(`/pans/${id}`, { - baseURL: config.public.apiBase, - method: 'PUT', - body: data, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const deletePan = async (id: number) => { - const response = await $fetch(`/pans/${id}`, { - baseURL: config.public.apiBase, - method: 'DELETE', - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - return { - getPans, - getPan, - createPan, - updatePan, - deletePan, - } + const getPans = () => useApiFetch('/pans').then(parseApiResponse) + const getPan = (id: number) => useApiFetch(`/pans/${id}`).then(parseApiResponse) + const createPan = (data: any) => useApiFetch('/pans', { method: 'POST', body: data }).then(parseApiResponse) + const updatePan = (id: number, data: any) => useApiFetch(`/pans/${id}`, { method: 'PUT', body: data }).then(parseApiResponse) + const deletePan = (id: number) => useApiFetch(`/pans/${id}`, { method: 'DELETE' }).then(parseApiResponse) + return { getPans, getPan, createPan, updatePan, deletePan } } -// Cookie相关API export const useCksApi = () => { - const config = useRuntimeConfig() - - const getAuthHeaders = () => { - const userStore = useUserStore() - return userStore.authHeaders - } - - const getCks = async (params?: any) => { - const response = await $fetch('/cks', { - baseURL: config.public.apiBase, - params, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const getCksByID = async (id: number) => { - const response = await $fetch(`/cks/${id}`, { - baseURL: config.public.apiBase, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const createCks = async (data: any) => { - const response = await $fetch('/cks', { - baseURL: config.public.apiBase, - method: 'POST', - body: data, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const updateCks = async (id: number, data: any) => { - const response = await $fetch(`/cks/${id}`, { - baseURL: config.public.apiBase, - method: 'PUT', - body: data, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const deleteCks = async (id: number) => { - const response = await $fetch(`/cks/${id}`, { - baseURL: config.public.apiBase, - method: 'DELETE', - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const refreshCapacity = async (id: number) => { - const response = await $fetch(`/cks/${id}/refresh-capacity`, { - baseURL: config.public.apiBase, - method: 'POST', - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - return { - getCks, - getCksByID, - createCks, - updateCks, - deleteCks, - refreshCapacity, - } + const getCks = (params?: any) => useApiFetch('/cks', { params }).then(parseApiResponse) + const getCksByID = (id: number) => useApiFetch(`/cks/${id}`).then(parseApiResponse) + const createCks = (data: any) => useApiFetch('/cks', { method: 'POST', body: data }).then(parseApiResponse) + const updateCks = (id: number, data: any) => useApiFetch(`/cks/${id}`, { method: 'PUT', body: data }).then(parseApiResponse) + const deleteCks = (id: number) => useApiFetch(`/cks/${id}`, { method: 'DELETE' }).then(parseApiResponse) + const refreshCapacity = (id: number) => useApiFetch(`/cks/${id}/refresh-capacity`, { method: 'POST' }).then(parseApiResponse) + return { getCks, getCksByID, createCks, updateCks, deleteCks, refreshCapacity } } -// 标签相关API export const useTagApi = () => { - const config = useRuntimeConfig() - - const getAuthHeaders = () => { - const userStore = useUserStore() - return userStore.authHeaders - } - - const getTags = async () => { - const response = await $fetch('/tags', { - baseURL: config.public.apiBase, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const getTagsByCategory = async (categoryId: number, params?: any) => { - const response = await $fetch(`/categories/${categoryId}/tags`, { - baseURL: config.public.apiBase, - params, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const getTag = async (id: number) => { - const response = await $fetch(`/tags/${id}`, { - baseURL: config.public.apiBase, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const createTag = async (data: any) => { - const response = await $fetch('/tags', { - baseURL: config.public.apiBase, - method: 'POST', - body: data, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const updateTag = async (id: number, data: any) => { - const response = await $fetch(`/tags/${id}`, { - baseURL: config.public.apiBase, - method: 'PUT', - body: data, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const deleteTag = async (id: number) => { - const response = await $fetch(`/tags/${id}`, { - baseURL: config.public.apiBase, - method: 'DELETE', - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const getResourceTags = async (resourceId: number) => { - const response = await $fetch(`/resources/${resourceId}/tags`, { - baseURL: config.public.apiBase, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - return { - getTags, - getTagsByCategory, - getTag, - createTag, - updateTag, - deleteTag, - getResourceTags, - } + const getTags = () => useApiFetch('/tags').then(parseApiResponse) + const getTagsByCategory = (categoryId: number, params?: any) => useApiFetch(`/categories/${categoryId}/tags`, { params }).then(parseApiResponse) + const getTag = (id: number) => useApiFetch(`/tags/${id}`).then(parseApiResponse) + const createTag = (data: any) => useApiFetch('/tags', { method: 'POST', body: data }).then(parseApiResponse) + const updateTag = (id: number, data: any) => useApiFetch(`/tags/${id}`, { method: 'PUT', body: data }).then(parseApiResponse) + const deleteTag = (id: number) => useApiFetch(`/tags/${id}`, { method: 'DELETE' }).then(parseApiResponse) + const getResourceTags = (resourceId: number) => useApiFetch(`/resources/${resourceId}/tags`).then(parseApiResponse) + return { getTags, getTagsByCategory, getTag, createTag, updateTag, deleteTag, getResourceTags } } -// 待处理资源相关API export const useReadyResourceApi = () => { - const config = useRuntimeConfig() - - const getAuthHeaders = () => { - const userStore = useUserStore() - return userStore.authHeaders - } - - const getReadyResources = async (params?: any) => { - const response = await $fetch('/ready-resources', { - baseURL: config.public.apiBase, - params, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const createReadyResource = async (data: any) => { - const response = await $fetch('/ready-resources', { - baseURL: config.public.apiBase, - method: 'POST', - body: data, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const batchCreateReadyResources = async (data: any) => { - const response = await $fetch('/ready-resources/batch', { - baseURL: config.public.apiBase, - method: 'POST', - body: data, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const createReadyResourcesFromText = async (text: string) => { + const getReadyResources = (params?: any) => useApiFetch('/ready-resources', { params }).then(parseApiResponse) + const createReadyResource = (data: any) => useApiFetch('/ready-resources', { method: 'POST', body: data }).then(parseApiResponse) + const batchCreateReadyResources = (data: any) => useApiFetch('/ready-resources/batch', { method: 'POST', body: data }).then(parseApiResponse) + const createReadyResourcesFromText = (text: string) => { const formData = new FormData() formData.append('text', text) - - const response = await $fetch('/ready-resources/text', { - baseURL: config.public.apiBase, - method: 'POST', - body: formData, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const deleteReadyResource = async (id: number) => { - const response = await $fetch(`/ready-resources/${id}`, { - baseURL: config.public.apiBase, - method: 'DELETE', - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const clearReadyResources = async () => { - const response = await $fetch('/ready-resources', { - baseURL: config.public.apiBase, - method: 'DELETE', - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - return { - getReadyResources, - createReadyResource, - batchCreateReadyResources, - createReadyResourcesFromText, - deleteReadyResource, - clearReadyResources, + return useApiFetch('/ready-resources/text', { method: 'POST', body: formData }).then(parseApiResponse) } + const deleteReadyResource = (id: number) => useApiFetch(`/ready-resources/${id}`, { method: 'DELETE' }).then(parseApiResponse) + const clearReadyResources = () => useApiFetch('/ready-resources', { method: 'DELETE' }).then(parseApiResponse) + return { getReadyResources, createReadyResource, batchCreateReadyResources, createReadyResourcesFromText, deleteReadyResource, clearReadyResources } } -// 统计相关API export const useStatsApi = () => { - const config = useRuntimeConfig() - - const getStats = async () => { - const response = await $fetch('/stats', { - baseURL: config.public.apiBase, - }) - return parseApiResponse(response) - } - - return { - getStats, - } + const getStats = () => useApiFetch('/stats').then(parseApiResponse) + return { getStats } } -// 系统配置相关API export const useSystemConfigApi = () => { - const config = useRuntimeConfig() - - const getAuthHeaders = () => { - const userStore = useUserStore() - return userStore.authHeaders - } - - const getSystemConfig = async () => { - const response = await $fetch('/system/config', { - baseURL: config.public.apiBase, - // GET接口不需要认证头 - }) - return parseApiResponse(response) - } - - const updateSystemConfig = async (data: any) => { - const authHeaders = getAuthHeaders() - console.log('updateSystemConfig - authHeaders:', authHeaders) - console.log('updateSystemConfig - token exists:', !!authHeaders.Authorization) - - const response = await $fetch('/system/config', { - baseURL: config.public.apiBase, - method: 'POST', - body: data, - headers: authHeaders as Record - }) - return parseApiResponse(response) - } - - return { - getSystemConfig, - updateSystemConfig, - } + const getSystemConfig = () => useApiFetch('/system/config').then(parseApiResponse) + const updateSystemConfig = (data: any) => useApiFetch('/system/config', { method: 'POST', body: data }).then(parseApiResponse) + return { getSystemConfig, updateSystemConfig } } -// 热播剧相关API export const useHotDramaApi = () => { - const config = useRuntimeConfig() - - const getAuthHeaders = () => { - const userStore = useUserStore() - return userStore.authHeaders - } - - const getHotDramas = async (params?: any) => { - const response = await $fetch('/hot-dramas', { - baseURL: config.public.apiBase, - params, - }) - return parseApiResponse(response) - } - - const createHotDrama = async (data: any) => { - const response = await $fetch('/hot-dramas', { - baseURL: config.public.apiBase, - method: 'POST', - body: data, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const updateHotDrama = async (id: number, data: any) => { - const response = await $fetch(`/hot-dramas/${id}`, { - baseURL: config.public.apiBase, - method: 'PUT', - body: data, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const deleteHotDrama = async (id: number) => { - const response = await $fetch(`/hot-dramas/${id}`, { - baseURL: config.public.apiBase, - method: 'DELETE', - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const fetchHotDramas = async () => { - const response = await $fetch('/hot-dramas/fetch', { - baseURL: config.public.apiBase, - method: 'POST', - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - return { - getHotDramas, - createHotDrama, - updateHotDrama, - deleteHotDrama, - fetchHotDramas, - } + const getHotDramas = (params?: any) => useApiFetch('/hot-dramas', { params }).then(parseApiResponse) + const createHotDrama = (data: any) => useApiFetch('/hot-dramas', { method: 'POST', body: data }).then(parseApiResponse) + const updateHotDrama = (id: number, data: any) => useApiFetch(`/hot-dramas/${id}`, { method: 'PUT', body: data }).then(parseApiResponse) + const deleteHotDrama = (id: number) => useApiFetch(`/hot-dramas/${id}`, { method: 'DELETE' }).then(parseApiResponse) + const fetchHotDramas = () => useApiFetch('/hot-dramas/fetch', { method: 'POST' }).then(parseApiResponse) + return { getHotDramas, createHotDrama, updateHotDrama, deleteHotDrama, fetchHotDramas } } -// 监控相关API export const useMonitorApi = () => { - const config = useRuntimeConfig() - - const getPerformanceStats = async () => { - const response = await $fetch('/performance', { - baseURL: config.public.apiBase, - }) - return parseApiResponse(response) - } + const getPerformanceStats = () => useApiFetch('/performance').then(parseApiResponse) + const getSystemInfo = () => useApiFetch('/system/info').then(parseApiResponse) + const getBasicStats = () => useApiFetch('/stats').then(parseApiResponse) + return { getPerformanceStats, getSystemInfo, getBasicStats } +} - const getSystemInfo = async () => { - const response = await $fetch('/system/info', { - baseURL: config.public.apiBase, - }) - return parseApiResponse(response) - } - - const getBasicStats = async () => { - const response = await $fetch('/stats', { - baseURL: config.public.apiBase, - }) - return parseApiResponse(response) - } - - return { - getPerformanceStats, - getSystemInfo, - getBasicStats, - } -} - -// 用户管理相关API export const useUserApi = () => { - const config = useRuntimeConfig() - - const getAuthHeaders = () => { - const userStore = useUserStore() - return userStore.authHeaders - } - - const getUsers = async (params?: any) => { - const response = await $fetch('/users', { - baseURL: config.public.apiBase, - params, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const getUser = async (id: number) => { - const response = await $fetch(`/users/${id}`, { - baseURL: config.public.apiBase, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const createUser = async (data: any) => { - const response = await $fetch('/users', { - baseURL: config.public.apiBase, - method: 'POST', - body: data, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const updateUser = async (id: number, data: any) => { - const response = await $fetch(`/users/${id}`, { - baseURL: config.public.apiBase, - method: 'PUT', - body: data, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const deleteUser = async (id: number) => { - const response = await $fetch(`/users/${id}`, { - baseURL: config.public.apiBase, - method: 'DELETE', - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - const changePassword = async (id: number, newPassword: string) => { - const response = await $fetch(`/users/${id}/password`, { - baseURL: config.public.apiBase, - method: 'PUT', - body: { new_password: newPassword }, - headers: getAuthHeaders() as Record - }) - return parseApiResponse(response) - } - - return { - getUsers, - getUser, - createUser, - updateUser, - deleteUser, - changePassword, - } + const getUsers = (params?: any) => useApiFetch('/users', { params }).then(parseApiResponse) + const getUser = (id: number) => useApiFetch(`/users/${id}`).then(parseApiResponse) + const createUser = (data: any) => useApiFetch('/users', { method: 'POST', body: data }).then(parseApiResponse) + const updateUser = (id: number, data: any) => useApiFetch(`/users/${id}`, { method: 'PUT', body: data }).then(parseApiResponse) + const deleteUser = (id: number) => useApiFetch(`/users/${id}`, { method: 'DELETE' }).then(parseApiResponse) + const changePassword = (id: number, newPassword: string) => useApiFetch(`/users/${id}/password`, { method: 'PUT', body: { new_password: newPassword } }).then(parseApiResponse) + return { getUsers, getUser, createUser, updateUser, deleteUser, changePassword } } \ No newline at end of file diff --git a/web/composables/useApiFetch.ts b/web/composables/useApiFetch.ts new file mode 100644 index 0000000..50f1b4c --- /dev/null +++ b/web/composables/useApiFetch.ts @@ -0,0 +1,37 @@ +import { useRuntimeConfig } from '#app' +import { useUserStore } from '~/stores/user' + +export function useApiFetch( + url: string, + options: any = {} +): Promise { + const config = useRuntimeConfig() + const userStore = useUserStore() + const baseURL = process.server + ? String(config.public.apiServer) + : String(config.public.apiBase) + + // 自动带上 token + const headers = { + ...(options.headers || {}), + ...(userStore.authHeaders || {}) + } + + return $fetch(url, { + baseURL, + ...options, + headers, + onResponse({ response }) { + // 统一处理 code/message + if (response._data && response._data.code && response._data.code !== 200) { + throw new Error(response._data.message || '请求失败') + } + }, + onResponseError({ error }) { + // 统一错误提示 + // 你可以用 naive-ui 的 useMessage() 这里弹窗 + // useMessage().error(error.message) + throw error + } + }) +} \ No newline at end of file diff --git a/web/nuxt.config.ts b/web/nuxt.config.ts index 9f95afa..39f139c 100644 --- a/web/nuxt.config.ts +++ b/web/nuxt.config.ts @@ -51,7 +51,7 @@ export default defineNuxtConfig({ }, runtimeConfig: { public: { - apiBase: process.env.NUXT_PUBLIC_API_CLIENT || '/api', + apiBase: process.env.NUXT_PUBLIC_API_CLIENT || 'http://localhost:8080/api', apiServer: process.env.NUXT_PUBLIC_API_SERVER || 'http://localhost:8080/api' } }, diff --git a/web/pages/admin/categories.vue b/web/pages/admin/categories.vue index 889badf..9716d9e 100644 --- a/web/pages/admin/categories.vue +++ b/web/pages/admin/categories.vue @@ -198,6 +198,8 @@ definePageMeta({ const router = useRouter() const userStore = useUserStore() const config = useRuntimeConfig() +import { useCategoryApi } from '~/composables/useApi' +const categoryApi = useCategoryApi() // 页面状态 const pageLoading = ref(true) @@ -257,23 +259,10 @@ const fetchCategories = async () => { page_size: pageSize.value, search: searchQuery.value } - - const response = await $fetch('/categories', { - baseURL: config.public.apiBase, - params - }) - - - // 解析响应 - if (response && typeof response === 'object' && 'code' in response && response.code === 200) { - categories.value = response.data.items || [] - totalCount.value = response.data.total || 0 - totalPages.value = Math.ceil(totalCount.value / pageSize.value) - } else { - categories.value = response.items || [] - totalCount.value = response.total || 0 - totalPages.value = Math.ceil(totalCount.value / pageSize.value) - } + const response = await categoryApi.getCategories(params) + categories.value = Array.isArray(response) ? response : [] + totalCount.value = response.total || 0 + totalPages.value = Math.ceil(totalCount.value / pageSize.value) } catch (error) { console.error('获取分类列表失败:', error) } finally { @@ -318,13 +307,8 @@ const deleteCategory = async (categoryId: number) => { if (!confirm(`确定要删除分类吗?`)) { return } - try { - await $fetch(`/categories/${categoryId}`, { - baseURL: config.public.apiBase, - method: 'DELETE', - headers: getAuthHeaders() - }) + await categoryApi.deleteCategory(categoryId) await fetchCategories() } catch (error) { console.error('删除分类失败:', error) @@ -335,23 +319,11 @@ const deleteCategory = async (categoryId: number) => { const handleSubmit = async () => { try { submitting.value = true - if (editingCategory.value) { - await $fetch(`/categories/${editingCategory.value.id}`, { - baseURL: config.public.apiBase, - method: 'PUT', - body: formData.value, - headers: getAuthHeaders() - }) + await categoryApi.updateCategory(editingCategory.value.id, formData.value) } else { - await $fetch('/categories', { - baseURL: config.public.apiBase, - method: 'POST', - body: formData.value, - headers: getAuthHeaders() - }) + await categoryApi.createCategory(formData.value) } - closeModal() await fetchCategories() } catch (error) { diff --git a/web/pages/admin/cks.vue b/web/pages/admin/cks.vue index a067b2c..9c8e580 100644 --- a/web/pages/admin/cks.vue +++ b/web/pages/admin/cks.vue @@ -315,7 +315,11 @@ const pageLoading = ref(true) const submitting = ref(false) const platform = ref(null) -const { data: pansData } = await useAsyncData('pans', () => $fetch('/api/pans')) +import { useCksApi, usePanApi } from '~/composables/useApi' +const cksApi = useCksApi() +const panApi = usePanApi() + +const { data: pansData } = await useAsyncData('pans', () => panApi.getPans()) const pans = computed(() => { return (pansData.value).data.list || [] }) @@ -339,8 +343,6 @@ const checkAuth = () => { const fetchCks = async () => { loading.value = true try { - const { useCksApi } = await import('~/composables/useApi') - const cksApi = useCksApi() const response = await cksApi.getCks() cksList.value = Array.isArray(response) ? response : [] } catch (error) { @@ -354,8 +356,6 @@ const fetchCks = async () => { // 获取平台列表 const fetchPlatforms = async () => { try { - const { usePanApi } = await import('~/composables/useApi') - const panApi = usePanApi() const response = await panApi.getPans() platforms.value = Array.isArray(response) ? response : [] } catch (error) { @@ -367,8 +367,6 @@ const fetchPlatforms = async () => { const createCks = async () => { submitting.value = true try { - const { useCksApi } = await import('~/composables/useApi') - const cksApi = useCksApi() await cksApi.createCks(form.value) await fetchCks() closeModal() @@ -384,8 +382,6 @@ const createCks = async () => { const updateCks = async () => { submitting.value = true try { - const { useCksApi } = await import('~/composables/useApi') - const cksApi = useCksApi() await cksApi.updateCks(editingCks.value.id, form.value) await fetchCks() closeModal() @@ -402,8 +398,6 @@ const deleteCks = async (id) => { if (!confirm('确定要删除这个账号吗?')) return try { - const { useCksApi } = await import('~/composables/useApi') - const cksApi = useCksApi() await cksApi.deleteCks(id) await fetchCks() } catch (error) { @@ -417,8 +411,6 @@ const refreshCapacity = async (id) => { if (!confirm('确定要刷新此账号的容量信息吗?')) return try { - const { useCksApi } = await import('~/composables/useApi') - const cksApi = useCksApi() await cksApi.refreshCapacity(id) await fetchCks() alert('容量信息已刷新!') diff --git a/web/pages/admin/index.vue b/web/pages/admin/index.vue index 8d00ab6..02c4612 100644 --- a/web/pages/admin/index.vue +++ b/web/pages/admin/index.vue @@ -244,15 +244,17 @@ definePageMeta({ const userStore = useUserStore() // 统计数据 -const { data: statsData } = await useAsyncData('stats', () => $fetch('/api/stats')) -const stats = computed(() => (statsData.value as any)?.data || {}) +import { useStatsApi, usePanApi } from '~/composables/useApi' + +const statsApi = useStatsApi() +const panApi = usePanApi() + +const { data: statsData } = await useAsyncData('stats', () => statsApi.getStats()) +const stats = computed(() => (statsData.value as any) || {}) // 平台数据 -const { data: pansData } = await useAsyncData('pans', () => $fetch('/api/pans')) -console.log() -const pans = computed(() => { - return (pansData.value as any).data.list || [] -}) +const { data: pansData } = await useAsyncData('pans', () => panApi.getPans()) +const pans = computed(() => (pansData.value as any) || []) // 分类管理相关 const goToCategoryManagement = () => { diff --git a/web/pages/admin/ready-resources.vue b/web/pages/admin/ready-resources.vue index 99e6af7..77dc9be 100644 --- a/web/pages/admin/ready-resources.vue +++ b/web/pages/admin/ready-resources.vue @@ -334,11 +334,8 @@ const totalCount = ref(0) const totalPages = ref(0) // 获取待处理资源API -const { useReadyResourceApi } = await import('~/composables/useApi') +import { useReadyResourceApi, useSystemConfigApi } from '~/composables/useApi' const readyResourceApi = useReadyResourceApi() - -// 获取系统配置API -const { useSystemConfigApi } = await import('~/composables/useApi') const systemConfigApi = useSystemConfigApi() // 获取系统配置 diff --git a/web/pages/admin/resources.vue b/web/pages/admin/resources.vue index efe0439..5a801de 100644 --- a/web/pages/admin/resources.vue +++ b/web/pages/admin/resources.vue @@ -420,10 +420,7 @@ const selectedResources = ref([]) const selectAll = ref(false) // API -const { useResourceApi } = await import('~/composables/useApi') -const { usePanApi } = await import('~/composables/useApi') -const { useCategoryApi } = await import('~/composables/useApi') -const { useTagApi } = await import('~/composables/useApi') +import { useResourceApi, usePanApi, useCategoryApi, useTagApi } from '~/composables/useApi' const resourceApi = useResourceApi() const panApi = usePanApi() diff --git a/web/pages/admin/system-config.vue b/web/pages/admin/system-config.vue index a0bb444..f399d14 100644 --- a/web/pages/admin/system-config.vue +++ b/web/pages/admin/system-config.vue @@ -334,9 +334,10 @@ definePageMeta({ }) import { ref, onMounted } from 'vue' +import { useSystemConfigApi } from '~/composables/useApi' // API -const { getSystemConfig, updateSystemConfig } = useSystemConfigApi() +const systemConfigApi = useSystemConfigApi() // 响应式数据 const loading = ref(false) @@ -388,7 +389,7 @@ useHead({ const loadConfig = async () => { try { loading.value = true - const response = await getSystemConfig() + const response = await systemConfigApi.getSystemConfig() console.log('系统配置响应:', response) // 使用新的统一响应格式,直接使用response @@ -441,7 +442,7 @@ const saveConfig = async () => { api_token: config.value.apiToken // 保存API Token } - const response = await updateSystemConfig(requestData) + const response = await systemConfigApi.updateSystemConfig(requestData) // 使用新的统一响应格式,直接检查response是否存在 if (response) { alert('配置保存成功!') diff --git a/web/pages/admin/tags.vue b/web/pages/admin/tags.vue index bb97919..5754619 100644 --- a/web/pages/admin/tags.vue +++ b/web/pages/admin/tags.vue @@ -331,16 +331,8 @@ const checkAuth = () => { // 获取分类列表 const fetchCategories = async () => { try { - const response = await $fetch('/categories', { - baseURL: config.public.apiBase, - headers: getAuthHeaders() as Record - }) - - if (response && typeof response === 'object' && 'code' in response && response.code === 200) { - categories.value = (response as any).data?.items || [] - } else { - categories.value = (response as any).items || [] - } + const response = await categoryApi.getCategories() + categories.value = Array.isArray(response) ? response : [] } catch (error) { console.error('获取分类列表失败:', error) } @@ -355,34 +347,15 @@ const fetchTags = async () => { page_size: pageSize.value, search: searchQuery.value } - let response: any if (selectedCategory.value) { - // 如果选择了分类,使用按分类查询的接口 - response = await $fetch(`/categories/${selectedCategory.value}/tags`, { - baseURL: config.public.apiBase, - params, - headers: getAuthHeaders() as Record - }) + response = await tagApi.getTagsByCategory(selectedCategory.value, params) } else { - // 否则使用普通查询接口 - response = await $fetch('/tags', { - baseURL: config.public.apiBase, - params, - headers: getAuthHeaders() as Record - }) - } - - // 解析响应 - if (response && typeof response === 'object' && 'code' in response && response.code === 200) { - tags.value = response.data?.items || [] - totalCount.value = response.data?.total || 0 - totalPages.value = Math.ceil(totalCount.value / pageSize.value) - } else { - tags.value = response.items || [] - totalCount.value = response.total || 0 - totalPages.value = Math.ceil(totalCount.value / pageSize.value) + response = await tagApi.getTags(params) } + tags.value = response.items || [] + totalCount.value = response.total || 0 + totalPages.value = Math.ceil(totalCount.value / pageSize.value) } catch (error) { console.error('获取标签列表失败:', error) } finally { @@ -436,11 +409,7 @@ const deleteTag = async (tagId: number) => { } try { - await $fetch(`/tags/${tagId}`, { - baseURL: config.public.apiBase, - method: 'DELETE', - headers: getAuthHeaders() as Record - }) + await tagApi.deleteTag(tagId) await fetchTags() } catch (error) { console.error('删除标签失败:', error) @@ -465,19 +434,9 @@ const handleSubmit = async () => { } if (editingTag.value) { - await $fetch(`/tags/${editingTag.value.id}`, { - baseURL: config.public.apiBase, - method: 'PUT', - body: submitData, - headers: getAuthHeaders() as Record - }) + await tagApi.updateTag(editingTag.value.id, submitData) } else { - await $fetch('/tags', { - baseURL: config.public.apiBase, - method: 'POST', - body: submitData, - headers: getAuthHeaders() as Record - }) + await tagApi.createTag(submitData) } closeModal() diff --git a/web/pages/hot-dramas.vue b/web/pages/hot-dramas.vue index 72b2cfa..481247b 100644 --- a/web/pages/hot-dramas.vue +++ b/web/pages/hot-dramas.vue @@ -209,6 +209,8 @@ definePageMeta({ }) import { ref, computed, onMounted, watch } from 'vue' +import { useHotDramaApi } from '~/composables/useApi' +const hotDramaApi = useHotDramaApi() // 响应式数据 const loading = ref(false) @@ -250,32 +252,20 @@ const averageRating = computed(() => { const fetchDramas = async () => { loading.value = true try { - const { useHotDramaApi } = await import('~/composables/useApi') - const hotDramaApi = useHotDramaApi() - const params = { page: 1, - page_size: 1000 // 获取大量数据,实际会返回所有数据 + page_size: 1000 } - if (selectedCategory.value) { params.category = selectedCategory.value } - const response = await hotDramaApi.getHotDramas(params) - console.log('API响应:', response) - - // 使用新的统一响应格式 if (response && response.items) { dramas.value = response.items total.value = response.total || 0 - console.log('设置数据:', dramas.value.length, '条') - console.log('第一条数据:', dramas.value[0]) } else { - // 兼容旧格式 dramas.value = Array.isArray(response) ? response : [] total.value = dramas.value.length - console.log('兼容格式数据:', dramas.value.length, '条') } } catch (error) { console.error('获取热播剧列表失败:', error) diff --git a/web/pages/index.vue b/web/pages/index.vue index bf0287e..dd67d59 100644 --- a/web/pages/index.vue +++ b/web/pages/index.vue @@ -250,7 +250,12 @@ useHead({ // 获取运行时配置 const config = useRuntimeConfig() +import { useResourceApi, useStatsApi, usePanApi, useSystemConfigApi } from '~/composables/useApi' +const resourceApi = useResourceApi() +const statsApi = useStatsApi() +const panApi = usePanApi() +const systemConfigApi = useSystemConfigApi() // 获取路由参数 const route = useRoute() @@ -268,51 +273,36 @@ const isLoadingMore = ref(false) const hasMoreData = ref(true) const pageLoading = ref(false) -console.log(pageSize.value, currentPage.value) - // 使用 useAsyncData 获取资源数据 const { data: resourcesData, pending, refresh } = await useAsyncData( () => `resources-${currentPage.value}-${searchQuery.value}-${selectedPlatform.value}`, - () => $fetch('/api/resources', { - params: { - page: currentPage.value, - page_size: pageSize.value, - search: searchQuery.value, - pan_id: selectedPlatform.value - } + () => resourceApi.getResources({ + page: currentPage.value, + page_size: pageSize.value, + search: searchQuery.value, + pan_id: selectedPlatform.value }) ) // 获取统计数据 -const { data: statsData } = await useAsyncData('stats', - () => $fetch('/api/stats') -) +const { data: statsData } = await useAsyncData('stats', () => statsApi.getStats()) // 获取平台数据 -const { data: platformsData } = await useAsyncData('platforms', - () => $fetch('/api/pans') -) +const { data: platformsData } = await useAsyncData('platforms', () => panApi.getPans()) // 获取系统配置 -const { data: systemConfigData } = await useAsyncData('systemConfig', - () => $fetch('/api/system-config') -) - -const sysConfig = (systemConfigData.value as any)?.data as any -const panList = (platformsData.value as any)?.data?.list as any[] -const resourceList = (resourcesData.value as any)?.data?.resources as any[] -const total = (resourcesData.value as any)?.data?.total as number +const { data: systemConfigData } = await useAsyncData('systemConfig', () => systemConfigApi.getSystemConfig()) // 从 SSR 数据中获取值 -const safeResources = computed(() => (resourcesData.value as any)?.data?.resources || []) -const safeStats = computed(() => (statsData.value as any)?.data || { total_resources: 0, total_categories: 0, total_tags: 0, total_views: 0, today_updates: 0 }) -const platforms = computed(() => panList || []) -const systemConfig = computed(() => sysConfig || { site_title: '老九网盘资源数据库' }) +const safeResources = computed(() => (resourcesData.value as any)?.resources || []) +const safeStats = computed(() => (statsData.value as any) || { total_resources: 0, total_categories: 0, total_tags: 0, total_views: 0, today_updates: 0 }) +const platforms = computed(() => platformsData.value || []) +const systemConfig = computed(() => (systemConfigData.value as any) || { site_title: '老九网盘资源数据库' }) const safeLoading = computed(() => pending.value) // 计算属性 const totalPages = computed(() => { - const total = (resourcesData.value as any)?.data?.total || 0 + const total = (resourcesData.value as any)?.total || 0 return Math.ceil(total / pageSize.value) }) diff --git a/web/pages/monitor.vue b/web/pages/monitor.vue index ff69ab0..3723c9a 100644 --- a/web/pages/monitor.vue +++ b/web/pages/monitor.vue @@ -245,6 +245,8 @@ definePageMeta({ }) import { ref, onMounted, onUnmounted, computed } from 'vue' +import { useMonitorApi } from '~/composables/useApi' +const monitorApi = useMonitorApi() // 响应式数据 const loading = ref(false) @@ -283,8 +285,6 @@ const formatTimestamp = (timestamp: number) => { // 获取系统信息 const fetchSystemInfo = async () => { try { - const { useMonitorApi } = await import('~/composables/useApi') - const monitorApi = useMonitorApi() const response = await monitorApi.getSystemInfo() systemInfo.value = response } catch (error) { @@ -295,8 +295,6 @@ const fetchSystemInfo = async () => { // 获取性能统计 const fetchPerformanceStats = async () => { try { - const { useMonitorApi } = await import('~/composables/useApi') - const monitorApi = useMonitorApi() const response = await monitorApi.getPerformanceStats() performanceStats.value = response } catch (error) { @@ -307,8 +305,6 @@ const fetchPerformanceStats = async () => { // 获取基础统计 const fetchBasicStats = async () => { try { - const { useMonitorApi } = await import('~/composables/useApi') - const monitorApi = useMonitorApi() const response = await monitorApi.getBasicStats() basicStats.value = response } catch (error) { diff --git a/web/server/api/pans.get.ts b/web/server/api/pans.get.ts index 9ab9ed8..643a9ed 100644 --- a/web/server/api/pans.get.ts +++ b/web/server/api/pans.get.ts @@ -4,7 +4,7 @@ export default defineEventHandler(async (event) => { try { // 在服务端调用后端 API const response = await $fetch('/pans', { - baseURL: config.public.apiBase, + baseURL: String(process.server ? config.public.apiServer : config.public.apiBase), headers: { 'Content-Type': 'application/json' } diff --git a/web/server/api/resources.get.ts b/web/server/api/resources.get.ts index 5e9b62f..ee81c85 100644 --- a/web/server/api/resources.get.ts +++ b/web/server/api/resources.get.ts @@ -5,7 +5,7 @@ export default defineEventHandler(async (event) => { try { // 在服务端调用后端 API const response = await $fetch('/resources', { - baseURL: config.public.apiBase, + baseURL: String(process.server ? config.public.apiServer : config.public.apiBase), query, headers: { 'Content-Type': 'application/json' diff --git a/web/server/api/stats.get.ts b/web/server/api/stats.get.ts index 77403cf..73a29ef 100644 --- a/web/server/api/stats.get.ts +++ b/web/server/api/stats.get.ts @@ -4,7 +4,7 @@ export default defineEventHandler(async (event) => { try { // 在服务端调用后端 API const response = await $fetch('/stats', { - baseURL: config.public.apiBase, + baseURL: String(process.server ? config.public.apiServer : config.public.apiBase), headers: { 'Content-Type': 'application/json' } diff --git a/web/server/api/system-config.get.ts b/web/server/api/system-config.get.ts index bd587e8..9925758 100644 --- a/web/server/api/system-config.get.ts +++ b/web/server/api/system-config.get.ts @@ -4,7 +4,7 @@ export default defineEventHandler(async (event) => { try { // 在服务端调用后端 API const response = await $fetch('/system/config', { - baseURL: config.public.apiBase, + baseURL: String(process.server ? config.public.apiServer : config.public.apiBase), headers: { 'Content-Type': 'application/json' } diff --git a/web/server/api/version.get.ts b/web/server/api/version.get.ts index 3593b14..78f2e66 100644 --- a/web/server/api/version.get.ts +++ b/web/server/api/version.get.ts @@ -1,6 +1,6 @@ export default defineEventHandler(async (event) => { const config = useRuntimeConfig() - const apiBase = config.public.apiBase || 'http://localhost:8080/api' + const apiBase = String(process.server ? config.public.apiServer : config.public.apiBase) try { const response = await $fetch(`${apiBase}/version`) @@ -11,4 +11,4 @@ export default defineEventHandler(async (event) => { statusMessage: error.statusMessage || '获取版本信息失败' }) } -}) \ No newline at end of file +}) \ No newline at end of file