提交 d5bb958c authored 作者: 龙菲's avatar 龙菲

增加展览和文物的详情预览,3D文物的在线预览

上级 7328c1b0
// 文物的展示字段
export const crTabletitle = [{
prop: "name",
label: "名称",
columnAlign: 'center',
showOverFlowToolTip: true,
},
{
prop: "levelLabel",
label: "文物级别",
columnAlign: 'center',
},
{
prop: "detailSize",
label: "尺寸",
columnAlign: 'center',
showOverFlowToolTip: true
},
{
prop: "textureTypeLabel",
label: "质地",
columnAlign: 'center',
},
{
prop: "typeLabel",
label: "类别",
width: 100,
columnAlign: 'center',
isCulturalRelicType: true
},
// {
// prop: "createId",
// label: "创建人",
// columnAlign: 'center',
// },
{
prop: "createTime",
label: "创建时间",
columnAlign: 'center',
showOverFlowToolTip: true
},
{
prop: "deptName",
label: "馆藏单位",
columnAlign: 'center',
showOverFlowToolTip: true,
},
{
prop: "regionName",
label: "所属地",
columnAlign: 'center',
showOverFlowToolTip: true,
},
{
prop: "intro",
label: "馆藏介绍",
columnAlign: 'center',
showOverFlowToolTip: true,
width: 120,
},
{
prop: "themeWord",
label: "主题词",
columnAlign: 'center',
showOverFlowToolTip: true,
},
{
prop: "faceImagePressUrl",
label: "封面",
columnAlign: 'center',
isFaceImage: true,
showOverFlowToolTip: true
},
{
prop: "imagesVo",
label: "文物图片",
columnAlign: 'center',
isFaceImage: true,
},
{
prop: "audiosVo",
label: "文物音频",
columnAlign: 'center',
isFaceImage: true,
},
{
prop: "videosVo",
label: "文物视频",
columnAlign: 'center',
isFaceImage: true,
},
{
prop: "literatureVo",
label: "相关文献",
columnAlign: 'center',
isFaceImage: true,
},
{
prop: "file3dUrl",
label: "3D文物",
columnAlign: 'center',
},
{
prop: "statusLabel",
label: "上下架状态",
width: 100,
columnAlign: 'center',
isStatus: true
},
{
prop: "num",
label: "数量",
columnAlign: 'center',
},
{
prop: "sourceWay",
label: "来源方式",
columnAlign: 'center',
showOverFlowToolTip: true,
},
{
prop: "remark",
label: "备注",
columnAlign: 'center',
},
// directory 文件夹
// flag3d 是否有3d图片
// updateId 更新人
]
...@@ -55,11 +55,11 @@ ...@@ -55,11 +55,11 @@
<el-table-column prop="name" label="名称"></el-table-column> <el-table-column prop="name" label="名称"></el-table-column>
<el-table-column prop="authors" label="作者"></el-table-column> <el-table-column prop="authors" label="作者"></el-table-column>
<el-table-column prop="source" label="来源"></el-table-column> <el-table-column prop="source" label="来源"></el-table-column>
<el-table-column prop="source" label="操作"> <!-- <el-table-column prop="source" label="操作">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text">预览</el-button> <el-button type="text" @click="$bizCommon.openliterature(scope.row)">预览</el-button>
</template> </template>
</el-table-column> </el-table-column> -->
</el-table> </el-table>
</div> </div>
<RichTextShow <RichTextShow
...@@ -74,6 +74,16 @@ ...@@ -74,6 +74,16 @@
/> />
<span v-else></span> <span v-else></span>
</div> </div>
<div v-else-if="item.prop === 'file3dUrl' && info['file3dUrl']">
<el-button type="text" @click="handleToggle3d">{{
show3d ? "收起" : "在线预览"
}}</el-button>
<Viewer3d
:url="info['file3dUrl']"
v-if="show3d"
class="container-3d"
/>
</div>
<span v-else>{{ info[item.prop] || "无" }}</span> <span v-else>{{ info[item.prop] || "无" }}</span>
</el-descriptions-item> </el-descriptions-item>
</el-descriptions> </el-descriptions>
...@@ -82,13 +92,15 @@ ...@@ -82,13 +92,15 @@
</template> </template>
<script> <script>
import { crTabletitle } from "../../config"; import { crTabletitle } from "./config";
import VideoPlayer from "@/components/VideoPlayer"; import VideoPlayer from "@/components/VideoPlayer";
import AudioPlayer from "@/components/AudioPlayer"; import AudioPlayer from "@/components/AudioPlayer";
import Viewer3d from "@/components/Viewer3d";
export default { export default {
components: { components: {
VideoPlayer, VideoPlayer,
AudioPlayer, AudioPlayer,
Viewer3d,
}, },
props: { props: {
info: { info: {
...@@ -121,8 +133,14 @@ export default { ...@@ -121,8 +133,14 @@ export default {
data() { data() {
return { return {
crTabletitle, crTabletitle,
show3d: false,
}; };
}, },
methods: {
handleToggle3d() {
this.show3d = !this.show3d;
},
},
}; };
</script> </script>
...@@ -134,6 +152,9 @@ export default { ...@@ -134,6 +152,9 @@ export default {
::v-deep .el-descriptions-item__content { ::v-deep .el-descriptions-item__content {
flex: 1; flex: 1;
} }
::v-deep .el-descriptions-item__container {
align-items: center;
}
.image { .image {
margin-right: 20px; margin-right: 20px;
...@@ -148,4 +169,9 @@ export default { ...@@ -148,4 +169,9 @@ export default {
border: 1px solid #dadada; border: 1px solid #dadada;
border-radius: 4px; border-radius: 4px;
} }
.container-3d {
border: 1px solid #dadada;
border-radius: 4px;
}
</style> </style>
// 展览的展示字段
export const displayTabletitle = [{
prop: "title",
label: "标题",
columnAlign: 'center',
width: 120,
showOverFlowToolTip: true,
},
{
prop: "keyword",
label: "关键词",
columnAlign: 'center',
showOverFlowToolTip: true,
},
{
prop: "type",
label: "展览类型",
columnAlign: 'center',
isDisplayType: true,
showOverFlowToolTip: true,
},
{
prop: "deptName",
label: "展览单位",
columnAlign: 'center',
showOverFlowToolTip: true,
},
{
prop: "regionName",
label: "所在地区",
columnAlign: 'center',
showOverFlowToolTip: true,
},
{
prop: "faceImagePressUrl",
label: "封面",
columnAlign: 'center',
isFaceImage: true,
width: 130
},
{
prop: "intro",
label: "展览介绍",
columnAlign: 'center',
},
{
prop: "literatureVo",
label: "关联文献",
columnAlign: 'center',
width: 100
},
{
prop: "themeType",
label: "模板主题",
columnAlign: 'center',
},
{
prop: "remark",
label: "备注",
columnAlign: 'center',
showOverFlowToolTip: true,
},
{
prop: "imagesVo",
label: "展览图片",
columnAlign: 'center',
isImages: true
},
{
prop: "audiosVo",
label: "展览音频",
columnAlign: 'center',
isAudios: true
},
{
prop: "videosVo",
label: "展览视频",
columnAlign: 'center',
isVideos: true
},
]
\ No newline at end of file
...@@ -82,11 +82,11 @@ ...@@ -82,11 +82,11 @@
<el-table-column prop="name" label="名称"></el-table-column> <el-table-column prop="name" label="名称"></el-table-column>
<el-table-column prop="authors" label="作者"></el-table-column> <el-table-column prop="authors" label="作者"></el-table-column>
<el-table-column prop="source" label="来源"></el-table-column> <el-table-column prop="source" label="来源"></el-table-column>
<el-table-column prop="source" label="操作"> <!-- <el-table-column prop="source" label="操作">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text">预览</el-button> <el-button type="text">预览</el-button>
</template> </template>
</el-table-column> </el-table-column> -->
</el-table> </el-table>
</div> </div>
<span v-else>暂无文献</span> <span v-else>暂无文献</span>
...@@ -95,7 +95,6 @@ ...@@ -95,7 +95,6 @@
v-else-if="item.prop === 'intro'" v-else-if="item.prop === 'intro'"
:richText="info['intro']" :richText="info['intro']"
></RichTextShow> ></RichTextShow>
<span v-else>{{ info[item.prop] || "无" }}</span> <span v-else>{{ info[item.prop] || "无" }}</span>
</el-descriptions-item> </el-descriptions-item>
</el-descriptions> </el-descriptions>
...@@ -105,7 +104,7 @@ ...@@ -105,7 +104,7 @@
</template> </template>
<script> <script>
import { displayTabletitle } from "../../config"; import { displayTabletitle } from "./config";
import VideoPlayer from "@/components/VideoPlayer"; import VideoPlayer from "@/components/VideoPlayer";
import AudioPlayer from "@/components/AudioPlayer"; import AudioPlayer from "@/components/AudioPlayer";
export default { export default {
......
<template>
<!-- 展览效果预览图 -->
<div>
<div class="container" v-if="info">
<NavBar />
<NormalStyle
v-if="info.themeType == NORMAL_STYLE.value"
:displayDetail="info"
:dicts="dicts"
/>
<ChStyle
v-if="info.themeType == CH_STYLE.value"
:displayDetail="info"
:dicts="dicts"
/>
<RedStyle
v-if="info.themeType == RED_STYLE.value"
:displayDetail="info"
:dicts="dicts"
/>
<Footer />
</div>
<el-empty v-else />
</div>
</template>
<script>
import NormalStyle from "@/views/display/components/templates/NormalStyle.vue";
import ChStyle from "@/views/display/components/templates/ChStyle.vue";
import RedStyle from "@/views/display/components/templates/RedStyle.vue";
import NavBar from "@/components/NavBar";
import Footer from "@/components/Footer";
import { THEME_TYPE } from "@/contants/display";
export default {
components: {
NormalStyle,
ChStyle,
RedStyle,
NavBar,
Footer,
},
props: {
// 展览本身信息
info: {
type: Object,
default: () => ({}),
},
// 字典值
dicts: {
type: Object,
default: () => ({}),
},
},
data() {
return {
...THEME_TYPE,
};
},
};
</script>
<style></style>
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<!-- online_3d_viewer --> <!-- online_3d_viewer -->
<div <div
class="online_3d_viewer" class="online_3d_viewer"
model="/static/3d/yshl.FBX" :model="url"
:backgroundcolor="backgroundcolor" :backgroundcolor="backgroundcolor"
></div> ></div>
</template> </template>
...@@ -19,7 +19,7 @@ export default { ...@@ -19,7 +19,7 @@ export default {
// 模型背景颜色 // 模型背景颜色
backgroundcolor: { backgroundcolor: {
type: String, type: String,
default: "0,0,0,80%", default: "0,0,0",
}, },
}, },
mounted() { mounted() {
...@@ -41,7 +41,7 @@ export default { ...@@ -41,7 +41,7 @@ export default {
.online_3d_viewer { .online_3d_viewer {
width: 100%; width: 100%;
height: 100%; height: 100%;
min-height: 600px; min-height: 400px;
min-width: 300px; min-width: 300px;
} }
</style> </style>
const boutiqueTool = {
// 精品展的key-label,统一在此处配置
boutiqueList: [{
key: 'smgz',
label: '神秘贵州'
},
{
key: 'ylgdyw',
label: '夜郎的疑问'
},
{
key: 'sdcs',
label: '四渡赤水出奇兵'
},
{
key: 'jyycc',
label: '记忆与传承'
},
{
key: 'lzst',
label: '梭戛博物馆陈列展览'
},
{
key: 'zggz',
label: '中共贵州省工委旧址纪念馆'
}, {
key: 'jysg',
label: '贵州教育史馆'
},
{
key: 'frgz',
label: '富饶贵州'
},
{
key: 'zs',
label: '追随-贵州奋斗者的故事'
},
{
key: 'lphy',
label: '黎平会议纪念馆'
},
{
key: 'wmsh',
label: '人类起源·乌蒙史话'
},
],
/**
* 通过key获取精品展对应的label
*/
getAllLabels() {
const labels = this.boutiqueList.map(item => {
return item.label
})
return labels
},
/**
* 通过key获取精品展对应的label
*/
getAllKeys() {
const keys = this.boutiqueList.map(item => {
return item.keys
})
return keys
},
/**
* 通过key获取精品展对应的label
* @param {string} key 精品展对应的key
* @returns {string}精品展对应的label
*/
getLabelByKey(key) {
const keyToLabel = {}
this.boutiqueList.forEach(item => {
keyToLabel[item.key] = item.label
})
return keyToLabel[key]
},
/**
* 通过label获取精品展对应的key
* @param {string} key 精品展对应的key
* @returns {string}精品展对应的label
*/
getKeyByLabel(label) {
const labelToKey = {}
this.boutiqueList.forEach(item => {
labelToKey[item.label] = item.key
})
return labelToKey[label]
},
/**
* 通过label判断是否是精品展
* @param {string} label 展览的标题
* @returns {boolean} 是否是精品展
*/
isBoutique(label) {
const labels = this.getAllLabels()
return labels.includes(label)
},
}
export default boutiqueTool
\ No newline at end of file
//此处为配置需跳转为精品展的展览
//在此处添加title后需在@/views/boutique/index.vue中引入对应的页面组件
export var titles = [
"神秘贵州",
"四渡赤水出奇兵",
"记忆与传承",
"夜郎的疑问",
"贵州教育史馆",
"梭戛博物馆陈列展览",
"中共贵州省工委旧址纪念馆"
];
<template> <template>
<el-dialog <el-dialog
:visible.sync="dialogVisible" :visible.sync="visible"
width="50%" width="50%"
style="height: 98%" style="height: 98%"
:before-close="handleClose" :before-close="handleClose"
top="5vh" top="5vh"
lock-scroll lock-scroll
title="预览文物"
> >
<div class="title" slot="title">
<div class="divider"></div>
<div class="label">{{ title }}</div>
</div>
<div class="dialog-content"> <div class="dialog-content">
<el-main style="height: 100%"> <CulturalRelicInfo :info="info" />
<el-row v-if="videos.length == 1" style="height: 100%">
<el-col :span="24" style="height: 100%" class="video-container">
<video
:src="videos[0]"
style="height: auto; width: 100%"
controls
muted
loop
></video>
</el-col>
</el-row>
<el-row v-if="videos.length > 1" style="height: 100%" :gutter="16">
<template v-for="(item, index) in videos">
<el-col
:span="16"
:key="item"
v-if="index == 0"
style="height: 100%"
class="video-container"
>
<video
:src="videos[0]"
style="height: auto; width: 100%"
controls
loop
></video>
</el-col>
<el-col :span="8" :key="item" v-else>
<video
:src="videos[index]"
style="height: auto; width: 100%"
class="video-container"
controls
loop
></video>
</el-col>
</template>
</el-row>
</el-main>
<div class="dialog-footer">
<el-button type="primary" size="mini" @click="handleClose">关闭</el-button>
</div>
</div> </div>
</el-dialog> </el-dialog>
</template> </template>
<script> <script>
import { dialogMixins } from "./dialogMixins"; import CulturalRelicInfo from "@/components/CulturalRelicInfo";
export default { export default {
name: "PreviewDialog", name: "PreviewDialog",
components: {}, components: {
props: { CulturalRelicInfo,
visible: {
type: Boolean,
default: false,
},
videos: {
type: Array,
default: () => [],
},
}, },
computed: { props: {
dialogVisible: { info: {
get: function () { type: Object,
return this.visible; default: () => ({}),
},
set: function () {},
},
title() {
return "查看视频";
}, },
}, },
dicts: [],
data() { data() {
return {}; return {
visible: false,
};
}, },
methods: { methods: {
// 取消编辑 handleClose() {
cancelForm() { this.visible = false;
this.$emit("handleClose");
},
handleClose(done) {
this.$emit("handleClose");
}, },
}, },
}; };
</script> </script>
<style lang='scss' scoped> <style lang="scss" scoped>
.title { .title {
display: flex; display: flex;
margin-bottom: 16px; margin-bottom: 16px;
...@@ -117,25 +53,9 @@ export default { ...@@ -117,25 +53,9 @@ export default {
font-weight: bold; font-weight: bold;
} }
} }
.dialog-content {
padding: 0 32px;
display: flex;
flex-direction: column;
.relate {
flex: 1;
}
.dialog-footer {
display: flex;
justify-content: flex-end;
}
}
.video-container { .dialog-content {
background-color: #000; height: 65vh;
display: flex; overflow: auto;
justify-content: center;
}
.el-dialog__body {
padding: 0 20px 30px 20px;
} }
</style> </style>
\ No newline at end of file
...@@ -255,7 +255,14 @@ export const operates = { ...@@ -255,7 +255,14 @@ export const operates = {
label: "操作", label: "操作",
titleAlign: "center", titleAlign: "center",
columnAlign: "center", columnAlign: "center",
width: "180px", width: "260px",
}
// 预览按钮
export const previewButton = {
type: 'view',
title: '详情',
perms: 'bizCulturalRelic:list'
} }
// 编辑按钮 // 编辑按钮
......
...@@ -128,11 +128,9 @@ ...@@ -128,11 +128,9 @@
@handleClose="handleImportRecordClose" @handleClose="handleImportRecordClose"
/> />
<View3dDialog <View3dDialog ref="View3dDialog" />
ref="View3dDialog"
:visible="view3dDialogVisible" <PreviewDialog ref="PreviewDialog" :info="previewInfo" />
@handleClose="handleView3dDialogClose"
/>
<el-image-viewer <el-image-viewer
v-if="imgViewerVisible" v-if="imgViewerVisible"
...@@ -147,6 +145,7 @@ import { ...@@ -147,6 +145,7 @@ import {
passedTitle, passedTitle,
unPassedTitle, unPassedTitle,
operates, operates,
previewButton,
editButton, editButton,
deleteButton, deleteButton,
editDisabledButton, editDisabledButton,
...@@ -163,15 +162,17 @@ import { ...@@ -163,15 +162,17 @@ import {
import InfoEditDialog from "./components/InfoEditDialog"; import InfoEditDialog from "./components/InfoEditDialog";
import UploadDialog from "@/components/UploadDialog"; //上传弹窗 import UploadDialog from "@/components/UploadDialog"; //上传弹窗
import ImportRecordDialog from "./components/ImportRecordDialog"; import ImportRecordDialog from "./components/ImportRecordDialog";
import PreviewDialog from "./components/PreviewDialog";
import View3dDialog from "./components/View3dDialog"; import View3dDialog from "./components/View3dDialog";
import { rules } from "./configs/validateRules"; import { rules } from "./configs/validateRules";
import boutiqueTool from "@/utils/boutique";
export default { export default {
components: { components: {
InfoEditDialog, InfoEditDialog,
ImportRecordDialog, ImportRecordDialog,
UploadDialog, UploadDialog,
View3dDialog, View3dDialog,
PreviewDialog,
}, },
data() { data() {
return { return {
...@@ -197,11 +198,11 @@ export default { ...@@ -197,11 +198,11 @@ export default {
imgViewerVisible: false, imgViewerVisible: false,
importRecordVisible: false, //上传记录 importRecordVisible: false, //上传记录
imgList: [], imgList: [],
view3dDialogVisible: false, //3D文件在线浏览弹窗可见性
passedTitle, passedTitle,
unPassedTitle, unPassedTitle,
operates, operates,
tabActive: "unPassed", tabActive: "unPassed",
previewInfo: {},
}; };
}, },
watch: { watch: {
...@@ -227,12 +228,12 @@ export default { ...@@ -227,12 +228,12 @@ export default {
getOperations(row) { getOperations(row) {
return (row) => { return (row) => {
if (this.tabActive == "passed") { if (this.tabActive == "passed") {
return [deleteButton]; return [previewButton, deleteButton];
} else if (row.checkStatus == 0) { } else if (row.checkStatus == 0) {
// 审核中的禁用编辑 // 审核中的禁用编辑
return [editDisabledButton, deleteButton]; return [previewButton, editDisabledButton, deleteButton];
} else { } else {
return [editButton, deleteButton]; return [previewButton, editButton, deleteButton];
} }
}; };
}, },
...@@ -325,37 +326,82 @@ export default { ...@@ -325,37 +326,82 @@ export default {
}; };
this.$refs.InfoEditDialog.visible = true; this.$refs.InfoEditDialog.visible = true;
break; break;
case "view":
this.view(row);
break;
case "view3D": case "view3D":
this.$refs.View3dDialog.visible = true; this.view3d(row);
break; break;
case "edit": case "edit":
this.$refs.InfoEditDialog.visible = true; this.edit(row);
let detailRes = await getRCDetailByIdTemp({ crId: row.crId });
if (detailRes.code == 0) {
this.form = detailRes.data;
this.editVisible = true;
}
break; break;
case "delete": case "delete":
let deleteRes = await deleteCultralRelic([row.crId]); this.deleteRow(row);
if (deleteRes.code == 0) {
this.$message.success("删除成功!");
this.loadData();
}
break; break;
case "multiAdd": case "multiAdd":
this.$refs.UploadDialog.visible = true; this.multiAdd();
break; break;
case "downloadTemplate": case "downloadTemplate":
this.handleDownloadTemplate(); this.handleDownloadTemplate();
break; break;
case "viewImportRecord": case "viewImportRecord":
this.importRecordVisible = true; this.viewImport();
break; break;
} }
}, },
async view(row) {
if (!row) {
return;
}
if (boutiqueTool.isBoutique(row.title)) {
this.$message.info("精品展暂不支持预览!");
return;
}
const request = this.getCurrentPreviewRequest();
const { crId } = row;
let res = await request({
crId,
});
if (res.data) {
this.previewInfo = res.data;
this.$refs.PreviewDialog.visible = true;
} else {
this.$message.error("暂无数据!");
}
},
view3d(row) {
this.$refs.View3dDialog.visible = true;
},
getCurrentPreviewRequest() {
const currentRequest =
this.tabActive == "passed" ? getRCDetailById : getRCDetailByIdTemp;
return currentRequest;
},
async edit(row) {
const { crId } = row;
let detailRes = await getRCDetailByIdTemp({ crId });
if (detailRes.code == 0) {
this.form = detailRes.data;
this.$refs.InfoEditDialog.visible = true;
}
},
async deleteRow(row) {
let deleteRes = await deleteCultralRelic([row.crId]);
if (deleteRes.code == 0) {
this.$message.success("删除成功!");
this.loadData();
}
},
multiAdd() {
this.$refs.UploadDialog.visible = true;
},
viewImport() {
this.importRecordVisible = true;
},
//下载批量导入模板 //下载批量导入模板
handleDownloadTemplate() { handleDownloadTemplate() {
this.loading = true; this.loading = true;
...@@ -411,10 +457,6 @@ export default { ...@@ -411,10 +457,6 @@ export default {
handleImportRecordClose() { handleImportRecordClose() {
this.importRecordVisible = false; this.importRecordVisible = false;
}, },
// 关闭预览3D弹窗
handleView3dDialogClose() {
this.view3dDialogVisible = false;
},
}, },
}; };
</script> </script>
......
...@@ -378,7 +378,6 @@ import { rules } from "../configs/validateRules"; ...@@ -378,7 +378,6 @@ import { rules } from "../configs/validateRules";
import { pageSelectUrl, upLoadAddress } from "../configs/urls"; import { pageSelectUrl, upLoadAddress } from "../configs/urls";
import transformData from "@/utils/bizTransform"; import transformData from "@/utils/bizTransform";
import fileUploadFunctions from "@/utils/bizUploadFunctions"; import fileUploadFunctions from "@/utils/bizUploadFunctions";
import unitsFunctions from "./units";
import submit from "./submit"; import submit from "./submit";
const { const {
faceImageToClient, faceImageToClient,
...@@ -499,7 +498,7 @@ export default { ...@@ -499,7 +498,7 @@ export default {
upLoadAddress, upLoadAddress,
rules, rules,
mediaKeys: ["faceImage", "images", "videos", "audios"], mediaKeys: ["faceImage", "images", "videos", "audios"],
removedIds:[] removedIds: [],
}; };
}, },
async created() { async created() {
...@@ -511,7 +510,6 @@ export default { ...@@ -511,7 +510,6 @@ export default {
methods: { methods: {
...mapActions("dict", ["getDictList", "getLtList", "getCrList"]), ...mapActions("dict", ["getDictList", "getLtList", "getCrList"]),
...mapActions("org", ["getMuseumTreeData", "getSysRegionTreeData"]), ...mapActions("org", ["getMuseumTreeData", "getSysRegionTreeData"]),
...unitsFunctions, //全部导入布展单元的所有函数
coverServerData(value) { coverServerData(value) {
if (value) { if (value) {
this.dialogForm = JSON.parse(JSON.stringify(value)); this.dialogForm = JSON.parse(JSON.stringify(value));
...@@ -534,7 +532,7 @@ export default { ...@@ -534,7 +532,7 @@ export default {
deptId, deptId,
exhibitionUnits, exhibitionUnits,
culturalRelicVo, culturalRelicVo,
virtualVo virtualVo,
} = this.dialogForm; } = this.dialogForm;
this.faceImage = faceImageToClient( this.faceImage = faceImageToClient(
faceImage, faceImage,
...@@ -875,4 +873,4 @@ export default { ...@@ -875,4 +873,4 @@ export default {
right: -8%; right: -8%;
} }
</style> </style>
@/utils/bizTransform@/utils/bizUploadFunctions @/utils/bizTransform@/utils/bizUploadFunctions
\ No newline at end of file
<template> <template>
<el-dialog <el-dialog
:visible.sync="dialogVisible" :visible.sync="visible"
width="94%" width="70%"
style="height: 98%" style="height: 98%"
:before-close="handleClose" :before-close="handleClose"
top="5vh" top="5vh"
lock-scroll lock-scroll
title="预览展览"
> >
<div class="title" slot="title">
<div class="divider"></div>
<div class="label">{{ title }}</div>
</div>
<div class="dialog-content"> <div class="dialog-content">
<NavBar/> <el-tabs v-model="activeName">
<NormalStyle <el-tab-pane name="基本信息" label="基本信息">
v-if="displayDetail.themeType == '1'" <DisplayBaseInfo :info="info" />
:displayDetail="displayDetail" </el-tab-pane>
:dicts="dicts" <el-tab-pane name="效果预览" label="效果预览">
/> <DislplayRender :info="info" />
<ChStyle </el-tab-pane>
v-if="displayDetail.themeType == '2'" </el-tabs>
:displayDetail="displayDetail"
:dicts="dicts"
/>
<RedStyle
v-if="displayDetail.themeType == '3'"
:displayDetail="displayDetail"
:dicts="dicts"
/>
<Footer/>
<div class="dialog-footer">
<el-button size="mini" type="primary" @click="handleClose">关闭</el-button>
</div>
</div> </div>
</el-dialog> </el-dialog>
</template> </template>
<script> <script>
import NormalStyle from "./templates/NormalStyle.vue"; import DisplayBaseInfo from "@/components/DisplayBaseInfo";
// import NormalStyle from "./components/NormalStyle.vue"; import DislplayRender from "@/components/DisplayRender";
import ChStyle from "./templates/ChStyle.vue";
import RedStyle from "./templates/RedStyle.vue";
import NavBar from '@/components/NavBar';
import Footer from '@/components/Footer';
import { mapGetters } from "vuex";
export default { export default {
name: "PreviewDialog", name: "PreviewDialog",
components: { components: {
NormalStyle, DisplayBaseInfo,
ChStyle, DislplayRender,
RedStyle,
NavBar,
Footer,
}, },
props: { props: {
visible: { info: {
type: Boolean,
default: false,
},
displayDetail: {
type: Object, type: Object,
default: () => ({}), default: () => ({}),
}, },
}, },
computed: {
...mapGetters(["dicts"]),
title() {
return "预览——" + this.displayDetail.title;
},
},
watch: {
visible: {
handler: function (value) {
this.dialogVisible = value;
},
immediate: true,
deep: true,
},
},
data() { data() {
return { return {
dialogVisible: false, visible: false,
activeName: "基本信息",
}; };
}, },
async mounted() {
await this.$store.dispatch("dict/getDictList", [
"displayType",
"displayCharacter",
]);
},
methods: { methods: {
handleClose(done) { handleClose() {
this.$emit("handleClose"); this.visible = false;
}, },
}, },
}; };
</script> </script>
<style lang="scss" scoped>
<style lang='scss' scoped>
.title { .title {
display: flex; display: flex;
margin-bottom: 16px; margin-bottom: 16px;
...@@ -113,26 +63,9 @@ export default { ...@@ -113,26 +63,9 @@ export default {
font-weight: bold; font-weight: bold;
} }
} }
.dialog-content {
padding: 0 32px;
display: flex;
flex-direction: column;
.relate {
flex: 1;
}
.dialog-footer {
display: flex;
justify-content: flex-end;
margin-top: 40px;
}
}
.video-container { .dialog-content {
background-color: #000; height: 65vh;
display: flex; overflow: auto;
justify-content: center;
}
.el-dialog__body {
padding: 0 20px 30px 20px;
} }
</style> </style>
\ No newline at end of file
import fileUploadFuctions from "@/utils/bizUploadFunctions";
const unitsFunctions = {
/**
* 获取新的布展单元,实装媒体id,
* @param {*} exhibitionUnits
* @param {*} upLoadRes
* @returns
*/
getNewUnits(exhibitionUnits, upLoadRes) {
const unitCopy = JSON.parse(JSON.stringify(exhibitionUnits))//不要修改原本的数据
const callback = (arr) => {
arr.forEach(unitItem => {
// 每一个unitItem有自己的euid,有唯一的一个images,唯一的一个videos
// 目的是要让每一个unitItem的images,videos实装回去,crId拼接回去
// mediaObj形如{
// images: "1,2,3",
// videos: "4,5,6",
// }
const mediaForm = unitsFunctions.getMediaForm(unitItem, upLoadRes)
const crForm = unitsFunctions.getCrForm(unitItem)
unitItem = Object.assign(unitItem, mediaForm, crForm)
});
}
// 遍历布展单元,并执行callback
unitsFunctions.loopUnits(unitCopy, callback)
return unitCopy
},
getMediaForm(unitItem, upLoadRes) {
const { euId } = unitItem
const mediaForm = unitsFunctions.getUnitFileIdstrObj(euId, upLoadRes)
return mediaForm
},
getCrForm(unitItem) {
const obj = {
crIds: ''
}
const { crIds } = unitItem
if (crIds instanceof Array) {
obj.crIds = crIds.join(",");
} else if (crIds) {
obj.crIds = crIds
}
return obj
},
/**
*
* @param {Array} arr 布展单元的数组
* @param {Function} callback 循环处理什么事
*/
loopUnits(arr, callback) {
if (arr.length > 0) {
callback(arr)
if (arr.children) {
unitsFunctions.loopUnits(arr.children, callback)
}
}
},
/**
* 获取布展单元下面的媒体的id字符串
* @param {String} euId 布展单元的key euId
* @param {String} res 上传后的结果 如unit-images-${euid}
* @returns {Obj} euId对应媒体文件ID字符串
* 形如{
images: "1,2,3",
videos: "4,5,6",
}item.fileId
*/
getUnitFileIdstrObj(euId, res) {
const obj = {};
const unitMediaKeys = ["images"];
const unitMediaFileIdArr = unitMediaKeys.map((mediaKey) => {
const filterArr = res.data.filter((item) => {
// 如果是当前的euId下的文件
const str1 = `unit-${mediaKey}-${euId}`
const arr = item.fileKey.split('-')
const str2 = arr.slice(0, 3).join('-') //前三位拼接
return str1 === str2
});
const arr = filterArr.map(item => {
return item.fileId
})
return arr;
});
unitMediaKeys.forEach((key, index) => {
if (unitMediaFileIdArr[index].length > 0) {
obj[key] = unitMediaFileIdArr[index].join(",");
} else {
obj[key] = "";
}
});
return obj;
},
/**
* 添加布展单元的图片至formData
* @param {array} unitData 布展单元数据
* @param {FormData} formData 需要上传的表单
*/
addUnitImageToFormData(unitData, formData) {
const callback = (arr) => {
arr.forEach(unitItem => {
unitsFunctions.appendMediaItemToFormData(unitItem, formData, "images");
})
}
unitsFunctions.loopUnits(unitData, callback)
},
/**
* 添加布展单元媒体item至formData
* @param {array} unitItem 布展单元的item
* @param {FormData} media 表单中存储ids的key
* @param {FormData} mediaVo 表单中存储文件List的key
*/
appendMediaItemToFormData(unitItem, formData, mediaKey) {
const mediaVo = unitItem[`${mediaKey}Vo`];
if (mediaVo && mediaVo.length > 0) {
mediaVo.forEach((file, index) => {
if (fileUploadFuctions.isFileRaw(file)) {
const uploadKey = `unit-${mediaKey}-${unitItem.euId}-${index}`;
formData.append(uploadKey, file.raw);
}
});
}
},
getUnitDeleteArr(newUnit, oldUnit) {
const deleteArr = []
return deleteArr
}
}
export default unitsFunctions
\ No newline at end of file
...@@ -260,11 +260,18 @@ export const unPassedTitle = [ ...@@ -260,11 +260,18 @@ export const unPassedTitle = [
export const operates = { export const operates = {
operate: true, operate: true,
label: "操作", label: "操作",
width: "140px", width: "220px",
titleAlign: "center", titleAlign: "center",
columnAlign: "center", columnAlign: "center",
}; };
// 预览按钮
export const previewButton = {
type: 'view',
title: '预览',
perms: 'bizCulturalRelic:list'
}
// 编辑按钮 // 编辑按钮
export const editButton = { export const editButton = {
type: 'edit', type: 'edit',
...@@ -280,7 +287,7 @@ export const editDisabledButton = { ...@@ -280,7 +287,7 @@ export const editDisabledButton = {
disabled: true disabled: true
} }
// 编辑按钮 // 删除按钮
export const deleteButton = { export const deleteButton = {
type: 'delete', type: 'delete',
title: '删除', title: '删除',
......
...@@ -124,12 +124,7 @@ ...@@ -124,12 +124,7 @@
@changeDisplay="reloadDisplay" @changeDisplay="reloadDisplay"
ref="InfoEditDialog" ref="InfoEditDialog"
/> />
<PreviewDialog <PreviewDialog ref="PreviewDialog" :info="curPreview" />
v-if="Object.keys(curPreviewObj).length > 0"
ref="PreviewDialog"
:displayDetail="curPreviewObj"
@handleClose="handleClosePreviewDialog"
/>
<ImportRecordDialog ref="ImportRecordDialog" @reload="loadData" /> <ImportRecordDialog ref="ImportRecordDialog" @reload="loadData" />
<UploadListDialog <UploadListDialog
...@@ -160,11 +155,13 @@ import { ...@@ -160,11 +155,13 @@ import {
editButton, editButton,
editDisabledButton, editDisabledButton,
deleteButton, deleteButton,
previewButton,
} from "./configs/list"; } from "./configs/list";
import { import {
getListPer, getListPer,
getListPerTemp, getListPerTemp,
deleteDisplay, deleteDisplay,
getDisplayById,
deleteDisplayTemp, deleteDisplayTemp,
getDisplayByIdTemp, getDisplayByIdTemp,
editDisplay, editDisplay,
...@@ -178,7 +175,7 @@ import { mapGetters } from "vuex"; ...@@ -178,7 +175,7 @@ import { mapGetters } from "vuex";
import { themeTypeCode } from "./contants"; import { themeTypeCode } from "./contants";
import { getToken } from "@/utils/auth"; import { getToken } from "@/utils/auth";
import { importZip } from "@/utils/file"; import { importZip } from "@/utils/file";
import { titles } from "@/utils/boutiqueTitles"; import boutiqueTool from "@/utils/boutique";
import { searchConfig } from "./configs/list"; import { searchConfig } from "./configs/list";
export default { export default {
components: { components: {
...@@ -232,7 +229,6 @@ export default { ...@@ -232,7 +229,6 @@ export default {
copyDialogVisible: false, copyDialogVisible: false,
previewVideos: [], previewVideos: [],
displayTypes: {}, displayTypes: {},
curPreviewObj: {}, //当前预览的对象
currentPageIds: [], //当前的id数组,用于给详情页切换用 currentPageIds: [], //当前的id数组,用于给详情页切换用
multiUploadVisible: false, //控制批量上传弹窗显示 multiUploadVisible: false, //控制批量上传弹窗显示
importRecordVisible: false, //上传记录 importRecordVisible: false, //上传记录
...@@ -244,6 +240,7 @@ export default { ...@@ -244,6 +240,7 @@ export default {
passedTitle, passedTitle,
unPassedTitle, unPassedTitle,
operates, operates,
curPreview: {}, //当前预览的对象
}; };
}, },
computed: { computed: {
...@@ -269,12 +266,12 @@ export default { ...@@ -269,12 +266,12 @@ export default {
getOperations(row) { getOperations(row) {
return (row) => { return (row) => {
if (this.tabActive == "passed") { if (this.tabActive == "passed") {
return [deleteButton]; return [previewButton, deleteButton];
} else if (row.checkStatus == 0) { } else if (row.checkStatus == 0) {
// 状态为审核中的禁用编辑 // 状态为审核中的禁用编辑
return [editDisabledButton, deleteButton]; return [editDisabledButton, previewButton, deleteButton];
} else { } else {
return [editButton, deleteButton]; return [editButton, previewButton, deleteButton];
} }
}; };
}, },
...@@ -389,15 +386,16 @@ export default { ...@@ -389,15 +386,16 @@ export default {
// 预览展览 // 预览展览
async handleView(row) { async handleView(row) {
if (row) { if (row) {
if (titles.includes(row.title)) { if (boutiqueTool.isBoutique(row.title)) {
this.$message.info("精品展暂不支持预览!"); this.$message.info("精品展暂不支持预览!");
return; return;
} }
let res = await getDisplayByIdTemp({ const request = this.getCurrentPreviewRequest();
let res = await request({
exhibitionId: row.exhibitionId, exhibitionId: row.exhibitionId,
}); });
if (res.data) { if (res.data) {
this.curPreviewObj = res.data; this.curPreview = res.data;
this.openDialog("PreviewDialog"); this.openDialog("PreviewDialog");
} else { } else {
this.$message.error("暂无数据!"); this.$message.error("暂无数据!");
...@@ -405,6 +403,12 @@ export default { ...@@ -405,6 +403,12 @@ export default {
} }
}, },
getCurrentPreviewRequest() {
const currentRequest =
this.tabActive == "passed" ? getDisplayById : getDisplayByIdTemp;
return currentRequest;
},
// 编辑展览 // 编辑展览
async handleEdit(row) { async handleEdit(row) {
let editRes = await getDisplayByIdTemp({ let editRes = await getDisplayByIdTemp({
......
...@@ -46,9 +46,9 @@ ...@@ -46,9 +46,9 @@
<script> <script>
import { mapGetters } from "vuex"; import { mapGetters } from "vuex";
import CulturalRelicBaseInfo from "./culturalRelic/CulturalRelicInfo.vue"; import CulturalRelicBaseInfo from "@/components/CulturalRelicInfo";
import DisplayBaseInfo from "@/components/DisplayBaseInfo";
import CulturalRelicTable from "./culturalRelic/CulturalRelicTable.vue"; import CulturalRelicTable from "./culturalRelic/CulturalRelicTable.vue";
import DisplayBaseInfo from "./display/DisplayBaseInfo.vue";
import ApprovalInfo from "./approval/ApprovalInfo.vue"; import ApprovalInfo from "./approval/ApprovalInfo.vue";
import DisplayRender from "./display/DisplayRender.vue"; import DisplayRender from "./display/DisplayRender.vue";
export default { export default {
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
</template> </template>
<script> <script>
import CulturalRelicBaseInfo from "./CulturalRelicInfo.vue"; import CulturalRelicBaseInfo from "@/components/CulturalRelicInfo";
import { crTabletitle } from "../../config"; import { crTabletitle } from "../../config";
import { getListFlowCulturalRelicByPage } from "@/api/approval"; import { getListFlowCulturalRelicByPage } from "@/api/approval";
export default { export default {
......
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
</template> </template>
<script> <script>
import { addCcProduct, updateCcProduct } from "@/api/literature"; import { addCcProduct, updateCcProduct } from "@/api/product";
import { mapGetters } from "vuex"; import { mapGetters } from "vuex";
import { uploadV1 } from "@/utils/file"; import { uploadV1 } from "@/utils/file";
import { deleteFiles } from "@/api/file"; import { deleteFiles } from "@/api/file";
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论