feat(ads/compliance/tencent): 新增导出失败素材接口并优化校验页面功能
1. 新增导出驳回素材的API接口和前端导出逻辑,统一处理图片/视频素材导出 2. 移除旧的批量校验、刷新、手动送检功能,重构日志查看逻辑 3. 优化预览弹窗样式,调整表格列宽和日志表格展示字段 4. 替换旧的本地导出实现为后端接口导出方式
This commit is contained in:
@@ -156,3 +156,16 @@ export function batchVerifyVideo(requestOptions?: RequestOptions) {
|
|||||||
requestOptions,
|
requestOptions,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ExportParams {
|
||||||
|
materialType?: 'IMAGE' | 'VIDEO';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function exportRejectedMaterials(data: ExportParams = {}, requestOptions?: RequestOptions) {
|
||||||
|
return request({
|
||||||
|
url: '/cid/material/verify/controller/export-rejected',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
requestOptions,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div class="ads-compliance-tencent">
|
<div class="ads-compliance-tencent">
|
||||||
<el-card shadow="hover" class="main-card">
|
<el-card shadow="hover" class="main-card">
|
||||||
<!-- Tabs -->
|
<!-- Tabs -->
|
||||||
<el-tabs v-model="activeTab" @tab-click="handleTabClick" class="main-tabs">
|
<el-tabs v-model="activeTab" class="main-tabs">
|
||||||
<el-tab-pane label="图片素材" name="image">
|
<el-tab-pane label="图片素材" name="image">
|
||||||
<!-- 图片素材内容区域 -->
|
<!-- 图片素材内容区域 -->
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
@@ -36,10 +36,10 @@
|
|||||||
|
|
||||||
<!-- 右侧:操作按钮 -->
|
<!-- 右侧:操作按钮 -->
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
<el-button type="success" @click="batchVerifyImage" :loading="batchLoading"> 批量校验图片 </el-button>
|
<!-- <el-button type="success" @click="batchVerifyImage" :loading="batchLoading"> 批量校验图片 </el-button> -->
|
||||||
<el-button type="primary" plain @click="pollImageResults" :loading="pollLoading">
|
<!-- <el-button type="primary" plain @click="pollImageResults" :loading="pollLoading">
|
||||||
<el-icon><Refresh /></el-icon> 刷新检测结果
|
<el-icon><Refresh /></el-icon> 刷新检测结果
|
||||||
</el-button>
|
</el-button> -->
|
||||||
<el-button type="warning" plain @click="exportImageUrls">
|
<el-button type="warning" plain @click="exportImageUrls">
|
||||||
<el-icon><Download /></el-icon> 导出失败素材
|
<el-icon><Download /></el-icon> 导出失败素材
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -71,7 +71,6 @@
|
|||||||
<el-table-column prop="description" label="描述" min-width="200"></el-table-column>
|
<el-table-column prop="description" label="描述" min-width="200"></el-table-column>
|
||||||
<el-table-column label="操作" width="160" fixed="right">
|
<el-table-column label="操作" width="160" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button size="small" type="text" @click="verifyImage(scope.row.imageId)">送检</el-button>
|
|
||||||
<el-button size="small" type="text" @click="viewLog(scope.row)">查看日志</el-button>
|
<el-button size="small" type="text" @click="viewLog(scope.row)">查看日志</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -124,10 +123,10 @@
|
|||||||
|
|
||||||
<!-- 右侧:操作按钮 -->
|
<!-- 右侧:操作按钮 -->
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
<el-button type="success" @click="batchVerifyVideo" :loading="batchLoading"> 批量校验视频 </el-button>
|
<!-- <el-button type="success" @click="batchVerifyVideo" :loading="batchLoading"> 批量校验视频 </el-button>
|
||||||
<el-button type="primary" plain @click="pollVideoResults" :loading="pollLoading">
|
<el-button type="primary" plain @click="pollVideoResults" :loading="pollLoading">
|
||||||
<el-icon><Refresh /></el-icon> 刷新检测结果
|
<el-icon><Refresh /></el-icon> 刷新检测结果
|
||||||
</el-button>
|
</el-button> -->
|
||||||
<el-button type="warning" plain @click="exportVideoUrls">
|
<el-button type="warning" plain @click="exportVideoUrls">
|
||||||
<el-icon><Download /></el-icon> 导出失败素材
|
<el-icon><Download /></el-icon> 导出失败素材
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -138,7 +137,7 @@
|
|||||||
<div class="table-wrapper">
|
<div class="table-wrapper">
|
||||||
<el-table :data="videoList" border style="width: 100%" v-loading="videoLoading">
|
<el-table :data="videoList" border style="width: 100%" v-loading="videoLoading">
|
||||||
<el-table-column prop="accountId" label="账户ID" width="120"></el-table-column>
|
<el-table-column prop="accountId" label="账户ID" width="120"></el-table-column>
|
||||||
<el-table-column label="预览" width="180">
|
<el-table-column label="预览" width="220">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div class="video-preview" @click="previewMedia(scope.row.previewUrl, 'video')">
|
<div class="video-preview" @click="previewMedia(scope.row.previewUrl, 'video')">
|
||||||
<el-icon><VideoPlay style="font-size: 32px" /></el-icon>
|
<el-icon><VideoPlay style="font-size: 32px" /></el-icon>
|
||||||
@@ -155,7 +154,6 @@
|
|||||||
<el-table-column prop="description" label="描述" min-width="200"></el-table-column>
|
<el-table-column prop="description" label="描述" min-width="200"></el-table-column>
|
||||||
<el-table-column label="操作" width="160" fixed="right">
|
<el-table-column label="操作" width="160" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button size="small" type="text" @click="verifyVideo(scope.row.videoId)">送检</el-button>
|
|
||||||
<el-button size="small" type="text" @click="viewLog(scope.row)">查看日志</el-button>
|
<el-button size="small" type="text" @click="viewLog(scope.row)">查看日志</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -179,15 +177,15 @@
|
|||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- 预览对话框 -->
|
<!-- 预览对话框 -->
|
||||||
<el-dialog title="媒体预览" v-model="previewVisible" width="60%">
|
<el-dialog title="媒体预览" v-model="previewVisible" width="60%" class="preview-dialog">
|
||||||
<div style="text-align: center">
|
<div class="preview-content">
|
||||||
<img v-if="previewType === 'image'" :src="previewUrl" style="max-width: 100%" />
|
<img v-if="previewType === 'image'" :src="previewUrl" />
|
||||||
<video v-if="previewType === 'video'" :src="previewUrl" controls style="max-width: 100%"></video>
|
<video v-if="previewType === 'video'" :src="previewUrl" controls></video>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 日志对话框 -->
|
<!-- 日志对话框 -->
|
||||||
<el-dialog title="校验日志" v-model="logVisible" width="60%">
|
<el-dialog title="校验日志" v-model="logVisible" width="70%">
|
||||||
<el-table :data="currentLogList" border style="width: 100%">
|
<el-table :data="currentLogList" border style="width: 100%">
|
||||||
<el-table-column prop="time" label="时间" width="180"></el-table-column>
|
<el-table-column prop="time" label="时间" width="180"></el-table-column>
|
||||||
<el-table-column prop="type" label="类型" width="120">
|
<el-table-column prop="type" label="类型" width="120">
|
||||||
@@ -197,7 +195,22 @@
|
|||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="message" label="日志内容"></el-table-column>
|
<el-table-column prop="status" label="状态" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
<span :class="'table-status status-' + (scope.row.status || 'info').toLowerCase()">
|
||||||
|
{{ getStatusText(scope.row.status) }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="suggestion" label="建议" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
<span :class="'table-status status-' + getSuggestionClass(scope.row.suggestion)">
|
||||||
|
{{ getSuggestionText(scope.row.suggestion) }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="errorMsg" label="错误信息" min-width="200"></el-table-column>
|
||||||
|
<el-table-column prop="message" label="日志内容" min-width="200"></el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<div v-if="!currentLogList.length" style="text-align: center; color: #909399; padding: 40px">暂无日志记录</div>
|
<div v-if="!currentLogList.length" style="text-align: center; color: #909399; padding: 40px">暂无日志记录</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -205,26 +218,28 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, onMounted } from 'vue';
|
import { ref, reactive, onMounted, watch } from 'vue';
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import { Refresh, Download, VideoPlay } from '@element-plus/icons-vue';
|
import { Download, VideoPlay } from '@element-plus/icons-vue';
|
||||||
import {
|
import {
|
||||||
getImageStats,
|
getImageStats,
|
||||||
getVideoStats,
|
getVideoStats,
|
||||||
getImageList,
|
getImageList,
|
||||||
getVideoList,
|
getVideoList,
|
||||||
manualVerifyImage,
|
getVerifyLogList,
|
||||||
manualVerifyVideo,
|
exportRejectedMaterials,
|
||||||
pollImageResults as pollImageResultsApi,
|
// manualVerifyImage,
|
||||||
pollVideoResults as pollVideoResultsApi,
|
// manualVerifyVideo,
|
||||||
batchVerifyImage as batchVerifyImageApi,
|
// pollImageResults as pollImageResultsApi,
|
||||||
batchVerifyVideo as batchVerifyVideoApi,
|
// pollVideoResults as pollVideoResultsApi,
|
||||||
|
// batchVerifyImage as batchVerifyImageApi,
|
||||||
|
// batchVerifyVideo as batchVerifyVideoApi,
|
||||||
} from '/@/api/ads/compliance/tencent/materialVerify';
|
} from '/@/api/ads/compliance/tencent/materialVerify';
|
||||||
|
|
||||||
// 响应式状态
|
// 响应式状态
|
||||||
const activeTab = ref('image');
|
const activeTab = ref('image');
|
||||||
const pollLoading = ref(false);
|
// const pollLoading = ref(false);
|
||||||
const batchLoading = ref(false);
|
// const batchLoading = ref(false);
|
||||||
|
|
||||||
// 图片统计
|
// 图片统计
|
||||||
const imageStats = reactive({ pending: 0, verified: 0, rejected: 0 });
|
const imageStats = reactive({ pending: 0, verified: 0, rejected: 0 });
|
||||||
@@ -319,14 +334,14 @@ const loadVideoList = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Tab 切换
|
// Tab 切换监听
|
||||||
const handleTabClick = (tab: any) => {
|
watch(activeTab, (newTab) => {
|
||||||
if (tab.name === 'image') {
|
if (newTab === 'image') {
|
||||||
loadImageList();
|
loadImageList();
|
||||||
} else if (tab.name === 'video') {
|
} else if (newTab === 'video') {
|
||||||
loadVideoList();
|
loadVideoList();
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
// 搜索
|
// 搜索
|
||||||
const searchImage = () => {
|
const searchImage = () => {
|
||||||
@@ -362,107 +377,123 @@ const handleVideoPageChange = (page: number) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 手动送检
|
// 手动送检
|
||||||
const verifyImage = (imageId: string) => {
|
// const verifyImage = (imageId: string) => {
|
||||||
ElMessageBox.confirm('确认提交图片 ' + imageId + ' 进行校验?', '提示', {
|
// ElMessageBox.confirm('确认提交图片 ' + imageId + ' 进行校验?', '提示', {
|
||||||
confirmButtonText: '确定',
|
// confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
// cancelButtonText: '取消',
|
||||||
type: 'warning',
|
// type: 'warning',
|
||||||
})
|
// })
|
||||||
.then(() => {
|
// .then(() => {
|
||||||
manualVerifyImage({ materialId: imageId })
|
// manualVerifyImage({ materialId: imageId })
|
||||||
.then(() => {
|
// .then(() => {
|
||||||
ElMessage.success('提交成功');
|
// ElMessage.success('提交成功');
|
||||||
loadImageList();
|
// loadImageList();
|
||||||
loadStats();
|
// loadStats();
|
||||||
})
|
// })
|
||||||
.catch(() => {});
|
// .catch(() => {});
|
||||||
})
|
// })
|
||||||
.catch(() => {});
|
// .catch(() => {});
|
||||||
};
|
// };
|
||||||
|
|
||||||
const verifyVideo = (videoId: string) => {
|
// const verifyVideo = (videoId: string) => {
|
||||||
ElMessageBox.confirm('确认提交视频 ' + videoId + ' 进行校验?', '提示', {
|
// ElMessageBox.confirm('确认提交视频 ' + videoId + ' 进行校验?', '提示', {
|
||||||
confirmButtonText: '确定',
|
// confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
// cancelButtonText: '取消',
|
||||||
type: 'warning',
|
// type: 'warning',
|
||||||
})
|
// })
|
||||||
.then(() => {
|
// .then(() => {
|
||||||
manualVerifyVideo({ materialId: videoId })
|
// manualVerifyVideo({ materialId: videoId })
|
||||||
.then(() => {
|
// .then(() => {
|
||||||
ElMessage.success('提交成功');
|
// ElMessage.success('提交成功');
|
||||||
loadVideoList();
|
// loadVideoList();
|
||||||
loadStats();
|
// loadStats();
|
||||||
})
|
// })
|
||||||
.catch(() => {});
|
// .catch(() => {});
|
||||||
})
|
// })
|
||||||
.catch(() => {});
|
// .catch(() => {});
|
||||||
};
|
// };
|
||||||
|
|
||||||
// 刷新检测结果
|
// // 刷新检测结果
|
||||||
const pollImageResults = () => {
|
// const pollImageResults = () => {
|
||||||
pollLoading.value = true;
|
// pollLoading.value = true;
|
||||||
pollImageResultsApi()
|
// pollImageResultsApi()
|
||||||
.then((res: any) => {
|
// .then((res: any) => {
|
||||||
ElMessage.success(res?.msg || '刷新完成');
|
// ElMessage.success(res?.msg || '刷新完成');
|
||||||
loadImageList();
|
// loadImageList();
|
||||||
loadStats();
|
// loadStats();
|
||||||
})
|
// })
|
||||||
.catch(() => {})
|
// .catch(() => {})
|
||||||
.finally(() => {
|
// .finally(() => {
|
||||||
pollLoading.value = false;
|
// pollLoading.value = false;
|
||||||
});
|
// });
|
||||||
};
|
// };
|
||||||
|
|
||||||
const pollVideoResults = () => {
|
// const pollVideoResults = () => {
|
||||||
pollLoading.value = true;
|
// pollLoading.value = true;
|
||||||
pollVideoResultsApi()
|
// pollVideoResultsApi()
|
||||||
.then((res: any) => {
|
// .then((res: any) => {
|
||||||
ElMessage.success(res?.msg || '刷新完成');
|
// ElMessage.success(res?.msg || '刷新完成');
|
||||||
loadVideoList();
|
// loadVideoList();
|
||||||
loadStats();
|
// loadStats();
|
||||||
})
|
// })
|
||||||
.catch(() => {})
|
// .catch(() => {})
|
||||||
.finally(() => {
|
// .finally(() => {
|
||||||
pollLoading.value = false;
|
// pollLoading.value = false;
|
||||||
});
|
// });
|
||||||
};
|
// };
|
||||||
|
|
||||||
// 导出失败素材
|
// 导出失败素材
|
||||||
const exportImageUrls = () => {
|
const exportImageUrls = () => {
|
||||||
const failedImages = imageList.value.filter((item) => item.verifyStatus === 'REJECTED');
|
ElMessage.info('正在导出图片失败素材...');
|
||||||
if (!failedImages.length) {
|
exportRejectedMaterials({ materialType: 'IMAGE' })
|
||||||
ElMessage.warning('没有失败的图片素材');
|
.then((res: any) => {
|
||||||
return;
|
if (res.data && res.data.items && res.data.items.length > 0) {
|
||||||
}
|
downloadJsonAsCsv('图片失败素材.csv', res.data.items);
|
||||||
const rows = [['ID', '图片ID', '账户ID', '用途', '预览URL', '状态', '描述']];
|
ElMessage.success('导出成功');
|
||||||
failedImages.forEach((item) => {
|
} else {
|
||||||
rows.push([
|
ElMessage.warning('没有失败的图片素材');
|
||||||
item.id,
|
}
|
||||||
item.imageId,
|
})
|
||||||
item.accountId,
|
.catch(() => {
|
||||||
item.imageUsage,
|
ElMessage.error('导出失败');
|
||||||
item.previewUrl || '-',
|
});
|
||||||
getStatusText(item.verifyStatus),
|
|
||||||
item.description || '-',
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
downloadCsv('图片失败素材.csv', rows);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const exportVideoUrls = () => {
|
const exportVideoUrls = () => {
|
||||||
const failedVideos = videoList.value.filter((item) => item.verifyStatus === 'REJECTED');
|
ElMessage.info('正在导出视频失败素材...');
|
||||||
if (!failedVideos.length) {
|
exportRejectedMaterials({ materialType: 'VIDEO' })
|
||||||
ElMessage.warning('没有失败的视频素材');
|
.then((res: any) => {
|
||||||
return;
|
if (res.data && res.data.items && res.data.items.length > 0) {
|
||||||
}
|
downloadJsonAsCsv('视频失败素材.csv', res.data.items);
|
||||||
const rows = [['ID', '视频ID', '账户ID', '预览URL', '状态', '描述']];
|
ElMessage.success('导出成功');
|
||||||
failedVideos.forEach((item) => {
|
} else {
|
||||||
rows.push([item.id, item.videoId, item.accountId, item.previewUrl || '-', getStatusText(item.verifyStatus), item.description || '-']);
|
ElMessage.warning('没有失败的视频素材');
|
||||||
});
|
}
|
||||||
downloadCsv('视频失败素材.csv', rows);
|
})
|
||||||
|
.catch(() => {
|
||||||
|
ElMessage.error('导出失败');
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const downloadCsv = (filename: string, rows: string[][]) => {
|
const downloadJsonAsCsv = (filename: string, items: any[]) => {
|
||||||
|
const headers = ['ID', '素材ID', '账户ID', '公司名称', '预览URL', '描述', '错误信息', '素材类型', '图片用途', '创建时间'];
|
||||||
|
const rows = [headers];
|
||||||
|
|
||||||
|
items.forEach((item) => {
|
||||||
|
rows.push([
|
||||||
|
item.id,
|
||||||
|
item.materialId,
|
||||||
|
item.accountId,
|
||||||
|
item.corporationName || '-',
|
||||||
|
(item.previewUrl || '').trim(),
|
||||||
|
item.description || '-',
|
||||||
|
item.errorMsg || '-',
|
||||||
|
item.materialType || '-',
|
||||||
|
item.imageUsage || '-',
|
||||||
|
item.createdAt || '-',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
const csv = rows.map((r) => r.map((v) => `"${String(v).replace(/"/g, '""')}"`).join(',')).join('\n');
|
const csv = rows.map((r) => r.map((v) => `"${String(v).replace(/"/g, '""')}"`).join(',')).join('\n');
|
||||||
const blob = new Blob(['\uFEFF' + csv], { type: 'text/csv;charset=utf-8;' });
|
const blob = new Blob(['\uFEFF' + csv], { type: 'text/csv;charset=utf-8;' });
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
@@ -475,49 +506,49 @@ const downloadCsv = (filename: string, rows: string[][]) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 批量送检
|
// 批量送检
|
||||||
const batchVerifyImage = () => {
|
// const batchVerifyImage = () => {
|
||||||
ElMessageBox.confirm('确认批量校验待处理的图片?', '提示', {
|
// ElMessageBox.confirm('确认批量校验待处理的图片?', '提示', {
|
||||||
confirmButtonText: '确定',
|
// confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
// cancelButtonText: '取消',
|
||||||
type: 'warning',
|
// type: 'warning',
|
||||||
})
|
// })
|
||||||
.then(() => {
|
// .then(() => {
|
||||||
batchLoading.value = true;
|
// batchLoading.value = true;
|
||||||
batchVerifyImageApi()
|
// batchVerifyImageApi()
|
||||||
.then((res: any) => {
|
// .then((res: any) => {
|
||||||
ElMessage.success(res?.msg || '批量校验完成');
|
// ElMessage.success(res?.msg || '批量校验完成');
|
||||||
loadImageList();
|
// loadImageList();
|
||||||
loadStats();
|
// loadStats();
|
||||||
})
|
// })
|
||||||
.catch(() => {})
|
// .catch(() => {})
|
||||||
.finally(() => {
|
// .finally(() => {
|
||||||
batchLoading.value = false;
|
// batchLoading.value = false;
|
||||||
});
|
// });
|
||||||
})
|
// })
|
||||||
.catch(() => {});
|
// .catch(() => {});
|
||||||
};
|
// };
|
||||||
|
|
||||||
const batchVerifyVideo = () => {
|
// const batchVerifyVideo = () => {
|
||||||
ElMessageBox.confirm('确认批量校验待处理的视频?', '提示', {
|
// ElMessageBox.confirm('确认批量校验待处理的视频?', '提示', {
|
||||||
confirmButtonText: '确定',
|
// confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
// cancelButtonText: '取消',
|
||||||
type: 'warning',
|
// type: 'warning',
|
||||||
})
|
// })
|
||||||
.then(() => {
|
// .then(() => {
|
||||||
batchLoading.value = true;
|
// batchLoading.value = true;
|
||||||
batchVerifyVideoApi()
|
// batchVerifyVideoApi()
|
||||||
.then((res: any) => {
|
// .then((res: any) => {
|
||||||
ElMessage.success(res?.msg || '批量校验完成');
|
// ElMessage.success(res?.msg || '批量校验完成');
|
||||||
loadVideoList();
|
// loadVideoList();
|
||||||
loadStats();
|
// loadStats();
|
||||||
})
|
// })
|
||||||
.catch(() => {})
|
// .catch(() => {})
|
||||||
.finally(() => {
|
// .finally(() => {
|
||||||
batchLoading.value = false;
|
// batchLoading.value = false;
|
||||||
});
|
// });
|
||||||
})
|
// })
|
||||||
.catch(() => {});
|
// .catch(() => {});
|
||||||
};
|
// };
|
||||||
|
|
||||||
// 预览
|
// 预览
|
||||||
const previewMedia = (url: string, type: string) => {
|
const previewMedia = (url: string, type: string) => {
|
||||||
@@ -541,17 +572,94 @@ const getStatusText = (status: string) => {
|
|||||||
return map[status] || status || '待校验';
|
return map[status] || status || '待校验';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 解析响应结果
|
||||||
|
const parseResponseResult = (responseResult: string) => {
|
||||||
|
try {
|
||||||
|
const result = JSON.parse(responseResult);
|
||||||
|
if (result.antispam && result.antispam.riskDescription) {
|
||||||
|
return result.antispam.riskDescription;
|
||||||
|
}
|
||||||
|
if (result.riskDescription) {
|
||||||
|
return result.riskDescription;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// 解析失败,返回原始字符串
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
};
|
||||||
|
|
||||||
// 查看日志
|
// 查看日志
|
||||||
const viewLog = (row: any) => {
|
const viewLog = (row: any) => {
|
||||||
// 模拟日志数据
|
const materialId = row.imageId || row.videoId;
|
||||||
currentLogList.value = [
|
const materialType = row.imageId ? 'IMAGE' : 'VIDEO';
|
||||||
{ time: new Date().toLocaleString('zh-CN'), type: 'INFO', message: '素材已创建' },
|
|
||||||
{ time: new Date().toLocaleString('zh-CN'), type: 'INFO', message: '开始校验流程' },
|
getVerifyLogList({
|
||||||
{ time: new Date().toLocaleString('zh-CN'), type: 'SUCCESS', message: `校验完成,结果:${getStatusText(row.verifyStatus)}` },
|
page: 1,
|
||||||
];
|
pageSize: 100,
|
||||||
|
materialId,
|
||||||
|
materialType,
|
||||||
|
})
|
||||||
|
.then((res: any) => {
|
||||||
|
if (res.data && res.data.list && res.data.list.length > 0) {
|
||||||
|
currentLogList.value = res.data.list.map((item: any) => {
|
||||||
|
const riskDesc = parseResponseResult(item.responseResult);
|
||||||
|
return {
|
||||||
|
time: item.createdAt || '-',
|
||||||
|
type: item.verifyStatus === 'REJECTED' ? 'ERROR' : 'SUCCESS',
|
||||||
|
status: item.verifyStatus,
|
||||||
|
suggestion: item.suggestion,
|
||||||
|
errorMsg: item.errorMsg || '-',
|
||||||
|
message: riskDesc || `校验状态:${getStatusText(item.verifyStatus)}`,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
currentLogList.value = [
|
||||||
|
{
|
||||||
|
time: row.createdAt || new Date().toLocaleString('zh-CN'),
|
||||||
|
type: row.verifyStatus === 'REJECTED' ? 'ERROR' : 'SUCCESS',
|
||||||
|
status: row.verifyStatus,
|
||||||
|
suggestion: row.suggestion,
|
||||||
|
errorMsg: row.errorMsg || '-',
|
||||||
|
message: `校验完成,结果:${getStatusText(row.verifyStatus)}`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
currentLogList.value = [
|
||||||
|
{
|
||||||
|
time: row.createdAt || new Date().toLocaleString('zh-CN'),
|
||||||
|
type: row.verifyStatus === 'REJECTED' ? 'ERROR' : 'SUCCESS',
|
||||||
|
status: row.verifyStatus,
|
||||||
|
suggestion: row.suggestion,
|
||||||
|
errorMsg: row.errorMsg || '-',
|
||||||
|
message: `校验完成,结果:${getStatusText(row.verifyStatus)}`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
logVisible.value = true;
|
logVisible.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 获取建议文本
|
||||||
|
const getSuggestionText = (suggestion: number) => {
|
||||||
|
const map: Record<number, string> = {
|
||||||
|
0: '通过',
|
||||||
|
1: '建议通过',
|
||||||
|
2: '建议删除',
|
||||||
|
3: '建议删除',
|
||||||
|
};
|
||||||
|
return map[suggestion] ?? '-';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取建议样式类
|
||||||
|
const getSuggestionClass = (suggestion: number) => {
|
||||||
|
if (suggestion === 0) return 'success';
|
||||||
|
if (suggestion === 1) return 'info';
|
||||||
|
if (suggestion === 2 || suggestion === 3) return 'rejected';
|
||||||
|
return 'info';
|
||||||
|
};
|
||||||
|
|
||||||
// 获取日志类型文本
|
// 获取日志类型文本
|
||||||
const getLogTypeText = (type: string) => {
|
const getLogTypeText = (type: string) => {
|
||||||
const map: Record<string, string> = {
|
const map: Record<string, string> = {
|
||||||
@@ -751,4 +859,26 @@ onMounted(() => {
|
|||||||
color: #606266;
|
color: #606266;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.preview-dialog {
|
||||||
|
:deep(.el-dialog__body) {
|
||||||
|
padding: 16px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
max-height: calc(80vh - 120px);
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
img,
|
||||||
|
video {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: calc(80vh - 120px);
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user