<template>
|
<div class="achievement-data">
|
<van-list
|
v-model:loading="loading"
|
:finished="finished"
|
:error="error"
|
error-text="加载失败,点击重新加载"
|
@load="getList"
|
>
|
<div class="achievements">
|
<div class="card" v-for="item in list" :key="item.id">
|
<div class="bg-img">
|
<van-checkbox v-model="item.checked" shape="square"></van-checkbox>
|
<van-image v-if="item.extension.includes('jpeg')" :src="item.smallUrl" fit="cover" />
|
|
<div class="video-content" v-if="item.extension.includes('mp4')" @click="showImagePreviews(item)">
|
<div class="shade"></div>
|
|
<div class="paly-icon"></div>
|
|
<img class="videoDisplay" :src="convertVideoUrlToThumbnail(item.link)" alt="" />
|
</div>
|
</div>
|
<div class="title">{{ item.eventName || item.nickName }}</div>
|
<div class="time-sf">
|
<div class="time">
|
<span v-if="item.status === 0" style="background-color: #ff7411"></span>
|
<span v-else-if="item.status === 2" style="background-color: #ff472f"></span>
|
<span v-else-if="item.status === 3" style="background-color: #ffc300"></span>
|
<span v-else-if="item.status === 4" style="background-color: #06d957"></span>
|
{{ formatDate(item.createTime) }}
|
</div>
|
<div class="sf" @click="showImagePreviews(item)"><img :src="sfSvg" alt="" /></div>
|
</div>
|
</div>
|
</div>
|
</van-list>
|
<van-empty v-if="!loading && list.length === 0" description="暂无数据" />
|
<div class="btns" v-if="list.length > 0">
|
<van-button class="btn all-checked" round block type="primary" color="#00994D" @click="AllChecked">
|
{{ isAllChecked ? '取消全选' : '全选' }}
|
</van-button>
|
<van-button class="btn down-load" round block type="primary" color="#1D6FE9" @click="downLoad">下载</van-button>
|
</div>
|
<van-dialog v-model:show="showDialog" :show-confirm-button="false" :show-cancel-button="false">
|
<template #title>
|
<div class="custom-header">
|
<van-icon name="cross" class="close-icon" @click="showDialog = false" />
|
</div>
|
</template>
|
<div class="dialog-content">
|
<video class="video-player" ref="videoRefs" controls :src="videoUrl" preload="auto"
|
@play="handleVideoPlay"
|
@ended="handleVideoEnded">
|
<source :src="videoUrl" type="video/mp4" />
|
</video>
|
</div>
|
</van-dialog>
|
</div>
|
</template>
|
<script setup>
|
import sfSvg from '@/appDataSource/inspectionTask/sf.svg'
|
import { aiImagesPage, getDownloadStatusApi, attachDownload } from '@/api/dataCenter'
|
import { getShowImg, getSmallImg, getzsSmallImg, getzsShowImg, aLinkDownloadUtil } from '@/utils/util'
|
import { getJobDetails } from '@/api/home/task'
|
import { showImagePreview, showNotify, showLoadingToast, closeToast } from 'vant'
|
import dayjs from 'dayjs'
|
import { ref } from 'vue'
|
import { useRoute } from 'vue-router'
|
const route = useRoute()
|
|
const props = defineProps(['wayLineJobInfoId'])
|
const currentIndex = ref(null)
|
const imageArr = ref([])
|
const total = ref(0)
|
const loading = ref(false)
|
const finished = ref(false)
|
const error = ref(false)
|
const list = ref([])
|
const videoRefs = ref(null)
|
const emit = defineEmits(['returnNum'])
|
// 视频播放事件处理
|
const handleVideoPlay = (event) => {
|
if (event.target.playbackRate !== 0.75) {
|
event.target.playbackRate = 0.75
|
|
}
|
}
|
const handleVideoEnded = index => {
|
// 获取当前视频
|
const video = videoRefs.value
|
|
// 重置视频播放时间为 0
|
video.currentTime = 0
|
|
// 重新加载视频
|
video.load()
|
}
|
const detailsObj = inject('detailsObj')
|
function getList() {
|
loading.value = true
|
// getJobDetails({ wayLineJobInfoId: props.wayLineJobInfoId, waylineJobId: route.query.waylineJobId, batchNo: route.query.batch_no }).then(async res => {
|
aiImagesPage({
|
wayLineJobId: detailsObj.value.job_id,
|
resultTypes: [0, 1, 2, 4, 5],
|
orderByCreateTime: true,
|
current: 1,
|
size: 2000,
|
}).then(res => {
|
if (res.data.data.records.length > 0) {
|
list.value = res.data.data.records.map(i => ({
|
...i,
|
checked: false,
|
smallUrl: i.resultType === 4 ? getzsSmallImg(i.link) : getSmallImg(i.link),
|
showUrl: i.resultType === 4 ? getzsShowImg(i.link) : getShowImg(i.link),
|
}))
|
total.value = res.data.data.total
|
imageArr.value = list.value.filter(item => item.extension.includes('jpeg')).map(item => item.showUrl)
|
}
|
// 检查是否加载完成
|
if (list.value.length >= res.data.data.total) {
|
finished.value = true
|
}
|
loading.value = false
|
})
|
// })
|
}
|
const isAllChecked = ref(false)
|
function AllChecked() {
|
isAllChecked.value = !isAllChecked.value
|
list.value = list.value.map(i => ({
|
...i,
|
checked: isAllChecked.value ? true : false,
|
}))
|
}
|
function showImagePreviews(val) {
|
console.log(val.extension)
|
if (val.extension.includes('jpeg')) {
|
currentIndex.value = list.value.findIndex(item => item.event_num === val.event_num)
|
showImagePreview({
|
images: imageArr.value,
|
startPosition: currentIndex.value,
|
})
|
} else {
|
clickVideo(val)
|
}
|
}
|
const formatDate = dateString => {
|
return dayjs(dateString).format('MM/DD HH:mm')
|
}
|
// 下载
|
async function downLoad() {
|
const checkedList = list.value.filter(i => i.checked)
|
if (checkedList.length === 0) {
|
return showNotify({ type: 'warning', message: '请选择要下载的图片' })
|
}
|
for (let i = 0; i < checkedList.length; i++) {
|
const item = checkedList[i]
|
const suffix = item.link.split('.').pop()
|
|
await new Promise(resolve => {
|
setTimeout(() => {
|
aLinkDownloadUtil(item.link, item.nickName + '.' + suffix)
|
resolve()
|
}, 1000) // 1秒间隔
|
})
|
}
|
// checkedList.forEach((item, index) => {
|
// const suffix = item.link.split('.').pop()
|
// aLinkDownloadUtil(item.link, item.nickName + '.' + suffix)
|
// })
|
// if (checkedList.length === 1) {
|
//
|
// } else {
|
// // 显示加载
|
// showLoadingToast({
|
// duration: 0, // 持续显示,不会自动关闭
|
// forbidClick: true, // 禁止背景点击
|
// message: '打包中,请稍等...',
|
// overlay: true, // 显示遮罩层
|
// background: 'rgba(0, 0, 0, 0.5)',
|
// });
|
// const fileIds = checkedList.map(i => i.id)
|
// const res = await getDownloadStatusApi({ type: 'dpsjzx' })
|
//
|
// if (!['CANCELLED', 'COMPLETED'].includes(res.data.data?.status || 'COMPLETED')) {
|
// return showNotify({ type: 'warning', message: '还有正在处理的' })
|
// }
|
// attachDownload({ attachIds: fileIds, type: 'dplsrwxq' }).finally(() => {
|
// closeToast();
|
// })
|
// }
|
}
|
const showDialog = ref(false)
|
let videoUrl = ref('')
|
function clickVideo(item) {
|
showDialog.value = true
|
videoUrl = item.link
|
}
|
|
function convertVideoUrlToThumbnail(videoUrl) {
|
// 检查是否是有效的视频URL
|
if (!videoUrl || typeof videoUrl !== 'string') {
|
return videoUrl
|
}
|
// 替换文件扩展名
|
return videoUrl.replace(/\.mp4$/, '_small.jpg')
|
}
|
|
watch(detailsObj, (newVal) => {
|
getList()
|
})
|
|
onMounted(() => {
|
// getList()
|
})
|
</script>
|
|
<style lang="scss" scoped>
|
.achievement-data {
|
margin: 12px;
|
.achievements {
|
//margin: 10px 0;
|
display: flex;
|
flex-wrap: wrap;
|
gap: 10px;
|
.card {
|
width: calc((100vw - 12px - 12px - 10px) / 2);
|
height: 146px;
|
background: #ffffff;
|
border-radius: 6px 6px 6px 6px;
|
.bg-img {
|
width: calc((100vw - 12px - 12px - 10px) / 2);
|
height: 98px;
|
margin-bottom: 4px;
|
position: relative;
|
:deep(.van-checkbox__icon .van-icon) {
|
border-radius: 4px 4px 4px 4px;
|
border: 1px solid #ffffff;
|
}
|
.van-checkbox {
|
position: absolute;
|
top: 7px;
|
left: 9px;
|
background: rgba(86, 86, 86, 0.4);
|
backdrop-filter: blur(0.4rem);
|
z-index: 1;
|
}
|
:deep(.van-image) {
|
width: 100%;
|
height: 100%;
|
border-radius: 6px 6px 6px 6px;
|
img {
|
border-radius: 6px 6px 6px 6px;
|
}
|
}
|
.videoDisplay {
|
width: 100%;
|
height: 100%;
|
border-radius: 6px 6px 6px 6px;
|
object-fit: cover;
|
}
|
}
|
|
.video-content {
|
position: relative;
|
width: 100%;
|
height: 100%;
|
border-radius: 6px 6px 6px 6px;
|
overflow: hidden;
|
|
.shade {
|
position: absolute;
|
top: 0;
|
left: 0;
|
width: 100%;
|
height: 100%;
|
background: rgba(26, 26, 26, 0.25);
|
}
|
|
.paly-icon {
|
position: absolute;
|
top: 50%;
|
left: 50%;
|
width: 42px;
|
height: 42px;
|
background: url('@/appDataSource/inspectionTask/video-play.png') no-repeat center / 100% 100%;
|
transform: translate(-50%, -50%);
|
}
|
|
.videoDisplay {
|
width: 100%;
|
height: 100%;
|
object-fit: cover;
|
}
|
}
|
|
.title {
|
padding: 0 4px;
|
font-weight: 500;
|
font-size: 14px;
|
color: #000000;
|
white-space: nowrap; /* 不换行 */
|
overflow: hidden; /* 超出隐藏 */
|
text-overflow: ellipsis; /* 显示省略号 */
|
}
|
.time-sf {
|
padding: 0 4px;
|
display: flex;
|
justify-content: space-between;
|
.time {
|
font-size: 12px;
|
span {
|
display: inline-block;
|
width: 8px;
|
height: 8px;
|
border-radius: 50%;
|
margin-right: 4px;
|
}
|
color: #a6a6a6;
|
}
|
}
|
}
|
}
|
.btns {
|
position: fixed;
|
bottom: 10px;
|
left: 10px;
|
right: 10px;
|
display: flex;
|
gap: 10px;
|
z-index: 1000;
|
.all-checked {
|
width: 30%;
|
}
|
.down-load {
|
width: 68%;
|
}
|
}
|
:deep(.van-dialog) {
|
width: 100vw;
|
background-color: rgba(33, 33, 33, 0.8);
|
.custom-header {
|
position: absolute;
|
top: 0;
|
.close-icon {
|
position: fixed;
|
top: 6px;
|
right: 10px;
|
color: white;
|
}
|
border: 1px solid #e4e7ed;
|
}
|
.dialog-content {
|
height: 200px;
|
position: relative;
|
.video-player {
|
width: 100%;
|
height: 100%;
|
}
|
}
|
}
|
}
|
</style>
|