import { type LoaderFunctionArgs } from '@remix-run/node'; import { API_BASE_URL } from '~/config/api-config'; /** * GET /api/dataset/dify-files/* * 代理 Dify 文件下载请求 * * 用于下载 Dify 知识库中的原始文件 * 将 /api/dataset/dify-files/xxx 转发到 Dify 的 /files/xxx */ export async function loader({ request, params }: LoaderFunctionArgs) { try { const { getUserSession } = await import("~/api/login/auth.server"); const { frontendJWT } = await getUserSession(request); if (!frontendJWT) { return new Response( JSON.stringify({ error: 'JWT认证失败,请重新登录' }), { status: 401, headers: { 'Content-Type': 'application/json' } } ); } // 获取完整路径(包含查询参数) const url = new URL(request.url); const filePath = params['*'] || ''; const queryString = url.search; console.log('[API] Dify File Proxy:', { filePath, queryString }); // 构建 Dify 文件下载 URL // 使用专门的文件下载代理路由 /dify_file/ // 因为 Dify 文件 API (/files/) 不需要 /v1 前缀,与其他 API 不同 const difyFileUrl = `${API_BASE_URL}/dify_file/${filePath}${queryString}`; console.log('[API] Proxying to:', difyFileUrl); // 转发请求到 Dify const response = await fetch(difyFileUrl, { method: 'GET', headers: { 'Authorization': `Bearer ${frontendJWT}`, }, }); if (!response.ok) { console.error('[API] Dify File Proxy - Error:', response.status, response.statusText); return new Response( JSON.stringify({ error: `文件下载失败: ${response.statusText}` }), { status: response.status, headers: { 'Content-Type': 'application/json' } } ); } // 获取文件内容 const fileBuffer = await response.arrayBuffer(); // 返回文件,保持原始的 Content-Type const contentType = response.headers.get('Content-Type') || 'application/octet-stream'; const contentDisposition = response.headers.get('Content-Disposition'); const headers: Record = { 'Content-Type': contentType, }; if (contentDisposition) { headers['Content-Disposition'] = contentDisposition; } return new Response(fileBuffer, { status: 200, headers, }); } catch (error: any) { console.error('[API] Dify File Proxy - Error:', error.message); return new Response( JSON.stringify({ error: error.message || 'Failed to download file' }), { status: 500, headers: { 'Content-Type': 'application/json' } } ); } }