添加转换历史组件
- 实现转换历史记录展示 - 支持查看历史转换详情
This commit is contained in:
parent
f14e62af66
commit
269c66d1ac
333
src/components/ConversionHistory.js
Normal file
333
src/components/ConversionHistory.js
Normal file
@ -0,0 +1,333 @@
|
||||
/**
|
||||
* 转换历史记录组件
|
||||
*/
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import {
|
||||
Table,
|
||||
Button,
|
||||
Tag,
|
||||
Space,
|
||||
Card,
|
||||
message,
|
||||
Modal,
|
||||
Descriptions,
|
||||
Alert,
|
||||
Typography,
|
||||
Tooltip,
|
||||
} from 'antd';
|
||||
import {
|
||||
DownloadOutlined,
|
||||
ReloadOutlined,
|
||||
EyeOutlined,
|
||||
ExclamationCircleOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { apiService } from '../services/api';
|
||||
import {
|
||||
formatFileSize,
|
||||
formatDateTime,
|
||||
formatConversionTime,
|
||||
getStatusColor,
|
||||
getStatusText,
|
||||
downloadFile
|
||||
} from '../utils/helpers';
|
||||
import Pagination from './Pagination';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
const ConversionHistory = ({ refreshTrigger }) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [data, setData] = useState([]);
|
||||
const [pagination, setPagination] = useState({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
});
|
||||
const [detailModalVisible, setDetailModalVisible] = useState(false);
|
||||
const [selectedRecord, setSelectedRecord] = useState(null);
|
||||
|
||||
// 加载历史记录
|
||||
const loadHistory = async (page = 1, pageSize = 10) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await apiService.getHistory(page, pageSize);
|
||||
if (response.data.status === 'success') {
|
||||
setData(response.data.data.records);
|
||||
setPagination(prev => ({
|
||||
...prev,
|
||||
current: page,
|
||||
pageSize,
|
||||
total: response.data.data.total,
|
||||
}));
|
||||
}
|
||||
} catch (err) {
|
||||
message.error('加载历史记录失败: ' + err.message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 初始加载
|
||||
useEffect(() => {
|
||||
loadHistory();
|
||||
}, []);
|
||||
|
||||
// 响应刷新触发器
|
||||
useEffect(() => {
|
||||
if (refreshTrigger) {
|
||||
loadHistory(1);
|
||||
}
|
||||
}, [refreshTrigger]);
|
||||
|
||||
// 处理分页变化
|
||||
const handlePaginationChange = (page, pageSize) => {
|
||||
loadHistory(page, pageSize);
|
||||
};
|
||||
|
||||
// 处理页面大小变化
|
||||
const handlePageSizeChange = (current, size) => {
|
||||
setPagination(prev => ({
|
||||
...prev,
|
||||
current: current,
|
||||
pageSize: size,
|
||||
}));
|
||||
};
|
||||
|
||||
// 下载文件
|
||||
const handleDownload = async (record) => {
|
||||
if (record.conversion_status !== 'success') {
|
||||
message.warning('只能下载转换成功的文件');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await apiService.downloadFile(record.id);
|
||||
const blob = new Blob([response.data], { type: 'text/plain' });
|
||||
downloadFile(blob, record.converted_filename);
|
||||
message.success('文件下载成功');
|
||||
} catch (err) {
|
||||
message.error('下载失败: ' + err.message);
|
||||
}
|
||||
};
|
||||
|
||||
// 查看详情
|
||||
const handleViewDetails = async (record) => {
|
||||
try {
|
||||
const response = await apiService.getRecord(record.id);
|
||||
if (response.data.status === 'success') {
|
||||
setSelectedRecord(response.data.data);
|
||||
setDetailModalVisible(true);
|
||||
}
|
||||
} catch (err) {
|
||||
message.error('获取详情失败: ' + err.message);
|
||||
}
|
||||
};
|
||||
|
||||
// 表格列定义
|
||||
const columns = [
|
||||
{
|
||||
title: '原始文件名',
|
||||
dataIndex: 'original_filename',
|
||||
key: 'original_filename',
|
||||
ellipsis: {
|
||||
showTitle: false,
|
||||
},
|
||||
render: (text) => (
|
||||
<Tooltip title={text}>
|
||||
<Text style={{ maxWidth: 200 }}>{text}</Text>
|
||||
</Tooltip>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '文件大小',
|
||||
dataIndex: 'file_size',
|
||||
key: 'file_size',
|
||||
width: 100,
|
||||
render: (size) => formatFileSize(size),
|
||||
},
|
||||
{
|
||||
title: '转换状态',
|
||||
dataIndex: 'conversion_status',
|
||||
key: 'conversion_status',
|
||||
width: 100,
|
||||
render: (status) => (
|
||||
<Tag color={getStatusColor(status)}>
|
||||
{getStatusText(status)}
|
||||
</Tag>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '转换时间',
|
||||
dataIndex: 'conversion_time',
|
||||
key: 'conversion_time',
|
||||
width: 100,
|
||||
render: (time) => formatConversionTime(time),
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'created_at',
|
||||
key: 'created_at',
|
||||
width: 160,
|
||||
render: (time) => formatDateTime(time),
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'actions',
|
||||
width: 160,
|
||||
render: (_, record) => (
|
||||
<Space size="small">
|
||||
<Tooltip title="查看详情">
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
icon={<EyeOutlined />}
|
||||
onClick={() => handleViewDetails(record)}
|
||||
/>
|
||||
</Tooltip>
|
||||
{record.conversion_status === 'success' && (
|
||||
<Tooltip title="下载文件">
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
icon={<DownloadOutlined />}
|
||||
onClick={() => handleDownload(record)}
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card
|
||||
title="转换历史记录"
|
||||
extra={
|
||||
<Button
|
||||
icon={<ReloadOutlined />}
|
||||
onClick={() => loadHistory(pagination.current, pagination.pageSize)}
|
||||
loading={loading}
|
||||
>
|
||||
刷新
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={data}
|
||||
rowKey="id"
|
||||
loading={loading}
|
||||
pagination={false}
|
||||
size="middle"
|
||||
scroll={{ x: 800 }}
|
||||
/>
|
||||
|
||||
{/* 自定义分页组件 */}
|
||||
<Pagination
|
||||
current={pagination.current}
|
||||
total={pagination.total}
|
||||
pageSize={pagination.pageSize}
|
||||
onChange={handlePaginationChange}
|
||||
onShowSizeChange={handlePageSizeChange}
|
||||
showSizeChanger={true}
|
||||
showQuickJumper={true}
|
||||
showTotal={true}
|
||||
pageSizeOptions={['10', '20', '50', '100']}
|
||||
/>
|
||||
</Card>
|
||||
|
||||
{/* 详情模态框 */}
|
||||
<Modal
|
||||
title="转换记录详情"
|
||||
open={detailModalVisible}
|
||||
onCancel={() => {
|
||||
setDetailModalVisible(false);
|
||||
setSelectedRecord(null);
|
||||
}}
|
||||
footer={[
|
||||
<Button key="close" onClick={() => setDetailModalVisible(false)}>
|
||||
关闭
|
||||
</Button>,
|
||||
selectedRecord?.conversion_status === 'success' && (
|
||||
<Button
|
||||
key="download"
|
||||
type="primary"
|
||||
icon={<DownloadOutlined />}
|
||||
onClick={() => handleDownload(selectedRecord)}
|
||||
>
|
||||
下载文件
|
||||
</Button>
|
||||
),
|
||||
].filter(Boolean)}
|
||||
width={800}
|
||||
>
|
||||
{selectedRecord && (
|
||||
<div>
|
||||
<Descriptions column={2} bordered size="small">
|
||||
<Descriptions.Item label="记录ID">
|
||||
{selectedRecord.id}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="转换状态">
|
||||
<Tag color={getStatusColor(selectedRecord.conversion_status)}>
|
||||
{getStatusText(selectedRecord.conversion_status)}
|
||||
</Tag>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="原始文件名">
|
||||
{selectedRecord.original_filename}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="转换后文件名">
|
||||
{selectedRecord.converted_filename || '-'}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="文件大小">
|
||||
{formatFileSize(selectedRecord.file_size)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="转换耗时">
|
||||
{formatConversionTime(selectedRecord.conversion_time)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="创建时间">
|
||||
{formatDateTime(selectedRecord.created_at)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="更新时间">
|
||||
{formatDateTime(selectedRecord.updated_at)}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
|
||||
{selectedRecord.original_minio_url && (
|
||||
<div style={{ marginTop: 16 }}>
|
||||
<Text strong>原始文件URL:</Text>
|
||||
<br />
|
||||
<Text code copyable style={{ wordBreak: 'break-all' }}>
|
||||
{selectedRecord.original_minio_url}
|
||||
</Text>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{selectedRecord.converted_minio_url && (
|
||||
<div style={{ marginTop: 16 }}>
|
||||
<Text strong>转换后文件URL:</Text>
|
||||
<br />
|
||||
<Text code copyable style={{ wordBreak: 'break-all' }}>
|
||||
{selectedRecord.converted_minio_url}
|
||||
</Text>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{selectedRecord.error_message && (
|
||||
<div style={{ marginTop: 16 }}>
|
||||
<Alert
|
||||
message="错误信息"
|
||||
description={selectedRecord.error_message}
|
||||
type="error"
|
||||
showIcon
|
||||
icon={<ExclamationCircleOutlined />}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConversionHistory;
|
||||
Loading…
Reference in New Issue
Block a user