From b0b227a5efc95f4ce870ba10c1c6dc51bdb5995f Mon Sep 17 00:00:00 2001 From: zzlgreat Date: Thu, 20 Nov 2025 08:18:02 +0800 Subject: [PATCH] update pay function --- app.py | 78 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 26 deletions(-) diff --git a/app.py b/app.py index 08f7728a..fcbdcfbe 100755 --- a/app.py +++ b/app.py @@ -1372,35 +1372,61 @@ def calculate_subscription_price_simple(user_id, to_plan_name, to_cycle, promo_c if current_sub.end_date and current_sub.end_date > datetime.utcnow(): # 获取当前套餐的原始价格 current_plan_obj = SubscriptionPlan.query.filter_by(name=current_plan, is_active=True).first() - if current_plan_obj and current_plan_obj.pricing_options: - try: - pricing_opts = json.loads(current_plan_obj.pricing_options) - current_price = None - for opt in pricing_opts: - if opt.get('cycle_key') == current_cycle: - current_price = float(opt.get('price', 0)) - break + if current_plan_obj: + current_price = None - if current_price and current_price > 0: - # 计算剩余天数 - remaining_days = (current_sub.end_date - datetime.utcnow()).days + # 优先从 pricing_options 获取价格 + if current_plan_obj.pricing_options: + try: + pricing_opts = json.loads(current_plan_obj.pricing_options) - # 计算总天数 - cycle_days_map = { - 'monthly': 30, - 'quarterly': 90, - 'semiannual': 180, - 'yearly': 365 - } - total_days = cycle_days_map.get(current_cycle, 30) + # 如果 current_cycle 为空或无效,根据剩余天数推断计费周期 + if not current_cycle or current_cycle.strip() == '': + remaining_days_total = (current_sub.end_date - current_sub.start_date).days if current_sub.start_date else 365 - # 计算剩余价值 - if total_days > 0 and remaining_days > 0: - remaining_value = current_price * (remaining_days / total_days) - # 实付金额 = 新套餐价格 - 剩余价值 - final_price = max(0, price - remaining_value) - except: - pass + # 根据总天数推断计费周期 + if remaining_days_total <= 35: + inferred_cycle = 'monthly' + elif remaining_days_total <= 100: + inferred_cycle = 'quarterly' + elif remaining_days_total <= 200: + inferred_cycle = 'semiannual' + else: + inferred_cycle = 'yearly' + else: + inferred_cycle = current_cycle + + for opt in pricing_opts: + if opt.get('cycle_key') == inferred_cycle: + current_price = float(opt.get('price', 0)) + current_cycle = inferred_cycle # 更新周期信息 + break + except: + pass + + # 如果 pricing_options 中没找到,使用 yearly_price 作为默认 + if current_price is None or current_price <= 0: + current_price = float(current_plan_obj.yearly_price) if current_plan_obj.yearly_price else 0 + current_cycle = 'yearly' + + if current_price and current_price > 0: + # 计算剩余天数 + remaining_days = (current_sub.end_date - datetime.utcnow()).days + + # 计算总天数 + cycle_days_map = { + 'monthly': 30, + 'quarterly': 90, + 'semiannual': 180, + 'yearly': 365 + } + total_days = cycle_days_map.get(current_cycle, 365) + + # 计算剩余价值 + if total_days > 0 and remaining_days > 0: + remaining_value = current_price * (remaining_days / total_days) + # 实付金额 = 新套餐价格 - 剩余价值 + final_price = max(0, price - remaining_value) elif current_plan == 'max' and to_plan_name == 'pro': # 降级:Max → Pro,到期后切换,全价购买 is_downgrade = True