图书馆小程序
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.

212 lines
4.9 KiB

2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
  1. <template>
  2. <view class="activity-detail">
  3. <image class="activity-img" :src="detail.imgUrl" mode="aspectFill"></image>
  4. <view class="activity-base">
  5. <text class="title">{{ detail.title }}</text>
  6. <view class="time">
  7. <uni-icons class="detail-icon" custom-prefix="iconfont" type="icon-shijian" size="15"></uni-icons>
  8. <text>{{ detail.time }}</text>
  9. </view>
  10. <view class="location">
  11. <uni-icons class="detail-icon" type="location" size="20"></uni-icons>
  12. <text>{{ detail.location }}</text>
  13. </view>
  14. </view>
  15. <view class="rich-content">
  16. <text class="content-title">活动介绍/回顾</text>
  17. <rich-text :nodes="contentNodes"></rich-text>
  18. </view>
  19. <view class="detail-bottom">
  20. <view class="detail-left">
  21. <button open-type="share" class="handle-btn">
  22. <uni-icons custom-prefix="iconfont" type="icon-fenxiang01" size="20"></uni-icons>
  23. <text>分享</text>
  24. </button>
  25. <button class="handle-btn" @click="toggleCollect">
  26. <uni-icons :type="isCollected ? 'heart-filled' : 'heart'" size="20" color="#ff4444"></uni-icons>
  27. <text>{{ isCollected ? '已收藏' : '收藏' }}</text>
  28. </button>
  29. </view>
  30. <button class="join-btn" :class="detail.status === 0 ? 'disabled-btn' : ''">
  31. {{ detail.status === 1 ? '我要参加' : '活动结束' }}
  32. </button>
  33. </view>
  34. </view>
  35. </template>
  36. <script>
  37. export default {
  38. data() {
  39. return {
  40. detail: {},
  41. isCollected: false,
  42. activityId: "",
  43. contentNodes: ""
  44. };
  45. },
  46. onLoad(options) {
  47. const item = JSON.parse(decodeURIComponent(options.item));
  48. this.detail = item;
  49. this.activityId = item.title;
  50. this.formatContent();
  51. this.checkCollectStatus();
  52. },
  53. methods: {
  54. formatContent() {
  55. let content = this.detail.content || "";
  56. // ======================================
  57. // 1. 把 content 里的 <image src="@/static/..."> 转成 <img> 标签
  58. // ======================================
  59. const localImgReg = /<image\s+src="@\/static\/([^"]+)"[^>]*>/gi;
  60. content = content.replace(localImgReg, (match, path) => {
  61. return `
  62. <div style="text-align:center; margin:12px 0;">
  63. <img src="/static/${path}" style="width:90%; border-radius:8px;">
  64. </div>
  65. `;
  66. });
  67. // ======================================
  68. // 2. 把 https://mmbiz.qpic.cn 图片链接转成图片
  69. // ======================================
  70. const httpImgReg = /https:\/\/mmbiz\.qpic\.cn[^ \n\r]+/g;
  71. content = content.replace(httpImgReg, url => {
  72. return `
  73. <div style="text-align:center; margin:12px 0;">
  74. <img src="${url}" style="width:90%; border-radius:8px;">
  75. </div>
  76. `;
  77. });
  78. this.contentNodes = content;
  79. },
  80. checkCollectStatus() {
  81. const list = uni.getStorageSync('activityCollectList') || [];
  82. this.isCollected = list.includes(this.activityId);
  83. },
  84. toggleCollect() {
  85. let list = uni.getStorageSync('activityCollectList') || [];
  86. if (this.isCollected) {
  87. list = list.filter(i => i !== this.activityId);
  88. uni.showToast({ title: "取消收藏" });
  89. } else {
  90. list.push(this.activityId);
  91. uni.showToast({ title: "收藏成功", icon: "success" });
  92. }
  93. uni.setStorageSync('activityCollectList', list);
  94. this.isCollected = !this.isCollected;
  95. }
  96. },
  97. onShareAppMessage() {
  98. return {
  99. title: this.detail.title,
  100. path: "/subpkg/pages/activity-detail/activity-detail?item=" + encodeURIComponent(JSON.stringify(this.detail)),
  101. imageUrl: this.detail.imgUrl
  102. };
  103. }
  104. };
  105. </script>
  106. <style lang="scss" scoped>
  107. .activity-detail {
  108. padding-bottom: 60px;
  109. background: #f5f5f5;
  110. }
  111. .activity-img {
  112. width: 100%;
  113. height: 180px;
  114. }
  115. .activity-base {
  116. background: #fff;
  117. padding: 15px;
  118. margin-bottom: 10px;
  119. .title {
  120. font-size: 16px;
  121. font-weight: bold;
  122. padding-bottom: 10px;
  123. }
  124. .time,
  125. .location {
  126. display: flex;
  127. align-items: center;
  128. font-size: 12px;
  129. color: #999;
  130. padding-top: 10px;
  131. .detail-icon {
  132. padding-right: 4px;
  133. }
  134. }
  135. .time{
  136. padding-left: 3px;
  137. }
  138. }
  139. .rich-content {
  140. background: #fff;
  141. padding: 10px 0;
  142. .content-title{
  143. position: relative;
  144. font-size: 16px;
  145. font-weight: bold;
  146. color: #333;
  147. padding-left: 12px;
  148. &::before{
  149. position: absolute;
  150. left: 0;
  151. top: 50%;
  152. margin-top: -9px;
  153. content: "";
  154. width: 4px;
  155. height: 18px;
  156. background-color: #01a4fe;
  157. }
  158. }
  159. }
  160. .detail-bottom {
  161. position: fixed;
  162. bottom: 0;
  163. left: 0;
  164. right: 0;
  165. height: 50px;
  166. background: #fff;
  167. display: flex;
  168. align-items: center;
  169. justify-content: space-between;
  170. padding: 0 15px;
  171. box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.05);
  172. }
  173. .detail-left {
  174. display: flex;
  175. gap: 10px;
  176. }
  177. .handle-btn {
  178. display: flex;
  179. align-items: center;
  180. gap: 4px;
  181. background: #f5f5f5;
  182. border-radius: 30px;
  183. padding: 0 12px;
  184. height: 36px;
  185. font-size: 14px;
  186. }
  187. .join-btn {
  188. background: #01a4fe;
  189. color: #fff;
  190. border-radius: 30px;
  191. padding: 0 20px;
  192. height: 36px;
  193. }
  194. .disabled-btn {
  195. background: #ccc !important;
  196. }
  197. </style>