2025-07-04 19:07:35 +08:00

246 lines
7.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
购物车视图
"""
from flask import Blueprint, render_template, request, jsonify, session, redirect, url_for, flash
from app.models.cart import Cart
from app.models.product import Product, ProductInventory
from app.models.user import User
from app.utils.decorators import login_required
from config.database import db
cart_bp = Blueprint('cart', __name__, url_prefix='/cart')
@cart_bp.route('/')
@login_required
def index():
"""购物车页面"""
user_id = session['user_id']
cart_items = Cart.get_user_cart(user_id)
# 计算总价和可用商品数量
total_price = 0
available_count = 0
for item in cart_items:
if item.is_available():
total_price += item.get_total_price()
available_count += 1
return render_template('cart/index.html',
cart_items=cart_items,
total_price=total_price,
available_count=available_count)
@cart_bp.route('/add', methods=['POST'])
@login_required
def add():
"""添加商品到购物车"""
try:
user_id = session['user_id']
product_id = request.json.get('product_id')
sku_code = request.json.get('sku_code')
spec_combination = request.json.get('spec_combination', '')
quantity = request.json.get('quantity', 1)
# 验证参数
if not product_id or quantity <= 0:
return jsonify({'success': False, 'message': '参数错误'})
# 检查商品是否存在且上架
product = Product.query.filter_by(id=product_id, status=1).first()
if not product:
return jsonify({'success': False, 'message': '商品不存在或已下架'})
# 检查库存
if sku_code:
sku_info = ProductInventory.query.filter_by(sku_code=sku_code).first()
if not sku_info:
return jsonify({'success': False, 'message': 'SKU不存在'})
if sku_info.stock < quantity:
return jsonify({'success': False, 'message': f'库存不足,仅剩{sku_info.stock}'})
else:
# 如果没有指定SKU检查默认库存
default_sku = ProductInventory.query.filter_by(
product_id=product_id,
is_default=1
).first()
if default_sku and default_sku.stock < quantity:
return jsonify({'success': False, 'message': f'库存不足,仅剩{default_sku.stock}'})
# 添加到购物车
Cart.add_to_cart(
user_id=user_id,
product_id=product_id,
sku_code=sku_code,
spec_combination=spec_combination,
quantity=quantity
)
# 获取购物车数量
cart_count = Cart.get_cart_count(user_id)
return jsonify({
'success': True,
'message': '已添加到购物车',
'cart_count': cart_count
})
except Exception as e:
db.session.rollback()
return jsonify({'success': False, 'message': f'添加失败: {str(e)}'})
@cart_bp.route('/update', methods=['POST'])
@login_required
def update():
"""更新购物车商品数量"""
try:
user_id = session['user_id']
cart_id = request.json.get('cart_id')
quantity = request.json.get('quantity')
if not cart_id or quantity is None or quantity < 0:
return jsonify({'success': False, 'message': '参数错误'})
# 获取购物车项目
cart_item = Cart.query.filter_by(id=cart_id, user_id=user_id).first()
if not cart_item:
return jsonify({'success': False, 'message': '购物车项目不存在'})
if quantity == 0:
# 删除商品
db.session.delete(cart_item)
else:
# 检查库存
if cart_item.get_stock() < quantity:
return jsonify({
'success': False,
'message': f'库存不足,仅剩{cart_item.get_stock()}'
})
# 更新数量
cart_item.quantity = quantity
cart_item.updated_at = db.func.now()
db.session.commit()
# 返回更新后的信息
cart_count = Cart.get_cart_count(user_id)
total_price = Cart.get_cart_total(user_id)
return jsonify({
'success': True,
'message': '更新成功',
'cart_count': cart_count,
'total_price': total_price,
'item_total': cart_item.get_total_price() if quantity > 0 else 0
})
except Exception as e:
db.session.rollback()
return jsonify({'success': False, 'message': f'更新失败: {str(e)}'})
@cart_bp.route('/remove', methods=['POST'])
@login_required
def remove():
"""删除购物车商品"""
try:
user_id = session['user_id']
cart_id = request.json.get('cart_id')
if not cart_id:
return jsonify({'success': False, 'message': '参数错误'})
# 获取购物车项目
cart_item = Cart.query.filter_by(id=cart_id, user_id=user_id).first()
if not cart_item:
return jsonify({'success': False, 'message': '购物车项目不存在'})
db.session.delete(cart_item)
db.session.commit()
# 返回更新后的信息
cart_count = Cart.get_cart_count(user_id)
total_price = Cart.get_cart_total(user_id)
return jsonify({
'success': True,
'message': '删除成功',
'cart_count': cart_count,
'total_price': total_price
})
except Exception as e:
db.session.rollback()
return jsonify({'success': False, 'message': f'删除失败: {str(e)}'})
@cart_bp.route('/clear', methods=['POST'])
@login_required
def clear():
"""清空购物车"""
try:
user_id = session['user_id']
Cart.query.filter_by(user_id=user_id).delete()
db.session.commit()
return jsonify({
'success': True,
'message': '购物车已清空'
})
except Exception as e:
db.session.rollback()
return jsonify({'success': False, 'message': f'清空失败: {str(e)}'})
@cart_bp.route('/count')
@login_required
def count():
"""获取购物车商品数量"""
user_id = session['user_id']
cart_count = Cart.get_cart_count(user_id)
return jsonify({'cart_count': cart_count})
@cart_bp.route('/checkout')
@login_required
def checkout():
"""去结算"""
user_id = session['user_id']
selected_items = request.args.getlist('items')
if not selected_items:
flash('请选择要购买的商品', 'error')
return redirect(url_for('cart.index'))
# 获取选中的购物车项目
cart_items = Cart.query.filter(
Cart.id.in_(selected_items),
Cart.user_id == user_id
).all()
if not cart_items:
flash('选中的商品不存在', 'error')
return redirect(url_for('cart.index'))
# 检查商品可用性
unavailable_items = []
for item in cart_items:
if not item.is_available():
unavailable_items.append(item.product.name)
if unavailable_items:
flash(f'以下商品库存不足或已下架:{", ".join(unavailable_items)}', 'error')
return redirect(url_for('cart.index'))
# 跳转到订单结算页面
items_param = '&'.join([f'items={item_id}' for item_id in selected_items])
return redirect(url_for('order.checkout') + '?' + items_param)