263 lines
6.1 KiB
Vue
263 lines
6.1 KiB
Vue
<template>
|
|
<view class="header-card animate-enter">
|
|
<image class="header-cover" :src="coverUrl" mode="aspectFill" />
|
|
<view class="header-info">
|
|
<view class="header-title">{{ title }}</view>
|
|
<view class="header-price-row" v-if="price !== undefined">
|
|
<text class="price-symbol">¥</text>
|
|
<text class="price-num">{{ formattedPrice }}</text>
|
|
<text class="price-unit">{{ priceUnit }}</text>
|
|
</view>
|
|
<view class="header-time-row" v-if="scheduledTime">
|
|
<text class="time-label">本期结束</text>
|
|
<text class="time-value">{{ scheduledTime }}</text>
|
|
</view>
|
|
<view class="header-tags" v-if="tags && tags.length">
|
|
<view class="tag-item" v-for="(tag, idx) in tags" :key="idx">{{ tag }}</view>
|
|
</view>
|
|
</view>
|
|
<view class="header-actions">
|
|
<view class="action-btn" @tap="$emit('show-rules')">
|
|
<view class="action-icon rules-icon"></view>
|
|
<text class="action-label">规则</text>
|
|
</view>
|
|
<view class="action-btn" @tap="$emit('go-cabinet')">
|
|
<view class="action-icon cabinet-icon"></view>
|
|
<text class="action-label">盒柜</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed } from 'vue'
|
|
|
|
const props = defineProps({
|
|
title: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
price: {
|
|
type: Number,
|
|
default: undefined
|
|
},
|
|
priceUnit: {
|
|
type: String,
|
|
default: '/发'
|
|
},
|
|
coverUrl: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
tags: {
|
|
type: Array,
|
|
default: () => []
|
|
},
|
|
scheduledTime: {
|
|
type: String,
|
|
default: ''
|
|
}
|
|
})
|
|
|
|
defineEmits(['show-rules', 'go-cabinet'])
|
|
|
|
const formattedPrice = computed(() => {
|
|
const cents = Number(props.price || 0)
|
|
return (cents / 100).toFixed(2)
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
/* ============================================
|
|
头部卡片 - 与原始设计完全一致
|
|
============================================ */
|
|
|
|
.header-card {
|
|
margin: $spacing-xl $spacing-lg;
|
|
background: rgba($bg-card, 0.72);
|
|
backdrop-filter: blur(32rpx);
|
|
border-radius: $radius-xl;
|
|
padding: $spacing-lg;
|
|
display: flex;
|
|
align-items: center;
|
|
box-shadow:
|
|
0 1rpx 0 rgba(255,255,255,0.5) inset,
|
|
0 -1rpx 0 rgba(0,0,0,0.02) inset,
|
|
$shadow-card;
|
|
border: none;
|
|
position: relative;
|
|
overflow: hidden;
|
|
|
|
&::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 2rpx;
|
|
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.8), transparent);
|
|
}
|
|
}
|
|
|
|
.header-cover {
|
|
width: 180rpx;
|
|
height: 180rpx;
|
|
border-radius: $radius-md;
|
|
margin-right: $spacing-lg;
|
|
background: $bg-secondary;
|
|
box-shadow: $shadow-md;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.header-info {
|
|
flex: 1;
|
|
min-width: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
padding: 6rpx 0;
|
|
}
|
|
|
|
.header-title {
|
|
font-size: $font-xl;
|
|
font-weight: 800;
|
|
color: $text-main;
|
|
margin-bottom: $spacing-xs;
|
|
line-height: 1.3;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 2;
|
|
-webkit-box-orient: vertical;
|
|
}
|
|
|
|
.header-price-row {
|
|
display: flex;
|
|
align-items: baseline;
|
|
color: $brand-primary;
|
|
margin-bottom: $spacing-sm;
|
|
text-shadow: 0 2rpx 4rpx rgba($brand-primary, 0.1);
|
|
}
|
|
|
|
.price-symbol {
|
|
font-size: $font-md;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.price-num {
|
|
font-size: $font-xxl;
|
|
font-weight: 900;
|
|
margin: 0 4rpx;
|
|
font-family: 'DIN Alternate', sans-serif;
|
|
}
|
|
|
|
.price-unit {
|
|
font-size: $font-sm;
|
|
color: $text-sub;
|
|
margin-left: 4rpx;
|
|
}
|
|
|
|
.header-time-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12rpx;
|
|
margin-bottom: $spacing-sm;
|
|
}
|
|
|
|
.time-label {
|
|
font-size: $font-xs;
|
|
color: $text-tertiary;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.time-value {
|
|
font-size: $font-sm;
|
|
color: $text-sub;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.header-tags {
|
|
display: flex;
|
|
gap: $spacing-xs;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.tag-item {
|
|
font-size: $font-xs;
|
|
color: $brand-primary-dark;
|
|
background: rgba($brand-primary, 0.08);
|
|
padding: 4rpx $spacing-sm;
|
|
border-radius: $radius-sm;
|
|
font-weight: 600;
|
|
border: 1rpx solid rgba($brand-primary, 0.1);
|
|
}
|
|
|
|
.header-actions {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 28rpx;
|
|
margin-left: 16rpx;
|
|
padding-left: 24rpx;
|
|
border-left: 2rpx solid #E8E8E8;
|
|
justify-content: center;
|
|
align-self: stretch;
|
|
}
|
|
|
|
.action-btn {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
|
|
&:active {
|
|
opacity: 0.6;
|
|
}
|
|
}
|
|
|
|
.action-icon {
|
|
width: 44rpx;
|
|
height: 44rpx;
|
|
margin-bottom: 8rpx;
|
|
background-size: contain;
|
|
background-repeat: no-repeat;
|
|
background-position: center;
|
|
}
|
|
|
|
.rules-icon {
|
|
background-color: #999;
|
|
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3E%3Cpath d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-5 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z'/%3E%3C/svg%3E");
|
|
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3E%3Cpath d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-5 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z'/%3E%3C/svg%3E");
|
|
mask-size: cover;
|
|
-webkit-mask-size: cover;
|
|
}
|
|
|
|
.cabinet-icon {
|
|
background-color: #999;
|
|
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3E%3Cpath d='M20 3H4c-1.1 0-2 .9-2 2v16l4-4h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-9 11H7v-2h4v2zm6-4H7V8h10v2z'/%3E%3C/svg%3E");
|
|
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3E%3Cpath d='M20 3H4c-1.1 0-2 .9-2 2v16l4-4h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-9 11H7v-2h4v2zm6-4H7V8h10v2z'/%3E%3C/svg%3E");
|
|
mask-size: cover;
|
|
-webkit-mask-size: cover;
|
|
}
|
|
|
|
.action-label {
|
|
font-size: 22rpx;
|
|
color: #666;
|
|
letter-spacing: 1rpx;
|
|
}
|
|
|
|
/* 入场动画 */
|
|
.animate-enter {
|
|
animation: slideUp 0.5s ease-out both;
|
|
}
|
|
|
|
@keyframes slideUp {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(20rpx);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
</style>
|