246 lines
7.4 KiB
Python
246 lines
7.4 KiB
Python
"""
|
||
购物车视图
|
||
"""
|
||
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)
|
||
|