|
@@ -36,6 +36,7 @@ import traceback,stat
|
|
|
import concurrent.futures
|
|
import concurrent.futures
|
|
|
from sockets.message_handler import handlerFolderDelete
|
|
from sockets.message_handler import handlerFolderDelete
|
|
|
from service.remove_bg_ali import RemoveBgALi
|
|
from service.remove_bg_ali import RemoveBgALi
|
|
|
|
|
+import uuid as mine_uuid
|
|
|
def log_exception_with_context(context_message=""):
|
|
def log_exception_with_context(context_message=""):
|
|
|
"""装饰器:为函数添加异常日志上下文"""
|
|
"""装饰器:为函数添加异常日志上下文"""
|
|
|
|
|
|
|
@@ -1085,46 +1086,85 @@ def reset_config(params: ModelGetDeviceConfig):
|
|
|
@app.get("/get_photo_records", description="获取拍照记录")
|
|
@app.get("/get_photo_records", description="获取拍照记录")
|
|
|
def get_photo_records(page: int = 1, size: int = 5):
|
|
def get_photo_records(page: int = 1, size: int = 5):
|
|
|
session = SqlQuery()
|
|
session = SqlQuery()
|
|
|
|
|
+ current_page = page
|
|
|
# photos = CRUD(PhotoRecord)
|
|
# photos = CRUD(PhotoRecord)
|
|
|
print("准备查询拍摄记录", datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
|
|
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)
|
|
.offset((page - 1) * size)
|
|
|
.limit(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 = (
|
|
query = (
|
|
|
select(PhotoRecord, DeviceConfig.action_name)
|
|
select(PhotoRecord, DeviceConfig.action_name)
|
|
|
- .where(PhotoRecord.goods_art_no == item.goods_art_no)
|
|
|
|
|
.join(DeviceConfig, PhotoRecord.action_id == DeviceConfig.id)
|
|
.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()
|
|
session.close()
|
|
|
print("循环查询 完成 ", datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
|
|
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 {
|
|
return {
|
|
|
"code": 0,
|
|
"code": 0,
|
|
|
"msg": "",
|
|
"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(
|
|
resultData = requests.post(
|
|
|
url, files={"file":im}, headers=post_headers
|
|
url, files={"file":im}, headers=post_headers
|
|
|
).json()
|
|
).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}")
|