noticeDetail.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <template>
  2. <home-container :customStyle="{ background: 'none' }" :customHomeStyle="{ overflow: 'hidden' }">
  3. <view class="detail-container" v-if="detailData">
  4. <!-- 公告标题 -->
  5. <view class="title">{{ detailData.noticeTitle }}</view>
  6. <!-- 发布信息 -->
  7. <view class="meta-info">
  8. <text class="author">{{ detailData.createUser || '管理员' }}</text>
  9. <text class="date">{{ formatDate(detailData.createTime) }}</text>
  10. </view>
  11. <!-- 分隔线 -->
  12. <view class="divider"></view>
  13. <!-- 富文本内容 -->
  14. <view class="content" v-html="detailData.noticeContent"></view>
  15. </view>
  16. <!-- 加载状态 -->
  17. <view v-else class="loading">加载中...</view>
  18. </home-container>
  19. </template>
  20. <script>
  21. import HomeContainer from "@/components/HomeContainer.vue";
  22. import { getNoticeDetail } from "@/api/announcement/announcement.js";
  23. export default {
  24. components: {
  25. HomeContainer
  26. },
  27. data() {
  28. return {
  29. detailData: null,
  30. loading: true
  31. };
  32. },
  33. onLoad(options) {
  34. // 从路由参数中获取公告ID
  35. if (options && options.id) {
  36. this.getDetailData(options.id);
  37. } else {
  38. console.error('公告ID不存在');
  39. uni.showToast({
  40. title: '获取公告详情失败',
  41. icon: 'none'
  42. });
  43. }
  44. },
  45. methods: {
  46. // 格式化日期
  47. formatDate(timeString) {
  48. if (!timeString) return '';
  49. const date = new Date(timeString);
  50. const year = date.getFullYear();
  51. const month = String(date.getMonth() + 1).padStart(2, '0');
  52. const day = String(date.getDate()).padStart(2, '0');
  53. const hour = String(date.getHours()).padStart(2, '0');
  54. const minute = String(date.getMinutes()).padStart(2, '0');
  55. return `${year}-${month}-${day} ${hour}:${minute}`;
  56. },
  57. // 处理富文本中的图片
  58. handleRichTextImages(html) {
  59. if (!html) return '';
  60. // 为所有img标签添加style="width:90%",同时保留原有的style属性
  61. return html.replace(/<img([^>]+)>/g, (match, attributes) => {
  62. // 检查是否已有style属性
  63. if (attributes.includes('style=')) {
  64. // 如果已有style属性,在其末尾添加width设置
  65. return `<img${attributes.replace(/style=["']([^"']*)["']/, (styleMatch, styleValue) => {
  66. return `style="${styleValue} width:90%;"`;
  67. })}>`;
  68. } else {
  69. // 如果没有style属性,添加一个包含width设置的style属性
  70. return `<img${attributes} style="width:90%;">`;
  71. }
  72. });
  73. },
  74. // 获取公告详情数据
  75. async getDetailData(id) {
  76. try {
  77. this.loading = true;
  78. const response = await getNoticeDetail(id);
  79. // 深拷贝响应数据
  80. this.detailData = JSON.parse(JSON.stringify(response.data));
  81. // 处理noticeContent中的图片样式
  82. if (this.detailData.noticeContent) {
  83. this.detailData.noticeContent = this.handleRichTextImages(this.detailData.noticeContent);
  84. }
  85. } catch (error) {
  86. console.error('获取公告详情失败:', error);
  87. uni.showToast({
  88. title: '获取公告详情失败',
  89. icon: 'none'
  90. });
  91. } finally {
  92. this.loading = false;
  93. }
  94. }
  95. }
  96. };
  97. </script>
  98. <style lang="scss" scoped>
  99. .detail-container {
  100. padding: 32rpx;
  101. background-color: #ffffff;
  102. min-height: calc(100vh - 177rpx);
  103. box-sizing: border-box;
  104. // 标题样式
  105. .title {
  106. font-size: 36rpx;
  107. font-weight: bold;
  108. color: #333333;
  109. line-height: 52rpx;
  110. margin-bottom: 24rpx;
  111. }
  112. // 元信息样式
  113. .meta-info {
  114. display: flex;
  115. justify-content: space-between;
  116. align-items: center;
  117. margin-bottom: 24rpx;
  118. .author,
  119. .date {
  120. font-size: 28rpx;
  121. color: #666666;
  122. }
  123. }
  124. // 分隔线样式
  125. .divider {
  126. height: 1rpx;
  127. background-color: #e5e5e5;
  128. margin: 32rpx 0;
  129. }
  130. // 富文本内容样式
  131. .content {
  132. font-size: 28rpx;
  133. color: #333333;
  134. line-height: 48rpx;
  135. // 富文本内部样式
  136. :deep() {
  137. p {
  138. margin-bottom: 20rpx;
  139. }
  140. img {
  141. max-width: 100%;
  142. height: auto;
  143. margin: 16rpx 0;
  144. }
  145. a {
  146. color: #007aff;
  147. text-decoration: underline;
  148. }
  149. }
  150. }
  151. }
  152. // 加载状态样式
  153. .loading {
  154. display: flex;
  155. justify-content: center;
  156. align-items: center;
  157. height: 400rpx;
  158. font-size: 28rpx;
  159. color: #999999;
  160. }
  161. </style>