feat: 用户个人中心功能
- 账户余额显示和管理 - 充值功能(模拟模式) - 退款申请功能(需管理员审核) - 账户流水记录查看 - 会员购买记录查看 - 使用统计展示 - 新增模型:UserRecharge, UserRefund, MembershipPurchase, AccountTransaction - User模型添加balance字段 - 导航栏添加个人中心入口
This commit is contained in:
160
app.py
160
app.py
@@ -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():
|
||||
"""初始化应用"""
|
||||
|
||||
Reference in New Issue
Block a user