Files
mp-10550/src/components/GiftCardQRCode.tsx
赵忠林 ee28aeeff9 refactor(components): 优化多个组件的样式和结构
-调整了多个组件的图标使用
- 优化了部分组件的布局结构
- 移除了不必要的空行和空格
-统一了部分样式类名的使用
2025-08-17 12:01:17 +08:00

334 lines
9.8 KiB
TypeScript
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.

import React, { useState, useEffect } from 'react'
import { View, Text } from '@tarojs/components'
import { Button, Popup, Tag } from '@nutui/nutui-react-taro'
import { Close, Copy, Share, Refresh, QrCode } from '@nutui/icons-react-taro'
import Taro from '@tarojs/taro'
import dayjs from 'dayjs'
import { generateVerificationCode } from '@/api/shop/shopGift'
export interface GiftCardQRCodeProps {
/** 是否显示弹窗 */
visible: boolean
/** 关闭弹窗回调 */
onClose: () => void
/** 礼品卡信息 */
giftCard: {
id: number
name?: string
goodsName?: string
code?: string
faceValue?: string
type?: number
status?: number
expireTime?: string
contactInfo?: string
}
}
const GiftCardQRCode: React.FC<GiftCardQRCodeProps> = ({
visible,
onClose,
giftCard
}) => {
const [loading, setLoading] = useState(false)
const [verificationCode, setVerificationCode] = useState<string>('')
const [qrData, setQrData] = useState<string>('')
// 生成核销码6位数字
const generateVerificationCode = () => {
return Math.random().toString().slice(2, 8)
}
// 生成二维码数据
const generateQRData = () => {
const code = generateVerificationCode()
setVerificationCode(code)
const data = {
type: 'gift_card_verification',
giftId: giftCard.id,
giftCode: giftCard.code,
verificationCode: code,
faceValue: giftCard.faceValue,
timestamp: Date.now(),
expireTime: giftCard.expireTime
}
const jsonData = JSON.stringify(data)
setQrData(jsonData)
return jsonData
}
// 生成二维码调用后端API
const generateQRCode = async () => {
try {
setLoading(true)
// 调用后端API生成核销码
const result = await generateVerificationCode(giftCard.id)
if (result) {
setVerificationCode(result.verificationCode)
// 生成二维码数据
const data = {
type: 'gift_card_verification',
giftId: giftCard.id,
giftCode: giftCard.code,
verificationCode: result.verificationCode,
faceValue: giftCard.faceValue,
timestamp: Date.now(),
expireTime: giftCard.expireTime,
codeExpireTime: result.expireTime
}
setQrData(JSON.stringify(data))
console.log('二维码数据:', data)
}
} catch (error) {
console.error('生成二维码失败:', error)
Taro.showToast({
title: '生成核销码失败',
icon: 'error'
})
} finally {
setLoading(false)
}
}
// 复制核销码
const copyVerificationCode = () => {
Taro.setClipboardData({
data: verificationCode,
success: () => {
Taro.showToast({
title: '核销码已复制',
icon: 'success'
})
}
})
}
// 复制礼品卡码
const copyGiftCode = () => {
if (giftCard.code) {
Taro.setClipboardData({
data: giftCard.code,
success: () => {
Taro.showToast({
title: '兑换码已复制',
icon: 'success'
})
}
})
}
}
// 分享二维码
const shareQRCode = () => {
// 这里可以实现分享功能
Taro.showToast({
title: '分享功能开发中',
icon: 'none'
})
}
// 刷新二维码
const refreshQRCode = () => {
generateQRCode()
}
// 获取状态文本
const getStatusText = (status?: number) => {
switch (status) {
case 0: return { text: '未使用', color: 'success' }
case 1: return { text: '已使用', color: 'warning' }
case 2: return { text: '失效', color: 'danger' }
default: return { text: '未知', color: 'default' }
}
}
// 获取类型文本
const getTypeText = (type?: number) => {
switch (type) {
case 10: return '实物礼品卡'
case 20: return '虚拟礼品卡'
case 30: return '服务礼品卡'
default: return '礼品卡'
}
}
// 弹窗打开时生成二维码
useEffect(() => {
if (visible && giftCard.id) {
generateQRCode()
}
}, [visible, giftCard.id])
const statusInfo = getStatusText(giftCard.status)
return (
<Popup
visible={visible}
position="center"
closeable
closeIcon={<Close />}
onClose={onClose}
style={{ width: '90%', maxWidth: '400px' }}
>
<View className="p-6">
{/* 标题 */}
<View className="text-center mb-4">
<Text className="text-lg font-bold"></Text>
<Text className="text-sm text-gray-500 mt-1">
</Text>
</View>
{/* 礼品卡信息 */}
<View className="bg-gray-50 rounded-lg p-4 mb-4">
<View className="flex justify-between items-start mb-2">
<Text className="font-medium text-base">
{giftCard.goodsName || giftCard.name}
</Text>
<Tag type={statusInfo.color} size="small">
{statusInfo.text}
</Tag>
</View>
<View className="flex justify-between items-center mb-2">
<Text className="text-sm text-gray-600"></Text>
<Text className="text-lg font-bold text-red-500">
¥{giftCard.faceValue}
</Text>
</View>
<View className="flex justify-between items-center mb-2">
<Text className="text-sm text-gray-600"></Text>
<Text className="text-sm">{getTypeText(giftCard.type)}</Text>
</View>
{giftCard.expireTime && (
<View className="flex justify-between items-center">
<Text className="text-sm text-gray-600"></Text>
<Text className="text-sm text-orange-600">
{dayjs(giftCard.expireTime).format('YYYY-MM-DD')}
</Text>
</View>
)}
</View>
{/* 二维码区域 */}
<View className="text-center mb-4">
{loading ? (
<View className="w-48 h-48 mx-auto bg-gray-100 rounded-lg flex items-center justify-center">
<Text className="text-gray-500">...</Text>
</View>
) : verificationCode ? (
<View className="relative">
{/* 模拟二维码显示区域 */}
<View className="w-48 h-48 mx-auto bg-white border-2 border-gray-300 rounded-lg flex flex-col items-center justify-center">
<QrCode size="80" className="text-gray-800 mb-2" />
<Text className="text-xs text-gray-600"></Text>
<Text className="text-xs text-gray-500 mt-1">
ID: {giftCard.id}
</Text>
</View>
<Button
size="small"
fill="outline"
icon={<Refresh />}
className="absolute top-2 right-2"
onClick={refreshQRCode}
>
</Button>
</View>
) : (
<View className="w-48 h-48 mx-auto bg-gray-100 rounded-lg flex items-center justify-center">
<Text className="text-gray-500"></Text>
</View>
)}
</View>
{/* 核销码 */}
{verificationCode && (
<View className="bg-blue-50 rounded-lg p-3 mb-4">
<View className="flex justify-between items-center">
<View>
<Text className="text-sm text-blue-600 mb-1"></Text>
<Text className="text-xl font-mono font-bold text-blue-800">
{verificationCode}
</Text>
</View>
<Button
size="small"
fill="outline"
icon={<Copy />}
onClick={copyVerificationCode}
>
</Button>
</View>
</View>
)}
{/* 兑换码 */}
{giftCard.code && (
<View className="bg-green-50 rounded-lg p-3 mb-4">
<View className="flex justify-between items-center">
<View>
<Text className="text-sm text-green-600 mb-1"></Text>
<Text className="text-base font-mono text-green-800">
{giftCard.code}
</Text>
</View>
<Button
size="small"
fill="outline"
icon={<Copy />}
onClick={copyGiftCode}
>
</Button>
</View>
</View>
)}
{/* 操作按钮 */}
<View className="flex">
<Button
size="large"
fill="outline"
icon={<Share />}
onClick={shareQRCode}
className="flex-1 mr-3"
>
</Button>
<Button
size="large"
type="primary"
onClick={onClose}
className="flex-1"
>
</Button>
</View>
{/* 使用说明 */}
<View className="mt-4 p-3 bg-yellow-50 rounded-lg">
<Text className="text-sm text-yellow-800 font-medium mb-2">使</Text>
<View>
<Text className="text-xs text-yellow-700 mb-1"> </Text>
<Text className="text-xs text-yellow-700 mb-1"> </Text>
<Text className="text-xs text-yellow-700 mb-1"> 使</Text>
<Text className="text-xs text-yellow-700"> {giftCard.contactInfo || '400-800-8888'}</Text>
</View>
</View>
</View>
</Popup>
)
}
export default GiftCardQRCode