""" 主页面视图 """ from flask import Blueprint, render_template, session, current_app, request, redirect, url_for from app.models.user import User from app.models.product import Product, Category from sqlalchemy import func main_bp = Blueprint('main', __name__) @main_bp.route('/') def index(): """首页""" user = None if 'user_id' in session: try: user = User.query.get(session['user_id']) if user and user.status != 1: # 用户被禁用,清除session session.pop('user_id', None) user = None except Exception as e: current_app.logger.error(f"获取用户信息失败: {str(e)}") session.pop('user_id', None) user = None # 获取热门商品(按销量排序,取前8个) hot_products = Product.query.filter_by(status=1)\ .order_by(Product.sales_count.desc())\ .limit(8).all() # 获取最新商品(按创建时间排序,取前8个) new_products = Product.query.filter_by(status=1)\ .order_by(Product.created_at.desc())\ .limit(8).all() # 获取活跃的顶级分类(用于导航) top_categories = Category.query.filter_by(is_active=1, parent_id=0)\ .order_by(Category.sort_order)\ .limit(6).all() return render_template('index.html', user=user, hot_products=hot_products, new_products=new_products, top_categories=top_categories) @main_bp.route('/products') def product_list(): """商品列表页面""" page = request.args.get('page', 1, type=int) per_page = 20 # 基础查询:只显示上架商品 query = Product.query.filter_by(status=1) # 分类筛选 category_id = request.args.get('category_id', type=int) if category_id: # 获取该分类及其所有子分类的商品 category = Category.query.get_or_404(category_id) if category.level == 1: # 一级分类,查找所有子分类 subcategory_ids = [c.id for c in Category.query.filter_by(parent_id=category_id).all()] subcategory_ids.append(category_id) query = query.filter(Product.category_id.in_(subcategory_ids)) else: query = query.filter_by(category_id=category_id) # 搜索功能 search = request.args.get('search', '').strip() if search: query = query.filter(Product.name.like(f'%{search}%')) # 价格筛选 min_price = request.args.get('min_price', type=float) max_price = request.args.get('max_price', type=float) if min_price is not None: query = query.filter(Product.price >= min_price) if max_price is not None: query = query.filter(Product.price <= max_price) # 排序 sort = request.args.get('sort', 'default') if sort == 'price_asc': query = query.order_by(Product.price.asc()) elif sort == 'price_desc': query = query.order_by(Product.price.desc()) elif sort == 'sales': query = query.order_by(Product.sales_count.desc()) elif sort == 'newest': query = query.order_by(Product.created_at.desc()) else: # default query = query.order_by(Product.created_at.desc()) # 分页 products = query.paginate(page=page, per_page=per_page, error_out=False) # 获取所有分类用于侧边栏 categories = Category.query.filter_by(is_active=1, parent_id=0)\ .order_by(Category.sort_order).all() # 当前分类信息 current_category = None if category_id: current_category = Category.query.get(category_id) return render_template('product/list.html', products=products, categories=categories, current_category=current_category, search=search, category_id=category_id, sort=sort, min_price=min_price, max_price=max_price) @main_bp.route('/products/') def product_detail(product_id): """商品详情页面""" product = Product.query.filter_by(id=product_id, status=1).first_or_404() # 增加浏览量 try: product.view_count += 1 from config.database import db db.session.commit() except Exception as e: current_app.logger.error(f"更新浏览量失败: {str(e)}") # 获取商品图片(按排序) images = product.images if images: images = sorted(images, key=lambda x: x.sort_order) # 获取商品库存信息并转换为字典 inventory_list = product.inventory inventory_data = [] if inventory_list: for inventory in inventory_list: inventory_data.append({ 'id': inventory.id, 'sku_code': inventory.sku_code, 'spec_combination': inventory.spec_combination, 'price_adjustment': float(inventory.price_adjustment) if inventory.price_adjustment else 0, 'stock': inventory.stock, 'warning_stock': inventory.warning_stock, 'is_default': inventory.is_default, 'status': inventory.status, 'final_price': inventory.get_final_price() }) # 获取推荐商品(同分类的其他商品) recommended_products = Product.query.filter( Product.category_id == product.category_id, Product.id != product.id, Product.status == 1 ).order_by(Product.sales_count.desc()).limit(4).all() return render_template('product/detail.html', product=product, images=images, inventory_list=inventory_list, inventory_data=inventory_data, recommended_products=recommended_products) @main_bp.route('/category/') def category_products(category_id): """分类商品页面(重定向到商品列表)""" return redirect(url_for('main.product_list', category_id=category_id)) @main_bp.route('/search') def search(): """搜索页面(重定向到商品列表)""" search_query = request.args.get('q', '').strip() return redirect(url_for('main.product_list', search=search_query)) @main_bp.route('/about') def about(): """关于我们""" return render_template('about.html')