Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3d67749101 |
@@ -11,7 +11,7 @@ from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
||||
|
||||
|
||||
# ===== 上报请求 =====
|
||||
@@ -21,8 +21,36 @@ class ComparisonItemIn(BaseModel):
|
||||
|
||||
name: str
|
||||
qty: int = 1
|
||||
# specs 仅供比价记录展示(admin-web 详情 / app 记录页都按字符串数组渲染并 join)。
|
||||
# pricebot(2026-06-27 嵌套规格统一)起 calibration 的 specs 可能是规格对象
|
||||
# [{name, qty, sub_specs}] 而非字符串 → 下面的 before-validator 统一拍平成可读字符串,
|
||||
# 兼容新旧两种输入、保持 list[str] 契约不变(下游零改动)。
|
||||
# ⚠️ 两个坑都踩过, 必须"拍平"而非别的: ① 直接声明 list[str] 不拍平 → 对象 specs 整条
|
||||
# 422 被拒、不入库(同下方 platform_results list→dict 同类事故); ② 仅放宽成裸 list 又会让
|
||||
# 下游 join 出 "[object Object]"/对象 toString 的乱码。
|
||||
specs: list[str] | None = None
|
||||
|
||||
@field_validator("specs", mode="before")
|
||||
@classmethod
|
||||
def _flatten_specs(cls, v: object) -> object:
|
||||
"""pricebot 规格对象 [{name, qty, sub_specs}] → 可读字符串数组; 字符串元素原样保留;
|
||||
非 list 原样交还(让 pydantic 照常报类型错)。嵌套规格拼成 '主项(子1,子2)'。"""
|
||||
if not isinstance(v, list):
|
||||
return v
|
||||
out: list[str] = []
|
||||
for it in v:
|
||||
if isinstance(it, str):
|
||||
s = it
|
||||
elif isinstance(it, dict):
|
||||
name = str(it.get("name") or "").strip()
|
||||
subs = [str(x).strip() for x in (it.get("sub_specs") or []) if str(x).strip()]
|
||||
s = f"{name}({','.join(subs)})" if name and subs else (name or ",".join(subs))
|
||||
else:
|
||||
continue
|
||||
if s:
|
||||
out.append(s)
|
||||
return out
|
||||
|
||||
|
||||
class AppliedCouponIn(BaseModel):
|
||||
"""单笔已用优惠(来自 comparison_results[].applied_coupons)。amount 单位:元、正数。"""
|
||||
|
||||
Reference in New Issue
Block a user