petstore-frontend/src/components/report/DuringMediaGrid.vue
2026-04-19 14:54:38 +08:00

195 lines
3.8 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>
<view v-if="items.length" class="dm-root">
<view class="dm-title-row">
<text class="dm-title">服务过程</text>
<text class="dm-sub">{{ items.length }} 段素材</text>
</view>
<view class="dm-grid">
<view
v-for="(it, idx) in displayItems"
:key="idx"
class="dm-cell"
@click="onCell(it, idx)"
>
<image
v-if="it.mediaType !== 'video'"
class="dm-thumb"
:src="it.url"
mode="aspectFill"
/>
<view v-else class="dm-video-wrap">
<view class="dm-video-ph"></view>
<view class="dm-play">
<text class="dm-play-icon">▶</text>
</view>
</view>
</view>
</view>
<!-- H5全屏遮罩播放小程序原生 video 在 fixed 遮罩内易触发渲染层异常,改跳转播放页 -->
<!-- #ifdef H5 -->
<view v-if="videoPreviewUrl" class="dm-video-overlay" @click="closeVideo">
<view class="dm-video-box" @click.stop>
<video
class="dm-video"
:src="videoPreviewUrl"
controls
autoplay
/>
<text class="dm-close">关闭</text>
</view>
</view>
<!-- #endif -->
</view>
</template>
<script setup>
import { ref, computed } from 'vue'
const props = defineProps({
items: {
type: Array,
default: () => []
}
})
const videoPreviewUrl = ref('')
const displayItems = computed(() => props.items.slice(0, 9))
const imageUrls = computed(() =>
displayItems.value.filter((i) => i.mediaType !== 'video').map((i) => i.url)
)
function onCell(it, idx) {
if (it.mediaType === 'video') {
// #ifdef H5
videoPreviewUrl.value = it.url
// #endif
// #ifndef H5
uni.navigateTo({
url: `/pages/video-player/videoPlayer?url=${encodeURIComponent(it.url)}`
})
// #endif
return
}
const urls = imageUrls.value
if (!urls.length) return
const current = it.url
uni.previewImage({
urls,
current
})
}
function closeVideo() {
videoPreviewUrl.value = ''
}
</script>
<style scoped>
.dm-root {
margin-top: 2px;
}
.dm-title-row {
display: flex;
align-items: baseline;
justify-content: space-between;
margin-bottom: 10px;
}
.dm-title {
font-size: 15px;
font-weight: 700;
color: #1f2937;
}
.dm-sub {
font-size: 12px;
color: #94a3b8;
}
.dm-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 6px;
}
.dm-cell {
aspect-ratio: 1;
border-radius: 10px;
overflow: hidden;
background: #f1f5f9;
border: 1px solid #e8edf4;
}
.dm-thumb {
width: 100%;
height: 100%;
display: block;
}
.dm-video-wrap {
position: relative;
width: 100%;
height: 100%;
}
.dm-video-ph {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background: linear-gradient(145deg, #1e293b 0%, #334155 100%);
}
.dm-play {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
background: rgba(15, 23, 42, 0.25);
}
.dm-play-icon {
width: 36px;
height: 36px;
line-height: 36px;
text-align: center;
border-radius: 50%;
background: rgba(255, 255, 255, 0.95);
color: var(--c-brand-accent);
font-size: 14px;
padding-left: 3px;
}
.dm-video-overlay {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 10000;
background: rgba(15, 23, 42, 0.75);
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
box-sizing: border-box;
}
.dm-video-box {
width: 100%;
max-width: 400px;
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
}
.dm-video {
width: 100%;
max-height: 70vh;
border-radius: 12px;
background: #000;
}
.dm-close {
color: #fff;
font-size: 14px;
padding: 8px 20px;
}
</style>