bindbox-mini/components/activity/RecordsList.vue
2026-01-21 12:39:52 +08:00

240 lines
5.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="records-wrapper">
<view class="records-list" v-if="records && records.length">
<view v-for="(item, idx) in records" :key="item.id ? `${item.id}_${idx}` : idx" class="record-item">
<!-- 用户信息 (左侧, 紧凑) -->
<view class="user-info-section">
<image class="user-avatar" :src="item.avatar || defaultAvatar" mode="aspectFill" />
<view class="user-detail">
<text class="user-name">{{ item.user_name }}</text>
<text class="record-time">{{ formatTime(item.created_at) }}</text>
</view>
</view>
<!-- 奖品信息 (右侧, 扩展) -->
<view class="prize-info-section">
<view class="prize-image-wrap">
<image class="record-img" :src="item.image" mode="aspectFill" />
<view class="level-badge" v-if="item.level_name">{{ item.level_name }}</view>
</view>
<view class="record-info">
<view class="record-title">{{ item.title }}</view>
<view class="record-meta">
<text class="record-count">x1</text>
</view>
</view>
</view>
</view>
</view>
<view class="empty-state-compact" v-else>
<view class="empty-icon-wrap">
<text class="empty-icon">🎁</text>
</view>
<text class="empty-title">{{ emptyText }}</text>
<text class="empty-hint">快来参与活动吧</text>
</view>
</view>
</template>
<script setup>
import { computed } from 'vue'
defineProps({
records: {
type: Array,
default: () => []
},
emptyText: {
type: String,
default: '今日暂无购买记录记录不会展示最近5分钟内的'
}
})
const defaultAvatar = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'
function formatTime(t) {
if (!t) return ''
const d = new Date(t)
if (isNaN(d.getTime())) return t // 如果解析失败直接返回
const m = String(d.getMonth() + 1).padStart(2, '0')
const day = String(d.getDate()).padStart(2, '0')
const hh = String(d.getHours()).padStart(2, '0')
const mm = String(d.getMinutes()).padStart(2, '0')
const ss = String(d.getSeconds()).padStart(2, '0')
return `${m}-${day} ${hh}:${mm}:${ss}`
}
</script>
<style lang="scss" scoped>
.records-list {
padding: $spacing-xs 0;
}
.record-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: $spacing-md $spacing-sm;
border-bottom: 1rpx solid rgba(0, 0, 0, 0.03);
&:last-child {
border-bottom: none;
}
}
.record-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: $spacing-md $spacing-sm;
border-bottom: 1rpx solid rgba(0, 0, 0, 0.03);
&:last-child {
border-bottom: none;
}
}
.user-info-section {
display: flex;
align-items: center;
gap: $spacing-xs;
flex: 0 0 35%; // 固定宽度给用户信息
min-width: 0;
}
.user-avatar {
width: 56rpx;
height: 56rpx;
border-radius: 50%;
background: $bg-secondary;
border: 1px solid rgba(0,0,0,0.05);
flex-shrink: 0;
}
.user-detail {
display: flex;
flex-direction: column;
gap: 2rpx;
min-width: 0;
}
.user-name {
font-size: 24rpx;
color: $text-main;
font-weight: 500;
@include text-ellipsis(1);
}
.record-time {
font-size: 20rpx;
color: $text-sub;
@include text-ellipsis(1);
}
.prize-info-section {
display: flex;
align-items: center;
gap: $spacing-sm;
flex: 1;
min-width: 0;
justify-content: flex-end;
}
.prize-image-wrap {
position: relative;
width: 72rpx;
height: 72rpx;
flex-shrink: 0;
}
.record-img {
width: 100%;
height: 100%;
border-radius: $radius-md;
background: $bg-secondary;
border: 1px solid rgba(0,0,0,0.05);
}
.level-badge {
position: absolute;
top: -6rpx;
right: -6rpx;
background: $gradient-gold;
color: #fff;
font-size: 16rpx;
padding: 2rpx 6rpx;
border-radius: 4rpx;
font-weight: bold;
box-shadow: 0 2rpx 4rpx rgba(0,0,0,0.1);
}
.record-info {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
align-items: flex-start; // 左对齐
}
.record-title {
font-size: 24rpx;
font-weight: 500;
color: $text-main;
@include text-ellipsis(2); // 允许两行
line-height: 1.3;
margin-bottom: 4rpx;
width: 100%;
}
.record-meta {
display: flex;
align-items: center;
}
.record-count {
font-size: 20rpx;
color: $brand-primary;
background: rgba($brand-primary, 0.08);
padding: 2rpx 8rpx;
border-radius: 4rpx;
}
/* 紧凑优雅的空状态 */
.empty-state-compact {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: $spacing-lg $spacing-xl;
min-height: 200rpx;
}
.empty-icon-wrap {
width: 80rpx;
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, rgba($brand-primary, 0.1) 0%, rgba($accent-gold, 0.1) 100%);
border-radius: 50%;
margin-bottom: $spacing-md;
}
.empty-icon {
font-size: 40rpx;
}
.empty-title {
font-size: $font-md;
color: $text-sub;
font-weight: 600;
margin-bottom: 8rpx;
}
.empty-hint {
font-size: $font-xs;
color: $text-tertiary;
}
</style>