Browse Source

feat: 添加资源转换日志页面和接口

新增资源转换日志功能页面,包含搜索、表格展示和详情查看功能
添加对应的API接口方法resourceConversionLog
tanshanming 6 tháng trước cách đây
mục cha
commit
7cae226693
2 tập tin đã thay đổi với 357 bổ sung0 xóa
  1. 4 0
      src/api/resourceAudit.js
  2. 353 0
      src/views/resourceConversionLog/index.vue

+ 4 - 0
src/api/resourceAudit.js

@@ -94,5 +94,9 @@ export default {
 	//根据学院id和专业id查询班级
 	gradeByZyAndOrgId(data = {}) {
 		return request('disk/grades/queryList', data, 'get')
+	},
+	//资源转换日志
+	resourceConversionLog(data = {}) {
+		return request('disk/userfileconvert/page', data, 'get')
 	}
 }

+ 353 - 0
src/views/resourceConversionLog/index.vue

@@ -0,0 +1,353 @@
+<template>
+	<div class="resource-conversion-log">
+		<a-card title="资源转换日志" :bordered="false">
+			<!-- 搜索区域 -->
+			<div class="search-area">
+				<a-form layout="inline" :model="searchForm">
+					<a-form-item label="文件名称">
+						<a-input
+							v-model:value="searchForm.fileName"
+							placeholder="请输入文件名称"
+							allow-clear
+							style="width: 200px"
+							@pressEnter="handleSearch"
+						/>
+					</a-form-item>
+					<a-form-item>
+						<a-button type="primary" @click="handleSearch" :loading="loading">
+							<template #icon><SearchOutlined /></template>
+							查询
+						</a-button>
+						<a-button style="margin-left: 8px" @click="handleReset">
+							<template #icon><ReloadOutlined /></template>
+							重置
+						</a-button>
+					</a-form-item>
+				</a-form>
+			</div>
+
+			<!-- 表格 -->
+			<a-table
+				:columns="columns"
+				:data-source="dataSource"
+				:loading="loading"
+				:pagination="pagination"
+				row-key="id"
+				@change="handleTableChange"
+				:scroll="{ x: 1200 }"
+			>
+				<!-- 文件名称列 -->
+				<template #fileName="{ record }">
+					<a-tooltip :title="record.fileName">
+						<span class="file-name">{{ record.fileName }}</span>
+					</a-tooltip>
+				</template>
+
+				<!-- 文件扩展名列 -->
+				<template #extendName="{ record }">
+					<a-tag :color="getExtensionColor(record.extendName)">
+						{{ record.extendName?.toUpperCase() || '-' }}
+					</a-tag>
+				</template>
+
+				<!-- 转换状态列 -->
+				<template #status="{ record }">
+					<a-tag :color="getStatusColor(record.status)">
+						<template #icon>
+							<LoadingOutlined v-if="record.status === '0'" />
+							<CheckCircleOutlined v-else-if="record.status === '1'" />
+							<CloseCircleOutlined v-else-if="record.status === '2'" />
+						</template>
+						{{ getStatusText(record.status) }}
+					</a-tag>
+				</template>
+
+				<!-- 创建时间列 -->
+				<template #createTime="{ record }">
+					{{ formatTime(record.createTime) }}
+				</template>
+
+				<!-- 操作列 -->
+				<!-- <template #action="{ record }">
+					<a-space>
+						<a-button type="link" size="small" @click="handleViewDetail(record)"> 查看详情 </a-button>
+						<a-button v-if="record.status === '2'" type="link" size="small" danger @click="handleRetry(record)">
+							重新转换
+						</a-button>
+					</a-space>
+				</template> -->
+			</a-table>
+		</a-card>
+
+		<!-- 详情弹窗 -->
+		<a-modal v-model:open="detailVisible" title="转换日志详情" width="600px" :footer="null">
+			<a-descriptions :column="1" bordered v-if="currentRecord">
+				<a-descriptions-item label="文件名称">
+					{{ currentRecord.fileName }}
+				</a-descriptions-item>
+				<a-descriptions-item label="文件扩展名">
+					<a-tag :color="getExtensionColor(currentRecord.extendName)">
+						{{ currentRecord.extendName?.toUpperCase() || '-' }}
+					</a-tag>
+				</a-descriptions-item>
+				<a-descriptions-item label="文件路径">
+					<a-typography-text copyable>{{ currentRecord.filePath || '-' }}</a-typography-text>
+				</a-descriptions-item>
+				<a-descriptions-item label="转换状态">
+					<a-tag :color="getStatusColor(currentRecord.status)">
+						<template #icon>
+							<LoadingOutlined v-if="currentRecord.status === '0'" />
+							<CheckCircleOutlined v-else-if="currentRecord.status === '1'" />
+							<CloseCircleOutlined v-else-if="currentRecord.status === '2'" />
+						</template>
+						{{ getStatusText(currentRecord.status) }}
+					</a-tag>
+				</a-descriptions-item>
+				<a-descriptions-item label="失败原因" v-if="currentRecord.status === '2' && currentRecord.reason">
+					<a-typography-text type="danger">{{ currentRecord.reason }}</a-typography-text>
+				</a-descriptions-item>
+				<a-descriptions-item label="创建时间">
+					{{ formatTime(currentRecord.createTime) }}
+				</a-descriptions-item>
+				<a-descriptions-item label="更新时间" v-if="currentRecord.updateTime">
+					{{ formatTime(currentRecord.updateTime) }}
+				</a-descriptions-item>
+			</a-descriptions>
+		</a-modal>
+	</div>
+</template>
+
+<script setup>
+	import { ref, reactive, onMounted } from 'vue'
+	import { message } from 'ant-design-vue'
+	import {
+		SearchOutlined,
+		ReloadOutlined,
+		LoadingOutlined,
+		CheckCircleOutlined,
+		CloseCircleOutlined
+	} from '@ant-design/icons-vue'
+	import resourceAuditApi from '@/api/resourceAudit'
+	import dayjs from 'dayjs'
+
+	// 搜索表单
+	const searchForm = reactive({
+		fileName: ''
+	})
+
+	// 表格数据
+	const dataSource = ref([])
+	const loading = ref(false)
+
+	// 分页配置
+	const pagination = reactive({
+		current: 1,
+		pageSize: 20,
+		total: 0,
+		showSizeChanger: true,
+		showQuickJumper: true,
+		showTotal: (total) => `共 ${total} 条记录`
+	})
+
+	// 详情弹窗
+	const detailVisible = ref(false)
+	const currentRecord = ref(null)
+
+	// 表格列配置
+	const columns = [
+		{
+			title: '文件名称',
+			dataIndex: 'fileName',
+			key: 'fileName',
+			width: 200,
+			ellipsis: true,
+			slots: { customRender: 'fileName' }
+		},
+		{
+			title: '文件扩展名',
+			dataIndex: 'extendName',
+			key: 'extendName',
+			width: 120,
+			align: 'center',
+			slots: { customRender: 'extendName' }
+		},
+		{
+			title: '转换状态',
+			dataIndex: 'status',
+			key: 'status',
+			width: 120,
+			align: 'center',
+			slots: { customRender: 'status' }
+		},
+		{
+			title: '文件路径',
+			dataIndex: 'filePath',
+			key: 'filePath',
+			width: 250,
+			ellipsis: true
+		},
+		{
+			title: '创建时间',
+			dataIndex: 'createTime',
+			key: 'createTime',
+			width: 180,
+			slots: { customRender: 'createTime' }
+		},
+		// {
+		// 	title: '操作',
+		// 	key: 'action',
+		// 	width: 150,
+		// 	align: 'center',
+		// 	fixed: 'right',
+		// 	slots: { customRender: 'action' }
+		// }
+	]
+
+	// 获取列表数据
+	const fetchData = async () => {
+		try {
+			loading.value = true
+			const params = {
+				current: pagination.current,
+				size: pagination.pageSize,
+				...searchForm
+			}
+
+			const response = await resourceAuditApi.resourceConversionLog(params)
+
+			if (response.code === 200) {
+				dataSource.value = response.data.records || []
+				pagination.total = response.data.total || 0
+			} else {
+				message.error(response.msg || '获取数据失败')
+			}
+		} catch (error) {
+			console.error('获取转换日志失败:', error)
+			message.error('获取数据失败')
+		} finally {
+			loading.value = false
+		}
+	}
+
+	// 搜索
+	const handleSearch = () => {
+		pagination.current = 1
+		fetchData()
+	}
+
+	// 重置
+	const handleReset = () => {
+		Object.keys(searchForm).forEach((key) => {
+			searchForm[key] = ''
+		})
+		pagination.current = 1
+		fetchData()
+	}
+
+	// 表格变化处理
+	const handleTableChange = (pag) => {
+		pagination.current = pag.current
+		pagination.pageSize = pag.pageSize
+		fetchData()
+	}
+
+	// 查看详情
+	const handleViewDetail = (record) => {
+		currentRecord.value = record
+		detailVisible.value = true
+	}
+
+	// 重新转换
+	const handleRetry = (record) => {
+		// 这里可以调用重新转换的接口
+		message.info('重新转换功能待实现')
+	}
+
+	// 获取状态文本
+	const getStatusText = (status) => {
+		const statusMap = {
+			0: '转换中',
+			1: '转换完成',
+			2: '转换失败'
+		}
+		return statusMap[status] || '未知状态'
+	}
+
+	// 获取状态颜色
+	const getStatusColor = (status) => {
+		const colorMap = {
+			0: 'processing',
+			1: 'success',
+			2: 'error'
+		}
+		return colorMap[status] || 'default'
+	}
+
+	// 获取文件扩展名颜色
+	const getExtensionColor = (extension) => {
+		const colorMap = {
+			pdf: 'red',
+			doc: 'blue',
+			docx: 'blue',
+			ppt: 'orange',
+			pptx: 'orange',
+			xls: 'green',
+			xlsx: 'green',
+			jpg: 'purple',
+			jpeg: 'purple',
+			png: 'purple',
+			gif: 'purple',
+			mp4: 'cyan',
+			avi: 'cyan',
+			mov: 'cyan'
+		}
+		return colorMap[extension?.toLowerCase()] || 'default'
+	}
+
+	// 格式化时间
+	const formatTime = (timestamp) => {
+		if (!timestamp) return '-'
+		return dayjs(timestamp).format('YYYY-MM-DD HH:mm:ss')
+	}
+
+	// 组件挂载时获取数据
+	onMounted(() => {
+		fetchData()
+	})
+</script>
+
+<style scoped>
+	.resource-conversion-log {
+		padding: 20px;
+	}
+
+	.search-area {
+		margin-bottom: 16px;
+		padding: 16px;
+		background: #fafafa;
+		border-radius: 6px;
+	}
+
+	.file-name {
+		max-width: 180px;
+		display: inline-block;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+		vertical-align: middle;
+	}
+
+	:deep(.ant-table-thead > tr > th) {
+		background: #fafafa;
+		font-weight: 600;
+	}
+
+	:deep(.ant-table-tbody > tr:hover > td) {
+		background: #f5f5f5;
+	}
+
+	:deep(.ant-descriptions-item-label) {
+		width: 120px;
+		font-weight: 600;
+	}
+</style>