ProductCard.vue 3.31 KB
<template>
  <view
    class="relative bg-white rounded-[24rpx] p-[32rpx] border border-gray-200 product-card overflow-hidden transition-all duration-300 active:scale-[0.99]"
    style="box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.05);"
  >
    <!-- 装饰背景: 右上角灰色光晕 -->
    <view class="absolute -right-[40rpx] -top-[40rpx] w-[160rpx] h-[160rpx] bg-gray-100 rounded-full opacity-60 blur-[30rpx] pointer-events-none"></view>

    <!-- 内容区域 -->
    <view class="relative z-10">
      <!-- 头部:标题与标签 -->
      <view class="mb-[36rpx]">
        <!-- 产品名称 -->
        <text class="block text-gray-900 text-[34rpx] font-bold leading-[1.4] mb-[20rpx] tracking-tight">
          {{ productName }}
        </text>

        <!-- 产品标签 -->
        <view v-if="tags && tags.length" class="flex flex-wrap gap-[12rpx]">
          <view
            v-for="tag in tags"
            :key="tag.id"
            class="text-[22rpx] px-[16rpx] py-[6rpx] rounded-[8rpx] font-medium flex items-center justify-center transition-opacity"
            :style="{
              backgroundColor: tag.bg_color || '#F3F4F6',
              color: tag.text_color || '#4B5563',
              border: `1px solid ${tag.bg_color ? 'transparent' : '#E5E7EB'}`
            }"
          >
            {{ tag.name }}
          </view>
        </view>
      </view>

      <!-- 操作按钮组 -->
      <view class="flex justify-between gap-[20rpx]">
        <!-- 详情按钮: 柔和的灰色背景 -->
        <view
          class="flex-1 h-[76rpx] flex items-center justify-center rounded-[16rpx] bg-[#F3F4F6] active:bg-[#E5E7EB] transition-colors"
          @tap.stop="handleDetail"
        >
          <text class="text-[28rpx] text-gray-600 font-medium">产品详情</text>
        </view>

        <!-- 计划书按钮: 柔和的蓝色背景,降低对比度 -->
        <view
          class="flex-1 h-[76rpx] flex items-center justify-center rounded-[16rpx] bg-[#EFF6FF] active:bg-[#DBEAFE] transition-colors"
          @tap.stop="handlePlan"
        >
          <text class="text-[28rpx] text-blue-600 font-medium">制作计划书</text>
        </view>
      </view>
    </view>
  </view>
</template>

<script setup>
/**
 * 产品卡片组件
 *
 * @description 热卖产品列表项卡片,展示产品名称、标签和操作按钮
 * @component ProductCard
 */

import { defineProps, defineEmits } from 'vue';

/**
 * 组件属性
 */
const props = defineProps({
  /** 产品 ID */
  productId: {
    type: Number,
    required: true
  },
  /** 产品名称 */
  productName: {
    type: String,
    required: true
  },
  /** 产品标签数组 */
  tags: {
    type: Array,
    default: () => []
  }
});

/**
 * 组件事件
 */
const emit = defineEmits({
  /** 点击产品详情按钮 */
  detail: (productId) => typeof productId === 'number',
  /** 点击计划书按钮 */
  plan: (productId) => typeof productId === 'number'
});

/**
 * 处理产品详情点击
 *
 * @description 触发 detail 事件,传递产品 ID
 */
const handleDetail = () => {
  emit('detail', props.productId);
};

/**
 * 处理计划书点击
 *
 * @description 触发 plan 事件,传递产品 ID
 */
const handlePlan = () => {
  emit('plan', props.productId);
};
</script>

<style lang="less" scoped>
.product-card {
  // 保持 scoped 样式块,方便未来扩展
}
</style>