index.vue 6.4 KB
<!--
 * @Date: 2025-01-15 10:00:00
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2025-09-03 14:54:12
 * @FilePath: /lls_program/src/pages/CheckinList/index.vue
 * @Description: 打卡列表页面 - 显示已打卡的地点列表
-->
<template>
  <view class="checkin-list-container">
    <!-- 活动信息 -->
    <!-- <view class="activity-info">
      <view class="activity-title">{{ activityData.title }}</view>
      <view class="activity-subtitle">{{ activityData.subtitle }}</view>
      <view class="progress-info">
        <text>已打卡 {{ checkedInCount }}/{{ totalLocations }} 个地点</text>
      </view>
    </view> -->

    <!-- 打卡地点列表 -->
    <view class="checkin-list">
      <view
        v-for="(location, index) in locationList"
        :key="index"
        class="checkin-item"
      >
        <view class="location-info">
          <view class="location-name">{{ location.name }}</view>
          <view class="location-address">{{ location.address }}</view>
          <view class="checkin-time" v-if="location.checkedIn">
            打卡时间:{{ location.checkinTime }}
          </view>
        </view>

        <view class="action-button">
          <nut-button
            v-if="location.checkedIn && location.hasPhoto"
            type="primary"
            size="normal"
            color="#4d96ea"
            @click="viewPhoto(location)"
          >
            查看照片
          </nut-button>
          <nut-button
            v-else-if="location.checkedIn && !location.hasPhoto"
            type="warning"
            size="normal"
            @click="uploadPhoto(location)"
          >
            上传照片
          </nut-button>
          <nut-button
            v-else
            type="default"
            size="normal"
            disabled
          >
            未打卡
          </nut-button>
        </view>
      </view>
    </view>

    <!-- 底部导航 -->
    <BottomNav />
  </view>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import Taro from '@tarojs/taro'
import BottomNav from '../../components/BottomNav.vue'
// 导入主题颜色
import { THEME_COLORS } from '@/utils/config'

/**
 * 打卡列表页面组件
 * 功能:显示活动的打卡地点列表,支持查看照片和上传照片
 */

// Mock活动数据
const activityData = ref({
  title: '南京路商圈时尚Citywalk',
  subtitle: '探索城市魅力,感受时尚脉搏',
  dateRange: '2024年1月15日 - 2024年1月31日'
})

// Mock打卡地点数据
const locationList = ref([
  {
    id: 1,
    name: '外滩观景台',
    address: '上海市黄浦区中山东一路',
    checkedIn: true,
    hasPhoto: true,
    checkinTime: '2024-01-16 09:30',
    photoUrl: 'https://img.yzcdn.cn/vant/cat.jpeg'
  },
  {
    id: 2,
    name: '南京路步行街',
    address: '上海市黄浦区南京东路',
    checkedIn: true,
    hasPhoto: false,
    checkinTime: '2024-01-16 10:45',
    photoUrl: ''
  },
  {
    id: 3,
    name: '人民广场',
    address: '上海市黄浦区人民大道',
    checkedIn: true,
    hasPhoto: true,
    checkinTime: '2024-01-16 14:20',
    photoUrl: 'https://img.yzcdn.cn/vant/cat.jpeg'
  },
  {
    id: 4,
    name: '豫园商城',
    address: '上海市黄浦区方浜中路',
    checkedIn: false,
    hasPhoto: false,
    checkinTime: '',
    photoUrl: ''
  },
  {
    id: 5,
    name: '城隍庙',
    address: '上海市黄浦区方浜中路',
    checkedIn: false,
    hasPhoto: false,
    checkinTime: '',
    photoUrl: ''
  }
])

// 计算已打卡数量
const checkedInCount = computed(() => {
  return locationList.value.filter(location => location.checkedIn).length
})

// 总地点数量
const totalLocations = computed(() => {
  return locationList.value.length
})

/**
 * 查看照片 - 跳转到海报打卡页面
 */
const viewPhoto = (location) => {
  Taro.navigateTo({
    url: `/pages/PosterCheckin/index?locationId=${location.id}&mode=view`
  })
}

/**
 * 上传照片 - 跳转到海报打卡页面
 */
const uploadPhoto = (location) => {
  Taro.navigateTo({
    url: `/pages/PosterCheckin/index?locationId=${location.id}&mode=upload`
  })
}

/**
 * 页面加载时初始化数据
 */
onMounted(() => {
  console.log('打卡列表页面加载完成')
  // 这里可以调用API获取真实的打卡数据
  // loadCheckinData()
})

/**
 * 加载打卡数据(预留接口)
 */
const loadCheckinData = async () => {
  try {
    // 调用API获取打卡数据
    // const response = await getCheckinListAPI()
    // locationList.value = response.data
    console.log('加载打卡数据')
  } catch (error) {
    console.error('加载打卡数据失败:', error)
    Taro.showToast({
      title: '加载数据失败',
      icon: 'error'
    })
  }
}
</script>

<style lang="less">
.checkin-list-container {
  min-height: 100vh;
  background-color: #f5f5f5;
  padding-bottom: 120rpx;
}

.header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20rpx 32rpx;
  background-color: #fff;
  border-bottom: 1rpx solid #eee;

  .back-button {
    width: 60rpx;
    height: 60rpx;
    display: flex;
    align-items: center;
    justify-content: center;

    .back-icon {
      font-size: 36rpx;
      color: #333;
    }
  }

  .title {
    font-size: 36rpx;
    font-weight: 600;
    color: #333;
  }

  .placeholder {
    width: 60rpx;
  }
}

.activity-info {
  background-color: #fff;
  padding: 32rpx;
  margin-bottom: 20rpx;

  .activity-title {
    font-size: 36rpx;
    font-weight: 600;
    color: #333;
    margin-bottom: 12rpx;
  }

  .activity-subtitle {
    font-size: 28rpx;
    color: #666;
    margin-bottom: 20rpx;
  }

  .progress-info {
    font-size: 26rpx;
    color: v-bind('THEME_COLORS.PRIMARY');
    background-color: #EBF4FF;
    padding: 12rpx 20rpx;
    border-radius: 20rpx;
    display: inline-block;
  }
}

.checkin-list {
  .checkin-item {
    background-color: #fff;
    margin-bottom: 20rpx;
    padding: 32rpx;
    display: flex;
    align-items: center;
    justify-content: space-between;

    .location-info {
      flex: 1;

      .location-name {
        font-size: 32rpx;
        font-weight: 600;
        color: #333;
        margin-bottom: 8rpx;
      }

      .location-address {
        font-size: 26rpx;
        color: #666;
        margin-bottom: 8rpx;
      }

      .checkin-time {
        font-size: 24rpx;
        color: #999;
      }
    }

    .action-button {
      margin-left: 20rpx;
    }
  }
}
</style>