|
@@ -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:visible="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>
|