YouKeChuanMei_VUE/src/views/mediaTool/pptAnalysisIndex.vue
2025-09-18 23:40:09 +08:00

346 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<el-card>
<template #header>
<div class="card-header">
<span>{{ formTitle }}</span>
<el-icon style="float: right;cursor: pointer;" @click="handleClose">
<Close />
</el-icon>
</div>
</template>
<div class="tool-content">
<el-row :gutter="20" style="margin: 0 -10px 30px -10px;">
<el-col :span="12">
<div class="toolItemTitle mb20">上传文件</div>
<el-upload class="my-upload-demo" drag action="#" :http-request="requestDocUpload"
:file-list="docUploadList" :before-upload="beforeDocUpload" :on-remove="removeDocUpload">
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">
<span class="upload_tip">将文件拖曳至此区域</span> <em>点击上传</em>
</div>
<div class="el-upload__text">
支持扩展名.pptx
</div>
</el-upload>
</el-col>
<el-col :span="12">
<div class="toolItemTitle mb20">使用统计</div>
<el-form ref="detailFormRef" :model="detailForm" label-width="160px" class="myUsingDetail">
<div class="splineBar" />
<el-form-item label="处理PPT文件数">
{{ detailForm.analysis_statistics.unique_tools }}
</el-form-item>
<div class="splineBar" />
<el-form-item label="提取图片总数">
{{ detailForm.analysis_statistics.total_images }}
</el-form-item>
<div class="splineBar" />
<el-form-item label="生成报告总数">
{{ detailForm.task_statistics.completed_tasks }}
</el-form-item>
<div class="splineBar" />
<el-form-item label="生成失败报告数量">
{{ detailForm.task_statistics.failed_tasks }}
</el-form-item>
<div class="splineBar" />
<el-form-item label="Adobe图片数量">
{{ detailForm.analysis_statistics.adobe_images }}
</el-form-item>
<div class="splineBar" />
</el-form>
</el-col>
</el-row>
<div class="toolItemTitle mb20">
任务记录
<el-icon class="refreshIcon" @click="getTaskRecordPageList">
<Refresh />
</el-icon>
</div>
<el-table v-loading="loading" :data="taskList" height="calc(100% - 422px)">
<el-table-column label="序号" align="center" width="80">
<template #default="scope">
{{ scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column label="文件名称" align="left" prop="file_name" min-width="180"
:show-overflow-tooltip="true" />
<el-table-column label="任务进度" align="center" prop="progress" min-width="150">
<template #default="scope">
<el-progress class="myprogress" type="circle"
:percentage="scope.row.progress == null ? 0 : scope.row.progress" :width="40"
:stroke-width="2" :color="colors" />
</template>
</el-table-column>
<el-table-column label="操作时间" align="center" prop="completed_at" width="210">
<template #default="scope">
<span>{{ parseTime(scope.row.completed_at) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" :width="160" align="center">
<template #default="scope">
<el-button v-if="scope.row.progress == 100" link type="primary"
@click="handleResultOption(scope.row)">
导出结果
</el-button>
<el-button link type="primary" @click="handleDeleteTask(scope.row)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination :total="total" v-model:page="queryParams.page" v-model:limit="queryParams.per_page"
@pagination="getTaskRecordPageList" />
</div>
</el-card>
</div>
</template>
<script setup>
import { onMounted, nextTick, defineEmits, ref } from 'vue'
import { Close } from '@element-plus/icons-vue'
import { uploadPPTAnalysisFile, pptAnalysisTaskPageList, pptAnalysisStatistics, deletePPTAnalysisTask, exportPPTAnalysisReport } from "@/api/pptAnalysis"
const { proxy } = getCurrentInstance()
const emit = defineEmits(['handleGoBack']);
const baseUrl = import.meta.env.VITE_APP_BASE_API
const formTitle = ref('')
const detailForm = ref({
analysis_statistics: {},
task_statistics: {}
})
// 上传文件列表
const docUploadList = ref([])
// 进度条颜色设置
const colors = [
{ color: '#EDEDED', percentage: 0 },
{ color: '#FFC63D', percentage: 99 },
{ color: '#ADE8BD', percentage: 100 },
]
// 任务列表
const taskList = ref([])
const total = ref(0)
const loading = ref(false)
const data = reactive({
queryParams: {
page: 1,
per_page: 10
}
})
const { queryParams } = toRefs(data)
// 自定义上传经纬度文件
const requestDocUpload = (options) => {
const { file } = options
var formData = new FormData();
formData.append('file', file);
proxy.$modal.loading('正在上传文件,请耐心等待...')
uploadPPTAnalysisFile(formData).then(res => {
proxy.$modal.msgSuccess("上传成功")
proxy.$modal.closeLoading()
docUploadList.value = []
getTaskRecordPageList()
}).catch(res => {
proxy.$modal.msgError(res.msg);
proxy.$modal.closeLoading()
})
}
//自定义上传文件资料校验
const beforeDocUpload = (file) => {
const type = [
'application/vnd.openxmlformats-officedocument.presentationml.presentation'
];
const isXlsx = type.includes(file.type);
// 检验文件格式
if (!isXlsx) {
proxy.$modal.msgError("文件格式错误,请上传.pptx后缀的文件。");
return false;
}
}
// 移除已上传文件列表
const removeDocUpload = (file, fileList) => {
docUploadList.value = docUploadList.value.filter(
item => item.name != file.name
);
}
// 删除任务
const handleDeleteTask = (row) => {
proxy.$modal.confirm('是否确认该任务?').then(function () {
return deletePPTAnalysisTask(row.task_id)
}).then(() => {
getTaskRecordPageList()
proxy.$modal.msgSuccess("删除成功")
}).catch(() => { })
}
// 结果操作
const handleResultOption = (row) => {
if (row.progress == 0) {
return
}
exportPPTAnalysisReport(row.task_id).then(res => {
const downLoadName = 'PPT分析结果_' + getCurrentTime() + '.xlsx'
// 通过a标签打开新页面下载文件
const a = document.createElement('a')
a.href = URL.createObjectURL(res)
// a标签里有download属性可以自定义文件名
a.setAttribute('download', downLoadName)
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
})
}
const getCurrentTime = () => {
//获取当前时间并打印
var getTime = new Date().getTime(); //获取到当前时间戳
var time = new Date(getTime); //创建一个日期对象
var year = time.getFullYear(); // 年
var month = (time.getMonth() + 1).toString().padStart(2, '0'); // 月
var date = time.getDate().toString().padStart(2, '0'); // 日
var hour = time.getHours().toString().padStart(2, '0'); // 时
var minute = time.getMinutes().toString().padStart(2, '0'); // 分
var second = time.getSeconds().toString().padStart(2, '0'); // 秒
var gettime = year + month + date + hour + minute + second
return gettime
}
// 获取使用统计
const getStatistics = () => {
pptAnalysisStatistics().then(res => {
detailForm.value = res
})
}
// 获取分析任务列表
const getTaskRecordPageList = () => {
loading.value = true
pptAnalysisTaskPageList(queryParams.value).then(res => {
taskList.value = res.tasks
total.value = res.pagination.total
loading.value = false
})
}
// 关闭
const handleClose = () => {
emit('handleGoBack')
}
// 初始化
const initTool = () => {
formTitle.value = 'PPT分析工具'
getStatistics()
getTaskRecordPageList()
}
// 暴露方法\属性给父组件
defineExpose({
initTool
});
</script>
<style lang="scss">
.tool-content {
width: 100%;
padding: 30px 20% 10px;
height: calc(100vh - 180px);
overflow-y: auto;
}
.toolItemTitle {
position: relative;
width: 100%;
height: 40px;
line-height: 40px;
font-family: Microsoft YaHei;
font-weight: 600;
font-size: 22px;
text-align: left;
color: #1E1E1E;
padding-left: 20px;
}
.toolItemTitle::before {
content: "";
position: absolute;
left: 0px;
top: -4px;
width: 8px;
height: 8px;
border-radius: 2px;
color: #ffc63d;
}
.my-upload-demo .el-upload-dragger {
background: #0090ff05;
border: 1px dashed #1A75E6;
border-radius: 6px;
}
.my-upload-demo .upload_tip {
font-family: Microsoft YaHei;
font-weight: 400;
font-size: 18px;
color: #000000;
}
.my-upload-demo em {
font-family: Microsoft YaHei;
font-weight: 400;
font-size: 18px;
color: #1A75E6;
}
.my-upload-demo .el-upload__text {
font-family: Microsoft YaHei;
font-weight: 400;
font-size: 16px;
color: #8C8C8C;
}
.myprogress .el-progress__text {
min-width: 40px !important;
}
.myprogress .el-progress__text span {
font-family: Arial;
font-weight: 700;
font-size: 14px;
color: #8F8F8F;
}
.mybadge1 .el-badge__content.is-dot {
width: 6px;
height: 6px;
background-color: #126601;
margin-right: 10px;
}
.myMedioStatus1 {
font-family: Microsoft YaHei;
font-weight: 400;
font-size: 16px;
color: #126601;
}
.mybadge2 .el-badge__content.is-dot {
width: 6px;
height: 6px;
background-color: #E12500;
margin-right: 10px;
}
.myMedioStatus2 {
font-family: Microsoft YaHei;
font-weight: 400;
font-size: 16px;
color: #E12500;
}
// 分割线
.splineBar {
width: 100%;
height: 1px;
background: #D9DFE5;
}
</style>