first commit
This commit is contained in:
parent
4bf83cc3fe
commit
5a13c949fa
@ -1,42 +1,46 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-row class="footer">
|
<el-row class="footer">
|
||||||
<el-col style="text-align: center;">
|
<el-col style="text-align: center;">
|
||||||
<el-col :xs="24" :sm="24" :xl="12">
|
<el-col :xs="24" :sm="24" :xl="12">
|
||||||
<span>{{ slogan }}</span>
|
<span>{{ slogan }}</span>
|
||||||
<span>{{ slogan_en }}</span>
|
<span>{{ slogan_en }}</span>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="24" :xl="12">
|
<el-col :xs="24" :sm="24" :xl="12">
|
||||||
<el-col class="row align-items-center">
|
<el-col class="row align-items-center">
|
||||||
<el-col class="col-auto">
|
<el-col class="col-auto">
|
||||||
Copyright © 2020 <el-link :underline="false" href="/" style="vertical-align: baseline;"><span>{{ systemName }}</span></el-link>.
|
Copyright © 2020
|
||||||
<el-link :underline="false" href="http://www.beian.miit.gov.cn/" style="vertical-align: baseline;"><span>{{ beiAn }}</span></el-link>
|
<el-link :underline="false" href="/" style="vertical-align: baseline;"><span>{{ systemName }}</span>
|
||||||
</el-col>
|
</el-link>
|
||||||
</el-col>
|
.
|
||||||
</el-col>
|
<el-link :underline="false" href="http://www.beian.miit.gov.cn/" style="vertical-align: baseline;"><span>{{ beiAn }}</span>
|
||||||
|
</el-link>
|
||||||
|
</el-col>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-col>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "MobileFooter",
|
name: "MobileFooter",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
systemTitle: '\u7f57\u5409\u7f51\u0020\u002d\u0020\u5185\u5bb9\u5206\u4eab\u751f\u6001\u5e73\u53f0',
|
systemTitle: '\u7f57\u5409\u7f51\u0020\u002d\u0020\u5185\u5bb9\u5206\u4eab\u751f\u6001\u5e73\u53f0',
|
||||||
systemName: 'RYMCU',
|
systemName: 'RYMCU',
|
||||||
systemUrl: 'https://rymcu.com',
|
systemUrl: 'https://rymcu.com',
|
||||||
slogan: 'rymcu · 嵌入式知识学习交流平台 ',
|
slogan: 'rymcu · 嵌入式知识学习交流平台 ',
|
||||||
slogan_en: 'Embedded knowledge learning exchange platform',
|
slogan_en: 'Embedded knowledge learning exchange platform',
|
||||||
beiAn: '沪ICP备19042611号'
|
beiAn: '沪ICP备19042611号'
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.footer {
|
.footer {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,224 +1,242 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-row justify="space-between" type="flex">
|
<el-row justify="space-between" type="flex">
|
||||||
<el-col>
|
<el-col>
|
||||||
<el-col :xs="8" :sm="4" :md="4" :xl="3" style="padding-top: 1rem;">
|
<el-col :xs="8" :sm="4" :md="4" :xl="3" style="padding-top: 1rem;">
|
||||||
<a class="navbar-brand" href="/">
|
<a class="navbar-brand" href="/">
|
||||||
<img src="@/assets/rymcu.png" alt="RYMCU" class="navbar-brand-img">
|
<img src="@/assets/rymcu.png" alt="RYMCU" class="navbar-brand-img">
|
||||||
<span>RYMCU</span>
|
<span>RYMCU</span>
|
||||||
</a>
|
</a>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="0" :sm="12" :md="14" :xl="18" style="text-align: center;">
|
<el-col :xs="0" :sm="12" :md="14" :xl="18" style="text-align: center;">
|
||||||
<el-row type="flex" justify="center">
|
<el-row type="flex" justify="center">
|
||||||
<el-col>
|
<el-col>
|
||||||
<el-menu :default-active="getActiveMenu" style="margin-top: -2px;border: 0;" mode="horizontal" @select="handleSelectMenu">
|
<el-menu :default-active="getActiveMenu" style="margin-top: -2px;border: 0;" mode="horizontal"
|
||||||
<el-menu-item index="home">首页</el-menu-item>
|
@select="handleSelectMenu">
|
||||||
<el-menu-item index="topic">专题</el-menu-item>
|
<el-menu-item index="index">首页</el-menu-item>
|
||||||
<el-menu-item index="github">开源代码</el-menu-item>
|
<el-menu-item index="topic">专题</el-menu-item>
|
||||||
<el-menu-item index="open-source">资料下载</el-menu-item>
|
<el-menu-item index="github">开源代码</el-menu-item>
|
||||||
</el-menu>
|
<el-menu-item index="open-source">资料下载</el-menu-item>
|
||||||
</el-col>
|
</el-menu>
|
||||||
</el-row>
|
</el-col>
|
||||||
</el-col>
|
</el-row>
|
||||||
<el-col :xs="16" :sm="8" :md="6" :xl="3" style="padding-top: 1rem;">
|
</el-col>
|
||||||
<!--<el-col :xs="24" :sm="16" :xl="12">-->
|
<el-col :xs="16" :sm="8" :md="6" :xl="3" style="padding-top: 1rem;">
|
||||||
<el-col :xs="0" :sm="0" :xl="0">
|
<!--<el-col :xs="24" :sm="16" :xl="12">-->
|
||||||
<el-autocomplete
|
<el-col :xs="0" :sm="0" :xl="0">
|
||||||
v-model="state"
|
<el-autocomplete
|
||||||
size="small"
|
v-model="state"
|
||||||
:fetch-suggestions="querySearchAsync"
|
size="small"
|
||||||
placeholder="搜索帖子、标签和用户"
|
:fetch-suggestions="querySearchAsync"
|
||||||
:trigger-on-focus="false"
|
placeholder="搜索帖子、标签和用户"
|
||||||
@select="handleSelect"
|
:trigger-on-focus="false"
|
||||||
/>
|
@select="handleSelect"
|
||||||
</el-col>
|
/>
|
||||||
<!--<el-col v-if="isLogin" :xs="0" :sm="8" :xl="6">-->
|
|
||||||
<el-col v-if="isLogin">
|
|
||||||
<el-link :underline="false" style="padding-left: 10px;padding-right: 10px;" href="/post-portfolio">创建作品集</el-link>
|
|
||||||
<el-link :underline="false" style="padding-left: 10px;padding-right: 10px;" href="/post-article">发帖</el-link>
|
|
||||||
<el-link :underline="false" style="padding-left: 10px;padding-right: 10px;">
|
|
||||||
<el-dropdown trigger="click" @command="handleCommand">
|
|
||||||
<el-badge :value="notificationNumbers" class="item">
|
|
||||||
<el-link :underline="false" style="font-size: 1.4rem;" class="el-icon-bell"></el-link>
|
|
||||||
</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>
|
|
||||||
<el-link :underline="false" style="margin-left: 10px;">
|
|
||||||
<el-dropdown trigger="click" @command="handleCommand">
|
|
||||||
<el-avatar v-if="avatarURL" size="small" :src="avatarURL"></el-avatar>
|
|
||||||
<el-avatar v-else size="small" src="https://rymcu.com/vertical/article/1578475481946.png"></el-avatar>
|
|
||||||
<el-dropdown-menu slot="dropdown">
|
|
||||||
<el-dropdown-item command="user" style="align-items: center;">
|
|
||||||
<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;" src="https://rymcu.com/vertical/article/1578475481946.png"></el-avatar>
|
|
||||||
<el-link :underline="false" style="margin-left: 10px;margin-bottom: 1rem;">{{ nickname }}</el-link>
|
|
||||||
</el-dropdown-item>
|
|
||||||
<el-dropdown-item v-show="hasPermissions" command="admin-dashboard">系统管理</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="user-info">资料与账号</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="drafts">我的草稿</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="logout" divided>退出登录</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</el-dropdown>
|
|
||||||
</el-link>
|
|
||||||
</el-col>
|
|
||||||
<el-col v-else>
|
|
||||||
<el-link :underline="false" style="margin-left: 10px;" href="/login">登录</el-link>
|
|
||||||
<el-link :underline="false" style="margin-left: 10px;" href="/register">注册</el-link>
|
|
||||||
</el-col>
|
|
||||||
</el-col>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
<!--<el-col v-if="isLogin" :xs="0" :sm="8" :xl="6">-->
|
||||||
|
<el-col v-if="isLogin">
|
||||||
|
<el-link :underline="false" style="padding-left: 10px;padding-right: 10px;" href="/post-portfolio">创建作品集
|
||||||
|
</el-link>
|
||||||
|
<el-link :underline="false" style="padding-left: 10px;padding-right: 10px;" href="/post-article">发帖</el-link>
|
||||||
|
<el-link :underline="false" style="padding-left: 10px;padding-right: 10px;">
|
||||||
|
<el-dropdown trigger="click" @command="handleCommand">
|
||||||
|
<el-badge :value="notificationNumbers" class="item">
|
||||||
|
<el-link :underline="false" style="font-size: 1.4rem;" class="el-icon-bell"></el-link>
|
||||||
|
</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>
|
||||||
|
<el-link :underline="false" style="margin-left: 10px;">
|
||||||
|
<el-dropdown trigger="click" @command="handleCommand">
|
||||||
|
<el-avatar v-if="avatarURL" size="small" :src="avatarURL"></el-avatar>
|
||||||
|
<el-avatar v-else size="small" src="https://rymcu.com/vertical/article/1578475481946.png"></el-avatar>
|
||||||
|
<el-dropdown-menu slot="dropdown">
|
||||||
|
<el-dropdown-item command="user" style="align-items: center;">
|
||||||
|
<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;"
|
||||||
|
src="https://rymcu.com/vertical/article/1578475481946.png"></el-avatar>
|
||||||
|
<el-link :underline="false" style="margin-left: 10px;margin-bottom: 1rem;">{{ nickname }}</el-link>
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item v-show="hasPermissions" command="admin-dashboard">系统管理</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="user-info">资料与账号</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="drafts">我的草稿</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="logout" divided>退出登录</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</el-dropdown>
|
||||||
|
</el-link>
|
||||||
|
</el-col>
|
||||||
|
<el-col v-else>
|
||||||
|
<nuxt-link to="/login">
|
||||||
|
<el-link :underline="false" style="margin-left: 10px;">登录</el-link>
|
||||||
|
</nuxt-link>
|
||||||
|
<nuxt-link to="/register">
|
||||||
|
<el-link :underline="false" style="margin-left: 10px;">注册</el-link>
|
||||||
|
</nuxt-link>
|
||||||
|
</el-col>
|
||||||
|
</el-col>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
const Cookie = process.client ? require('js-cookie') : undefined
|
||||||
name: "MobileHeader",
|
export default {
|
||||||
computed: {
|
name: "MobileHeader",
|
||||||
getActiveMenu () {
|
computed: {
|
||||||
return this.$store.state.activeMenu;
|
getActiveMenu() {
|
||||||
},
|
return this.$store.state.activeMenu;
|
||||||
isLogin () {
|
},
|
||||||
return this.$store.getters.isLogin;
|
isLogin() {
|
||||||
},
|
return this.$store.state.oauth;
|
||||||
avatarURL () {
|
},
|
||||||
return this.$store.state.avatarURL;
|
avatarURL() {
|
||||||
},
|
return this.$store.state.oauth?.avatarURL;
|
||||||
nickname() {
|
},
|
||||||
return this.$store.state.nickname;
|
nickname() {
|
||||||
},
|
return this.$store.state.oauth?.nickname;
|
||||||
hasPermissions () {
|
},
|
||||||
return this.$store.getters.hasPermissions('blog_admin');
|
hasPermissions() {
|
||||||
}
|
return this.$store.getters.hasPermissions('blog_admin');
|
||||||
},
|
}
|
||||||
data() {
|
},
|
||||||
return {
|
data() {
|
||||||
restaurants: [],
|
return {
|
||||||
state: '',
|
restaurants: [],
|
||||||
timeout: null,
|
state: '',
|
||||||
show: false,
|
timeout: null,
|
||||||
notifications: [],
|
show: false,
|
||||||
notificationNumbers: ""
|
notifications: [],
|
||||||
};
|
notificationNumbers: ""
|
||||||
},
|
};
|
||||||
watch: {
|
},
|
||||||
isLogin: function () {
|
watch: {
|
||||||
this.getUnreadNotifications();
|
isLogin: function () {
|
||||||
}
|
this.getUnreadNotifications();
|
||||||
},
|
}
|
||||||
methods: {
|
},
|
||||||
loadAll() {
|
methods: {
|
||||||
return [
|
loadAll() {
|
||||||
{ "value": "三全鲜食(北新泾店)", "address": "长宁区新渔路144号" },
|
return [
|
||||||
{ "value": "Hot honey 首尔炸鸡(仙霞路)", "address": "上海市长宁区淞虹路661号" },
|
{"value": "三全鲜食(北新泾店)", "address": "长宁区新渔路144号"},
|
||||||
{ "value": "新旺角茶餐厅", "address": "上海市普陀区真北路988号创邑金沙谷6号楼113" }
|
{"value": "Hot honey 首尔炸鸡(仙霞路)", "address": "上海市长宁区淞虹路661号"},
|
||||||
]
|
{"value": "新旺角茶餐厅", "address": "上海市普陀区真北路988号创邑金沙谷6号楼113"}
|
||||||
},
|
]
|
||||||
querySearchAsync(queryString, cb) {
|
},
|
||||||
let restaurants = this.restaurants;
|
querySearchAsync(queryString, cb) {
|
||||||
let results = queryString ? restaurants.filter(this.createStateFilter(queryString)) : restaurants;
|
let restaurants = this.restaurants;
|
||||||
|
let results = queryString ? restaurants.filter(this.createStateFilter(queryString)) : restaurants;
|
||||||
|
|
||||||
clearTimeout(this.timeout);
|
clearTimeout(this.timeout);
|
||||||
this.timeout = setTimeout(() => {
|
this.timeout = setTimeout(() => {
|
||||||
cb(results);
|
cb(results);
|
||||||
}, 3000 * Math.random());
|
}, 3000 * Math.random());
|
||||||
},
|
},
|
||||||
createStateFilter(queryString) {
|
createStateFilter(queryString) {
|
||||||
return (state) => {
|
return (state) => {
|
||||||
return (state.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
|
return (state.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
handleSelectMenu(item) {
|
handleSelectMenu(item) {
|
||||||
let _ts = this;
|
let _ts = this;
|
||||||
let activeMenu = _ts.$store.state.activeMenu;
|
let activeMenu = _ts.$store.state.activeMenu;
|
||||||
if (activeMenu !== item) {
|
if (activeMenu !== item) {
|
||||||
this.$store.commit('setActiveMenu', item);
|
if (item === 'topic') {
|
||||||
if(item === 'topic'){
|
_ts.$router.push(
|
||||||
_ts.$router.push(
|
{
|
||||||
{
|
name: item,
|
||||||
name: item,
|
params: {
|
||||||
params: {
|
name: '51mcu'
|
||||||
name: '51mcu'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if(item === 'github') {
|
|
||||||
window.open("https://github.com/Hugh-rymcu");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
_ts.$router.push(
|
|
||||||
{
|
|
||||||
name: item
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
handleSelect(item) {
|
)
|
||||||
console.log(item)
|
}
|
||||||
},
|
if (item === 'github') {
|
||||||
handleCommand(item) {
|
window.open("https://github.com/Hugh-rymcu");
|
||||||
let _ts = this;
|
return false;
|
||||||
if(item === 'user'){
|
}
|
||||||
_ts.$router.push({
|
_ts.$router.push(
|
||||||
path: '/user/' + _ts.$store.state.nickname
|
{
|
||||||
})
|
name: item
|
||||||
}
|
|
||||||
if( item === 'user-info'){
|
|
||||||
_ts.$router.push({
|
|
||||||
name: 'account',
|
|
||||||
params: {
|
|
||||||
id: _ts.$store.state.idUser
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (item === 'logout'){
|
|
||||||
_ts.$store.commit('logout');
|
|
||||||
item = 'login';
|
|
||||||
}
|
|
||||||
_ts.$router.push({
|
|
||||||
name: item
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getUnreadNotifications() {
|
|
||||||
let _ts = this;
|
|
||||||
_ts.axios.get('/notification/unread').then(function (res) {
|
|
||||||
if (res) {
|
|
||||||
_ts.$set(_ts, 'notifications', res.notifications);
|
|
||||||
_ts.$set(_ts, 'notificationNumbers', res.notifications.length == 0 ? "" : res.notifications.length);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.restaurants = this.loadAll();
|
|
||||||
let isLogin = this.isLogin;
|
|
||||||
if (isLogin) {
|
|
||||||
this.getUnreadNotifications();
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
handleSelect(item) {
|
||||||
|
console.log(item)
|
||||||
|
},
|
||||||
|
handleCommand(item) {
|
||||||
|
let _ts = this;
|
||||||
|
if (item === 'user') {
|
||||||
|
_ts.$router.push({
|
||||||
|
path: '/user/' + _ts.$store.state.nickname
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (item === 'user-info') {
|
||||||
|
_ts.$router.push({
|
||||||
|
name: 'account',
|
||||||
|
params: {
|
||||||
|
id: _ts.$store.state.idUser
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (item === 'logout') {
|
||||||
|
Cookie.remove('auth')
|
||||||
|
_ts.$store.commit('setAuth', null)
|
||||||
|
item = 'login';
|
||||||
|
}
|
||||||
|
_ts.$router.push({
|
||||||
|
name: item
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getUnreadNotifications() {
|
||||||
|
let _ts = this;
|
||||||
|
if (_ts.isLogin) {
|
||||||
|
_ts.$axios.$get('/api/v1/notification/unread', {
|
||||||
|
headers: {
|
||||||
|
Authorization: _ts.$store.state.oauth?.accessToken
|
||||||
|
}
|
||||||
|
}).then(function (res) {
|
||||||
|
if (res) {
|
||||||
|
_ts.$set(_ts, 'notifications', res.data.notifications);
|
||||||
|
_ts.$set(_ts, 'notificationNumbers', res.data.notifications.length == 0 ? "" : res.data.notifications.length);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.restaurants = this.loadAll();
|
||||||
|
let isLogin = this.isLogin;
|
||||||
|
if (isLogin) {
|
||||||
|
this.getUnreadNotifications();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.navbar-brand {
|
.navbar-brand {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
margin-right: 1rem;
|
margin-right: 1rem;
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
transition: .3s opacity;
|
transition: .3s opacity;
|
||||||
line-height: 2rem;
|
line-height: 2rem;
|
||||||
}
|
}
|
||||||
.navbar-brand-img {
|
|
||||||
height: 2rem;
|
.navbar-brand-img {
|
||||||
line-height: 2rem;
|
height: 2rem;
|
||||||
vertical-align: bottom;
|
line-height: 2rem;
|
||||||
margin-right: .5rem;
|
vertical-align: bottom;
|
||||||
width: auto;
|
margin-right: .5rem;
|
||||||
}
|
width: auto;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,27 +1,58 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-container>
|
<el-container>
|
||||||
<el-header>
|
<el-header>
|
||||||
<mobile-header/>
|
<header-view/>
|
||||||
</el-header>
|
</el-header>
|
||||||
<el-main>
|
<el-main>
|
||||||
<!-- <nuxt></nuxt>-->
|
<nuxt :nuxt-child-key="$route.name" />
|
||||||
</el-main>
|
</el-main>
|
||||||
<el-footer>
|
<el-footer>
|
||||||
<mobile-footer/>
|
<footer-view/>
|
||||||
</el-footer>
|
</el-footer>
|
||||||
</el-container>
|
</el-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import MobileHeader from "./header";
|
import { mapState } from 'vuex'
|
||||||
import MobileFooter from "./footer";
|
import HeaderView from "./header";
|
||||||
|
import FooterView from "./footer";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "mobileMain",
|
name: "MobileMain",
|
||||||
components: {MobileFooter, MobileHeader}
|
components: {
|
||||||
|
HeaderView,
|
||||||
|
FooterView
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState('global', [])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.el-header {
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
background: #fff;
|
||||||
|
border-bottom: 1px solid rgba(0, 40, 100, 0.12);
|
||||||
|
z-index: 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-main {
|
||||||
|
padding: 20px 0;
|
||||||
|
background-attachment: fixed;
|
||||||
|
min-height: 280px;
|
||||||
|
margin-bottom: 60px;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-footer {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 1rem;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
background: #fff;
|
||||||
|
border-top: 1px solid rgba(0, 40, 100, 0.12);
|
||||||
|
z-index: 80;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -84,6 +84,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
const Cookie = process.client ? require('js-cookie') : undefined
|
||||||
export default {
|
export default {
|
||||||
name: "PcHeader",
|
name: "PcHeader",
|
||||||
computed: {
|
computed: {
|
||||||
@ -91,16 +92,16 @@
|
|||||||
return this.$store.state.activeMenu;
|
return this.$store.state.activeMenu;
|
||||||
},
|
},
|
||||||
isLogin() {
|
isLogin() {
|
||||||
return this.$store.getters['auth/isLogin'];
|
return this.$store.state.oauth;
|
||||||
},
|
},
|
||||||
avatarURL() {
|
avatarURL() {
|
||||||
return this.$store.state['auth/avatarURL'];
|
return this.$store.state.oauth?.avatarURL;
|
||||||
},
|
},
|
||||||
nickname() {
|
nickname() {
|
||||||
return this.$store.state['auth/nickname'];
|
return this.$store.state.oauth?.nickname;
|
||||||
},
|
},
|
||||||
hasPermissions() {
|
hasPermissions() {
|
||||||
return this.$store.getters['auth/hasPermissions(\'blog_admin\')'];
|
return this.$store.getters.hasPermissions('blog_admin');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@ -184,7 +185,8 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (item === 'logout') {
|
if (item === 'logout') {
|
||||||
_ts.$store.commit('logout');
|
Cookie.remove('auth')
|
||||||
|
_ts.$store.commit('setAuth', null)
|
||||||
item = 'login';
|
item = 'login';
|
||||||
}
|
}
|
||||||
_ts.$router.push({
|
_ts.$router.push({
|
||||||
@ -193,12 +195,18 @@
|
|||||||
},
|
},
|
||||||
getUnreadNotifications() {
|
getUnreadNotifications() {
|
||||||
let _ts = this;
|
let _ts = this;
|
||||||
_ts.$axios.$get('/api/v1/notification/unread').then(function (res) {
|
if (_ts.isLogin) {
|
||||||
if (res) {
|
_ts.$axios.$get('/api/v1/notification/unread', {
|
||||||
_ts.$set(_ts, 'notifications', res.data.notifications);
|
headers: {
|
||||||
_ts.$set(_ts, 'notificationNumbers', res.data.notifications.length == 0 ? "" : res.notifications.length);
|
Authorization: _ts.$store.state.oauth?.accessToken
|
||||||
}
|
}
|
||||||
})
|
}).then(function (res) {
|
||||||
|
if (res) {
|
||||||
|
_ts.$set(_ts, 'notifications', res.data.notifications);
|
||||||
|
_ts.$set(_ts, 'notificationNumbers', res.data.notifications.length == 0 ? "" : res.data.notifications.length);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { NODE_ENV } from '../environment'
|
import {NODE_ENV} from '../environment'
|
||||||
|
|
||||||
const apisMap = {
|
const apisMap = {
|
||||||
development: {
|
development: {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
title: 'RYMCU - 嵌入式知识学习交流平台',
|
title: 'RYMCU - 嵌入式知识学习交流平台',
|
||||||
keywords: 'RYMCU,嵌入式,51,单片机,STM,STM8,STM32',
|
keywords: 'RYMCU,嵌入式,51,单片机,STM,STM8,STM32',
|
||||||
@ -8,11 +7,9 @@ export const meta = {
|
|||||||
email: 'ronger@rymcu.com'
|
email: 'ronger@rymcu.com'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const links = {
|
export const links = {}
|
||||||
}
|
|
||||||
|
|
||||||
export const friendLinks = {
|
export const friendLinks = {}
|
||||||
}
|
|
||||||
|
|
||||||
export const music = {
|
export const music = {
|
||||||
id: '638949385'
|
id: '638949385'
|
||||||
|
6
middleware/authenticated.js
Normal file
6
middleware/authenticated.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export default function ({ store, redirect }) {
|
||||||
|
// If the user is not authenticated
|
||||||
|
if (!store.state.oauth) {
|
||||||
|
return redirect('/login')
|
||||||
|
}
|
||||||
|
}
|
6
middleware/notAuthenticated.js
Normal file
6
middleware/notAuthenticated.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export default function ({ store, redirect }) {
|
||||||
|
// If the user is authenticated redirect to home page
|
||||||
|
if (store.state.oauth) {
|
||||||
|
return redirect('/')
|
||||||
|
}
|
||||||
|
}
|
@ -63,7 +63,9 @@ export default {
|
|||||||
** Nuxt.js modules
|
** Nuxt.js modules
|
||||||
*/
|
*/
|
||||||
modules: [
|
modules: [
|
||||||
['@nuxtjs/axios', {baseURL: apiConfig.BASE}]
|
['@nuxtjs/axios', {baseURL: apiConfig.BASE}],
|
||||||
|
'js-cookie',
|
||||||
|
'cookieparser'
|
||||||
],
|
],
|
||||||
/*
|
/*
|
||||||
** Build configuration
|
** Build configuration
|
||||||
|
1542
package-lock.json
generated
1542
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -10,11 +10,13 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxtjs/axios": "^5.11.0",
|
"@nuxtjs/axios": "^5.11.0",
|
||||||
|
"cookieparser": "^0.1.0",
|
||||||
"cross-env": "^7.0.2",
|
"cross-env": "^7.0.2",
|
||||||
"element-ui": "^2.13.2",
|
"element-ui": "^2.13.2",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"nuxt": "^2.13.0",
|
"js-cookie": "^2.2.1",
|
||||||
"vditor": "^3.3.2"
|
"nuxt": "^2.13.3",
|
||||||
|
"vditor": "^3.3.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxtjs/proxy": "^2.0.0",
|
"@nuxtjs/proxy": "^2.0.0",
|
||||||
|
@ -13,12 +13,14 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="9" :sm="11" :xl="11">
|
<el-col :xs="9" :sm="11" :xl="11">
|
||||||
<div style="margin-left: 1rem;">
|
<div style="margin-left: 1rem;">
|
||||||
<el-link @click="onRouter('user', article.articleAuthorName)" :underline="false" class="text-default" >{{ article.articleAuthorName }}</el-link>
|
<el-link @click="onRouter('user', article.articleAuthorName)" :underline="false"
|
||||||
|
class="text-default">{{ article.articleAuthorName }}
|
||||||
|
</el-link>
|
||||||
<small class="d-block text-muted">{{ article.timeAgo }}</small>
|
<small class="d-block text-muted">{{ article.timeAgo }}</small>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="12" :sm="12" :xl="12" v-if="isLogin" class="text-right">
|
<el-col :xs="12" :sm="12" :xl="12" v-if="isLogin" class="text-right">
|
||||||
<el-dropdown trigger="click" @command="handleCommand">
|
<el-dropdown trigger="click" @command="handleCommand">
|
||||||
<el-link :underline="false"><i class="el-icon-more"></i></el-link>
|
<el-link :underline="false"><i class="el-icon-more"></i></el-link>
|
||||||
<el-dropdown-menu slot="dropdown">
|
<el-dropdown-menu slot="dropdown">
|
||||||
<el-dropdown-item command="edit" v-if="hasPermissions">编辑</el-dropdown-item>
|
<el-dropdown-item command="edit" v-if="hasPermissions">编辑</el-dropdown-item>
|
||||||
@ -27,7 +29,8 @@
|
|||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col class="text-right">
|
<el-col class="text-right">
|
||||||
<el-link :underline="false" title="总浏览数"><i class="el-icon-s-data"></i><span style="color: red;">{{ article.articleViewCount }}</span></el-link>
|
<el-link :underline="false" title="总浏览数"><i class="el-icon-s-data"></i><span style="color: red;">{{ article.articleViewCount }}</span>
|
||||||
|
</el-link>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col style="margin: 1rem 0;">
|
<el-col style="margin: 1rem 0;">
|
||||||
<el-tag
|
<el-tag
|
||||||
@ -49,29 +52,32 @@
|
|||||||
<el-avatar :size="24" :src="portfolio.headImgUrl"></el-avatar>
|
<el-avatar :size="24" :src="portfolio.headImgUrl"></el-avatar>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="20" :sm="20" :xl="20">
|
<el-col :xs="20" :sm="20" :xl="20">
|
||||||
<el-link @click="onRouter('portfolio', portfolio.idPortfolio)" :underline="false" class="text-default">{{ portfolio.portfolioTitle }}</el-link>
|
<el-link @click="onRouter('portfolio', portfolio.idPortfolio)" :underline="false"
|
||||||
|
class="text-default">{{ portfolio.portfolioTitle }}
|
||||||
|
</el-link>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-col>
|
</el-col>
|
||||||
<!-- <el-col v-if="isShare" style="margin-bottom: 1rem;">-->
|
<!-- <el-col v-if="isShare" style="margin-bottom: 1rem;">-->
|
||||||
<!-- <el-input v-model="shareData.shareUrl">-->
|
<!-- <el-input v-model="shareData.shareUrl">-->
|
||||||
<!-- <el-popover slot="append"-->
|
<!-- <el-popover slot="append"-->
|
||||||
<!-- placement="bottom"-->
|
<!-- placement="bottom"-->
|
||||||
<!-- width="20"-->
|
<!-- width="20"-->
|
||||||
<!-- trigger="hover">-->
|
<!-- trigger="hover">-->
|
||||||
<!-- <el-col>-->
|
<!-- <el-col>-->
|
||||||
<!-- <qrcode :value="shareWeiXin(shareData.shareUrl)" :options="{ width: 20 }"></qrcode>-->
|
<!-- <qrcode :value="shareWeiXin(shareData.shareUrl)" :options="{ width: 20 }"></qrcode>-->
|
||||||
<!-- </el-col>-->
|
<!-- </el-col>-->
|
||||||
<!-- <el-col class="text-center">-->
|
<!-- <el-col class="text-center">-->
|
||||||
<!-- <span>扫码分享至微信</span>-->
|
<!-- <span>扫码分享至微信</span>-->
|
||||||
<!-- </el-col>-->
|
<!-- </el-col>-->
|
||||||
<!-- <el-button slot="reference"><el-image style="width: 14px;height: 14px;" :src="weiXin" fit="cover"></el-image></el-button>-->
|
<!-- <el-button slot="reference"><el-image style="width: 14px;height: 14px;" :src="weiXin" fit="cover"></el-image></el-button>-->
|
||||||
<!-- </el-popover>-->
|
<!-- </el-popover>-->
|
||||||
<!-- </el-input>-->
|
<!-- </el-input>-->
|
||||||
<!-- </el-col>-->
|
<!-- </el-col>-->
|
||||||
</el-row>
|
</el-row>
|
||||||
<div class="pt-7 pipe-content__reset vditor-reset" id="articleContent" v-html="article.articleContent" style="overflow: hidden;"></div>
|
<div class="pt-7 pipe-content__reset vditor-reset" id="articleContent" v-html="article.articleContent"
|
||||||
|
style="overflow: hidden;"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
@ -83,25 +89,25 @@
|
|||||||
<el-col :xs="22" :sm="23" :xl="23" style="padding-left: 1rem;">
|
<el-col :xs="22" :sm="23" :xl="23" style="padding-left: 1rem;">
|
||||||
<el-input @click.native="showComment" placeholder="请输入回帖内容"></el-input>
|
<el-input @click.native="showComment" placeholder="请输入回帖内容"></el-input>
|
||||||
</el-col>
|
</el-col>
|
||||||
<!-- <el-col>-->
|
<!-- <el-col>-->
|
||||||
<!-- <el-drawer-->
|
<!-- <el-drawer-->
|
||||||
<!-- :visible.sync="drawer"-->
|
<!-- :visible.sync="drawer"-->
|
||||||
<!-- :direction="direction"-->
|
<!-- :direction="direction"-->
|
||||||
<!-- size="40%">-->
|
<!-- size="40%">-->
|
||||||
<!-- <el-col slot="title">-->
|
<!-- <el-col slot="title">-->
|
||||||
<!-- <el-col>-->
|
<!-- <el-col>-->
|
||||||
<!-- <el-avatar v-if="commentAuthorAvatar" :src="commentAuthorAvatar"></el-avatar>-->
|
<!-- <el-avatar v-if="commentAuthorAvatar" :src="commentAuthorAvatar"></el-avatar>-->
|
||||||
<!-- <span class="text-default" style="padding-left: 1rem;">{{ title }}</span>-->
|
<!-- <span class="text-default" style="padding-left: 1rem;">{{ title }}</span>-->
|
||||||
<!-- </el-col>-->
|
<!-- </el-col>-->
|
||||||
<!-- </el-col>-->
|
<!-- </el-col>-->
|
||||||
<!-- <el-col>-->
|
<!-- <el-col>-->
|
||||||
<!-- <div id="contentEditor"></div>-->
|
<!-- <div id="contentEditor"></div>-->
|
||||||
<!-- </el-col>-->
|
<!-- </el-col>-->
|
||||||
<!-- <el-col style="margin-top: 1rem;padding-right:3rem;text-align: right;">-->
|
<!-- <el-col style="margin-top: 1rem;padding-right:3rem;text-align: right;">-->
|
||||||
<!-- <el-button type="primary" :loading="loading" @click="postComment">发布</el-button>-->
|
<!-- <el-button type="primary" :loading="loading" @click="postComment">发布</el-button>-->
|
||||||
<!-- </el-col>-->
|
<!-- </el-col>-->
|
||||||
<!-- </el-drawer>-->
|
<!-- </el-drawer>-->
|
||||||
<!-- </el-col>-->
|
<!-- </el-col>-->
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col v-else class="text-center" style="margin-top: 1rem;">
|
<el-col v-else class="text-center" style="margin-top: 1rem;">
|
||||||
<el-button type="primary" size="medium" @click="gotoLogin">登录</el-button>
|
<el-button type="primary" size="medium" @click="gotoLogin">登录</el-button>
|
||||||
@ -119,7 +125,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { mapState } from 'vuex';
|
import {mapState} from 'vuex';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ArticleDetail",
|
name: "ArticleDetail",
|
||||||
@ -139,11 +145,22 @@
|
|||||||
article: state => state.article.detail.data,
|
article: state => state.article.detail.data,
|
||||||
isFetching: state => state.article.detail.fetching,
|
isFetching: state => state.article.detail.fetching,
|
||||||
isMobile: state => state.global.isMobile,
|
isMobile: state => state.global.isMobile,
|
||||||
})
|
isLogin: state => state.oauth,
|
||||||
|
avatar: state => state.oauth?.avatarURL,
|
||||||
|
}),
|
||||||
|
hasPermissions() {
|
||||||
|
let account = this.$store.state.oauth?.nickname;
|
||||||
|
if (account) {
|
||||||
|
if (account === this.article.articleAuthor.userNickname) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.$store.getters.hasPermissions('blog_admin');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
head () {
|
head() {
|
||||||
return {
|
return {
|
||||||
title: this.article.articleTitle||'RYMCU - 嵌入式知识学习交流平台',
|
title: this.article.articleTitle || 'RYMCU - 嵌入式知识学习交流平台',
|
||||||
meta: [
|
meta: [
|
||||||
{
|
{
|
||||||
name: 'keywords',
|
name: 'keywords',
|
||||||
@ -184,14 +201,12 @@
|
|||||||
return {
|
return {
|
||||||
isShow: true,
|
isShow: true,
|
||||||
loading: false,
|
loading: false,
|
||||||
isLogin: false,
|
|
||||||
isShare: false,
|
isShare: false,
|
||||||
shareData: {},
|
shareData: {},
|
||||||
avatar: ''
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onRouter (name, data) {
|
onRouter(name, data) {
|
||||||
this.$router.push(
|
this.$router.push(
|
||||||
{
|
{
|
||||||
name: name,
|
name: name,
|
||||||
@ -227,21 +242,22 @@
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
Vue.nextTick(() => {
|
Vue.nextTick(() => {
|
||||||
const previewElement = document.getElementById("articleContent");
|
this.$store.commit('setActiveMenu', 'articleDetail')
|
||||||
// //const outLineElement = document.getElementById("articleToC");
|
const previewElement = document.getElementById("articleContent");
|
||||||
// VditorPreview.setContentTheme('light');
|
// //const outLineElement = document.getElementById("articleToC");
|
||||||
|
// VditorPreview.setContentTheme('light');
|
||||||
Vue.VditorPreview.codeRender(previewElement, 'zh_CN');
|
Vue.VditorPreview.codeRender(previewElement, 'zh_CN');
|
||||||
Vue.VditorPreview.highlightRender({"enable":true,"lineNumber":false,"style":"github"}, previewElement);
|
Vue.VditorPreview.highlightRender({"enable": true, "lineNumber": false, "style": "github"}, previewElement);
|
||||||
Vue.VditorPreview.mathRender(previewElement, {
|
Vue.VditorPreview.mathRender(previewElement, {
|
||||||
math: {"engine":"KaTeX","inlineDigit":false,"macros":{}},
|
math: {"engine": "KaTeX", "inlineDigit": false, "macros": {}},
|
||||||
});
|
});
|
||||||
Vue.VditorPreview.mermaidRender(previewElement, ".language-mermaid");
|
Vue.VditorPreview.mermaidRender(previewElement, ".language-mermaid");
|
||||||
Vue.VditorPreview.graphvizRender(previewElement);
|
Vue.VditorPreview.graphvizRender(previewElement);
|
||||||
Vue.VditorPreview.chartRender(previewElement);
|
Vue.VditorPreview.chartRender(previewElement);
|
||||||
Vue.VditorPreview.mindmapRender(previewElement);
|
Vue.VditorPreview.mindmapRender(previewElement);
|
||||||
Vue.VditorPreview.abcRender(previewElement);
|
Vue.VditorPreview.abcRender(previewElement);
|
||||||
Vue.VditorPreview.mediaRender(previewElement);
|
Vue.VditorPreview.mediaRender(previewElement);
|
||||||
//VditorPreview.outlineRender(previewElement, outLineElement);
|
//VditorPreview.outlineRender(previewElement, outLineElement);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,6 +266,7 @@
|
|||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "~vditor/src/assets/scss/index.scss";
|
@import "~vditor/src/assets/scss/index.scss";
|
||||||
|
|
||||||
.article__wrapper {
|
.article__wrapper {
|
||||||
max-width: 980px;
|
max-width: 980px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import ArticleList from '~/components/archive/list'
|
import ArticleList from '~/components/archive/list'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Index',
|
name: 'Index',
|
||||||
fetch({store}) {
|
fetch({store}) {
|
||||||
@ -24,6 +25,9 @@
|
|||||||
currentChangeArticle(page) {
|
currentChangeArticle(page) {
|
||||||
this.$store.dispatch('article/fetchList', {page: page})
|
this.$store.dispatch('article/fetchList', {page: page})
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$store.commit('setActiveMenu', 'index')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -52,9 +52,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapState } from 'vuex';
|
import {mapState} from 'vuex';
|
||||||
|
|
||||||
|
const Cookie = process.client ? require('js-cookie') : undefined
|
||||||
export default {
|
export default {
|
||||||
name: "login",
|
name: "login",
|
||||||
|
middleware: 'notAuthenticated',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
user: {
|
user: {
|
||||||
@ -84,13 +87,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
_ts.$axios.$post('/api/v1/console/login', data).then(function (res) {
|
_ts.$axios.$post('/api/v1/console/login', data).then(function (res) {
|
||||||
console.log(res);
|
|
||||||
if (res.data) {
|
if (res.data) {
|
||||||
if (res.data.message) {
|
if (res.data.message) {
|
||||||
_ts.$message(res.data.message);
|
_ts.$message(res.data.message);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_ts.$store.dispatch('auth/initLogin', res.data.user);
|
let auth = {
|
||||||
|
accessToken: res.data.user.token,
|
||||||
|
nickname: res.data.user.nickname,
|
||||||
|
avatarURL: res.data.user.avatarUrl,
|
||||||
|
role: res.data.user.weights
|
||||||
|
}
|
||||||
|
_ts.$store.commit('setAuth', auth) // mutating to store for client rendering
|
||||||
|
Cookie.set('auth', auth)
|
||||||
_ts.$router.push({
|
_ts.$router.push({
|
||||||
name: 'index'
|
name: 'index'
|
||||||
})
|
})
|
||||||
@ -132,6 +141,9 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$store.commit('setActiveMenu', 'login')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -69,7 +69,9 @@
|
|||||||
if (response.data) {
|
if (response.data) {
|
||||||
_ts.$message(response.data.message)
|
_ts.$message(response.data.message)
|
||||||
}
|
}
|
||||||
}).catch(error=>{ console.log(error) })
|
}).catch(error => {
|
||||||
|
console.log(error)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
register() {
|
register() {
|
||||||
let _ts = this;
|
let _ts = this;
|
||||||
@ -107,6 +109,9 @@
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$store.commit('setActiveMenu', 'register')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,28 +1,2 @@
|
|||||||
import apiConfig from '~/config/api.config'
|
import apiConfig from '~/config/api.config'
|
||||||
|
|
||||||
export default function ({ app: { $axios, $cookies } }) {
|
|
||||||
$axios.defaults.baseURL = apiConfig.BASE
|
|
||||||
$axios.defaults.timeout = 30000
|
|
||||||
$axios.interceptors.request.use(config => {
|
|
||||||
config.headers['X-Token'] = $cookies.get('token') || ''
|
|
||||||
config.headers['X-Device-Id'] = $cookies.get('clientId') || ''
|
|
||||||
config.headers['X-Uid'] = $cookies.get('userId') || ''
|
|
||||||
return config
|
|
||||||
})
|
|
||||||
$axios.interceptors.response.use(response => {
|
|
||||||
if (/^[4|5]/.test(response.status)) {
|
|
||||||
return Promise.reject(response.statusText)
|
|
||||||
}
|
|
||||||
let message;
|
|
||||||
if (typeof(response.data.data) !== 'undefined') {
|
|
||||||
message = response.data.data.message
|
|
||||||
} else if (typeof(response.data) !== 'undefined') {
|
|
||||||
message = response.data.message
|
|
||||||
}
|
|
||||||
console.log(message);
|
|
||||||
if (response.data.success) {
|
|
||||||
return response.data.data
|
|
||||||
}
|
|
||||||
return response.data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
@ -1,83 +0,0 @@
|
|||||||
export const state = () => {
|
|
||||||
return {
|
|
||||||
isLogin: false,
|
|
||||||
token: '',
|
|
||||||
nickname: '',
|
|
||||||
idUser: '',
|
|
||||||
avatarURL: '',
|
|
||||||
role: 0, // 0-no login, 1-admin, 2-blog admin, 3-blog author, 4-blog user, 5-visitor
|
|
||||||
login: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const mutations = {
|
|
||||||
updateUserInfo(state, data) {
|
|
||||||
state.isLogin = true;
|
|
||||||
state.avatarURL = data.avatarUrl;
|
|
||||||
state.nickname = data.nickname;
|
|
||||||
state.token = data.token;
|
|
||||||
state.account = data.account;
|
|
||||||
state.role = data.weights;
|
|
||||||
state.idUser = data.idUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
export const actions = {
|
|
||||||
setLogin(state, data){
|
|
||||||
state.login = data
|
|
||||||
},
|
|
||||||
setUserInfo(state, data) {
|
|
||||||
state.avatarURL = data.avatarUrl;
|
|
||||||
state.nickname = data.nickname;
|
|
||||||
},
|
|
||||||
initLogin({commit}, data = {}){
|
|
||||||
commit('updateUserInfo', data)
|
|
||||||
},
|
|
||||||
logout(state){
|
|
||||||
state.isLogin = false;
|
|
||||||
state.avatarURL = '';
|
|
||||||
state.nickname = '';
|
|
||||||
state.token = '';
|
|
||||||
state.account = '';
|
|
||||||
state.role = '';
|
|
||||||
state.idUser = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getters = {
|
|
||||||
isLogin(state){
|
|
||||||
return state.isLogin
|
|
||||||
},
|
|
||||||
hasPermissions:(state)=>(scenes)=>{
|
|
||||||
let hasPermissions = false;
|
|
||||||
if (state.role) {
|
|
||||||
switch (scenes) {
|
|
||||||
case 'user':
|
|
||||||
hasPermissions = state.role < 5;
|
|
||||||
break;
|
|
||||||
case 'role':
|
|
||||||
hasPermissions = state.role < 2;
|
|
||||||
break;
|
|
||||||
case 'topic':
|
|
||||||
hasPermissions = state.role < 3;
|
|
||||||
break;
|
|
||||||
case 'tag':
|
|
||||||
hasPermissions = state.role < 3;
|
|
||||||
break;
|
|
||||||
case 'admin':
|
|
||||||
hasPermissions = state.role < 2;
|
|
||||||
break;
|
|
||||||
case 'blog_admin':
|
|
||||||
hasPermissions = state.role < 3;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
hasPermissions = false;
|
|
||||||
this.commit('logout');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hasPermissions;
|
|
||||||
},
|
|
||||||
isAuthor: (state)=>(scenes)=> {
|
|
||||||
return state.nickname === scenes ? true : false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +1,34 @@
|
|||||||
|
const cookieparser = process.server ? require('cookieparser') : undefined
|
||||||
|
|
||||||
export const state = () => {
|
export const state = () => {
|
||||||
return {
|
return {
|
||||||
activeMenu: 'index'
|
activeMenu: 'index',
|
||||||
|
oauth: null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const mutations = {
|
||||||
|
setAuth (state, auth) {
|
||||||
|
state.oauth = auth
|
||||||
|
},
|
||||||
|
setActiveMenu (state, activeMenu) {
|
||||||
|
state.activeMenu = activeMenu
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
nuxtServerInit(store, {req}) {
|
nuxtServerInit(store, {req}) {
|
||||||
// 初始化时的全局任务
|
// 初始化时的全局任务
|
||||||
|
let auth = null
|
||||||
|
if (req.headers.cookie) {
|
||||||
|
const parsed = cookieparser.parse(req.headers.cookie)
|
||||||
|
try {
|
||||||
|
auth = JSON.parse(parsed.auth)
|
||||||
|
} catch (err) {
|
||||||
|
// No valid cookie found
|
||||||
|
}
|
||||||
|
store.commit('setAuth', auth)
|
||||||
|
}
|
||||||
const initFetchAppData = [
|
const initFetchAppData = [
|
||||||
// 内容数据
|
// 内容数据
|
||||||
store.dispatch('article/fetchList')
|
store.dispatch('article/fetchList')
|
||||||
@ -13,3 +36,36 @@ export const actions = {
|
|||||||
return Promise.all(initFetchAppData)
|
return Promise.all(initFetchAppData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getters = {
|
||||||
|
hasPermissions: (state) => (scenes) => {
|
||||||
|
let hasPermissions = false;
|
||||||
|
const role = state.oauth?.role
|
||||||
|
if (role) {
|
||||||
|
switch (scenes) {
|
||||||
|
case 'user':
|
||||||
|
hasPermissions = role < 5;
|
||||||
|
break;
|
||||||
|
case 'role':
|
||||||
|
hasPermissions = role < 2;
|
||||||
|
break;
|
||||||
|
case 'topic':
|
||||||
|
hasPermissions = role < 3;
|
||||||
|
break;
|
||||||
|
case 'tag':
|
||||||
|
hasPermissions = role < 3;
|
||||||
|
break;
|
||||||
|
case 'admin':
|
||||||
|
hasPermissions = role < 2;
|
||||||
|
break;
|
||||||
|
case 'blog_admin':
|
||||||
|
hasPermissions = role < 3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
hasPermissions = false;
|
||||||
|
this.commit('logout');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hasPermissions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user