绿满眶商城微信小程序-uniapp
xiangpei
2025-06-09 78685131317e9a08a05895c899ebea9970be52c8
pages/mine/activity/detail.vue
New file
@@ -0,0 +1,318 @@
<template>
   <view class="container">
      <!-- 顶部海报图 -->
      <!-- 动态封面区域 -->
      <view class="cover-container">
        <!-- 图片类型 -->
        <block v-if="activityInfo.coverType === '图片'">
          <image :src="getUrl(activityInfo.cover)"  class="activity-cover" />
        </block>
        <block v-if=" activityInfo.coverType === '视频'">
           <video :src="getUrl(item.cover)"
               @play="handleVideoPlay"  class="activity-cover"></video>
        </block>
        <!-- 文字类型 -->
        <block v-if="activityInfo.coverType === '文字'">
          <view class="text-cover">
            <text class="cover-text">{{ activityInfo.cover }}</text>
          </view>
        </block>
      </view>
      <!-- 活动基本信息 -->
      <view class="info-section">
         <text class="title">{{ activityInfo.activityName }}</text>
         <view class="meta-info">
            <view>
               <text class="time">
                  开始时间:{{ activityInfo.startTime }}
               </text>
            </view>
            <view>
               <text class="time">
                  结束时间:{{ activityInfo.endTime }}
               </text>
            </view>
            <view>
               <text class="location">地点:{{ activityInfo.activityLocation || '暂无' }}</text>
            </view>
            <view>
               <text class="location">最大人数:{{ activityInfo.limitUserNum || '暂无' }}</text>
            </view>
            <view>
               <text class="location">活动类型:{{ activityInfo.activityType || '暂无' }}</text>
            </view>
         </view>
         <view class="tags">
            <text v-for="(tag, index) in activityInfo.tags" :key="index" class="tag">{{ tag }}</text>
         </view>
      </view>
      <!-- 活动详情内容 -->
      <view class="content-section">
         <rich-text :nodes="activityInfo.activityContent"></rich-text>
      </view>
      <!-- 报名状态 -->
      <view class="status-bar" :style="{ backgroundColor: statusBarColor }">
         <u-button class="signup-btn" @click.stop="activityReport()" :disabled="reportBtn" >{{ reportBtn ? '已报名': '立即报名'}}</u-button>
         <u-button class="signup-btn" @click.stop="collect()">{{ isCollect ? '取消收藏' : '收藏' }}</u-button>
      </view>
   </view>
</template>
<script>
   import UButton from '@/uview-components/uview-ui/components/u-button/u-button.vue';
   import {changeCollect} from '@/api/collect.js'
   import {getFilePreviewUrl} from '@/api/common.js'
   import {
      getActivityDetail,
      activityReport
   } from '@/api/activity.js';
   export default {
      components: {
         UButton
      },
      data() {
         return {
            activityInfo: {
               coverType: '',
               cover: '',
               activityName: '',
               startTime: '', // 时间戳
               endTime: '',
               activityLocation: '',
               tags: [],
               activityContent: '',
               activityType: '',
               limitUserNum:'',
            },
            isCollect:false,
            reportBtn:false,
            detailId: null, // 存储接收的参数
            reportFrom: {
               activityId: '',
               cancel: false, //报名接口默认我false
            },
            collectForm:{
               collectType:'',
               refId:'',
            },
         };
      },
      onLoad(options) {
         // 接收 URL 参数
         if (options.id) {
            this.detailId = options.id;
            // 可在此处发起请求,根据 ID 加载详情数据
            this.loadDetailData();
         }
      },
      methods: {
         collect(){
            this.collectForm.collectType = 'activity'
            this.collectForm.refId = this.detailId
            changeCollect(this.collectForm).then(res=>{
               if (res.statusCode === 200) {
                  this.isCollect = true;
                  uni.showToast({
                     title: res.data.msg, // 提示文字
                     icon: 'success', // 图标类型(success/loading/none)
                     mask: true // 是否显示透明蒙层(防止触摸穿透)
                  });
               }
            })
         },
         //报名
         activityReport() {
            this.reportFrom.activityId = this.detailId
            activityReport(this.reportFrom).then(res => {
               if (res.statusCode === 200) {
                  this.reportBtn = true;
                  uni.showToast({
                     title: res.data.msg, // 提示文字
                     icon: 'success', // 图标类型(success/loading/none)
                     mask: true // 是否显示透明蒙层(防止触摸穿透)
                  });
               }
            })
         },
         getUrl(params){
            getFilePreviewUrl(params).then(res =>{
               return res.data.data
            })
         },
         getActivityDetail(id) {
            uni.showLoading({
               title: '加载中'
            });
            getActivityDetail(id).then(res => {
               uni.hideLoading();
               console.log(res.data)
               if (res.statusCode === 200) {
                  //赋值
                  this.activityInfo.coverType = res.data.data.coverType;
                  this.activityInfo.cover = res.data.data.cover;
                  this.activityInfo.activityName = res.data.data.activityName;
                  this.activityInfo.startTime = res.data.data.startTime;
                  this.activityInfo.endTime = res.data.data.endTime;
                  this.activityInfo.activityLocation = res.data.data.activityLocation;
                  this.activityInfo.activityContent = '<h2>活动介绍</h2>' + '<p>' + res.data.data.activityContent  + '</p>';
                  this.activityInfo.activityType = res.data.data.activityType;
                  this.activityInfo.limitUserNum = res.data.data.limitUserNum;
                  this.reportBtn = res.data.data.isReport;
                  this.isCollect = res.data.data.isCollect;
               }
            })
         },
         loadDetailData() {
            //获得详情接口
            this.getActivityDetail(this.detailId);
         }
      }
   };
</script>
<style lang="scss">
   /* 封面容器 */
   .cover-container {
     position: relative;
     width: 100%;
     height: 400rpx;
     overflow: hidden;
     background-color: #f5f5f5;
   }
   /* 图片/视频封面样式 */
   .activity-cover {
     width: 100%;
     height: 100%;
     border-radius: 0; /* 与列表页保持一致 */
   }
   /* 文字封面样式 - 与列表页保持一致 */
   .text-cover {
     width: 100%;
     height: 100%;
     display: flex;
     align-items: center;
     justify-content: center;
     background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
     padding: 40rpx;
   }
   .cover-text {
     color: #fff;
     font-size: 36rpx;
     font-weight: bold;
     text-align: center;
     line-height: 1.4;
     text-shadow: 0 2rpx 4rpx rgba(0,0,0,0.2);
   }
   .header-image {
      width: 100%;
      height: 400rpx;
   }
   .info-section {
      padding: 30rpx;
      background: #fff;
      margin-top: 20rpx;
   }
   .title {
      font-size: 40rpx;
      font-weight: bold;
      color: #333;
      display: block;
      margin-bottom: 20rpx;
   }
   .meta-info {
      margin-bottom: 20rpx;
      color: #666;
   }
   .time {
      margin-right: 30rpx;
   }
   .tags {
      display: flex;
      flex-wrap: wrap;
      margin-top: 20rpx;
   }
   .tag {
      font-size: 24rpx;
      padding: 8rpx 20rpx;
      background: #f0f0f0;
      border-radius: 30rpx;
      margin-right: 15rpx;
      margin-bottom: 15rpx;
   }
   .status-bar {
      padding: 25rpx 30rpx;
      display: flex;
      justify-content: space-between;
      align-items: center;
      color: #fff;
      font-size: 28rpx;
      margin: 20rpx 0;
   }
   .signup-btn {
      background: #fff;
      color: #2196F3;
      padding: 10rpx 30rpx;
      border-radius: 50rpx;
      font-size: 28rpx;
   }
   .content-section {
      padding: 30rpx;
      background: #fff;
      margin-top: 20rpx;
   }
   .footer {
      position: fixed;
      bottom: 0;
      left: 0;
      right: 0;
      height: 100rpx;
      background: #fff;
      display: flex;
      justify-content: space-around;
      align-items: center;
      border-top: 1rpx solid #eee;
      padding: 20rpx 0;
   }
   .footer-item {
      display: flex;
      flex-direction: column;
      align-items: center;
      font-size: 24rpx;
      color: #666;
   }
   .footer-icon {
      width: 40rpx;
      height: 40rpx;
      margin-bottom: 10rpx;
   }
   .btn-container {
       display: flex;
       justify-content: center;
       align-items: center;
       margin-top: 8px; /* 与上方标题保持间距 */
   }
</style>