import random import copy def generate_unique_id(): """生成一个随机的整数ID""" return random.randint(1000000, 99999999) def _points_list_to_xy_dicts(points: list) -> list: """ 后端 -> 前端 [[x, y], ...] => [{"id": 123, "x": x, "y": y}, ...] """ if not points: return [] return [ {"id": generate_unique_id(), "x": p[0], "y": p[1]} for p in points if len(p) >= 2 ] def _xy_dicts_to_points_list(xy_dicts: list) -> list: """ 前端 -> 后端 [{"id": 123, "x": x, "y": y}, ...] => [[x, y], ...] """ if not xy_dicts: return [] # 兼容处理:万一前端传回来的已经是列表列表格式,直接返回 if len(xy_dicts) > 0 and isinstance(xy_dicts[0], list): return xy_dicts return [ [d.get("x"), d.get("y")] for d in xy_dicts if "x" in d and "y" in d ] def convert_internal_to_xy_format(internal_json: dict) -> dict: """ 将后端存储的 JSON 转换为前端需要的 XY + ID 格式 1. points 变为对象列表 2. defects 中的每一项增加 id """ if not internal_json: return {} # 深拷贝以免修改原始缓存或对象 data = copy.deepcopy(internal_json) result = data.get("result", {}) # 1. 处理 Center Result (Box Result) # 路径通常是: result -> center_result -> box_result -> inner_box/outer_box -> shapes -> points center_result = result.get("center_result", {}) box_result = center_result.get("box_result", {}) for box_key in ["inner_box", "outer_box"]: if box_key in box_result: shapes = box_result[box_key].get("shapes", []) for shape in shapes: if "points" in shape: shape["points"] = _points_list_to_xy_dicts(shape["points"]) if "rect_box" in shape: shape["rect_box"] = _points_list_to_xy_dicts(shape["rect_box"]) # 2. 处理 Defect Result # 路径通常是: result -> defect_result -> defects -> [item] -> (id & points) defect_result = result.get("defect_result", {}) defects = defect_result.get("defects", []) for defect in defects: # 给缺陷本身加一个 ID if "id" not in defect: defect["id"] = generate_unique_id() # 处理缺陷的坐标点 if "points" in defect: defect["points"] = _points_list_to_xy_dicts(defect["points"]) return data def convert_xy_to_internal_format(frontend_json: dict) -> dict: """ 将前端传来的 XY + ID 格式还原为后端存储格式 1. points 还原为 [[x,y]] 2. 丢弃为了前端展示生成的临时 ID (defects 里的 id 可以保留也可以丢弃,这里选择保留以免影响逻辑,但 points 里的必须变回列表) """ if not frontend_json: return {} data = copy.deepcopy(frontend_json) result = data.get("result", {}) # 1. 处理 Center Result center_result = result.get("center_result", {}) box_result = center_result.get("box_result", {}) for box_key in ["inner_box", "outer_box"]: if box_key in box_result: shapes = box_result[box_key].get("shapes", []) for shape in shapes: if "points" in shape: shape["points"] = _xy_dicts_to_points_list(shape["points"]) if "rect_box" in shape: shape["rect_box"] = _xy_dicts_to_points_list(shape["rect_box"]) # 2. 处理 Defect Result defect_result = result.get("defect_result", {}) defects = defect_result.get("defects", []) for defect in defects: # points 还原 if "points" in defect: defect["points"] = _xy_dicts_to_points_list(defect["points"]) # 这里的 defect["id"] 如果后端不需要存储,可以 del defect["id"] # if "id" in defect: del defect["id"] return data