修改优化图片
修复积分列表功能
This commit is contained in:
parent
dc9c44b626
commit
0005967a13
@ -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] # 积分记录列表
|
||||
})
|
||||
62
app/core/imageprocessor.py
Normal file
62
app/core/imageprocessor.py
Normal 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)
|
||||
@ -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}"
|
||||
@ -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
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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}$")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user