update pay function

This commit is contained in:
2025-11-23 18:48:12 +08:00
parent 13f8e2a4f1
commit 2fb12e0cc7
5 changed files with 611 additions and 0 deletions

View File

@@ -0,0 +1,309 @@
/**
* 图片灯箱组件
* 点击图片放大查看
*/
import React, { useState } from 'react';
import {
Modal,
ModalOverlay,
ModalContent,
ModalBody,
ModalCloseButton,
Image,
Box,
IconButton,
HStack,
useDisclosure,
} from '@chakra-ui/react';
import { ChevronLeft, ChevronRight, X, ZoomIn } from 'lucide-react';
import { motion, AnimatePresence } from 'framer-motion';
const MotionBox = motion(Box);
/**
* 单图片灯箱
*/
export const ImageLightbox = ({ src, alt, ...props }) => {
const { isOpen, onOpen, onClose } = useDisclosure();
return (
<>
{/* 缩略图 */}
<Box
position="relative"
cursor="pointer"
onClick={onOpen}
_hover={{
'& .zoom-icon': {
opacity: 1,
},
}}
{...props}
>
<Image
src={src}
alt={alt}
w="100%"
h="100%"
objectFit="cover"
borderRadius="md"
transition="all 0.3s"
_hover={{
transform: 'scale(1.05)',
filter: 'brightness(0.8)',
}}
/>
{/* 放大图标 */}
<Box
className="zoom-icon"
position="absolute"
top="50%"
left="50%"
transform="translate(-50%, -50%)"
opacity={0}
transition="opacity 0.3s"
pointerEvents="none"
>
<Box
bg="blackAlpha.700"
borderRadius="full"
p="3"
>
<ZoomIn size={32} color="white" />
</Box>
</Box>
</Box>
{/* 灯箱模态框 */}
<Modal isOpen={isOpen} onClose={onClose} size="full" isCentered>
<ModalOverlay bg="blackAlpha.900" backdropFilter="blur(10px)" />
<ModalContent bg="transparent" boxShadow="none">
<ModalCloseButton
position="fixed"
top="4"
right="4"
size="lg"
color="white"
bg="blackAlpha.600"
_hover={{ bg: 'blackAlpha.800' }}
borderRadius="full"
zIndex={2}
/>
<ModalBody display="flex" alignItems="center" justifyContent="center" p="0">
<MotionBox
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.9 }}
transition={{ duration: 0.3 }}
maxW="90vw"
maxH="90vh"
>
<Image
src={src}
alt={alt}
maxW="100%"
maxH="90vh"
objectFit="contain"
borderRadius="lg"
/>
</MotionBox>
</ModalBody>
</ModalContent>
</Modal>
</>
);
};
/**
* 多图片轮播灯箱
*/
export const ImageGalleryLightbox = ({ images, initialIndex = 0, ...props }) => {
const { isOpen, onOpen, onClose } = useDisclosure();
const [currentIndex, setCurrentIndex] = useState(initialIndex);
const handleOpen = (index) => {
setCurrentIndex(index);
onOpen();
};
const handlePrev = () => {
setCurrentIndex((prev) => (prev === 0 ? images.length - 1 : prev - 1));
};
const handleNext = () => {
setCurrentIndex((prev) => (prev === images.length - 1 ? 0 : prev + 1));
};
const handleKeyDown = (e) => {
if (e.key === 'ArrowLeft') handlePrev();
if (e.key === 'ArrowRight') handleNext();
if (e.key === 'Escape') onClose();
};
return (
<>
{/* 缩略图网格 */}
<HStack spacing="2" flexWrap="wrap" {...props}>
{images.map((image, index) => (
<Box
key={index}
position="relative"
cursor="pointer"
onClick={() => handleOpen(index)}
_hover={{
'& .zoom-icon': {
opacity: 1,
},
}}
>
<Image
src={image.src || image}
alt={image.alt || `图片 ${index + 1}`}
w="150px"
h="150px"
objectFit="cover"
borderRadius="md"
transition="all 0.3s"
_hover={{
transform: 'scale(1.05)',
filter: 'brightness(0.8)',
}}
/>
{/* 放大图标 */}
<Box
className="zoom-icon"
position="absolute"
top="50%"
left="50%"
transform="translate(-50%, -50%)"
opacity={0}
transition="opacity 0.3s"
pointerEvents="none"
>
<Box bg="blackAlpha.700" borderRadius="full" p="2">
<ZoomIn size={24} color="white" />
</Box>
</Box>
</Box>
))}
</HStack>
{/* 灯箱模态框(带轮播) */}
<Modal
isOpen={isOpen}
onClose={onClose}
size="full"
isCentered
onKeyDown={handleKeyDown}
>
<ModalOverlay bg="blackAlpha.900" backdropFilter="blur(10px)" />
<ModalContent bg="transparent" boxShadow="none">
{/* 关闭按钮 */}
<IconButton
icon={<X />}
position="fixed"
top="4"
right="4"
size="lg"
color="white"
bg="blackAlpha.600"
_hover={{ bg: 'blackAlpha.800' }}
borderRadius="full"
zIndex={2}
onClick={onClose}
/>
<ModalBody
display="flex"
alignItems="center"
justifyContent="center"
p="0"
position="relative"
>
{/* 左箭头 */}
{images.length > 1 && (
<IconButton
icon={<ChevronLeft />}
position="absolute"
left="4"
top="50%"
transform="translateY(-50%)"
size="lg"
color="white"
bg="blackAlpha.600"
_hover={{ bg: 'blackAlpha.800' }}
borderRadius="full"
zIndex={2}
onClick={handlePrev}
/>
)}
{/* 图片 */}
<AnimatePresence mode="wait">
<MotionBox
key={currentIndex}
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.9 }}
transition={{ duration: 0.3 }}
maxW="90vw"
maxH="90vh"
>
<Image
src={images[currentIndex].src || images[currentIndex]}
alt={images[currentIndex].alt || `图片 ${currentIndex + 1}`}
maxW="100%"
maxH="90vh"
objectFit="contain"
borderRadius="lg"
/>
</MotionBox>
</AnimatePresence>
{/* 右箭头 */}
{images.length > 1 && (
<IconButton
icon={<ChevronRight />}
position="absolute"
right="4"
top="50%"
transform="translateY(-50%)"
size="lg"
color="white"
bg="blackAlpha.600"
_hover={{ bg: 'blackAlpha.800' }}
borderRadius="full"
zIndex={2}
onClick={handleNext}
/>
)}
{/* 图片计数 */}
{images.length > 1 && (
<Box
position="absolute"
bottom="4"
left="50%"
transform="translateX(-50%)"
bg="blackAlpha.700"
color="white"
px="4"
py="2"
borderRadius="full"
fontSize="sm"
fontWeight="600"
>
{currentIndex + 1} / {images.length}
</Box>
)}
</ModalBody>
</ModalContent>
</Modal>
</>
);
};
export default ImageLightbox;