update pay function
This commit is contained in:
@@ -243,7 +243,7 @@ export default function SubscriptionContentNew() {
|
|||||||
},
|
},
|
||||||
credentials: 'include',
|
credentials: 'include',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
plan_type: selectedPlan.name,
|
plan_name: selectedPlan.name,
|
||||||
billing_cycle: selectedCycle,
|
billing_cycle: selectedCycle,
|
||||||
promo_code: promoCodeApplied ? promoCode : null,
|
promo_code: promoCodeApplied ? promoCode : null,
|
||||||
}),
|
}),
|
||||||
@@ -582,18 +582,28 @@ export default function SubscriptionContentNew() {
|
|||||||
h="100%"
|
h="100%"
|
||||||
borderRadius="20px"
|
borderRadius="20px"
|
||||||
overflow="hidden"
|
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)'}
|
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)"
|
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={
|
_before={
|
||||||
isPremium
|
isPremium
|
||||||
? {
|
? {
|
||||||
content: '""',
|
content: '""',
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: '-144px',
|
top: '50%',
|
||||||
left: '52px',
|
left: '50%',
|
||||||
width: '420px',
|
transform: 'translate(-50%, -50%)',
|
||||||
maskImage: 'radial-gradient(circle at center, black 20%, transparent 52%)',
|
width: '120%',
|
||||||
WebkitMaskImage: 'radial-gradient(circle at center, black 20%, transparent 52%)',
|
height: '120%',
|
||||||
|
background: 'radial-gradient(circle at center, rgba(212, 175, 55, 0.1) 0%, transparent 70%)',
|
||||||
pointerEvents: 'none',
|
pointerEvents: 'none',
|
||||||
zIndex: 0,
|
zIndex: 0,
|
||||||
}
|
}
|
||||||
@@ -609,26 +619,24 @@ export default function SubscriptionContentNew() {
|
|||||||
pointerEvents: 'none',
|
pointerEvents: 'none',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* 推荐标签 */}
|
{/* 套餐标题 */}
|
||||||
{plan.badge && (
|
|
||||||
<Box
|
<Box
|
||||||
position="relative"
|
position="relative"
|
||||||
zIndex={2}
|
zIndex={2}
|
||||||
py={2}
|
py={3}
|
||||||
px={8.5}
|
px={8.5}
|
||||||
fontSize="sm"
|
fontSize="lg"
|
||||||
fontWeight="bold"
|
fontWeight="bold"
|
||||||
bgGradient={
|
bgGradient={
|
||||||
isPremium
|
isPremium
|
||||||
? 'linear-gradient(to right, rgba(212, 175, 55, 0.2), rgba(212, 175, 55, 0.2))'
|
? '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"
|
borderTopRadius="20px"
|
||||||
color={isPremium ? '#D4AF37' : 'white'}
|
color={isPremium ? '#D4AF37' : 'white'}
|
||||||
>
|
>
|
||||||
{plan.displayName}
|
{plan.displayName}
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
|
||||||
|
|
||||||
<VStack
|
<VStack
|
||||||
spacing={0}
|
spacing={0}
|
||||||
@@ -636,7 +644,7 @@ export default function SubscriptionContentNew() {
|
|||||||
position="relative"
|
position="relative"
|
||||||
zIndex={3}
|
zIndex={3}
|
||||||
flex={1}
|
flex={1}
|
||||||
mt={plan.badge ? -5 : 0}
|
mt={-1}
|
||||||
p={3.5}
|
p={3.5}
|
||||||
pb={8}
|
pb={8}
|
||||||
backdropFilter={isPremium ? 'blur(32px)' : 'blur(20px)'}
|
backdropFilter={isPremium ? 'blur(32px)' : 'blur(20px)'}
|
||||||
@@ -655,108 +663,137 @@ export default function SubscriptionContentNew() {
|
|||||||
{/* 价格卡片 */}
|
{/* 价格卡片 */}
|
||||||
<Box
|
<Box
|
||||||
position="relative"
|
position="relative"
|
||||||
mb={8}
|
mb={6}
|
||||||
p={5}
|
p={6}
|
||||||
borderRadius="13px"
|
borderRadius="16px"
|
||||||
bg={isPremium ? 'rgba(255, 255, 255, 0.1)' : 'rgba(255, 255, 255, 0.02)'}
|
bg={isPremium ? 'rgba(212, 175, 55, 0.1)' : 'rgba(255, 255, 255, 0.03)'}
|
||||||
backdropFilter="blur(20px)"
|
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={{
|
_after={{
|
||||||
content: '""',
|
content: '""',
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
inset: 0,
|
inset: 0,
|
||||||
borderRadius: '13px',
|
borderRadius: '16px',
|
||||||
border: '1px solid',
|
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',
|
pointerEvents: 'none',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<HStack align="baseline" spacing={3} mb={4}>
|
<Flex align="baseline" justify="center" mb={5}>
|
||||||
<Text
|
<Text
|
||||||
fontSize="4xl"
|
fontSize="5xl"
|
||||||
fontWeight="bold"
|
fontWeight="bold"
|
||||||
bgGradient="radial-gradient(circle at center, #FFFFFF 0%, rgba(255,255,255,0.6) 100%)"
|
bgGradient="radial-gradient(circle at center, #FFFFFF 0%, rgba(255,255,255,0.6) 100%)"
|
||||||
bgClip="text"
|
bgClip="text"
|
||||||
lineHeight="1.2"
|
lineHeight="1"
|
||||||
|
letterSpacing="-0.02em"
|
||||||
>
|
>
|
||||||
¥{getCurrentPrice(plan)}
|
¥{getCurrentPrice(plan)}
|
||||||
</Text>
|
</Text>
|
||||||
<Text fontSize="sm" color="rgba(255, 255, 255, 0.7)">
|
<Text fontSize="lg" color="rgba(255, 255, 255, 0.6)" ml={2}>
|
||||||
/ {currentPriceOption?.label || '月'}
|
/ {currentPriceOption?.label || '月'}
|
||||||
</Text>
|
</Text>
|
||||||
</HStack>
|
</Flex>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
w="full"
|
w="full"
|
||||||
size="lg"
|
size="lg"
|
||||||
py={6}
|
h="56px"
|
||||||
bgGradient={
|
bg={
|
||||||
isPremium
|
isCurrentPlan
|
||||||
? 'linear-gradient(135deg, #D4AF37, #B8941F)'
|
? 'transparent'
|
||||||
: 'linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05))'
|
: 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"
|
fontWeight="bold"
|
||||||
fontSize="md"
|
fontSize="md"
|
||||||
|
borderRadius="lg"
|
||||||
onClick={() => !isCurrentPlan && handleSubscribe(plan)}
|
onClick={() => !isCurrentPlan && handleSubscribe(plan)}
|
||||||
isDisabled={isCurrentPlan}
|
isDisabled={isCurrentPlan}
|
||||||
|
cursor={isCurrentPlan ? 'not-allowed' : 'pointer'}
|
||||||
_hover={
|
_hover={
|
||||||
!isCurrentPlan
|
!isCurrentPlan
|
||||||
? {
|
? {
|
||||||
transform: 'scale(1.02)',
|
transform: 'translateY(-2px)',
|
||||||
shadow: isPremium
|
shadow: isPremium
|
||||||
? '0 0 30px rgba(212, 175, 55, 0.4)'
|
? '0 8px 30px rgba(212, 175, 55, 0.4)'
|
||||||
: '0 4px 12px rgba(255, 255, 255, 0.1)',
|
: '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>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* 功能列表 */}
|
{/* 功能列表 */}
|
||||||
<VStack spacing={5} align="stretch" px={3.5}>
|
<VStack spacing={4} align="stretch" px={2}>
|
||||||
{plan.features.map((feature: any, idx: number) => (
|
{plan.features.map((feature: any, idx: number) => (
|
||||||
<HStack key={idx} spacing={2.5} align="center">
|
<Flex key={idx} align="start" gap={3}>
|
||||||
<Flex
|
<Flex
|
||||||
justify="center"
|
justify="center"
|
||||||
align="center"
|
align="center"
|
||||||
flexShrink={0}
|
flexShrink={0}
|
||||||
w={5}
|
w={5}
|
||||||
h={5}
|
h={5}
|
||||||
|
mt={0.5}
|
||||||
bg={feature.enabled ? (isPremium ? '#D4AF37' : '#00ff88') : 'transparent'}
|
bg={feature.enabled ? (isPremium ? '#D4AF37' : '#00ff88') : 'transparent'}
|
||||||
borderRadius="full"
|
borderRadius="full"
|
||||||
boxShadow={
|
boxShadow={
|
||||||
feature.enabled
|
feature.enabled
|
||||||
? isPremium
|
? 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 0 0 1px rgba(212,175,55,0.30) inset, 0 0 10px 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(255,255,255,0.20) inset, 0 0 10px rgba(255,255,255,0.50) inset'
|
||||||
: 'none'
|
: 'none'
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
as={feature.enabled ? FaCheck : FaTimes}
|
as={feature.enabled ? FaCheck : FaTimes}
|
||||||
color={feature.enabled ? '#000' : 'rgba(255, 255, 255, 0.3)'}
|
color={feature.enabled ? '#000' : 'rgba(255, 255, 255, 0.3)'}
|
||||||
boxSize={5}
|
boxSize={3}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Text
|
<Text
|
||||||
fontSize="sm"
|
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}
|
flex={1}
|
||||||
fontWeight={feature.enabled && isPremium && idx === 0 ? 'medium' : 'normal'}
|
fontWeight={feature.enabled && isPremium && idx === 0 ? 'semibold' : 'normal'}
|
||||||
|
lineHeight="1.6"
|
||||||
>
|
>
|
||||||
{feature.name}
|
{feature.name}
|
||||||
{feature.limit && (
|
{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})
|
({feature.limit})
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
</Text>
|
</Text>
|
||||||
</HStack>
|
</Flex>
|
||||||
))}
|
))}
|
||||||
</VStack>
|
</VStack>
|
||||||
</VStack>
|
</VStack>
|
||||||
@@ -851,13 +888,127 @@ export default function SubscriptionContentNew() {
|
|||||||
<ModalCloseButton color="white" />
|
<ModalCloseButton color="white" />
|
||||||
<ModalBody pb={6}>
|
<ModalBody pb={6}>
|
||||||
{!paymentOrder ? (
|
{!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">
|
<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>
|
||||||
<Text color="#D4AF37" fontSize="3xl" fontWeight="bold">
|
<Text color="white" fontWeight="medium">
|
||||||
¥{priceInfo?.final_amount || getCurrentPrice(selectedPlan)}
|
¥{priceInfo.original_price?.toFixed(2) || getCurrentPrice(selectedPlan).toFixed(2)}
|
||||||
</Text>
|
</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
|
<Button
|
||||||
w="full"
|
w="full"
|
||||||
size="lg"
|
size="lg"
|
||||||
@@ -866,8 +1017,12 @@ export default function SubscriptionContentNew() {
|
|||||||
fontWeight="bold"
|
fontWeight="bold"
|
||||||
onClick={handleCreatePaymentOrder}
|
onClick={handleCreatePaymentOrder}
|
||||||
isLoading={loading}
|
isLoading={loading}
|
||||||
|
isDisabled={!selectedPlan}
|
||||||
|
_hover={{
|
||||||
|
bgGradient: 'linear-gradient(135deg, #F4E3A7, #D4AF37)',
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
创建支付订单
|
创建微信支付订单
|
||||||
</Button>
|
</Button>
|
||||||
</VStack>
|
</VStack>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
Reference in New Issue
Block a user