feat: 用户个人中心功能

- 账户余额显示和管理
- 充值功能(模拟模式)
- 退款申请功能(需管理员审核)
- 账户流水记录查看
- 会员购买记录查看
- 使用统计展示
- 新增模型:UserRecharge, UserRefund, MembershipPurchase, AccountTransaction
- User模型添加balance字段
- 导航栏添加个人中心入口
This commit is contained in:
2026-04-14 18:29:46 +08:00
parent 436ac2cb66
commit 4f33e92abf
5 changed files with 699 additions and 1 deletions

160
app.py
View File

@@ -14,7 +14,8 @@ from werkzeug.utils import secure_filename
from config import *
from models import (db, User, Translation, TranslationCache, GuestTranslation,
DataPackage, UserPackage, DynamicConfig)
DataPackage, UserPackage, DynamicConfig, UserRecharge, UserRefund,
MembershipPurchase, AccountTransaction)
from services import TranslationService, CacheService, TranslationTask
from admin import admin_bp
@@ -210,6 +211,24 @@ def pricing():
return render_template('pricing.html', plans=MEMBERSHIP_PLANS, user=user)
@app.route('/profile')
def profile():
"""个人中心"""
user = get_current_user()
if not user:
return redirect(url_for('login'))
limits = USER_LIMITS.get(user.user_type, USER_LIMITS['free'])
daily_remaining = limits['daily_translations'] - user.daily_count if limits['daily_translations'] > 0 else '无限'
max_pages = limits['max_pages'] if limits['max_pages'] > 0 else '无限'
return render_template('profile.html',
user=user,
daily_remaining=daily_remaining,
max_pages=max_pages
)
# ==================== 路由: API ====================
@app.route('/api/upload', methods=['POST'])
def upload_pdf():
@@ -552,6 +571,145 @@ def user_info():
})
# ==================== 个人中心API ====================
@app.route('/api/profile/transactions')
def get_transactions():
"""获取账户流水"""
user = get_current_user()
if not user:
return jsonify({'error': '请登录'}), 401
filter_type = request.args.get('type', 'all')
query = AccountTransaction.query.filter_by(user_id=user.id)
if filter_type != 'all':
query = query.filter_by(transaction_type=filter_type)
transactions = query.order_by(AccountTransaction.created_at.desc()).limit(50).all()
return jsonify({
'success': True,
'transactions': [t.to_dict() for t in transactions]
})
@app.route('/api/profile/purchases')
def get_purchases():
"""获取会员购买记录"""
user = get_current_user()
if not user:
return jsonify({'error': '请登录'}), 401
purchases = MembershipPurchase.query.filter_by(user_id=user.id)\
.order_by(MembershipPurchase.created_at.desc()).limit(20).all()
return jsonify({
'success': True,
'purchases': [p.to_dict() for p in purchases]
})
@app.route('/api/profile/recharge', methods=['POST'])
def recharge_balance():
"""充值"""
user = get_current_user()
if not user:
return jsonify({'error': '请登录'}), 401
data = request.json
amount = float(data.get('amount', 0))
payment_method = data.get('payment_method', 'balance')
if amount < 10:
return jsonify({'error': '充值金额最少10元'}), 400
if amount > 10000:
return jsonify({'error': '充值金额最多10000元'}), 400
balance_before = user.balance
# 创建充值记录
order_no = f"RC{datetime.now().strftime('%Y%m%d%H%M%S')}{user.id}"
recharge = UserRecharge(
user_id=user.id,
amount=amount,
balance_before=balance_before,
payment_method=payment_method,
status='completed',
order_no=order_no,
completed_at=datetime.utcnow()
)
# 更新余额
user.balance += amount
recharge.balance_after = user.balance
db.session.add(recharge)
# 创建流水记录
transaction = AccountTransaction(
user_id=user.id,
transaction_type='recharge',
amount=amount,
balance_before=balance_before,
balance_after=user.balance,
related_id=recharge.id,
related_type='recharge',
description=f'充值¥{amount}'
)
db.session.add(transaction)
db.session.commit()
return jsonify({
'success': True,
'balance': user.balance,
'recharge_id': recharge.id
})
@app.route('/api/profile/refund', methods=['POST'])
def request_refund():
"""申请退款"""
user = get_current_user()
if not user:
return jsonify({'error': '请登录'}), 401
data = request.json
amount = float(data.get('amount', 0))
reason = data.get('reason', '')
if amount <= 0:
return jsonify({'error': '退款金额必须大于0'}), 400
if amount > user.balance:
return jsonify({'error': '退款金额不能超过余额'}), 400
if not reason:
return jsonify({'error': '请填写退款原因'}), 400
balance_before = user.balance
# 创建退款申请
refund = UserRefund(
user_id=user.id,
amount=amount,
balance_before=balance_before,
reason=reason,
reason_type='user_request',
status='pending'
)
db.session.add(refund)
db.session.commit()
return jsonify({
'success': True,
'refund_id': refund.id,
'message': '退款申请已提交,等待管理员审核'
})
# ==================== 初始化 ====================
def init_app():
"""初始化应用"""