103 lines
3.4 KiB
Python
103 lines
3.4 KiB
Python
"""
|
|
用户收藏模型
|
|
"""
|
|
from datetime import datetime
|
|
from config.database import db
|
|
from app.models.product import Product
|
|
from app.models.user import User
|
|
|
|
|
|
class UserFavorite(db.Model):
|
|
__tablename__ = 'user_favorites'
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
|
|
product_id = db.Column(db.Integer, db.ForeignKey('products.id'), nullable=False)
|
|
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
|
|
|
# 关联关系
|
|
user = db.relationship('User', backref='favorites')
|
|
product = db.relationship('Product', backref='favorited_by')
|
|
|
|
# 唯一约束
|
|
__table_args__ = (db.UniqueConstraint('user_id', 'product_id', name='uk_user_product'),)
|
|
|
|
def to_dict(self):
|
|
"""转换为字典"""
|
|
return {
|
|
'id': self.id,
|
|
'user_id': self.user_id,
|
|
'product_id': self.product_id,
|
|
'created_at': self.created_at.isoformat() if self.created_at else None,
|
|
'product': {
|
|
'id': self.product.id,
|
|
'name': self.product.name,
|
|
'price': float(self.product.price),
|
|
'main_image': self.product.main_image,
|
|
'status': self.product.status,
|
|
'sales_count': self.product.sales_count
|
|
} if self.product else None
|
|
}
|
|
|
|
@classmethod
|
|
def is_favorited(cls, user_id, product_id):
|
|
"""检查用户是否收藏了某商品"""
|
|
return cls.query.filter_by(user_id=user_id, product_id=product_id).first() is not None
|
|
|
|
@classmethod
|
|
def add_favorite(cls, user_id, product_id):
|
|
"""添加收藏"""
|
|
# 检查是否已存在
|
|
existing = cls.query.filter_by(user_id=user_id, product_id=product_id).first()
|
|
if existing:
|
|
return False, "商品已在收藏夹中"
|
|
|
|
# 检查商品是否存在
|
|
product = Product.query.get(product_id)
|
|
if not product:
|
|
return False, "商品不存在"
|
|
|
|
# 添加收藏
|
|
favorite = cls(user_id=user_id, product_id=product_id)
|
|
db.session.add(favorite)
|
|
|
|
try:
|
|
db.session.commit()
|
|
return True, "收藏成功"
|
|
except Exception as e:
|
|
db.session.rollback()
|
|
return False, f"收藏失败: {str(e)}"
|
|
|
|
@classmethod
|
|
def remove_favorite(cls, user_id, product_id):
|
|
"""取消收藏"""
|
|
favorite = cls.query.filter_by(user_id=user_id, product_id=product_id).first()
|
|
if not favorite:
|
|
return False, "商品未收藏"
|
|
|
|
db.session.delete(favorite)
|
|
|
|
try:
|
|
db.session.commit()
|
|
return True, "取消收藏成功"
|
|
except Exception as e:
|
|
db.session.rollback()
|
|
return False, f"取消收藏失败: {str(e)}"
|
|
|
|
@classmethod
|
|
def get_user_favorites(cls, user_id, page=1, per_page=20):
|
|
"""获取用户收藏列表"""
|
|
return cls.query.filter_by(user_id=user_id) \
|
|
.join(Product) \
|
|
.filter(Product.status == 1) \
|
|
.order_by(cls.created_at.desc()) \
|
|
.paginate(page=page, per_page=per_page, error_out=False)
|
|
|
|
@classmethod
|
|
def get_user_favorites_count(cls, user_id):
|
|
"""获取用户收藏数量"""
|
|
return cls.query.filter_by(user_id=user_id).count()
|
|
|
|
def __repr__(self):
|
|
return f'<UserFavorite {self.user_id}-{self.product_id}>'
|