2020-06-19 17:10:44 +08:00
|
|
|
<template>
|
|
|
|
<el-row justify="space-between" type="flex">
|
|
|
|
<el-col>
|
2020-08-21 15:26:04 +08:00
|
|
|
<el-col :xs="8" :sm="4" :md="4" :xl="3" style="padding-top: .5rem;text-align: left;">
|
2020-08-12 11:28:37 +08:00
|
|
|
<a rel="nofollow" class="navbar-brand" href="/">
|
2020-06-19 17:10:44 +08:00
|
|
|
<img src="@/assets/rymcu.png" alt="RYMCU" class="navbar-brand-img">
|
|
|
|
</a>
|
|
|
|
</el-col>
|
2020-11-30 23:56:08 +08:00
|
|
|
<el-col :xs="0" :sm="8" :md="8" :xl="12" style="text-align: center;">
|
2020-06-19 17:10:44 +08:00
|
|
|
<el-row type="flex" justify="center">
|
|
|
|
<el-col>
|
2020-11-30 23:56:08 +08:00
|
|
|
<el-menu :default-active="activeMenu" style="margin-top: -2px;border: 0;" mode="horizontal"
|
2020-06-19 17:10:44 +08:00
|
|
|
@select="handleSelectMenu">
|
2020-06-29 21:30:58 +08:00
|
|
|
<el-menu-item index="index">首页</el-menu-item>
|
2020-06-19 17:10:44 +08:00
|
|
|
<el-menu-item index="topic">专题</el-menu-item>
|
2021-03-06 21:29:35 +08:00
|
|
|
<el-menu-item index="portfolios">作品集</el-menu-item>
|
2020-06-19 17:10:44 +08:00
|
|
|
</el-menu>
|
|
|
|
</el-col>
|
|
|
|
</el-row>
|
|
|
|
</el-col>
|
2021-05-30 12:08:20 +08:00
|
|
|
<el-col :xs="16" :sm="12" :md="12" :xl="9" style="padding-top: 1rem;">
|
2020-08-02 00:25:44 +08:00
|
|
|
<client-only>
|
2020-08-21 15:26:04 +08:00
|
|
|
<el-col v-if="user" style="text-align: right;">
|
2021-05-30 12:08:20 +08:00
|
|
|
<el-popover
|
|
|
|
placement="bottom"
|
|
|
|
width="400"
|
|
|
|
trigger="click"
|
|
|
|
v-model="showPopover"
|
|
|
|
@show="handleShowPopover">
|
|
|
|
<el-input id="searchInput" v-model="queryString" @keyup.enter.native="querySearchAsync" placeholder="搜索文章,作品集,用户"
|
|
|
|
:autofocus="autofocus">
|
|
|
|
<el-button slot="append" icon="el-icon-search" @click="querySearchAsync"></el-button>
|
|
|
|
</el-input>
|
|
|
|
<el-button slot="reference" icon="el-icon-search" circle size="small"></el-button>
|
|
|
|
</el-popover>
|
2020-11-30 23:56:08 +08:00
|
|
|
<el-link rel="nofollow" :underline="false" style="padding-left: 10px;padding-right: 10px;"
|
|
|
|
href="/portfolio/post">创建作品集
|
2020-08-02 00:25:44 +08:00
|
|
|
</el-link>
|
2020-11-30 23:56:08 +08:00
|
|
|
<el-link rel="nofollow" :underline="false" style="padding-left: 10px;padding-right: 10px;"
|
|
|
|
href="/article/post">发帖
|
2020-08-02 00:25:44 +08:00
|
|
|
</el-link>
|
2020-08-12 11:28:37 +08:00
|
|
|
<el-link rel="nofollow" :underline="false" style="padding-left: 10px;padding-right: 10px;">
|
2020-08-02 00:25:44 +08:00
|
|
|
<el-dropdown trigger="click" @command="handleCommand">
|
|
|
|
<el-badge :value="notificationNumbers" class="item">
|
2020-08-12 11:28:37 +08:00
|
|
|
<el-link rel="nofollow" :underline="false" style="font-size: 1.4rem;" class="el-icon-bell"></el-link>
|
2020-08-02 00:25:44 +08:00
|
|
|
</el-badge>
|
|
|
|
<el-dropdown-menu slot="dropdown">
|
|
|
|
<el-dropdown-item v-for="notification in notifications" :key="notification.idNotification"
|
|
|
|
command="notification">{{ notification.dataSummary }}
|
|
|
|
</el-dropdown-item>
|
|
|
|
<el-dropdown-item command="notification">查看所有消息</el-dropdown-item>
|
|
|
|
</el-dropdown-menu>
|
|
|
|
</el-dropdown>
|
|
|
|
</el-link>
|
2020-08-12 11:28:37 +08:00
|
|
|
<el-link rel="nofollow" :underline="false" style="margin-left: 10px;">
|
2020-08-02 00:25:44 +08:00
|
|
|
<el-dropdown trigger="click" @command="handleCommand">
|
|
|
|
<el-avatar v-if="avatarURL" size="small" :src="avatarURL"></el-avatar>
|
2020-08-02 23:55:08 +08:00
|
|
|
<el-avatar v-else size="small" src="https://static.rymcu.com/article/1578475481946.png"></el-avatar>
|
2020-08-02 00:25:44 +08:00
|
|
|
<el-dropdown-menu slot="dropdown">
|
2020-11-18 15:57:32 +08:00
|
|
|
<el-dropdown-item style="align-items: center;">
|
2020-08-02 00:25:44 +08:00
|
|
|
<el-avatar class="mr-3" v-if="avatarURL" size="small" style="margin-top: 1rem;"
|
|
|
|
:src="avatarURL"></el-avatar>
|
|
|
|
<el-avatar class="mr-3" v-else size="small" style="margin-top: 1rem;"
|
2020-08-02 23:55:08 +08:00
|
|
|
src="https://static.rymcu.com/article/1578475481946.png"></el-avatar>
|
2020-11-30 23:56:08 +08:00
|
|
|
<el-link rel="nofollow" :underline="false" style="margin-left: 10px;margin-bottom: 1rem;">
|
|
|
|
{{ nickname }}
|
|
|
|
</el-link>
|
2020-08-02 00:25:44 +08:00
|
|
|
</el-dropdown-item>
|
2020-11-18 15:57:32 +08:00
|
|
|
<el-dropdown-item command="user">个人中心</el-dropdown-item>
|
2020-12-08 19:59:46 +08:00
|
|
|
<el-dropdown-item command="answer">每日一题</el-dropdown-item>
|
2020-12-15 17:32:06 +08:00
|
|
|
<el-dropdown-item command="drafts" divided>我的草稿</el-dropdown-item>
|
2020-11-30 20:42:24 +08:00
|
|
|
<el-dropdown-item command="wallet">我的钱包</el-dropdown-item>
|
2020-12-15 17:32:06 +08:00
|
|
|
<el-dropdown-item command="user-info" divided>设置</el-dropdown-item>
|
2020-12-10 22:30:57 +08:00
|
|
|
<el-dropdown-item v-if="hasPermissions" command="admin-dashboard">系统管理</el-dropdown-item>
|
2020-08-02 00:25:44 +08:00
|
|
|
<el-dropdown-item command="logout" divided>退出登录</el-dropdown-item>
|
|
|
|
</el-dropdown-menu>
|
|
|
|
</el-dropdown>
|
|
|
|
</el-link>
|
|
|
|
</el-col>
|
2020-08-21 15:26:04 +08:00
|
|
|
<el-col v-else style="text-align: right;">
|
2021-05-30 12:08:20 +08:00
|
|
|
<el-popover
|
|
|
|
placement="bottom"
|
|
|
|
width="400"
|
|
|
|
trigger="click"
|
|
|
|
v-model="showPopover">
|
|
|
|
<el-input v-model="queryString" @keyup.enter.native="querySearchAsync" placeholder="搜索文章,作品集,用户"
|
|
|
|
autofocus>
|
|
|
|
<el-button slot="append" icon="el-icon-search" @click="querySearchAsync"></el-button>
|
|
|
|
</el-input>
|
|
|
|
<el-button slot="reference" icon="el-icon-search" circle size="small"></el-button>
|
|
|
|
</el-popover>
|
2020-08-02 00:25:44 +08:00
|
|
|
<nuxt-link to="/login">
|
2020-08-12 11:28:37 +08:00
|
|
|
<el-link rel="nofollow" :underline="false" style="margin-left: 10px;">登录</el-link>
|
2020-08-02 00:25:44 +08:00
|
|
|
</nuxt-link>
|
|
|
|
<nuxt-link to="/register">
|
2020-08-12 11:28:37 +08:00
|
|
|
<el-link rel="nofollow" :underline="false" style="margin-left: 10px;">注册</el-link>
|
2020-08-02 00:25:44 +08:00
|
|
|
</nuxt-link>
|
|
|
|
</el-col>
|
|
|
|
</client-only>
|
2020-06-19 17:10:44 +08:00
|
|
|
</el-col>
|
|
|
|
</el-col>
|
|
|
|
</el-row>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
2020-11-30 23:56:08 +08:00
|
|
|
import {mapState} from 'vuex';
|
|
|
|
import {isBrowser} from '~/environment';
|
2021-03-25 21:48:05 +08:00
|
|
|
import sockClient from '~/plugins/sockjs';
|
2020-08-06 15:44:29 +08:00
|
|
|
|
2020-11-30 23:56:08 +08:00
|
|
|
const Cookie = process.client ? require('js-cookie') : undefined
|
|
|
|
export default {
|
|
|
|
name: "PcHeader",
|
|
|
|
computed: {
|
|
|
|
...mapState({
|
|
|
|
activeMenu: state => state.activeMenu,
|
2021-05-20 22:02:49 +08:00
|
|
|
user: state => state.oauth
|
2020-11-30 23:56:08 +08:00
|
|
|
}),
|
|
|
|
avatarURL() {
|
|
|
|
let _ts = this;
|
|
|
|
if (isBrowser) {
|
|
|
|
if (!_ts.$store.state.userInfo) {
|
|
|
|
let user = localStorage.getItem('user');
|
|
|
|
if (user) {
|
|
|
|
_ts.$store.commit('setUser', JSON.parse(user))
|
2020-08-06 15:44:29 +08:00
|
|
|
}
|
|
|
|
}
|
2020-06-19 17:10:44 +08:00
|
|
|
}
|
2020-11-30 23:56:08 +08:00
|
|
|
return _ts.$store.state.userInfo?.avatarURL;
|
2020-06-19 17:10:44 +08:00
|
|
|
},
|
2020-11-30 23:56:08 +08:00
|
|
|
nickname() {
|
|
|
|
let _ts = this;
|
|
|
|
if (isBrowser) {
|
|
|
|
if (!_ts.$store.state.userInfo) {
|
|
|
|
let user = localStorage.getItem('user');
|
|
|
|
if (user) {
|
|
|
|
_ts.$store.commit('setUser', JSON.parse(user))
|
|
|
|
}
|
|
|
|
}
|
2020-06-19 17:10:44 +08:00
|
|
|
}
|
2020-11-30 23:56:08 +08:00
|
|
|
return _ts.$store.state.userInfo?.nickname;
|
2020-06-19 17:10:44 +08:00
|
|
|
},
|
2021-03-26 10:44:54 +08:00
|
|
|
account() {
|
|
|
|
let _ts = this;
|
|
|
|
if (isBrowser) {
|
|
|
|
if (!_ts.$store.state.userInfo) {
|
|
|
|
let user = localStorage.getItem('user');
|
|
|
|
if (user) {
|
|
|
|
_ts.$store.commit('setUser', JSON.parse(user))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return _ts.$store.state.userInfo?.account;
|
|
|
|
},
|
2020-11-30 23:56:08 +08:00
|
|
|
hasPermissions() {
|
|
|
|
return this.$store.getters.hasPermissions('blog_admin');
|
|
|
|
}
|
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
queryString: '',
|
|
|
|
timeout: null,
|
|
|
|
show: false,
|
|
|
|
notifications: [],
|
2021-05-30 12:08:20 +08:00
|
|
|
notificationNumbers: "",
|
|
|
|
showPopover: false,
|
|
|
|
autofocus: false
|
2020-11-30 23:56:08 +08:00
|
|
|
};
|
|
|
|
},
|
|
|
|
watch: {
|
|
|
|
user: function () {
|
|
|
|
this.getUnreadNotifications();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
methods: {
|
2021-05-20 22:02:49 +08:00
|
|
|
querySearchAsync() {
|
|
|
|
this.$router.push({
|
|
|
|
path: `/search?q=${this.queryString}`
|
|
|
|
})
|
2021-05-30 12:08:20 +08:00
|
|
|
this.$set(this, 'showPopover', false);
|
|
|
|
this.$set(this, 'queryString', '');
|
|
|
|
},
|
|
|
|
handleShowPopover() {
|
|
|
|
setTimeout(function () {
|
|
|
|
document.getElementById("searchInput").focus()
|
|
|
|
}, 500);
|
2020-11-30 23:56:08 +08:00
|
|
|
},
|
|
|
|
handleSelectMenu(item) {
|
|
|
|
let _ts = this;
|
|
|
|
let activeMenu = _ts.$store.state.activeMenu;
|
|
|
|
if (activeMenu !== item) {
|
2020-07-31 17:40:17 +08:00
|
|
|
switch (item) {
|
2020-11-30 23:56:08 +08:00
|
|
|
case 'topic':
|
2020-07-31 17:40:17 +08:00
|
|
|
_ts.$router.push({
|
2021-02-03 16:10:57 +08:00
|
|
|
path: '/topic/news?page=1'
|
2020-07-31 17:40:17 +08:00
|
|
|
})
|
|
|
|
break;
|
2021-03-06 21:29:35 +08:00
|
|
|
case 'portfolios':
|
|
|
|
_ts.$router.push({
|
|
|
|
path: '/portfolios?page=1'
|
|
|
|
})
|
|
|
|
break;
|
2020-11-30 23:56:08 +08:00
|
|
|
case 'github':
|
|
|
|
window.open("https://github.com/rymcu");
|
|
|
|
return false;
|
2020-07-31 17:40:17 +08:00
|
|
|
break;
|
|
|
|
default:
|
2020-11-30 23:56:08 +08:00
|
|
|
_ts.$router.push(
|
|
|
|
{
|
|
|
|
path: '/'
|
|
|
|
}
|
|
|
|
)
|
2020-06-19 17:10:44 +08:00
|
|
|
}
|
2020-11-30 23:56:08 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
handleCommand(item) {
|
|
|
|
let _ts = this;
|
|
|
|
switch (item) {
|
|
|
|
case 'user':
|
|
|
|
_ts.$router.push({
|
2021-03-26 10:44:54 +08:00
|
|
|
path: '/user/' + _ts.account
|
2020-07-03 11:04:25 +08:00
|
|
|
})
|
2020-11-30 23:56:08 +08:00
|
|
|
break;
|
|
|
|
case 'user-info':
|
|
|
|
_ts.$router.push({
|
|
|
|
path: '/user/settings/account'
|
|
|
|
})
|
|
|
|
break;
|
|
|
|
case 'logout':
|
|
|
|
Cookie.remove('auth')
|
|
|
|
_ts.$store.commit('setAuth', null)
|
|
|
|
item = 'login';
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
_ts.$router.push({
|
|
|
|
name: item
|
|
|
|
})
|
|
|
|
}
|
|
|
|
},
|
|
|
|
getUnreadNotifications() {
|
|
|
|
let _ts = this;
|
|
|
|
if (_ts.user) {
|
|
|
|
_ts.$axios.$get('/api/notification/unread').then(function (res) {
|
|
|
|
if (res) {
|
|
|
|
_ts.$set(_ts, 'notifications', res.notifications);
|
|
|
|
_ts.$set(_ts, 'notificationNumbers', res.notifications.length == 0 ? "" : res.notifications.length);
|
|
|
|
}
|
|
|
|
})
|
2020-06-19 17:10:44 +08:00
|
|
|
}
|
2020-11-30 23:56:08 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
mounted() {
|
|
|
|
let user = this.user;
|
|
|
|
if (user) {
|
|
|
|
this.getUnreadNotifications();
|
2021-05-30 12:08:20 +08:00
|
|
|
// sockClient.initSocket(this.$store.state.userInfo);
|
2020-06-19 17:10:44 +08:00
|
|
|
}
|
|
|
|
}
|
2020-11-30 23:56:08 +08:00
|
|
|
|
|
|
|
}
|
2020-06-19 17:10:44 +08:00
|
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
2020-11-30 23:56:08 +08:00
|
|
|
.navbar-brand {
|
|
|
|
color: inherit;
|
|
|
|
margin-right: 1rem;
|
|
|
|
font-size: 1.25rem;
|
|
|
|
white-space: nowrap;
|
|
|
|
font-weight: 600;
|
|
|
|
padding: 0;
|
|
|
|
transition: .3s opacity;
|
|
|
|
line-height: 3rem;
|
|
|
|
}
|
2020-06-19 17:10:44 +08:00
|
|
|
|
2020-11-30 23:56:08 +08:00
|
|
|
.navbar-brand-img {
|
|
|
|
height: 3rem;
|
|
|
|
line-height: 3rem;
|
|
|
|
vertical-align: top;
|
|
|
|
width: auto;
|
|
|
|
}
|
|
|
|
|
|
|
|
.search-result-box {
|
|
|
|
min-width: 20vw !important;
|
|
|
|
}
|
|
|
|
|
|
|
|
.search-result-type {
|
|
|
|
padding-right: 5px;
|
|
|
|
}
|
2020-06-19 17:10:44 +08:00
|
|
|
</style>
|