|
@@ -223,7 +223,7 @@ async def create_card_record(
|
|
|
raise HTTPException(status_code=response.status, detail=f"创建卡牌记录失败: {text}")
|
|
raise HTTPException(status_code=response.status, detail=f"创建卡牌记录失败: {text}")
|
|
|
|
|
|
|
|
|
|
|
|
|
-async def upload_fusion_image(
|
|
|
|
|
|
|
+async def upload_main_image(
|
|
|
session: aiohttp.ClientSession,
|
|
session: aiohttp.ClientSession,
|
|
|
base_url: str,
|
|
base_url: str,
|
|
|
card_id: int,
|
|
card_id: int,
|
|
@@ -232,7 +232,7 @@ async def upload_fusion_image(
|
|
|
filename: str,
|
|
filename: str,
|
|
|
score_json: Dict[str, Any],
|
|
score_json: Dict[str, Any],
|
|
|
):
|
|
):
|
|
|
- """融合图带 JSON 走主图入库接口。"""
|
|
|
|
|
|
|
+ """带 JSON 的图走主图入库接口(fusion / ring / stripe 共用同一面的 detection_json)。"""
|
|
|
url = f"{base_url}{settings.API_PREFIX}/images/insert/{card_id}"
|
|
url = f"{base_url}{settings.API_PREFIX}/images/insert/{card_id}"
|
|
|
|
|
|
|
|
form_fields = {
|
|
form_fields = {
|
|
@@ -250,10 +250,10 @@ async def upload_fusion_image(
|
|
|
)
|
|
)
|
|
|
if status != 201:
|
|
if status != 201:
|
|
|
logger.error(
|
|
logger.error(
|
|
|
- "[融合图上传失败] image_type=%s status=%s msg=%s",
|
|
|
|
|
|
|
+ "[主表图上传失败] image_type=%s status=%s msg=%s",
|
|
|
image_type, status, body.decode("utf-8", errors="ignore")[:200],
|
|
image_type, status, body.decode("utf-8", errors="ignore")[:200],
|
|
|
)
|
|
)
|
|
|
- raise HTTPException(status_code=500, detail=f"融合图保存失败: {image_type}")
|
|
|
|
|
|
|
+ raise HTTPException(status_code=500, detail=f"主表图保存失败: {image_type}")
|
|
|
|
|
|
|
|
|
|
|
|
|
async def upload_auxiliary_image(
|
|
async def upload_auxiliary_image(
|
|
@@ -307,9 +307,15 @@ async def _run_import_flow(
|
|
|
card_type: CardType,
|
|
card_type: CardType,
|
|
|
strict_mode: bool,
|
|
strict_mode: bool,
|
|
|
bytes_map: Dict[str, Tuple[bytes, str]],
|
|
bytes_map: Dict[str, Tuple[bytes, str]],
|
|
|
|
|
+ non_gray_to_main: bool = False,
|
|
|
) -> Dict[str, Any]:
|
|
) -> Dict[str, Any]:
|
|
|
"""
|
|
"""
|
|
|
共用导入流程:bytes_map 的 key 是 image_type,value 是 (bytes, filename)。
|
|
共用导入流程:bytes_map 的 key 是 image_type,value 是 (bytes, filename)。
|
|
|
|
|
+
|
|
|
|
|
+ non_gray_to_main:
|
|
|
|
|
+ False -> 仅融合图进主表(带 JSON),ring/gray/stripe 进辅助表(无 JSON)。
|
|
|
|
|
+ True -> 除灰度图外(fusion/ring/stripe)都进主表,并共用所在面的 detection_json;
|
|
|
|
|
+ 灰度图仍进辅助表。
|
|
|
"""
|
|
"""
|
|
|
expected_types = _flat_image_types()
|
|
expected_types = _flat_image_types()
|
|
|
provided = [t for t in expected_types if t in bytes_map]
|
|
provided = [t for t in expected_types if t in bytes_map]
|
|
@@ -362,41 +368,42 @@ async def _run_import_flow(
|
|
|
upload_count = 0
|
|
upload_count = 0
|
|
|
for side in ("front", "back"):
|
|
for side in ("front", "back"):
|
|
|
side_map = SIDE_IMAGE_TYPES[side]
|
|
side_map = SIDE_IMAGE_TYPES[side]
|
|
|
- fusion_type = side_map["fusion"]
|
|
|
|
|
- fusion_data = bytes_map.get(fusion_type)
|
|
|
|
|
score_json = side_score_json.get(side)
|
|
score_json = side_score_json.get(side)
|
|
|
|
|
|
|
|
- if fusion_data is not None:
|
|
|
|
|
- f_bytes, f_name = fusion_data
|
|
|
|
|
- if score_json is not None:
|
|
|
|
|
- await upload_fusion_image(
|
|
|
|
|
|
|
+ # 按 fusion -> ring -> gray -> stripe1..4 顺序处理该面所有图
|
|
|
|
|
+ for field in ["fusion"] + STITCH_FORM_FIELDS:
|
|
|
|
|
+ image_type = side_map[field]
|
|
|
|
|
+ data = bytes_map.get(image_type)
|
|
|
|
|
+ if data is None:
|
|
|
|
|
+ continue
|
|
|
|
|
+ f_bytes, f_name = data
|
|
|
|
|
+
|
|
|
|
|
+ is_gray = (field == "gray")
|
|
|
|
|
+ # 进主表(带该面 detection_json)的条件:
|
|
|
|
|
+ # - 非灰度图
|
|
|
|
|
+ # - 该面有 stitch 结果
|
|
|
|
|
+ # - URL 模式(non_gray_to_main) 下所有非灰度图都进;文件模式仅 fusion 进
|
|
|
|
|
+ to_main = (
|
|
|
|
|
+ not is_gray
|
|
|
|
|
+ and score_json is not None
|
|
|
|
|
+ and (non_gray_to_main or field == "fusion")
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ if to_main:
|
|
|
|
|
+ await upload_main_image(
|
|
|
session, local_base_url, card_id,
|
|
session, local_base_url, card_id,
|
|
|
- fusion_type, f_bytes, f_name, score_json,
|
|
|
|
|
|
|
+ image_type, f_bytes, f_name, score_json,
|
|
|
)
|
|
)
|
|
|
- upload_count += 1
|
|
|
|
|
else:
|
|
else:
|
|
|
- # 没有该面推理结果,融合图退化为辅助图,避免主表 detection_json 为空
|
|
|
|
|
- logger.warning(
|
|
|
|
|
- "%s 面缺少 stitch 推理结果,融合图 %s 退化为辅助图入库",
|
|
|
|
|
- side, fusion_type,
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ if field == "fusion" and score_json is None:
|
|
|
|
|
+ logger.warning(
|
|
|
|
|
+ "%s 面缺少 stitch 推理结果,融合图 %s 退化为辅助图入库",
|
|
|
|
|
+ side, image_type,
|
|
|
|
|
+ )
|
|
|
await upload_auxiliary_image(
|
|
await upload_auxiliary_image(
|
|
|
session, local_base_url, card_id,
|
|
session, local_base_url, card_id,
|
|
|
- fusion_type, f_bytes, f_name,
|
|
|
|
|
|
|
+ image_type, f_bytes, f_name,
|
|
|
)
|
|
)
|
|
|
- upload_count += 1
|
|
|
|
|
-
|
|
|
|
|
- # ring / gray / stripe1..4 走辅助表
|
|
|
|
|
- for field in STITCH_FORM_FIELDS:
|
|
|
|
|
- aux_type = side_map[field]
|
|
|
|
|
- aux_data = bytes_map.get(aux_type)
|
|
|
|
|
- if aux_data is None:
|
|
|
|
|
- continue
|
|
|
|
|
- a_bytes, a_name = aux_data
|
|
|
|
|
- await upload_auxiliary_image(
|
|
|
|
|
- session, local_base_url, card_id,
|
|
|
|
|
- aux_type, a_bytes, a_name,
|
|
|
|
|
- )
|
|
|
|
|
upload_count += 1
|
|
upload_count += 1
|
|
|
|
|
|
|
|
logger.info(
|
|
logger.info(
|
|
@@ -499,6 +506,7 @@ async def auto_import_script_api(
|
|
|
card_type=card_type,
|
|
card_type=card_type,
|
|
|
strict_mode=strict_mode,
|
|
strict_mode=strict_mode,
|
|
|
bytes_map=bytes_map,
|
|
bytes_map=bytes_map,
|
|
|
|
|
+ non_gray_to_main=True,
|
|
|
)
|
|
)
|
|
|
except HTTPException as e:
|
|
except HTTPException as e:
|
|
|
logger.error(
|
|
logger.error(
|
|
@@ -601,6 +609,7 @@ async def auto_import_url_script_api(
|
|
|
card_type=card_type,
|
|
card_type=card_type,
|
|
|
strict_mode=strict_mode,
|
|
strict_mode=strict_mode,
|
|
|
bytes_map=bytes_map,
|
|
bytes_map=bytes_map,
|
|
|
|
|
+ non_gray_to_main=True,
|
|
|
)
|
|
)
|
|
|
except HTTPException:
|
|
except HTTPException:
|
|
|
raise
|
|
raise
|