collect-system/apps/web/src/app/admin/sharecode/sharecodegenerator.tsx

142 lines
4.3 KiB
TypeScript
Raw Normal View History

2025-04-02 16:14:30 +08:00
2025-04-02 21:59:19 +08:00
import React, { useEffect, useState } from 'react';
2025-04-02 16:14:30 +08:00
import { Button, message } from 'antd';
import { CopyOutlined } from '@ant-design/icons';
2025-04-02 21:59:19 +08:00
import { env } from '../../../env'
import { useQueryClient } from '@tanstack/react-query';
import { getQueryKey } from '@trpc/react-query';
import { api } from '@nice/client';
2025-04-02 16:14:30 +08:00
interface ShareCodeGeneratorProps {
fileId: string;
onSuccess?: (code: string) => void;
fileName?: string;
}
2025-04-02 21:59:19 +08:00
interface ShareCodeResponse {
code?: string;
expiresAt?: Date;
2025-04-03 13:27:58 +08:00
}
2025-04-02 16:14:30 +08:00
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);
2025-04-02 21:59:19 +08:00
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])
2025-04-02 16:14:30 +08:00
const generateCode = async () => {
2025-04-03 13:27:58 +08:00
if (!fileId) {
message.error('请先上传文件');
return;
}
2025-04-02 16:14:30 +08:00
setLoading(true);
console.log('开始生成分享码fileId:', fileId, 'fileName:', fileName);
try {
2025-04-02 21:59:19 +08:00
const data: ShareCodeResponse = await generateShareCode.mutateAsync({ fileId });
console.log('生成分享码结果:', data);
2025-04-02 16:14:30 +08:00
setShareCode(data.code);
2025-04-02 21:59:19 +08:00
setIsGenerate(true);
2025-04-02 16:14:30 +08:00
setExpiresAt(data.expiresAt ? new Date(data.expiresAt) : null);
onSuccess?.(data.code);
2025-04-03 13:27:58 +08:00
//message.success('分享码生成成功');
2025-04-02 16:14:30 +08:00
} catch (error) {
console.error('生成分享码错误:', error);
message.error('生成分享码失败: ' + (error instanceof Error ? error.message : '未知错误'));
} finally {
setLoading(false);
}
};
2025-04-03 13:27:58 +08:00
function copyToClipboard(text) {
if (navigator.clipboard) {
return navigator.clipboard.writeText(text);
} else {
const textarea = document.createElement('textarea');
textarea.value = text;
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
return Promise.resolve();
}
}
// 组件使用
const handleCopy = (code) => {
copyToClipboard(code)
.then(() => console.log('复制成功'))
.catch(() => console.error('复制失败'));
};
2025-04-02 16:14:30 +08:00
return (
<div style={{ padding: '20px', backgroundColor: '#f8f9fa', borderRadius: '8px' }}>
<div style={{ marginBottom: '10px' }}>
{/* 添加调试信息 */}
2025-04-02 21:59:19 +08:00
<small style={{ color: '#666' }}>ID: {fileId ? fileId : '未选择文件'}</small>
2025-04-02 16:14:30 +08:00
</div>
2025-04-02 21:59:19 +08:00
{!isGenerate ? (
2025-04-02 16:14:30 +08:00
<Button
type="primary"
onClick={generateCode}
loading={loading}
block
>
</Button>
) : (
<div style={{ textAlign: 'center' }}>
2025-04-02 21:59:19 +08:00
<div style={{
2025-04-02 16:14:30 +08:00
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={() => {
2025-04-03 13:27:58 +08:00
handleCopy(shareCode)
//navigator.clipboard.writeText(shareCode);
2025-04-02 16:14:30 +08:00
message.success('分享码已复制');
}}
/>
</div>
{expiresAt ? (
<div style={{ color: '#666' }}>
: {expiresAt.toLocaleString()}
</div>
) : (
<div style={{ color: 'red' }}>
</div>
)}
</div>
)}
</div>
);
};