429 lines
10 KiB
Vue
429 lines
10 KiB
Vue
<template>
|
|
<div class="user-bar">
|
|
<div class="panel-item hidden-sm-and-down" @click="search">
|
|
<el-icon><sc-icon-Search /></el-icon>
|
|
</div>
|
|
<div class="screen panel-item hidden-sm-and-down" @click="screen">
|
|
<el-icon><sc-icon-Full /></el-icon>
|
|
</div>
|
|
<!-- <div class="tasks panel-item" @click="tasks">-->
|
|
<!-- <el-icon><el-icon-sort /></el-icon>-->
|
|
<!-- </div>-->
|
|
<div class="tasks panel-item">
|
|
<el-icon><sc-icon-Refresh /></el-icon>
|
|
</div>
|
|
<div class="msg panel-item" @click="showMsg">
|
|
<el-badge :hidden="unreadMsgNum.length==0" :value="unreadMsgNum.length" class="badge" type="danger">
|
|
<el-icon>
|
|
<!-- <el-icon-chat-dot-round />-->
|
|
<sc-icon-Bell />
|
|
</el-icon>
|
|
</el-badge>
|
|
<el-drawer title="新消息" v-model="msg" :size="400" append-to-body destroy-on-close>
|
|
<template #title>
|
|
<span class="msgTitle">新消息 <span class="msg-tag">{{unreadMsgNum.length>99?'99+':unreadMsgNum.length}}</span></span>
|
|
</template>
|
|
<el-container>
|
|
<el-main class="nopadding" v-loading="msgLoading" element-loading-text="加载中...">
|
|
<el-scrollbar>
|
|
<ul class="msg-list">
|
|
<li v-for="item in msgList" v-bind:key="item.id" @click.stop="msgClick(item)">
|
|
<a :href="item.link" target="_blank">
|
|
<div class="msg-list__icon">
|
|
<el-badge :is-dot="item.read_status?false:true" type="danger">
|
|
<el-avatar :size="40" icon="sc-icon-SmallBell"></el-avatar>
|
|
</el-badge>
|
|
</div>
|
|
<div class="msg-list__main">
|
|
<h2>{{item.title}}</h2>
|
|
<p>{{item.content}}</p>
|
|
</div>
|
|
<div class="msg-list__time">
|
|
<p>{{item.created_at}}</p>
|
|
</div>
|
|
</a>
|
|
</li>
|
|
<el-empty v-if="msgList.length==0" description="暂无新消息" :image-size="100"></el-empty>
|
|
</ul>
|
|
</el-scrollbar>
|
|
</el-main>
|
|
<el-footer>
|
|
<el-button type="primary">消息中心</el-button>
|
|
<el-button @click="markRead">全部设为已读</el-button>
|
|
</el-footer>
|
|
</el-container>
|
|
</el-drawer>
|
|
</div>
|
|
<el-dropdown ref="userDropdown" class="user userDropdown panel-item" trigger="click" @command="handleUser">
|
|
<div class="user-avatar">
|
|
<el-avatar :size="22" shape="circle" :src="this.$store.state.global.login_avatar"><span class="userName">{{ userNameF }}</span></el-avatar>
|
|
<label>{{ userName }}</label>
|
|
<el-icon class="el-icon--right"><el-icon-arrow-down /></el-icon>
|
|
</div>
|
|
<template #dropdown>
|
|
<div class="userView" style="width: 300px">
|
|
<div class="headerView">
|
|
<el-icon class="icon" size="18px"><sc-icon-User/></el-icon>
|
|
<span class="name">{{userName}}</span>
|
|
<span class="solid"></span>
|
|
<span class="account">{{userInfo.login_name}}</span>
|
|
</div>
|
|
<div class="itemBox">
|
|
<div class="name">邮箱</div>
|
|
<div class="text">{{userInfo.email}}</div>
|
|
</div>
|
|
<div class="itemBox">
|
|
<div class="name">手机号</div>
|
|
<div class="text">{{userInfo.mobile}}</div>
|
|
</div>
|
|
<div class="itemBox">
|
|
<div class="name">公司名称</div>
|
|
<div class="text">{{userInfo.company_info && userInfo.company_info.full_name?userInfo.company_info.full_name:''}}</div>
|
|
</div>
|
|
</div>
|
|
<div class="menuRow">
|
|
<div class="itemCol" @click="linkUser"><el-icon size="16"><sc-icon-AccountNumber/></el-icon><span class="name">帐号信息</span></div>
|
|
<div class="itemCol" @click="clearCache"><el-icon size="16"><sc-icon-ClearCache/></el-icon><span class="name">清除缓存</span></div>
|
|
</div>
|
|
<div class="loginOut">
|
|
<el-button class="btn" style="width: 100%" @click="loginOut">退出登录</el-button>
|
|
</div>
|
|
</template>
|
|
</el-dropdown>
|
|
</div>
|
|
|
|
<el-dialog v-model="searchVisible" :width="700" title="搜索" center destroy-on-close>
|
|
<search @success="searchVisible=false"></search>
|
|
</el-dialog>
|
|
|
|
<el-drawer v-model="tasksVisible" :size="450" title="任务中心" destroy-on-close>
|
|
<tasks></tasks>
|
|
</el-drawer>
|
|
|
|
</template>
|
|
|
|
<script>
|
|
import search from './search.vue'
|
|
import tasks from './tasks.vue'
|
|
import {eventBus} from "@/utils/eventBus";
|
|
|
|
export default {
|
|
components: {
|
|
search,
|
|
tasks
|
|
},
|
|
data() {
|
|
return {
|
|
userName: "",
|
|
userNameF: "",
|
|
userInfo:{},
|
|
searchVisible: false,
|
|
tasksVisible: false,
|
|
msg: false,
|
|
msgLoading:false,
|
|
msgList: [],
|
|
unreadMsgNum:[]
|
|
}
|
|
},
|
|
created() {
|
|
const userInfo = this.$TOOL.data.get("USER_INFO");
|
|
|
|
this.$store.commit("SET_LOGIN_AVATAR", userInfo.avatar);
|
|
this.$store.commit("SET_LOGIN_NAME", userInfo.name);
|
|
|
|
this.userInfo = userInfo;
|
|
this.userName = this.$store.state.global.login_name;
|
|
if(userInfo.company_info){
|
|
this.companyName = userInfo.company_info.name;
|
|
}
|
|
if(this.userName!=''){
|
|
this.userNameF = this.userName.substring(0, 1);
|
|
}
|
|
this.avatar = this.$store.state.global.login_avatar;
|
|
this.userId = userInfo.id;
|
|
},
|
|
mounted() {
|
|
// 获取新消息
|
|
eventBus.$on('sockBack', this.getWsResult);
|
|
},
|
|
unmounted() {
|
|
eventBus.$off('sockBack', this.getWsResult);
|
|
},
|
|
methods: {
|
|
//个人信息
|
|
handleUser(command) {
|
|
if (command == "cmd") {
|
|
this.$router.push({ path: '/cmd' });
|
|
}
|
|
},
|
|
linkUser(){
|
|
this.$refs.userDropdown.handleClose();
|
|
this.$router.push({ path: '/user/center' });
|
|
},
|
|
clearCache(){
|
|
this.$confirm('清除缓存会将系统初始化,包括登录状态、主题、语言设置等,是否继续?', '警告', {
|
|
type: 'warning',
|
|
}).then(async () => {
|
|
const loading = this.$loading()
|
|
const res = await this.$API.system.user.logout.post();
|
|
if (res.code == 200) {
|
|
this.$TOOL.data.clear()
|
|
this.$router.replace({path: '/login'});
|
|
setTimeout(() => {
|
|
loading.close()
|
|
location.reload()
|
|
}, 1000)
|
|
}
|
|
}).catch(() => {
|
|
//取消
|
|
})
|
|
},
|
|
loginOut(){
|
|
this.$confirm('确认是否退出当前用户?', '警告', {
|
|
type: 'warning',
|
|
confirmButtonText: '退出',
|
|
confirmButtonClass: 'el-button--danger'
|
|
}).then(async () => {
|
|
const res = await this.$API.system.user.logout.post();
|
|
if(res.code == 200){
|
|
this.$TOOL.data.clear();
|
|
this.$socketApi.closeSock(true);
|
|
this.$router.replace({path: '/login'});
|
|
}
|
|
}).catch(() => {
|
|
//取消退出
|
|
})
|
|
},
|
|
//全屏
|
|
screen() {
|
|
const element = document.documentElement;
|
|
this.$TOOL.screen(element);
|
|
},
|
|
//显示短消息
|
|
showMsg() {
|
|
this.msg = true
|
|
},
|
|
getWsResult(res){
|
|
if(res.data && res.data.type == 22){
|
|
if(res.data.list_backlog_info && res.data.list_backlog_info.length>0){
|
|
this.msgList = res.data.list_backlog_info;
|
|
this.unreadMsgNum = res.data.list_backlog_info.map(item=>!item.read_status).filter(em=>em);
|
|
}
|
|
}
|
|
},
|
|
async msgClick(em) {
|
|
if (em.read_status) {
|
|
return
|
|
}
|
|
let params = {
|
|
message_id: em.id,
|
|
is_read:true
|
|
}
|
|
this.msgLoading = true;
|
|
await this.$API.user.messages.read.post(params);
|
|
this.msgLoading = false;
|
|
this.msgList.forEach(item => {
|
|
if (item.id == em.id) {
|
|
item.is_read = true;
|
|
}
|
|
})
|
|
},
|
|
//标记已读
|
|
markRead() {
|
|
this.msgList = [];
|
|
},
|
|
//搜索
|
|
search() {
|
|
// this.searchVisible = true;
|
|
eventBus.$emit('tagClose','/view-search');
|
|
},
|
|
//任务
|
|
tasks() {
|
|
this.tasksVisible = true
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.badge{
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
.user-bar {
|
|
display: flex;
|
|
align-items: center;
|
|
height: 100%;
|
|
}
|
|
|
|
.user-bar .panel-item {
|
|
padding: 0 10px;
|
|
cursor: pointer;
|
|
height: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.user-bar .panel-item i {
|
|
font-size: 16px;
|
|
}
|
|
|
|
.user-bar .panel-item:hover {
|
|
background: rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.user-bar .user-avatar {
|
|
height: 49px;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.user-bar .user-avatar label {
|
|
display: inline-block;
|
|
margin-left: 5px;
|
|
font-size: 12px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.msg-list li {
|
|
border-top: 1px solid #eee;
|
|
}
|
|
|
|
.msg-list li a {
|
|
display: flex;
|
|
padding: 20px;
|
|
}
|
|
|
|
.msg-list li a:hover {
|
|
background: #ecf5ff;
|
|
}
|
|
|
|
.msg-list__icon {
|
|
width: 40px;
|
|
margin-right: 15px;
|
|
}
|
|
|
|
.msg-list__main {
|
|
flex: 1;
|
|
}
|
|
|
|
.msg-list__main h2 {
|
|
font-size: 15px;
|
|
font-weight: normal;
|
|
color: #333;
|
|
}
|
|
|
|
.msg-list__main p {
|
|
font-size: 12px;
|
|
color: #999;
|
|
line-height: 1.8;
|
|
margin-top: 5px;
|
|
}
|
|
|
|
.msg-list__time {
|
|
width: 100px;
|
|
text-align: right;
|
|
color: #999;
|
|
}
|
|
.userView{
|
|
background: #F5F7FA;
|
|
padding:10px;
|
|
border-top-left-radius: 4px;
|
|
border-top-right-radius: 4px;
|
|
border-bottom: 1px solid #EBEEF5;
|
|
.headerView{
|
|
padding: 0 6px;
|
|
display: flex;align-items: center;
|
|
margin-bottom: 10px;
|
|
.icon{
|
|
color: var(--el-color-primary);
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
.name{
|
|
font-size: 16px;font-weight: 500;
|
|
margin-left: 8px;
|
|
}
|
|
.solid{
|
|
width: 2px;
|
|
height: 18px;
|
|
background: var(--el-color-danger);
|
|
margin: 0 12px;
|
|
}
|
|
.account{
|
|
font-size: 14px;
|
|
}
|
|
}
|
|
.itemBox{
|
|
display: flex;align-items: center;
|
|
padding: 6px 6px;
|
|
font-size: 13px;
|
|
.name{
|
|
width: 65px;
|
|
color: #888;
|
|
}
|
|
.text{
|
|
flex: 1;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;
|
|
}
|
|
}
|
|
}
|
|
.menuRow{
|
|
padding: 10px;
|
|
.itemCol{
|
|
padding: 6px;
|
|
border-radius: 3px;
|
|
display: flex;
|
|
align-items: center;
|
|
color: #888;
|
|
border: 1px solid #fff;
|
|
.name{
|
|
margin-left: 10px;
|
|
}
|
|
}
|
|
.itemCol:hover{
|
|
background: #e7eff8;
|
|
border-color:#b8d1ec;
|
|
color: #1367C1; // #626266
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
.loginOut{
|
|
border-top: 1px solid #EBEEF5;
|
|
padding: 16px 10px;
|
|
.btn{
|
|
font-weight: inherit;
|
|
}
|
|
}
|
|
.msgTitle{
|
|
display: flex;align-items: center;
|
|
}
|
|
.msg-tag{
|
|
height: 18px;
|
|
line-height: 18px;
|
|
padding: 0 6px;
|
|
border-radius: 18px;
|
|
background: var(--el-color-danger);
|
|
color: var(--el-color-white);
|
|
font-size: 12px;
|
|
font-weight: initial;
|
|
margin-left: 15px;
|
|
}
|
|
|
|
.dark .msg-list__main h2 {
|
|
color: #d0d0d0;
|
|
}
|
|
|
|
.dark .msg-list li {
|
|
border-top: 1px solid #363636;
|
|
}
|
|
|
|
.dark .msg-list li a:hover {
|
|
background: #383838;
|
|
}
|
|
|
|
.el-popper.is-light ::v-deep .el-popper__arrow::before{
|
|
background: #F5F7FA !important;
|
|
}
|
|
|
|
</style>
|