feat(components): 新增 GiftCard礼品卡组件

- 新增 GiftCard 组件,支持多种类型礼品卡的展示和交互
- 组件包含商品信息、价格、折扣、使用指南等丰富功能- 优化图像展示,支持单
This commit is contained in:
2025-08-17 00:06:03 +08:00
parent 1b24a611a8
commit ecb5d9059a
22 changed files with 2788 additions and 191 deletions

201
src/user/gift/demo.tsx Normal file
View File

@@ -0,0 +1,201 @@
import React, { useState } from 'react'
import { View, Text } from '@tarojs/components'
import { Button, Tabs, TabPane } from '@nutui/nutui-react-taro'
import GiftCard from '@/components/GiftCard'
import { ShopGift } from '@/api/shop/shopGift/model'
const GiftCardDemo: React.FC = () => {
const [activeTab, setActiveTab] = useState('0')
// 模拟不同类型的礼品卡数据
const mockGifts: ShopGift[] = [
{
id: 1,
name: '星巴克礼品卡',
goodsName: '星巴克咖啡礼品卡(电子版)',
goodsImage: 'https://img.alicdn.com/imgextra/i1/2206571109/O1CN01QZxQJJ1Uw8QZxQJJ_!!2206571109.jpg',
description: '享受醇香咖啡时光,适用于全国星巴克门店',
code: 'SB2024001234567890',
goodsId: 101,
faceValue: '100',
type: 20,
useStatus: 0,
expireTime: '2024-12-31 23:59:59',
instructions: '请在有效期内使用,出示兑换码即可使用',
contactInfo: '400-800-8888'
},
{
id: 2,
name: '麦当劳优惠券',
goodsName: '麦当劳经典套餐券',
goodsImage: 'https://img.alicdn.com/imgextra/i2/2206571109/O1CN01ABC123_!!2206571109.jpg',
description: '美味汉堡套餐,限时优惠',
code: 'MCD2024987654321',
goodsId: 102,
faceValue: '50',
type: 20,
useStatus: 0,
expireTime: '2024-10-31 23:59:59',
instructions: '适用于全国麦当劳门店,不可与其他优惠同享',
contactInfo: '400-517-517'
},
{
id: 3,
name: '海底捞火锅券',
goodsName: '海底捞火锅代金券',
goodsImage: 'https://img.alicdn.com/imgextra/i3/2206571109/O1CN01DEF456_!!2206571109.jpg',
description: '享受正宗川味火锅',
code: 'HDL2024555666777',
goodsId: 103,
faceValue: '200',
type: 30,
useStatus: 1,
useTime: '2024-08-15 19:30:00',
useLocation: '海底捞王府井店',
instructions: '需提前预约,适用于全国海底捞门店',
contactInfo: '400-869-8888'
}
]
// 转换数据格式
const transformGiftData = (gift: ShopGift) => {
return {
id: gift.id || 0,
name: gift.goodsName || gift.name || '礼品卡',
description: gift.description || gift.instructions,
code: gift.code,
goodsImage: gift.goodsImage,
faceValue: gift.faceValue,
type: gift.type,
useStatus: gift.useStatus,
expireTime: gift.expireTime,
useTime: gift.useTime,
useLocation: gift.useLocation,
contactInfo: gift.contactInfo,
goodsInfo: {
...(gift.goodsId && {
specification: `礼品卡面值:¥${gift.faceValue}`,
category: getTypeText(gift.type),
tags: [
getTypeText(gift.type),
gift.useStatus === 0 ? '可使用' : gift.useStatus === 1 ? '已使用' : '已过期',
'全国通用',
gift.type === 20 ? '即买即用' : '需预约'
].filter(Boolean),
instructions: gift.instructions ? [gift.instructions] : [
'请在有效期内使用',
'出示兑换码即可使用',
'不可兑换现金'
],
notices: [
'礼品卡一经使用不可退换',
'请妥善保管兑换码',
'如有疑问请联系客服'
]
})
},
showCode: gift.useStatus === 0,
showUseBtn: gift.useStatus === 0,
showDetailBtn: true,
showGoodsDetail: true,
theme: getThemeByType(gift.type),
onUse: () => handleUse(gift),
onDetail: () => handleDetail(gift),
onClick: () => handleClick(gift)
}
}
const getTypeText = (type?: number): string => {
switch (type) {
case 10: return '实物礼品卡'
case 20: return '虚拟礼品卡'
case 30: return '服务礼品卡'
default: return '礼品卡'
}
}
const getThemeByType = (type?: number): 'gold' | 'silver' | 'bronze' | 'blue' | 'green' | 'purple' => {
switch (type) {
case 10: return 'gold'
case 20: return 'blue'
case 30: return 'green'
default: return 'silver'
}
}
const handleUse = (gift: ShopGift) => {
console.log('使用礼品卡:', gift.goodsName)
}
const handleDetail = (gift: ShopGift) => {
console.log('查看详情:', gift.goodsName)
}
const handleClick = (gift: ShopGift) => {
console.log('点击礼品卡:', gift.goodsName)
}
// 根据状态筛选礼品卡
const getFilteredGifts = () => {
const statusMap = {
'0': 0, // 可用
'1': 1, // 已使用
'2': 2 // 已过期
}
const targetStatus = statusMap[activeTab as keyof typeof statusMap]
return mockGifts.filter(gift => gift.useStatus === targetStatus)
}
return (
<View className="bg-gray-50 min-h-screen">
{/* 页面标题 */}
<View className="bg-white px-4 py-3 border-b border-gray-100">
<Text className="text-lg font-bold text-center">
</Text>
</View>
{/* Tab切换 */}
<View className="bg-white">
<Tabs value={activeTab} onChange={setActiveTab}>
<TabPane title="可用" value="0" />
<TabPane title="已使用" value="1" />
<TabPane title="已过期" value="2" />
</Tabs>
</View>
{/* 礼品卡列表 */}
<View className="p-4">
{getFilteredGifts().map((gift) => (
<View key={gift.id} className="mb-4">
<GiftCard {...transformGiftData(gift)} />
</View>
))}
{getFilteredGifts().length === 0 && (
<View className="text-center py-16">
<Text className="text-gray-500">
{activeTab === '0' ? '暂无可用礼品卡' :
activeTab === '1' ? '暂无已使用礼品卡' :
'暂无已过期礼品卡'}
</Text>
</View>
)}
</View>
{/* 功能说明 */}
<View className="bg-white mx-4 mb-4 p-4 rounded-lg">
<Text className="font-bold mb-2"></Text>
<View className="space-y-1">
<Text className="text-sm text-gray-600"> goodsName</Text>
<Text className="text-sm text-gray-600"> goodsImage</Text>
<Text className="text-sm text-gray-600"> </Text>
<Text className="text-sm text-gray-600"> </Text>
<Text className="text-sm text-gray-600"> </Text>
</View>
</View>
</View>
)
}
export default GiftCardDemo