rambo 1 månad sedan
förälder
incheckning
8091221194
3 ändrade filer med 197 tillägg och 28 borttagningar
  1. 188 27
      python/api.py
  2. 1 0
      python/middleware.py
  3. 8 1
      python/models.py

+ 188 - 27
python/api.py

@@ -36,6 +36,7 @@ import traceback,stat
 import concurrent.futures
 from sockets.message_handler import handlerFolderDelete
 from service.remove_bg_ali import RemoveBgALi
+import uuid as mine_uuid
 def log_exception_with_context(context_message=""):
     """装饰器:为函数添加异常日志上下文"""
 
@@ -1085,46 +1086,85 @@ def reset_config(params: ModelGetDeviceConfig):
 @app.get("/get_photo_records", description="获取拍照记录")
 def get_photo_records(page: int = 1, size: int = 5):
     session = SqlQuery()
+    current_page = page
     # photos = CRUD(PhotoRecord)
     print("准备查询拍摄记录", datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
-    statement = (
-        select(PhotoRecord)
+    
+    # 首先统计总数
+    count_statement = (
+        select(func.count(PhotoRecord.goods_art_no.distinct()))
+        .where(PhotoRecord.delete_time == None)
+    )
+    total_count = session.exec(count_statement).one()
+    
+    # 查询所有不重复的货号及对应的最大时间,进行分页
+    base_statement = (
+        select(PhotoRecord.goods_art_no, func.max(PhotoRecord.id).label('max_id'))
+        .where(PhotoRecord.delete_time == None)
+        .group_by(PhotoRecord.goods_art_no)
+        .order_by(desc('max_id'))
         .offset((page - 1) * size)
         .limit(size)
-        .where(PhotoRecord.delete_time == None)
-        .order_by(desc("id"))
-        .group_by("goods_art_no")
     )
-    list = []
-    result = session.exec(statement).all()
-    print("group 完成 ", datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
-    join_conditions = [
-        {
-            "model": DeviceConfig,
-            "on": PhotoRecord.action_id == DeviceConfig.id,
-            "is_outer": False,  # 可选,默认False,设为True则为LEFT JOIN
-        }
-    ]
-    for item in result:
+    paginated_results = session.exec(base_statement).all()
+    
+    # 获取这些货号的详细记录
+    list_data = []
+    if paginated_results:
+        # 获取当前页的货号列表
+        current_goods_art_nos = [item.goods_art_no for item in paginated_results]
+        
+        # 查询这些货号的所有记录
         query = (
             select(PhotoRecord, DeviceConfig.action_name)
-            .where(PhotoRecord.goods_art_no == item.goods_art_no)
             .join(DeviceConfig, PhotoRecord.action_id == DeviceConfig.id)
+            .where(PhotoRecord.goods_art_no.in_(current_goods_art_nos))
+            .order_by(PhotoRecord.goods_art_no, desc("id"))  # 按货号分组并按ID倒序
         )
-        list_item = session.exec(query).mappings().all()
-        list.append(
-            {
-                "goods_art_no": item.goods_art_no,
-                "action_time": item.create_time,
-                "items": list_item,
-            }
-        )
+        all_items = session.exec(query).mappings().all()
+        
+        # 按货号分组
+        items_by_goods = {}
+        for item in all_items:
+            goods_art_no = item.PhotoRecord.goods_art_no
+            if goods_art_no not in items_by_goods:
+                items_by_goods[goods_art_no] = []
+            items_by_goods[goods_art_no].append(item)
+        
+        # 构建结果列表,保持分页的顺序
+        for item in paginated_results:
+            goods_art_no = item.goods_art_no
+            if goods_art_no in items_by_goods:
+                # 获取该货号下时间最新的记录作为action_time
+                latest_record = items_by_goods[goods_art_no][0].PhotoRecord
+                list_data.append(
+                    {
+                        "goods_art_no": goods_art_no,
+                        "action_time": latest_record.create_time,
+                        "items": items_by_goods[goods_art_no],
+                    }
+                )
+    
     session.close()
     print("循环查询 完成 ", datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
+    
+    # 计算分页信息
+    total_pages = (total_count + size - 1) // size  # 向上取整
+    has_prev = page > 1
+    has_next = page < total_pages
+    
     return {
         "code": 0,
         "msg": "",
-        "data": {"list": list, "page": page, "size": size},
+        "data": {
+            "list": list_data, 
+            "current_page": current_page,
+            "size": size,
+            "total_count": total_count,
+            "total_pages": total_pages,
+            "has_prev": has_prev,
+            "has_next": has_next
+        },
     }
 
 
@@ -1515,4 +1555,125 @@ def uploadImage(remove_pic_ins,token:str, local_path: str) -> str:
         resultData = requests.post(
             url, files={"file":im}, headers=post_headers
         ).json()
-        return resultData["data"]["url"]
+        return resultData["data"]["url"]
+    
+    
+    
+@app.post("/remove_background", description="图片抠图-http请求")
+async def remove_background(params:PhotoRecordRemoveBackground):
+    # await socket_manager.send_message(msg="测试")
+    executor = ThreadPoolExecutor(max_workers=4)
+    obj = None
+    token = params.token
+    token = "Bearer " + token
+    uuid = mine_uuid.uuid4().hex
+    run_main = RunMain(obj, token, uuid)
+    goods_art_no_arrays = params.goods_art_nos
+    limit_path = "{}/{}".format(settings.OUTPUT_DIR,
+        time.strftime("%Y-%m-%d", time.localtime(time.time()))
+    )
+    try:
+        move_folder_array = handlerFolderDelete(limit_path,goods_art_no_arrays,True)
+    except UnicornException as e:
+        raise UnicornException(e.msg)
+    # 该数组表示是否需要后面的移动文件夹操作,减少重复抠图,提升抠图时间和速度
+    session = SqlQuery()
+    for goods_art_no in goods_art_no_arrays:
+        pr = CRUD(PhotoRecord)
+        images = pr.read_all(session, conditions={"goods_art_no": goods_art_no,"delete_time": None})
+        if not images:
+            raise UnicornException(f"商品货号【{goods_art_no}】在商品档案资料中不存在,请检查货号是否正确")
+        if move_folder_array.get(goods_art_no) == None:
+            image_dir = "{}/data/".format(os.getcwd()).replace("\\", "/")
+            check_path(image_dir)
+            for idx, itemImg in enumerate(images):
+                if itemImg.image_path == "" or itemImg.image_path == None:
+                    raise UnicornException(f"货号【{goods_art_no}】存在没有拍摄完成的图片,请重拍或删除后重试")
+                new_file_name = (
+                    str(idx)+"_"+str(itemImg.goods_art_no) + "_" + str(idx) + ".jpg"
+                )
+                if not os.path.exists(
+                    image_dir + "/" + os.path.basename(new_file_name)
+                ):
+                    shutil.copy(itemImg.image_path, image_dir + new_file_name)
+            dealImage = DealImage(image_dir)
+            resFlag, path = dealImage.dealMoveImage(
+                image_dir=image_dir,
+                callback_func=None,
+                goods_art_no=goods_art_no,
+            )
+            if not resFlag:
+                raise UnicornException(f"抠图操作异常,请检查目录是否存在,或者权限不足")
+    session.close()
+    # try:
+    cutOutMode = (
+        "1"
+        if settings.getSysConfigs("other_configs", "cutout_mode", "普通抠图")
+        == "普通抠图"
+        else "2"
+    )
+    config_data = {
+        "image_dir": limit_path,
+        "image_order": (
+            "俯视,侧视,后跟,鞋底,内里,组合,组合2,组合3,组合4,组合5"
+        ),
+        "goods_art_no": "",
+        "goods_art_nos": goods_art_no_arrays,
+        "is_check_number": False,
+        "resize_image_view": "后跟",
+        "cutout_mode": cutOutMode,
+        "logo_path": "",
+        "special_goods_art_no_folder_line": "",
+        "is_use_excel": False,  # 是否使用excel
+        "excel_path": "",  # excel路径
+        "is_check_color_is_all": False,
+        "cutout_is_pass": True,
+        "assigned_page_dict": {},
+        "detail_is_pass": True,
+        "upload_is_pass": False,
+        "upload_is_enable": settings.IS_UPLOAD_HLM,  # 是否上传到惠利玛商品库,通过config.ini得is_upload开启
+        "is_filter": False,
+        "temp_class": {},
+        "temp_name": "",
+        "temp_name_list": [],
+        "target_error_folder": f"{limit_path}/软件-生成详情错误",
+        "success_handler": [],
+    }
+    try:
+        loop = asyncio.get_event_loop()
+        return_data = await loop.run_in_executor(
+            executor, partial(run_main.check_before_cutout, config_data)
+        )
+        cutout_res = await loop.run_in_executor(
+            executor,
+            partial(run_main.check_for_cutout_image_first_call_back, return_data),
+        )
+        handler_result = []
+        have_handler_keys = move_folder_array.keys()
+        if cutout_res:
+            handler_result_folder = f"{config_data['image_dir']}"
+            for goods_art_item in goods_art_no_arrays:
+                handler_result.append({
+                    "goods_art_no": goods_art_item,
+                    "success": True,
+                    "info": "处理成功",
+                })
+        else:
+            return {"code": 1, "message": "抠图失败", "data": None} 
+        if len(have_handler_keys) == len(goods_art_no_arrays) or (len(have_handler_keys) == 0  and cutout_res):
+            handler_result_folder = handler_result_folder.replace("\\", "/")
+            success_items = [item for item in handler_result if item.get('success') == True]
+            cutout_folder = handler_result_folder+"/"+success_items[0].get("goods_art_no")+"/800x800" if len(success_items) > 0 else ""
+            progress = {
+                "status": "处理完成",
+                "current": len(goods_art_no_arrays),
+                "total": len(goods_art_no_arrays),
+                "error": 0,
+                "folder":cutout_folder,
+            }
+            return {"code": 0, "message": "抠图完成", "data": {"output_folder": handler_result_folder, "list": handler_result,"progress":progress}}
+    except UnicornException as e:
+        raise UnicornException(e.msg)
+    except Exception as e:
+        print("error",e)
+        raise UnicornException(f"抠图异常,请稍后重试:{e}")

+ 1 - 0
python/middleware.py

@@ -56,6 +56,7 @@ class UnicornException(Exception):
     def __init__(self, msg: str, code: int = -1):
         self.msg = msg
         self.code = code
+        self.message = msg
 
 
 @app.exception_handler(UnicornException)

+ 8 - 1
python/models.py

@@ -151,4 +151,11 @@ class SyncLocalConfigs(BaseModel):
 class GenerateImageJson(BaseModel):
     """货号json数据生成"""
 
-    goods_art_no: str = Field(default=None, description="货号")
+    goods_art_no: str = Field(default=None, description="货号")
+    
+    
+class PhotoRecordRemoveBackground(BaseModel):
+    """获取可执行程序命令列表"""
+
+    goods_art_nos: list[str] = Field(default=None, description="货号数组")
+    token: str = Field(default=None, description="用户token")