提交 8408180d authored 作者: 龙菲's avatar 龙菲

feat:完善布展详情页、增加svg

上级 543e543c
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
"js-cookie": "^3.0.1", "js-cookie": "^3.0.1",
"mockjs": "^1.1.0", "mockjs": "^1.1.0",
"qrcodejs2": "^0.0.2", "qrcodejs2": "^0.0.2",
"svg-sprite-loader": "^6.0.11",
"svgo": "^2.8.0", "svgo": "^2.8.0",
"vue": "^2.6.14", "vue": "^2.6.14",
"vue-router": "^3.5.1", "vue-router": "^3.5.1",
...@@ -40,6 +39,7 @@ ...@@ -40,6 +39,7 @@
"eslint-plugin-vue": "^8.0.3", "eslint-plugin-vue": "^8.0.3",
"sass": "^1.32.7", "sass": "^1.32.7",
"sass-loader": "^12.0.0", "sass-loader": "^12.0.0",
"svg-sprite-loader": "^6.0.11",
"vue-template-compiler": "^2.6.14" "vue-template-compiler": "^2.6.14"
}, },
"eslintConfig": { "eslintConfig": {
......
...@@ -5,27 +5,26 @@ ...@@ -5,27 +5,26 @@
default-active="" default-active=""
@open="handleOpen" @open="handleOpen"
@close="handleClose" @close="handleClose"
:collapse="isCollapse" :default-openeds="[items[0].euId]"
> >
<!-- 遍历菜单 --> <!-- 遍历菜单 -->
<template v-for="item in items"> <template v-for="(item) in items">
<!-- 含有子菜单 --> <!-- 含有子菜单 -->
<template v-if="item.children"> <template v-if="item.children">
<!-- 第一层 含有子菜单菜单 --> <!-- 第一层 含有子菜单菜单 -->
<el-submenu :index="item.title" :key="item.title"> <el-submenu :index="item.euId" :key="item.title">
<template slot="title"> <template slot="title">
<span slot="title">{{ item.title }}</span> <div slot="title" @click="handleClick(item)">{{ item.title }}</div>
</template> </template>
<menu-list :items="item.children"></menu-list <menu-list :items="item.children" v-bind="$attrs" v-on="$listeners"></menu-list
><!--递归调用--> ><!--递归调用-->
</el-submenu> </el-submenu>
</template> </template>
<!-- 第一层 不含子菜单 --> <!-- 第一层 不含子菜单 -->
<template v-else> <template v-else>
<el-menu-item :index="item.title" :key="item.title"> <el-menu-item :index="item.euId" :key="item.title">
<!-- <i :class="item.meta.icon"></i> --> <div slot="title" @click="handleClick(item)">{{ item.title }}</div>
<span slot="title">{{ item.title }}</span>
</el-menu-item> </el-menu-item>
</template> </template>
</template> </template>
...@@ -39,13 +38,20 @@ export default { ...@@ -39,13 +38,20 @@ export default {
items: Array, items: Array,
isCollapse: Boolean, isCollapse: Boolean,
}, },
inheritAttrs:false,
methods: { methods: {
handleOpen(key, keyPath) { handleOpen(key, keyPath) {
console.log(key, keyPath); debugger
}, },
handleClose(key, keyPath) { handleClose(key, keyPath) {
console.log(key, keyPath); // console.log(key, keyPath);
}, },
handleClick(item){
// console.log(item.title);
this.$emit('open',item)
}
}, },
}; };
</script> </script>
......
<template> <template>
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" /> <svg :class="svgClass" aria-hidden="true" v-on="$listeners">
<svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
<use :xlink:href="iconName" /> <use :xlink:href="iconName" />
</svg> </svg>
</template> </template>
<script> <script>
// doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
import { isExternal } from '@/utils/validate'
export default { export default {
name: 'SvgIcon', name: 'SvgIcon',
props: { props: {
...@@ -22,25 +18,12 @@ export default { ...@@ -22,25 +18,12 @@ export default {
} }
}, },
computed: { computed: {
isExternal() {
return isExternal(this.iconClass)
},
iconName() { iconName() {
return `#icon-${this.iconClass}` return `#icon-${this.iconClass}`
}, },
svgClass() { svgClass() {
if (this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon' return 'svg-icon'
} }
},
styleExternalIcon() {
return {
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
'-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
}
}
} }
} }
</script> </script>
...@@ -53,10 +36,4 @@ export default { ...@@ -53,10 +36,4 @@ export default {
fill: currentColor; fill: currentColor;
overflow: hidden; overflow: hidden;
} }
.svg-external-icon {
background-color: currentColor;
mask-size: cover!important;
display: inline-block;
}
</style> </style>
<template>
<video :src="url" style="height: auto; width: 100%" controls loop></video>
</template>
<script>
export default {
name: 'Video',
props: {
url: {
default: "",
type: String,
},
},
};
</script>
<style>
</style>
\ No newline at end of file
import Vue from 'vue' import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'// svg component import SvgIcon from '@/components/SvgIcon'// svg组件
// register globally // register globally
Vue.component('svg-icon', SvgIcon) Vue.component('svg-icon', SvgIcon)
const req = require.context('./svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys().map(requireContext) const requireAll = requireContext => requireContext.keys().map(requireContext)
const req = require.context('./svg', false, /\.svg$/)
requireAll(req) requireAll(req)
\ No newline at end of file
...@@ -6,7 +6,7 @@ import store from './store/index' ...@@ -6,7 +6,7 @@ import store from './store/index'
import ElementUI from 'element-ui'; import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css'; import 'element-ui/lib/theme-chalk/index.css';
// import * as echarts from 'echarts' // import * as echarts from 'echarts'
import './icons'
Vue.config.productionTip = false Vue.config.productionTip = false
Vue.use(ElementUI); Vue.use(ElementUI);
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<div class="title-container"> <div class="title-container">
<h3 class="title">{{ displayDetail.title }}</h3> <h3 class="title">{{ displayDetail.title }}</h3>
<div class="operation"> <div class="operation">
<!-- <svg-icon icon-class="eye"></svg-icon> --> <svg-icon icon-class="user" style="color:red"></svg-icon>
<el-button <el-button
type="text" type="text"
@click.native="handleCollect(exhibitionId)" @click.native="handleCollect(exhibitionId)"
...@@ -31,14 +31,28 @@ ...@@ -31,14 +31,28 @@
</div> </div>
<div class="content"> <div class="content">
{{ displayDetail.intro }} <div class="intro margin-bottom-32">{{ displayDetail.intro }}</div>
<!-- 可乐遗址位于贵州省赫章县可乐乡可乐河两岸的丘陵坡地上,是一处战国至汉时期(公元前475年至公元220年)的遗址。 <div
遗址区包括遗址2处、墓葬群14处。遗址和墓葬群均有汉代遗址和战国时期的当地少数民族(即夜郎)遗址和墓葬两类。汉代城址,位于可乐河南岸,平面为“猪心形”,面积约6-7万平方米,有夯土城墙环绕。城内出土大量青铜戈、矛、钱币、瓦当、花纹砖等建材及陶、铜、铁等生产和生活用品。夜郎文化遗址距汉城约1公里,位于可乐河北岸,出土石器、铜器、陶器。汉墓一般规模较大,随葬少量金、银、玉等饰件及铜、铁、陶器等物。少数民族墓群除随葬少量陶、铜、铁、漆器外,其葬式极为特殊,其中的“套头葬”在国内罕见,反映出夜郎民族的埋葬特点。 class="images"
可乐遗址对研究夜郎民族的政治、经济和文化都具有重要的历史价值和科学价值。 --> v-if="displayDetail.imagesVo && displayDetail.imagesVo.length > 0"
>
<el-row :gutter="20">
<el-col
:span="24"
v-for="item in displayDetail.imagesVo"
:key="item.fileId"
>
<img :src="item.url" alt="" width="100%"/>
<div class="name flex-center margin-bottom-32">
{{ item.name }}
</div>
</el-col>
</el-row>
</div>
</div> </div>
</div> </div>
<div class="relate-book marginBottom32"> <div class="relate-book margin-bottom-32">
<CustomTitle text="相关文献" /> <CustomTitle text="相关文献" />
<div <div
class="book-item" class="book-item"
...@@ -49,7 +63,7 @@ ...@@ -49,7 +63,7 @@
<span style="margin: 0 20px">{{ item.author }}</span> <span style="margin: 0 20px">{{ item.author }}</span>
</div> </div>
</div> </div>
<div class="relate-cultual-relic marginBottom32"> <div class="relate-cultual-relic margin-bottom-32">
<CustomTitle text="关联文物" /> <CustomTitle text="关联文物" />
<!-- <div class="display-group"> <!-- <div class="display-group">
<div <div
...@@ -76,7 +90,7 @@ ...@@ -76,7 +90,7 @@
</div> </div>
</div> --> </div> -->
</div> </div>
<div class="relate-video marginBottom32"> <div class="relate-video margin-bottom-32">
<CustomTitle text="关联视频" /> <CustomTitle text="关联视频" />
<el-carousel :interval="4000" type="card" height="400px"> <el-carousel :interval="4000" type="card" height="400px">
<el-carousel-item <el-carousel-item
...@@ -85,12 +99,13 @@ ...@@ -85,12 +99,13 @@
> >
<div class="video-container"> <div class="video-container">
<div class="video-box"> <div class="video-box">
<video <!-- <video
:src="item.url" :src="item.url"
style="height: auto; width: 100%" style="height: auto; width: 100%"
controls controls
loop loop
></video> ></video> -->
<Video :url="item.url" />
</div> </div>
<div class="info-box"> <div class="info-box">
<h4 class="name">{{ item.name.split(".")[0] }}</h4> <h4 class="name">{{ item.name.split(".")[0] }}</h4>
...@@ -99,16 +114,65 @@ ...@@ -99,16 +114,65 @@
</el-carousel-item> </el-carousel-item>
</el-carousel> </el-carousel>
</div> </div>
<div class="relate-video marginBottom32"> <div
class="relate-video margin-bottom-32"
v-if="
displayDetail.exhibitionUnits &&
displayDetail.exhibitionUnits.length > 0
"
>
<CustomTitle text="布展单元" /> <CustomTitle text="布展单元" />
<el-row> <el-row :gutter="20">
<el-col :span="8"> <el-col :span="8">
<!-- 只能单开 unique-opened --> <!-- 只能单开 unique-opened -->
<menu-list :items="displayDetail.exhibitionUnits" :isCollapse="false" @handleOpen="handleOpenUnit"></menu-list> <menu-list
:items="displayDetail.exhibitionUnits"
:isCollapse="false"
@open="handleOpenUnit"
></menu-list>
</el-col> </el-col>
<el-col :span="16"> <el-col :span="16">
<el-card> <el-card>
<div slot="header" class="clearfix">
<span>单元介绍</span>
</div>
<div class="unit-content">
<div class="intro text-indent" v-if="curUnit.intro">
{{ curUnit.intro }}
</div>
<div
class="images"
v-if="curUnit.imagesVo && curUnit.imagesVo.length > 0"
>
<el-row :gutter="20">
<el-col
:span="24 / curUnit.imagesVo.length"
v-for="item in curUnit.imagesVo"
:key="item.euId"
class="margin-bottom-32"
>
<img :src="item.url" alt="" srcset="" width="100%" />
<div class="desc flex-center">
{{ item.name }}
</div>
</el-col>
</el-row>
</div>
<div
class="videos"
v-if="curUnit.videosVo && curUnit.videosVo.length > 0"
>
<el-row :gutter="20">
<el-col
:span="24 / curUnit.videosVo.length"
v-for="item in curUnit.videosVo"
:key="item.euId"
>
<Video :url="item.url" />
</el-col>
</el-row>
</div>
</div>
</el-card> </el-card>
</el-col> </el-col>
</el-row> </el-row>
...@@ -164,8 +228,9 @@ import CustomTitle from "@/components/CustomTitle"; ...@@ -164,8 +228,9 @@ import CustomTitle from "@/components/CustomTitle";
import { getDisplayById } from "@/api/display"; import { getDisplayById } from "@/api/display";
// import { getToken } from "@/utils/auth"; // import { getToken } from "@/utils/auth";
import { mapGetters } from "vuex"; import { mapGetters } from "vuex";
import Video from "@/components/Video";
export default { export default {
components: { SearchBar, CustomTitle,MenuList }, components: { SearchBar, CustomTitle, MenuList, Video },
data() { data() {
return { return {
options: [ options: [
...@@ -181,6 +246,7 @@ export default { ...@@ -181,6 +246,7 @@ export default {
loginDialogVisible: false, loginDialogVisible: false,
shareDialogVisible: false, shareDialogVisible: false,
curLink: "", //当前地址栏的链接 curLink: "", //当前地址栏的链接
curUnit: {}, //当前点击的单元
// relateBooks: [ // relateBooks: [
// { name: "带钩及其演变", author: "王莉", source: "文博.1996(01)" }, // { name: "带钩及其演变", author: "王莉", source: "文博.1996(01)" },
// { name: "古代带钩用途考实", author: "王仁湘", source: "文物.1982(10)" }, // { name: "古代带钩用途考实", author: "王仁湘", source: "文物.1982(10)" },
...@@ -243,6 +309,25 @@ export default { ...@@ -243,6 +309,25 @@ export default {
let res = await getDisplayById({ exhibitionId }); let res = await getDisplayById({ exhibitionId });
if (res.code == 0) { if (res.code == 0) {
this.displayDetail = res.data; this.displayDetail = res.data;
if (
this.displayDetail.exhibitionUnits &&
this.displayDetail.exhibitionUnits.length > 0
) {
this.curUnit = this.displayDetail.exhibitionUnits[0];
}
processUnit(this.displayDetail.exhibitionUnits);
// console.log(unit);
function processUnit(list) {
for (let o of list || []) {
if (o.children) {
if (o.children.length == 0) {
o.children = null;
} else {
processUnit(o.children);
}
}
}
}
} }
} }
}, },
...@@ -286,9 +371,9 @@ export default { ...@@ -286,9 +371,9 @@ export default {
handleShareClose() { handleShareClose() {
this.shareDialogVisible = false; this.shareDialogVisible = false;
}, },
handleOpenUnit(item){ handleOpenUnit(item) {
console.log(item); this.curUnit = item;
} },
}, },
}; };
</script> </script>
...@@ -387,10 +472,20 @@ export default { ...@@ -387,10 +472,20 @@ export default {
} }
} }
.marginBottom32 { .margin-bottom-32 {
margin-bottom: 32px; margin-bottom: 32px;
} }
.text-indent {
text-indent: 28px;
}
.flex-center {
display: flex;
justify-content: center;
align-items: center;
}
.qrcode, .qrcode,
.copy { .copy {
display: flex; display: flex;
......
...@@ -16,8 +16,8 @@ module.exports = defineConfig({ ...@@ -16,8 +16,8 @@ module.exports = defineConfig({
hot: true, hot: true,
proxy: { proxy: {
'/api': { '/api': {
target: 'http://172.24.100.189:8080', // target: 'http://172.24.100.189:8080',
// target: 'http://222.85.214.245:9062/api', target: 'http://222.85.214.245:9062/api',
changeOrigin: true, changeOrigin: true,
pathRewrite: { pathRewrite: {
'^/api': '' '^/api': ''
...@@ -34,21 +34,14 @@ module.exports = defineConfig({ ...@@ -34,21 +34,14 @@ module.exports = defineConfig({
return args return args
}) })
// set svg-sprite-loader // set svg-sprite-loader
config.module const svgRule = config.module.rule('svg')
.rule('svg') // 清除已有的所有 loader,如果你不这样做,接下来的 loader 会附加在该规则现有的 loader 之后。
.exclude.add(resolve('src/icons')) svgRule.uses.clear()
.end() // 添加要替换的 loader
config.module svgRule.use('svg-sprite-loader').loader('svg-sprite-loader')
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({ .options({
symbolId: 'icon-[name]' symbolId: 'icon-[name]'
}) })
.end()
}, },
configureWebpack: { configureWebpack: {
// provide the app's title in webpack's name field, so that // provide the app's title in webpack's name field, so that
...@@ -60,7 +53,4 @@ module.exports = defineConfig({ ...@@ -60,7 +53,4 @@ module.exports = defineConfig({
} }
}, },
}) })
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论