|
|
@ -0,0 +1,224 @@ |
|
|
|
|
|
<template> |
|
|
|
|
|
<view class="page"> |
|
|
|
|
|
<navbar title="文章详情" /> |
|
|
|
|
|
|
|
|
|
|
|
<view class="content"> |
|
|
|
|
|
<!-- 加载状态 --> |
|
|
|
|
|
<view class="loading-container" v-if="loading"> |
|
|
|
|
|
<text class="loading-text">加载中...</text> |
|
|
|
|
|
</view> |
|
|
|
|
|
|
|
|
|
|
|
<!-- 文章详情 --> |
|
|
|
|
|
<view class="article-detail" v-if="!loading && articleDetail"> |
|
|
|
|
|
<!-- 创建时间 --> |
|
|
|
|
|
<view class="article-meta"> |
|
|
|
|
|
<text class="create-time">{{ formatTime(articleDetail.createTime) }}</text> |
|
|
|
|
|
</view> |
|
|
|
|
|
|
|
|
|
|
|
<!-- 富文本内容 --> |
|
|
|
|
|
<view class="article-content"> |
|
|
|
|
|
<rich-text :nodes="articleDetail.content"></rich-text> |
|
|
|
|
|
</view> |
|
|
|
|
|
</view> |
|
|
|
|
|
|
|
|
|
|
|
<!-- 错误状态 --> |
|
|
|
|
|
<view class="error-container" v-if="!loading && !articleDetail"> |
|
|
|
|
|
<text class="error-text">文章不存在或已被删除</text> |
|
|
|
|
|
</view> |
|
|
|
|
|
</view> |
|
|
|
|
|
</view> |
|
|
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
|
|
<script> |
|
|
|
|
|
|
|
|
|
|
|
export default { |
|
|
|
|
|
data() { |
|
|
|
|
|
return { |
|
|
|
|
|
articleId: '', |
|
|
|
|
|
articleDetail: null, |
|
|
|
|
|
loading: false |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
onLoad(options) { |
|
|
|
|
|
if (options.id) { |
|
|
|
|
|
this.articleId = options.id; |
|
|
|
|
|
this.loadArticleDetail(); |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
onShareAppMessage(res) { |
|
|
|
|
|
return { |
|
|
|
|
|
title: this.articleDetail ? this.articleDetail.title || '文章详情' : '文章详情', |
|
|
|
|
|
imageUrl: this.articleDetail ? this.articleDetail.image : '', |
|
|
|
|
|
path: '/pages_order/article/index?id=' + this.articleId |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
methods: { |
|
|
|
|
|
// 加载文章详情 |
|
|
|
|
|
loadArticleDetail() { |
|
|
|
|
|
if (!this.articleId) return; |
|
|
|
|
|
|
|
|
|
|
|
this.loading = true; |
|
|
|
|
|
|
|
|
|
|
|
const params = { |
|
|
|
|
|
id: this.articleId |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
this.$api('articleDetail', params, (res) => { |
|
|
|
|
|
this.loading = false; |
|
|
|
|
|
|
|
|
|
|
|
if (res.code === 200 && res.result) { |
|
|
|
|
|
this.articleDetail = res.result; |
|
|
|
|
|
} else { |
|
|
|
|
|
uni.showToast({ |
|
|
|
|
|
title: res.message || '加载失败', |
|
|
|
|
|
icon: 'none' |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
// 格式化时间 |
|
|
|
|
|
formatTime(time) { |
|
|
|
|
|
if (!time) return ''; |
|
|
|
|
|
|
|
|
|
|
|
const date = new Date(time); |
|
|
|
|
|
const year = date.getFullYear(); |
|
|
|
|
|
const month = String(date.getMonth() + 1).padStart(2, '0'); |
|
|
|
|
|
const day = String(date.getDate()).padStart(2, '0'); |
|
|
|
|
|
const hours = String(date.getHours()).padStart(2, '0'); |
|
|
|
|
|
const minutes = String(date.getMinutes()).padStart(2, '0'); |
|
|
|
|
|
|
|
|
|
|
|
return `${year}-${month}-${day} ${hours}:${minutes}`; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
</script> |
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss"> |
|
|
|
|
|
.page { |
|
|
|
|
|
background-color: #f5f5f5; |
|
|
|
|
|
min-height: 100vh; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.content { |
|
|
|
|
|
padding: 20rpx; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.loading-container { |
|
|
|
|
|
display: flex; |
|
|
|
|
|
justify-content: center; |
|
|
|
|
|
align-items: center; |
|
|
|
|
|
padding: 200rpx 0; |
|
|
|
|
|
|
|
|
|
|
|
.loading-text { |
|
|
|
|
|
font-size: 28rpx; |
|
|
|
|
|
color: #999; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.error-container { |
|
|
|
|
|
display: flex; |
|
|
|
|
|
justify-content: center; |
|
|
|
|
|
align-items: center; |
|
|
|
|
|
padding: 200rpx 0; |
|
|
|
|
|
|
|
|
|
|
|
.error-text { |
|
|
|
|
|
font-size: 28rpx; |
|
|
|
|
|
color: #999; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.article-detail { |
|
|
|
|
|
background-color: #fff; |
|
|
|
|
|
border-radius: 16rpx; |
|
|
|
|
|
padding: 30rpx; |
|
|
|
|
|
margin-bottom: 20rpx; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.article-meta { |
|
|
|
|
|
padding-bottom: 20rpx; |
|
|
|
|
|
border-bottom: 1px solid #f0f0f0; |
|
|
|
|
|
margin-bottom: 30rpx; |
|
|
|
|
|
|
|
|
|
|
|
.create-time { |
|
|
|
|
|
font-size: 24rpx; |
|
|
|
|
|
color: #999; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.article-content { |
|
|
|
|
|
line-height: 1.6; |
|
|
|
|
|
|
|
|
|
|
|
// 富文本内容样式 |
|
|
|
|
|
:deep(rich-text) { |
|
|
|
|
|
font-size: 30rpx; |
|
|
|
|
|
color: #333; |
|
|
|
|
|
|
|
|
|
|
|
// 图片样式 |
|
|
|
|
|
img { |
|
|
|
|
|
max-width: 100%; |
|
|
|
|
|
height: auto; |
|
|
|
|
|
border-radius: 8rpx; |
|
|
|
|
|
margin: 20rpx 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 段落样式 |
|
|
|
|
|
p { |
|
|
|
|
|
margin: 20rpx 0; |
|
|
|
|
|
line-height: 1.8; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 标题样式 |
|
|
|
|
|
h1, h2, h3, h4, h5, h6 { |
|
|
|
|
|
margin: 30rpx 0 20rpx 0; |
|
|
|
|
|
font-weight: bold; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
h1 { font-size: 36rpx; } |
|
|
|
|
|
h2 { font-size: 34rpx; } |
|
|
|
|
|
h3 { font-size: 32rpx; } |
|
|
|
|
|
|
|
|
|
|
|
// 列表样式 |
|
|
|
|
|
ul, ol { |
|
|
|
|
|
padding-left: 40rpx; |
|
|
|
|
|
margin: 20rpx 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
li { |
|
|
|
|
|
margin: 10rpx 0; |
|
|
|
|
|
line-height: 1.6; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 引用样式 |
|
|
|
|
|
blockquote { |
|
|
|
|
|
border-left: 4rpx solid #ddd; |
|
|
|
|
|
padding-left: 20rpx; |
|
|
|
|
|
margin: 20rpx 0; |
|
|
|
|
|
color: #666; |
|
|
|
|
|
font-style: italic; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 代码样式 |
|
|
|
|
|
code { |
|
|
|
|
|
background-color: #f5f5f5; |
|
|
|
|
|
padding: 4rpx 8rpx; |
|
|
|
|
|
border-radius: 4rpx; |
|
|
|
|
|
font-family: monospace; |
|
|
|
|
|
font-size: 26rpx; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pre { |
|
|
|
|
|
background-color: #f5f5f5; |
|
|
|
|
|
padding: 20rpx; |
|
|
|
|
|
border-radius: 8rpx; |
|
|
|
|
|
overflow-x: auto; |
|
|
|
|
|
margin: 20rpx 0; |
|
|
|
|
|
|
|
|
|
|
|
code { |
|
|
|
|
|
background: none; |
|
|
|
|
|
padding: 0; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
</style> |