187 lines
6.4 KiB
Python
187 lines
6.4 KiB
Python
"""
|
||
主页面视图
|
||
"""
|
||
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/<int:product_id>')
|
||
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/<int:category_id>')
|
||
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')
|