first commit
This commit is contained in:
parent
4bf83cc3fe
commit
5a13c949fa
@ -8,8 +8,12 @@
|
|||||||
<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-link>
|
||||||
|
.
|
||||||
|
<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-col>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
@ -10,8 +10,9 @@
|
|||||||
<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="index">首页</el-menu-item>
|
||||||
<el-menu-item index="topic">专题</el-menu-item>
|
<el-menu-item index="topic">专题</el-menu-item>
|
||||||
<el-menu-item index="github">开源代码</el-menu-item>
|
<el-menu-item index="github">开源代码</el-menu-item>
|
||||||
<el-menu-item index="open-source">资料下载</el-menu-item>
|
<el-menu-item index="open-source">资料下载</el-menu-item>
|
||||||
@ -33,7 +34,8 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<!--<el-col v-if="isLogin" :xs="0" :sm="8" :xl="6">-->
|
<!--<el-col v-if="isLogin" :xs="0" :sm="8" :xl="6">-->
|
||||||
<el-col v-if="isLogin">
|
<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-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;" href="/post-article">发帖</el-link>
|
||||||
<el-link :underline="false" style="padding-left: 10px;padding-right: 10px;">
|
<el-link :underline="false" style="padding-left: 10px;padding-right: 10px;">
|
||||||
<el-dropdown trigger="click" @command="handleCommand">
|
<el-dropdown trigger="click" @command="handleCommand">
|
||||||
@ -41,7 +43,9 @@
|
|||||||
<el-link :underline="false" style="font-size: 1.4rem;" class="el-icon-bell"></el-link>
|
<el-link :underline="false" style="font-size: 1.4rem;" class="el-icon-bell"></el-link>
|
||||||
</el-badge>
|
</el-badge>
|
||||||
<el-dropdown-menu slot="dropdown">
|
<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 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-item command="notification">查看所有消息</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
@ -52,8 +56,10 @@
|
|||||||
<el-avatar v-else size="small" src="https://rymcu.com/vertical/article/1578475481946.png"></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-menu slot="dropdown">
|
||||||
<el-dropdown-item command="user" style="align-items: center;">
|
<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-if="avatarURL" size="small" style="margin-top: 1rem;"
|
||||||
<el-avatar class="mr-3" v-else size="small" style="margin-top: 1rem;" src="https://rymcu.com/vertical/article/1578475481946.png"></el-avatar>
|
: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-link :underline="false" style="margin-left: 10px;margin-bottom: 1rem;">{{ nickname }}</el-link>
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item v-show="hasPermissions" command="admin-dashboard">系统管理</el-dropdown-item>
|
<el-dropdown-item v-show="hasPermissions" command="admin-dashboard">系统管理</el-dropdown-item>
|
||||||
@ -65,8 +71,12 @@
|
|||||||
</el-link>
|
</el-link>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col v-else>
|
<el-col v-else>
|
||||||
<el-link :underline="false" style="margin-left: 10px;" href="/login">登录</el-link>
|
<nuxt-link to="/login">
|
||||||
<el-link :underline="false" style="margin-left: 10px;" href="/register">注册</el-link>
|
<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-col>
|
||||||
</el-col>
|
</el-col>
|
||||||
@ -74,22 +84,23 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
const Cookie = process.client ? require('js-cookie') : undefined
|
||||||
export default {
|
export default {
|
||||||
name: "MobileHeader",
|
name: "MobileHeader",
|
||||||
computed: {
|
computed: {
|
||||||
getActiveMenu () {
|
getActiveMenu() {
|
||||||
return this.$store.state.activeMenu;
|
return this.$store.state.activeMenu;
|
||||||
},
|
},
|
||||||
isLogin () {
|
isLogin() {
|
||||||
return this.$store.getters.isLogin;
|
return this.$store.state.oauth;
|
||||||
},
|
},
|
||||||
avatarURL () {
|
avatarURL() {
|
||||||
return this.$store.state.avatarURL;
|
return this.$store.state.oauth?.avatarURL;
|
||||||
},
|
},
|
||||||
nickname() {
|
nickname() {
|
||||||
return this.$store.state.nickname;
|
return this.$store.state.oauth?.nickname;
|
||||||
},
|
},
|
||||||
hasPermissions () {
|
hasPermissions() {
|
||||||
return this.$store.getters.hasPermissions('blog_admin');
|
return this.$store.getters.hasPermissions('blog_admin');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -111,9 +122,9 @@
|
|||||||
methods: {
|
methods: {
|
||||||
loadAll() {
|
loadAll() {
|
||||||
return [
|
return [
|
||||||
{ "value": "三全鲜食(北新泾店)", "address": "长宁区新渔路144号" },
|
{"value": "三全鲜食(北新泾店)", "address": "长宁区新渔路144号"},
|
||||||
{ "value": "Hot honey 首尔炸鸡(仙霞路)", "address": "上海市长宁区淞虹路661号" },
|
{"value": "Hot honey 首尔炸鸡(仙霞路)", "address": "上海市长宁区淞虹路661号"},
|
||||||
{ "value": "新旺角茶餐厅", "address": "上海市普陀区真北路988号创邑金沙谷6号楼113" }
|
{"value": "新旺角茶餐厅", "address": "上海市普陀区真北路988号创邑金沙谷6号楼113"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
querySearchAsync(queryString, cb) {
|
querySearchAsync(queryString, cb) {
|
||||||
@ -134,8 +145,7 @@
|
|||||||
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,
|
||||||
@ -145,7 +155,7 @@
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if(item === 'github') {
|
if (item === 'github') {
|
||||||
window.open("https://github.com/Hugh-rymcu");
|
window.open("https://github.com/Hugh-rymcu");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -161,12 +171,12 @@
|
|||||||
},
|
},
|
||||||
handleCommand(item) {
|
handleCommand(item) {
|
||||||
let _ts = this;
|
let _ts = this;
|
||||||
if(item === 'user'){
|
if (item === 'user') {
|
||||||
_ts.$router.push({
|
_ts.$router.push({
|
||||||
path: '/user/' + _ts.$store.state.nickname
|
path: '/user/' + _ts.$store.state.nickname
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if( item === 'user-info'){
|
if (item === 'user-info') {
|
||||||
_ts.$router.push({
|
_ts.$router.push({
|
||||||
name: 'account',
|
name: 'account',
|
||||||
params: {
|
params: {
|
||||||
@ -174,8 +184,9 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
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({
|
||||||
@ -184,13 +195,19 @@
|
|||||||
},
|
},
|
||||||
getUnreadNotifications() {
|
getUnreadNotifications() {
|
||||||
let _ts = this;
|
let _ts = this;
|
||||||
_ts.axios.get('/notification/unread').then(function (res) {
|
if (_ts.isLogin) {
|
||||||
|
_ts.$axios.$get('/api/v1/notification/unread', {
|
||||||
|
headers: {
|
||||||
|
Authorization: _ts.$store.state.oauth?.accessToken
|
||||||
|
}
|
||||||
|
}).then(function (res) {
|
||||||
if (res) {
|
if (res) {
|
||||||
_ts.$set(_ts, 'notifications', res.notifications);
|
_ts.$set(_ts, 'notifications', res.data.notifications);
|
||||||
_ts.$set(_ts, 'notificationNumbers', res.notifications.length == 0 ? "" : res.notifications.length);
|
_ts.$set(_ts, 'notificationNumbers', res.data.notifications.length == 0 ? "" : res.data.notifications.length);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.restaurants = this.loadAll();
|
this.restaurants = this.loadAll();
|
||||||
@ -214,6 +231,7 @@
|
|||||||
transition: .3s opacity;
|
transition: .3s opacity;
|
||||||
line-height: 2rem;
|
line-height: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-brand-img {
|
.navbar-brand-img {
|
||||||
height: 2rem;
|
height: 2rem;
|
||||||
line-height: 2rem;
|
line-height: 2rem;
|
||||||
|
@ -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,13 +195,19 @@
|
|||||||
},
|
},
|
||||||
getUnreadNotifications() {
|
getUnreadNotifications() {
|
||||||
let _ts = this;
|
let _ts = this;
|
||||||
_ts.$axios.$get('/api/v1/notification/unread').then(function (res) {
|
if (_ts.isLogin) {
|
||||||
|
_ts.$axios.$get('/api/v1/notification/unread', {
|
||||||
|
headers: {
|
||||||
|
Authorization: _ts.$store.state.oauth?.accessToken
|
||||||
|
}
|
||||||
|
}).then(function (res) {
|
||||||
if (res) {
|
if (res) {
|
||||||
_ts.$set(_ts, 'notifications', res.data.notifications);
|
_ts.$set(_ts, 'notifications', res.data.notifications);
|
||||||
_ts.$set(_ts, 'notificationNumbers', res.data.notifications.length == 0 ? "" : res.notifications.length);
|
_ts.$set(_ts, 'notificationNumbers', res.data.notifications.length == 0 ? "" : res.data.notifications.length);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.restaurants = this.loadAll();
|
this.restaurants = this.loadAll();
|
||||||
|
@ -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,7 +13,9 @@
|
|||||||
</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>
|
||||||
@ -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,13 +242,14 @@
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
Vue.nextTick(() => {
|
Vue.nextTick(() => {
|
||||||
|
this.$store.commit('setActiveMenu', 'articleDetail')
|
||||||
const previewElement = document.getElementById("articleContent");
|
const previewElement = document.getElementById("articleContent");
|
||||||
// //const outLineElement = document.getElementById("articleToC");
|
// //const outLineElement = document.getElementById("articleToC");
|
||||||
// VditorPreview.setContentTheme('light');
|
// 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);
|
||||||
@ -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