first commit

This commit is contained in:
ronger 2020-06-23 17:40:43 +08:00
parent f1f9648a06
commit 0348969a99
7 changed files with 1524 additions and 45 deletions

View File

@ -30,5 +30,29 @@
</script> </script>
<style scoped> <style scoped>
.el-header {
padding-bottom: 1rem;
background: #fff;
border-bottom: 1px solid rgba(0, 40, 100, 0.12);
z-index: 80;
}
.el-main {
padding: 20px 0;
background-attachment: fixed;
min-height: 280px;
margin-bottom: 60px;
overflow-x: hidden;
}
.el-footer {
position: fixed;
bottom: 0;
width: 100%;
padding-top: 1rem;
padding-bottom: 1rem;
background: #fff;
border-top: 1px solid rgba(0, 40, 100, 0.12);
z-index: 80;
}
</style> </style>

View File

@ -3,7 +3,7 @@ import { NODE_ENV } from '../environment'
const apisMap = { const apisMap = {
development: { development: {
FE: 'http://localhost:3000', FE: 'http://localhost:3000',
BASE: 'http://localhost:8099/vertical-console', BASE: 'http://localhost:8099/vertical',
CDN: '', CDN: '',
PROXY: '/proxy', PROXY: '/proxy',
SOCKET: 'http://localhost:3000', SOCKET: 'http://localhost:3000',

1325
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,8 @@
"vditor": "^3.3.2" "vditor": "^3.3.2"
}, },
"devDependencies": { "devDependencies": {
"@nuxtjs/proxy": "^2.0.0" "@nuxtjs/proxy": "^2.0.0",
"node-sass": "^4.14.1",
"sass-loader": "^8.0.2"
} }
} }

View File

@ -1,13 +1,168 @@
<template> <template>
<el-row class="article__wrapper">
<el-col v-if="isShow">
<el-col>
<el-card>
<div class="card-body d-flex flex-column article">
<div class="article__item">
<h1 class="list__title" v-html="article.articleTitle"></h1>
<el-row class="pt-5">
<el-col :xs="3" :sm="1" :xl="1">
<el-avatar v-if="article.articleAuthorAvatarUrl" :src="article.articleAuthorAvatarUrl"></el-avatar>
<el-avatar v-else src="https://rymcu.com/vertical/article/1578475481946.png"></el-avatar>
</el-col>
<el-col :xs="9" :sm="11" :xl="11">
<div style="margin-left: 1rem;">
<el-link @click="onRouter('user', article.articleAuthorName)" :underline="false"
class="text-default">{{ article.articleAuthorName }}
</el-link>
<small class="d-block text-muted">{{ article.timeAgo }}</small>
</div>
</el-col>
<el-col :xs="12" :sm="12" :xl="12" v-if="isLogin" class="text-right">
<el-dropdown trigger="click" @command="handleCommand">
<el-link :underline="false"><i class="el-icon-more"></i></el-link>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="edit" v-if="hasPermissions">编辑</el-dropdown-item>
<el-dropdown-item command="share">分享</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-col>
<el-col class="text-right">
<el-link :underline="false" title="总浏览数"><i class="el-icon-s-data"></i><span style="color: red;">{{ article.articleViewCount }}</span>
</el-link>
</el-col>
<el-col style="margin: 1rem 0;">
<el-tag
style="margin-right: 0.5rem;"
v-for="tag in article.tags"
:key="tag.idTag"
size="small"
effect="plain">
{{ tag.tagTitle }}
</el-tag>
</el-col>
<el-col v-if="article.portfolios && article.portfolios.length > 0">
<el-col>
<h4>所属作品集</h4>
</el-col>
<el-col style="padding: 1rem">
<el-col v-for="portfolio in article.portfolios" :key="portfolio.idPortfolio" :span="8">
<el-col :xs="3" :sm="3" :xl="3">
<el-avatar :size="24" :src="portfolio.headImgUrl"></el-avatar>
</el-col>
<el-col :xs="20" :sm="20" :xl="20">
<el-link @click="onRouter('portfolio', portfolio.idPortfolio)" :underline="false"
class="text-default">{{ portfolio.portfolioTitle }}
</el-link>
</el-col>
</el-col>
</el-col>
</el-col>
<el-col v-if="isShare" style="margin-bottom: 1rem;">
<el-input v-model="shareData.shareUrl">
<el-popover slot="append"
placement="bottom"
width="20"
trigger="hover">
<el-col>
<qrcode :value="shareWeiXin(shareData.shareUrl)" :options="{ width: 20 }"></qrcode>
</el-col>
<el-col class="text-center">
<span>扫码分享至微信</span>
</el-col>
<el-button slot="reference">
<el-image style="width: 14px;height: 14px;" :src="weiXin" fit="cover"></el-image>
</el-button>
</el-popover>
</el-input>
</el-col>
</el-row>
<div class="pt-7 pipe-content__reset" v-html="article.articleContent" style="overflow: hidden;"></div>
</div>
</div>
</el-card>
</el-col>
<el-col v-if="isLogin" style="margin-top: 1rem;">
<el-col :xs="2" :sm="1" :xl="1">
<el-avatar :src="avatar"></el-avatar>
</el-col>
<el-col :xs="22" :sm="23" :xl="23" style="padding-left: 1rem;">
<el-input @click.native="showComment" placeholder="请输入回帖内容"></el-input>
</el-col>
<el-col>
<el-drawer
:visible.sync="drawer"
:direction="direction"
size="40%">
<el-col slot="title">
<el-col>
<el-avatar v-if="commentAuthorAvatar" :src="commentAuthorAvatar"></el-avatar>
<span class="text-default" style="padding-left: 1rem;">{{ title }}</span>
</el-col>
</el-col>
<el-col>
<div id="contentEditor"></div>
</el-col>
<el-col style="margin-top: 1rem;padding-right:3rem;text-align: right;">
<el-button type="primary" :loading="loading" @click="postComment">发布</el-button>
</el-col>
</el-drawer>
</el-col>
</el-col>
<el-col v-else class="text-center" style="margin-top: 1rem;">
<el-button type="primary" size="medium" @click="gotoLogin">登录</el-button>
后发布评论
</el-col>
<el-col>
<!-- <Comment :comments="article.articleComments" :reply="reply"></Comment>-->
</el-col>
</el-col>
<el-col v-else>
<!-- <Component404></Component404>-->
</el-col>
</el-row>
</template> </template>
<script> <script>
import { mapState } from 'vuex'
export default { export default {
name: "ArticleDetail" name: "ArticleDetail",
validate({params, store}) {
return params.article_id && !isNaN(Number(params.article_id))
},
fetch({store, params, error}) {
return Promise.all([
store
.dispatch('article/fetchDetail', params)
.catch(err => error({statusCode: 404})),
// store.dispatch('comment/fetchList', {post_id: params.article_id})
])
},
computed: {
...mapState({
article: state => state.article.detail.data,
isFetching: state => state.article.detail.fetching,
isMobile: state => state.global.isMobile,
})
},
data() {
return {
isShow: true,
loading: false,
}
}
} }
</script> </script>
<style scoped> <style lang="scss">
.article__wrapper {
max-width: 980px;
margin: 0 auto;
display: block;
padding-left: 1rem;
padding-right: 1rem;
box-sizing: border-box;
}
</style> </style>

View File

@ -29,29 +29,5 @@
</script> </script>
<style> <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> </style>

View File

@ -41,7 +41,7 @@ export const mutations = {
state.detail.fetching = action state.detail.fetching = action
}, },
updateDetailData(state, action) { updateDetailData(state, action) {
state.detail.data = action state.detail.data = action.article
}, },
// 更新文章阅读全文状态 // 更新文章阅读全文状态
@ -78,12 +78,13 @@ export const actions = {
// 获取文章详情 // 获取文章详情
fetchDetail({ commit }, params = {}) { fetchDetail({ commit }, params = {}) {
const delay = fetchDelay( // const delay = fetchDelay(
isBrowser && isArticleDetailRoute(window.$nuxt.$route.name) ? null : 0 // isBrowser
) // )
console.log(params)
if (isBrowser) { if (isBrowser) {
Vue.nextTick(() => { Vue.nextTick(() => {
scrollTo(0, 300, { easing: Easing['ease-in'] }) window.scrollTo(0, 300);
}) })
} }
commit('updateDetailFetching', true) commit('updateDetailFetching', true)
@ -91,13 +92,13 @@ export const actions = {
return this.$axios return this.$axios
.$get(`${ARTICLE_API_PATH}/article/${params.article_id}`) .$get(`${ARTICLE_API_PATH}/article/${params.article_id}`)
.then(response => { .then(response => {
return new Promise(resolve => { commit('updateDetailData', response.data)
delay(() => {
commit('updateDetailData', response.result)
commit('updateDetailFetching', false) commit('updateDetailFetching', false)
resolve(response) // return new Promise(resolve => {
}) // delay(() => {
}) // resolve(response)
// })
// })
}) })
.catch(error => { .catch(error => {
commit('updateDetailFetching', false) commit('updateDetailFetching', false)