189 lines
6.8 KiB
Vue
189 lines
6.8 KiB
Vue
<template>
|
|
<div class="pv-page">
|
|
<PhotoSlidePlayer v-model:controls="controlsVisible" :items="slides" @close="onClose" />
|
|
</div>
|
|
</template>
|
|
<script lang="ts" setup>
|
|
import { watch, computed, inject, reactive, ref, VNode, h, unref, onMounted, onBeforeMount, onUnmounted } from "vue";
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
import PhotoSlidePlayer from "@/components/basic/PhotoSlidePlayer.vue";
|
|
import type { PhotoSlideItem } from "@/components/basic/PhotoSlidePlayer.vue";
|
|
import { PublishPhotoDetailDisplayData } from "@/data/auto/publishPhotoDetailDisplayData";
|
|
import publishPhotoService from "@/service/master/publishPhotoService";
|
|
import { bsInfo } from "@/utils/browser"
|
|
import { DmsFileSearchCriteria } from "@/data/auto/dmsFileSearchCriteria";
|
|
import { SearchFilter } from "@/data/auto/searchFilter";
|
|
import { DmsFileUploadViewDisplayData } from "@/data/auto/dmsFileUploadViewDisplayData";
|
|
import { FileTypePolicy } from "@/policy/custom/fileTypePolicy";
|
|
import { DmsFileResultData } from "@/data/auto/dmsFileResultData";
|
|
import dmsFileService from "@/service/master/dmsFileService";
|
|
import { LeftCircleOutlined, RightCircleOutlined } from '@ant-design/icons-vue';
|
|
import { SearchCriteriaResultData } from "@/data/auto/searchCriteriaResultData";
|
|
|
|
/**
|
|
* 后端 PublishPhotoService 会把同一张图给出两个地址(见 PublishPhotoService.auto.cs):
|
|
* FileName —— 原图
|
|
* FormattedPic —— 缩放后的缩略图
|
|
* 幻灯片轮播与图片列表用缩略图(加载快),精看和下载用原图。
|
|
*/
|
|
const images = ref<PublishPhotoDetailDisplayData[]>([]);
|
|
|
|
|
|
const route = useRoute();
|
|
const router = useRouter();
|
|
|
|
|
|
const publishName = ref<string>(route.params.id as string)
|
|
const mode = ref<string>(route.params.mode as string)
|
|
|
|
/**
|
|
* 控制区显隐:与影视厅 PreviewVideo.vue 同一套机制——
|
|
* 收起控制区时给 body 挂 .pv-fullscreen,藏掉 layout 顶部的两条栏
|
|
* (标题栏 + 页面头)并把内容区撑到整屏,图片真正占满全屏。
|
|
* class 挂在 body 上,离开本页立即移除,不会影响其它页面(样式见 styles/main.css)。
|
|
*/
|
|
const controlsVisible = ref(true);
|
|
|
|
/** 退出全屏后让顶栏短暂不响应指针的定时器 */
|
|
let settleTimer = 0;
|
|
|
|
watch(controlsVisible, (visible) => {
|
|
document.body.classList.toggle("pv-fullscreen", !visible);
|
|
|
|
// 退出全屏时鼠标往往正好停在右上角(恢复按钮的位置,也是顶栏菜单的位置),
|
|
// 顶栏一恢复显示就会被 hover 展开下拉。让它先"冷静" 400ms,避开这次误触。
|
|
if (visible) {
|
|
window.clearTimeout(settleTimer);
|
|
document.body.classList.add("pv-settling");
|
|
settleTimer = window.setTimeout(() => {
|
|
document.body.classList.remove("pv-settling");
|
|
}, 400);
|
|
}
|
|
});
|
|
|
|
onUnmounted(() => {
|
|
document.body.classList.remove("pv-fullscreen");
|
|
document.body.classList.remove("pv-settling");
|
|
window.clearTimeout(settleTimer);
|
|
});
|
|
|
|
const toIndex = ref<number>(0)
|
|
const beforeChange = (from: number, to: number) => {
|
|
if (to > 0) {
|
|
toIndex.value = to;
|
|
}
|
|
}
|
|
|
|
// 交给 PhotoSlidePlayer 播放:舞台与列表用 FormattedPic(缩略图),精看/下载用 FileName(原图)
|
|
const slides = computed<PhotoSlideItem[]>(() =>
|
|
images.value.map((item) => ({
|
|
url: item.FormattedPic || item.FileName,
|
|
thumb: item.FormattedPic || item.FileName,
|
|
full: item.FileName || item.FormattedPic,
|
|
name: (item.FileName || "").replace(/\.[^./\\]+$/, "") || undefined,
|
|
}))
|
|
);
|
|
|
|
// 收起播放器:返回来源页;没有历史时回首页
|
|
const onClose = (() => {
|
|
if (window.history.length > 1) {
|
|
router.back();
|
|
}
|
|
else {
|
|
router.push('/');
|
|
}
|
|
});
|
|
|
|
const pagingParams = ref<PagingParams>({ pageSize: bsInfo.size.sm ? 30 : 100, page: 1 });
|
|
const result = ref<SearchCriteriaResultData>(new SearchCriteriaResultData());
|
|
const pageSizeOptions = ref<string[]>(['30', '60', '90', '100', '120']);
|
|
|
|
result.value.Page = pagingParams.value.page ?? 1;
|
|
result.value.Limit = pagingParams.value.pageSize;
|
|
|
|
onMounted(async () => {
|
|
if (mode.value == "list") {
|
|
findData(1);
|
|
}
|
|
else if (publishName.value && publishName.value.length > 0) {
|
|
publishPhotoService.FindPublishPhotoDetailByPublishName(publishName.value).then(res => {
|
|
images.value = res;
|
|
});
|
|
}
|
|
else {
|
|
publishPhotoService.FindPublishPhotoDetail().then(res => {
|
|
images.value = res;
|
|
});
|
|
}
|
|
})
|
|
|
|
const findData = async (params: number) => {
|
|
try {
|
|
let c: DmsFileSearchCriteria = new DmsFileSearchCriteria();
|
|
c.page = params;
|
|
c.limit =999999;// pagingParams.value.pageSize;
|
|
let filter: SearchFilter;
|
|
filter = new SearchFilter();
|
|
filter.Column = DmsFileUploadViewDisplayData.DB_FILE_PATH;
|
|
filter.Type = "SingleSelection";
|
|
filter.Operator = "single";
|
|
filter.Value = publishName.value;
|
|
c.Filter.push(filter);
|
|
filter = new SearchFilter();
|
|
filter.Column = DmsFileUploadViewDisplayData.DB_FILE_TYPE;
|
|
filter.Type = "SingleSelection";
|
|
filter.Operator = "single";
|
|
filter.Value = FileTypePolicy.PHOTO;
|
|
c.Filter.push(filter);
|
|
let dr: DmsFileResultData = await dmsFileService.FindBySearchCriteria(c);
|
|
result.value.Total = dr.Total;
|
|
result.value.Page = dr.Page;
|
|
|
|
if (dr && dr.Datas && dr.Datas.length > 0) {
|
|
|
|
images.value = [];
|
|
let detail: PublishPhotoDetailDisplayData;
|
|
for (let i = 0; i < dr.Datas.length; i++) {
|
|
detail = new PublishPhotoDetailDisplayData()
|
|
detail.FileName = dr.Datas[i].Url; // 原图:精看 / 下载
|
|
detail.FormattedPic = dr.Datas[i].FormattedPic; // 缩略图:舞台轮播 / 列表
|
|
detail.Notice = dr.Datas[i].LandscapeIndc;
|
|
images.value.push(detail);
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.log(error);
|
|
}
|
|
}
|
|
|
|
const onPagination = (async (params: number) => {
|
|
findData(params);
|
|
});
|
|
|
|
const showSizeChange = (async (current: number, size: number) => {
|
|
pagingParams.value.page = 1;
|
|
pagingParams.value.pageSize = size;
|
|
result.value.Page = 1;
|
|
result.value.Limit = size;
|
|
});
|
|
|
|
</script>
|
|
|
|
|
|
<style lang="less" scoped>
|
|
/* 外层 .layout-content-view 自带 padding-top / padding-left(各 8px),
|
|
这里用等量负外边距抵消、同时把宽高补回满格,让播放器铺满整个内容区,
|
|
最外层不留任何间距 */
|
|
.pv-page {
|
|
width: calc(100% + 8px);
|
|
height: calc(100% + 8px);
|
|
margin: -8px 0 0 -8px;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* 铺满后不再需要卡片圆角,否则四个角会露出留白 */
|
|
.pv-page :deep(.psp) {
|
|
border-radius: 0;
|
|
}
|
|
</style>
|