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