<template>
|
<view>
|
<!-- 弹窗 -->
|
<u-popup
|
:show="dialogVisitable"
|
mode="center"
|
border-radius="20"
|
@close="cancel"
|
:closeable="true"
|
:customStyle="{
|
width: '92vw',
|
maxWidth: '720rpx',
|
height: '82vh'
|
}"
|
>
|
<view class="popup-content">
|
<view class="popup-header">
|
<text class="popup-title">查看附件</text>
|
</view>
|
|
<view class="upload-container">
|
<view class="form-container">
|
<view class="title">巡检附件</view>
|
|
<!-- 图片列表 -->
|
<view v-if="beforeProductionImgs.length > 0" class="media-section">
|
<view class="section-title">图片</view>
|
<view class="image-grid">
|
<view
|
v-for="(item, index) in beforeProductionImgs"
|
:key="index"
|
class="image-item"
|
@click="previewImage(item, index)"
|
>
|
<image
|
:src="item"
|
mode="aspectFill"
|
class="image-preview"
|
/>
|
</view>
|
</view>
|
</view>
|
|
<!-- 视频列表 -->
|
<view v-if="beforeProductionVideos.length > 0" class="media-section">
|
<view class="section-title">视频</view>
|
<view class="video-grid">
|
<view
|
v-for="(videoUrl, index) in beforeProductionVideos"
|
:key="index"
|
class="video-item"
|
@click="playVideo(videoUrl, index)"
|
>
|
<video
|
:src="videoUrl"
|
class="video-thumbnail"
|
:poster="videoUrl"
|
:controls="false"
|
:show-center-play-btn="true"
|
@play="onVideoPlay"
|
></video>
|
<view class="video-overlay">
|
<u-icon name="play-circle-fill" size="40" color="#fff"></u-icon>
|
</view>
|
</view>
|
</view>
|
</view>
|
|
<!-- 视频播放弹窗 -->
|
<u-popup
|
:show="showVideoPlayer"
|
mode="center"
|
width="100%"
|
height="100%"
|
:closeable="true"
|
@close="closeVideoPlayer"
|
:safeAreaInsetBottom="false"
|
>
|
<view class="video-player-container">
|
<video
|
v-if="currentVideoUrl"
|
:src="currentVideoUrl"
|
class="video-player"
|
:controls="true"
|
:show-center-play-btn="true"
|
:enable-play-gesture="true"
|
:show-fullscreen-btn="true"
|
:enable-progress-gesture="true"
|
:object-fit="'contain'"
|
@fullscreenchange="onFullscreenChange"
|
></video>
|
</view>
|
</u-popup>
|
|
<!-- 空状态 -->
|
<view v-if="beforeProductionImgs.length === 0 && beforeProductionVideos.length === 0" class="empty-state">
|
<u-empty
|
mode="data"
|
text="暂无附件"
|
:iconSize="60"
|
></u-empty>
|
</view>
|
</view>
|
</view>
|
</view>
|
</u-popup>
|
</view>
|
</template>
|
|
<script setup>
|
import { ref, onUnmounted } from 'vue'
|
|
// 控制弹窗显示
|
const dialogVisitable = ref(false)
|
// 图片数组
|
const beforeProductionImgs = ref([])
|
// 视频数组
|
const beforeProductionVideos = ref([])
|
// 视频播放器
|
const showVideoPlayer = ref(false)
|
const currentVideoUrl = ref('')
|
|
// 打开弹窗并加载数据
|
const openDialog = async (row) => {
|
console.log('打开附件查看弹窗,数据:', row)
|
|
// 处理数据,分离图片和视频
|
const { images: beforeImgs, videos: beforeVids } = processItems(row.storageBlobDTO || [])
|
|
beforeProductionImgs.value = beforeImgs
|
beforeProductionVideos.value = beforeVids
|
dialogVisitable.value = true
|
}
|
|
// 预览图片
|
const previewImage = (url, index) => {
|
uni.previewImage({
|
urls: beforeProductionImgs.value,
|
current: index,
|
fail: (err) => {
|
console.error('图片预览失败:', err)
|
uni.showToast({
|
title: '图片预览失败',
|
icon: 'error'
|
})
|
}
|
})
|
}
|
|
// 播放视频
|
const playVideo = (url, index) => {
|
currentVideoUrl.value = url
|
showVideoPlayer.value = true
|
}
|
|
// 关闭视频播放器
|
const closeVideoPlayer = () => {
|
showVideoPlayer.value = false
|
currentVideoUrl.value = ''
|
}
|
|
// 视频播放事件
|
const onVideoPlay = () => {
|
// 可以在这里处理播放事件
|
}
|
|
// 全屏变化事件
|
const onFullscreenChange = (e) => {
|
console.log('全屏状态变化:', e)
|
// 如果退出全屏,可以选择关闭弹窗
|
if (e.detail && e.detail.fullScreen === false) {
|
// 可以选择保持弹窗打开或关闭
|
}
|
}
|
|
// 表单关闭方法
|
const cancel = () => {
|
dialogVisitable.value = false
|
// 重置数据
|
beforeProductionImgs.value = []
|
beforeProductionVideos.value = []
|
}
|
|
// 处理URL,添加基础域名
|
function formatUrl(url) {
|
if (!url) return ''
|
// 如果已经是完整URL,直接返回
|
if (url.startsWith('http://') || url.startsWith('https://')) {
|
return url
|
}
|
// 否则添加基础域名
|
return `https://nj477vg8876.vicp.fun${url.startsWith('/') ? '' : '/'}${url}`
|
}
|
|
// 处理每一类数据:分离图片和视频
|
function processItems(items) {
|
if (!items || !Array.isArray(items)) {
|
return { images: [], videos: [] }
|
}
|
|
const images = []
|
const videos = []
|
|
items.forEach(item => {
|
const fileUrl = item.url || item.downloadUrl || item.fileUrl
|
if (!fileUrl) return
|
|
const fullUrl = formatUrl(fileUrl)
|
|
if (item.contentType?.startsWith('image/')) {
|
images.push(fullUrl)
|
} else if (item.contentType?.startsWith('video/')) {
|
videos.push(fullUrl)
|
}
|
})
|
|
return { images, videos }
|
}
|
|
// 组件销毁时的清理
|
onUnmounted(() => {
|
// 关闭弹窗
|
dialogVisitable.value = false
|
// 清理数据
|
beforeProductionImgs.value = []
|
beforeProductionVideos.value = []
|
})
|
|
// 暴露方法给父组件
|
defineExpose({ openDialog })
|
</script>
|
|
<style scoped lang="scss">
|
.popup-content {
|
height: 100%;
|
width: 100%;
|
display: flex;
|
flex-direction: column;
|
}
|
|
.popup-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 20px;
|
border-bottom: 1px solid #f0f0f0;
|
}
|
|
.popup-title {
|
font-size: 18px;
|
font-weight: 600;
|
color: #333;
|
}
|
|
.upload-container {
|
flex: 1;
|
padding: 20px;
|
overflow-y: auto;
|
}
|
|
.form-container {
|
width: 100%;
|
}
|
|
.title {
|
font-size: 16px;
|
color: #1890ff;
|
line-height: 24px;
|
font-weight: 600;
|
padding-left: 12px;
|
position: relative;
|
margin: 0 0 20px 0;
|
|
&::before {
|
content: "";
|
position: absolute;
|
left: 0;
|
top: 4px;
|
width: 4px;
|
height: 16px;
|
background-color: #1890ff;
|
border-radius: 2px;
|
}
|
}
|
|
.media-section {
|
margin-bottom: 30px;
|
}
|
|
.section-title {
|
font-size: 14px;
|
color: #666;
|
margin-bottom: 15px;
|
font-weight: 500;
|
}
|
|
.image-grid {
|
display: flex;
|
flex-wrap: wrap;
|
gap: 10px;
|
}
|
|
.image-item {
|
width: 100px;
|
height: 100px;
|
border-radius: 8px;
|
overflow: hidden;
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
}
|
|
.image-preview {
|
width: 100%;
|
height: 100%;
|
}
|
|
.video-grid {
|
display: flex;
|
flex-wrap: wrap;
|
gap: 15px;
|
}
|
|
.video-item {
|
width: 160px;
|
height: 90px;
|
border-radius: 8px;
|
overflow: hidden;
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
position: relative;
|
}
|
|
.video-thumbnail {
|
width: 100%;
|
height: 100%;
|
object-fit: cover;
|
}
|
|
.video-overlay {
|
position: absolute;
|
top: 0;
|
left: 0;
|
width: 100%;
|
height: 100%;
|
background-color: rgba(0, 0, 0, 0.3);
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
pointer-events: none;
|
}
|
|
.video-player-container {
|
width: 100%;
|
height: 100%;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
background-color: #000;
|
position: relative;
|
}
|
|
.video-player {
|
width: 100%;
|
height: 100%;
|
max-width: 100vw;
|
max-height: 100vh;
|
}
|
|
.empty-state {
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
height: 200px;
|
}
|
</style>
|