袁威 пре 2 недеља
родитељ
комит
761dc701e7
3 измењених фајлова са 59 додато и 29 уклоњено
  1. 29 6
      app/api/config_proxy.py
  2. 21 14
      app/api/formate_xy.py
  3. 9 9
      app/crud/crud_card.py

+ 29 - 6
app/api/config_proxy.py

@@ -14,6 +14,23 @@ router = APIRouter()
 # limits: max_keepalive_connections 控制连接池大小
 http_client = httpx.AsyncClient(timeout=10.0, limits=httpx.Limits(max_keepalive_connections=20, max_connections=100))
 
+def _extract_upstream_error_detail(resp: httpx.Response) -> str:
+    try:
+        data = resp.json()
+        if isinstance(data, dict):
+            detail = data.get("detail")
+            if detail:
+                return str(detail)
+            message = data.get("message")
+            if message:
+                return str(message)
+        return str(data)
+    except Exception:
+        text = (resp.text or "").strip()
+        if text:
+            return text[:2000]
+        return "上游服务错误"
+
 
 @router.get("/scoring_config", summary="(管理员) 获取评分配置 [用户调用]")
 async def proxy_get_scoring_config(current_user: dict = Depends(require_admin_user)):
@@ -27,7 +44,7 @@ async def proxy_get_scoring_config(current_user: dict = Depends(require_admin_us
             logger.error(f"项目1返回错误: {resp.status_code} - {resp.text}")
             raise HTTPException(
                 status_code=resp.status_code,
-                detail=resp.json().get("detail", "上游服务错误")
+                detail=_extract_upstream_error_detail(resp)
             )
         return resp.json()
 
@@ -48,9 +65,14 @@ async def proxy_update_scoring_config(
         resp = await http_client.put(target_url, json=config_data)
 
         if resp.status_code != 200:
-            raise HTTPException(status_code=resp.status_code, detail=f"保存失败: {resp.json()['detail']}")
-
-        return_data = {"detail": f"{resp.json()['message']}"}
+            raise HTTPException(status_code=resp.status_code, detail=f"保存失败: {_extract_upstream_error_detail(resp)}")
+
+        try:
+            payload = resp.json()
+        except Exception:
+            payload = None
+        message = payload.get("message") if isinstance(payload, dict) else None
+        return_data = {"detail": f"{message or '保存成功'}"}
         return JSONResponse(status_code=resp.status_code, content=return_data)
 
     except httpx.RequestError as exc:
@@ -68,7 +90,8 @@ async def proxy_get_severity_names(defect_label: str = Query(..., description="
 
     # 假设 settings.SCORE_SERVER_CONFIG_URL 是完整路径 ".../scoring_config"
     # 我们需要把它替换掉
-    base_url = settings.SCORE_SERVER_CONFIG_URL.rsplit('/', 1)[0]
+    temp = settings.SCORE_SERVER_CONFIG_URL
+    base_url = temp.rsplit('/', 1)[0]
     final_url = f"{base_url}/severity_names"
 
     try:
@@ -79,7 +102,7 @@ async def proxy_get_severity_names(defect_label: str = Query(..., description="
             logger.error(f"项目1返回错误: {resp.status_code} - {resp.text}")
             raise HTTPException(
                 status_code=resp.status_code,
-                detail=resp.json().get("detail", "上游服务错误")
+                detail=_extract_upstream_error_detail(resp)
             )
         return resp.json()
 

+ 21 - 14
app/api/formate_xy.py

@@ -1,5 +1,6 @@
 import requests
 import json
+import copy
 from enum import Enum
 
 from fastapi import APIRouter, Depends, HTTPException, Query, Body
@@ -130,20 +131,26 @@ def _process_images_to_xy_format(card_data: dict):
     all_images = card_data.get("images", [])
     if all_images:
         for img in all_images:
-            # Pydantic模型属性访问
-            d_json = img.detection_json
-            if d_json:
-                if isinstance(d_json, str):
-                    d_json = json.loads(d_json)
-                _process_defects_for_json(card_id, img.id, img.image_path, d_json, img.image_type, all_images)
-                img.detection_json = convert_internal_to_xy_format(d_json)
-
-            m_json = img.modified_json
-            if m_json:
-                if isinstance(m_json, str):
-                    m_json = json.loads(m_json)
-                _process_defects_for_json(card_id, img.id, img.image_path, m_json, img.image_type, all_images)
-                img.modified_json = convert_internal_to_xy_format(m_json)
+            d_internal = img.detection_json
+            if d_internal and isinstance(d_internal, str):
+                d_internal = json.loads(d_internal)
+
+            if d_internal:
+                _process_defects_for_json(card_id, img.id, img.image_path, d_internal, img.image_type, all_images)
+                img.detection_json = convert_internal_to_xy_format(d_internal)
+            else:
+                img.detection_json = convert_internal_to_xy_format({})
+
+            m_internal = img.modified_json
+            if m_internal and isinstance(m_internal, str):
+                m_internal = json.loads(m_internal)
+
+            if m_internal:
+                _process_defects_for_json(card_id, img.id, img.image_path, m_internal, img.image_type, all_images)
+                img.modified_json = convert_internal_to_xy_format(m_internal)
+            else:
+                m_fallback = copy.deepcopy(d_internal) if d_internal else {}
+                img.modified_json = convert_internal_to_xy_format(m_fallback)
     return card_data
 
 

+ 9 - 9
app/crud/crud_card.py

@@ -183,16 +183,16 @@ def get_card_with_details(db_conn: PooledMySQLConnection, card_id: int) -> Optio
         score_details = calculate_scores_from_images(main_images_objs)
 
         # 6. 对图片列表进行自定义排序
-        # 顺序: [front_gray, back_gray, front_ring, back_ring, front_coaxial, back_coaxial, front_fusion, back_fusion]
+        # 顺序: [back_fusion, front_fusion, front_gray, back_gray, front_ring, back_ring, front_coaxial, back_coaxial]
         sort_priority = {
-            ImageType.front_gray.value: 0,
-            ImageType.back_gray.value: 1,
-            ImageType.front_ring.value: 2,
-            ImageType.back_ring.value: 3,
-            ImageType.front_coaxial.value: 4,
-            ImageType.back_coaxial.value: 5,
-            ImageType.front_fusion.value: 6,
-            ImageType.back_fusion.value: 7
+            ImageType.back_fusion.value: 0,
+            ImageType.front_fusion.value: 1,
+            ImageType.front_gray.value: 2,
+            ImageType.back_gray.value: 3,
+            ImageType.front_ring.value: 4,
+            ImageType.back_ring.value: 5,
+            ImageType.front_coaxial.value: 6,
+            ImageType.back_coaxial.value: 7
         }
         final_images_list.sort(key=lambda x: sort_priority.get(x.image_type, 999))