瀏覽代碼

feat(api): 添加开放平台企业列表和商品资料上传功能

- 新增开放平台API配置信息包括基础URL、应用密钥和应用密钥
- 实现获取开放平台API请求头的方法
- 添加查询开放平台企业列表的GET接口
- 添加拍照机商品资料上传到开放平台的POST接口
- 实现商品图片批量上传功能支持多种图片格式
- 新增OpenApiCompanyList和OpenApiUploadItem数据模型
- 添加上传结果统计和错误处理机制
rambo 9 小時之前
父節點
當前提交
8a526022ab
共有 2 個文件被更改,包括 130 次插入0 次删除
  1. 117 0
      python/api.py
  2. 13 0
      python/models.py

+ 117 - 0
python/api.py

@@ -2280,3 +2280,120 @@ async def import_images_from_dir(params: MeasurerRequest):
     ).measure()
     result["goods_path"] = goods_path
     return {"code": 0, "msg": "操作成功", "data": result}
+
+
+OPEN_API_BASE_URL = "https://zjai.pubdata.cn/api/v1/open"
+OPEN_API_APP_KEY = "ak_5e8b417bbeb581ad"
+OPEN_API_APP_SECRET = "P3gxaIINUhXRrF4bND5EUwpH"
+
+
+def _get_open_api_headers():
+    return {
+        "X-App-Key": OPEN_API_APP_KEY,
+        "X-App-Secret": OPEN_API_APP_SECRET,
+    }
+
+
+@app.get("/open_api/companies", description="企业列表")
+async def get_open_api_companies(
+        q: str = "",
+        page: int = 1,
+        page_size: int = 100,
+):
+    """查询开放平台企业列表"""
+    try:
+        params = {"page": page, "page_size": page_size}
+        if q:
+            params["q"] = q
+        resp = requests.get(
+            f"{OPEN_API_BASE_URL}/companies",
+            headers=_get_open_api_headers(),
+            params=params,
+            timeout=15,
+        )
+        return resp.json()
+    except Exception as e:
+        raise UnicornException(f"请求企业列表接口失败: {str(e)}")
+
+
+@app.post("/open_api/upload_item", description="拍照机商品资料上传")
+async def upload_item_to_open_api(params: OpenApiUploadItem):
+    """将货号800x800目录下已抠图图片上传到开放平台商品档案"""
+    goods_art_no = params.goods_art_no
+    company_id = params.company_id
+    if not goods_art_no:
+        raise UnicornException("货号不能为空")
+    if not company_id:
+        raise UnicornException("企业ID不能为空")
+
+    goods_path = check_goods_art_no_cutout_dir(goods_art_no)
+    if not goods_path:
+        raise UnicornException("请先对图像进行抠图")
+
+    cutout_dir = os.path.join(goods_path, "800x800")
+    if not os.path.isdir(cutout_dir):
+        raise UnicornException("800x800抠图目录不存在")
+
+    image_files = natsorted([
+        f for f in os.listdir(cutout_dir)
+        if os.path.isfile(os.path.join(cutout_dir, f))
+    ])
+    if not image_files:
+        raise UnicornException("800x800目录下无图片文件")
+
+    create_date = time.strftime("%Y-%m-%d")
+    upload_results = []
+
+    try:
+        for image_name in image_files:
+            image_path = os.path.join(cutout_dir, image_name)
+            file_ext = os.path.splitext(image_name)[1].lower()
+            content_type_map = {
+                ".jpg": "image/jpeg",
+                ".jpeg": "image/jpeg",
+                ".png": "image/png",
+                ".gif": "image/gif",
+                ".webp": "image/webp",
+                ".bmp": "image/bmp",
+            }
+            content_type = content_type_map.get(file_ext, "image/jpeg")
+            image_type = os.path.splitext(image_name)[0]
+
+            with open(image_path, "rb") as f:
+                files = [
+                    ("File", (image_name, f, content_type)),
+                ]
+                data = {
+                    "Key": goods_art_no,
+                    "ImageType": image_type,
+                    "CreateDate": create_date,
+                    "CompanyId": company_id,
+                }
+                resp = requests.post(
+                    f"{OPEN_API_BASE_URL}/camera/items",
+                    headers=_get_open_api_headers(),
+                    data=data,
+                    files=files,
+                    timeout=30,
+                )
+                result = resp.json()
+                upload_results.append({
+                    "image": image_name,
+                    "status_code": resp.status_code,
+                    "result": result,
+                })
+
+        success_count = sum(1 for r in upload_results if r.get("result", {}).get("code") == "OK")
+        return {
+            "code": 0,
+            "msg": f"上传完成,成功{success_count}/{len(upload_results)}",
+            "data": {
+                "total": len(upload_results),
+                "success": success_count,
+                "details": upload_results,
+            },
+        }
+    except requests.RequestException as e:
+        raise UnicornException(f"请求开放平台接口失败: {str(e)}")
+    except Exception as e:
+        raise UnicornException(f"上传异常: {str(e)}")

+ 13 - 0
python/models.py

@@ -205,3 +205,16 @@ class MeasurerRequest(BaseModel):
     # front_png: str = Field(default=None, description="正视图")
     # topdown_png: str = Field(default=None, description="俯视图")
     calib: dict = Field(default=None, description="像素标定尺寸")
+
+
+class OpenApiCompanyList(BaseModel):
+    """企业列表查询"""
+    q: Optional[str] = Field(default="", description="企业名称模糊搜索")
+    page: Optional[int] = Field(default=1, description="页码")
+    page_size: Optional[int] = Field(default=100, description="每页条数")
+
+
+class OpenApiUploadItem(BaseModel):
+    """拍照机商品资料上传"""
+    goods_art_no: str = Field(default=None, description="货号")
+    company_id: str = Field(default=None, description="混淆企业ID")