feat: pricing页面使用后台管理配置的会员套餐数据

- 从数据库MembershipPlanConfig读取动态配置
- 支持推荐标记、原价显示
- 按用户状态显示按钮
This commit is contained in:
2026-04-14 18:39:04 +08:00
parent 4f33e92abf
commit ee5e672901
2 changed files with 52 additions and 69 deletions

35
app.py
View File

@@ -15,7 +15,7 @@ from werkzeug.utils import secure_filename
from config import * from config import *
from models import (db, User, Translation, TranslationCache, GuestTranslation, from models import (db, User, Translation, TranslationCache, GuestTranslation,
DataPackage, UserPackage, DynamicConfig, UserRecharge, UserRefund, DataPackage, UserPackage, DynamicConfig, UserRecharge, UserRefund,
MembershipPurchase, AccountTransaction) MembershipPurchase, AccountTransaction, MembershipPlanConfig, UserTypeConfig)
from services import TranslationService, CacheService, TranslationTask from services import TranslationService, CacheService, TranslationTask
from admin import admin_bp from admin import admin_bp
@@ -208,7 +208,38 @@ def history():
def pricing(): def pricing():
"""会员定价页""" """会员定价页"""
user = get_current_user() user = get_current_user()
return render_template('pricing.html', plans=MEMBERSHIP_PLANS, user=user)
# 从数据库读取动态配置的会员套餐
db_plans = MembershipPlanConfig.query.filter_by(is_active=True)\
.order_by(MembershipPlanConfig.sort_order).all()
# 如果数据库没有配置,使用默认配置
if not db_plans:
plans = MEMBERSHIP_PLANS
else:
# 转换为字典格式供模板使用
plans = {}
for plan in db_plans:
plans[plan.plan_key] = {
'name': plan.display_name,
'price': plan.price,
'original_price': plan.original_price,
'period': plan.period,
'period_days': plan.period_days,
'description': plan.description,
'is_recommended': plan.is_recommended,
'user_type_key': plan.user_type_key,
}
# 添加免费用户套餐(固定)
plans['free'] = {
'name': '免费用户',
'price': 0,
'period': 'forever',
'description': '基础翻译功能',
}
return render_template('pricing.html', plans=plans, user=user, db_plans=db_plans)
@app.route('/profile') @app.route('/profile')

View File

@@ -41,7 +41,7 @@
<h2 class="text-center mb-5">会员套餐</h2> <h2 class="text-center mb-5">会员套餐</h2>
<div class="row justify-content-center"> <div class="row justify-content-center">
<!-- 免费用户 --> <!-- 免费用户(固定) -->
<div class="col-lg-3 col-md-6 mb-4"> <div class="col-lg-3 col-md-6 mb-4">
<div class="card pricing-card h-100"> <div class="card pricing-card h-100">
<div class="card-body text-center"> <div class="card-body text-center">
@@ -69,87 +69,39 @@
</div> </div>
</div> </div>
<!-- 基础会员 --> <!-- 动态套餐 -->
{% for plan in db_plans if plan.is_active %}
<div class="col-lg-3 col-md-6 mb-4"> <div class="col-lg-3 col-md-6 mb-4">
<div class="card pricing-card h-100"> <div class="card pricing-card h-100 {% if plan.is_recommended %}border-primary{% endif %}">
<div class="card-body text-center"> {% if plan.is_recommended %}
<h4 class="card-title">基础会员</h4>
<div class="price my-3">¥29<small>/月</small></div>
<ul class="features text-start">
<li>✅ 每日翻译50次</li>
<li>✅ 单文件最大100页</li>
<li>✅ 翻译历史记录</li>
<li>✅ 不满意重新翻译</li>
<li>✅ 原文译文对比查看</li>
<li>✅ 导出PDF格式</li>
<li>✅ 优先处理队列</li>
</ul>
{% if user and user.user_type == 'vip_basic' %}
<span class="btn btn-success w-100 mt-3 disabled">当前套餐</span>
{% elif user and user.user_type in ['vip_pro', 'vip_enterprise', 'admin'] %}
<span class="btn btn-secondary w-100 mt-3 disabled">已升级</span>
{% else %}
<button class="btn btn-outline-primary w-100 mt-3">立即购买</button>
{% endif %}
</div>
</div>
</div>
<!-- 专业会员 -->
<div class="col-lg-3 col-md-6 mb-4">
<div class="card pricing-card h-100 border-primary">
<div class="card-header bg-primary text-white text-center"> <div class="card-header bg-primary text-white text-center">
<strong>推荐</strong> <strong>推荐</strong>
</div> </div>
{% endif %}
<div class="card-body text-center"> <div class="card-body text-center">
<h4 class="card-title">专业会员</h4> <h4 class="card-title">{{ plan.display_name }}</h4>
<div class="price my-3">¥99<small>/月</small></div> <div class="price my-3">
¥{{ plan.price }}<small>/{{ plan.period }}</small>
{% if plan.original_price and plan.original_price > plan.price %}
<br><span class="text-muted" style="font-size:0.8em">原价¥{{ plan.original_price }}</span>
{% endif %}
</div>
<ul class="features text-start"> <p class="text-muted">{{ plan.description }}</p>
<li>✅ 每日翻译200次</li>
<li>✅ 单文件最大500页</li>
<li>✅ 所有基础会员功能</li>
<li>✅ 原文译文对比查看</li>
<li>✅ 批量翻译</li>
<li>✅ 自定义术语库</li>
</ul>
{% if user and user.user_type == 'vip_pro' %} {% if user and user.user_type == plan.user_type_key %}
<span class="btn btn-success w-100 mt-3 disabled">当前套餐</span> <span class="btn btn-success w-100 mt-3 disabled">当前套餐</span>
{% elif user and user.user_type in ['vip_enterprise', 'admin'] %} {% elif user and user.user_type in ['vip_enterprise', 'admin'] %}
<span class="btn btn-secondary w-100 mt-3 disabled">已升级</span> <span class="btn btn-secondary w-100 mt-3 disabled">已升级</span>
{% elif user and user.user_type in ['vip_pro', 'vip_basic'] and plan.user_type_key not in ['vip_basic'] %}
<span class="btn btn-secondary w-100 mt-3 disabled">已升级</span>
{% else %} {% else %}
<button class="btn btn-primary w-100 mt-3">立即购买</button> <button class="btn {% if plan.is_recommended %}btn-primary{% else %}btn-outline-primary{% endif %} w-100 mt-3">立即购买</button>
{% endif %}
</div>
</div>
</div>
<!-- 企业会员 -->
<div class="col-lg-3 col-md-6 mb-4">
<div class="card pricing-card h-100">
<div class="card-body text-center">
<h4 class="card-title">企业会员</h4>
<div class="price my-3">¥999<small>/年</small></div>
<ul class="features text-start">
<li>✅ 翻译次数无限制</li>
<li>✅ 页数无限制</li>
<li>✅ 所有功能解锁</li>
<li>✅ 专属客服支持</li>
<li>✅ API接口调用</li>
</ul>
{% if user and user.user_type in ['vip_enterprise', 'admin'] %}
<span class="btn btn-success w-100 mt-3 disabled">当前套餐</span>
{% else %}
<button class="btn btn-outline-primary w-100 mt-3">联系购买</button>
{% endif %} {% endif %}
</div> </div>
</div> </div>
</div> </div>
{% endfor %}
</div> </div>
<!-- 功能对比表 --> <!-- 功能对比表 -->