✨ nuxt/auth
This commit is contained in:
parent
2b10747e97
commit
a2f72f6d0a
@ -48,7 +48,7 @@ export default {
|
||||
name: "UserList",
|
||||
computed: {
|
||||
...mapState({
|
||||
userInfo: state => state.oauth
|
||||
userInfo: state => state.auth.user
|
||||
})
|
||||
},
|
||||
props: {
|
||||
|
@ -9,7 +9,7 @@
|
||||
<el-col :xs="0" :sm="12" :md="8" :xl="8" 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"
|
||||
<el-menu :default-active="activeMenu" style="margin-top: -2px;border: 0;" mode="horizontal"
|
||||
@select="handleSelectMenu">
|
||||
<el-menu-item index="index">首页</el-menu-item>
|
||||
<el-menu-item index="topic">专题</el-menu-item>
|
||||
@ -19,8 +19,9 @@
|
||||
</el-col>
|
||||
<el-col :xs="16" :sm="8" :md="6" :xl="3" style="padding-top: 1rem;">
|
||||
<client-only>
|
||||
<el-col v-if="user" style="text-align: right;">
|
||||
<el-link rel="nofollow" :underline="false" style="padding-left: 10px;padding-right: 10px;" href="/article/post">发帖
|
||||
<el-col v-if="loggedIn" style="text-align: right;">
|
||||
<el-link rel="nofollow" :underline="false" style="padding-left: 10px;padding-right: 10px;"
|
||||
href="/article/post">发帖
|
||||
</el-link>
|
||||
<el-link rel="nofollow" :underline="false" style="padding-left: 10px;padding-right: 10px;">
|
||||
<el-dropdown trigger="click" @command="handleCommand">
|
||||
@ -37,15 +38,17 @@
|
||||
</el-link>
|
||||
<el-link rel="nofollow" :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-if="loggedIn" size="small" :src="user.avatarUrl"></el-avatar>
|
||||
<el-avatar v-else size="small" src="https://static.rymcu.com/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-if="user.avatarUrl" size="small" style="margin-top: 1rem;"
|
||||
:src="loggedIn"></el-avatar>
|
||||
<el-avatar class="mr-3" v-else size="small" style="margin-top: 1rem;"
|
||||
src="https://static.rymcu.com/article/1578475481946.png"></el-avatar>
|
||||
<el-link rel="nofollow" :underline="false" style="margin-left: 10px;margin-bottom: 1rem;">{{ nickname }}</el-link>
|
||||
<el-link rel="nofollow" :underline="false" style="margin-left: 10px;margin-bottom: 1rem;">
|
||||
{{ user.nickname }}
|
||||
</el-link>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="hasPermissions" command="admin-dashboard">系统管理</el-dropdown-item>
|
||||
<el-dropdown-item command="user-info">资料与账号</el-dropdown-item>
|
||||
@ -70,203 +73,165 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { isBrowser } from '~/environment'
|
||||
import {mapState} from 'vuex';
|
||||
|
||||
const Cookie = process.client ? require('js-cookie') : undefined
|
||||
export default {
|
||||
name: "MobileHeader",
|
||||
computed: {
|
||||
getActiveMenu() {
|
||||
return this.$store.state.activeMenu;
|
||||
},
|
||||
user() {
|
||||
return this.$store.state.oauth;
|
||||
},
|
||||
avatarURL() {
|
||||
let _ts = this;
|
||||
if (isBrowser) {
|
||||
if (!_ts.$store.state.userInfo) {
|
||||
let user = localStorage.getItem('user');
|
||||
if (user) {
|
||||
_ts.$store.commit('setUser', JSON.parse(user))
|
||||
}
|
||||
}
|
||||
}
|
||||
return _ts.$store.state.userInfo?.avatarURL;
|
||||
},
|
||||
nickname() {
|
||||
let _ts = this;
|
||||
if (isBrowser) {
|
||||
if (!_ts.$store.state.userInfo) {
|
||||
let user = localStorage.getItem('user');
|
||||
if (user) {
|
||||
_ts.$store.commit('setUser', JSON.parse(user))
|
||||
}
|
||||
}
|
||||
}
|
||||
return _ts.$store.state.userInfo?.nickname;
|
||||
},
|
||||
account() {
|
||||
let _ts = this;
|
||||
if (isBrowser) {
|
||||
if (!_ts.$store.state.userInfo) {
|
||||
let user = localStorage.getItem('user');
|
||||
if (user) {
|
||||
_ts.$store.commit('setUser', JSON.parse(user))
|
||||
}
|
||||
}
|
||||
}
|
||||
return _ts.$store.state.userInfo?.account;
|
||||
},
|
||||
hasPermissions() {
|
||||
return this.$store.getters.hasPermissions('blog_admin');
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
restaurants: [],
|
||||
state: '',
|
||||
timeout: null,
|
||||
show: false,
|
||||
notifications: [],
|
||||
notificationNumbers: ""
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
user: function () {
|
||||
this.getUnreadNotifications();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSelectMenu(item) {
|
||||
let _ts = this;
|
||||
let activeMenu = _ts.$store.state.activeMenu;
|
||||
if (activeMenu !== item) {
|
||||
switch (item) {
|
||||
case 'topic':
|
||||
_ts.$router.push({
|
||||
path: '/topic/news'
|
||||
})
|
||||
break;
|
||||
case 'github':
|
||||
window.open("https://github.com/rymcu");
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
_ts.$router.push(
|
||||
{
|
||||
path: '/'
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
handleCommand(item) {
|
||||
let _ts = this;
|
||||
export default {
|
||||
name: "MobileHeader",
|
||||
computed: {
|
||||
...mapState({
|
||||
activeMenu: state => state.activeMenu,
|
||||
user: state => state.auth.user,
|
||||
loggedIn: state => state.auth.loggedIn
|
||||
}),
|
||||
hasPermissions() {
|
||||
return this.$auth.hasScope('blog_admin');
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
restaurants: [],
|
||||
state: '',
|
||||
timeout: null,
|
||||
show: false,
|
||||
notifications: [],
|
||||
notificationNumbers: ""
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
user: function () {
|
||||
this.getUnreadNotifications();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSelectMenu(item) {
|
||||
let _ts = this;
|
||||
let activeMenu = _ts.$store.state.activeMenu;
|
||||
if (activeMenu !== item) {
|
||||
switch (item) {
|
||||
case 'user':
|
||||
case 'topic':
|
||||
_ts.$router.push({
|
||||
path: '/user/' + _ts.account
|
||||
path: '/topic/news'
|
||||
})
|
||||
break;
|
||||
case 'user-info':
|
||||
_ts.$router.push({
|
||||
path: '/user/settings/account'
|
||||
})
|
||||
break;
|
||||
case 'logout':
|
||||
Cookie.remove('auth')
|
||||
_ts.$store.commit('setAuth', null)
|
||||
item = 'login';
|
||||
case 'github':
|
||||
window.open("https://github.com/rymcu");
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
_ts.$router.push({
|
||||
name: item
|
||||
})
|
||||
}
|
||||
},
|
||||
getUnreadNotifications() {
|
||||
let _ts = this;
|
||||
if (_ts.user) {
|
||||
_ts.$axios.$get('/api/notification/unread').then(function (res) {
|
||||
if (res) {
|
||||
_ts.$set(_ts, 'notifications', res.notifications);
|
||||
_ts.$set(_ts, 'notificationNumbers', res.pagination.total === 0 ? "" : res.pagination.total);
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
browserFingerprint() {
|
||||
let _ts = this
|
||||
let canvas = document.createElement('canvas');
|
||||
let ctx = canvas.getContext('2d');
|
||||
let txt = 'https://rymcu.com/';
|
||||
ctx.textBaseline = "top";
|
||||
ctx.font = "14px 'Arial'";
|
||||
ctx.textBaseline = "rymcu";
|
||||
ctx.fillStyle = "#f60";
|
||||
ctx.fillRect(125,1,62,20);
|
||||
ctx.fillStyle = "#069";
|
||||
ctx.fillText(txt, 2, 15);
|
||||
ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
|
||||
ctx.fillText(txt, 4, 17);
|
||||
let b64 = canvas.toDataURL().replace("data:image/png;base64,","");
|
||||
let bin = atob(b64);
|
||||
let fingerprint = _ts.bin2hex(bin.slice(-16,-12));
|
||||
_ts.$store.commit('setFingerprint', fingerprint);
|
||||
},
|
||||
bin2hex(str) {
|
||||
let _ts = this
|
||||
let result = "";
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
let c = str.charCodeAt(i);
|
||||
// 高字节
|
||||
result += _ts.byte2Hex(c >> 8 & 0xff);
|
||||
// 低字节
|
||||
result += _ts.byte2Hex(c & 0xff);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
byte2Hex(b) {
|
||||
if (b < 0x10) {
|
||||
return "0" + b.toString(16);
|
||||
} else {
|
||||
return b.toString(16);
|
||||
_ts.$router.push(
|
||||
{
|
||||
path: '/'
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let _ts = this
|
||||
let user = _ts.user;
|
||||
if (user) {
|
||||
_ts.getUnreadNotifications();
|
||||
handleCommand(item) {
|
||||
let _ts = this;
|
||||
switch (item) {
|
||||
case 'user':
|
||||
_ts.$router.push({
|
||||
path: '/user/' + _ts.user.account
|
||||
})
|
||||
break;
|
||||
case 'user-info':
|
||||
_ts.$router.push({
|
||||
path: '/user/settings/account'
|
||||
})
|
||||
break;
|
||||
case 'logout':
|
||||
_ts.$auth.reset()
|
||||
item = 'login';
|
||||
item = 'login';
|
||||
break;
|
||||
default:
|
||||
_ts.$router.push({
|
||||
name: item
|
||||
})
|
||||
}
|
||||
let fingerprint = _ts.$store.state.fingerprint
|
||||
if (!fingerprint) {
|
||||
_ts.browserFingerprint();
|
||||
},
|
||||
getUnreadNotifications() {
|
||||
let _ts = this;
|
||||
if (_ts.user) {
|
||||
_ts.$axios.$get('/api/notification/unread').then(function (res) {
|
||||
if (res) {
|
||||
_ts.$set(_ts, 'notifications', res.notifications);
|
||||
_ts.$set(_ts, 'notificationNumbers', res.pagination.total === 0 ? "" : res.pagination.total);
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
browserFingerprint() {
|
||||
let _ts = this
|
||||
let canvas = document.createElement('canvas');
|
||||
let ctx = canvas.getContext('2d');
|
||||
let txt = 'https://rymcu.com/';
|
||||
ctx.textBaseline = "top";
|
||||
ctx.font = "14px 'Arial'";
|
||||
ctx.textBaseline = "rymcu";
|
||||
ctx.fillStyle = "#f60";
|
||||
ctx.fillRect(125, 1, 62, 20);
|
||||
ctx.fillStyle = "#069";
|
||||
ctx.fillText(txt, 2, 15);
|
||||
ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
|
||||
ctx.fillText(txt, 4, 17);
|
||||
let b64 = canvas.toDataURL().replace("data:image/png;base64,", "");
|
||||
let bin = atob(b64);
|
||||
let fingerprint = _ts.bin2hex(bin.slice(-16, -12));
|
||||
_ts.$store.commit('setFingerprint', fingerprint);
|
||||
},
|
||||
bin2hex(str) {
|
||||
let _ts = this
|
||||
let result = "";
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
let c = str.charCodeAt(i);
|
||||
// 高字节
|
||||
result += _ts.byte2Hex(c >> 8 & 0xff);
|
||||
// 低字节
|
||||
result += _ts.byte2Hex(c & 0xff);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
byte2Hex(b) {
|
||||
if (b < 0x10) {
|
||||
return "0" + b.toString(16);
|
||||
} else {
|
||||
return b.toString(16);
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
mounted() {
|
||||
let _ts = this
|
||||
let user = _ts.user;
|
||||
if (user) {
|
||||
_ts.getUnreadNotifications();
|
||||
}
|
||||
let fingerprint = _ts.$store.state.fingerprint
|
||||
if (!fingerprint) {
|
||||
_ts.browserFingerprint();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</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 {
|
||||
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;
|
||||
}
|
||||
.navbar-brand-img {
|
||||
height: 2rem;
|
||||
line-height: 2rem;
|
||||
vertical-align: bottom;
|
||||
margin-right: .5rem;
|
||||
width: auto;
|
||||
}
|
||||
</style>
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
<el-col :md="10" :span="10" :xs="16" style="line-height: 60px">
|
||||
<client-only>
|
||||
<el-col style="text-align: right;" v-if="user">
|
||||
<el-col style="text-align: right;" v-if="loggedIn">
|
||||
<el-popover
|
||||
@show="handleShowPopover"
|
||||
placement="bottom"
|
||||
@ -76,17 +76,17 @@
|
||||
</el-link>
|
||||
<el-link :underline="false" rel="nofollow" style="margin-left: 10px;">
|
||||
<el-dropdown @command="handleCommand" trigger="click">
|
||||
<el-avatar :src="avatarURL" size="small" v-if="avatarURL"></el-avatar>
|
||||
<el-avatar :src="user.avatarUrl" size="small" v-if="user.avatarUrl"></el-avatar>
|
||||
<el-avatar size="small" src="https://static.rymcu.com/article/1578475481946.png" v-else></el-avatar>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item style="align-items: center;">
|
||||
<el-avatar :src="avatarURL" class="mr-3" size="small" style="margin-top: 1rem;"
|
||||
v-if="avatarURL"></el-avatar>
|
||||
<el-avatar :src="user.avatarUrl" class="mr-3" size="small" style="margin-top: 1rem;"
|
||||
v-if="user.avatarUrl"></el-avatar>
|
||||
<el-avatar class="mr-3" size="small" src="https://static.rymcu.com/article/1578475481946.png"
|
||||
style="margin-top: 1rem;"
|
||||
v-else></el-avatar>
|
||||
<el-link :underline="false" rel="nofollow" style="margin-left: 10px;margin-bottom: 1rem;">
|
||||
{{ nickname }}
|
||||
{{ user.nickname }}
|
||||
</el-link>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="user">个人中心</el-dropdown-item>
|
||||
@ -138,251 +138,213 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapState} from 'vuex';
|
||||
import {isBrowser} from '~/environment';
|
||||
// import sockClient from '~/plugins/sockjs';
|
||||
import {mapState} from 'vuex';
|
||||
// import sockClient from '~/plugins/sockjs';
|
||||
|
||||
const Cookie = process.client ? require('js-cookie') : undefined
|
||||
export default {
|
||||
name: "PcHeader",
|
||||
computed: {
|
||||
...mapState({
|
||||
activeMenu: state => state.activeMenu,
|
||||
user: state => state.oauth
|
||||
}),
|
||||
avatarURL() {
|
||||
let _ts = this;
|
||||
if (isBrowser) {
|
||||
if (!_ts.$store.state.userInfo) {
|
||||
let user = localStorage.getItem('user');
|
||||
if (user) {
|
||||
_ts.$store.commit('setUser', JSON.parse(user))
|
||||
}
|
||||
}
|
||||
}
|
||||
return _ts.$store.state.userInfo?.avatarURL;
|
||||
},
|
||||
nickname() {
|
||||
let _ts = this;
|
||||
if (isBrowser) {
|
||||
if (!_ts.$store.state.userInfo) {
|
||||
let user = localStorage.getItem('user');
|
||||
if (user) {
|
||||
_ts.$store.commit('setUser', JSON.parse(user))
|
||||
}
|
||||
}
|
||||
}
|
||||
return _ts.$store.state.userInfo?.nickname;
|
||||
},
|
||||
account() {
|
||||
let _ts = this;
|
||||
if (isBrowser) {
|
||||
if (!_ts.$store.state.userInfo) {
|
||||
let user = localStorage.getItem('user');
|
||||
if (user) {
|
||||
_ts.$store.commit('setUser', JSON.parse(user))
|
||||
}
|
||||
}
|
||||
}
|
||||
return _ts.$store.state.userInfo?.account;
|
||||
},
|
||||
hasPermissions() {
|
||||
return this.$store.getters.hasPermissions('blog_admin');
|
||||
}
|
||||
export default {
|
||||
name: "PcHeader",
|
||||
computed: {
|
||||
...mapState({
|
||||
activeMenu: state => state.activeMenu,
|
||||
user: state => state.auth.user,
|
||||
loggedIn: state => state.auth.loggedIn
|
||||
}),
|
||||
hasPermissions() {
|
||||
return this.$auth.hasScope('admin') || this.$auth.hasScope('blog_admin');
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
queryString: '',
|
||||
timeout: null,
|
||||
show: false,
|
||||
notifications: [],
|
||||
notificationNumbers: "",
|
||||
showPopover: false,
|
||||
autofocus: false
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
user: function () {
|
||||
this.getUnreadNotifications();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
querySearchAsync() {
|
||||
this.$router.push({
|
||||
path: `/search?q=${this.queryString}`
|
||||
})
|
||||
this.$set(this, 'showPopover', false);
|
||||
this.$set(this, 'queryString', '');
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
queryString: '',
|
||||
timeout: null,
|
||||
show: false,
|
||||
notifications: [],
|
||||
notificationNumbers: "",
|
||||
showPopover: false,
|
||||
autofocus: false
|
||||
};
|
||||
handleShowPopover() {
|
||||
setTimeout(function () {
|
||||
document.getElementsByName("searchInput")[0].focus()
|
||||
}, 500);
|
||||
},
|
||||
watch: {
|
||||
user: function () {
|
||||
this.getUnreadNotifications();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
querySearchAsync() {
|
||||
this.$router.push({
|
||||
path: `/search?q=${this.queryString}`
|
||||
})
|
||||
this.$set(this, 'showPopover', false);
|
||||
this.$set(this, 'queryString', '');
|
||||
},
|
||||
handleShowPopover() {
|
||||
setTimeout(function () {
|
||||
document.getElementsByName("searchInput")[0].focus()
|
||||
}, 500);
|
||||
},
|
||||
handleSelectMenu(item) {
|
||||
let _ts = this;
|
||||
let activeMenu = _ts.$store.state.activeMenu;
|
||||
if (activeMenu !== item) {
|
||||
switch (item) {
|
||||
case 'topic':
|
||||
_ts.$router.push({
|
||||
path: '/topic/news?page=1'
|
||||
})
|
||||
break;
|
||||
case 'portfolios':
|
||||
_ts.$router.push({
|
||||
path: '/portfolios?page=1'
|
||||
})
|
||||
break;
|
||||
case 'products':
|
||||
_ts.$router.push({
|
||||
path: '/products?page=1'
|
||||
})
|
||||
break;
|
||||
case 'github':
|
||||
window.open("https://github.com/rymcu");
|
||||
break;
|
||||
case 'taobao':
|
||||
window.open("https://rymcu.taobao.com?utm_source=rymcu.com");
|
||||
break;
|
||||
case 'open-data':
|
||||
_ts.$router.push({
|
||||
path: '/open-data'
|
||||
})
|
||||
break;
|
||||
default:
|
||||
_ts.$router.push(
|
||||
{
|
||||
path: '/'
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
handleCommand(item) {
|
||||
let _ts = this;
|
||||
handleSelectMenu(item) {
|
||||
let _ts = this;
|
||||
let activeMenu = _ts.$store.state.activeMenu;
|
||||
if (activeMenu !== item) {
|
||||
switch (item) {
|
||||
case 'user':
|
||||
case 'topic':
|
||||
_ts.$router.push({
|
||||
path: '/user/' + _ts.account
|
||||
path: '/topic/news?page=1'
|
||||
})
|
||||
break;
|
||||
case 'user-info':
|
||||
case 'portfolios':
|
||||
_ts.$router.push({
|
||||
path: '/user/settings/account'
|
||||
path: '/portfolios?page=1'
|
||||
})
|
||||
break;
|
||||
case 'logout':
|
||||
Cookie.remove('auth')
|
||||
_ts.$store.commit('setAuth', null)
|
||||
item = 'login';
|
||||
case 'products':
|
||||
_ts.$router.push({
|
||||
path: '/products?page=1'
|
||||
})
|
||||
break;
|
||||
case 'github':
|
||||
window.open("https://github.com/rymcu");
|
||||
break;
|
||||
case 'taobao':
|
||||
window.open("https://rymcu.taobao.com?utm_source=rymcu.com");
|
||||
break;
|
||||
case 'open-data':
|
||||
_ts.$router.push({
|
||||
path: '/open-data'
|
||||
})
|
||||
break;
|
||||
default:
|
||||
_ts.$router.push({
|
||||
name: item
|
||||
})
|
||||
}
|
||||
},
|
||||
getUnreadNotifications() {
|
||||
let _ts = this;
|
||||
if (_ts.user) {
|
||||
_ts.$axios.$get('/api/notification/unread').then(function (res) {
|
||||
if (res) {
|
||||
_ts.$set(_ts, 'notifications', res.list);
|
||||
_ts.$set(_ts, 'notificationNumbers', res.total === 0 ? "" : res.total);
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
login() {
|
||||
this.$router.push({
|
||||
path: '/login',
|
||||
query: {
|
||||
historyUrl: window.location.href
|
||||
}
|
||||
})
|
||||
},
|
||||
browserFingerprint() {
|
||||
let _ts = this
|
||||
let canvas = document.createElement('canvas');
|
||||
let ctx = canvas.getContext('2d');
|
||||
let txt = 'https://rymcu.com/';
|
||||
ctx.textBaseline = "top";
|
||||
ctx.font = "14px 'Arial'";
|
||||
ctx.textBaseline = "rymcu";
|
||||
ctx.fillStyle = "#f60";
|
||||
ctx.fillRect(125, 1, 62, 20);
|
||||
ctx.fillStyle = "#069";
|
||||
ctx.fillText(txt, 2, 15);
|
||||
ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
|
||||
ctx.fillText(txt, 4, 17);
|
||||
let b64 = canvas.toDataURL().replace("data:image/png;base64,", "");
|
||||
let bin = atob(b64);
|
||||
let fingerprint = _ts.bin2hex(bin.slice(-16, -12));
|
||||
_ts.$store.commit('setFingerprint', fingerprint);
|
||||
},
|
||||
bin2hex(str) {
|
||||
let _ts = this
|
||||
let result = "";
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
let c = str.charCodeAt(i);
|
||||
// 高字节
|
||||
result += _ts.byte2Hex(c >> 8 & 0xff);
|
||||
// 低字节
|
||||
result += _ts.byte2Hex(c & 0xff);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
byte2Hex(b) {
|
||||
if (b < 0x10) {
|
||||
return "0" + b.toString(16);
|
||||
} else {
|
||||
return b.toString(16);
|
||||
_ts.$router.push(
|
||||
{
|
||||
path: '/'
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
handleCommand(item) {
|
||||
let _ts = this;
|
||||
let user = _ts.user;
|
||||
if (user) {
|
||||
_ts.getUnreadNotifications();
|
||||
_ts.$store.dispatch('follow/fetchUserFollowerList');
|
||||
_ts.$store.dispatch('follow/fetchUserFollowingList');
|
||||
// sockClient.initSocket(this.$store.state.userInfo);
|
||||
switch (item) {
|
||||
case 'user':
|
||||
_ts.$router.push({
|
||||
path: '/user/' + _ts.user.account
|
||||
})
|
||||
break;
|
||||
case 'user-info':
|
||||
_ts.$router.push({
|
||||
path: '/user/settings/account'
|
||||
})
|
||||
break;
|
||||
case 'logout':
|
||||
_ts.$auth.logout()
|
||||
item = 'login';
|
||||
break;
|
||||
default:
|
||||
_ts.$router.push({
|
||||
name: item
|
||||
})
|
||||
}
|
||||
let fingerprint = _ts.$store.state.fingerprint
|
||||
if (!fingerprint) {
|
||||
_ts.browserFingerprint();
|
||||
},
|
||||
getUnreadNotifications() {
|
||||
let _ts = this;
|
||||
if (_ts.user) {
|
||||
_ts.$axios.$get('/api/notification/unread').then(function (res) {
|
||||
if (res) {
|
||||
_ts.$set(_ts, 'notifications', res.list);
|
||||
_ts.$set(_ts, 'notificationNumbers', res.total === 0 ? "" : res.total);
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
login() {
|
||||
this.$router.push({
|
||||
path: '/login',
|
||||
query: {
|
||||
historyUrl: window.location.href
|
||||
}
|
||||
})
|
||||
},
|
||||
browserFingerprint() {
|
||||
let _ts = this
|
||||
let canvas = document.createElement('canvas');
|
||||
let ctx = canvas.getContext('2d');
|
||||
let txt = 'https://rymcu.com/';
|
||||
ctx.textBaseline = "top";
|
||||
ctx.font = "14px 'Arial'";
|
||||
ctx.textBaseline = "rymcu";
|
||||
ctx.fillStyle = "#f60";
|
||||
ctx.fillRect(125, 1, 62, 20);
|
||||
ctx.fillStyle = "#069";
|
||||
ctx.fillText(txt, 2, 15);
|
||||
ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
|
||||
ctx.fillText(txt, 4, 17);
|
||||
let b64 = canvas.toDataURL().replace("data:image/png;base64,", "");
|
||||
let bin = atob(b64);
|
||||
let fingerprint = _ts.bin2hex(bin.slice(-16, -12));
|
||||
_ts.$store.commit('setFingerprint', fingerprint);
|
||||
},
|
||||
bin2hex(str) {
|
||||
let _ts = this
|
||||
let result = "";
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
let c = str.charCodeAt(i);
|
||||
// 高字节
|
||||
result += _ts.byte2Hex(c >> 8 & 0xff);
|
||||
// 低字节
|
||||
result += _ts.byte2Hex(c & 0xff);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
byte2Hex(b) {
|
||||
if (b < 0x10) {
|
||||
return "0" + b.toString(16);
|
||||
} else {
|
||||
return b.toString(16);
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
mounted() {
|
||||
let _ts = this;
|
||||
let user = _ts.user;
|
||||
if (user) {
|
||||
_ts.getUnreadNotifications();
|
||||
_ts.$store.dispatch('follow/fetchUserFollowerList');
|
||||
_ts.$store.dispatch('follow/fetchUserFollowingList');
|
||||
// sockClient.initSocket(this.$store.state.auth.user);
|
||||
}
|
||||
let fingerprint = _ts.$store.state.fingerprint
|
||||
if (!fingerprint) {
|
||||
_ts.browserFingerprint();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</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: 3rem;
|
||||
}
|
||||
.navbar-brand {
|
||||
color: inherit;
|
||||
margin-right: 1rem;
|
||||
font-size: 1.25rem;
|
||||
white-space: nowrap;
|
||||
font-weight: 600;
|
||||
padding: 0;
|
||||
transition: .3s opacity;
|
||||
line-height: 3rem;
|
||||
}
|
||||
|
||||
.navbar-brand-img {
|
||||
height: 3rem;
|
||||
line-height: 3rem;
|
||||
vertical-align: top;
|
||||
width: auto;
|
||||
}
|
||||
.navbar-brand-img {
|
||||
height: 3rem;
|
||||
line-height: 3rem;
|
||||
vertical-align: top;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.search-result-box {
|
||||
min-width: 20vw !important;
|
||||
}
|
||||
.search-result-box {
|
||||
min-width: 20vw !important;
|
||||
}
|
||||
|
||||
.search-result-type {
|
||||
padding-right: 5px;
|
||||
}
|
||||
.search-result-type {
|
||||
padding-right: 5px;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,6 +0,0 @@
|
||||
export default function ({ store, redirect }) {
|
||||
// If the user is not authenticated
|
||||
if (!store.state.oauth) {
|
||||
return redirect('/login')
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
export default function ({ store, redirect }) {
|
||||
// If the user is authenticated redirect to home page
|
||||
if (store.state.oauth) {
|
||||
return redirect('/')
|
||||
}
|
||||
}
|
@ -70,9 +70,44 @@ export default {
|
||||
modules: [
|
||||
'@nuxtjs/axios',
|
||||
'@nuxtjs/proxy',
|
||||
'js-cookie',
|
||||
'cookieparser'
|
||||
'@nuxtjs/auth-next'
|
||||
],
|
||||
auth: {
|
||||
redirect: {
|
||||
login: '/login',
|
||||
logout: false,
|
||||
home: false
|
||||
},
|
||||
strategies: {
|
||||
local: {
|
||||
// scope: true,
|
||||
scheme: 'refresh',
|
||||
token: {
|
||||
property: 'token',
|
||||
global: true,
|
||||
maxAge: 60 * 15,
|
||||
// required: true,
|
||||
type: false
|
||||
},
|
||||
refreshToken: {
|
||||
property: 'refreshToken',
|
||||
data: 'refreshToken',
|
||||
maxAge: 60 * 60 * 2
|
||||
},
|
||||
user: {
|
||||
property: 'user',
|
||||
autoFetch: false
|
||||
},
|
||||
endpoints: {
|
||||
login: { url: '/api/auth/login', method: 'post' },
|
||||
logout: { url: '/api/auth/logout', method: 'post' },
|
||||
refresh: { url: '/api/auth/refresh-token', method: 'post' },
|
||||
user: { url: '/api/auth/user', method: 'get' }
|
||||
},
|
||||
autoLogout: false
|
||||
}
|
||||
}
|
||||
},
|
||||
axios: {
|
||||
proxy: true // 开启proxy
|
||||
},
|
||||
|
@ -11,13 +11,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@chenfengyuan/vue-qrcode": "^1.0.2",
|
||||
"@nuxtjs/auth-next": "^5.0.0-1648802546.c9880dc",
|
||||
"@nuxtjs/axios": "^5.13.1",
|
||||
"babel-plugin-lodash": "^3.3.4",
|
||||
"cookieparser": "^0.1.0",
|
||||
"echarts": "^4.9.0",
|
||||
"element-ui": "^2.15.8",
|
||||
"express": "^4.18.1",
|
||||
"js-cookie": "^2.2.1",
|
||||
"lodash": "^4.17.21",
|
||||
"net": "^1.0.2",
|
||||
"nuxt": "^2.15.8",
|
||||
|
@ -45,6 +45,7 @@ import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: "Admin",
|
||||
middleware: 'auth',
|
||||
data() {
|
||||
return {
|
||||
menus: [
|
||||
@ -144,7 +145,7 @@ export default {
|
||||
return this.$store.state.activeMenu;
|
||||
},
|
||||
hasPermissions() {
|
||||
return this.$store.getters.hasPermissions('blog_admin');
|
||||
return this.$auth.hasScope('admin') || this.$auth.hasScope('blog_admin');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -107,6 +107,7 @@ import EditTags from '~/components/widget/tags';
|
||||
|
||||
export default {
|
||||
name: "articles",
|
||||
middleware: 'auth',
|
||||
components: {
|
||||
EditTags
|
||||
},
|
||||
|
@ -75,6 +75,7 @@ import Records from "../../components/common/bank/account/records";
|
||||
|
||||
export default {
|
||||
name: "bank-accounts",
|
||||
middleware: 'auth',
|
||||
components: {Records},
|
||||
fetch() {
|
||||
let {store, params, error} = this.$nuxt.context
|
||||
|
@ -87,6 +87,7 @@ import {mapState} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: "banks",
|
||||
middleware: 'auth',
|
||||
fetch() {
|
||||
let {store, params, error} = this.$nuxt.context
|
||||
return Promise.all([
|
||||
|
@ -97,6 +97,7 @@ import {mapState} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: "comments",
|
||||
middleware: 'auth',
|
||||
fetch() {
|
||||
let {store, params, error} = this.$nuxt.context
|
||||
return Promise.all([
|
||||
|
@ -81,6 +81,7 @@ import {mapState} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: "currency-rules",
|
||||
middleware: 'auth',
|
||||
fetch() {
|
||||
let {store, params, error} = this.$nuxt.context
|
||||
return Promise.all([
|
||||
|
@ -248,6 +248,7 @@ import EditTags from '~/components/widget/tags';
|
||||
Vue.prototype.$echarts = echarts;
|
||||
export default {
|
||||
name: "Dashboard",
|
||||
middleware: 'auth',
|
||||
components: {
|
||||
EditTags
|
||||
},
|
||||
|
@ -80,6 +80,7 @@ import {mapState} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: "products",
|
||||
middleware: 'auth',
|
||||
fetch() {
|
||||
let {store, params, error} = this.$nuxt.context
|
||||
return Promise.all([
|
||||
|
@ -91,6 +91,7 @@
|
||||
|
||||
export default {
|
||||
name: "roles",
|
||||
middleware: 'auth',
|
||||
fetch() {
|
||||
let {store, params, error} = this.$nuxt.context
|
||||
return Promise.all([
|
||||
|
@ -126,6 +126,7 @@ import apiConfig from '~/config/api.config';
|
||||
|
||||
export default {
|
||||
name: "PostTag",
|
||||
middleware: 'auth',
|
||||
components: {
|
||||
VueCropper
|
||||
},
|
||||
|
@ -48,6 +48,7 @@
|
||||
|
||||
export default {
|
||||
name: "tags",
|
||||
middleware: 'auth',
|
||||
fetch() {
|
||||
let {store, params, error} = this.$nuxt.context
|
||||
return Promise.all([
|
||||
|
@ -71,6 +71,7 @@ import {mapState} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: "adminTopicDetail",
|
||||
middleware: 'auth',
|
||||
validate({params, store}) {
|
||||
if (typeof params.topic_uri === 'undefined') {
|
||||
return true;
|
||||
@ -94,7 +95,7 @@ export default {
|
||||
tags: state => state.topic.tags.data
|
||||
}),
|
||||
hasPermissions() {
|
||||
return this.$store.getters.hasPermissions('topic');
|
||||
return this.$auth.hasScope('topic');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -53,6 +53,7 @@ import {mapState} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: "adminTopicBindTag",
|
||||
middleware: 'auth',
|
||||
fetch({store, params, error}) {
|
||||
let _ts = this;
|
||||
return Promise.all([
|
||||
|
@ -124,6 +124,7 @@ import apiConfig from '~/config/api.config';
|
||||
|
||||
export default {
|
||||
name: "adminTopicPost",
|
||||
middleware: 'auth',
|
||||
components: {
|
||||
VueCropper
|
||||
},
|
||||
|
@ -39,6 +39,7 @@
|
||||
|
||||
export default {
|
||||
name: "topics",
|
||||
middleware: 'auth',
|
||||
fetch() {
|
||||
let {store, params, error} = this.$nuxt.context
|
||||
return Promise.all([
|
||||
|
@ -119,6 +119,7 @@ import {mapState} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: "users",
|
||||
middleware: 'auth',
|
||||
fetch() {
|
||||
let {store, params, error} = this.$nuxt.context
|
||||
return Promise.all([
|
||||
|
@ -62,6 +62,7 @@ import {mapState} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: "answer",
|
||||
middleware: 'auth',
|
||||
fetch({store, params, error}) {
|
||||
return Promise.all([
|
||||
store
|
||||
|
@ -82,7 +82,7 @@
|
||||
<el-col v-if="article.portfolios && article.portfolios.length > 0">
|
||||
<portfolios-widget :portfolios="article.portfolios"></portfolios-widget>
|
||||
</el-col>
|
||||
<el-col v-if="user">
|
||||
<el-col v-if="loggedIn">
|
||||
<el-tooltip class="item" effect="dark" content="酷" placement="top-start">
|
||||
<el-button type="text" style="font-size: 1.2rem;" @click="thumbsUp">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
||||
@ -192,11 +192,12 @@ export default {
|
||||
article: state => state.article.detail.data,
|
||||
isFetching: state => state.article.detail.fetching,
|
||||
isMobile: state => state.global.isMobile,
|
||||
user: state => state.oauth,
|
||||
avatar: state => state.userInfo?.avatarURL
|
||||
loggedIn: state => state.auth.loggedIn,
|
||||
user: state => state.auth.user,
|
||||
avatar: state => state.auth.user.avatarUrl
|
||||
}),
|
||||
hasPermissions() {
|
||||
let account = this.$store.state.userInfo?.nickname;
|
||||
let account = this.$store.state.auth.user?.nickname;
|
||||
if (account) {
|
||||
if (account === this.article.articleAuthor.userNickname) {
|
||||
return true;
|
||||
@ -205,7 +206,7 @@ export default {
|
||||
return false;
|
||||
},
|
||||
isAdmin() {
|
||||
return this.$store.getters.hasPermissions('blog_admin');
|
||||
return this.$auth.hasScope('admin') || this.$auth.hasScope('blog_admin');
|
||||
},
|
||||
routeArticleId() {
|
||||
return Number(this.$route.params.article_id);
|
||||
|
@ -63,6 +63,7 @@
|
||||
|
||||
export default {
|
||||
name: "PostArticle",
|
||||
middleware: 'auth',
|
||||
validate({params, store}) {
|
||||
if (typeof params.article_id === 'undefined') {
|
||||
return true;
|
||||
@ -80,7 +81,7 @@
|
||||
article: state => state.article.detail.data
|
||||
}),
|
||||
hasPermissions() {
|
||||
let account = this.$store.state.userInfo?.nickname;
|
||||
let account = this.$store.state.auth.user?.nickname;
|
||||
if (account) {
|
||||
if (this.$route.params.article_id) {
|
||||
if (account === this.article.articleAuthor.userNickname) {
|
||||
@ -90,7 +91,7 @@
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return this.$store.getters.hasPermissions('blog_admin');
|
||||
return this.$auth.hasScope('blog_admin');
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
@ -45,7 +45,7 @@ export default {
|
||||
name: "Chat",
|
||||
computed: {
|
||||
...mapState({
|
||||
user: state => state.userInfo
|
||||
user: state => state.auth.user
|
||||
})
|
||||
},
|
||||
data() {
|
||||
|
@ -71,6 +71,7 @@
|
||||
|
||||
export default {
|
||||
name: "DraftDetail",
|
||||
middleware: 'auth',
|
||||
validate({params, store}) {
|
||||
return params.draft_id && !isNaN(Number(params.draft_id))
|
||||
},
|
||||
@ -86,17 +87,17 @@
|
||||
article: state => state.draft.detail.data,
|
||||
isFetching: state => state.draft.detail.fetching,
|
||||
isMobile: state => state.global.isMobile,
|
||||
user: state => state.oauth,
|
||||
avatar: state => state.userInfo?.avatarURL
|
||||
user: state => state.auth.user,
|
||||
avatar: state => state.auth.user?.avatarURL
|
||||
}),
|
||||
hasPermissions() {
|
||||
let account = this.$store.state.userInfo?.nickname;
|
||||
let account = this.$store.state.auth.user?.nickname;
|
||||
if (account) {
|
||||
if (account === this.article?.articleAuthor?.userNickname) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return this.$store.getters.hasPermissions('blog_admin');
|
||||
return this.$auth.hasScope('blog_admin');
|
||||
},
|
||||
routeArticleId() {
|
||||
return Number(this.$route.params.draft_id)
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
export default {
|
||||
name: "Drafts",
|
||||
middleware: 'auth',
|
||||
components: {
|
||||
DraftList
|
||||
},
|
||||
@ -27,7 +28,7 @@
|
||||
computed: {
|
||||
...mapState({
|
||||
articles: state => state.draft.list.data,
|
||||
user: state => state.oauth
|
||||
user: state => state.auth.user
|
||||
})
|
||||
},
|
||||
mounted() {
|
||||
|
@ -54,10 +54,9 @@
|
||||
<script>
|
||||
import {mapState} from 'vuex';
|
||||
|
||||
const Cookie = process.client ? require('js-cookie') : undefined
|
||||
export default {
|
||||
name: "login",
|
||||
middleware: 'notAuthenticated',
|
||||
middleware: 'auth',
|
||||
data() {
|
||||
return {
|
||||
user: {
|
||||
@ -81,40 +80,25 @@ export default {
|
||||
methods: {
|
||||
login() {
|
||||
let _ts = this;
|
||||
_ts.$refs.user.validate((valid) => {
|
||||
_ts.$refs.user.validate(async (valid) => {
|
||||
if (valid) {
|
||||
_ts.$set(_ts, 'loginLoading', true);
|
||||
setTimeout(function () {
|
||||
_ts.$set(_ts, 'loginLoading', false);
|
||||
}, 10000);
|
||||
|
||||
|
||||
let fingerprint = _ts.$store.state.fingerprint;
|
||||
|
||||
let data = {
|
||||
account: _ts.user.account,
|
||||
password: _ts.user.password
|
||||
password: _ts.user.password,
|
||||
fingerprint: fingerprint
|
||||
}
|
||||
|
||||
_ts.$axios.$post('/api/console/login', data).then(function (res) {
|
||||
_ts.$set(_ts, 'loginLoading', false);
|
||||
if (res) {
|
||||
if (res.message) {
|
||||
_ts.$message(res.message);
|
||||
return false;
|
||||
}
|
||||
let auth = {
|
||||
accessToken: res.token,
|
||||
idUser: res.idUser,
|
||||
role: res.weights
|
||||
}
|
||||
|
||||
let user = {
|
||||
nickname: res.nickname,
|
||||
avatarURL: res.avatarUrl || 'https://static.rymcu.com/article/1578475481946.png',
|
||||
account: res.account
|
||||
}
|
||||
_ts.$store.commit('setAuth', auth) // mutating to store for client rendering
|
||||
localStorage.setItem('user', JSON.stringify(user))
|
||||
_ts.$store.commit('setUser', user) // mutating to store for client rendering
|
||||
Cookie.set('auth', auth, { expires: 7 })
|
||||
try {
|
||||
let response = await _ts.$auth.loginWith('local', {data: data})
|
||||
if (response.success) {
|
||||
_ts.$auth.setUserToken(response.data.token, response.data.refreshToken);
|
||||
if (_ts.historyUrl) {
|
||||
window.location.href = _ts.historyUrl
|
||||
} else {
|
||||
@ -123,7 +107,9 @@ export default {
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
export default {
|
||||
name: "Notification",
|
||||
middleware: 'authenticated',
|
||||
middleware: 'auth',
|
||||
components: {
|
||||
NotificationList
|
||||
},
|
||||
@ -33,7 +33,7 @@
|
||||
computed: {
|
||||
...mapState({
|
||||
notifications: state => state.notification.list.data,
|
||||
user: state => state.oauth
|
||||
user: state => state.auth.user
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
|
@ -83,11 +83,11 @@ export default {
|
||||
articles: state => state.portfolio.articles,
|
||||
isFetching: state => state.portfolio.detail.fetching,
|
||||
isMobile: state => state.global.isMobile,
|
||||
user: state => state.oauth,
|
||||
avatar: state => state.userInfo?.avatarURL
|
||||
user: state => state.auth.user,
|
||||
avatar: state => state.auth.user?.avatarURL
|
||||
}),
|
||||
isAuthor() {
|
||||
let account = this.$store.state.userInfo?.nickname;
|
||||
let account = this.$store.state.auth.user?.nickname;
|
||||
if (account) {
|
||||
if (account === this.portfolio.portfolioAuthor.userNickname) {
|
||||
return true;
|
||||
|
@ -78,7 +78,7 @@
|
||||
portfolio: state => state.portfolio.detail.data
|
||||
}),
|
||||
isAuthor() {
|
||||
let account = this.$store.state.userInfo?.nickname;
|
||||
let account = this.$store.state.auth.user?.nickname;
|
||||
if (account) {
|
||||
if (account === this.portfolio.portfolioAuthorName) {
|
||||
return true;
|
||||
|
@ -125,7 +125,7 @@ export default {
|
||||
return {'X-Upload-Token': state.uploadHeaders}
|
||||
},
|
||||
isAuthor() {
|
||||
let account = this.$store.state.userInfo?.nickname;
|
||||
let account = this.$store.state.auth.user?.nickname;
|
||||
if (account) {
|
||||
if (this.$route.params.portfolio_id) {
|
||||
if (account === this.portfolioDetail.portfolioAuthorName) {
|
||||
@ -334,7 +334,7 @@ export default {
|
||||
if (res) {
|
||||
_ts.$set(_ts, 'notificationFlag', false);
|
||||
_ts.$router.push({
|
||||
path: '/user/' + _ts.$store.state.userInfo?.account
|
||||
path: '/user/' + _ts.$store.state.auth.user?.account
|
||||
})
|
||||
}
|
||||
})
|
||||
|
@ -61,8 +61,8 @@
|
||||
</el-link>
|
||||
</el-popover>
|
||||
</div>
|
||||
<div v-if="oauth">
|
||||
<div v-if="oauth.idUser !== user.idUser">
|
||||
<div v-if="auth.user">
|
||||
<div v-if="auth.user.idUser !== user.idUser">
|
||||
<el-button type="primary" v-if="isFollow" @click="cancelFollowUser(user.idUser)" plain>取消关注</el-button>
|
||||
<el-button type="primary" v-else @click="followUser(user.idUser)" plain>关注</el-button>
|
||||
<el-button v-show="false" @click="gotoChats" plain>聊天</el-button>
|
||||
@ -176,7 +176,7 @@ export default {
|
||||
portfolios: state => state.user.portfolios,
|
||||
followers: state => state.user.followers,
|
||||
followings: state => state.user.followings,
|
||||
oauth: state => state.oauth
|
||||
auth: state => state.auth.user
|
||||
})
|
||||
},
|
||||
data() {
|
||||
@ -227,7 +227,7 @@ export default {
|
||||
},
|
||||
followUser(idUser) {
|
||||
let _ts = this;
|
||||
if (_ts.oauth) {
|
||||
if (_ts.auth) {
|
||||
_ts.$axios.$post('/api/follow', {
|
||||
followingId: idUser,
|
||||
followingType: 0
|
||||
@ -241,7 +241,7 @@ export default {
|
||||
},
|
||||
cancelFollowUser(idUser) {
|
||||
let _ts = this;
|
||||
if (_ts.oauth) {
|
||||
if (_ts.auth) {
|
||||
_ts.$axios.$post('/api/follow/cancel-follow', {
|
||||
followingId: idUser,
|
||||
followingType: 0
|
||||
@ -265,7 +265,7 @@ export default {
|
||||
mounted() {
|
||||
let _ts = this;
|
||||
this.$store.commit('setActiveMenu', 'user');
|
||||
if (_ts.oauth) {
|
||||
if (_ts.auth) {
|
||||
_ts.$axios.$get('/api/follow/is-follow', {
|
||||
params: {
|
||||
followingId: _ts.user.idUser,
|
||||
|
@ -47,12 +47,13 @@
|
||||
<script>
|
||||
export default {
|
||||
name: "Settings",
|
||||
middleware: 'auth',
|
||||
computed: {
|
||||
getActiveMenu () {
|
||||
return this.$store.state.activeMenu;
|
||||
},
|
||||
isLogin () {
|
||||
return this.$store.state.oauth;
|
||||
return this.$store.state.auth.user;
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
@ -65,9 +65,10 @@
|
||||
|
||||
export default {
|
||||
name: "account",
|
||||
middleware: 'auth',
|
||||
computed: {
|
||||
...mapState({
|
||||
idUser: state => state.oauth.idUser
|
||||
idUser: state => state.auth.user.idUser
|
||||
})
|
||||
},
|
||||
data() {
|
||||
|
@ -81,6 +81,7 @@ import 'cropperjs/dist/cropper.css';
|
||||
const {generateRandomAvatar} = require('~/plugins/avataaars/generator/generateAvatar');
|
||||
export default {
|
||||
name: "avatar",
|
||||
middleware: 'auth',
|
||||
components: {
|
||||
Avataaars,
|
||||
VueCropper
|
||||
@ -90,7 +91,7 @@ export default {
|
||||
uploadHeaders: state => {
|
||||
return {'X-Upload-Token': state.uploadHeaders}
|
||||
},
|
||||
idUser: state => state.oauth.idUser
|
||||
idUser: state => state.auth.user.idUser
|
||||
})
|
||||
},
|
||||
data() {
|
||||
|
@ -12,10 +12,11 @@ import LoginRecords from "@/components/common/user/login-records";
|
||||
|
||||
export default {
|
||||
name: "loginRecord",
|
||||
middleware: 'auth',
|
||||
components: {LoginRecords},
|
||||
computed: {
|
||||
...mapState({
|
||||
idUser: state => state.oauth.idUser
|
||||
idUser: state => state.auth.user.idUser
|
||||
})
|
||||
},
|
||||
data() {
|
||||
|
@ -79,7 +79,7 @@ export default {
|
||||
name: "security",
|
||||
computed: {
|
||||
...mapState({
|
||||
idUser: state => state.oauth.idUser
|
||||
idUser: state => state.auth.user.idUser
|
||||
})
|
||||
},
|
||||
data() {
|
||||
|
@ -1,17 +1,22 @@
|
||||
<template>
|
||||
<el-row class="wrapper">
|
||||
<el-col>
|
||||
<h1>账户信息</h1>
|
||||
<el-col v-if="bankAccount">
|
||||
<el-col>
|
||||
<h1>账户信息</h1>
|
||||
</el-col>
|
||||
<el-col class="bank-account-item">
|
||||
<span style="font-size: 24px;"> 账号:</span> <span style="color: red;">{{ bankAccount.bankAccount }}</span>
|
||||
</el-col>
|
||||
<el-col class="bank-account-item">
|
||||
<span style="font-size: 24px;"> 余额:</span> <span style="color: red;">{{ bankAccount.accountBalance }}</span> <span
|
||||
style="font-size: 24px;">巴旦木</span>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<records :records="records" :bankAccount="bankAccount.bankAccount" @currentChange="handleCurrentChange" @searchTransactionRecord="searchTransactionRecord"></records>
|
||||
</el-col>
|
||||
</el-col>
|
||||
<el-col class="bank-account-item">
|
||||
<span style="font-size: 24px;"> 账号:</span> <span style="color: red;">{{ bankAccount.bankAccount }}</span>
|
||||
</el-col>
|
||||
<el-col class="bank-account-item">
|
||||
<span style="font-size: 24px;"> 余额:</span> <span style="color: red;">{{ bankAccount.accountBalance }}</span> <span
|
||||
style="font-size: 24px;">巴旦木</span>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<records :records="records" :bankAccount="bankAccount.bankAccount" @currentChange="handleCurrentChange" @searchTransactionRecord="searchTransactionRecord"></records>
|
||||
<el-col v-else style="text-align: center;margin-top: 10vh;">
|
||||
<el-button type="primary">开通钱包账号</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
@ -26,10 +31,10 @@ export default {
|
||||
fetch({store, error}) {
|
||||
return Promise.all([
|
||||
store
|
||||
.dispatch('wallet/fetchDetail', {idUser: store.state.oauth.idUser})
|
||||
.dispatch('wallet/fetchDetail')
|
||||
.catch(err => error({statusCode: 404})),
|
||||
store
|
||||
.dispatch('wallet/fetchTransactionRecordList', {idUser: store.state.oauth.idUser})
|
||||
.dispatch('wallet/fetchTransactionRecordList')
|
||||
.catch(err => error({statusCode: 404}))
|
||||
])
|
||||
},
|
||||
@ -47,7 +52,7 @@ export default {
|
||||
handleCurrentChange(search) {
|
||||
let _ts = this;
|
||||
_ts.$store.dispatch('wallet/fetchTransactionRecordList', {
|
||||
idUser: _ts.$store.state.oauth.idUser,
|
||||
idUser: _ts.$store.state.auth.user.idUser,
|
||||
startDate: search.startDate,
|
||||
endDate: search.endDate,
|
||||
page: search.page
|
||||
@ -58,7 +63,7 @@ export default {
|
||||
let startDate = dates[0]
|
||||
let endDate = dates[1]
|
||||
_ts.$store.dispatch('wallet/fetchTransactionRecordList', {
|
||||
idUser: _ts.$store.state.oauth.idUser,
|
||||
idUser: _ts.$store.state.auth.user.idUser,
|
||||
startDate: startDate,
|
||||
endDate: endDate
|
||||
})
|
||||
|
@ -1,18 +1,11 @@
|
||||
import {Message} from 'element-ui'
|
||||
|
||||
const Cookie = process.client ? require('js-cookie') : undefined
|
||||
export default function ({app, $axios, store, redirect}) {
|
||||
$axios.onRequest(config => {
|
||||
let fingerprint = store.state.fingerprint;
|
||||
if (fingerprint) {
|
||||
config.headers['fingerprint'] = fingerprint
|
||||
}
|
||||
let token = store.state.oauth?.accessToken;
|
||||
if (token) {
|
||||
// if (!(config.url.indexOf('console') > -1 || config.url.indexOf('comments') > -1)) {
|
||||
// }
|
||||
config.headers['Authorization'] = token
|
||||
}
|
||||
})
|
||||
$axios.onResponse(response => {
|
||||
return new Promise((resolve, reject) => {
|
||||
@ -29,13 +22,9 @@ export default function ({app, $axios, store, redirect}) {
|
||||
if (response.data.code === 0) {
|
||||
Message.error(message ? message : '服务异常')
|
||||
} else if (response.data.code === 401) {
|
||||
Cookie.remove('auth');
|
||||
store.commit('setAuth', null);
|
||||
window.location.reload()
|
||||
app.$auth.logout()
|
||||
} else if (response.data.code === 402) {
|
||||
Cookie.remove('auth');
|
||||
store.commit('setAuth', null);
|
||||
window.location.reload()
|
||||
app.$auth.strategy.token.reset()
|
||||
} else if (response.data.code === 404) {
|
||||
Message.error('操作失败,请稍后再试......')
|
||||
} else if (response.data.code === 500) {
|
||||
@ -47,6 +36,7 @@ export default function ({app, $axios, store, redirect}) {
|
||||
reject(response);
|
||||
})
|
||||
});
|
||||
|
||||
$axios.onError(error => {
|
||||
const code = parseInt(error.response && error.response.status)
|
||||
if (code === 400) {
|
||||
|
@ -26,7 +26,6 @@ export const mutations = {
|
||||
state.list.fetching = action
|
||||
},
|
||||
updateListData(state, action) {
|
||||
console.log(action)
|
||||
state.list.data = action
|
||||
},
|
||||
// 文章详情
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { isServer } from '~/environment'
|
||||
|
||||
const cookieParser = isServer ? require('cookieparser') : undefined
|
||||
|
||||
export const state = () => {
|
||||
return {
|
||||
activeMenu: 'index',
|
||||
@ -14,28 +12,12 @@ export const state = () => {
|
||||
}
|
||||
|
||||
export const mutations = {
|
||||
setAuth (state, auth) {
|
||||
state.oauth = auth
|
||||
},
|
||||
setUser (state, data) {
|
||||
state.userInfo = data
|
||||
},
|
||||
setActiveMenu (state, activeMenu) {
|
||||
state.activeMenu = activeMenu
|
||||
},
|
||||
setUploadHeaders(state, data){
|
||||
state.uploadHeaders = data
|
||||
},
|
||||
setUserInfo(state, data) {
|
||||
state.userInfo.avatarURL = data.avatarUrl;
|
||||
state.userInfo.nickname = data.nickname;
|
||||
let user = {
|
||||
nickname: data.nickname,
|
||||
avatarURL: data.avatarUrl,
|
||||
account: this.state.userInfo.account
|
||||
}
|
||||
localStorage.setItem('user', JSON.stringify(user))
|
||||
},
|
||||
setFingerprint (state, fingerprint) {
|
||||
state.fingerprint = fingerprint
|
||||
}
|
||||
@ -65,17 +47,6 @@ export const actions = {
|
||||
// 移动端
|
||||
store.commit('global/updateMobileState', true)
|
||||
}
|
||||
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
|
||||
console.log(err);
|
||||
}
|
||||
store.commit('setAuth', auth)
|
||||
}
|
||||
|
||||
const initFetchAppData = [
|
||||
// 内容数据
|
||||
@ -86,36 +57,3 @@ export const actions = {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -39,10 +39,10 @@ export const mutations = {
|
||||
|
||||
export const actions = {
|
||||
// 获取账户详情
|
||||
fetchDetail({commit}, params = {}) {
|
||||
fetchDetail({commit}) {
|
||||
commit('updateDetailFetching', true)
|
||||
return this.$axios
|
||||
.$get(`${WALLET_API_PATH}/${params.idUser}`)
|
||||
.$get(`${WALLET_API_PATH}/detail`)
|
||||
.then(response => {
|
||||
return new Promise(resolve => {
|
||||
commit('updateDetailData', response)
|
||||
@ -64,7 +64,6 @@ export const actions = {
|
||||
return this.$axios
|
||||
.$get(`${WALLET_API_PATH}/transaction-records`, {
|
||||
params: {
|
||||
idUser: params.idUser,
|
||||
startDate: params.startDate,
|
||||
endDate: params.endDate,
|
||||
page: params.page || 1
|
||||
|
Loading…
Reference in New Issue
Block a user