diff --git a/src/api/download.ts b/src/api/download.ts new file mode 100644 index 0000000..c7fb288 --- /dev/null +++ b/src/api/download.ts @@ -0,0 +1,119 @@ +import request from '@/utils/request' + +/** 下载资源信息 */ +export interface DownloadResource { + id?: string + created_at: string + created_by: string + download_url: string + features: string | null + file_hash: string | null + file_size: string | null + is_active: boolean | null + package_type: string + version: string +} + +/** + * 获取所有发布的资源 + * GET /download-resources + */ +export function getDownloadResourcesApi(): Promise { + return request({ + url: '/download-resources', + method: 'get', + }) +} + +/** + * 获取最新版本 + * GET /download-resources/latest + */ +export function getLatestVersionApi(): Promise { + return request({ + url: '/download-resources/latest', + method: 'get', + }) +} + +/** + * 获取资源列表(包含未激活的) + * GET /web-api/download-resources + * @param package_type 筛选包类型(msi或者msix) + * @param is_active 筛选是否激活 + */ +export function getDownloadResourceListApi(params?: { + package_type?: string + is_active?: string +}): Promise { + return request({ + url: '/web-api/download-resources', + method: 'get', + params, + }) +} + +/** + * 获取单个资源详情 + * GET /web-api/download-resources/{resource_id} + * @param resource_id 资源id + */ +export function getDownloadResourceDetailApi(resource_id: string): Promise { + return request({ + url: `/web-api/download-resources/${resource_id}`, + method: 'get', + }) +} + +/** + * 删除下载资源 + * DELETE /web-api/download-resources/{resource_id} + * @param resource_id 资源id + */ +export function deleteDownloadResourceApi(resource_id: string): Promise { + return request({ + url: `/web-api/download-resources/${resource_id}`, + method: 'delete', + }) +} + +/** 创建资源请求参数类型 */ +export interface CreateResourceRequest { + version: string + package_type: string + download_url: string + features?: string | null + file_size?: string | null + file_hash?: string | null + is_active?: boolean | null +} + +/** 创建资源响应数据类型 */ +export interface CreateResourceResponse { + id: string +} + +/** + * 创建新版本资源信息 + * POST /web-api/download-resources + */ +export function createDownloadResourceApi(params: CreateResourceRequest): Promise { + return request({ + url: '/web-api/download-resources', + method: 'post', + data: params, + }) +} + +/** + * 更新下载资源 + * PUT /web-api/download-resources/{resource_id} + * @param resource_id 资源id + */ +export function updateDownloadResourceApi(resource_id: string, params: Partial): Promise { + return request({ + url: `/web-api/download-resources/${resource_id}`, + method: 'put', + data: params, + }) +} \ No newline at end of file diff --git a/src/router/index.ts b/src/router/index.ts index b60a1eb..2d20086 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -12,6 +12,11 @@ const routes = [ component: () => import('@/views/home/index.vue'), meta: { hidden: true } }, + { + path: '/download', + component: () => import('@/views/download/index.vue'), + meta: { hidden: true } + }, { path: '/dashboard', component: DefaultLayout, @@ -47,6 +52,11 @@ const routes = [ component: () => import('@/views/announcement/index.vue'), meta: { title: '公告管理', icon: 'Bell' }, }, + { + path: 'download-manager', + component: () => import('@/views/download-manager/index.vue'), + meta: { title: '下载资源管理', icon: 'Download' }, + }, ], }, ], diff --git a/src/router/permission.ts b/src/router/permission.ts index 39feadb..3285059 100644 --- a/src/router/permission.ts +++ b/src/router/permission.ts @@ -6,8 +6,8 @@ router.beforeEach(async (to, _ , next) => { // 未登录 if (!userStore.token) { - // 主页(/)允许未登录访问 - if (to.path === '/' || to.path === '/login') { + // 主页(/)、登录页和下载页允许未登录访问 + if (to.path === '/' || to.path === '/login' || to.path === '/download') { next() } else { next('/login') diff --git a/src/utils/request.ts b/src/utils/request.ts index 2c2da33..cfaa1e8 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -2,13 +2,13 @@ import axios from 'axios' import { ElMessage } from 'element-plus' import { useUserStore } from '@/stores/user' -const request = axios.create({ +const axiosInstance = axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL, timeout: 10000, }) /** 请求拦截:自动加 Token */ -request.interceptors.request.use((config) => { +axiosInstance.interceptors.request.use((config: any) => { const userStore = useUserStore() if (userStore.token) { config.headers = config.headers || {} @@ -18,8 +18,8 @@ request.interceptors.request.use((config) => { }) /** 响应拦截:兼容 code / retcode */ -request.interceptors.response.use( - (response) => { +axiosInstance.interceptors.response.use( + (response: any) => { const res = response.data // 登录接口:code @@ -43,24 +43,24 @@ request.interceptors.response.use( // 兜底 return res }, - (error) => { + (error: any) => { // 处理401未授权错误 if (error.response?.status === 401) { const userStore = useUserStore() userStore.logout() - + // 如果不在登录页,则跳转到登录页 if (window.location.pathname !== '/login') { window.location.href = '/login' } - + ElMessage.error('登录已过期,请重新登录') return Promise.reject(new Error('登录已过期')) } - + ElMessage.error(error.message || '网络错误') return Promise.reject(error) } ) -export default request +export default axiosInstance \ No newline at end of file diff --git a/src/views/download-manager/index.vue b/src/views/download-manager/index.vue new file mode 100644 index 0000000..2014ba1 --- /dev/null +++ b/src/views/download-manager/index.vue @@ -0,0 +1,641 @@ + + + + + \ No newline at end of file diff --git a/src/views/download/index.vue b/src/views/download/index.vue new file mode 100644 index 0000000..af21a0e --- /dev/null +++ b/src/views/download/index.vue @@ -0,0 +1,557 @@ + + + + + \ No newline at end of file diff --git a/src/views/home/index.vue b/src/views/home/index.vue index 148bfd4..53e8708 100644 --- a/src/views/home/index.vue +++ b/src/views/home/index.vue @@ -90,18 +90,28 @@ const headerActions = ref([ // 主页中心按钮配置 const heroButtons = ref([ + // { + // id: 'btn1', + // label: '快速开始', + // type: 'primary', + // size: 'large', + // icon: undefined, + // onClick: () => { + // window.open('https://github.com/wangdage12/Snap.Hutao', '_blank') + // } + // }, { - id: 'btn1', - label: '快速开始', + id: 'btn2', + label: '立即下载', type: 'primary', size: 'large', icon: undefined, onClick: () => { - window.open('https://github.com/wangdage12/Snap.Hutao', '_blank') + router.push('/download') } }, { - id: 'btn2', + id: 'btn3', label: '查看文档', type: 'default', size: 'large', diff --git a/src/views/login/index.vue b/src/views/login/index.vue index 8f52ba0..d5a84d0 100644 --- a/src/views/login/index.vue +++ b/src/views/login/index.vue @@ -94,7 +94,7 @@ const handleLogin = async () => { const userStore = useUserStore() // 处理响应数据结构 - const tokenData = response.data || response + const tokenData = response as any userStore.setToken(tokenData.access_token) // 获取用户信息