update pay function
This commit is contained in:
@@ -53,6 +53,7 @@ export default function SubscriptionContentNew() {
|
||||
|
||||
const [selectedCycle, setSelectedCycle] = useState('yearly');
|
||||
const [selectedPlan, setSelectedPlan] = useState(null);
|
||||
const [subscriptionPlans, setSubscriptionPlans] = useState([]);
|
||||
const [priceInfo, setPriceInfo] = useState(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [promoCode, setPromoCode] = useState('');
|
||||
@@ -94,6 +95,46 @@ export default function SubscriptionContentNew() {
|
||||
};
|
||||
}, []);
|
||||
|
||||
// 组件加载时获取套餐数据
|
||||
useEffect(() => {
|
||||
fetchSubscriptionPlans();
|
||||
}, []);
|
||||
|
||||
const fetchSubscriptionPlans = async () => {
|
||||
try {
|
||||
logger.debug('SubscriptionContentNew', '正在获取订阅套餐');
|
||||
const response = await fetch('/api/subscription/plans');
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success && Array.isArray(data.data)) {
|
||||
const validPlans = data.data.filter(
|
||||
(plan: any) =>
|
||||
plan &&
|
||||
plan.name &&
|
||||
typeof plan.monthly_price === 'number' &&
|
||||
typeof plan.yearly_price === 'number'
|
||||
);
|
||||
logger.debug('SubscriptionContentNew', '套餐加载成功', {
|
||||
status: response.status,
|
||||
validPlansCount: validPlans.length,
|
||||
});
|
||||
setSubscriptionPlans(validPlans);
|
||||
} else {
|
||||
logger.warn('SubscriptionContentNew', '套餐数据格式异常', { data });
|
||||
setSubscriptionPlans([]);
|
||||
}
|
||||
} else {
|
||||
logger.error('SubscriptionContentNew', 'fetchSubscriptionPlans', new Error(`HTTP ${response.status}`));
|
||||
setSubscriptionPlans([]);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('SubscriptionContentNew', 'fetchSubscriptionPlans', error);
|
||||
setSubscriptionPlans([]);
|
||||
}
|
||||
};
|
||||
|
||||
const handlePaymentExpire = () => {
|
||||
stopAutoPaymentCheck();
|
||||
toast({
|
||||
@@ -377,13 +418,63 @@ export default function SubscriptionContentNew() {
|
||||
}
|
||||
};
|
||||
|
||||
// 合并数据库数据和前端配置
|
||||
const getMergedPlans = () => {
|
||||
// 如果数据库还没有加载数据,使用静态配置
|
||||
if (subscriptionPlans.length === 0) {
|
||||
return subscriptionConfig.plans;
|
||||
}
|
||||
|
||||
// 合并数据库价格和前端UI配置
|
||||
return subscriptionConfig.plans.map((configPlan: any) => {
|
||||
const dbPlan = subscriptionPlans.find((p: any) => p.name === configPlan.name);
|
||||
|
||||
if (!dbPlan) {
|
||||
return configPlan; // 如果数据库中没有,使用前端配置
|
||||
}
|
||||
|
||||
// 解析数据库中的 pricing_options JSON
|
||||
let pricingOptions = configPlan.pricingOptions;
|
||||
if (dbPlan.pricing_options) {
|
||||
try {
|
||||
const parsedOptions = typeof dbPlan.pricing_options === 'string'
|
||||
? JSON.parse(dbPlan.pricing_options)
|
||||
: dbPlan.pricing_options;
|
||||
|
||||
if (Array.isArray(parsedOptions) && parsedOptions.length > 0) {
|
||||
pricingOptions = parsedOptions.map((opt: any) => ({
|
||||
cycleKey: opt.cycle_key,
|
||||
label: opt.label,
|
||||
months: opt.months,
|
||||
price: parseFloat(opt.price),
|
||||
originalPrice: opt.original_price ? parseFloat(opt.original_price) : null,
|
||||
discountPercent: opt.discount_percent || 0,
|
||||
}));
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('SubscriptionContentNew', '解析pricing_options失败', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 合并数据,数据库价格优先
|
||||
return {
|
||||
...configPlan,
|
||||
monthly_price: dbPlan.monthly_price,
|
||||
yearly_price: dbPlan.yearly_price,
|
||||
pricingOptions: pricingOptions,
|
||||
displayName: dbPlan.display_name || configPlan.displayName,
|
||||
description: dbPlan.description || configPlan.description,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const getCurrentPrice = (plan: any) => {
|
||||
if (!plan || plan.name === 'free') return 0;
|
||||
|
||||
const option = plan.pricingOptions?.find(
|
||||
(opt: any) => opt.cycleKey === selectedCycle
|
||||
);
|
||||
return option ? option.price : plan.pricingOptions[0]?.price || 0;
|
||||
return option ? option.price : plan.pricingOptions?.[0]?.price || 0;
|
||||
};
|
||||
|
||||
const getCurrentPriceOption = (plan: any) => {
|
||||
@@ -488,7 +579,7 @@ export default function SubscriptionContentNew() {
|
||||
flexWrap="wrap"
|
||||
justify="center"
|
||||
>
|
||||
{subscriptionConfig.plans[1]?.pricingOptions?.map((option: any, index: number) => (
|
||||
{getMergedPlans()[1]?.pricingOptions?.map((option: any, index: number) => (
|
||||
<Box key={index} position="relative">
|
||||
{option.discountPercent > 0 && (
|
||||
<Badge
|
||||
@@ -534,7 +625,7 @@ export default function SubscriptionContentNew() {
|
||||
</HStack>
|
||||
|
||||
{(() => {
|
||||
const currentOption = subscriptionConfig.plans[1]?.pricingOptions?.find(
|
||||
const currentOption = getMergedPlans()[1]?.pricingOptions?.find(
|
||||
(opt: any) => opt.cycleKey === selectedCycle
|
||||
);
|
||||
if (currentOption && currentOption.discountPercent > 0) {
|
||||
@@ -560,7 +651,7 @@ export default function SubscriptionContentNew() {
|
||||
maxW="1200px"
|
||||
mx="auto"
|
||||
>
|
||||
{subscriptionConfig.plans.slice(1).map((plan: any, index: number) => {
|
||||
{getMergedPlans().slice(1).map((plan: any, index: number) => {
|
||||
const IconComponent = getIconComponent(plan.icon);
|
||||
const currentPriceOption = getCurrentPriceOption(plan);
|
||||
const isCurrentPlan =
|
||||
|
||||
Reference in New Issue
Block a user