修改优化图片

修复积分列表功能
This commit is contained in:
aaron 2025-02-07 22:13:38 +09:00
parent dc9c44b626
commit 0005967a13
7 changed files with 92 additions and 31 deletions

View File

@ -43,16 +43,31 @@ async def add_points(
@router.get("/records", response_model=ResponseModel) @router.get("/records", response_model=ResponseModel)
async def get_point_records( async def get_point_records(
skip: int = 0,
limit: int = 20,
db: Session = Depends(get_db), db: Session = Depends(get_db),
current_user: UserDB = Depends(get_current_user) current_user: UserDB = Depends(get_current_user)
): ):
"""获取积分明细""" """获取积分明细"""
# 获取总记录数
total = db.query(PointRecordDB).filter(
PointRecordDB.user_id == current_user.userid
).count()
# 获取分页数据
records = db.query(PointRecordDB).filter( records = db.query(PointRecordDB).filter(
PointRecordDB.user_id == current_user.userid PointRecordDB.user_id == current_user.userid
).order_by( ).order_by(
PointRecordDB.create_time.desc() PointRecordDB.create_time.desc()
).all() ).offset(skip).limit(limit).all()
return success_response(data=[ # 获取用户当前总积分
PointRecordInfo.model_validate(r) for r in records total_points = db.query(UserDB.points).filter(
]) UserDB.userid == current_user.userid
).scalar()
return success_response(data={
"total": total, # 总记录数
"total_points": float(total_points), # 当前总积分
"items": [PointRecordInfo.model_validate(r) for r in records] # 积分记录列表
})

View File

@ -0,0 +1,62 @@
from enum import Enum
from typing import Optional, List
from urllib.parse import urlparse, urlencode
class ImageFormat(Enum):
ORIGINAL = "original"
WEBP = "webp"
HEIC = "heic"
TPG = "tpg"
AVIF = "avif"
class ImageProcessor:
def __init__(self, url: Optional[str]):
self.url = url
self.params = []
def thumbnail(self, width: int, height: int) -> 'ImageProcessor':
"""缩略图,按比例缩放"""
self.params.append(f"thumbnail/{width}x{height}")
return self
def crop(self, width: int, height: int) -> 'ImageProcessor':
"""居中裁剪"""
self.params.append(f"crop/{width}x{height}")
return self
def quality(self, value: int) -> 'ImageProcessor':
"""设置图片质量 1-100"""
self.params.append(f"quality/{max(1, min(100, value))}")
return self
def format(self, fmt: ImageFormat) -> 'ImageProcessor':
"""转换图片格式"""
if fmt != ImageFormat.ORIGINAL:
self.params.append(f"format/{fmt.value}")
return self
def blur(self, radius: int = 10) -> 'ImageProcessor':
"""高斯模糊"""
self.params.append(f"blur/radius/{radius}")
return self
def watermark(self, text: str) -> 'ImageProcessor':
"""文字水印"""
self.params.append(f"watermark/2/text/{text}")
return self
def build(self) -> Optional[str]:
"""生成最终的图片 URL"""
if not self.url:
return None
if not self.params:
return self.url
# 拼接处理参数
rules = "/".join(self.params)
return f"{self.url}?imageMogr2/{rules}"
def process_image(url: Optional[str]) -> ImageProcessor:
"""创建图片处理器"""
return ImageProcessor(url)

View File

@ -28,24 +28,3 @@ class CommonUtils:
date_str = now.strftime('%Y%m%d') date_str = now.strftime('%Y%m%d')
timestamp = str(int(time.time() * 1000))[-8:] timestamp = str(int(time.time() * 1000))[-8:]
return f"{date_str}{timestamp}" return f"{date_str}{timestamp}"
@staticmethod
def optimized_image_url(url: Optional[str], quality: int = 60) -> Optional[str]:
"""
为图片URL添加腾讯云图片处理参数
:param url: 原始图片URL
:param quality: 图片质量范围1-100默认80
:return: 处理后的URL
"""
if not url:
return url
# 确保quality在有效范围内
quality = max(1, min(100, quality))
# 如果URL已经包含图片处理参数则不重复添加
if "?imageMogr2/quality/" in url:
return url
# 添加图片处理参数
return f"{url}?imageMogr2/quality/{quality}"

View File

@ -6,6 +6,7 @@ from typing import Optional, List
from datetime import datetime from datetime import datetime
from .database import Base from .database import Base
from app.core.utils import CommonUtils from app.core.utils import CommonUtils
from app.core.imageprocessor import process_image, ImageFormat
# 数据库模型 # 数据库模型
class MerchantDB(Base): class MerchantDB(Base):
@ -28,7 +29,7 @@ class MerchantDB(Base):
@property @property
def optimized_brand_image_url(self): def optimized_brand_image_url(self):
return CommonUtils.optimized_image_url(self.brand_image_url) return process_image(self.brand_image_url).quality(80).thumbnail(width=450, height=450).format(ImageFormat.WEBP).build()
class MerchantCreate(BaseModel): class MerchantCreate(BaseModel):
user_id: int user_id: int

View File

@ -7,7 +7,7 @@ from datetime import datetime
from .database import Base from .database import Base
import enum import enum
from app.core.utils import CommonUtils from app.core.utils import CommonUtils
from app.core.imageprocessor import process_image, ImageFormat
class ProductStatus(str, enum.Enum): class ProductStatus(str, enum.Enum):
LISTING = "LISTING" # 上架 LISTING = "LISTING" # 上架
@ -33,7 +33,7 @@ class MerchantProductDB(Base):
@property @property
def optimized_image_url(self): def optimized_image_url(self):
return CommonUtils.optimized_image_url(self.image_url) return process_image(self.image_url).quality(80).thumbnail(width=450, height=450).format(ImageFormat.WEBP).build()
# Pydantic 模型 # Pydantic 模型
class MerchantProductCreate(BaseModel): class MerchantProductCreate(BaseModel):

View File

@ -5,7 +5,7 @@ from sqlalchemy.sql import func
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from .database import Base from .database import Base
import enum import enum
from app.core.utils import CommonUtils from app.core.imageprocessor import process_image, ImageFormat
class OrderStatus(str, enum.Enum): class OrderStatus(str, enum.Enum):
CREATED = "CREATED" # 已创建 CREATED = "CREATED" # 已创建
@ -51,7 +51,7 @@ class ShippingOrderDB(Base):
@property @property
def optimized_complete_images(self): def optimized_complete_images(self):
if self.complete_images: if self.complete_images:
return [CommonUtils.optimized_image_url(image) for image in self.complete_images.split(",")] return [process_image(image).quality(80).thumbnail(width=450, height=450).format(ImageFormat.WEBP).build() for image in self.complete_images.split(",")]
return [] return []
class ShippingOrderPackageDB(Base): class ShippingOrderPackageDB(Base):

View File

@ -8,7 +8,7 @@ from datetime import datetime
import enum import enum
import random import random
import string import string
from app.core.imageprocessor import process_image, ImageFormat
class UserRole(str, enum.Enum): class UserRole(str, enum.Enum):
USER = "user" USER = "user"
DELIVERYMAN = "deliveryman" DELIVERYMAN = "deliveryman"
@ -40,6 +40,10 @@ class UserDB(Base):
community_id = Column(Integer, ForeignKey("communities.id"), nullable=True) # 归属小区 community_id = Column(Integer, ForeignKey("communities.id"), nullable=True) # 归属小区
is_auth = Column(Boolean, nullable=False, default=False) is_auth = Column(Boolean, nullable=False, default=False)
@property
def optimized_avatar(self):
return process_image(self.avatar).quality(80).thumbnail(width=450, height=450).format(ImageFormat.WEBP).build()
# Pydantic 模型 # Pydantic 模型
class UserLogin(BaseModel): class UserLogin(BaseModel):
phone: str = Field(..., pattern="^1[3-9]\d{9}$") phone: str = Field(..., pattern="^1[3-9]\d{9}$")