You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
227 lines
5.9 KiB
227 lines
5.9 KiB
import React from 'react'
|
|
import { View, Text } from '@tarojs/components'
|
|
import { Popup } from '@nutui/nutui-react-taro'
|
|
import { Share, Link, Close, Gift } from '@nutui/icons-react-taro'
|
|
import Taro from '@tarojs/taro'
|
|
|
|
export interface GiftCardShareProps {
|
|
/** 是否显示分享弹窗 */
|
|
visible: boolean
|
|
/** 礼品卡信息 */
|
|
giftCard: {
|
|
id: number
|
|
name: string
|
|
type: number
|
|
faceValue: string
|
|
code?: string
|
|
description?: string
|
|
}
|
|
/** 关闭回调 */
|
|
onClose: () => void
|
|
}
|
|
|
|
const GiftCardShare: React.FC<GiftCardShareProps> = ({
|
|
visible,
|
|
giftCard,
|
|
onClose
|
|
}) => {
|
|
// 获取礼品卡类型文本
|
|
const getTypeText = () => {
|
|
switch (giftCard.type) {
|
|
case 10: return '实物礼品卡'
|
|
case 20: return '虚拟礼品卡'
|
|
case 30: return '服务礼品卡'
|
|
default: return '礼品卡'
|
|
}
|
|
}
|
|
|
|
// 生成分享文案
|
|
const generateShareText = () => {
|
|
const typeText = getTypeText()
|
|
const valueText = `¥${giftCard.faceValue}`
|
|
|
|
return `🎁 ${giftCard.name}\n💰 面值 ${valueText}\n🏷️ ${typeText}\n${giftCard.description ? `📝 ${giftCard.description}\n` : ''}快来领取这份礼品卡吧!`
|
|
}
|
|
|
|
// 生成分享链接
|
|
const generateShareUrl = () => {
|
|
// 这里应该是实际的分享链接,包含礼品卡ID等参数
|
|
return `https://your-domain.com/gift/share?id=${giftCard.id}`
|
|
}
|
|
|
|
// 微信分享
|
|
const handleWechatShare = () => {
|
|
Taro.showShareMenu({
|
|
withShareTicket: true,
|
|
success: () => {
|
|
Taro.showToast({
|
|
title: '分享成功',
|
|
icon: 'success'
|
|
})
|
|
onClose()
|
|
},
|
|
fail: () => {
|
|
Taro.showToast({
|
|
title: '分享失败',
|
|
icon: 'error'
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
// 复制链接
|
|
const handleCopyLink = () => {
|
|
const shareUrl = generateShareUrl()
|
|
const shareText = generateShareText()
|
|
const fullText = `${shareText}\n\n${shareUrl}`
|
|
|
|
Taro.setClipboardData({
|
|
data: fullText,
|
|
success: () => {
|
|
Taro.showToast({
|
|
title: '已复制到剪贴板',
|
|
icon: 'success'
|
|
})
|
|
onClose()
|
|
},
|
|
fail: () => {
|
|
Taro.showToast({
|
|
title: '复制失败',
|
|
icon: 'error'
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
// 复制兑换码
|
|
const handleCopyCode = () => {
|
|
if (!giftCard.code) {
|
|
Taro.showToast({
|
|
title: '暂无兑换码',
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
|
|
Taro.setClipboardData({
|
|
data: giftCard.code,
|
|
success: () => {
|
|
Taro.showToast({
|
|
title: '兑换码已复制',
|
|
icon: 'success'
|
|
})
|
|
onClose()
|
|
},
|
|
fail: () => {
|
|
Taro.showToast({
|
|
title: '复制失败',
|
|
icon: 'error'
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
// 保存图片分享
|
|
const handleSaveImage = async () => {
|
|
try {
|
|
// 这里可以生成礼品卡图片并保存到相册
|
|
// 实际实现需要canvas绘制礼品卡图片
|
|
Taro.showToast({
|
|
title: '功能开发中',
|
|
icon: 'none'
|
|
})
|
|
} catch (error) {
|
|
Taro.showToast({
|
|
title: '保存失败',
|
|
icon: 'error'
|
|
})
|
|
}
|
|
}
|
|
|
|
const shareOptions = [
|
|
{
|
|
icon: <Share size="32" className="text-green-500" />,
|
|
label: '微信好友',
|
|
onClick: handleWechatShare
|
|
},
|
|
{
|
|
icon: <Link size="32" className="text-blue-500" />,
|
|
label: '复制链接',
|
|
onClick: handleCopyLink
|
|
},
|
|
{
|
|
icon: <Gift size="32" className="text-purple-500" />,
|
|
label: '复制兑换码',
|
|
onClick: handleCopyCode,
|
|
disabled: !giftCard.code
|
|
},
|
|
{
|
|
icon: <Share size="32" className="text-orange-500" />,
|
|
label: '保存图片',
|
|
onClick: handleSaveImage
|
|
}
|
|
]
|
|
|
|
return (
|
|
<Popup
|
|
visible={visible}
|
|
position="bottom"
|
|
style={{ height: 'auto' }}
|
|
round
|
|
>
|
|
<View className="p-6">
|
|
{/* 头部 */}
|
|
<View className="flex items-center justify-between mb-6">
|
|
<Text className="text-lg font-semibold">分享礼品卡</Text>
|
|
<View onClick={onClose}>
|
|
<Close size="20" className="text-gray-500" />
|
|
</View>
|
|
</View>
|
|
|
|
{/* 礼品卡预览 */}
|
|
<View className="rounded-xl p-4 mb-6 text-white" style={{backgroundColor: '#fbbf24'}}>
|
|
<Text className="text-xl font-bold mb-2">{giftCard.name}</Text>
|
|
<View className="flex items-center justify-between">
|
|
<View>
|
|
<Text className="text-2xl font-bold">¥{giftCard.faceValue}</Text>
|
|
<Text className="text-sm opacity-90">{getTypeText()}</Text>
|
|
</View>
|
|
<Gift size="24" />
|
|
</View>
|
|
{giftCard.code && (
|
|
<View className="mt-3 p-2 bg-white bg-opacity-20 rounded">
|
|
<Text className="text-xs opacity-80">兑换码</Text>
|
|
<Text className="font-mono font-bold">{giftCard.code}</Text>
|
|
</View>
|
|
)}
|
|
</View>
|
|
|
|
{/* 分享选项 */}
|
|
<View className="flex justify-between mb-4" style={{gap: '16px'}}>
|
|
{shareOptions.map((option, index) => (
|
|
<View
|
|
key={index}
|
|
className={`flex-1 flex flex-col items-center py-4 bg-gray-50 rounded-lg ${
|
|
option.disabled ? 'opacity-50' : ''
|
|
}`}
|
|
onClick={option.disabled ? undefined : option.onClick}
|
|
>
|
|
<View className="mb-2">{option.icon}</View>
|
|
<Text className="text-sm text-gray-700">{option.label}</Text>
|
|
</View>
|
|
))}
|
|
</View>
|
|
|
|
{/* 分享文案预览 */}
|
|
<View className="bg-gray-50 rounded-lg p-3">
|
|
<Text className="text-xs text-gray-500 mb-2">分享文案预览:</Text>
|
|
<Text className="text-sm text-gray-700 leading-relaxed">
|
|
{generateShareText()}
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
</Popup>
|
|
)
|
|
}
|
|
|
|
export default GiftCardShare
|