瑶都万能墙
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

248 lines
4.9 KiB

  1. <template>
  2. <view class="page">
  3. <navbar title="文章详情" />
  4. <view class="content">
  5. <!-- 加载状态 -->
  6. <view class="loading-container" v-if="loading">
  7. <text class="loading-text">加载中...</text>
  8. </view>
  9. <!-- 文章详情 -->
  10. <view class="article-detail" v-if="!loading && articleDetail">
  11. <!-- 创建时间 -->
  12. <view class="article-meta">
  13. <text class="create-time">{{ formatTime(articleDetail.createTime) }}</text>
  14. </view>
  15. <!-- 富文本内容 -->
  16. <view class="article-content">
  17. <uv-parse
  18. :content="articleDetail.content"
  19. :preview-img="true"
  20. :scroll-table="true"
  21. :tag-style="parseTagStyle"
  22. />
  23. </view>
  24. </view>
  25. <!-- 错误状态 -->
  26. <view class="error-container" v-if="!loading && !articleDetail">
  27. <text class="error-text">文章不存在或已被删除</text>
  28. </view>
  29. </view>
  30. <commentList @getData="getData" :list="list" :params="params" />
  31. </view>
  32. </template>
  33. <script>
  34. import mixinsList from '@/mixins/list.js'
  35. import commentList from '../components/list/comment/commentList.vue'
  36. export default {
  37. components: {
  38. commentList,
  39. },
  40. mixins: [mixinsList],
  41. data() {
  42. return {
  43. mixinsListApi : 'getCommentPage',
  44. articleId: '',
  45. articleDetail: null,
  46. loading: false,
  47. params : {
  48. type : '8',
  49. orderId : '',
  50. name : '',
  51. }
  52. ,
  53. // uv-parse 标签默认样式,确保图片不超过容器宽度
  54. parseTagStyle: {
  55. img: 'max-width:100%;height:auto;display:block;',
  56. video: 'max-width:100%;height:auto;display:block;',
  57. table: 'width:100%;display:block;'
  58. }
  59. }
  60. },
  61. onLoad(options) {
  62. if (options.id) {
  63. this.articleId = options.id;
  64. this.loadArticleDetail();
  65. this.queryParams.type = this.params.type
  66. this.queryParams.orderId = options.id
  67. this.params.orderId = options.id
  68. }
  69. },
  70. onShareAppMessage(res) {
  71. return {
  72. title: this.articleDetail ? this.articleDetail.title || '文章详情' : '文章详情',
  73. imageUrl: this.articleDetail ? this.articleDetail.image : '',
  74. path: '/pages_order/article/index?id=' + this.articleId
  75. }
  76. },
  77. methods: {
  78. // 加载文章详情
  79. loadArticleDetail() {
  80. if (!this.articleId) return;
  81. this.loading = true;
  82. const params = {
  83. id: this.articleId
  84. };
  85. this.$api('articleDetail', params, (res) => {
  86. this.loading = false;
  87. if (res.code === 200 && res.result) {
  88. this.params.name = res.result.title
  89. this.articleDetail = res.result;
  90. } else {
  91. uni.showToast({
  92. title: res.message || '加载失败',
  93. icon: 'none'
  94. });
  95. }
  96. });
  97. },
  98. // 格式化时间
  99. formatTime(time) {
  100. if (!time) return '';
  101. const date = new Date(time);
  102. const year = date.getFullYear();
  103. const month = String(date.getMonth() + 1).padStart(2, '0');
  104. const day = String(date.getDate()).padStart(2, '0');
  105. const hours = String(date.getHours()).padStart(2, '0');
  106. const minutes = String(date.getMinutes()).padStart(2, '0');
  107. return `${year}-${month}-${day} ${hours}:${minutes}`;
  108. }
  109. }
  110. }
  111. </script>
  112. <style scoped lang="scss">
  113. .page {
  114. background-color: #f5f5f5;
  115. min-height: 100vh;
  116. }
  117. .content {
  118. padding: 20rpx;
  119. }
  120. .loading-container {
  121. display: flex;
  122. justify-content: center;
  123. align-items: center;
  124. padding: 200rpx 0;
  125. .loading-text {
  126. font-size: 28rpx;
  127. color: #999;
  128. }
  129. }
  130. .error-container {
  131. display: flex;
  132. justify-content: center;
  133. align-items: center;
  134. padding: 200rpx 0;
  135. .error-text {
  136. font-size: 28rpx;
  137. color: #999;
  138. }
  139. }
  140. .article-detail {
  141. background-color: #fff;
  142. border-radius: 16rpx;
  143. padding: 30rpx;
  144. margin-bottom: 20rpx;
  145. }
  146. .article-meta {
  147. padding-bottom: 20rpx;
  148. border-bottom: 1px solid #f0f0f0;
  149. margin-bottom: 30rpx;
  150. .create-time {
  151. font-size: 24rpx;
  152. color: #999;
  153. }
  154. }
  155. .article-content {
  156. line-height: 1.6;
  157. // 富文本内容样式
  158. :deep(.uv-parse) {
  159. font-size: 30rpx;
  160. color: #333;
  161. // 图片样式由 uv-parse 的 tag-style 控制
  162. // 段落样式
  163. p {
  164. margin: 20rpx 0;
  165. line-height: 1.8;
  166. }
  167. // 标题样式
  168. h1, h2, h3, h4, h5, h6 {
  169. margin: 30rpx 0 20rpx 0;
  170. font-weight: bold;
  171. }
  172. h1 { font-size: 36rpx; }
  173. h2 { font-size: 34rpx; }
  174. h3 { font-size: 32rpx; }
  175. // 列表样式
  176. ul, ol {
  177. padding-left: 40rpx;
  178. margin: 20rpx 0;
  179. }
  180. li {
  181. margin: 10rpx 0;
  182. line-height: 1.6;
  183. }
  184. // 引用样式
  185. blockquote {
  186. border-left: 4rpx solid #ddd;
  187. padding-left: 20rpx;
  188. margin: 20rpx 0;
  189. color: #666;
  190. font-style: italic;
  191. }
  192. // 代码样式
  193. code {
  194. background-color: #f5f5f5;
  195. padding: 4rpx 8rpx;
  196. border-radius: 4rpx;
  197. font-family: monospace;
  198. font-size: 26rpx;
  199. }
  200. pre {
  201. background-color: #f5f5f5;
  202. padding: 20rpx;
  203. border-radius: 8rpx;
  204. overflow-x: auto;
  205. margin: 20rpx 0;
  206. code {
  207. background: none;
  208. padding: 0;
  209. }
  210. }
  211. }
  212. }
  213. </style>