135 lines
3.9 KiB
TypeScript
135 lines
3.9 KiB
TypeScript
|
|
|||
|
import React, { useState } from 'react';
|
|||
|
import { Button, message } from 'antd';
|
|||
|
import { CopyOutlined } from '@ant-design/icons';
|
|||
|
import {env} from '../../../env'
|
|||
|
interface ShareCodeGeneratorProps {
|
|||
|
fileId: string;
|
|||
|
onSuccess?: (code: string) => void;
|
|||
|
fileName?: string;
|
|||
|
}
|
|||
|
|
|||
|
export const ShareCodeGenerator: React.FC<ShareCodeGeneratorProps> = ({
|
|||
|
fileId,
|
|||
|
onSuccess,
|
|||
|
fileName,
|
|||
|
}) => {
|
|||
|
const [loading, setLoading] = useState(false);
|
|||
|
const [shareCode, setShareCode] = useState<string>('');
|
|||
|
const [expiresAt, setExpiresAt] = useState<Date | null>(null);
|
|||
|
|
|||
|
const generateCode = async () => {
|
|||
|
setLoading(true);
|
|||
|
console.log('开始生成分享码,fileId:', fileId, 'fileName:', fileName);
|
|||
|
|
|||
|
try {
|
|||
|
const response = await fetch(`http://${env.SERVER_IP}:${env.SERVER_PORT}/upload/share/${fileId}`, {
|
|||
|
method: 'POST',
|
|||
|
headers: {
|
|||
|
'Content-Type': 'application/json',
|
|||
|
},
|
|||
|
body: JSON.stringify({
|
|||
|
fileId
|
|||
|
})
|
|||
|
});
|
|||
|
console.log('Current fileId:', fileId); // 确保 fileId 有效
|
|||
|
console.log('请求URL:', `http://${env.SERVER_IP}:${env.SERVER_PORT}/upload/share/${fileId}`);
|
|||
|
console.log('API响应状态:', response.status);
|
|||
|
|
|||
|
const responseText = await response.text();
|
|||
|
console.log('API原始响应:', responseText);
|
|||
|
|
|||
|
if (!response.ok) {
|
|||
|
throw new Error(`请求失败: ${response.status} ${responseText || '无错误信息'}`);
|
|||
|
}
|
|||
|
|
|||
|
// 确保响应不为空
|
|||
|
if (!responseText) {
|
|||
|
throw new Error('服务器返回空响应');
|
|||
|
}
|
|||
|
|
|||
|
// 尝试解析JSON
|
|||
|
let data;
|
|||
|
try {
|
|||
|
data = JSON.parse(responseText);
|
|||
|
} catch (e) {
|
|||
|
console.error('解析响应JSON失败:', e);
|
|||
|
throw new Error('服务器响应格式错误');
|
|||
|
}
|
|||
|
|
|||
|
console.log('解析后的响应数据:', data); // 调试日志
|
|||
|
|
|||
|
if (!data.code) {
|
|||
|
throw new Error('响应中没有分享码');
|
|||
|
}
|
|||
|
|
|||
|
setShareCode(data.code);
|
|||
|
setExpiresAt(data.expiresAt ? new Date(data.expiresAt) : null);
|
|||
|
onSuccess?.(data.code);
|
|||
|
message.success('分享码生成成功');
|
|||
|
} catch (error) {
|
|||
|
console.error('生成分享码错误:', error);
|
|||
|
message.error('生成分享码失败: ' + (error instanceof Error ? error.message : '未知错误'));
|
|||
|
} finally {
|
|||
|
setLoading(false);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
return (
|
|||
|
<div style={{ padding: '20px', backgroundColor: '#f8f9fa', borderRadius: '8px' }}>
|
|||
|
<div style={{ marginBottom: '10px' }}>
|
|||
|
{/* 添加调试信息 */}
|
|||
|
<small style={{ color: '#666' }}>文件ID: {fileId}</small>
|
|||
|
</div>
|
|||
|
|
|||
|
{!shareCode ? (
|
|||
|
<Button
|
|||
|
type="primary"
|
|||
|
onClick={generateCode}
|
|||
|
loading={loading}
|
|||
|
block
|
|||
|
>
|
|||
|
生成分享码
|
|||
|
</Button>
|
|||
|
) : (
|
|||
|
<div style={{ textAlign: 'center' }}>
|
|||
|
<div style={{
|
|||
|
display: 'flex',
|
|||
|
alignItems: 'center',
|
|||
|
justifyContent: 'center',
|
|||
|
gap: '12px',
|
|||
|
margin: '16px 0'
|
|||
|
}}>
|
|||
|
<span style={{
|
|||
|
fontSize: '24px',
|
|||
|
fontWeight: 'bold',
|
|||
|
letterSpacing: '2px',
|
|||
|
color: '#1890ff',
|
|||
|
padding: '8px 16px',
|
|||
|
backgroundColor: '#e6f7ff',
|
|||
|
borderRadius: '4px'
|
|||
|
}}>
|
|||
|
{shareCode}
|
|||
|
</span>
|
|||
|
<Button
|
|||
|
icon={<CopyOutlined />}
|
|||
|
onClick={() => {
|
|||
|
navigator.clipboard.writeText(shareCode);
|
|||
|
message.success('分享码已复制');
|
|||
|
}}
|
|||
|
/>
|
|||
|
</div>
|
|||
|
{expiresAt ? (
|
|||
|
<div style={{ color: '#666' }}>
|
|||
|
有效期至: {expiresAt.toLocaleString()}
|
|||
|
</div>
|
|||
|
) : (
|
|||
|
<div style={{ color: 'red' }}>
|
|||
|
未获取到有效期信息
|
|||
|
</div>
|
|||
|
)}
|
|||
|
</div>
|
|||
|
)}
|
|||
|
</div>
|
|||
|
);
|
|||
|
};
|