5 Commits

Author SHA1 Message Date
bae0ba9a6d feat: 套餐按钮根据用户会员状态显示
- 当前套餐:绿色disabled按钮
- 已升级:灰色disabled按钮
- 未登录/低等级:显示购买按钮
- pricing路由传递user对象
2026-04-14 18:18:42 +08:00
c1e929fc8a fix: 四个套餐卡片一排显示 (col-lg-3) 2026-04-14 18:13:16 +08:00
5572e41d08 feat: 更新会员套餐页面权益显示
- 添加免费用户卡片,显示可用权益
- 免费用户:重新翻译、导出PDF、对比查看
- 基础会员:增加对比查看功能
- 专业会员:完整功能列表
- 功能对比表同步更新
2026-04-14 18:09:25 +08:00
84bd151431 fix: 调整免费用户权益
- 新增:不满意重新翻译、导出PDF格式
- 移除:原文译文对比查看(改为VIP专属)
2026-04-14 18:06:11 +08:00
ad4f86b507 feat: 导航栏下方添加显眼会员状态栏
- guest: 灰色提示登录注册
- free: 蓝色提示升级
- vip_basic: 绿色显示权益和到期
- vip_pro: 金色显示权益和升级提示
- vip_enterprise: 深色显示无限权益
- admin: 红色显示后台入口
2026-04-14 18:02:42 +08:00
4 changed files with 103 additions and 8 deletions

3
app.py
View File

@@ -206,7 +206,8 @@ def history():
@app.route('/pricing')
def pricing():
"""会员定价页"""
return render_template('pricing.html', plans=MEMBERSHIP_PLANS)
user = get_current_user()
return render_template('pricing.html', plans=MEMBERSHIP_PLANS, user=user)
# ==================== 路由: API ====================

View File

@@ -39,7 +39,7 @@ USER_LIMITS = {
"daily_translations": 10,
"max_pages": 50,
"max_file_size": 30 * 1024 * 1024, # 30MB
"features": ["basic_translate", "compare_view", "retranslate", "history"],
"features": ["basic_translate", "retranslate", "export_pdf", "history"],
},
"vip_basic": { # 基础会员 (月付 ¥29)
"daily_translations": 50,

View File

@@ -37,6 +37,45 @@
</div>
</nav>
<!-- 会员状态栏 -->
{% if user %}
{% if user.user_type == 'vip_enterprise' %}
<div class="alert alert-dark py-2 mb-0 text-center">
<strong>👑 企业会员</strong> |
无限翻译次数 | 到期:{{ user.membership_expire.strftime('%Y-%m-%d') if user.membership_expire else '永久' }}
</div>
{% elif user.user_type == 'vip_pro' %}
<div class="alert alert-warning py-2 mb-0 text-center">
<strong>⭐ 专业会员</strong> |
每日200次 · 最多500页 | 到期:{{ user.membership_expire.strftime('%Y-%m-%d') if user.membership_expire else '永久' }}
| <a href="/pricing" class="alert-link">升级企业会员享无限</a>
</div>
{% elif user.user_type == 'vip_basic' %}
<div class="alert alert-success py-2 mb-0 text-center">
<strong>💚 基础会员</strong> |
每日50次 · 最多100页 | 到期:{{ user.membership_expire.strftime('%Y-%m-%d') if user.membership_expire else '永久' }}
| <a href="/pricing" class="alert-link">升级享更多权益</a>
</div>
{% elif user.user_type == 'free' %}
<div class="alert alert-info py-2 mb-0 text-center">
<strong>👤 免费用户</strong> |
每日10次 · 最多50页 | <a href="/pricing" class="alert-link">升级会员解锁更多功能</a>
</div>
{% elif user.user_type == 'admin' %}
<div class="alert alert-danger py-2 mb-0 text-center">
<strong>🔧 管理员</strong> |
完整权限 | <a href="/admin" class="alert-link">进入后台管理</a>
</div>
{% endif %}
{% else %}
<div class="alert alert-secondary py-2 mb-0 text-center">
<strong>👁 访客模式</strong> |
每日仅3次 · 最多20页 · 功能受限 |
<a href="/login" class="alert-link">登录获取更多权益</a>
<a href="/register" class="alert-link">免费注册</a>
</div>
{% endif %}
<!-- 主内容 -->
<main class="container my-5">
<!-- 用户信息卡片 -->

View File

@@ -23,8 +23,36 @@
<h2 class="text-center mb-5">会员套餐</h2>
<div class="row justify-content-center">
<!-- 免费用户 -->
<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">¥0<small>/永久</small></div>
<ul class="features text-start">
<li>✅ 每日翻译10次</li>
<li>✅ 单文件最大50页</li>
<li>✅ 翻译历史记录</li>
<li>✅ 不满意重新翻译</li>
<li>✅ 导出PDF格式</li>
<li class="text-muted">❌ 原文译文对比</li>
<li class="text-muted">❌ 批量翻译</li>
</ul>
{% if user and user.user_type in ['free', 'vip_basic', 'vip_pro', 'vip_enterprise', 'admin'] %}
<span class="btn btn-secondary w-100 mt-3 disabled">
{% if user.user_type == 'free' %}当前套餐{% else %}已升级{% endif %}
</span>
{% else %}
<a href="/register" class="btn btn-outline-secondary w-100 mt-3">免费注册</a>
{% endif %}
</div>
</div>
</div>
<!-- 基础会员 -->
<div class="col-md-4 mb-4">
<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>
@@ -34,17 +62,25 @@
<li>✅ 每日翻译50次</li>
<li>✅ 单文件最大100页</li>
<li>✅ 翻译历史记录</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-md-4 mb-4">
<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">
<strong>推荐</strong>
@@ -57,17 +93,24 @@
<li>✅ 每日翻译200次</li>
<li>✅ 单文件最大500页</li>
<li>✅ 所有基础会员功能</li>
<li>✅ 原文译文对比查看</li>
<li>✅ 批量翻译</li>
<li>✅ 自定义术语库</li>
</ul>
{% if user and user.user_type == 'vip_pro' %}
<span class="btn btn-success w-100 mt-3 disabled">当前套餐</span>
{% elif user and user.user_type in ['vip_enterprise', 'admin'] %}
<span class="btn btn-secondary w-100 mt-3 disabled">已升级</span>
{% else %}
<button class="btn btn-primary w-100 mt-3">立即购买</button>
{% endif %}
</div>
</div>
</div>
<!-- 企业会员 -->
<div class="col-md-4 mb-4">
<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>
@@ -81,7 +124,11 @@
<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 %}
</div>
</div>
</div>
@@ -148,7 +195,7 @@
<tr>
<td>对比查看</td>
<td class="text-danger"></td>
<td class="text-success"></td>
<td class="text-danger"></td>
<td class="text-success"></td>
<td class="text-success"></td>
<td class="text-success"></td>
@@ -156,7 +203,7 @@
<tr>
<td>导出PDF</td>
<td class="text-danger"></td>
<td class="text-danger"></td>
<td class="text-success"></td>
<td class="text-success"></td>
<td class="text-success"></td>
<td class="text-success"></td>
@@ -177,6 +224,14 @@
<td class="text-success"></td>
<td class="text-success"></td>
</tr>
<tr>
<td>自定义翻译要求</td>
<td class="text-danger"></td>
<td class="text-danger"></td>
<td class="text-danger"></td>
<td class="text-danger"></td>
<td class="text-success"></td>
</tr>
<tr>
<td>API调用</td>
<td class="text-danger"></td>