update pay function
This commit is contained in:
@@ -243,7 +243,7 @@ export default function SubscriptionContentNew() {
|
||||
},
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({
|
||||
plan_type: selectedPlan.name,
|
||||
plan_name: selectedPlan.name,
|
||||
billing_cycle: selectedCycle,
|
||||
promo_code: promoCodeApplied ? promoCode : null,
|
||||
}),
|
||||
@@ -582,18 +582,28 @@ export default function SubscriptionContentNew() {
|
||||
h="100%"
|
||||
borderRadius="20px"
|
||||
overflow="hidden"
|
||||
bg={isPremium ? 'rgba(10, 10, 10, 0.5)' : 'rgba(10, 10, 10, 0.3)'}
|
||||
border={isPremium ? '1px solid rgba(212, 175, 55, 0.3)' : '1px solid rgba(255, 255, 255, 0.1)'}
|
||||
boxShadow={isPremium ? '0 20px 60px rgba(212, 175, 55, 0.2)' : '0 20px 60px rgba(0, 0, 0, 0.3)'}
|
||||
transition="all 0.4s cubic-bezier(0.4, 0, 0.2, 1)"
|
||||
_hover={{
|
||||
transform: 'translateY(-8px)',
|
||||
borderColor: isPremium ? 'rgba(212, 175, 55, 0.5)' : 'rgba(255, 255, 255, 0.2)',
|
||||
boxShadow: isPremium
|
||||
? '0 30px 80px rgba(212, 175, 55, 0.3)'
|
||||
: '0 30px 80px rgba(0, 0, 0, 0.5)',
|
||||
}}
|
||||
_before={
|
||||
isPremium
|
||||
? {
|
||||
content: '""',
|
||||
position: 'absolute',
|
||||
top: '-144px',
|
||||
left: '52px',
|
||||
width: '420px',
|
||||
maskImage: 'radial-gradient(circle at center, black 20%, transparent 52%)',
|
||||
WebkitMaskImage: 'radial-gradient(circle at center, black 20%, transparent 52%)',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
width: '120%',
|
||||
height: '120%',
|
||||
background: 'radial-gradient(circle at center, rgba(212, 175, 55, 0.1) 0%, transparent 70%)',
|
||||
pointerEvents: 'none',
|
||||
zIndex: 0,
|
||||
}
|
||||
@@ -609,26 +619,24 @@ export default function SubscriptionContentNew() {
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
>
|
||||
{/* 推荐标签 */}
|
||||
{plan.badge && (
|
||||
{/* 套餐标题 */}
|
||||
<Box
|
||||
position="relative"
|
||||
zIndex={2}
|
||||
py={2}
|
||||
py={3}
|
||||
px={8.5}
|
||||
fontSize="sm"
|
||||
fontSize="lg"
|
||||
fontWeight="bold"
|
||||
bgGradient={
|
||||
isPremium
|
||||
? 'linear-gradient(to right, rgba(212, 175, 55, 0.2), rgba(212, 175, 55, 0.2))'
|
||||
: 'transparent'
|
||||
: 'linear-gradient(to right, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.05))'
|
||||
}
|
||||
borderTopRadius="20px"
|
||||
color={isPremium ? '#D4AF37' : 'white'}
|
||||
>
|
||||
{plan.displayName}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<VStack
|
||||
spacing={0}
|
||||
@@ -636,7 +644,7 @@ export default function SubscriptionContentNew() {
|
||||
position="relative"
|
||||
zIndex={3}
|
||||
flex={1}
|
||||
mt={plan.badge ? -5 : 0}
|
||||
mt={-1}
|
||||
p={3.5}
|
||||
pb={8}
|
||||
backdropFilter={isPremium ? 'blur(32px)' : 'blur(20px)'}
|
||||
@@ -655,108 +663,137 @@ export default function SubscriptionContentNew() {
|
||||
{/* 价格卡片 */}
|
||||
<Box
|
||||
position="relative"
|
||||
mb={8}
|
||||
p={5}
|
||||
borderRadius="13px"
|
||||
bg={isPremium ? 'rgba(255, 255, 255, 0.1)' : 'rgba(255, 255, 255, 0.02)'}
|
||||
mb={6}
|
||||
p={6}
|
||||
borderRadius="16px"
|
||||
bg={isPremium ? 'rgba(212, 175, 55, 0.1)' : 'rgba(255, 255, 255, 0.03)'}
|
||||
backdropFilter="blur(20px)"
|
||||
boxShadow={isPremium ? '0 20px 60px rgba(0, 0, 0, 0.7)' : '0 20px 60px rgba(0, 0, 0, 0.5)'}
|
||||
boxShadow="0 8px 32px rgba(0, 0, 0, 0.4)"
|
||||
_after={{
|
||||
content: '""',
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
borderRadius: '13px',
|
||||
borderRadius: '16px',
|
||||
border: '1px solid',
|
||||
borderColor: 'rgba(255, 255, 255, 0.1)',
|
||||
borderColor: isPremium ? 'rgba(212, 175, 55, 0.2)' : 'rgba(255, 255, 255, 0.1)',
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
>
|
||||
<HStack align="baseline" spacing={3} mb={4}>
|
||||
<Flex align="baseline" justify="center" mb={5}>
|
||||
<Text
|
||||
fontSize="4xl"
|
||||
fontSize="5xl"
|
||||
fontWeight="bold"
|
||||
bgGradient="radial-gradient(circle at center, #FFFFFF 0%, rgba(255,255,255,0.6) 100%)"
|
||||
bgClip="text"
|
||||
lineHeight="1.2"
|
||||
lineHeight="1"
|
||||
letterSpacing="-0.02em"
|
||||
>
|
||||
¥{getCurrentPrice(plan)}
|
||||
</Text>
|
||||
<Text fontSize="sm" color="rgba(255, 255, 255, 0.7)">
|
||||
/{currentPriceOption?.label || '月'}
|
||||
<Text fontSize="lg" color="rgba(255, 255, 255, 0.6)" ml={2}>
|
||||
/ {currentPriceOption?.label || '月'}
|
||||
</Text>
|
||||
</HStack>
|
||||
</Flex>
|
||||
|
||||
<Button
|
||||
w="full"
|
||||
size="lg"
|
||||
py={6}
|
||||
bgGradient={
|
||||
isPremium
|
||||
? 'linear-gradient(135deg, #D4AF37, #B8941F)'
|
||||
: 'linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05))'
|
||||
h="56px"
|
||||
bg={
|
||||
isCurrentPlan
|
||||
? 'transparent'
|
||||
: isPremium
|
||||
? 'linear-gradient(135deg, #D4AF37 0%, #B8941F 100%)'
|
||||
: 'rgba(255, 255, 255, 0.05)'
|
||||
}
|
||||
color={
|
||||
isCurrentPlan
|
||||
? 'rgba(255, 255, 255, 0.5)'
|
||||
: isPremium
|
||||
? '#000'
|
||||
: '#fff'
|
||||
}
|
||||
border={
|
||||
isCurrentPlan
|
||||
? '1px solid rgba(255, 255, 255, 0.2)'
|
||||
: isPremium
|
||||
? 'none'
|
||||
: '1px solid rgba(255, 255, 255, 0.1)'
|
||||
}
|
||||
color={isPremium ? '#000' : 'rgba(255, 255, 255, 0.9)'}
|
||||
border={isPremium ? 'none' : '1px solid rgba(255, 255, 255, 0.1)'}
|
||||
fontWeight="bold"
|
||||
fontSize="md"
|
||||
borderRadius="lg"
|
||||
onClick={() => !isCurrentPlan && handleSubscribe(plan)}
|
||||
isDisabled={isCurrentPlan}
|
||||
cursor={isCurrentPlan ? 'not-allowed' : 'pointer'}
|
||||
_hover={
|
||||
!isCurrentPlan
|
||||
? {
|
||||
transform: 'scale(1.02)',
|
||||
transform: 'translateY(-2px)',
|
||||
shadow: isPremium
|
||||
? '0 0 30px rgba(212, 175, 55, 0.4)'
|
||||
: '0 4px 12px rgba(255, 255, 255, 0.1)',
|
||||
? '0 8px 30px rgba(212, 175, 55, 0.4)'
|
||||
: '0 8px 20px rgba(255, 255, 255, 0.1)',
|
||||
bg: isPremium
|
||||
? 'linear-gradient(135deg, #E5C047 0%, #C9A52F 100%)'
|
||||
: 'rgba(255, 255, 255, 0.08)',
|
||||
}
|
||||
: {}
|
||||
}
|
||||
transition="all 0.3s"
|
||||
_active={
|
||||
!isCurrentPlan
|
||||
? {
|
||||
transform: 'translateY(0)',
|
||||
}
|
||||
: {}
|
||||
}
|
||||
transition="all 0.3s cubic-bezier(0.4, 0, 0.2, 1)"
|
||||
>
|
||||
{isCurrentPlan ? '当前套餐' : `选择 ${plan.displayName}`}
|
||||
{isCurrentPlan ? '当前套餐' : `选择${plan.displayName}`}
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
{/* 功能列表 */}
|
||||
<VStack spacing={5} align="stretch" px={3.5}>
|
||||
<VStack spacing={4} align="stretch" px={2}>
|
||||
{plan.features.map((feature: any, idx: number) => (
|
||||
<HStack key={idx} spacing={2.5} align="center">
|
||||
<Flex key={idx} align="start" gap={3}>
|
||||
<Flex
|
||||
justify="center"
|
||||
align="center"
|
||||
flexShrink={0}
|
||||
w={5}
|
||||
h={5}
|
||||
mt={0.5}
|
||||
bg={feature.enabled ? (isPremium ? '#D4AF37' : '#00ff88') : 'transparent'}
|
||||
borderRadius="full"
|
||||
boxShadow={
|
||||
feature.enabled
|
||||
? isPremium
|
||||
? '0.0625rem 0.0625rem 0.0625rem 0 rgba(212,175,55,0.30) inset, 0 0 0.625rem 0 rgba(212,175,55,0.50) inset'
|
||||
: '0.0625rem 0.0625rem 0.0625rem 0 rgba(255,255,255,0.20) inset, 0 0 0.625rem 0 rgba(255,255,255,0.50) inset'
|
||||
? '0 0 0 1px rgba(212,175,55,0.30) inset, 0 0 10px rgba(212,175,55,0.50) inset'
|
||||
: '0 0 0 1px rgba(255,255,255,0.20) inset, 0 0 10px rgba(255,255,255,0.50) inset'
|
||||
: 'none'
|
||||
}
|
||||
>
|
||||
<Icon
|
||||
as={feature.enabled ? FaCheck : FaTimes}
|
||||
color={feature.enabled ? '#000' : 'rgba(255, 255, 255, 0.3)'}
|
||||
boxSize={5}
|
||||
boxSize={3}
|
||||
/>
|
||||
</Flex>
|
||||
<Text
|
||||
fontSize="sm"
|
||||
color={feature.enabled ? 'rgba(255, 255, 255, 0.9)' : 'rgba(255, 255, 255, 0.3)'}
|
||||
color={feature.enabled ? 'rgba(255, 255, 255, 0.85)' : 'rgba(255, 255, 255, 0.35)'}
|
||||
flex={1}
|
||||
fontWeight={feature.enabled && isPremium && idx === 0 ? 'medium' : 'normal'}
|
||||
fontWeight={feature.enabled && isPremium && idx === 0 ? 'semibold' : 'normal'}
|
||||
lineHeight="1.6"
|
||||
>
|
||||
{feature.name}
|
||||
{feature.limit && (
|
||||
<Text as="span" fontSize="xs" color="#D4AF37" ml={1}>
|
||||
<Text as="span" fontSize="xs" color={isPremium ? '#E5C047' : '#00ff88'} ml={1.5} fontWeight="medium">
|
||||
({feature.limit})
|
||||
</Text>
|
||||
)}
|
||||
</Text>
|
||||
</HStack>
|
||||
</Flex>
|
||||
))}
|
||||
</VStack>
|
||||
</VStack>
|
||||
@@ -851,13 +888,127 @@ export default function SubscriptionContentNew() {
|
||||
<ModalCloseButton color="white" />
|
||||
<ModalBody pb={6}>
|
||||
{!paymentOrder ? (
|
||||
<VStack spacing={6}>
|
||||
<VStack spacing={6} align="stretch">
|
||||
{/* 价格明细 */}
|
||||
{selectedPlan && priceInfo && (
|
||||
<Box
|
||||
p={4}
|
||||
bg="rgba(255, 255, 255, 0.05)"
|
||||
borderRadius="lg"
|
||||
border="1px solid rgba(255, 255, 255, 0.1)"
|
||||
>
|
||||
<VStack spacing={3} align="stretch">
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text color="rgba(255, 255, 255, 0.7)" fontSize="sm">
|
||||
套餐: {selectedPlan?.displayName} · {selectedCycle === 'monthly' ? '月付' : selectedCycle === 'quarterly' ? '季付' : selectedCycle === 'semiannual' ? '半年付' : '年付'}
|
||||
{selectedPlan.displayName} · {selectedCycle === 'monthly' ? '月付' : selectedCycle === 'quarterly' ? '季付' : selectedCycle === 'semiannual' ? '半年付' : '年付'}
|
||||
</Text>
|
||||
<Text color="#D4AF37" fontSize="3xl" fontWeight="bold">
|
||||
¥{priceInfo?.final_amount || getCurrentPrice(selectedPlan)}
|
||||
<Text color="white" fontWeight="medium">
|
||||
¥{priceInfo.original_price?.toFixed(2) || getCurrentPrice(selectedPlan).toFixed(2)}
|
||||
</Text>
|
||||
</Flex>
|
||||
|
||||
{/* 升级抵扣价值 */}
|
||||
{priceInfo.is_upgrade && priceInfo.remaining_value > 0 && (
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text color="rgba(255, 255, 255, 0.7)" fontSize="sm">
|
||||
当前订阅剩余价值抵扣
|
||||
</Text>
|
||||
<Text color="green.400" fontWeight="medium">
|
||||
-¥{priceInfo.remaining_value.toFixed(2)}
|
||||
</Text>
|
||||
</Flex>
|
||||
)}
|
||||
|
||||
{/* 优惠码折扣 */}
|
||||
{promoCodeApplied && priceInfo.discount_amount > 0 && (
|
||||
<Flex justify="space-between" align="center">
|
||||
<HStack spacing={2}>
|
||||
<Icon as={FaCheck} color="green.400" boxSize={3} />
|
||||
<Text color="rgba(255, 255, 255, 0.7)" fontSize="sm">
|
||||
优惠码折扣
|
||||
</Text>
|
||||
</HStack>
|
||||
<Text color="green.400" fontWeight="medium">
|
||||
-¥{priceInfo.discount_amount.toFixed(2)}
|
||||
</Text>
|
||||
</Flex>
|
||||
)}
|
||||
|
||||
<Divider borderColor="rgba(255, 255, 255, 0.1)" />
|
||||
|
||||
<Flex justify="space-between" align="baseline">
|
||||
<Text fontSize="lg" fontWeight="bold" color="white">实付金额:</Text>
|
||||
<Text fontSize="2xl" fontWeight="bold" color="#D4AF37">
|
||||
¥{priceInfo.final_amount.toFixed(2)}
|
||||
</Text>
|
||||
</Flex>
|
||||
</VStack>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* 优惠码输入 */}
|
||||
{selectedPlan && (
|
||||
<Box>
|
||||
<HStack spacing={2}>
|
||||
<Input
|
||||
placeholder="输入优惠码(可选)"
|
||||
value={promoCode}
|
||||
onChange={(e) => {
|
||||
setPromoCode(e.target.value.toUpperCase());
|
||||
setPromoCodeError('');
|
||||
}}
|
||||
size="md"
|
||||
isDisabled={promoCodeApplied}
|
||||
bg="rgba(255, 255, 255, 0.05)"
|
||||
border="1px solid rgba(255, 255, 255, 0.1)"
|
||||
color="white"
|
||||
_placeholder={{ color: 'rgba(255, 255, 255, 0.4)' }}
|
||||
_hover={{ borderColor: 'rgba(212, 175, 55, 0.3)' }}
|
||||
_focus={{ borderColor: '#D4AF37', boxShadow: '0 0 0 1px #D4AF37' }}
|
||||
/>
|
||||
<Button
|
||||
bgGradient="linear-gradient(135deg, rgba(138, 43, 226, 0.8), rgba(123, 31, 162, 0.8))"
|
||||
color="white"
|
||||
onClick={handleValidatePromoCode}
|
||||
isLoading={validatingPromo}
|
||||
isDisabled={!promoCode || promoCodeApplied}
|
||||
minW="80px"
|
||||
_hover={{
|
||||
bgGradient: 'linear-gradient(135deg, rgba(138, 43, 226, 1), rgba(123, 31, 162, 1))',
|
||||
}}
|
||||
>
|
||||
应用
|
||||
</Button>
|
||||
</HStack>
|
||||
{promoCodeError && (
|
||||
<Text color="red.400" fontSize="sm" mt={2}>
|
||||
{promoCodeError}
|
||||
</Text>
|
||||
)}
|
||||
{promoCodeApplied && priceInfo && (
|
||||
<HStack
|
||||
mt={2}
|
||||
p={2}
|
||||
bg="rgba(72, 187, 120, 0.1)"
|
||||
borderRadius="md"
|
||||
border="1px solid rgba(72, 187, 120, 0.3)"
|
||||
>
|
||||
<Icon as={FaCheck} color="green.400" />
|
||||
<Text color="green.400" fontSize="sm" fontWeight="medium" flex={1}>
|
||||
优惠码已应用!节省 ¥{priceInfo.discount_amount.toFixed(2)}
|
||||
</Text>
|
||||
<Icon
|
||||
as={FaTimes}
|
||||
color="rgba(255, 255, 255, 0.5)"
|
||||
cursor="pointer"
|
||||
onClick={handleRemovePromoCode}
|
||||
_hover={{ color: 'red.400' }}
|
||||
/>
|
||||
</HStack>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Button
|
||||
w="full"
|
||||
size="lg"
|
||||
@@ -866,8 +1017,12 @@ export default function SubscriptionContentNew() {
|
||||
fontWeight="bold"
|
||||
onClick={handleCreatePaymentOrder}
|
||||
isLoading={loading}
|
||||
isDisabled={!selectedPlan}
|
||||
_hover={{
|
||||
bgGradient: 'linear-gradient(135deg, #F4E3A7, #D4AF37)',
|
||||
}}
|
||||
>
|
||||
创建支付订单
|
||||
创建微信支付订单
|
||||
</Button>
|
||||
</VStack>
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user