first commit
This commit is contained in:
commit
08c1630a31
13
.editorconfig
Normal file
13
.editorconfig
Normal file
@ -0,0 +1,13 @@
|
||||
# editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
90
.gitignore
vendored
Normal file
90
.gitignore
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
# Created by .ignore support plugin (hsz.mobi)
|
||||
### Node template
|
||||
# Logs
|
||||
/logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
|
||||
# next.js build output
|
||||
.next
|
||||
|
||||
# nuxt.js build output
|
||||
.nuxt
|
||||
|
||||
# Nuxt generate
|
||||
dist
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless
|
||||
|
||||
# IDE / Editor
|
||||
.idea
|
||||
|
||||
# Service worker
|
||||
sw.*
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
|
||||
# Vim swap files
|
||||
*.swp
|
20
README.md
Normal file
20
README.md
Normal file
@ -0,0 +1,20 @@
|
||||
# nebula
|
||||
|
||||
## Build Setup
|
||||
|
||||
```bash
|
||||
# install dependencies
|
||||
$ yarn install
|
||||
|
||||
# serve with hot reload at localhost:3000
|
||||
$ yarn dev
|
||||
|
||||
# build for production and launch server
|
||||
$ yarn build
|
||||
$ yarn start
|
||||
|
||||
# generate static project
|
||||
$ yarn generate
|
||||
```
|
||||
|
||||
For detailed explanation on how things work, check out [Nuxt.js docs](https://nuxtjs.org).
|
7
assets/README.md
Normal file
7
assets/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
# ASSETS
|
||||
|
||||
**This directory is not required, you can delete it if you don't want to use it.**
|
||||
|
||||
This directory contains your un-compiled assets such as LESS, SASS, or JavaScript.
|
||||
|
||||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked).
|
BIN
assets/rymcu.png
Normal file
BIN
assets/rymcu.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
28
components/Logo.vue
Normal file
28
components/Logo.vue
Normal file
@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<svg class="NuxtLogo" width="245" height="180" viewBox="0 0 452 342" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M139 330l-1-2c-2-4-2-8-1-13H29L189 31l67 121 22-16-67-121c-1-2-9-14-22-14-6 0-15 2-22 15L5 303c-1 3-8 16-2 27 4 6 10 12 24 12h136c-14 0-21-6-24-12z"
|
||||
fill="#00C58E"
|
||||
/>
|
||||
<path
|
||||
d="M447 304L317 70c-2-2-9-15-22-15-6 0-15 3-22 15l-17 28v54l39-67 129 230h-49a23 23 0 0 1-2 14l-1 1c-6 11-21 12-23 12h76c3 0 17-1 24-12 3-5 5-14-2-26z"
|
||||
fill="#108775"
|
||||
/>
|
||||
<path
|
||||
d="M376 330v-1l1-2c1-4 2-8 1-12l-4-12-102-178-15-27h-1l-15 27-102 178-4 12a24 24 0 0 0 2 15c4 6 10 12 24 12h190c3 0 18-1 25-12zM256 152l93 163H163l93-163z"
|
||||
fill="#2F495E"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
<style>
|
||||
.NuxtLogo {
|
||||
animation: 1s appear;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
@keyframes appear {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
7
components/README.md
Normal file
7
components/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
# COMPONENTS
|
||||
|
||||
**This directory is not required, you can delete it if you don't want to use it.**
|
||||
|
||||
The components directory contains your Vue.js Components.
|
||||
|
||||
_Nuxt.js doesn't supercharge these components._
|
42
components/layouts/mobile/footer.vue
Normal file
42
components/layouts/mobile/footer.vue
Normal file
@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<el-row class="footer">
|
||||
<el-col style="text-align: center;">
|
||||
<el-col :xs="24" :sm="24" :xl="12">
|
||||
<span>{{ slogan }}</span>
|
||||
<span>{{ slogan_en }}</span>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :xl="12">
|
||||
<el-col class="row align-items-center">
|
||||
<el-col class="col-auto">
|
||||
Copyright © 2020 <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-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MobileFooter",
|
||||
data() {
|
||||
return {
|
||||
systemTitle: '\u7f57\u5409\u7f51\u0020\u002d\u0020\u5185\u5bb9\u5206\u4eab\u751f\u6001\u5e73\u53f0',
|
||||
systemName: 'RYMCU',
|
||||
systemUrl: 'https://rymcu.com',
|
||||
slogan: 'rymcu · 嵌入式知识学习交流平台 ',
|
||||
slogan_en: 'Embedded knowledge learning exchange platform',
|
||||
beiAn: '沪ICP备19042611号'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.footer {
|
||||
font-size: 14px;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
224
components/layouts/mobile/header.vue
Normal file
224
components/layouts/mobile/header.vue
Normal file
@ -0,0 +1,224 @@
|
||||
<template>
|
||||
<el-row justify="space-between" type="flex">
|
||||
<el-col>
|
||||
<el-col :xs="8" :sm="4" :md="4" :xl="3" style="padding-top: 1rem;">
|
||||
<a class="navbar-brand" href="/">
|
||||
<img src="@/assets/rymcu.png" alt="RYMCU" class="navbar-brand-img">
|
||||
<span>RYMCU</span>
|
||||
</a>
|
||||
</el-col>
|
||||
<el-col :xs="0" :sm="12" :md="14" :xl="18" style="text-align: center;">
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col>
|
||||
<el-menu :default-active="getActiveMenu" style="margin-top: -2px;border: 0;" mode="horizontal" @select="handleSelectMenu">
|
||||
<el-menu-item index="home">首页</el-menu-item>
|
||||
<el-menu-item index="topic">专题</el-menu-item>
|
||||
<el-menu-item index="github">开源代码</el-menu-item>
|
||||
<el-menu-item index="open-source">资料下载</el-menu-item>
|
||||
</el-menu>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :xs="16" :sm="8" :md="6" :xl="3" style="padding-top: 1rem;">
|
||||
<!--<el-col :xs="24" :sm="16" :xl="12">-->
|
||||
<el-col :xs="0" :sm="0" :xl="0">
|
||||
<el-autocomplete
|
||||
v-model="state"
|
||||
size="small"
|
||||
:fetch-suggestions="querySearchAsync"
|
||||
placeholder="搜索帖子、标签和用户"
|
||||
: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-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MobileHeader",
|
||||
computed: {
|
||||
getActiveMenu () {
|
||||
return this.$store.state.activeMenu;
|
||||
},
|
||||
isLogin () {
|
||||
return this.$store.getters.isLogin;
|
||||
},
|
||||
avatarURL () {
|
||||
return this.$store.state.avatarURL;
|
||||
},
|
||||
nickname() {
|
||||
return this.$store.state.nickname;
|
||||
},
|
||||
hasPermissions () {
|
||||
return this.$store.getters.hasPermissions('blog_admin');
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
restaurants: [],
|
||||
state: '',
|
||||
timeout: null,
|
||||
show: false,
|
||||
notifications: [],
|
||||
notificationNumbers: ""
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
isLogin: function () {
|
||||
this.getUnreadNotifications();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadAll() {
|
||||
return [
|
||||
{ "value": "三全鲜食(北新泾店)", "address": "长宁区新渔路144号" },
|
||||
{ "value": "Hot honey 首尔炸鸡(仙霞路)", "address": "上海市长宁区淞虹路661号" },
|
||||
{ "value": "新旺角茶餐厅", "address": "上海市普陀区真北路988号创邑金沙谷6号楼113" }
|
||||
]
|
||||
},
|
||||
querySearchAsync(queryString, cb) {
|
||||
let restaurants = this.restaurants;
|
||||
let results = queryString ? restaurants.filter(this.createStateFilter(queryString)) : restaurants;
|
||||
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = setTimeout(() => {
|
||||
cb(results);
|
||||
}, 3000 * Math.random());
|
||||
},
|
||||
createStateFilter(queryString) {
|
||||
return (state) => {
|
||||
return (state.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
|
||||
};
|
||||
},
|
||||
handleSelectMenu(item) {
|
||||
let _ts = this;
|
||||
let activeMenu = _ts.$store.state.activeMenu;
|
||||
if (activeMenu !== item) {
|
||||
this.$store.commit('setActiveMenu', item);
|
||||
if(item === 'topic'){
|
||||
_ts.$router.push(
|
||||
{
|
||||
name: item,
|
||||
params: {
|
||||
name: '51mcu'
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
if(item === 'github') {
|
||||
window.open("https://github.com/Hugh-rymcu");
|
||||
return false;
|
||||
}
|
||||
_ts.$router.push(
|
||||
{
|
||||
name: item
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
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'){
|
||||
_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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.navbar-brand {
|
||||
color: inherit;
|
||||
margin-right: 1rem;
|
||||
font-size: 1.25rem;
|
||||
white-space: nowrap;
|
||||
font-weight: 600;
|
||||
padding: 0;
|
||||
transition: .3s opacity;
|
||||
line-height: 2rem;
|
||||
}
|
||||
.navbar-brand-img {
|
||||
height: 2rem;
|
||||
line-height: 2rem;
|
||||
vertical-align: bottom;
|
||||
margin-right: .5rem;
|
||||
width: auto;
|
||||
}
|
||||
</style>
|
27
components/layouts/mobile/main.vue
Normal file
27
components/layouts/mobile/main.vue
Normal file
@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header>
|
||||
<mobile-header/>
|
||||
</el-header>
|
||||
<el-main>
|
||||
<!-- <nuxt></nuxt>-->
|
||||
</el-main>
|
||||
<el-footer>
|
||||
<mobile-footer/>
|
||||
</el-footer>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MobileHeader from "./header";
|
||||
import MobileFooter from "./footer";
|
||||
|
||||
export default {
|
||||
name: "moblieMain",
|
||||
components: {MobileFooter, MobileHeader}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
46
components/layouts/pc/footer.vue
Normal file
46
components/layouts/pc/footer.vue
Normal file
@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<el-row class="footer">
|
||||
<el-col style="text-align: center;">
|
||||
<el-col :xs="24" :sm="24" :xl="12">
|
||||
<span>{{ slogan }}</span>
|
||||
<span>{{ slogan_en }}</span>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :xl="12">
|
||||
<el-col class="row align-items-center">
|
||||
<el-col class="col-auto">
|
||||
Copyright © 2020
|
||||
<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-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "PcFooter",
|
||||
data() {
|
||||
return {
|
||||
systemTitle: '\u7f57\u5409\u7f51\u0020\u002d\u0020\u5185\u5bb9\u5206\u4eab\u751f\u6001\u5e73\u53f0',
|
||||
systemName: 'RYMCU',
|
||||
systemUrl: 'https://rymcu.com',
|
||||
slogan: 'rymcu · 嵌入式知识学习交流平台 ',
|
||||
slogan_en: 'Embedded knowledge learning exchange platform',
|
||||
beiAn: '沪ICP备19042611号'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.footer {
|
||||
font-size: 14px;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
231
components/layouts/pc/header.vue
Normal file
231
components/layouts/pc/header.vue
Normal file
@ -0,0 +1,231 @@
|
||||
<template>
|
||||
<el-row justify="space-between" type="flex">
|
||||
<el-col>
|
||||
<el-col :xs="8" :sm="4" :md="4" :xl="3" style="padding-top: 1rem;">
|
||||
<a class="navbar-brand" href="/">
|
||||
<img src="@/assets/rymcu.png" alt="RYMCU" class="navbar-brand-img">
|
||||
<span>RYMCU</span>
|
||||
</a>
|
||||
</el-col>
|
||||
<el-col :xs="0" :sm="12" :md="14" :xl="18" style="text-align: center;">
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col>
|
||||
<el-menu :default-active="getActiveMenu" style="margin-top: -2px;border: 0;" mode="horizontal"
|
||||
@select="handleSelectMenu">
|
||||
<el-menu-item index="home">首页</el-menu-item>
|
||||
<el-menu-item index="topic">专题</el-menu-item>
|
||||
<el-menu-item index="github">开源代码</el-menu-item>
|
||||
<el-menu-item index="open-source">资料下载</el-menu-item>
|
||||
</el-menu>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :xs="16" :sm="8" :md="6" :xl="3" style="padding-top: 1rem;">
|
||||
<!--<el-col :xs="24" :sm="16" :xl="12">-->
|
||||
<el-col :xs="0" :sm="0" :xl="0">
|
||||
<el-autocomplete
|
||||
v-model="state"
|
||||
size="small"
|
||||
:fetch-suggestions="querySearchAsync"
|
||||
placeholder="搜索帖子、标签和用户"
|
||||
: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-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "PcHeader",
|
||||
computed: {
|
||||
getActiveMenu() {
|
||||
return this.$store.state.activeMenu;
|
||||
},
|
||||
isLogin() {
|
||||
return this.$store.getters.isLogin;
|
||||
},
|
||||
avatarURL() {
|
||||
return this.$store.state.avatarURL;
|
||||
},
|
||||
nickname() {
|
||||
return this.$store.state.nickname;
|
||||
},
|
||||
hasPermissions() {
|
||||
return this.$store.getters.hasPermissions('blog_admin');
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
restaurants: [],
|
||||
state: '',
|
||||
timeout: null,
|
||||
show: false,
|
||||
notifications: [],
|
||||
notificationNumbers: ""
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
isLogin: function () {
|
||||
this.getUnreadNotifications();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadAll() {
|
||||
return [
|
||||
{"value": "三全鲜食(北新泾店)", "address": "长宁区新渔路144号"},
|
||||
{"value": "Hot honey 首尔炸鸡(仙霞路)", "address": "上海市长宁区淞虹路661号"},
|
||||
{"value": "新旺角茶餐厅", "address": "上海市普陀区真北路988号创邑金沙谷6号楼113"}
|
||||
]
|
||||
},
|
||||
querySearchAsync(queryString, cb) {
|
||||
let restaurants = this.restaurants;
|
||||
let results = queryString ? restaurants.filter(this.createStateFilter(queryString)) : restaurants;
|
||||
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = setTimeout(() => {
|
||||
cb(results);
|
||||
}, 3000 * Math.random());
|
||||
},
|
||||
createStateFilter(queryString) {
|
||||
return (state) => {
|
||||
return (state.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
|
||||
};
|
||||
},
|
||||
handleSelectMenu(item) {
|
||||
let _ts = this;
|
||||
let activeMenu = _ts.$store.state.activeMenu;
|
||||
if (activeMenu !== item) {
|
||||
this.$store.commit('setActiveMenu', item);
|
||||
if (item === 'topic') {
|
||||
_ts.$router.push(
|
||||
{
|
||||
name: item,
|
||||
params: {
|
||||
name: '51mcu'
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
if (item === 'github') {
|
||||
window.open("https://github.com/Hugh-rymcu");
|
||||
return false;
|
||||
}
|
||||
_ts.$router.push(
|
||||
{
|
||||
name: item
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
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') {
|
||||
_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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.navbar-brand {
|
||||
color: inherit;
|
||||
margin-right: 1rem;
|
||||
font-size: 1.25rem;
|
||||
white-space: nowrap;
|
||||
font-weight: 600;
|
||||
padding: 0;
|
||||
transition: .3s opacity;
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
||||
.navbar-brand-img {
|
||||
height: 2rem;
|
||||
line-height: 2rem;
|
||||
vertical-align: bottom;
|
||||
margin-right: .5rem;
|
||||
width: auto;
|
||||
}
|
||||
</style>
|
30
components/layouts/pc/main.vue
Normal file
30
components/layouts/pc/main.vue
Normal file
@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header>
|
||||
<header-view/>
|
||||
</el-header>
|
||||
<el-main>
|
||||
<!-- <nuxt></nuxt>-->
|
||||
</el-main>
|
||||
<el-footer>
|
||||
<footer-view/>
|
||||
</el-footer>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import HeaderView from "./header";
|
||||
import FooterView from "./footer";
|
||||
|
||||
export default {
|
||||
name: "PcMain",
|
||||
components: {
|
||||
HeaderView,
|
||||
FooterView
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
7
layouts/README.md
Normal file
7
layouts/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
# LAYOUTS
|
||||
|
||||
**This directory is not required, you can delete it if you don't want to use it.**
|
||||
|
||||
This directory contains your Application Layouts.
|
||||
|
||||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/views#layouts).
|
161
layouts/default.vue
Normal file
161
layouts/default.vue
Normal file
@ -0,0 +1,161 @@
|
||||
<template>
|
||||
<div>
|
||||
<nuxt />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
display: block;
|
||||
overflow-wrap: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
background-color: rgb(246, 247, 248);
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
a, li {
|
||||
text-decoration:none !important;
|
||||
}
|
||||
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a, .h1 a, .h2 a, .h3 a, .h4 a, .h5 a, .h6 a {
|
||||
color: inherit;
|
||||
}
|
||||
h4, .h4 {
|
||||
font-size: 1.125rem;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
|
||||
margin-bottom: 0.66em;
|
||||
font-family: inherit;
|
||||
font-weight: 600;
|
||||
line-height: 1.1;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
p {
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.avatar-md {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
line-height: 2.5rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
line-height: 2rem;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
background: #ced4da no-repeat center/cover;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
color: #868e96;
|
||||
font-weight: 600;
|
||||
vertical-align: bottom;
|
||||
font-size: .875rem;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.pt-5, .py-5 {
|
||||
padding-top: 1.5rem !important;
|
||||
}
|
||||
|
||||
.text-default {
|
||||
color: #495057 !important;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #9aa0ac !important;
|
||||
}
|
||||
|
||||
.d-block {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.article-summary-md {
|
||||
position:relative;
|
||||
line-height:1.4em;
|
||||
/* 3 times the line-height to show 3 lines */
|
||||
height:4.2em;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
.article-summary-md::after {
|
||||
content:"...";
|
||||
font-weight:bold;
|
||||
position:absolute;
|
||||
bottom:0;
|
||||
right:0;
|
||||
padding:0 20px 1px 45px;
|
||||
/*background:url(http://newimg88.b0.upaiyun.com/newimg88/2014/09/ellipsis_bg.png) repeat-y;*/
|
||||
}
|
||||
|
||||
.article-summary-sd {
|
||||
position:relative;
|
||||
line-height:1.4em;
|
||||
/* 1 times the line-height to show 1 lines */
|
||||
height:1.4em;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
.article-summary-sd::after {
|
||||
content:"...";
|
||||
font-weight:bold;
|
||||
position:absolute;
|
||||
bottom:0;
|
||||
right:0;
|
||||
padding:0 20px 1px 45px;
|
||||
/*background:url(http://newimg88.b0.upaiyun.com/newimg88/2014/09/ellipsis_bg.png) repeat-y;*/
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
max-width: 980px;
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
box-sizing: border-box;
|
||||
float: none;
|
||||
}
|
||||
|
||||
.mr-3, .mx-3 {
|
||||
margin-right: 0.75rem !important;
|
||||
}
|
||||
|
||||
|
||||
.navbar-brand-img {
|
||||
height: 2rem;
|
||||
line-height: 2rem;
|
||||
vertical-align: bottom;
|
||||
margin-right: .5rem;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.topic-brand-img {
|
||||
height: 4rem;
|
||||
line-height: 2rem;
|
||||
vertical-align: bottom;
|
||||
margin-right: .5rem;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.text-left {
|
||||
text-align: left;
|
||||
}
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
</style>
|
8
middleware/README.md
Normal file
8
middleware/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
# MIDDLEWARE
|
||||
|
||||
**This directory is not required, you can delete it if you don't want to use it.**
|
||||
|
||||
This directory contains your application middleware.
|
||||
Middleware let you define custom functions that can be run before rendering either a page or a group of pages.
|
||||
|
||||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing#middleware).
|
54
nuxt.config.js
Normal file
54
nuxt.config.js
Normal file
@ -0,0 +1,54 @@
|
||||
|
||||
export default {
|
||||
/*
|
||||
** Nuxt rendering mode
|
||||
** See https://nuxtjs.org/api/configuration-mode
|
||||
*/
|
||||
mode: 'universal',
|
||||
/*
|
||||
** Headers of the page
|
||||
** See https://nuxtjs.org/api/configuration-head
|
||||
*/
|
||||
head: {
|
||||
title: process.env.npm_package_name || '',
|
||||
meta: [
|
||||
{ charset: 'utf-8' },
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
|
||||
{ hid: 'description', name: 'description', content: process.env.npm_package_description || '' }
|
||||
],
|
||||
link: [
|
||||
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
|
||||
]
|
||||
},
|
||||
/*
|
||||
** Global CSS
|
||||
*/
|
||||
css: [
|
||||
'element-ui/lib/theme-chalk/index.css'
|
||||
],
|
||||
/*
|
||||
** Plugins to load before mounting the App
|
||||
** https://nuxtjs.org/guide/plugins
|
||||
*/
|
||||
plugins: [
|
||||
'@/plugins/element-ui',
|
||||
'@/plugins/axios'
|
||||
],
|
||||
/*
|
||||
** Nuxt.js dev-modules
|
||||
*/
|
||||
buildModules: [
|
||||
],
|
||||
/*
|
||||
** Nuxt.js modules
|
||||
*/
|
||||
modules: [
|
||||
],
|
||||
/*
|
||||
** Build configuration
|
||||
** See https://nuxtjs.org/api/configuration-build/
|
||||
*/
|
||||
build: {
|
||||
transpile: [/^element-ui/],
|
||||
}
|
||||
}
|
10247
package-lock.json
generated
Normal file
10247
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
19
package.json
Normal file
19
package.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "nebula",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "nuxt",
|
||||
"build": "nuxt build",
|
||||
"start": "nuxt start",
|
||||
"generate": "nuxt generate"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.19.2",
|
||||
"element-ui": "^2.13.2",
|
||||
"nuxt": "^2.13.0",
|
||||
"vditor": "^3.3.2",
|
||||
"vue-axios": "^2.1.5"
|
||||
},
|
||||
"devDependencies": {}
|
||||
}
|
6
pages/README.md
Normal file
6
pages/README.md
Normal file
@ -0,0 +1,6 @@
|
||||
# PAGES
|
||||
|
||||
This directory contains your Application Views and Routes.
|
||||
The framework reads all the `*.vue` files inside this directory and creates the router of your application.
|
||||
|
||||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing).
|
54
pages/index.vue
Normal file
54
pages/index.vue
Normal file
@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<div>
|
||||
<pc-main-view v-if="!isMobile"/>
|
||||
<mobile-main-view v-else/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PcMainView from '~/components/layouts/pc/main.vue'
|
||||
import MobileMainView from '~/components/layouts/mobile/main.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
PcMainView,
|
||||
MobileMainView
|
||||
},
|
||||
computed: {
|
||||
theme() {
|
||||
return this.$store.state.theme
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.isMobile
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.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>
|
7
plugins/README.md
Normal file
7
plugins/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
# PLUGINS
|
||||
|
||||
**This directory is not required, you can delete it if you don't want to use it.**
|
||||
|
||||
This directory contains Javascript plugins that you want to run before mounting the root Vue.js application.
|
||||
|
||||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins).
|
88
plugins/axios.js
Normal file
88
plugins/axios.js
Normal file
@ -0,0 +1,88 @@
|
||||
import axios from 'axios'
|
||||
import VueAxios from 'vue-axios'
|
||||
import Vue from 'vue'
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
export default (ctx) => {
|
||||
const customAxios = axios.create({
|
||||
baseURL: '/api',
|
||||
timeout:'10000',
|
||||
withCredentials: true
|
||||
});
|
||||
|
||||
customAxios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
|
||||
customAxios.defaults.headers.common['x-requested-with'] = 'XMLHttpRequest';
|
||||
|
||||
Vue.use(VueAxios, customAxios);
|
||||
|
||||
customAxios.interceptors.request.use((config) => {
|
||||
if(config.url){
|
||||
let token = localStorage.getItem("x-auth-token");
|
||||
if (token) { // 判断是否存在token,如果存在的话,则每个http header都加上token
|
||||
if (!(config.url.indexOf('console') > -1)){
|
||||
config.headers.Authorization = `${token}`;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
config.url = '/console/heartbeat'
|
||||
}
|
||||
|
||||
// clear cache
|
||||
// if (config.method === 'get') {
|
||||
// let char = '?'
|
||||
// if (config.url.split('?').length > 1) {
|
||||
// char = '&'
|
||||
// }
|
||||
// config.url += `${char}${(new Date()).getTime()}`
|
||||
// }
|
||||
return config
|
||||
}, function (error) {
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
customAxios.interceptors.response.use((response) => {
|
||||
let message;
|
||||
if (typeof(response.data.data) !== 'undefined') {
|
||||
message = response.data.data.message
|
||||
} else if (typeof(response.data) !== 'undefined') {
|
||||
message = response.data.message
|
||||
}
|
||||
if (response.data.success) {
|
||||
return response.data.data
|
||||
} else {
|
||||
if(response.data.code === 0){
|
||||
window.app.$message(message);
|
||||
}else if(response.data.code === 401){
|
||||
window.app.$store.commit('logout');
|
||||
window.app.$router.push({
|
||||
name: 'login',
|
||||
query: {
|
||||
historyUrl: window.location.href
|
||||
}
|
||||
})
|
||||
}else if(response.data.code === 402){
|
||||
window.app.$store.commit('logout');
|
||||
window.app.$router.push({
|
||||
name: 'login',
|
||||
query: {
|
||||
historyUrl: window.location.href
|
||||
}
|
||||
})
|
||||
}else if(response.data.code === 404){
|
||||
window.app.$message('操作失败,请稍后再试......')
|
||||
}else if(response.data.code === 500){
|
||||
window.app.$message('服务器正在开小差,请稍后再试......')
|
||||
}
|
||||
return false
|
||||
}
|
||||
}, (error) => {
|
||||
/*console.log(ctx.app.store.state.locale)
|
||||
ctx.store.commit('setSnackBar', {
|
||||
snackBar: true,
|
||||
snackMsg: ctx.app.i18n.t('requestError', ctx.app.store.state.locale)
|
||||
})*/
|
||||
return Promise.reject(error)
|
||||
})
|
||||
|
||||
return customAxios
|
||||
}
|
5
plugins/element-ui.js
Normal file
5
plugins/element-ui.js
Normal file
@ -0,0 +1,5 @@
|
||||
import Vue from 'vue'
|
||||
import Element from 'element-ui'
|
||||
import locale from 'element-ui/lib/locale/lang/en'
|
||||
|
||||
Vue.use(Element, { locale })
|
11
static/README.md
Normal file
11
static/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# STATIC
|
||||
|
||||
**This directory is not required, you can delete it if you don't want to use it.**
|
||||
|
||||
This directory contains your static files.
|
||||
Each file inside this directory is mapped to `/`.
|
||||
Thus you'd want to delete this README.md before deploying to production.
|
||||
|
||||
Example: `/static/robots.txt` is mapped as `/robots.txt`.
|
||||
|
||||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static).
|
BIN
static/favicon.ico
Normal file
BIN
static/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
3
static/robots.txt
Normal file
3
static/robots.txt
Normal file
@ -0,0 +1,3 @@
|
||||
User-agent: *
|
||||
Disallow: /api/
|
||||
Disallow: /admin/
|
10
store/README.md
Normal file
10
store/README.md
Normal file
@ -0,0 +1,10 @@
|
||||
# STORE
|
||||
|
||||
**This directory is not required, you can delete it if you don't want to use it.**
|
||||
|
||||
This directory contains your Vuex Store files.
|
||||
Vuex Store option is implemented in the Nuxt.js framework.
|
||||
|
||||
Creating a file in this directory automatically activates the option in the framework.
|
||||
|
||||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store).
|
142
store/index.js
Normal file
142
store/index.js
Normal file
@ -0,0 +1,142 @@
|
||||
export const state = () => ({
|
||||
locale: 'zh_CN',
|
||||
version: '1.0.0',
|
||||
isInit: false,
|
||||
isLogin: false,
|
||||
token: '',
|
||||
nickname: '',
|
||||
idUser: '',
|
||||
blogTitle: '',
|
||||
avatarURL: '',
|
||||
blogURL: '/',
|
||||
role: 0, // 0-no login, 1-admin, 2-blog admin, 3-blog author, 4-blog user, 5-visitor
|
||||
blogs: [{
|
||||
title: '',
|
||||
id: ''
|
||||
}],
|
||||
snackMsg: '',
|
||||
snackBar: false,
|
||||
snackModify: 'error',
|
||||
menu: [],
|
||||
tagsItems: [],
|
||||
bodySide: '',
|
||||
login: false,
|
||||
activeMenu: 'home',
|
||||
activeAdminMenu: 'admin-dashboard',
|
||||
activeTopic: '51mcu',
|
||||
activeTag: 'news',
|
||||
uploadHeaders: '',
|
||||
theme: '',
|
||||
isMobile: false
|
||||
})
|
||||
|
||||
export const mutations = () => ({
|
||||
setLogin(state, data) {
|
||||
state.login = data
|
||||
},
|
||||
setActiveMenu(state, data) {
|
||||
state.activeMenu = data
|
||||
},
|
||||
setActiveAdminMenu(state, data) {
|
||||
state.activeAdminMenu = data
|
||||
},
|
||||
setActiveTopic(state, data) {
|
||||
state.activeTopic = data
|
||||
},
|
||||
setActiveTag(state, data) {
|
||||
state.activeTag = data
|
||||
},
|
||||
setUserInfo(state, data) {
|
||||
state.avatarURL = data.avatarUrl;
|
||||
state.nickname = data.nickname;
|
||||
localStorage.setItem('avatarURL', data.avatarUrl);
|
||||
localStorage.setItem('nickname', data.nickname);
|
||||
},
|
||||
initLogin(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;
|
||||
localStorage.setItem('isLogin', 'true');
|
||||
localStorage.setItem('avatarURL', data.avatarUrl);
|
||||
localStorage.setItem('nickname', data.nickname);
|
||||
localStorage.setItem('account', data.account);
|
||||
localStorage.setItem('idUser', data.idUser);
|
||||
localStorage.setItem('x-auth-token', data.token);
|
||||
localStorage.setItem('role', data.weights);
|
||||
},
|
||||
logout(state) {
|
||||
state.isLogin = false;
|
||||
state.avatarURL = '';
|
||||
state.nickname = '';
|
||||
state.token = '';
|
||||
state.account = '';
|
||||
state.role = '';
|
||||
state.idUser = '';
|
||||
localStorage.removeItem('isLogin');
|
||||
localStorage.removeItem('avatarURL');
|
||||
localStorage.removeItem('nickname');
|
||||
localStorage.removeItem('account');
|
||||
localStorage.removeItem('idUser');
|
||||
localStorage.removeItem('x-auth-token');
|
||||
localStorage.removeItem('role');
|
||||
},
|
||||
setUploadHeaders(state, data) {
|
||||
state.uploadHeaders = data
|
||||
}
|
||||
})
|
||||
|
||||
export const actions = () => ({})
|
||||
|
||||
export const getters = () => ({
|
||||
uploadHeaders(state) {
|
||||
return state.uploadHeaders;
|
||||
},
|
||||
isLogin(state) {
|
||||
if (!state.isLogin) {
|
||||
state.isLogin = localStorage.getItem('isLogin'); //从localStorage中读取状态
|
||||
state.nickname = localStorage.getItem('nickname');
|
||||
state.avatarURL = localStorage.getItem('avatarURL') !== 'undefined' ? localStorage.getItem('avatarURL') : "";
|
||||
state.token = localStorage.getItem('x-auth-token');
|
||||
state.account = localStorage.getItem('account');
|
||||
state.idUser = localStorage.getItem('idUser');
|
||||
state.role = Number(localStorage.getItem('role'));
|
||||
}
|
||||
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;
|
||||
window.app.$store.commit('logout');
|
||||
}
|
||||
}
|
||||
return hasPermissions;
|
||||
},
|
||||
isAuthor: (state) => (scenes) => {
|
||||
return state.nickname === scenes ? true : false;
|
||||
}
|
||||
})
|
Loading…
Reference in New Issue
Block a user