From 269c66d1ace18ddd3b32285f537a49b91ca4c90d Mon Sep 17 00:00:00 2001
From: Leo <98382335+gaoziman@users.noreply.github.com>
Date: Mon, 20 Oct 2025 14:06:32 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=BD=AC=E6=8D=A2=E5=8E=86?=
=?UTF-8?q?=E5=8F=B2=E7=BB=84=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 实现转换历史记录展示
- 支持查看历史转换详情
---
src/components/ConversionHistory.js | 333 ++++++++++++++++++++++++++++
1 file changed, 333 insertions(+)
create mode 100644 src/components/ConversionHistory.js
diff --git a/src/components/ConversionHistory.js b/src/components/ConversionHistory.js
new file mode 100644
index 0000000..80f0004
--- /dev/null
+++ b/src/components/ConversionHistory.js
@@ -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) => (
+