Merge branch 'feature_bugfix/251201_py_h5_ui' of https://git.valuefrontier.cn/vf/vf_react into feature_bugfix/251201_py_h5_ui

This commit is contained in:
2025-12-17 13:53:21 +08:00
2 changed files with 99 additions and 2 deletions

View File

@@ -32,6 +32,8 @@ import {
Input,
InputGroup,
InputRightElement,
Checkbox,
Link as ChakraLink,
} from '@chakra-ui/react';
import React, { useState, useEffect } from 'react';
import { logger } from '../../utils/logger';
@@ -55,6 +57,12 @@ import {
} from 'react-icons/fa';
import { getApiBase } from '../../utils/apiConfig';
// 会员协议 URL 配置
const AGREEMENT_URLS = {
pro: 'https://valuefrontier.cn/htmls/pro-member-agreement.html',
max: 'https://valuefrontier.cn/htmls/max-member-agreement.html',
};
export default function SubscriptionContent() {
// Auth context
const { user } = useAuth();
@@ -97,6 +105,9 @@ export default function SubscriptionContent() {
const [validatingPromo, setValidatingPromo] = useState(false);
const [priceInfo, setPriceInfo] = useState(null); // 价格信息(包含升级计算)
// 会员协议确认状态
const [agreementChecked, setAgreementChecked] = useState(false);
// 加载订阅套餐数据
useEffect(() => {
fetchSubscriptionPlans();
@@ -286,6 +297,9 @@ export default function SubscriptionContent() {
setSelectedPlan(plan);
// 切换套餐时重置协议勾选状态
setAgreementChecked(false);
// 计算价格(包含升级判断)
await calculatePrice(plan, selectedCycle, promoCodeApplied ? promoCode : null);
@@ -1603,11 +1617,45 @@ export default function SubscriptionContent() {
</Box>
)}
{/* 会员协议确认 */}
<Checkbox
isChecked={agreementChecked}
onChange={(e) => setAgreementChecked(e.target.checked)}
colorScheme="green"
size="md"
>
<Text fontSize="sm" color={secondaryText}>
我已阅读并同意
<ChakraLink
href={AGREEMENT_URLS[selectedPlan?.name?.toLowerCase()] || AGREEMENT_URLS.pro}
isExternal
color="blue.500"
textDecoration="underline"
mx={1}
onClick={(e) => e.stopPropagation()}
>
{selectedPlan?.name?.toLowerCase() === 'max' ? 'MAX' : 'PRO'}会员服务协议
</ChakraLink>
</Text>
</Checkbox>
<Button
colorScheme="green"
size="lg"
leftIcon={<Icon as={FaWeixin} />}
onClick={handleCreateOrder}
onClick={() => {
if (!agreementChecked) {
toast({
title: '请先阅读并同意会员服务协议',
status: 'warning',
duration: 3000,
isClosable: true,
position: 'top',
});
return;
}
handleCreateOrder();
}}
isLoading={loading}
loadingText="创建订单中..."
isDisabled={!selectedPlan}

View File

@@ -23,6 +23,8 @@ import {
Icon,
Container,
useBreakpointValue,
Checkbox,
Link as ChakraLink,
} from '@chakra-ui/react';
import {
FaWeixin,
@@ -46,6 +48,12 @@ import { useSubscriptionEvents } from '../../hooks/useSubscriptionEvents';
import { subscriptionConfig, themeColors } from '../../views/Pages/Account/subscription-content';
import { getApiBase } from '../../utils/apiConfig';
// 会员协议 URL 配置
const AGREEMENT_URLS = {
pro: 'https://valuefrontier.cn/htmls/pro-member-agreement.html',
max: 'https://valuefrontier.cn/htmls/max-member-agreement.html',
};
// 计费周期选择器组件 - 移动端垂直布局(年付在上),桌面端水平布局
interface CycleSelectorProps {
options: any[];
@@ -154,6 +162,9 @@ export default function SubscriptionContentNew() {
const [openFaqIndex, setOpenFaqIndex] = useState(null);
// 会员协议确认状态
const [agreementChecked, setAgreementChecked] = useState(false);
const { isOpen, onOpen, onClose } = useDisclosure();
const toast = useToast();
@@ -418,6 +429,10 @@ export default function SubscriptionContentNew() {
);
setSelectedPlan(plan);
// 切换套餐时重置协议勾选状态
setAgreementChecked(false);
await calculatePrice(plan, selectedCycle, promoCodeApplied ? promoCode : null);
onOpen();
};
@@ -1607,6 +1622,28 @@ export default function SubscriptionContentNew() {
</Box>
)}
{/* 会员协议确认 */}
<Checkbox
isChecked={agreementChecked}
onChange={(e) => setAgreementChecked(e.target.checked)}
colorScheme="green"
size="md"
>
<Text fontSize="sm" color="rgba(255, 255, 255, 0.7)">
<ChakraLink
href={AGREEMENT_URLS[(selectedPlan as any)?.name?.toLowerCase()] || AGREEMENT_URLS.pro}
isExternal
color="#3182CE"
textDecoration="underline"
mx={1}
onClick={(e) => e.stopPropagation()}
>
{(selectedPlan as any)?.name?.toLowerCase() === 'max' ? 'MAX' : 'PRO'}
</ChakraLink>
</Text>
</Checkbox>
<Button
w="full"
size="lg"
@@ -1615,7 +1652,19 @@ export default function SubscriptionContentNew() {
: 'linear-gradient(135deg, #07C160, #059048)'}
color="white"
fontWeight="bold"
onClick={handleCreatePaymentOrder}
onClick={() => {
if (!agreementChecked) {
toast({
title: '请先阅读并同意会员服务协议',
status: 'warning',
duration: 3000,
isClosable: true,
position: 'top',
});
return;
}
handleCreatePaymentOrder();
}}
isLoading={loading}
isDisabled={!selectedPlan}
leftIcon={paymentMethod === 'alipay'