From 7d1eaf5829697382a4b33cbbceb52597b8e1144b Mon Sep 17 00:00:00 2001 From: chenshuobo Date: Tue, 23 Jun 2026 20:23:02 +0800 Subject: [PATCH] =?UTF-8?q?feat(meituan-coupon):=20=E5=A4=B4=E5=9B=BE?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E7=BB=9F=E4=B8=80=E5=8E=8B=E7=BC=A9(?= =?UTF-8?q?=E5=8E=BB=E6=8E=89=E5=A4=A7=E5=B0=8F=E9=98=88=E5=80=BC,?= =?UTF-8?q?=E5=85=A8=E9=83=A8=E6=8B=BC=E7=BC=A9=E6=94=BE=E5=8F=82=E6=95=B0?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 产品要求所有头图都压缩,不再按 image_size 阈值判定: - feed_image_url 改为无条件给图片 URL 拼 @375w_375h_1e_1c.webp(缩 124dp + 转 WebP) - 去掉 FEED_THUMB_SIZE_THRESHOLD 阈值常量;from_raw / 两处 DB 路不再传 image_size - image_size/image_type 两列保留用于分析/监控(GIF 占比、体积分布),采集逻辑不变 - 文档更新:head_image_url 现统一带缩放参数 注:读取侧统一压缩,部署后即对全部 feed 图生效,无需依赖 image_size 回填。 --- app/api/v1/meituan.py | 4 ++-- app/models/meituan_coupon.py | 2 +- app/schemas/meituan.py | 26 ++++++++++---------------- docs/api/README.md | 2 +- 4 files changed, 14 insertions(+), 20 deletions(-) diff --git a/app/api/v1/meituan.py b/app/api/v1/meituan.py index 715ee80..5bb0031 100644 --- a/app/api/v1/meituan.py +++ b/app/api/v1/meituan.py @@ -202,7 +202,7 @@ def feed(req: FeedRequest, db: Session = Depends(get_db)) -> FeedResponse: cards: list[CouponCard] = [] for row in rows[:PAGE]: try: - card = CouponCard.from_raw(row.raw or {}, image_size=row.image_size) + card = CouponCard.from_raw(row.raw or {}) except Exception: # noqa: BLE001 continue if card.product_view_sign: @@ -288,7 +288,7 @@ def top_sales(req: TopSalesRequest, db: Session = Depends(get_db)) -> CouponList cards: list[CouponCard] = [] for row in rows[:req.page_size]: try: - card = CouponCard.from_raw(row.raw or {}, image_size=row.image_size) + card = CouponCard.from_raw(row.raw or {}) except Exception: # noqa: BLE001 continue if card.product_view_sign: diff --git a/app/models/meituan_coupon.py b/app/models/meituan_coupon.py index da08334..216f10f 100644 --- a/app/models/meituan_coupon.py +++ b/app/models/meituan_coupon.py @@ -56,7 +56,7 @@ class MeituanCoupon(Base): original_price_cents: Mapped[int | None] = mapped_column(Integer, nullable=True) head_url: Mapped[str | None] = mapped_column(String(512), nullable=True) # 头图字节大小 / MIME 类型:采集时 HEAD head_url 得到(Content-Length / Content-Type)。 - # 供读取侧按 image_size 决定是否给图片 URL 拼缩放参数(124dp 卡片下原图,长尾到 17MB)。 + # 读取侧已统一压缩(不再按大小判定),这两列保留用于分析/监控(GIF 占比、体积分布等)。 image_size: Mapped[int | None] = mapped_column(Integer, nullable=True) # 字节 image_type: Mapped[str | None] = mapped_column(String(32), nullable=True) # 如 image/jpeg diff --git a/app/schemas/meituan.py b/app/schemas/meituan.py index 0c109fc..b40f3ed 100644 --- a/app/schemas/meituan.py +++ b/app/schemas/meituan.py @@ -13,25 +13,19 @@ from pydantic import BaseModel, Field FeedStatus = Literal["ok", "empty", "degraded"] -# ───────────────── 头图传输优化口子(按大小决定是否拼缩放参数) ───────────────── +# ───────────────── 头图传输优化(统一缩放 + 转 WebP) ───────────────── # 美团图片 CDN 支持在 URL 后拼 @w_h_1e_1c[.webp] 让服务端缩放/转码。feed 卡片只占 -# 124dp(≈372px@3x),但库里 head_url 是原图(实测中位 137KB、长尾到 17MB),是首页 feed -# 图片加载偏慢/卡顿的一个来源。采集时已把头图字节大小存进 meituan_coupon.image_size, -# 这里据其决定是否给大图拼缩略参数(实测 124dp 缩略 + 转 WebP 可省 76–99%)。 -# -# ⚠️ 口子待产品确定阈值:FEED_THUMB_SIZE_THRESHOLD=None 时**完全 passthrough、不改变现网行为**。 -# 产品定下阈值(如 300*1024)后改这里即可生效,无需动调用方。 -FEED_THUMB_SIZE_THRESHOLD: int | None = None # 超过多少字节才拼缩放参数;None=暂不启用 +# 124dp(≈372px@3x),而库里 head_url 是原图(实测中位 137KB、长尾到 17MB、GIF 均 4.8MB), +# 是首页 feed 图片加载偏慢的来源。按产品要求,头图**统一**缩到 124dp + 转 WebP 再下发 +# (全部压缩、不设大小阈值),由美团 CDN 服务端缩放/转码,实测省 76–99% 体积。 FEED_THUMB_PARAM = "@375w_375h_1e_1c.webp" # 124dp@3x 缩略 + 转 WebP -def feed_image_url(head_url: str, image_size: int | None = None) -> str: - """据头图字节大小决定是否给 URL 拼缩放参数提速。阈值=None 或大小未知/不超阈值时返回原 URL。""" - if not head_url or FEED_THUMB_SIZE_THRESHOLD is None: +def feed_image_url(head_url: str) -> str: + """统一给头图 URL 拼缩放参数(缩到 124dp + 转 WebP),让美团 CDN 出小图;空 URL 原样返回。""" + if not head_url: return head_url - if image_size is not None and image_size >= FEED_THUMB_SIZE_THRESHOLD: - return head_url.split("@")[0] + FEED_THUMB_PARAM - return head_url + return head_url.split("@")[0] + FEED_THUMB_PARAM # ───────────────── 券卡片(归一化后给客户端) ───────────────── @@ -66,7 +60,7 @@ class CouponCard(BaseModel): rating_label: str | None = Field(None, description="如 4.6分") @classmethod - def from_raw(cls, item: dict[str, Any], image_size: int | None = None) -> CouponCard: + def from_raw(cls, item: dict[str, Any]) -> CouponCard: cpd = item.get("couponPackDetail") or {} brand = item.get("brandInfo") or {} comm = item.get("commissionInfo") or {} @@ -115,7 +109,7 @@ class CouponCard(BaseModel): platform=platform, biz_line=biz_line, name=cpd.get("name") or "", - head_image_url=feed_image_url(head_url, image_size), + head_image_url=feed_image_url(head_url), brand_name=brand.get("brandName"), brand_logo_url=brand.get("brandLogoUrl"), sell_price=sell, diff --git a/docs/api/README.md b/docs/api/README.md index 721d2c8..1eabe1f 100644 --- a/docs/api/README.md +++ b/docs/api/README.md @@ -173,7 +173,7 @@ | `platform` | int | `1`=外卖/到家, `2`=到店 | | `biz_line` | int \| null | 到店子类:1到餐 2到综 3酒店 4门票 | | `name` | string | 商品名 | -| `head_image_url` | string | 头图直链(美团原图)。**预留**:采集时已把头图字节大小记到 `meituan_coupon.image_size`,后续可按阈值在 URL 拼缩放参数(124dp 缩略+WebP,实测省 76–99%)提速;当前阈值未启用、直出原图、行为不变 | +| `head_image_url` | string | 头图;后端已**统一**拼缩放参数 `@375w_375h_1e_1c.webp`(美团 CDN 服务端缩到 124dp + 转 WebP,实测省 76–99%),客户端直接用 | | `brand_name` | string \| null | 品牌名 | | `brand_logo_url` | string \| null | 品牌 logo | | `sell_price` | string | 现价 |