国外MOSE官网
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.

398 lines
10 KiB

6 days ago
  1. <template>
  2. <view class="activity-detail">
  3. <!-- 轮播图 -->
  4. <view class="banner-container">
  5. <swiper class="banner-swiper" height="450rpx" :indicator-dots="true" :autoplay="true" :interval="3000" :duration="500">
  6. <swiper-item v-for="(image, index) in bannerImages" :key="index">
  7. <image class="banner-image" :src="image" mode="aspectFill"></image>
  8. </swiper-item>
  9. </swiper>
  10. </view>
  11. <!-- 活动信息 -->
  12. <view class="activity-info">
  13. <!-- 活动标题和标签 -->
  14. <view class="title-section">
  15. <view class="activity-badge">
  16. <text class="badge-text">{{ activityData.duration }}</text>
  17. </view>
  18. <text class="activity-title">{{ activityData.title }}</text>
  19. </view>
  20. <!-- 活动详细信息 -->
  21. <view class="info-section">
  22. <view class="info-item">
  23. <uv-icon name="calendar" size="16" color="#666"></uv-icon>
  24. <text class="info-label">活动时间</text>
  25. <text class="info-value">{{ activityData.time }}</text>
  26. </view>
  27. <view class="info-item">
  28. <uv-icon name="clock" size="16" color="#666"></uv-icon>
  29. <text class="info-label">报名时间</text>
  30. <text class="info-value">{{ activityData.registrationTime }}</text>
  31. </view>
  32. <view class="info-item">
  33. <uv-icon name="account-fill" size="16" color="#666"></uv-icon>
  34. <text class="info-label">联系人</text>
  35. <text class="info-value">{{ activityData.contact }}</text>
  36. </view>
  37. <view class="info-item">
  38. <uv-icon name="phone" size="16" color="#666"></uv-icon>
  39. <text class="info-label">取消规则</text>
  40. <text class="info-value">{{ activityData.cancelRule }}</text>
  41. </view>
  42. <view class="info-item">
  43. <uv-icon name="map-fill" size="16" color="#666"></uv-icon>
  44. <text class="info-label">活动地点</text>
  45. <text class="info-value">{{ activityData.location }}</text>
  46. </view>
  47. </view>
  48. <!-- 活动详情 -->
  49. <view class="detail-section">
  50. <view class="section-title">
  51. <text class="title-text">活动详情</text>
  52. </view>
  53. <view class="detail-content">
  54. <text class="detail-text" v-for="(item, index) in activityData.details" :key="index">
  55. {{ index + 1 }}. {{ item }}
  56. </text>
  57. </view>
  58. </view>
  59. <!-- 活动图集 -->
  60. <view class="gallery-section">
  61. <view class="section-title">
  62. <text class="title-text">活动图集</text>
  63. </view>
  64. <view class="gallery-grid">
  65. <image
  66. v-for="(image, index) in activityData.gallery"
  67. :key="index"
  68. class="gallery-image"
  69. :src="image"
  70. mode="aspectFill"
  71. @click="previewImage(image, activityData.gallery)"
  72. ></image>
  73. <!-- <uv-album :urls="activityData.gallery"></uv-album> -->
  74. </view>
  75. </view>
  76. </view>
  77. <!-- 固定底部操作栏 -->
  78. <view class="bottom-action">
  79. <view class="action-left">
  80. <view class="action-item" @click="shareActivity">
  81. <uv-icon name="share" size="24" color="#000"></uv-icon>
  82. <text class="action-text">分享</text>
  83. </view>
  84. <view class="action-item" @click="collectActivity">
  85. <uv-icon name="heart-fill" size="24" :color="isCollected ? '#ff4757' : '#999'"></uv-icon>
  86. <text class="action-text">收藏</text>
  87. </view>
  88. <view class="action-item">
  89. <text class="participants-count">
  90. <text :style="{'color': activityData.registeredCount >= activityData.maxCount ? '#999' : '#1488DB'}">{{ activityData.registeredCount }}</text>
  91. /{{ activityData.maxCount }}</text>
  92. <text class="action-text">已报名</text>
  93. </view>
  94. </view>
  95. <view class="action-right">
  96. <uv-button
  97. type="primary"
  98. size="normal"
  99. text="我要报名"
  100. shape="circle"
  101. @click="signUpActivity"
  102. :disabled="activityData.registeredCount >= activityData.maxCount"
  103. ></uv-button>
  104. </view>
  105. </view>
  106. <SignUpForm
  107. ref="signUpFormRef"
  108. @close="onSignUpFormClose"
  109. @submit="onSignUpFormSubmit"
  110. />
  111. </view>
  112. <!-- 报名表单弹窗 -->
  113. </template>
  114. <script>
  115. import SignUpForm from '@/subPages/index/components/SignUpForm.vue'
  116. export default {
  117. components: {
  118. SignUpForm
  119. },
  120. data() {
  121. return {
  122. isCollected: false,
  123. showSignUpForm: false,
  124. bannerImages: [
  125. '/static/bannerImage.png',
  126. '/static/bannerImage.png',
  127. '/static/bannerImage.png'
  128. ],
  129. activityData: {
  130. title: '关爱自闭症儿童活动',
  131. duration: '30积分',
  132. time: '2025-06-12 14:30',
  133. registrationTime: '2025-06-01 14:30——2025-09-01 14:30',
  134. contact: '柳老师 (13256484512)',
  135. cancelRule: '报名随时可取消',
  136. location: '长沙市雨花区时代阳光大夏国际大厅2145',
  137. registeredCount: 9,
  138. maxCount: 30,
  139. details: [
  140. '身体健康,热爱志愿服务工作,富有责任感和奉献精神',
  141. '遵纪守法,思想上进,作风正派,服从安排',
  142. '年龄在60岁以下,具备广告宣传理能力'
  143. ],
  144. gallery: [
  145. '/static/bannerImage.png',
  146. '/static/bannerImage.png',
  147. '/static/bannerImage.png',
  148. '/static/bannerImage.png'
  149. ]
  150. }
  151. }
  152. },
  153. onLoad(options) {
  154. if (options.id) {
  155. this.loadActivityDetail(options.id)
  156. }
  157. },
  158. methods: {
  159. loadActivityDetail(id) {
  160. // 根据ID加载活动详情
  161. console.log('加载活动详情:', id)
  162. },
  163. previewImage(current, urls) {
  164. uni.previewImage({
  165. current: current,
  166. urls: urls
  167. })
  168. },
  169. shareActivity() {
  170. uni.showToast({
  171. title: '分享功能',
  172. icon: 'none'
  173. })
  174. },
  175. collectActivity() {
  176. this.isCollected = !this.isCollected
  177. uni.showToast({
  178. title: this.isCollected ? '收藏成功' : '取消收藏',
  179. icon: 'none'
  180. })
  181. },
  182. signUpActivity() {
  183. if (this.activityData.registeredCount >= this.activityData.maxCount) {
  184. uni.showToast({
  185. title: '报名人数已满',
  186. icon: 'none'
  187. })
  188. return
  189. }
  190. this.$refs.signUpFormRef.open()
  191. },
  192. onSignUpFormClose() {
  193. this.$refs.signUpFormRef.close()
  194. },
  195. onSignUpFormSubmit(formData) {
  196. console.log('报名表单数据:', formData)
  197. // 这里可以调用API提交报名数据
  198. this.showSignUpForm = false
  199. }
  200. }
  201. }
  202. </script>
  203. <style lang="scss" scoped>
  204. .activity-detail {
  205. min-height: 100vh;
  206. background: #f8f8f8;
  207. padding-bottom: 120rpx;
  208. .banner-container {
  209. width: 100%;
  210. height: 450rpx;
  211. .banner-swiper {
  212. width: 100%;
  213. height: 100%;
  214. .banner-image {
  215. width: 100%;
  216. height: 100%;
  217. }
  218. }
  219. }
  220. .activity-info {
  221. background: #ffffff;
  222. // border: 1rpx dashed #F3F7F8;
  223. margin: 20rpx;
  224. border-radius: 16rpx;
  225. padding: 30rpx;
  226. .title-section {
  227. display: flex;
  228. align-items: center;
  229. margin-bottom: 30rpx;
  230. .activity-badge {
  231. background: #218CDD;
  232. border-radius: 8rpx;
  233. padding: 4rpx 10rpx;
  234. margin-right: 16rpx;
  235. .badge-text {
  236. color: #ffffff;
  237. font-size: 24rpx;
  238. font-weight: 500;
  239. }
  240. }
  241. .activity-title {
  242. font-size: 36rpx;
  243. font-weight: bold;
  244. color: #333333;
  245. flex: 1;
  246. }
  247. }
  248. .info-section {
  249. background: #F3F7F8;
  250. margin-bottom: 40rpx;
  251. // 虚线属性
  252. border: 2rpx dashed #F3F7F8;
  253. .info-item {
  254. display: flex;
  255. align-items: center;
  256. margin-bottom: 20rpx;
  257. &:last-child {
  258. margin-bottom: 0;
  259. }
  260. .info-label {
  261. font-size: 28rpx;
  262. color: #999999;
  263. margin-left: 12rpx;
  264. margin-right: 8rpx;
  265. }
  266. .info-value {
  267. font-size: 28rpx;
  268. color: #999999;
  269. flex: 1;
  270. }
  271. }
  272. }
  273. .detail-section {
  274. margin-bottom: 40rpx;
  275. .section-title {
  276. margin-bottom: 20rpx;
  277. .title-text {
  278. font-size: 32rpx;
  279. font-weight: bold;
  280. color: #333333;
  281. }
  282. }
  283. .detail-content {
  284. .detail-text {
  285. display: block;
  286. font-size: 28rpx;
  287. color: #666666;
  288. line-height: 1.6;
  289. margin-bottom: 16rpx;
  290. &:last-child {
  291. margin-bottom: 0;
  292. }
  293. }
  294. }
  295. }
  296. .gallery-section {
  297. .section-title {
  298. margin-bottom: 20rpx;
  299. .title-text {
  300. font-size: 32rpx;
  301. font-weight: bold;
  302. color: #333333;
  303. }
  304. }
  305. .gallery-grid {
  306. display: grid;
  307. grid-template-columns: repeat(2, 1fr);
  308. gap: 16rpx;
  309. .gallery-image {
  310. width: 100%;
  311. height: 200rpx;
  312. border-radius: 12rpx;
  313. }
  314. }
  315. }
  316. }
  317. .bottom-action {
  318. position: fixed;
  319. bottom: 0;
  320. left: 0;
  321. right: 0;
  322. background: #ffffff;
  323. padding: 20rpx 30rpx;
  324. border-top: 1rpx solid #eeeeee;
  325. display: flex;
  326. align-items: center;
  327. justify-content: space-between;
  328. z-index: 100;
  329. .action-left {
  330. display: flex;
  331. align-items: center;
  332. gap: 100rpx;
  333. .action-item {
  334. display: flex;
  335. flex-direction: column;
  336. align-items: center;
  337. gap: 8rpx;
  338. .action-text {
  339. font-size: 22rpx;
  340. color: #000;
  341. }
  342. .participants-count {
  343. font-size: 24rpx;
  344. color: #333333;
  345. // font-weight: bold;
  346. }
  347. }
  348. }
  349. .action-right {
  350. flex-shrink: 0;
  351. }
  352. }
  353. }
  354. </style>