"""发布:组装 ImportProductsV3 items[0] + 必填校验 + 轮询回填。""" from __future__ import annotations from models import Product def _fmt(v) -> str: if v is None: return "" return str(v) def validate_ready(product: Product) -> list[str]: """返回缺失/非法必填项的中文提示列表;空列表表示可发布。""" missing: list[str] = [] if not product.offer_id.strip(): missing.append("货号 offer_id") if not product.name.strip(): missing.append("商品名 name") if not product.description.strip(): missing.append("描述 description") if not product.description_category_id: missing.append("类目 description_category_id") if product.price is None or product.price <= 0: missing.append("售价 price") if not product.weight or product.weight <= 0: missing.append("重量 weight") for label, val in (("长 depth", product.depth), ("宽 width", product.width), ("高 height", product.height)): if not val or val <= 0: missing.append(label) if not product.images: missing.append("主图 images(至少 1 张)") elif any(u and u.startswith("http://") for u in product.images): missing.append("图片链接必须使用 https(Ozon 不接受 http 直链)") return missing def _with_model_name(product: Product) -> list: """把 raw.model_name 自动注入为 attribute 9048(型号名称),用于多变体合并。""" attrs = list(product.attributes or []) model_name = (product.raw or {}).get("model_name") if product.raw else None if not model_name: return attrs # 已手动映射 9048 就不重复添加 for a in attrs: if isinstance(a, dict) and a.get("id") == 9048: return attrs attrs.append({"complex_id": 0, "id": 9048, "values": [{"value": model_name}]}) return attrs def build_import_item(product: Product) -> dict: item: dict = { "offer_id": product.offer_id, "name": product.name, "description": product.description, "description_category_id": product.description_category_id, "price": _fmt(product.price), "old_price": _fmt(product.old_price), "currency_code": product.currency_code or "CNY", "vat": product.vat or "0", "depth": product.depth, "width": product.width, "height": product.height, "dimension_unit": product.dimension_unit or "mm", "weight": product.weight, "weight_unit": product.weight_unit or "g", "images": product.images or [], "primary_image": product.primary_image or "", "images360": product.images360 or [], "color_image": product.color_image or "", "attributes": _with_model_name(product), "complex_attributes": product.complex_attributes or [], } if product.type_id: item["type_id"] = product.type_id if product.barcode: item["barcode"] = product.barcode return item