This commit is contained in:
itcsx committed 2026-09-22 10:13:49 +08:00
1 parent 2e1974c35d
commit 9cf69dee5d
3 files changed
+84 -6

No files matched your search

@@ -24,6 +24,12 @@
@click.stop="toggle">
<CaretRightFilled />
</button>
<!-- 控制区收起后画面上留一个恢复入口:影视厅这种整页用法没有弹窗右上角按钮,
否则收起后就再也点不回来了 -->
<button v-if="!controlsVisible" class="vp-restore" type="button" title="显示控制区"
@click.stop="toggleControls">
<EyeOutlined />
</button>
</div>
<!-- 控制区:单击画面区可隐藏,隐藏后画面区吃掉这部分空间 -->
@@ -861,6 +867,30 @@ onBeforeUnmount(() => {
cursor: pointer;
}
/* 控制区收起后留在画面右下角的「显示控制区」入口 */
.vp-restore {
position: absolute;
right: 14px;
bottom: 14px;
z-index: 3;
width: 38px;
height: 38px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
color: #fff;
background: rgba(6, 56, 62, 0.5);
border: 1px solid rgba(255, 255, 255, 0.45);
backdrop-filter: blur(6px);
opacity: 0.85;
}
.vp-restore:active {
transform: scale(0.94);
}
/* ---------- 功能图标行 ---------- */
+12 -4
View File
@@ -370,21 +370,29 @@ const clearRefreshTimers = () => {
const onUploadComplete = (payload: { count?: number }) => {
const count = payload?.count ?? 1;
const sec = 2500 + (count - 1) * 1000;
// 本次是不是视频:只有视频才需要补刷和转码提示
const isVideo = uploadingVideo.value;
// 视频场景由转码提示接管文案,等首刷完成后再切回"加载中..."
if (!uploadingVideo.value) spinTip.value = "加载中...";
if (!isVideo) spinTip.value = "加载中...";
clearRefreshTimers();
refreshTimers.push(
window.setTimeout(() => {
// 列表已经刷出来了,转码提示到此为止(后续补刷沿用默认的"加载中...")
// 列表已经刷出来了,转码提示到此为止
stopTranscodeTip();
uploadingVideo.value = false;
onReSearch();
loading.value = false;
}, sec),
);
refreshTimers.push(window.setTimeout(onReSearch, sec + 3000));
refreshTimers.push(window.setTimeout(onReSearch, sec + 6000));
// 只有视频才补刷:封面(jpg)是服务端 ffmpeg 异步生成的,首刷时可能还没落盘;
// 每次查询服务端都会重新拼 ?v=,src 变了 <img> 才会重新请求,封面就能补上来。
// 图片/音频/普通文件上传后文件已经就绪,一次刷新就够,多刷纯属浪费。
if (isVideo) {
refreshTimers.push(window.setTimeout(onReSearch, sec + 3000));
refreshTimers.push(window.setTimeout(onReSearch, sec + 6000));
}
};
/** 中断时的断点信息,弹窗里展示用 */
+42 -2
View File
@@ -2,12 +2,12 @@
<div class="pv-page" :style="{
height: bsInfo.height - 120 + 'px',
}">
<VideoPlayer :videos="videos" />
<VideoPlayer v-model:controls="controlsVisible" :videos="videos" />
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from "vue";
import { ref, onMounted, onUnmounted, watch } from "vue";
import { useRoute } from "vue-router";
import VideoPlayer from "@/components/basic/VideoPlayer.vue";
@@ -32,6 +32,21 @@ const mode = ref<string>(route.params.mode as string);
// 视频列表:与 VinylAudioPlayer 的 tracks 一致,组件负责 UI,页面只负责数据
const videos = ref<VideoItem[]>([]);
/**
* 底部控制区显隐(点播放器控制栏里的眼睛图标切换)。
* 影视厅是整页用法,收起控制区时连 layout 顶部的两条栏(标题栏 + 页面头)一起藏掉,
* 视频才能占满整屏。class 挂在 body 上,离开本页/恢复显示时立即移除,不会影响其它页面。
*/
const controlsVisible = ref(true);
watch(controlsVisible, (visible) => {
document.body.classList.toggle("pv-fullscreen", !visible);
});
onUnmounted(() => {
document.body.classList.remove("pv-fullscreen");
});
onMounted(async () => {
await loadVideos();
});
@@ -113,4 +128,29 @@ const loadVideos = async () => {
padding-right: 8px;
box-sizing: border-box;
}
</style>
<style>
/* 注意:这里是全局样式,但所有选择器都要求 body 上有 .pv-fullscreen
(只在影视厅收起控制区时由 PreviewVideo.vue 临时挂上,离开页面即移除),
所以不会影响其它页面。
收起控制区 = 页面全屏:
1. 藏掉 layout 顶部两条栏(标题栏 64px + 页面头 42px);
2. 内容区和视频容器撑到整屏,去掉原有的 8px 内边距,做到真正的全屏铺满。
容器高度是行内样式(bsInfo.height - 100/-120),只能用 !important 覆盖。 */
body.pv-fullscreen .layout-header,
body.pv-fullscreen .layout-page-header {
display: none !important;
}
body.pv-fullscreen .layout-content-view {
height: 100vh !important;
padding: 0 !important;
}
body.pv-fullscreen .pv-page {
height: 100vh !important;
padding-right: 0 !important;
}
</style>