117 lines
3.6 KiB
TypeScript
Executable File
117 lines
3.6 KiB
TypeScript
Executable File
|
||
import React, { useEffect, useState } from 'react';
|
||
import { Button, message } from 'antd';
|
||
import { CopyOutlined } from '@ant-design/icons';
|
||
import { env } from '../../../env'
|
||
import { useQueryClient } from '@tanstack/react-query';
|
||
import { getQueryKey } from '@trpc/react-query';
|
||
import { api } from '@nice/client';
|
||
interface ShareCodeGeneratorProps {
|
||
fileId: string;
|
||
onSuccess?: (code: string) => void;
|
||
fileName?: string;
|
||
}
|
||
interface ShareCodeResponse {
|
||
code?: string;
|
||
expiresAt?: Date;
|
||
}
|
||
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 queryClient = useQueryClient();
|
||
const queryKey = getQueryKey(api.term);
|
||
const [isGenerate, setIsGenerate] = useState(false);
|
||
const [currentFileId, setCurrentFileId] = useState<string>('');
|
||
const generateShareCode = api.shareCode.generateShareCodeByFileId.useMutation({
|
||
onSuccess: (data) => {
|
||
queryClient.invalidateQueries({ queryKey });
|
||
},
|
||
});
|
||
useEffect(() => {
|
||
if (fileId !== currentFileId || !fileId) {
|
||
setIsGenerate(false);
|
||
}
|
||
setCurrentFileId(fileId);
|
||
}, [fileId])
|
||
const generateCode = async () => {
|
||
setLoading(true);
|
||
console.log('开始生成分享码,fileId:', fileId, 'fileName:', fileName);
|
||
try {
|
||
const data: ShareCodeResponse = await generateShareCode.mutateAsync({ fileId });
|
||
console.log('生成分享码结果:', data);
|
||
setShareCode(data.code);
|
||
setIsGenerate(true);
|
||
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 ? fileId : '未选择文件'}</small>
|
||
</div>
|
||
|
||
{!isGenerate ? (
|
||
<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>
|
||
);
|
||
}; |