diff --git a/components/common/comment/index.js b/components/common/comment/index.js new file mode 100644 index 0000000..edeeba8 --- /dev/null +++ b/components/common/comment/index.js @@ -0,0 +1,15 @@ +/** + * @file Comment box component / ES module + * @module components/common/comment + * @author Surmon + */ + +import Comment from './main' + +export const comment = { + install(Vue) { + Vue.component('comment-box', Comment) + } +} + +export default comment diff --git a/components/common/comment/main.vue b/components/common/comment/main.vue new file mode 100644 index 0000000..88d9da7 --- /dev/null +++ b/components/common/comment/main.vue @@ -0,0 +1,328 @@ + + + + + diff --git a/components/layouts/mobile/header.vue b/components/layouts/mobile/header.vue index e5749bd..9aac976 100644 --- a/components/layouts/mobile/header.vue +++ b/components/layouts/mobile/header.vue @@ -196,7 +196,7 @@ getUnreadNotifications() { let _ts = this; if (_ts.isLogin) { - _ts.$axios.$get('/api/v1/notification/unread', { + _ts.$axios.$get('/api/notification/unread', { headers: { Authorization: _ts.$store.state.oauth?.accessToken } diff --git a/components/layouts/pc/header.vue b/components/layouts/pc/header.vue index 5ae8690..f405c92 100644 --- a/components/layouts/pc/header.vue +++ b/components/layouts/pc/header.vue @@ -196,10 +196,10 @@ getUnreadNotifications() { let _ts = this; if (_ts.isLogin) { - _ts.$axios.$get('/api/v1/notification/unread').then(function (res) { + _ts.$axios.$get('/api/notification/unread').then(function (res) { if (res) { - _ts.$set(_ts, 'notifications', res.data.notifications); - _ts.$set(_ts, 'notificationNumbers', res.data.notifications.length == 0 ? "" : res.data.notifications.length); + _ts.$set(_ts, 'notifications', res.notifications); + _ts.$set(_ts, 'notificationNumbers', res.notifications.length == 0 ? "" : res.notifications.length); } }) } diff --git a/nuxt.config.js b/nuxt.config.js index 6359d49..948a79c 100644 --- a/nuxt.config.js +++ b/nuxt.config.js @@ -2,7 +2,6 @@ import appConfig from './config/app.config' import apiConfig from './config/api.config' import {isProdMode, isDevMode} from './environment' - export default { /* ** Nuxt rendering mode @@ -13,7 +12,7 @@ export default { ** Render configuration */ render: { - csp: true + csp: false }, modern: true, dev: isDevMode, @@ -52,9 +51,10 @@ export default { ** https://nuxtjs.org/guide/plugins */ plugins: [ - {src: '@/plugins/axios'}, - {src: '@/plugins/element-ui'}, - {src: '@/plugins/vditor', ssr: false} + {src: '~/plugins/extend'}, + {src: '~/plugins/axios'}, + {src: '~/plugins/element-ui'}, + {src: '~/plugins/vditor', ssr: false} ], /* ** Nuxt.js dev-modules @@ -64,10 +64,20 @@ export default { ** Nuxt.js modules */ modules: [ - ['@nuxtjs/axios', {baseURL: apiConfig.BASE}], + '@nuxtjs/axios', + '@nuxtjs/proxy', 'js-cookie', 'cookieparser' ], + axios: { + proxy: true // 开启proxy + }, + proxy: [ //proxy配置 + ['/api', { + target:'https://rymcu.com/vertical-console/', //api请求路径 + pathRewrite: { '^/api' : '/api/v1' } //重定向请求路径,防止路由、api路径的冲突 + }] + ], /* ** Build configuration ** See https://nuxtjs.org/api/configuration-build/ diff --git a/package-lock.json b/package-lock.json index 83aa9d6..705e5db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1471,21 +1471,28 @@ } }, "@nuxtjs/axios": { - "version": "5.11.0", - "resolved": "https://registry.npm.taobao.org/@nuxtjs/axios/download/@nuxtjs/axios-5.11.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40nuxtjs%2Faxios%2Fdownload%2F%40nuxtjs%2Faxios-5.11.0.tgz", - "integrity": "sha1-J9cpemnhHDkDm5ysrGHi4NDgDx8=", + "version": "5.12.0", + "resolved": "https://registry.npm.taobao.org/@nuxtjs/axios/download/@nuxtjs/axios-5.12.0.tgz", + "integrity": "sha1-UGkjQOZOyDjxZ9KS1ZscwqDi2+8=", "requires": { "@nuxtjs/proxy": "^2.0.0", "axios": "^0.19.2", "axios-retry": "^3.1.8", - "consola": "^2.11.3", - "defu": "^2.0.2" + "consola": "^2.14.0", + "defu": "^2.0.4" + }, + "dependencies": { + "consola": { + "version": "2.14.0", + "resolved": "https://registry.npm.taobao.org/consola/download/consola-2.14.0.tgz?cache=0&sync_timestamp=1593184572399&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fconsola%2Fdownload%2Fconsola-2.14.0.tgz", + "integrity": "sha1-Fi7pA7bJxN4lB32T80q5AuvLTaw=" + } } }, "@nuxtjs/proxy": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/@nuxtjs/proxy/download/@nuxtjs/proxy-2.0.0.tgz", - "integrity": "sha1-zxmJTqxyGirYlik/JBNx8Ebbcec=", + "version": "2.0.1", + "resolved": "https://registry.npm.taobao.org/@nuxtjs/proxy/download/@nuxtjs/proxy-2.0.1.tgz", + "integrity": "sha1-JGm24xYxGqjGDTSFAqVL/m1VNqo=", "requires": { "consola": "^2.11.3", "http-proxy-middleware": "^1.0.4" @@ -2261,6 +2268,29 @@ "integrity": "sha1-PqNsXYgY0NX4qKl6bTa4bNwAyyc=", "requires": { "follow-redirects": "1.5.10" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npm.taobao.org/debug/download/debug-3.1.0.tgz", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "requires": { + "ms": "2.0.0" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.5.10.tgz?cache=0&sync_timestamp=1592518530318&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.5.10.tgz", + "integrity": "sha1-e3qfmuov3/NnhqlP9kPtB/T/Xio=", + "requires": { + "debug": "=3.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } } }, "axios-retry": { @@ -3107,17 +3137,6 @@ } } }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npm.taobao.org/clone-deep/download/clone-deep-4.0.1.tgz", - "integrity": "sha1-wZ/Zvbv4WUK0/ZechNz31fB8I4c=", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, "coa": { "version": "2.0.2", "resolved": "https://registry.npm.taobao.org/coa/download/coa-2.0.2.tgz", @@ -4856,27 +4875,9 @@ } }, "follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.5.10.tgz?cache=0&sync_timestamp=1592518530318&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.5.10.tgz", - "integrity": "sha1-e3qfmuov3/NnhqlP9kPtB/T/Xio=", - "requires": { - "debug": "=3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npm.taobao.org/debug/download/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } + "version": "1.12.1", + "resolved": "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.12.1.tgz?cache=0&sync_timestamp=1592518530318&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.12.1.tgz", + "integrity": "sha1-3lSmIFMRuT1gOY68Ac9wFWgjErY=" }, "for-in": { "version": "1.0.2", @@ -5595,14 +5596,14 @@ } }, "http-proxy-middleware": { - "version": "1.0.4", - "resolved": "https://registry.npm.taobao.org/http-proxy-middleware/download/http-proxy-middleware-1.0.4.tgz", - "integrity": "sha1-Ql6hd5hqDNo0+cgeyWHHGa22wqk=", + "version": "1.0.5", + "resolved": "https://registry.npm.taobao.org/http-proxy-middleware/download/http-proxy-middleware-1.0.5.tgz", + "integrity": "sha1-TG4l2VpBHj11C8ecz2YpBnUXbcI=", "requires": { "@types/http-proxy": "^1.17.4", "http-proxy": "^1.18.1", "is-glob": "^4.0.1", - "lodash": "^4.17.15", + "lodash": "^4.17.19", "micromatch": "^4.0.2" }, "dependencies": { @@ -5627,6 +5628,11 @@ "resolved": "https://registry.npm.taobao.org/is-number/download/is-number-7.0.0.tgz", "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=" }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npm.taobao.org/lodash/download/lodash-4.17.19.tgz?cache=0&sync_timestamp=1594226827854&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.19.tgz", + "integrity": "sha1-5I3e2+MLMyF4PFtDAfvTU7weSks=" + }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npm.taobao.org/micromatch/download/micromatch-4.0.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmicromatch%2Fdownload%2Fmicromatch-4.0.2.tgz", @@ -6298,6 +6304,12 @@ "resolved": "https://registry.npm.taobao.org/kind-of/download/kind-of-6.0.3.tgz", "integrity": "sha1-B8BQNKbDSfoG4k+jWqdttFgM5N0=" }, + "klona": { + "version": "1.1.2", + "resolved": "https://registry.npm.taobao.org/klona/download/klona-1.1.2.tgz?cache=0&sync_timestamp=1594031545393&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fklona%2Fdownload%2Fklona-1.1.2.tgz", + "integrity": "sha1-p54pJRilpUEuyNCXlkv/FXGmTbA=", + "dev": true + }, "last-call-webpack-plugin": { "version": "3.0.0", "resolved": "https://registry.npm.taobao.org/last-call-webpack-plugin/download/last-call-webpack-plugin-3.0.0.tgz", @@ -9348,23 +9360,28 @@ } }, "sass-loader": { - "version": "8.0.2", - "resolved": "https://registry.npm.taobao.org/sass-loader/download/sass-loader-8.0.2.tgz", - "integrity": "sha1-3r7NjDziQ8dkVPLoKQSCFQOACQ0=", + "version": "9.0.2", + "resolved": "https://registry.npm.taobao.org/sass-loader/download/sass-loader-9.0.2.tgz?cache=0&sync_timestamp=1594134152417&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsass-loader%2Fdownload%2Fsass-loader-9.0.2.tgz", + "integrity": "sha1-hHybTJUyjdyMfTXPKMnW5U5ZqQs=", "dev": true, "requires": { - "clone-deep": "^4.0.1", - "loader-utils": "^1.2.3", + "klona": "^1.1.1", + "loader-utils": "^2.0.0", "neo-async": "^2.6.1", - "schema-utils": "^2.6.1", - "semver": "^6.3.0" + "schema-utils": "^2.7.0", + "semver": "^7.3.2" }, "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npm.taobao.org/semver/download/semver-6.3.0.tgz", - "integrity": "sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0=", - "dev": true + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-2.0.0.tgz?cache=0&sync_timestamp=1584445207623&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-utils%2Fdownload%2Floader-utils-2.0.0.tgz", + "integrity": "sha1-5MrOW4FtQloWa18JfhDNErNgZLA=", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } } } }, @@ -9541,15 +9558,6 @@ "safe-buffer": "^5.0.1" } }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npm.taobao.org/shallow-clone/download/shallow-clone-3.0.1.tgz", - "integrity": "sha1-jymBrZJTH1UDWwH7IwdppA4C76M=", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npm.taobao.org/shebang-command/download/shebang-command-2.0.0.tgz", @@ -10747,11 +10755,11 @@ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, "vditor": { - "version": "3.3.3", - "resolved": "https://registry.npm.taobao.org/vditor/download/vditor-3.3.3.tgz", - "integrity": "sha1-+6sWvyWeBgqVAqqKFGlDpwzXV/E=", + "version": "3.3.8", + "resolved": "https://registry.npm.taobao.org/vditor/download/vditor-3.3.8.tgz", + "integrity": "sha1-1gucJNej4iA1LAu7qxWP9ek+lV8=", "requires": { - "diff-match-patch": "^1.0.4" + "diff-match-patch": "^1.0.5" } }, "vendors": { diff --git a/package.json b/package.json index 8b97f02..31020a3 100644 --- a/package.json +++ b/package.json @@ -9,18 +9,18 @@ "generate": "nuxt generate" }, "dependencies": { - "@nuxtjs/axios": "^5.11.0", + "@nuxtjs/axios": "^5.12.0", "cookieparser": "^0.1.0", "cross-env": "^7.0.2", "element-ui": "^2.13.2", "express": "^4.17.1", "js-cookie": "^2.2.1", "nuxt": "^2.13.3", - "vditor": "^3.3.3" + "vditor": "^3.3.8" }, "devDependencies": { - "@nuxtjs/proxy": "^2.0.0", + "@nuxtjs/proxy": "^2.0.1", "node-sass": "^4.14.1", - "sass-loader": "^8.0.2" + "sass-loader": "^9.0.2" } } diff --git a/pages/article/_article_id.vue b/pages/article/_article_id.vue index 7406297..c78641d 100644 --- a/pages/article/_article_id.vue +++ b/pages/article/_article_id.vue @@ -19,7 +19,7 @@ {{ article.timeAgo }} - + @@ -82,39 +82,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 登录 - 后发布评论 - - + @@ -137,7 +107,7 @@ store .dispatch('article/fetchDetail', params) .catch(err => error({statusCode: 404})), - // store.dispatch('comment/fetchList', {post_id: params.article_id}) + store.dispatch('comment/fetchList', {post_id: params.article_id}) ]) }, computed: { @@ -145,8 +115,8 @@ article: state => state.article.detail.data, isFetching: state => state.article.detail.fetching, isMobile: state => state.global.isMobile, - isLogin: state => state.oauth, - avatar: state => state.oauth?.avatarURL, + user: state => state.oauth, + avatar: state => state.oauth?.avatarURL }), hasPermissions() { let account = this.$store.state.oauth?.nickname; @@ -156,6 +126,9 @@ } } return this.$store.getters.hasPermissions('blog_admin'); + }, + routeArticleId() { + return Number(this.$route.params.article_id) } }, head() { @@ -226,7 +199,7 @@ } }) } else { - _ts.$axios.$get('/api/v1/article/' + _ts.article.idArticle + '/share').then(function (res) { + _ts.$axios.$get('/api/article/' + _ts.article.idArticle + '/share').then(function (res) { if (res) { _ts.$set(_ts, 'shareData', res); _ts.$set(_ts, 'isShare', true); @@ -241,7 +214,7 @@ } }, mounted() { - this.$store.commit('setActiveMenu', 'articleDetail') + this.$store.commit('setActiveMenu', 'articleDetail'); Vue.nextTick(() => { const previewElement = document.getElementById("articleContent"); // //const outLineElement = document.getElementById("articleToC"); @@ -258,6 +231,7 @@ Vue.VditorPreview.abcRender(previewElement); Vue.VditorPreview.mediaRender(previewElement); //VditorPreview.outlineRender(previewElement, outLineElement); + window.scrollTo(0,0); }) } diff --git a/pages/login.vue b/pages/login.vue index 4f64034..5a14f3c 100644 --- a/pages/login.vue +++ b/pages/login.vue @@ -86,7 +86,7 @@ password: _ts.user.password } - _ts.$axios.$post('/api/v1/console/login', data).then(function (res) { + _ts.$axios.$post('/api/console/login', data).then(function (res) { if (res) { if (res.message) { _ts.$message(res.message); @@ -96,6 +96,7 @@ accessToken: res.user.token, nickname: res.user.nickname, avatarURL: res.user.avatarUrl, + idUser: res.user.idUser, role: res.user.weights } _ts.$store.commit('setAuth', auth) // mutating to store for client rendering diff --git a/pages/register.vue b/pages/register.vue index 789bea1..c9b3405 100644 --- a/pages/register.vue +++ b/pages/register.vue @@ -63,7 +63,7 @@ let data = { email: email } - _ts.$axios.$get('/api/v1/console/get-email-code', { + _ts.$axios.$get('/api/console/get-email-code', { params: data }).then(response => { if (response.data) { @@ -82,7 +82,7 @@ password: _ts.user.password, code: _ts.user.code } - _ts.$axios.$post('/api/v1/console/register', data).then(function (res) { + _ts.$axios.$post('/api/console/register', data).then(function (res) { if (res) { _ts.$message(res.message); if (res.flag && res.flag === 1) { diff --git a/plugins/extend.js b/plugins/extend.js new file mode 100644 index 0000000..fbb82a2 --- /dev/null +++ b/plugins/extend.js @@ -0,0 +1,3 @@ +import Vue from 'vue' +import CommentBox from '~/components/common/comment' +Vue.use(CommentBox) diff --git a/plugins/vditor.js b/plugins/vditor.js index aa4b6fd..cc509c6 100644 --- a/plugins/vditor.js +++ b/plugins/vditor.js @@ -1,4 +1,7 @@ import Vue from 'vue'; import VditorPreview from 'vditor/dist/method.min'; -Vue.VditorPreview = VditorPreview +import Vditor from 'vditor'; + +Vue.VditorPreview = VditorPreview; +Vue.Vditor = Vditor diff --git a/store/article.js b/store/article.js index 0841faa..5ea0d66 100644 --- a/store/article.js +++ b/store/article.js @@ -1,7 +1,7 @@ import Vue from 'vue'; import { isBrowser } from '~/environment'; -export const ARTICLE_API_PATH = '/api/v1/console' +export const ARTICLE_API_PATH = '/api/console' const getDefaultListData = () => { return { diff --git a/store/comment.js b/store/comment.js new file mode 100644 index 0000000..7234cb2 --- /dev/null +++ b/store/comment.js @@ -0,0 +1,117 @@ +/** + * @file 评论数据状态 / ES module + * @module store/comment + * @author Surmon + */ + +export const COMMENT_API_PATH = '/api/article/' +export const LIKE_COMMENT_API_PATH = '/like/comment' + +const getDefaultListData = () => { + return { + data: [], + pagination: {} + } +} + +export const state = () => { + return { + fetching: false, + posting: false, + data: getDefaultListData() + } +} + +export const mutations = { + // 请求列表 + updateListFetching(state, action) { + state.fetching = action + }, + updateListData(state, action) { + state.data = { + data: action.comments, + pagination: { + page: 1 + } + } + }, + clearListData(state) { + state.data = getDefaultListData() + }, + + // 发布评论 + updatePostFetching(state, action) { + state.posting = action + }, + updateListNewItemData(state, action) { + state.data.pagination.total += 1 + state.data.data.push(action.result) + }, + + // 喜欢某条评论 + updateLikesIncrement(state, action) { + state.data.data.find(comment => { + const isMatched = comment.id === action.id + isMatched && comment.likes++ + return isMatched + }) + } +} + +export const actions = { + fetchList({ commit, rootState }, params = {}) { + // const { SortType } = rootState.global.constants + + // 修正参数 + // params = Object.assign( + // { + // page: 1, + // per_page: 88 + // }, + // params + // ) + + // const isRestart = params.page === 1 + // const isDescSort = params.sort === SortType.Desc + + // 清空数据 + // isRestart && commit('updateListData', getDefaultListData()) + commit('updateListData', getDefaultListData()) + commit('updateListFetching', true) + + return this.$axios + .$get(COMMENT_API_PATH + `${params.post_id}/comments`) + .then(response => { + // isDescSort && response.result.data.reverse() + commit('updateListData', response) + commit('updateListFetching', false) + }) + .catch(error => commit('updateListFetching', false)) + }, + + // 发布评论 + fetchPostComment({ commit }, comment) { + commit('updatePostFetching', true) + return this.$axios + .$post(COMMENT_API_PATH, comment) + .then(response => { + commit('updateListNewItemData', response) + commit('updatePostFetching', false) + return Promise.resolve(response) + }) + .catch(error => { + commit('updatePostFetching', false) + return Promise.reject(error) + }) + }, + + // 喜欢评论 + fetchLikeComment({ commit }, comment) { + return this.$axios + .$patch(LIKE_COMMENT_API_PATH, { comment_id: comment.id }) + .then(response => { + commit('updateLikesIncrement', comment) + return Promise.resolve(response) + }) + } +} diff --git a/store/index.js b/store/index.js index fce8c3c..85446e3 100644 --- a/store/index.js +++ b/store/index.js @@ -3,7 +3,8 @@ const cookieparser = process.server ? require('cookieparser') : undefined export const state = () => { return { activeMenu: 'index', - oauth: null + oauth: null, + locale: 'zh_CN' } }