446 lines
11 KiB
Vue
446 lines
11 KiB
Vue
<template>
|
|
<div>
|
|
<el-container>
|
|
<el-container>
|
|
<el-aside :class="show ? 'aside-show' : 'aside-hide'">
|
|
<el-menu router background-color="#282c34" :unique-opened="true" text-color="#fff" :default-active="$route.path"
|
|
:default-openeds="openeds">
|
|
<div v-for="item in menu" :key="item.id">
|
|
<el-menu-item :index="'/' + item.code" v-if="!item.children">
|
|
<span>{{ item.name }}</span>
|
|
</el-menu-item>
|
|
<el-submenu v-else :index="'/' + item.code">
|
|
<template slot="title">
|
|
<span>{{ item.name }}</span>
|
|
</template>
|
|
<el-menu-item :index="'/' + children.code" :key="children.id" v-for="children in item.children">
|
|
{{ children.name }}
|
|
</el-menu-item>
|
|
</el-submenu>
|
|
</div>
|
|
</el-menu>
|
|
</el-aside>
|
|
|
|
<el-main>
|
|
<div class="head">
|
|
<ul>
|
|
<li>
|
|
<div @click="add" class="add">
|
|
<i class="el-icon-s-unfold" v-if="show"></i>
|
|
<i class="el-icon-s-fold" v-else></i>
|
|
</div>
|
|
<div class="right">
|
|
<el-breadcrumb separator-class="el-icon-arrow-right">
|
|
<el-breadcrumb-item v-for="(item, index) in titie" :key="index">{{ item.name }}</el-breadcrumb-item>
|
|
</el-breadcrumb>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<div class="msg" @click="openMessage">
|
|
<el-badge :hidden="noReadNum == 0" :value="noReadNum" :max="99"><i class="el-icon-message"></i></el-badge>
|
|
</div>
|
|
<div style="margin-right: 10px;">{{ usernmae }}</div>
|
|
<div class="token" @click="hanleLogout">登出</div>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="box-card">
|
|
<router-view></router-view>
|
|
</div>
|
|
</el-main>
|
|
</el-container>
|
|
</el-container>
|
|
|
|
<el-dialog :visible.sync="showMsg" title="站内信" width="1100px" custom-class="vanmsgbox" @close="showMsg = false">
|
|
<div class="msgbox">
|
|
<el-tabs type="border-card" @tab-click="handleTabClick" v-model="curTopTab">
|
|
<el-tab-pane name="0">
|
|
<template #label>
|
|
<span>未读消息</span>
|
|
<span v-if="noReadNum !== 0" class="numtag">{{ noReadNum }}</span>
|
|
</template>
|
|
</el-tab-pane>
|
|
<el-tab-pane label="已读消息" name="1"></el-tab-pane>
|
|
</el-tabs>
|
|
<div class="listbox" v-loading="loading">
|
|
<div class="item" v-for="item in msgList">
|
|
<div class="title" :class="item.status ? '' : 'notread'">
|
|
<div class="tit">{{ item.title }}</div>
|
|
<span v-if="!item.status" class="not" @click="markRead(item)">标为已读</span>
|
|
<span v-else>已读</span>
|
|
</div>
|
|
<div class="info">
|
|
<div class="tit" v-if="item.content" v-html="item.content.replace(/\n/g,'<br/>')"></div>
|
|
<div class="time">{{ item.created_at }}</div>
|
|
</div>
|
|
</div>
|
|
<div v-if="msgList.length == 0 && !loading">
|
|
<el-empty description="暂无消息" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bottom">
|
|
<el-pagination
|
|
:current-page="page"
|
|
:page-sizes="[10, 20, 50, 100]"
|
|
:page-size="pageSize"
|
|
layout="prev, pager, next, sizes, total"
|
|
:total="total"
|
|
@current-change="handleCurrentChange"
|
|
@size-change="handleSizeChange">
|
|
</el-pagination>
|
|
</div>
|
|
|
|
</div>
|
|
</el-dialog>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
import { removeToken } from "@/util/auth"
|
|
import { getMenu } from "../api/menu.js"
|
|
import { websiteMessage, messageRead } from "../api/user.js"
|
|
|
|
export default {
|
|
mounted() {
|
|
getMenu().then((res) => {
|
|
this.menu = res.data.data
|
|
})
|
|
this.usernmae = localStorage.getItem('userName');
|
|
this.getNoReadNum()
|
|
},
|
|
data() {
|
|
return {
|
|
menu: [], // 侧边栏
|
|
show: false, // 导航栏折叠
|
|
levelData: [], // table导航栏
|
|
titie: [], // 面包屑
|
|
head: "", // 路由name
|
|
onindex: 0, // 索引
|
|
openeds: ["GOODS_MANAGE"],
|
|
usernmae: '',
|
|
noReadNum: 0,
|
|
total: 0,
|
|
msgList: [],
|
|
page: 1,
|
|
pageSize: 10,
|
|
showMsg: false,
|
|
curTopTab: '2',
|
|
loading: false
|
|
}
|
|
},
|
|
watch: {
|
|
// table构造
|
|
$route: {
|
|
handler: function (val) {
|
|
this.titie = val.matched;
|
|
this.head = val.name;
|
|
this.levelData.push({ name: val.name, path: val.path });
|
|
const newArr = [];
|
|
const obj = {};
|
|
for (var i = 0; i < this.levelData.length; i++) {
|
|
if (!obj[this.levelData[i].name]) {
|
|
newArr.push(this.levelData[i]);
|
|
obj[this.levelData[i].name] = true;
|
|
}
|
|
}
|
|
|
|
this.levelData = newArr;
|
|
},
|
|
deep: true,
|
|
immediate: true
|
|
}
|
|
},
|
|
methods: {
|
|
next() {
|
|
this.hanletop();
|
|
},
|
|
hanletop() {
|
|
document.getElementById("bottom").scrollIntoView({ behavior: "smooth" });
|
|
},
|
|
hanlebottom() {
|
|
document.getElementById("top").scrollIntoView({ behavior: "smooth" });
|
|
},
|
|
hanleLogout() {
|
|
removeToken();
|
|
localStorage.removeItem('token')
|
|
localStorage.removeItem('userName')
|
|
this.$router.push({ path: "/Login" })
|
|
},
|
|
handlerclick(e) {
|
|
if (this.$route.path !== e) {
|
|
this.$router.push({ path: e });
|
|
}
|
|
},
|
|
add() {
|
|
this.show = !this.show;
|
|
},
|
|
hanblDelete(index, titie) {
|
|
var list = this.levelData[index].name;
|
|
|
|
this.onindex = index;
|
|
this.levelData.splice(this.onindex, 1);
|
|
if (titie === this.head) {
|
|
var item;
|
|
var name;
|
|
for (let i = 0; i < this.levelData.length; i++) {
|
|
item = this.levelData[i].path;
|
|
name = this.levelData[i].name;
|
|
}
|
|
if (this.levelData.length) {
|
|
if (name !== list) {
|
|
this.$router.push({ path: item });
|
|
}
|
|
}
|
|
}
|
|
},
|
|
getNoReadNum() {
|
|
let params = {
|
|
page: 1,
|
|
status: 0
|
|
}
|
|
websiteMessage(params).then((res) => {
|
|
this.noReadNum = res.data.meta.total
|
|
})
|
|
},
|
|
openMessage() {
|
|
this.curTopTab = '0'
|
|
this.showMsg = true
|
|
this.page = 1
|
|
this.getMsgList()
|
|
},
|
|
getMsgList() {
|
|
this.loading = true
|
|
let params = {
|
|
page: this.page,
|
|
per_page: this.pageSize,
|
|
status: this.curTopTab == '2' ? '' : this.curTopTab
|
|
}
|
|
websiteMessage(params).then((res) => {
|
|
this.msgList = res.data.data
|
|
this.total = res.data.meta.total
|
|
this.loading = false
|
|
}).catch(() => {
|
|
this.loading = false
|
|
})
|
|
},
|
|
handleTabClick() {
|
|
this.page = 1
|
|
this.getMsgList()
|
|
},
|
|
markRead(item) {
|
|
messageRead(item.id, {status: 1}).then((res) => {
|
|
item.status = 1
|
|
this.getNoReadNum()
|
|
})
|
|
},
|
|
handleCurrentChange(e) {
|
|
this.page = e
|
|
this.getMsgList()
|
|
},
|
|
handleSizeChange(e) {
|
|
this.page = 1
|
|
this.pageSize = e
|
|
this.getMsgList()
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.aside-show {
|
|
transition: all 0.3s;
|
|
opacity: 0;
|
|
width: 0px !important;
|
|
}
|
|
|
|
.aside-hide {
|
|
transition: all 0.3s;
|
|
opacity: 1;
|
|
width: 200px !important;
|
|
}
|
|
|
|
.el-container {
|
|
height: 100vh;
|
|
}
|
|
|
|
.el-aside {
|
|
background-color: #d3dce6;
|
|
color: #333;
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
.el-aside::-webkit-scrollbar {
|
|
width: 8px;
|
|
/*对垂直流动条有效*/
|
|
}
|
|
|
|
.el-aside::-webkit-scrollbar-thumb {
|
|
background-color: rgba(144, 147, 153, 0.3);
|
|
border-radius: 20px;
|
|
}
|
|
|
|
.el-main {
|
|
background-color: #f0f2f5;
|
|
color: #333;
|
|
padding: 0 0 !important;
|
|
}
|
|
|
|
.el-main::-webkit-scrollbar {
|
|
width: 10px;
|
|
/*对垂直流动条有效*/
|
|
}
|
|
|
|
.el-main::-webkit-scrollbar-thumb {
|
|
background-color: rgba(144, 147, 153, 0.3);
|
|
}
|
|
|
|
.box-card {
|
|
min-height: calc(100vh - 120px);
|
|
margin: 10px;
|
|
}
|
|
|
|
.conent {
|
|
width: 100%;
|
|
min-height: calc(100vh - 200px);
|
|
position: relative;
|
|
}
|
|
|
|
.add {
|
|
cursor: pointer;
|
|
font-size: 16px;
|
|
color: #606266;
|
|
}
|
|
|
|
.head {
|
|
padding: 10px;
|
|
background-color: #fff;
|
|
border-bottom: 1px solid #f6f6f6;
|
|
box-shadow: 0 1px 4px rgb(0 21 41 / 8%);
|
|
ul {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
li {
|
|
display: flex;
|
|
align-items: center;
|
|
.right {
|
|
margin-left: 20px;
|
|
}
|
|
.token {
|
|
cursor: pointer;
|
|
}
|
|
.msg{
|
|
margin-right: 15px;
|
|
font-size: 20px;
|
|
cursor: pointer;
|
|
&:hover{
|
|
color: #409EFF;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.el-aside {
|
|
background: #282c34;
|
|
box-shadow: 2px 0 6px rgb(0 21 41 / 35%);
|
|
}
|
|
|
|
::v-deep .el-menu {
|
|
border: none;
|
|
}
|
|
|
|
.el-menu-item:hover {
|
|
outline: 0 !important;
|
|
background: #5470c6 !important;
|
|
}
|
|
|
|
.el-menu-item.is-active {
|
|
color: #fff !important;
|
|
background: #5470c6 !important;
|
|
}
|
|
|
|
.el-menu-item-group__title {
|
|
padding: 0 0 !important;
|
|
}
|
|
.msgbox{
|
|
padding: 20px;
|
|
.numtag{
|
|
padding: 1px 4px;
|
|
font-size: 12px;
|
|
background: #f00;
|
|
color: #fff;
|
|
margin-left: 10px;
|
|
border-radius: 50%;
|
|
}
|
|
.listbox{
|
|
height: 550px;
|
|
overflow: auto;
|
|
.item{
|
|
color: #555;
|
|
font-size: 14px;
|
|
padding: 20px 30px;
|
|
box-sizing: border-box;
|
|
border-bottom: 1px solid #D7D7D7;
|
|
.title{
|
|
margin-bottom: 10px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
position: relative;
|
|
&.notread::after{
|
|
position: absolute;
|
|
left: -14px;
|
|
width: 7px;
|
|
height: 7px;
|
|
border-radius: 50%;
|
|
top: 8px;
|
|
content: '';
|
|
background: #f00;
|
|
}
|
|
.tit{
|
|
font-size: 16px;
|
|
width: calc(100% - 150px);
|
|
}
|
|
span{
|
|
font-size: 12px;
|
|
color: #777;
|
|
&.not{
|
|
color: #409eff;
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
}
|
|
.info{
|
|
margin-bottom: 10px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
.tit{
|
|
font-size: 14px;
|
|
width: calc(100% - 200px);
|
|
}
|
|
.time{
|
|
font-size: 14px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.bottom{
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 20px 0;
|
|
border-top: 1px solid #D7D7D7;
|
|
}
|
|
::v-deep .vanmsgbox .el-tabs__content{
|
|
display: none;
|
|
}
|
|
::v-deep .vanmsgbox .el-tabs--border-card{
|
|
box-shadow: none;
|
|
}
|
|
::v-deep .vanmsgbox .el-dialog__body{
|
|
padding: 0 !important;
|
|
}
|
|
</style>
|