origin/apps/web/src/app/main/admin/deptsettingpage/page.tsx

221 lines
8.9 KiB
TypeScript
Raw Normal View History

2025-03-21 10:55:44 +08:00
import { useTusUpload } from "@web/src/hooks/useTusUpload";
import { ShareCodeGenerator } from "../sharecode/sharecodegenerator";
import { ShareCodeValidator } from "../sharecode/sharecodevalidator";
import { useState } from "react";
import { message, Progress, Button, Tabs } from "antd";
import { UploadOutlined } from "@ant-design/icons";
const { TabPane } = Tabs;
2025-03-20 23:09:41 +08:00
export default function DeptSettingPage() {
2025-03-21 10:55:44 +08:00
const [uploadedFileId, setUploadedFileId] = useState<string>('');
2025-03-21 17:25:39 +08:00
const [fileNameMap, setFileNameMap] = useState<Record<string, string>>({});
2025-03-21 10:55:44 +08:00
// 使用您的 useTusUpload hook
const { uploadProgress, isUploading, uploadError, handleFileUpload } = useTusUpload({
onSuccess: (fileId: string) => {
setUploadedFileId(fileId);
message.success('文件上传成功');
},
onError: (error: Error) => {
message.error('上传失败:' + error.message);
}
});
// 处理文件上传
const handleFileSelect = async (file: File) => {
const fileKey = `file-${Date.now()}`; // 生成唯一的文件标识
2025-03-21 17:25:39 +08:00
2025-03-21 10:55:44 +08:00
handleFileUpload(
file,
2025-03-21 17:25:39 +08:00
async (result) => {
2025-03-21 10:55:44 +08:00
setUploadedFileId(result.fileId);
2025-03-21 17:25:39 +08:00
// 在前端保存文件名映射(用于当前会话)
setFileNameMap(prev => ({
...prev,
[result.fileId]: file.name
}));
// 上传成功后保存原始文件名到数据库
try {
console.log('正在保存文件名到数据库:', file.name, '对应文件ID:', result.fileId);
const response = await fetch('/api/upload/filename', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
fileId: result.fileId,
fileName: file.name
}),
});
const responseText = await response.text();
console.log('保存文件名响应:', response.status, responseText);
if (!response.ok) {
console.error('保存文件名失败:', responseText);
message.warning('文件名保存失败,下载时可能无法显示原始文件名');
} else {
console.log('文件名保存成功:', file.name);
}
} catch (error) {
console.error('保存文件名请求失败:', error);
message.warning('文件名保存失败,下载时可能无法显示原始文件名');
}
2025-03-21 10:55:44 +08:00
message.success('文件上传成功');
},
(error) => {
message.error('上传失败:' + error.message);
},
fileKey
);
};
// 处理分享码生成成功
const handleShareSuccess = (code: string) => {
message.success('分享码生成成功:' + code);
// 可以在这里添加其他逻辑,比如保存到历史记录
};
// 处理分享码验证成功
const handleValidSuccess = async (fileId: string) => {
try {
// 构建下载URL
const response = await fetch(`/api/upload/download/${fileId}`);
if (!response.ok) {
throw new Error('文件下载失败');
}
// 获取文件名
const contentDisposition = response.headers.get('content-disposition');
2025-03-21 17:25:39 +08:00
console.log('Content-Disposition 头:', contentDisposition);
let filename = fileNameMap[fileId] || 'downloaded-file'; // 优先使用本地缓存的文件名
2025-03-21 10:55:44 +08:00
if (contentDisposition) {
2025-03-21 17:25:39 +08:00
// 改进文件名提取逻辑
const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
const matches = filenameRegex.exec(contentDisposition);
if (matches && matches[1]) {
// 移除引号并解码 URL 编码的文件名
2025-03-21 10:55:44 +08:00
filename = matches[1].replace(/['"]/g, '');
2025-03-21 17:25:39 +08:00
try {
// 尝试解码 URL 编码的文件名
filename = decodeURIComponent(filename);
} catch (e) {
console.warn('文件名解码失败,使用原始文件名');
}
2025-03-21 10:55:44 +08:00
}
}
2025-03-21 17:25:39 +08:00
console.log('提取的文件名:', filename);
2025-03-21 10:55:44 +08:00
// 创建下载链接
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
2025-03-21 17:25:39 +08:00
// 使用获取到的文件名或本地缓存的文件名
2025-03-21 10:55:44 +08:00
link.download = filename;
2025-03-21 17:25:39 +08:00
// 触发下载
2025-03-21 10:55:44 +08:00
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
message.success('文件下载开始');
} catch (error) {
console.error('下载失败:', error);
message.error('文件下载失败');
}
};
2025-03-20 23:09:41 +08:00
return (
2025-03-21 10:55:44 +08:00
<div style={{ maxWidth: '800px', margin: '0 auto', padding: '20px' }}>
<h2></h2>
<Tabs defaultActiveKey="upload">
<TabPane tab="上传分享" key="upload">
{/* 文件上传区域 */}
<div style={{ marginBottom: '40px' }}>
<h3></h3>
<div style={{
padding: '20px',
border: '2px dashed #d9d9d9',
borderRadius: '8px',
textAlign: 'center'
}}>
<input
type="file"
id="file-input"
style={{ display: 'none' }}
onChange={(e) => {
const file = e.target.files?.[0];
if (file) {
handleFileSelect(file);
}
}}
disabled={isUploading}
/>
<label
htmlFor="file-input"
style={{
display: 'inline-block',
padding: '12px 24px',
backgroundColor: '#1890ff',
color: 'white',
borderRadius: '6px',
cursor: 'pointer',
}}
>
<UploadOutlined />
</label>
{isUploading && (
<div style={{ marginTop: '20px' }}>
<Progress
percent={Object.values(uploadProgress)[0] || 0}
status="active"
/>
</div>
)}
{uploadError && (
<div style={{ color: '#ff4d4f', marginTop: '10px' }}>
{uploadError}
</div>
)}
</div>
</div>
{/* 生成分享码区域 */}
{uploadedFileId && (
<div style={{ marginBottom: '40px' }}>
<h3></h3>
<ShareCodeGenerator
fileId={uploadedFileId}
onSuccess={handleShareSuccess}
/>
</div>
)}
</TabPane>
{/* 使用分享码区域 */}
<TabPane tab="下载文件" key="download">
<div>
<h3>使</h3>
<ShareCodeValidator
onValidSuccess={handleValidSuccess}
/>
</div>
</TabPane>
</Tabs>
2025-03-20 23:09:41 +08:00
</div>
);
}