提交 2ccbaeda authored 作者: 龙菲's avatar 龙菲

增加布展模板

上级 dd0a0e35
......@@ -31,3 +31,11 @@ export function logout() {
method: 'get'
})
}
// 获取菜单权限
export function getMenu() {
return request({
url: '/sys/home',
method: 'get'
})
}
<template>
<div>
<audio
@timeupdate="updateProgress"
controls
ref="audioRef"
style="display: none"
>
<source :src="fileurl" type="audio/mpeg" />
您的浏览器不支持音频播放
</audio>
<div class="audio-right">
<i
:class="
audioStatus !== 'pause' ? 'el-icon-video-play' : 'el-icon-video-pause'
"
@click="playAudio"
class="dialogAudioPlay"
></i>
<div class="progress-bar-bg" id="progressBarBg" v-dragto="setAudioIcon">
<div class="progress-bar" id="progressBar"></div>
</div>
<div class="audio-time" style="min-height: 10px">
<span class="audio-length-current" id="audioCurTime">{{
audioStart
}}</span
>/
<span class="audio-length-total">{{ duration }}</span>
</div>
<div class="volume">
<div
@click.stop="
() => {
return false;
}
"
class="volume-progress"
v-show="audioHuds"
>
<div
class="volume-bar-bg"
id="volumeBarBg"
v-adjuster="handleShowMuteIcon"
>
<div class="volume-bar" id="volumeBar"></div>
</div>
</div>
<i
class="iconfont pl-1"
:class="audioIcon"
@click.stop="audioHuds = !audioHuds"
>
</i>
</div>
</div>
</div>
</template>
<script>
export default {
name: "NormalPlayer",
props: {
fileurl: {
trpe: String,
},
},
data() {
return {
audioStatus: "play",
audioStart: "0:00",
duration: "0:00",
audioVolume: 0.5,
audioHuds: false,
};
},
directives: {
dragto: {
inserted: function (el, binding, vnode) {
el.addEventListener(
"click",
(e) => {
let wdiv = document.getElementById("progressBarBg").clientWidth;
let audio = vnode.context.$refs.audioRef;
// 只有音乐开始播放后才可以调节,已经播放过但暂停了的也可以
let ratemin = e.offsetX / wdiv;
let rate = ratemin * 100;
document.getElementById("progressBar").style.width = rate + "%";
audio.currentTime = audio.duration * ratemin;
audio.play();
binding.value();
},
false
);
},
},
adjuster: {
inserted: function (el, binding, vnode) {
el.addEventListener(
"click",
(e) => {
let hdiv = document.getElementById("volumeBarBg").clientHeight;
let audio = vnode.context.$refs.audioRef;
// 只有音乐开始播放后才可以调节,已经播放过但暂停了的也可以
let ratemin = e.offsetY / hdiv;
let rate = ratemin * 100;
document.getElementById("volumeBar").style.height = rate + "%";
audio.volume = ratemin;
binding.value(rate / 100);
},
false
);
},
},
},
computed: {
audioIcon() {
if (this.audioHuds) {
return this.audioVolume < 0.01
? "checked icon-jingyin"
: "checked icon-shengyin";
} else {
return "icon-shengyin";
}
},
},
mounted() {
this.fetch();
},
methods: {
fetch() {
let that = this;
var myVid = this.$refs.audioRef;
myVid.loop = false;
// 监听音频播放完毕
myVid.addEventListener(
"ended",
function () {
that.audioStatus = "play"; // 显示播放icon
document.getElementById("progressBar").style.width = "0%"; // 进度条初始化
},
false
);
if (myVid != null) {
myVid.oncanplay = function () {
that.duration = that.transTime(myVid.duration); // 计算音频时长
};
myVid.volume = 0.5; // 设置音量50%
}
},
// 播放暂停控制
playAudio() {
let recordAudio = this.$refs.audioRef; // 获取audio元素
if (recordAudio.paused) {
recordAudio.play();
this.audioStatus = "pause";
} else {
recordAudio.pause();
this.audioStatus = "play";
}
},
// 更新进度条与当前播放时间
updateProgress(e) {
var value = e.target.currentTime / e.target.duration;
if (document.getElementById("progressBar")) {
document.getElementById("progressBar").style.width = value * 100 + "%";
if (e.target.currentTime === e.target.duration) {
this.audioStatus = "pause";
}
} else {
this.audioStatus = "pause";
}
this.audioStart = this.transTime(this.$refs.audioRef.currentTime);
},
/**
* 音频播放时间换算
* @param {number} value - 音频当前播放时间,单位秒
*/
transTime(time) {
var duration = parseInt(time);
var minute = parseInt(duration / 60);
var sec = (duration % 60) + "";
var isM0 = ":";
if (minute === 0) {
minute = "00";
} else if (minute < 10) {
minute = "0" + minute;
}
if (sec.length === 1) {
sec = "0" + sec;
}
return minute + isM0 + sec;
},
setAudioIcon() {
this.audioStatus = "pause";
},
handleShowMuteIcon(val) {
this.audioVolume = val;
},
},
};
</script>
<style lang="scss" scoped>
.volume {
position: relative;
.volume-progress {
position: absolute;
top: -150px;
width: 32px;
height: 140px;
background: #f6f6f6;
border-radius: 4px;
padding-top: 10px;
}
.volume-bar-bg {
margin: 0 auto;
width: 6px;
height: 120px;
background: #dcdcdc;
border-radius: 100px;
flex: 1;
position: relative;
transform: rotate(180deg);
cursor: pointer;
.volume-bar {
width: 6px;
height: 50%;
background: #56bf8b;
border-radius: 100px;
}
}
.checked {
color: #56bf8b;
}
}
.audio-right {
width: 100%;
height: 49px;
line-height: 49px;
background: #f6f6f6;
border-radius: 6px;
display: flex;
padding: 0 15px;
.dialogAudioPlay {
cursor: pointer;
color: #5c5e66;
font-size: 20px;
}
.progress-bar-bg {
background-color: #fff;
flex: 1;
position: relative;
height: 10px;
top: 50%;
transform: translateY(-50%);
margin-top: -1px;
cursor: pointer;
margin: 0 10px;
}
.progress-bar {
background-color: #56bf8b;
width: 0%;
height: 10px;
border-radius: 5px;
}
.audio-time {
overflow: hidden;
font-size: 14px;
.audio-length-total {
float: right;
}
.audio-length-current {
float: left;
}
}
}
</style>
<template>
<audio
ref="audio"
@pause="onPause"
@play="onPlay"
@timeupdate="onTimeupdate"
@loadedmetadata="onLoadedmetadata"
:src="url"
controls="controls"
></audio>
</template>
<script>
// 将整数转换成 时:分:秒的格式
function realFormatSecond(second) {
var secondType = typeof second;
if (secondType === "number" || secondType === "string") {
second = parseInt(second);
var hours = Math.floor(second / 3600);
second = second - hours * 3600;
var mimute = Math.floor(second / 60);
second = second - mimute * 60;
return (
hours + ":" + ("0" + mimute).slice(-2) + ":" + ("0" + second).slice(-2)
);
} else {
return "0:00:00";
}
}
export default {
name: "AudioPlayer",
props: {
url: String,
},
data() {
return {
audio: {
// 该字段是音频是否处于播放状态的属性
playing: false,
// 音频当前播放时长
currentTime: 0,
// 音频最大播放时长
maxTime: 0,
},
};
},
methods: {
// 控制音频的播放与暂停
startPlayOrPause() {
return this.audio.playing ? this.pause() : this.play();
},
// 播放音频
play() {
this.$refs.audio.play();
},
// 暂停音频
pause() {
this.$refs.audio.pause();
},
// 当音频播放
onPlay() {
this.audio.playing = true;
},
// 当音频暂停
onPause() {
this.audio.playing = false;
},
// 当timeupdate事件大概每秒一次,用来更新音频流的当前播放时间
onTimeupdate(res) {
this.audio.currentTime = res.target.currentTime;
},
// 当加载语音流元数据完成后,会触发该事件的回调函数
// 语音元数据主要是语音的长度之类的数据
onLoadedmetadata(res) {
console.log("loadedmetadata");
console.log(res);
this.audio.maxTime = parseInt(res.target.duration);
},
},
};
</script>
<style>
</style>
......@@ -26,8 +26,9 @@ export default {
.custom-title {
width: 100%;
padding: 8px;
font-size: 18px;
border-bottom: 1px solid rgba($color: #000000, $alpha: 0.3);
font-size: 32px;
border-bottom: 2px solid rgba($color: #b8b8b8, $alpha: 0.3);
margin-bottom: 32px;
font-family: 'KaiTi';
}
</style>
......@@ -21,11 +21,6 @@ export default {
align-items: center;
background-color: #2069C4;
color: #fff;
// position: fixed;
// bottom: 0;
// left: 0;
// right: 0;
span{
margin-right: 16px;
}
......
<!-- -->
<template>
<el-menu
v-if="items.length > 0"
class="sidebar-el-menu"
default-active=""
@open="handleOpen"
......@@ -8,7 +9,7 @@
:default-openeds="[items[0].euId]"
>
<!-- 遍历菜单 -->
<template v-for="(item) in items">
<template v-for="item in items">
<!-- 含有子菜单 -->
<template v-if="item.children">
<!-- 第一层 含有子菜单菜单 -->
......@@ -16,7 +17,11 @@
<template slot="title">
<div slot="title" @click="handleClick(item)">{{ item.title }}</div>
</template>
<menu-list :items="item.children" v-bind="$attrs" v-on="$listeners"></menu-list
<menu-list
:items="item.children"
v-bind="$attrs"
v-on="$listeners"
></menu-list
><!--递归调用-->
</el-submenu>
</template>
......@@ -24,7 +29,7 @@
<!-- 第一层 不含子菜单 -->
<template v-else>
<el-menu-item :index="item.euId" :key="item.title">
<div slot="title" @click="handleClick(item)">{{ item.title }}</div>
<div slot="title" @click="handleClick(item)">{{ item.title }}</div>
</el-menu-item>
</template>
</template>
......@@ -38,22 +43,27 @@ export default {
items: Array,
isCollapse: Boolean,
},
inheritAttrs:false,
inheritAttrs: false,
methods: {
handleOpen(key, keyPath) {
},
handleOpen(key, keyPath) {},
handleClose(key, keyPath) {
// console.log(key, keyPath);
},
handleClick(item){
handleClick(item) {
// console.log(item.title);
this.$emit('open',item)
}
this.$emit("open", item);
},
},
};
</script>
<style lang="scss" scoped>
.el-menu-item {
background-color: #ecf5ff;
color: #2069c4;
&:hover {
background-color: #2069c4;
color: #fff;
}
}
</style>
......@@ -2,7 +2,7 @@
<div class="nav" id="navbar">
<div class="container">
<div class="logo-container">
<img src="@/assets/imgs/home/logo.png" />
<img src="@/assets/imgs/display/logo.png" />
</div>
<div class="right">
<div class="tabs">
......@@ -25,7 +25,7 @@
<script>
export default {
name: "NavBar",
name: "Navbar",
data() {
return {
pages: [
......@@ -111,7 +111,7 @@ export default {
min-width: 512px;
height: 100%;
.tab-item {
margin-right: 70px;
margin-right: 50px;
color: #fff;
display: flex;
align-items: center;
......
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1657871872507" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13498" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: feedback-iconfont; src: url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff2?t=1630033759944") format("woff2"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff?t=1630033759944") format("woff"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.ttf?t=1630033759944") format("truetype"); }
</style></defs><path d="M335.008 916.629333c-35.914667 22.314667-82.88 10.773333-104.693333-25.557333a77.333333 77.333333 0 0 1-8.96-57.429333l46.485333-198.24a13.141333 13.141333 0 0 0-4.021333-12.864l-152.16-132.586667c-31.605333-27.52-35.253333-75.648-8.234667-107.733333a75.68 75.68 0 0 1 51.733333-26.752L354.848 339.2c4.352-0.362667 8.245333-3.232 10.026667-7.594667l76.938666-188.170666c16.032-39.2 60.618667-57.92 99.52-41.461334a76.309333 76.309333 0 0 1 40.832 41.461334l76.938667 188.16c1.781333 4.373333 5.674667 7.253333 10.026667 7.605333l199.712 16.277333c41.877333 3.413333 72.885333 40.458667 69.568 82.517334a76.938667 76.938667 0 0 1-26.08 51.978666l-152.16 132.586667c-3.541333 3.082667-5.141333 8.074667-4.021334 12.853333l46.485334 198.24c9.621333 41.013333-15.36 82.336-56.138667 92.224a75.285333 75.285333 0 0 1-57.525333-9.237333l-170.976-106.24a11.296 11.296 0 0 0-12.010667 0l-170.986667 106.24z" p-id="13499"></path></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1657871883846" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13919" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: feedback-iconfont; src: url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff2?t=1630033759944") format("woff2"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff?t=1630033759944") format("woff"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.ttf?t=1630033759944") format("truetype"); }
</style></defs><path d="M669.781333 130.752c71.637333-11.093333 138.901333 11.477333 193.344 64.533333 55.317333 53.930667 81.834667 124.992 74.282667 199.530667-7.466667 73.642667-46.549333 146.368-112.32 210.474667-18.346667 17.898667-67.669333 66.218667-138.453333 135.637333-31.829333 31.232-65.706667 64.448-99.84 97.984L553.6 871.466667l-13.184 12.949333a40.554667 40.554667 0 0 1-56.832 0l-114.602667-112.64-24.213333-23.722667a677626.346667 677626.346667 0 0 0-145.856-142.762666C133.141333 541.184 94.08 468.48 86.613333 394.816c-7.552-74.538667 18.944-145.6 74.282667-199.530667 54.442667-53.056 121.706667-75.605333 193.344-64.533333 53.162667 8.213333 107.093333 34.688 157.781333 76.949333 50.709333-42.24 104.618667-68.736 157.781334-76.949333z" p-id="13920"></path></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1657871880711" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13779" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: feedback-iconfont; src: url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff2?t=1630033759944") format("woff2"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff?t=1630033759944") format("woff"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.ttf?t=1630033759944") format("truetype"); }
</style></defs><path d="M551.6 276V141.4c12.1-56.3 58.2-22 58.2-22L930 395.9c70.4 48.9 4.8 85.7 4.8 85.7L619.5 755.7c-63.1 46.5-67.9-24.5-67.9-24.5V606.4C231.4 506.1 100.4 907.5 100.4 907.5c-12.1 22-19.4 0-19.4 0C-42.8 305.4 551.6 276 551.6 276z" p-id="13780"></path></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1657871877834" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13638" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: feedback-iconfont; src: url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff2?t=1630033759944") format("woff2"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff?t=1630033759944") format("woff"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.ttf?t=1630033759944") format("truetype"); }
</style></defs><path d="M1024 512c-93.44 180.224-287.744 303.872-512 303.872S93.44 692.224 0 512c93.44-180.224 287.744-303.872 512-303.872S930.56 331.776 1024 512zM512 698.112c110.08 0 199.168-85.248 199.168-190.464S622.08 317.184 512 317.184s-199.168 85.248-199.168 190.464S401.92 698.112 512 698.112z" p-id="13639"></path><path d="M369.664 512c0 83.2 63.744 150.784 142.336 150.784S654.336 595.2 654.336 512 590.592 361.216 512 361.216 369.664 428.8 369.664 512z" p-id="13640"></path></svg>
\ No newline at end of file
<template>
<div :class="{'has-logo':showLogo}">
<div :class="{ 'has-logo': showLogo }">
<logo v-if="showLogo" :collapse="isCollapse" />
<el-scrollbar wrap-class="scrollbar-wrapper">
<el-menu
......@@ -12,45 +12,146 @@
:collapse-transition="false"
mode="vertical"
>
<sidebar-item v-for="route in routes" :key="route.path" :item="route" :base-path="route.path" />
<sidebar-item
v-for="route in routes"
:key="route.path"
:item="route"
:base-path="route.path"
/>
</el-menu>
</el-scrollbar>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import Logo from './Logo'
import SidebarItem from './SidebarItem'
import variables from '@/styles/variables.scss'
import { mapGetters } from "vuex";
import Logo from "./Logo";
import SidebarItem from "./SidebarItem";
import variables from "@/styles/variables.scss";
export default {
components: { SidebarItem, Logo },
computed: {
...mapGetters([
'sidebar'
]),
...mapGetters(["sidebar", "menu"]),
routes() {
return this.$router.options.routes
console.log(this.menu);
let obj = {};
let that = this;
traverseMenuList(this.menu || []);
that.addParentKeyWrapper(that.$router.options.routes); //为路由树增加parentKey
let flattenRouterData = that.flattenTreeDataClosure(
that.$router.options.routes
);
// debugger
let newMenu = getNewMenu(that.$router.options.routes);
newMenu.map((item) => {
if (!item.hidden) {
let parent = that.findParent(item.name, flattenRouterData);
that.$router.options.routes.map((v) => {
if (v == parent) {
v.hidden = false;
}
});
}
});
function traverseMenuList(arr) {
if (arr.length > 0) {
arr.map((item) => {
if (item.menuName) {
obj[item.menuName] = true;
}
if (item.children) {
traverseMenuList(item.children);
}
});
}
}
// 设置需要隐藏的菜单
function getNewMenu(arr) {
// debugger
arr.map((item) => {
if (!item.name || item.hidden) {
return;
} else {
item.hidden = item.hidden ? item.hidden : !obj[item.name];
// 如果该节点要显示,则获取到该节点的父节点并显示该父节点
// if (!item.hidden) {
// // console.log(222, item);
// // debugger;
// let parent = that.findParent(item.name, flattenRouterData);
// console.log(111, parent);
// }
if (item.children) {
getNewMenu(item.children);
}
}
});
return arr;
}
// console.log(obj);
return newMenu;
},
activeMenu() {
const route = this.$route
const { meta, path } = route
const route = this.$route;
const { meta, path } = route;
// if set path, the sidebar will highlight the path you set
if (meta.activeMenu) {
return meta.activeMenu
return meta.activeMenu;
}
return path
return path;
},
showLogo() {
return this.$store.state.settings.sidebarLogo
return this.$store.state.settings.sidebarLogo;
},
variables() {
return variables
return variables;
},
isCollapse() {
return !this.sidebar.opened
}
}
}
return !this.sidebar.opened;
},
},
methods: {
// 1. 为子节点添加父级的key
addParentKeyWrapper(tree) {
// debugger
const data = JSON.parse(JSON.stringify(tree)); // 深度克隆(deepClone)
function addParentKey(data, parentKey) {
data.forEach((ele) => {
ele.parent = parentKey;
if (ele.children) {
addParentKey(ele.children, ele.name);
}
});
}
addParentKey(data, null); // 一开始的时候是null
return data;
},
// 将树拉平,节点之间通过parentKey联系
flattenTreeDataClosure(data) {
const treeData = JSON.parse(JSON.stringify(data));
const flattenData = [];
function flattenTree(data, parentKey) {
data.forEach((ele) => {
// const { name } = ele;
flattenData.push({ name: ele.name, parentKey });
if (ele.children) {
flattenTree(ele.children, ele.name);
}
});
}
flattenTree(treeData, null);
return flattenData;
},
// 找到某个元素的父节点
findParent(item, flattenTree) {
return flattenTree.find((ele) => {
return ele.name === item;
});
},
},
};
</script>
......@@ -45,11 +45,12 @@ export const constantRoutes = [{
{
path: '/',
component: Layout,
redirect: '/dashboard',
redirect: '/home',
name:'HomeMenu',
children: [{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index'),
path: 'home',
name: 'Home',
component: () => import('@/views/home/index'),
meta: {
title: '首页',
icon: 'dashboard'
......@@ -59,6 +60,7 @@ export const constantRoutes = [{
{
path: '/display',
component: Layout,
name:'DisplayMenu',
children: [{
path: 'display',
name: 'Display',
......@@ -72,6 +74,7 @@ export const constantRoutes = [{
{
path: '/boutique',
component: Layout,
name:'BoutiqueMenu',
children: [{
path: 'boutique',
name: 'Boutique',
......@@ -85,6 +88,7 @@ export const constantRoutes = [{
{
path: '/culturalRelic',
component: Layout,
name:'CulturalRelicMenu',
children: [{
path: 'culturalRelic',
name: 'CulturalRelic',
......@@ -98,6 +102,7 @@ export const constantRoutes = [{
{
path: '/museum',
component: Layout,
name:'MuseumRelicMenu',
children: [{
path: 'museum',
name: 'Museum',
......@@ -111,9 +116,10 @@ export const constantRoutes = [{
{
path: '/virtual',
component: Layout,
name:'VirtualMenu',
children: [{
path: 'virtual',
name: 'virtual',
name: 'Virtual',
component: () => import('@/views/virtual/index'),
meta: {
title: '虚拟展厅',
......@@ -124,9 +130,10 @@ export const constantRoutes = [{
{
path: '/literature',
component: Layout,
name:'LiteratureMenu',
children: [{
path: 'literature',
name: 'literature',
name: 'Literature',
component: () => import('@/views/literature/index'),
meta: {
title: '文献管理',
......@@ -137,6 +144,7 @@ export const constantRoutes = [{
{
path: '/log',
component: Layout,
name:'LogMenu',
children: [{
path: 'log',
name: 'Log',
......@@ -150,6 +158,7 @@ export const constantRoutes = [{
{
path: '/importExport',
component: Layout,
name:'ImportExportMenu',
children: [{
path: 'importExport',
name: 'ImportExport',
......@@ -161,112 +170,6 @@ export const constantRoutes = [{
}]
},
// {
// path: '/example',
// component: Layout,
// redirect: '/example/table',
// name: 'Example',
// meta: { title: 'Example', icon: 'el-icon-s-help' },
// children: [
// {
// path: 'table',
// name: 'Table',
// component: () => import('@/views/table/index'),
// meta: { title: 'Table', icon: 'table' }
// },
// {
// path: 'tree',
// name: 'Tree',
// component: () => import('@/views/tree/index'),
// meta: { title: 'Tree', icon: 'tree' }
// }
// ]
// },
// {
// path: '/form',
// component: Layout,
// children: [
// {
// path: 'index',
// name: 'Form',
// component: () => import('@/views/form/index'),
// meta: { title: 'Form', icon: 'form' }
// }
// ]
// },
// {
// path: '/nested',
// component: Layout,
// redirect: '/nested/menu1',
// name: 'Nested',
// meta: {
// title: 'Nested',
// icon: 'nested'
// },
// children: [
// {
// path: 'menu1',
// component: () => import('@/views/nested/menu1/index'), // Parent router-view
// name: 'Menu1',
// meta: { title: 'Menu1' },
// children: [
// {
// path: 'menu1-1',
// component: () => import('@/views/nested/menu1/menu1-1'),
// name: 'Menu1-1',
// meta: { title: 'Menu1-1' }
// },
// {
// path: 'menu1-2',
// component: () => import('@/views/nested/menu1/menu1-2'),
// name: 'Menu1-2',
// meta: { title: 'Menu1-2' },
// children: [
// {
// path: 'menu1-2-1',
// component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
// name: 'Menu1-2-1',
// meta: { title: 'Menu1-2-1' }
// },
// {
// path: 'menu1-2-2',
// component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
// name: 'Menu1-2-2',
// meta: { title: 'Menu1-2-2' }
// }
// ]
// },
// {
// path: 'menu1-3',
// component: () => import('@/views/nested/menu1/menu1-3'),
// name: 'Menu1-3',
// meta: { title: 'Menu1-3' }
// }
// ]
// },
// {
// path: 'menu2',
// component: () => import('@/views/nested/menu2/index'),
// name: 'Menu2',
// meta: { title: 'menu2' }
// }
// ]
// },
// {
// path: 'external-link',
// component: Layout,
// children: [
// {
// path: 'https://panjiachen.github.io/vue-element-admin-site/#/',
// meta: { title: 'External Link', icon: 'link' }
// }
// ]
// },
// 404 page must be placed at the end !!!
{
path: '*',
......
const getters = {
sidebar: state => state.app.sidebar,
device: state => state.app.device,
token: state => state.user.token,
userInfo: state => state.user.userInfo,
avatar: state => state.user.avatar,
name: state => state.user.name,
menu: state => state.user.menu,
dicts: state => state.dict.dicts,
museumTree: state => state.org.museumTree
museumTree: state => state.org.museumTree,
}
export default getters
import {
login,
logout,
getInfo
getMenu
} from '@/api/user'
import {
getToken,
......@@ -9,7 +9,10 @@ import {
removeToken,
getUserInfo,
setUserInfo,
removeUserInfo
removeUserInfo,
setLocalMenu,
getLocalMenu,
removeLocalMenu
} from '@/utils/auth'
import {
resetRouter
......@@ -18,10 +21,10 @@ import {
const getDefaultState = () => {
return {
token: getToken(),
userInfo:getUserInfo(),
userInfo: getUserInfo(),
menu:getLocalMenu(),
name: '',
avatar: '',
// deptList:{}
}
}
......@@ -43,9 +46,9 @@ const mutations = {
SET_USERINFO: (state, userInfo) => {
state.userInfo = userInfo
},
// SET_DEPTLIST:(state,deptList)=>{
// state.deptList = deptList
// }
SET_MENU:(state,menu)=>{
state.menu = menu
}
}
const actions = {
......@@ -79,35 +82,6 @@ const actions = {
})
},
// get user info
// getInfo({
// commit,
// state
// }) {
// return new Promise((resolve, reject) => {
// getInfo(state.token).then(response => {
// const {
// data
// } = response
// if (!data) {
// return reject('Verification failed, please Login again.')
// }
// const {
// name,
// avatar
// } = data
// commit('SET_NAME', name)
// commit('SET_AVATAR', avatar)
// resolve(data)
// }).catch(error => {
// reject(error)
// })
// })
// },
// user logout
logout({
commit,
......@@ -117,11 +91,12 @@ const actions = {
logout(state.token).then(() => {
removeToken() // must remove token first
removeUserInfo()
removeLocalMenu()
resetRouter()
commit('RESET_STATE')
resolve()
}).catch(error => {
console.log('err',error);
console.log('err', error);
// reject(error)
})
})
......@@ -138,22 +113,25 @@ const actions = {
})
},
// getDeptList({
// commit,
// state
// }) {
// return new Promise((resolve, reject) => {
// let deptRes = await getDepList();
// let deptList = {};
// deptRes.data.map((dept) => {
// deptList[dept[id]] = {
// name: dept.name,
// regionCode: dept.regionCode,
// };
// });
// this.$store.commit('SET_DEPTLIST',deptList)
// })
// },
getMenuList({
commit
}) {
console.log('getMenuList');
return new Promise((resolve, reject) => {
getMenu().then((res) => {
console.log(res);
const {
menus
} = res.data
commit('SET_MENU', menus)
setLocalMenu(menus)
resolve()
}).catch(error => {
reject(error)
})
})
}
}
......
......@@ -2,6 +2,7 @@ import Cookies from 'js-cookie'
const TokenKey = 'exhibition_token'
const UserInfoKey = 'exhibition_userInfo'
const MenuKey = 'exhibition_menu'
export function getToken() {
// return Cookies.get(TokenKey)
......@@ -9,7 +10,7 @@ export function getToken() {
}
export function setToken(token) {
return localStorage.setItem(TokenKey,token)
return localStorage.setItem(TokenKey, token)
// return Cookies.set(TokenKey, token)
}
......@@ -18,16 +19,27 @@ export function removeToken() {
localStorage.removeItem(TokenKey)
}
export function setUserInfo(userInfo){
return localStorage.setItem(UserInfoKey,JSON.stringify(userInfo))
export function setUserInfo(userInfo) {
return localStorage.setItem(UserInfoKey, JSON.stringify(userInfo))
}
export function getUserInfo() {
// return Cookies.get(TokenKey)
return JSON.parse(localStorage.getItem(UserInfoKey))
}
export function removeUserInfo() {
// return Cookies.remove(TokenKey)
localStorage.removeItem(UserInfoKey)
}
export function setLocalMenu(menu) {
return localStorage.setItem(MenuKey, JSON.stringify(menu))
}
export function getLocalMenu() {
return JSON.parse(localStorage.getItem(MenuKey))
}
export function removeLocalMenu() {
localStorage.removeItem(MenuKey)
}
......@@ -95,6 +95,7 @@ export default {
.dialog-footer {
display: flex;
justify-content: flex-end;
margin-top: 40px;
}
}
......
<!-- -->
<template>
<div class="display-detail">
<div class="wrapper">
<div class="back">
<el-button type="text" icon="el-icon-arrow-left">返回上页</el-button>
</div>
<el-row class="detail-container" :gutter="30">
<el-col class="cr-images" :span="16">
<el-carousel
indicator-position="outside"
:autoplay="false"
height="600px"
>
<el-carousel-item
v-for="(item, index) in displayDetail.imagesVo"
:key="index"
>
<el-image
style="width: 100%; height: 100%"
:src="$getFullUrl(item.url)"
fit="contain"
></el-image>
</el-carousel-item>
</el-carousel>
<div class="enlarge" @click="handelPreviewImages">
<img src="@/assets/imgs/enlarge-s.png" alt="" />
</div>
</el-col>
<el-col class="relic-info" :span="8">
<div class="info-title">
<div
style="
display: flex;
align-items: center;
justify-content: space-between;
"
<div class="normal-style">
<NavBar />
<div class="display-detail">
<div class="wrapper">
<div class="back">
<el-button type="text" icon="el-icon-arrow-left">返回上页</el-button>
</div>
<el-row class="detail-container" :gutter="60">
<el-col class="cr-images" :span="16">
<el-carousel
indicator-position="outside"
:autoplay="false"
height="600px"
>
<h4>
{{ displayDetail.title }}
</h4>
<span class="view-container">
<svg-icon icon-class="view" class="view-svg-icon"></svg-icon>
<span class="view-text">{{ displayDetail.browseCount }}</span>
</span>
<el-carousel-item
v-for="(item, index) in displayDetail.imagesVo"
:key="index"
>
<el-image
style="width: 100%; height: 100%"
:src="$getFullUrl(item.url)"
fit="contain"
></el-image>
</el-carousel-item>
</el-carousel>
<div class="enlarge" @click="handelPreviewImages">
<img src="@/assets/imgs/enlarge-s.png" alt="" />
</div>
<AudioPlayer
:url="$getFullUrl(displayDetail.audiosVo[0].url)"
ref="AudioPlayer"
v-if="displayDetail.audiosVo && displayDetail.audiosVo.length > 0"
/>
</div>
<div class="info-body">
<div class="basic-info">
<div class="body-item">
<span class="label">关键词</span>
<span class="value">{{ displayDetail.keyword }}</span>
</div>
<div class="body-item">
<span class="label">展览类型</span>
<span class="value">{{
dicts.display_type[displayDetail.type]
}}</span>
</div>
<div class="body-item">
<span class="label">展览性质</span>
<span class="value">{{
dicts.display_character[displayDetail.displayCharacter]
}}</span>
</div>
<div class="body-item">
<span class="label">展览单位</span>
<span class="value">{{ displayDetail.deptName }}</span>
</div>
</div>
</div>
<ReaderOperations
:loveCount="displayDetail.loveCount"
:loveCountStatus="Boolean(displayDetail.loveCountStatus)"
:collectCount="displayDetail.collectCount"
:collectCountStatus="Boolean(displayDetail.collectCountStatus)"
:sourceId="displayDetail.exhibitionId"
:title="displayDetail.title"
:sourceType="'biz_exhibition'"
@reload="loadDetail"
/>
</el-col>
</el-row>
<div class="margin-bottom-32">
<CustomTitle text="展览介绍" />
<div class="intro text-indent">
{{ displayDetail.intro }}
</div>
</div>
<div
class="margin-bottom-32"
v-if="
displayDetail.exhibitionUnits &&
displayDetail.exhibitionUnits.length > 0
"
>
<CustomTitle text="展览单元" />
<el-row :gutter="20">
<el-col :span="8">
<!-- 只能单开 unique-opened -->
<menu-list
:items="displayDetail.exhibitionUnits"
:isCollapse="false"
@open="handleOpenUnit"
></menu-list>
</el-col>
<el-col :span="16">
<el-card>
<div slot="header" class="clearfix">
<span>单元介绍</span>
<el-col class="relic-info" :span="8">
<div class="info-title">
<div
style="
display: flex;
align-items: center;
justify-content: space-between;
"
>
<h4>
{{ displayDetail.title }}
</h4>
<span class="view-container">
<svg-icon icon-class="view" class="view-svg-icon"></svg-icon>
<span class="view-text">{{ displayDetail.browseCount }}</span>
</span>
</div>
<div class="unit-content">
<div class="intro text-indent" v-if="curUnit.intro">
{{ curUnit.intro }}
<NormalPlayer
:fileurl="$getFullUrl(displayDetail.audiosVo[0].url)"
ref="AudioPlayer"
v-if="
displayDetail.audiosVo && displayDetail.audiosVo.length > 0
"
/>
</div>
<div class="info-body">
<div class="basic-info">
<div class="body-item">
<span class="label">关键词</span>
<span class="value">{{ displayDetail.keyword }}</span>
</div>
<div class="body-item">
<span class="label">展览类型</span>
<span class="value">{{
dicts.display_type[displayDetail.type]
}}</span>
</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="$getFullUrl(item.url)"
alt=""
srcset=""
width="100%"
/>
<div class="desc flex-center">
{{ item.name }}
</div>
</el-col>
</el-row>
<div class="body-item">
<span class="label">展览性质</span>
<span class="value">{{
dicts.display_character[displayDetail.displayCharacter]
}}</span>
</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="$getFullUrl(item.url)" />
</el-col>
</el-row>
<div class="body-item">
<span class="label">展览单位</span>
<span class="value">{{ displayDetail.deptName }}</span>
</div>
</div>
</el-card>
</div>
<ReaderOperations
:loveCount="displayDetail.loveCount"
:loveCountStatus="Boolean(displayDetail.loveCountStatus)"
:collectCount="displayDetail.collectCount"
:collectCountStatus="Boolean(displayDetail.collectCountStatus)"
:sourceId="displayDetail.exhibitionId"
:title="displayDetail.title"
:sourceType="'biz_exhibition'"
@reload="loadDetail"
/>
</el-col>
</el-row>
</div>
<div
class="margin-bottom-32"
v-if="
displayDetail.culturalRelicVo &&
displayDetail.culturalRelicVo.length > 0
"
>
<CustomTitle text="关联文物" />
<el-row :gutter="20">
<el-col
:span="6"
v-for="(item, index) in displayDetail.culturalRelicVo"
:key="index"
>
<Card :title="item.name" :url="$getFullUrl(item.faceImageUrl)"
/></el-col>
</el-row>
</div>
<div
class="relate-video margin-bottom-32"
v-if="displayDetail.videosVo && displayDetail.videosVo.length > 0"
>
<CustomTitle text="关联视频" />
<el-carousel :interval="4000" type="card" height="400px">
<el-carousel-item
v-for="item in displayDetail.videosVo"
:key="item.fileId"
>
<div class="video-container">
<div class="video-box">
<Video :url="$getFullUrl(item.url)" />
<div class="margin-bottom-32 intro">
<CustomTitle text="展览介绍" />
<div class="text-indent intro_text">
{{ displayDetail.intro }}
</div>
</div>
<div
class="margin-bottom-32 unit"
v-if="
displayDetail.exhibitionUnits &&
displayDetail.exhibitionUnits.length > 0
"
>
<CustomTitle text="展览单元" />
<el-row :gutter="40">
<el-col :span="8">
<!-- 只能单开 unique-opened -->
<menu-list
:items="displayDetail.exhibitionUnits"
:isCollapse="false"
@open="handleOpenUnit"
></menu-list>
</el-col>
<el-col :span="16" class="unit-content">
<div class="text-indent unit-content_intro" v-if="curUnit.intro">
{{ curUnit.intro }}
</div>
<div class="info-box">
<h4 class="name">{{ item.name.split(".")[0] }}</h4>
<div
class="unit-content_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="$getFullUrl(item.url)" width="100%" />
<div class="unit-content_images_desc">
{{ item.name }}
</div>
</el-col>
</el-row>
</div>
</div>
</el-carousel-item>
</el-carousel>
</div>
<div class="relate-book margin-bottom-32">
<CustomTitle text="相关文献" />
<div
class="unit-content_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="$getFullUrl(item.url)" />
</el-col>
</el-row>
</div>
</el-col>
</el-row>
</div>
<div
class="book-item"
v-for="(item, index) in displayDetail.literatureVo"
:key="index"
class="margin-bottom-32"
v-if="
displayDetail.culturalRelicVo &&
displayDetail.culturalRelicVo.length > 0
"
>
<span class="mr-20">{{ item.name }}</span>
<span class="mr-20">{{ item.author }}</span>
<span>{{ item.source }}</span>
<CustomTitle text="关联文物" />
<el-row :gutter="20">
<el-col
:span="6"
v-for="(item, index) in displayDetail.culturalRelicVo"
:key="index"
>
<Card :title="item.name" :url="$getFullUrl(item.faceImageUrl)"
/></el-col>
</el-row>
</div>
</div>
<!-- <div class="relate-cultual-relic margin-bottom-32">
<div
class="relate-video margin-bottom-32"
v-if="displayDetail.videosVo && displayDetail.videosVo.length > 0"
>
<CustomTitle text="关联视频" />
<el-carousel :interval="4000" type="card" height="400px">
<el-carousel-item
v-for="item in displayDetail.videosVo"
:key="item.fileId"
>
<div class="video-container">
<div class="video-box">
<Video :url="$getFullUrl(item.url)" />
</div>
<div class="info-box">
<h4 class="name">{{ item.name.split(".")[0] }}</h4>
</div>
</div>
</el-carousel-item>
</el-carousel>
</div>
<div class="relate-book margin-bottom-32">
<CustomTitle text="相关文献" />
<div
class="book-item"
v-for="(item, index) in displayDetail.literatureVo"
:key="index"
>
<span class="mr-20">{{ item.name }}</span>
<span class="mr-20">{{ item.author }}</span>
<span>{{ item.source }}</span>
</div>
</div>
<!-- <div class="relate-cultual-relic margin-bottom-32">
<CustomTitle text="关联文物" />
<div class="display-group">
<div
......@@ -231,32 +223,40 @@
</div>
</div>
</div> -->
</div>
<el-image-viewer
v-if="imgViewerVisible"
:on-close="closeImgViewer"
:url-list="imgList"
/>
</div>
<el-image-viewer
v-if="imgViewerVisible"
:on-close="closeImgViewer"
:url-list="imgList"
/>
<Footer />
</div>
</template>
<script>
import AudioPlayer from "@/components/AudioPlayer";
// import AudioPlayer from "@/components/AudioPlayer";
import NormalPlayer from "@/components/AudioPlayer/NormalPlayer.vue";
import CustomTitle from "@/components/CustomTitle";
import ReaderOperations from "@/components/ReaderOperations";
import Card from "@/components/Card";
import Video from "@/components/Video";
// import QRCode from "qrcodejs2";
import MenuList from "@/components/MenuList";
import NavBar from "@/components/NavBar";
import Footer from "@/components/Footer";
import { mapGetters } from "vuex";
export default {
components: {
CustomTitle,
AudioPlayer,
// AudioPlayer,
NormalPlayer,
ReaderOperations,
MenuList,
Video,
Card,
NavBar,
Footer,
"el-image-viewer": () =>
import("element-ui/packages/image/src/image-viewer"),
},
......@@ -276,7 +276,6 @@ export default {
],
selectValue: "",
keyword: "",
displayDetail: {},
slideImageWidth: "",
imgViewerVisible: false,
relateRelics: [],
......@@ -305,6 +304,7 @@ export default {
},
loadDetail() {
if (Object.keys(this.displayDetail).length > 0) {
console.log(this.displayDetail);
if (
this.displayDetail.exhibitionUnits &&
this.displayDetail.exhibitionUnits.length > 0
......@@ -357,6 +357,7 @@ $label: #9f9c9a;
margin: 60px auto;
background-color: #fff;
padding: 60px;
// 返回按钮
.back {
font-size: 18px;
font-weight: bold;
......@@ -365,6 +366,8 @@ $label: #9f9c9a;
color: $label;
}
}
// 描述框
.detail-container {
margin-bottom: 32px;
// display: flex;
......@@ -372,6 +375,7 @@ $label: #9f9c9a;
max-width: 100%;
height: auto;
}
.cr-images {
width: 700px;
// margin-right: 32px;
......@@ -465,11 +469,35 @@ $label: #9f9c9a;
text-indent: 32px;
}
}
// 展览介绍
.intro {
.intro_text {
line-height: 30px;
}
}
// 布展单元
.unit {
.unit-content {
line-height: 30px;
.unit-content_intro {
margin-bottom: 20px;
}
.unit-content_images {
.unit-content_images_desc {
display: flex;
justify-content: center;
}
}
}
}
// 关联文献
.relate-book {
.book-item {
margin-bottom: 10px;
}
}
// 关联文物
.relate-cultual-relic {
.display-group {
margin-top: 24px;
......@@ -508,7 +536,7 @@ $label: #9f9c9a;
}
}
}
// 关联视频
.relate-video {
.video-container {
display: flex;
......
......@@ -237,15 +237,16 @@ export default {
}
},
async handleOperation(value, row) {
const { exhibitionId } = row;
switch (value.type) {
case "add":
this.editDialogVisible = true;
case "view":
this.previewDialogVisible = true;
this.curPreviewObj = row;
let res = await getDisplayById({ exhibitionId });
this.curPreviewObj = res.data;
break;
case "edit":
const { exhibitionId } = row;
let editRes = await getDisplayById({ exhibitionId });
this.form = editRes.data;
this.editDialogVisible = true;
......
<template>
<div class="app-container">
<el-form ref="form" :model="form" label-width="120px">
<el-form-item label="Activity name">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="Activity zone">
<el-select v-model="form.region" placeholder="please select your zone">
<el-option label="Zone one" value="shanghai" />
<el-option label="Zone two" value="beijing" />
</el-select>
</el-form-item>
<el-form-item label="Activity time">
<el-col :span="11">
<el-date-picker v-model="form.date1" type="date" placeholder="Pick a date" style="width: 100%;" />
</el-col>
<el-col :span="2" class="line">-</el-col>
<el-col :span="11">
<el-time-picker v-model="form.date2" type="fixed-time" placeholder="Pick a time" style="width: 100%;" />
</el-col>
</el-form-item>
<el-form-item label="Instant delivery">
<el-switch v-model="form.delivery" />
</el-form-item>
<el-form-item label="Activity type">
<el-checkbox-group v-model="form.type">
<el-checkbox label="Online activities" name="type" />
<el-checkbox label="Promotion activities" name="type" />
<el-checkbox label="Offline activities" name="type" />
<el-checkbox label="Simple brand exposure" name="type" />
</el-checkbox-group>
</el-form-item>
<el-form-item label="Resources">
<el-radio-group v-model="form.resource">
<el-radio label="Sponsor" />
<el-radio label="Venue" />
</el-radio-group>
</el-form-item>
<el-form-item label="Activity form">
<el-input v-model="form.desc" type="textarea" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">Create</el-button>
<el-button @click="onCancel">Cancel</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data() {
return {
form: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: ''
}
}
},
methods: {
onSubmit() {
this.$message('submit!')
},
onCancel() {
this.$message({
message: 'cancel!',
type: 'warning'
})
}
}
}
</script>
<style scoped>
.line{
text-align: center;
}
</style>
......@@ -8,7 +8,7 @@
import { mapGetters } from 'vuex'
export default {
name: 'Dashboard',
name: 'Home',
computed: {
...mapGetters([
'name'
......
......@@ -156,7 +156,9 @@ export default {
this.loading = true;
this.$store
.dispatch("user/login", this.loginForm)
.then(() => {
.then(async() => {
// debugger
await this.$store.dispatch('user/getMenuList')
this.$router.push({ path: this.redirect || "/" });
this.loading = false;
})
......
<template>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1">
<router-view />
</el-alert>
</div>
</template>
<template>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-1" type="success">
<router-view />
</el-alert>
</div>
</template>
<template>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-2" type="success">
<router-view />
</el-alert>
</div>
</template>
<template functional>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-2-1" type="warning" />
</div>
</template>
<template functional>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-2-2" type="warning" />
</div>
</template>
<template functional>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-3" type="success" />
</div>
</template>
<template>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 2" />
</div>
</template>
<template>
<div class="app-container">
<el-table
v-loading="listLoading"
:data="list"
element-loading-text="Loading"
border
fit
highlight-current-row
>
<el-table-column align="center" label="ID" width="95">
<template slot-scope="scope">
{{ scope.$index }}
</template>
</el-table-column>
<el-table-column label="Title">
<template slot-scope="scope">
{{ scope.row.title }}
</template>
</el-table-column>
<el-table-column label="Author" width="110" align="center">
<template slot-scope="scope">
<span>{{ scope.row.author }}</span>
</template>
</el-table-column>
<el-table-column label="Pageviews" width="110" align="center">
<template slot-scope="scope">
{{ scope.row.pageviews }}
</template>
</el-table-column>
<el-table-column class-name="status-col" label="Status" width="110" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" prop="created_at" label="Display_time" width="200">
<template slot-scope="scope">
<i class="el-icon-time" />
<span>{{ scope.row.display_time }}</span>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import { getList } from '@/api/dict'
export default {
filters: {
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'gray',
deleted: 'danger'
}
return statusMap[status]
}
},
data() {
return {
list: null,
listLoading: true
}
},
created() {
this.fetchData()
},
methods: {
fetchData() {
this.listLoading = true
getList().then(response => {
this.list = response.data.items
this.listLoading = false
})
}
}
}
</script>
<template>
<div class="app-container">
<el-input v-model="filterText" placeholder="Filter keyword" style="margin-bottom:30px;" />
<el-tree
ref="tree2"
:data="data2"
:props="defaultProps"
:filter-node-method="filterNode"
class="filter-tree"
default-expand-all
/>
</div>
</template>
<script>
export default {
data() {
return {
filterText: '',
data2: [{
id: 1,
label: 'Level one 1',
children: [{
id: 4,
label: 'Level two 1-1',
children: [{
id: 9,
label: 'Level three 1-1-1'
}, {
id: 10,
label: 'Level three 1-1-2'
}]
}]
}, {
id: 2,
label: 'Level one 2',
children: [{
id: 5,
label: 'Level two 2-1'
}, {
id: 6,
label: 'Level two 2-2'
}]
}, {
id: 3,
label: 'Level one 3',
children: [{
id: 7,
label: 'Level two 3-1'
}, {
id: 8,
label: 'Level two 3-2'
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
}
},
watch: {
filterText(val) {
this.$refs.tree2.filter(val)
}
},
methods: {
filterNode(value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
}
}
}
</script>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论