修改优化图片

修复积分列表功能
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)
async def get_point_records(
skip: int = 0,
limit: int = 20,
db: Session = Depends(get_db),
current_user: UserDB = Depends(get_current_user)
):
"""获取积分明细"""
# 获取总记录数
total = db.query(PointRecordDB).filter(
PointRecordDB.user_id == current_user.userid
).count()
# 获取分页数据
records = db.query(PointRecordDB).filter(
PointRecordDB.user_id == current_user.userid
).order_by(
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')
timestamp = str(int(time.time() * 1000))[-8:]
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 .database import Base
from app.core.utils import CommonUtils
from app.core.imageprocessor import process_image, ImageFormat
# 数据库模型
class MerchantDB(Base):
@ -28,7 +29,7 @@ class MerchantDB(Base):
@property
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):
user_id: int

View File

@ -7,7 +7,7 @@ from datetime import datetime
from .database import Base
import enum
from app.core.utils import CommonUtils
from app.core.imageprocessor import process_image, ImageFormat
class ProductStatus(str, enum.Enum):
LISTING = "LISTING" # 上架
@ -33,7 +33,7 @@ class MerchantProductDB(Base):
@property
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 模型
class MerchantProductCreate(BaseModel):

View File

@ -5,7 +5,7 @@ from sqlalchemy.sql import func
from pydantic import BaseModel, Field
from .database import Base
import enum
from app.core.utils import CommonUtils
from app.core.imageprocessor import process_image, ImageFormat
class OrderStatus(str, enum.Enum):
CREATED = "CREATED" # 已创建
@ -51,7 +51,7 @@ class ShippingOrderDB(Base):
@property
def optimized_complete_images(self):
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 []
class ShippingOrderPackageDB(Base):

View File

@ -8,7 +8,7 @@ from datetime import datetime
import enum
import random
import string
from app.core.imageprocessor import process_image, ImageFormat
class UserRole(str, enum.Enum):
USER = "user"
DELIVERYMAN = "deliveryman"
@ -40,6 +40,10 @@ class UserDB(Base):
community_id = Column(Integer, ForeignKey("communities.id"), nullable=True) # 归属小区
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 模型
class UserLogin(BaseModel):
phone: str = Field(..., pattern="^1[3-9]\d{9}$")