|
|
@@ -15,14 +15,14 @@ from PIL import Image
|
|
|
from io import BytesIO
|
|
|
import os, re
|
|
|
from functools import partial
|
|
|
-
|
|
|
+from service.customer_template_service import CustomerTemplateService
|
|
|
# from multiprocessing import Process, Queue
|
|
|
import pickle
|
|
|
from .base_deal import BaseDealImage
|
|
|
from middleware import UnicornException
|
|
|
from settings import recordDataPoint
|
|
|
import asyncio
|
|
|
-
|
|
|
+from utils.common import message_queue
|
|
|
|
|
|
class RunMain:
|
|
|
# run_end_sign = Signal(dict)
|
|
|
@@ -35,6 +35,9 @@ class RunMain:
|
|
|
# dialog_result_signal = Signal(str)
|
|
|
|
|
|
# dialog_result_signal = Signal(str)
|
|
|
+
|
|
|
+ # 重试机制配置:最大重试次数(固定为1,避免死循环)
|
|
|
+ MAX_RETRY_COUNT = 1
|
|
|
|
|
|
def __init__(self, windows, token, uuid):
|
|
|
super().__init__()
|
|
|
@@ -186,22 +189,10 @@ class RunMain:
|
|
|
|
|
|
# 抠图校验后的回调函数处理
|
|
|
def check_for_cutout_image_first_call_back(self, return_data):
|
|
|
- # return_data = {
|
|
|
- # "code": 99,
|
|
|
- # "message": "",
|
|
|
- # "data": {
|
|
|
- # "all_goods_art_no_folder_data": [],
|
|
|
- # },
|
|
|
- # }
|
|
|
code = return_data["code"]
|
|
|
config_data = return_data["data"]["config_data"]
|
|
|
config_data["sign_text"] = ""
|
|
|
if code != 0:
|
|
|
- # self.windows.show_message(return_data["message"])
|
|
|
- # self.show_progress_detail(return_data["message"])
|
|
|
- # _dialog_dict = {"text": return_data["message"],
|
|
|
- # "windows": self,
|
|
|
- # }
|
|
|
raise UnicornException(return_data["message"])
|
|
|
|
|
|
do_next = False
|
|
|
@@ -233,27 +224,6 @@ class RunMain:
|
|
|
elif button_1 == "继续" and button_2 is None and button_3 is None:
|
|
|
do_next = True
|
|
|
else:
|
|
|
- # print("runmain 179----------------")
|
|
|
- # # print(self)
|
|
|
- # # print(self.windows)
|
|
|
- # _dialog_dict = {"text": text,
|
|
|
- # "button_1": button_1,
|
|
|
- # "button_2": button_2,
|
|
|
- # "button_3": button_3,
|
|
|
- # "windows": self,
|
|
|
- # }
|
|
|
- # self.show_dialog_sign.emit(_dialog_dict)
|
|
|
- # # self.exec_()
|
|
|
- # # 等待事件被设置
|
|
|
- # self.event.wait()
|
|
|
- # print("self.dialog_result", self.dialog_result)
|
|
|
- # #
|
|
|
- # # my_dialog = DialogShow(self.windows, text=text, button_1=button_1, button_2=button_2,
|
|
|
- # # button_3=button_3)
|
|
|
- # # ret = my_dialog.exec()
|
|
|
- # print("460 ===============my_dialog.flag_name===============")
|
|
|
- # print(my_dialog.flag_name)
|
|
|
-
|
|
|
if "移除" in self.dialog_result:
|
|
|
for error_folder_data in [
|
|
|
x for x in all_goods_art_no_folder_data if x["label"] == "错误"
|
|
|
@@ -270,28 +240,6 @@ class RunMain:
|
|
|
goods_art_no_folder_data["folder_name"]
|
|
|
for goods_art_no_folder_data in all_goods_art_no_folder_data
|
|
|
]
|
|
|
- # try:
|
|
|
- # loop = asyncio.get_event_loop()
|
|
|
- # loop.create_task(sendSocketMessage(
|
|
|
- # code=0,
|
|
|
- # msg="开始处理抠图",
|
|
|
- # data={
|
|
|
- # "status": "进行中",
|
|
|
- # "goods_art_nos": goods_arts,
|
|
|
- # },
|
|
|
- # msg_type="segment_progress",
|
|
|
- # ))
|
|
|
- # except:
|
|
|
- # print('An exception occurred')
|
|
|
- # asyncio.run(sendSocketMessage(
|
|
|
- # code=0,
|
|
|
- # msg="开始处理抠图",
|
|
|
- # data={
|
|
|
- # "status": "进行中",
|
|
|
- # "goods_art_nos": goods_arts,
|
|
|
- # },
|
|
|
- # msg_type="segment_progress",
|
|
|
- # ))
|
|
|
if do_next:
|
|
|
all_goods_art_no_folder_data = [
|
|
|
x for x in all_goods_art_no_folder_data if x["label"] == "待处理"
|
|
|
@@ -312,34 +260,172 @@ class RunMain:
|
|
|
return new_func
|
|
|
else:
|
|
|
print("已结束抠图处理")
|
|
|
- # try:
|
|
|
- # loop = asyncio.get_event_loop()
|
|
|
- # loop.create_task(
|
|
|
- # sendSocketMessage(
|
|
|
- # code=0,
|
|
|
- # msg="抠图结束",
|
|
|
- # data={
|
|
|
- # "status": "已完成",
|
|
|
- # "goods_art_nos": goods_arts,
|
|
|
- # },
|
|
|
- # msg_type="segment_progress",
|
|
|
- # )
|
|
|
- # )
|
|
|
- # except:
|
|
|
- # print('An exception occurred')
|
|
|
- # asyncio.run(
|
|
|
- # sendSocketMessage(
|
|
|
- # code=0,
|
|
|
- # msg="抠图结束",
|
|
|
- # data={
|
|
|
- # "status": "已完成",
|
|
|
- # "goods_art_nos": goods_arts,
|
|
|
- # },
|
|
|
- # msg_type="segment_progress",
|
|
|
- # )
|
|
|
- # )
|
|
|
return True
|
|
|
|
|
|
+ def validate_folder_integrity(self, folder_path, folder_name, expected_output_count=None):
|
|
|
+ """
|
|
|
+ 验证货号文件夹的完整性
|
|
|
+ 检查800x800目录和阴影图处理目录中的文件数量是否等于预期数量
|
|
|
+
|
|
|
+ Args:
|
|
|
+ folder_path: 货号文件夹路径
|
|
|
+ folder_name: 货号名称
|
|
|
+ expected_output_count: 预期的输出文件数量(如果为None则根据原始图数量计算)
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ tuple: (is_valid, original_count, processed_count, expected_count, message)
|
|
|
+ """
|
|
|
+ from logger import logger
|
|
|
+ import settings
|
|
|
+
|
|
|
+ original_dir = "{}/原始图".format(folder_path)
|
|
|
+ processed_dir = "{}/800x800".format(folder_path)
|
|
|
+ shadow_dir = "{}/阴影图处理".format(folder_path)
|
|
|
+
|
|
|
+ # 检查目录是否存在
|
|
|
+ if not os.path.exists(original_dir):
|
|
|
+ logger.warning(f"[目录校验] 货号 {folder_name} - 原始图目录不存在: {original_dir}")
|
|
|
+ return False, 0, 0, 0, f"原始图目录不存在"
|
|
|
+
|
|
|
+ if not os.path.exists(processed_dir):
|
|
|
+ logger.warning(f"[目录校验] 货号 {folder_name} - 800x800目录不存在: {processed_dir}")
|
|
|
+ return False, 0, 0, 0, f"800x800目录不存在"
|
|
|
+
|
|
|
+ if not os.path.exists(shadow_dir):
|
|
|
+ logger.warning(f"[目录校验] 货号 {folder_name} - 阴影图处理目录不存在: {shadow_dir}")
|
|
|
+ return False, 0, 0, 0, f"阴影图处理目录不存在"
|
|
|
+
|
|
|
+ # 统计原始图文件数量(只统计图片文件)
|
|
|
+ _Type = [".png", ".PNG", ".jpg", ".JPG", ".gif", ".GIF", ".jpge", ".JPGE"]
|
|
|
+ original_files = []
|
|
|
+ for f in os.listdir(original_dir):
|
|
|
+ _, ext = os.path.splitext(f)
|
|
|
+ if ext in _Type:
|
|
|
+ original_files.append(f)
|
|
|
+
|
|
|
+ original_count = len(original_files)
|
|
|
+
|
|
|
+ # 统计800x800目录文件数量
|
|
|
+ processed_files = []
|
|
|
+ for f in os.listdir(processed_dir):
|
|
|
+ _, ext = os.path.splitext(f)
|
|
|
+ if ext in _Type:
|
|
|
+ processed_files.append(f)
|
|
|
+
|
|
|
+ processed_count = len(processed_files)
|
|
|
+
|
|
|
+ # 统计阴影图处理目录文件数量
|
|
|
+ shadow_files = []
|
|
|
+ for f in os.listdir(shadow_dir):
|
|
|
+ _, ext = os.path.splitext(f)
|
|
|
+ if ext in _Type:
|
|
|
+ shadow_files.append(f)
|
|
|
+
|
|
|
+ shadow_count = len(shadow_files)
|
|
|
+
|
|
|
+ # 计算预期的输出文件数量
|
|
|
+ if expected_output_count is None:
|
|
|
+ # 从配置中获取主图尺寸列表
|
|
|
+ try:
|
|
|
+ out_pic_size_list = settings.getSysConfigs("basic_configs", "main_image_size", [1600])
|
|
|
+ # 如果是字符串,尝试解析为列表
|
|
|
+ if isinstance(out_pic_size_list, str):
|
|
|
+ import json
|
|
|
+ try:
|
|
|
+ out_pic_size_list = json.loads(out_pic_size_list)
|
|
|
+ except:
|
|
|
+ out_pic_size_list = [1600]
|
|
|
+ # 确保是列表
|
|
|
+ if not isinstance(out_pic_size_list, list):
|
|
|
+ out_pic_size_list = [out_pic_size_list]
|
|
|
+ # 过滤空值
|
|
|
+ out_pic_size_list = [x for x in out_pic_size_list if x]
|
|
|
+
|
|
|
+ if not out_pic_size_list:
|
|
|
+ out_pic_size_list = [1600]
|
|
|
+
|
|
|
+ # 预期输出数量 = 原始图数量 * 尺寸数量
|
|
|
+ expected_count = original_count * len(out_pic_size_list)
|
|
|
+ logger.info(f"[目录校验] 货号 {folder_name} - 配置的输出尺寸: {out_pic_size_list}, 共{len(out_pic_size_list)}个尺寸")
|
|
|
+ except Exception as e:
|
|
|
+ logger.warning(f"[目录校验] 货号 {folder_name} - 获取配置失败,使用默认值: {e}")
|
|
|
+ expected_count = original_count # 默认1倍
|
|
|
+ else:
|
|
|
+ expected_count = expected_output_count
|
|
|
+
|
|
|
+ # 预期的阴影图数量 = 原始图数量 * 2(每个原图生成2个文件:阴影图和抠图)
|
|
|
+ expected_shadow_count = original_count * 2
|
|
|
+
|
|
|
+ logger.info(f"[目录校验] 货号 {folder_name} - 原始图: {original_count}张, 800x800: {processed_count}张, 预期: {expected_count}张, 阴影图: {shadow_count}张, 预期阴影图: {expected_shadow_count}张")
|
|
|
+
|
|
|
+ # 如果原始图为空,认为无效
|
|
|
+ if original_count == 0:
|
|
|
+ logger.error(f"[目录校验] 货号 {folder_name} - 原始图目录为空")
|
|
|
+ return False, original_count, processed_count, expected_count, "原始图目录为空"
|
|
|
+
|
|
|
+ # 严格检查:800x800文件数量必须等于预期数量
|
|
|
+ if processed_count != expected_count:
|
|
|
+ logger.error(f"[目录校验] 货号 {folder_name} - 800x800处理失败: 预期{expected_count}张,实际{processed_count}张 (原始图{original_count}张 × {len(out_pic_size_list) if 'out_pic_size_list' in locals() else '?'}个尺寸)")
|
|
|
+ return False, original_count, processed_count, expected_count, f"800x800文件数量不匹配: 预期{expected_count}张,实际{processed_count}张"
|
|
|
+
|
|
|
+ # 严格检查:阴影图处理文件数量必须等于原始图的2倍
|
|
|
+ if shadow_count != expected_shadow_count:
|
|
|
+ logger.error(f"[目录校验] 货号 {folder_name} - 阴影图处理失败: 预期{expected_shadow_count}张(原始图{original_count}张 × 2),实际{shadow_count}张")
|
|
|
+ return False, original_count, processed_count, expected_count, f"阴影图文件数量不匹配: 预期{expected_shadow_count}张,实际{shadow_count}张"
|
|
|
+
|
|
|
+ logger.info(f"[目录校验] 货号 {folder_name} - 校验通过 ✓")
|
|
|
+ return True, original_count, processed_count, expected_count, "校验通过"
|
|
|
+
|
|
|
+ def retry_single_folder(self, goods_art_no_folder_data, image_order_list, cutout_mode, resize_image_view, logo_path, callback_func):
|
|
|
+ """
|
|
|
+ 重试单个货号的处理(仅执行一次,不会递归或循环)
|
|
|
+
|
|
|
+ Args:
|
|
|
+ goods_art_no_folder_data: 货号文件夹数据
|
|
|
+ image_order_list: 图片顺序列表
|
|
|
+ cutout_mode: 抠图模式
|
|
|
+ resize_image_view: 缩放视角
|
|
|
+ logo_path: Logo路径
|
|
|
+ callback_func: 回调函数
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ bool: 重试是否成功
|
|
|
+ """
|
|
|
+ from logger import logger
|
|
|
+
|
|
|
+ folder_name = goods_art_no_folder_data["folder_name"]
|
|
|
+ folder_path = goods_art_no_folder_data["folder_path"]
|
|
|
+
|
|
|
+ logger.info(f"[重试处理] 开始重试货号: {folder_name} (仅此一次,不会重复重试)")
|
|
|
+ callback_func(f"正在重试货号: {folder_name}")
|
|
|
+
|
|
|
+ deal = BaseDealImage(token=self.token)
|
|
|
+ try:
|
|
|
+ # 只处理这一个货号 - 注意:这里直接调用处理逻辑,不会再触发校验和重试
|
|
|
+ result = deal.shoes_run_one_folder_to_deal(
|
|
|
+ goods_art_no_folder_data=goods_art_no_folder_data,
|
|
|
+ resize_image_view=resize_image_view,
|
|
|
+ logo_path=logo_path,
|
|
|
+ image_order_list=image_order_list,
|
|
|
+ callback_func=callback_func,
|
|
|
+ windows=None,
|
|
|
+ )
|
|
|
+
|
|
|
+ if result:
|
|
|
+ logger.info(f"[重试处理] 货号 {folder_name} 重试成功 ✓")
|
|
|
+ callback_func(f"货号 {folder_name} 重试成功")
|
|
|
+ return True
|
|
|
+ else:
|
|
|
+ logger.error(f"[重试处理] 货号 {folder_name} 重试失败 (不再重试)")
|
|
|
+ callback_func(f"货号 {folder_name} 重试失败")
|
|
|
+ return False
|
|
|
+ except Exception as e:
|
|
|
+ import traceback
|
|
|
+ logger.error(f"[重试处理] 货号 {folder_name} 重试异常: {e}\n{traceback.format_exc()}")
|
|
|
+ callback_func(f"货号 {folder_name} 重试异常: {e}")
|
|
|
+ raise
|
|
|
+ return False
|
|
|
+
|
|
|
def do_run_cutout_image(
|
|
|
self,
|
|
|
all_goods_art_no_folder_data,
|
|
|
@@ -351,6 +437,7 @@ class RunMain:
|
|
|
logo_path,
|
|
|
config_data,
|
|
|
):
|
|
|
+ from logger import logger
|
|
|
try:
|
|
|
loop = asyncio.get_event_loop()
|
|
|
except:
|
|
|
@@ -362,32 +449,83 @@ class RunMain:
|
|
|
]
|
|
|
print("BaseDealImage().run_main========>>>>")
|
|
|
deal = BaseDealImage(token=self.token)
|
|
|
- try:
|
|
|
- loop.run_in_executor(
|
|
|
- executor,
|
|
|
- deal.run_main(
|
|
|
- all_goods_art_no_folder_data=all_goods_art_no_folder_data,
|
|
|
- callback_func=callback_func,
|
|
|
+ deal.run_main(
|
|
|
+ all_goods_art_no_folder_data=all_goods_art_no_folder_data,
|
|
|
+ callback_func=callback_func,
|
|
|
+ image_order_list=image_order_list,
|
|
|
+ cutout_mode=cutout_mode,
|
|
|
+ resize_image_view=resize_image_view,
|
|
|
+ windows=windows,
|
|
|
+ logo_path=logo_path,
|
|
|
+ )
|
|
|
+
|
|
|
+ # ========== 后置校验:检查所有货号的目录完整性 ==========
|
|
|
+ logger.info("=" * 50)
|
|
|
+ logger.info("[后置校验] 开始检查所有货号的目录完整性")
|
|
|
+ logger.info("=" * 50)
|
|
|
+
|
|
|
+ failed_folders = []
|
|
|
+ for goods_art_no_folder_data in all_goods_art_no_folder_data:
|
|
|
+ if goods_art_no_folder_data["label"] != "待处理":
|
|
|
+ continue
|
|
|
+
|
|
|
+ folder_name = goods_art_no_folder_data["folder_name"]
|
|
|
+ folder_path = goods_art_no_folder_data["folder_path"]
|
|
|
+
|
|
|
+ is_valid, original_count, processed_count, expected_count, message = self.validate_folder_integrity(
|
|
|
+ folder_path, folder_name
|
|
|
+ )
|
|
|
+
|
|
|
+ if not is_valid:
|
|
|
+ logger.warning(f"[后置校验] 货号 {folder_name} 校验失败: {message}")
|
|
|
+ failed_folders.append({
|
|
|
+ "data": goods_art_no_folder_data,
|
|
|
+ "reason": message,
|
|
|
+ "original_count": original_count,
|
|
|
+ "processed_count": processed_count,
|
|
|
+ "expected_count": expected_count
|
|
|
+ })
|
|
|
+
|
|
|
+ # ========== 如果有失败的货号,进行重试(仅重试一次,避免死循环)==========
|
|
|
+ if failed_folders:
|
|
|
+ logger.info("=" * 50)
|
|
|
+ logger.info(f"[重试机制] 发现 {len(failed_folders)} 个货号需要重试")
|
|
|
+ logger.info(f"[重试机制] 重要提示:每个货号最多重试 {self.MAX_RETRY_COUNT} 次,不会无限重试")
|
|
|
+ logger.info("=" * 50)
|
|
|
+
|
|
|
+ retry_success_count = 0
|
|
|
+ retry_failed_count = 0
|
|
|
+
|
|
|
+ for failed_item in failed_folders:
|
|
|
+ folder_name = failed_item["data"]["folder_name"]
|
|
|
+ logger.info(f"[重试机制] 开始重试货号: {folder_name}, 原因: {failed_item['reason']}")
|
|
|
+ callback_func(f"检测到 {folder_name} 处理不完整,正在重试...")
|
|
|
+
|
|
|
+ # 执行单次重试(retry_single_folder 内部不会再触发校验和重试)
|
|
|
+ # 注意:这里只调用一次,不会循环或递归
|
|
|
+ retry_result = self.retry_single_folder(
|
|
|
+ goods_art_no_folder_data=failed_item["data"],
|
|
|
image_order_list=image_order_list,
|
|
|
cutout_mode=cutout_mode,
|
|
|
resize_image_view=resize_image_view,
|
|
|
- windows=windows,
|
|
|
logo_path=logo_path,
|
|
|
- ),
|
|
|
- )
|
|
|
- except UnicornException as e:
|
|
|
- raise UnicornException(e.msg)
|
|
|
- except Exception as e:
|
|
|
- raise UnicornException(e)
|
|
|
- # deal.run_main(
|
|
|
- # all_goods_art_no_folder_data=all_goods_art_no_folder_data,
|
|
|
- # callback_func=callback_func,
|
|
|
- # image_order_list=image_order_list,
|
|
|
- # cutout_mode=cutout_mode,
|
|
|
- # resize_image_view=resize_image_view,
|
|
|
- # windows=windows,
|
|
|
- # logo_path=logo_path,
|
|
|
- # )
|
|
|
+ callback_func=callback_func
|
|
|
+ )
|
|
|
+
|
|
|
+ if retry_result:
|
|
|
+ retry_success_count += 1
|
|
|
+ else:
|
|
|
+ retry_failed_count += 1
|
|
|
+ logger.warning(f"[重试机制] 货号 {folder_name} 重试后仍然失败,不再继续重试(已达最大重试次数 {self.MAX_RETRY_COUNT})")
|
|
|
+
|
|
|
+ logger.info("=" * 50)
|
|
|
+ logger.info(f"[重试机制] 重试完成: 成功 {retry_success_count} 个, 失败 {retry_failed_count} 个")
|
|
|
+ logger.info(f"[重试机制] 所有货号处理结束(包含一次重试),流程终止")
|
|
|
+ logger.info("=" * 50)
|
|
|
+
|
|
|
+ callback_func(f"重试完成: 成功 {retry_success_count} 个, 失败 {retry_failed_count} 个")
|
|
|
+ else:
|
|
|
+ logger.info("[后置校验] 所有货号校验通过,无需重试 ✓")
|
|
|
|
|
|
recordDataPoint(
|
|
|
token=self.token,
|
|
|
@@ -395,31 +533,6 @@ class RunMain:
|
|
|
page="抠图结束",
|
|
|
data=goods_arts,
|
|
|
)
|
|
|
- # try:
|
|
|
- # loop = asyncio.get_event_loop()
|
|
|
- # loop.create_task(
|
|
|
- # sendSocketMessage(
|
|
|
- # code=0,
|
|
|
- # msg="抠图结束",
|
|
|
- # data={
|
|
|
- # "status": "已完成",
|
|
|
- # "goods_art_nos": goods_arts,
|
|
|
- # },
|
|
|
- # msg_type="segment_progress",
|
|
|
- # )
|
|
|
- # )
|
|
|
- # except:
|
|
|
- # asyncio.run(
|
|
|
- # sendSocketMessage(
|
|
|
- # code=0,
|
|
|
- # msg="抠图结束",
|
|
|
- # data={
|
|
|
- # "status": "已完成",
|
|
|
- # "goods_art_nos": goods_arts,
|
|
|
- # },
|
|
|
- # msg_type="segment_progress",
|
|
|
- # )
|
|
|
- # )
|
|
|
callback_func("已结束抠图处理")
|
|
|
return True
|
|
|
|
|
|
@@ -471,7 +584,7 @@ class RunMain:
|
|
|
config_data["sign_text"] = "已结束抠图处理"
|
|
|
self.run_end_sign.emit(config_data)
|
|
|
|
|
|
- def check_before_detail(self, config_data):
|
|
|
+ def check_before_detail(self, config_data,is_detail):
|
|
|
|
|
|
# =============
|
|
|
# 整体数据校验,返回错误内容,以及
|
|
|
@@ -522,18 +635,13 @@ class RunMain:
|
|
|
_result = {"code": 99, "message": "无法解析到数据,请检查登录企业"}
|
|
|
print("is_use_excel", is_use_excel)
|
|
|
if not is_use_excel:
|
|
|
- if settings.PROJECT == "红蜻蜓":
|
|
|
- # goods_no_dict输出为文件夹下涉及到的所有款为key的字典,后续通过解析字典,进行提取对应文件夹
|
|
|
+ if is_detail == 1:
|
|
|
_result = self.data_mode_generate_detail.get_basic_goods_art_data_by_hqt_and_hlm(
|
|
|
- folder_name_list
|
|
|
- )
|
|
|
-
|
|
|
- elif settings.PROJECT == "惠利玛":
|
|
|
- if settings.Company:
|
|
|
- if "惠利玛" in settings.Company:
|
|
|
- _result = self.data_mode_generate_detail.get_basic_goods_art_data_by_hqt_and_hlm(
|
|
|
- folder_name_list
|
|
|
- )
|
|
|
+ folder_name_list
|
|
|
+ )
|
|
|
+ else:
|
|
|
+ _result = self.data_mode_generate_detail.makeFakeData(folder_name_list)
|
|
|
+ print("fake data _result", _result)
|
|
|
else:
|
|
|
keys = settings.keys
|
|
|
_result = (
|
|
|
@@ -543,7 +651,7 @@ class RunMain:
|
|
|
keys,
|
|
|
)
|
|
|
)
|
|
|
- print("打印=======>>>>>>>_result=============>", _result)
|
|
|
+ print("打印=======>>>>>>>_result=============>", _result)
|
|
|
if _result["code"] == 0:
|
|
|
remote_data = _result["data"]
|
|
|
else:
|
|
|
@@ -561,7 +669,23 @@ class RunMain:
|
|
|
print("temp_class====>", temp_class)
|
|
|
print("temp_class====>", temp_name)
|
|
|
# 获取所有文件夹基础数据内容 检查不满足要求的文件不满足要求移动到错误文件夹
|
|
|
- need_view_list = temp_class[temp_name].need_view
|
|
|
+ # 在访问 temp_class[temp_name].need_view 前增加检查
|
|
|
+ need_view_list = []
|
|
|
+ if is_detail == 1:
|
|
|
+ if temp_name not in temp_class or temp_class[temp_name] is None:
|
|
|
+ raise UnicornException(f"模板 {temp_name} 未正确初始化或不存在")
|
|
|
+ class_obj = temp_class[temp_name]
|
|
|
+ class_path = class_obj.get("cls")
|
|
|
+ template_type = class_obj.get("template_type")
|
|
|
+ # 确保 temp_class[temp_name] 是可调用的
|
|
|
+ # if template_type ==0:
|
|
|
+ # if not callable(temp_class[temp_name]):
|
|
|
+ # raise UnicornException(f"模板 {temp_name} 不是有效的可调用对象")
|
|
|
+ try:
|
|
|
+ if template_type ==0:
|
|
|
+ need_view_list = class_path.need_view
|
|
|
+ except KeyError as ke:
|
|
|
+ raise UnicornException("未选择详情页模板,请检查")
|
|
|
_all_dir_info_data = get_all_dir_info_and_pic_info(
|
|
|
image_dir, folder_name_list, need_view_list
|
|
|
)
|
|
|
@@ -604,14 +728,14 @@ class RunMain:
|
|
|
"folder_path": "{}/{}".format(image_dir, one_folder),
|
|
|
}
|
|
|
)
|
|
|
- return_data["message"] += "文件夹:{} 找不到对应数据\n".format(
|
|
|
+ return_data["message"] += "文件夹:{} 在系统资料中找不到对应数据\n".format(
|
|
|
one_folder
|
|
|
)
|
|
|
return_data["data"]["config_data"]["success_handler"].append(
|
|
|
{
|
|
|
"goods_art_no": one_folder,
|
|
|
"success": False,
|
|
|
- "info": f"文件夹:{one_folder} 找不到对应数据",
|
|
|
+ "info": f"文件夹:{one_folder} 在系统资料中找不到对应数据",
|
|
|
}
|
|
|
)
|
|
|
|
|
|
@@ -647,7 +771,7 @@ class RunMain:
|
|
|
# 款号反向映射;因为部分key键格式为KUM9999999
|
|
|
_x = {}
|
|
|
for i, v in goods_no_dict.items():
|
|
|
- _x[v["款号"]] = i
|
|
|
+ _x[str(v["款号"])] = i
|
|
|
|
|
|
for goods_no, value in error_data_dict.items():
|
|
|
if goods_no in _x:
|
|
|
@@ -675,7 +799,7 @@ class RunMain:
|
|
|
|
|
|
# 如果没有有效数据则进行退出
|
|
|
if not goods_no_dict:
|
|
|
- return_data["message"] += "没有任何有效数据\n"
|
|
|
+ return_data["message"] += "在系统资料中没有查询到有效数据\n"
|
|
|
return return_data
|
|
|
|
|
|
# 校验无误的文件夹数据 goods_no_dict为最终有效数据
|
|
|
@@ -732,8 +856,11 @@ class RunMain:
|
|
|
if goods_no not in goods_no_need_temps:
|
|
|
continue
|
|
|
for __temp_name in goods_no_need_temps[goods_no]:
|
|
|
- _path = "{}/{}/{}/{}".format(
|
|
|
- image_dir, "软件-详情图生成", __temp_name, goods_no
|
|
|
+ # _path = "{}/{}/{}/{}".format(
|
|
|
+ # image_dir, "软件-详情图生成", __temp_name, goods_no
|
|
|
+ # )
|
|
|
+ _path = "{}/{}/切片图-{}".format(
|
|
|
+ image_dir, f"详情图-{goods_no}",__temp_name
|
|
|
)
|
|
|
if not os.path.exists(_path):
|
|
|
print("款号详情图不存在", _path)
|
|
|
@@ -774,8 +901,6 @@ class RunMain:
|
|
|
_goods_no_dict[goods_no] = value # 需要生成的数据
|
|
|
finally_goods_no_need_temps[goods_no].append(__temp_name)
|
|
|
|
|
|
- pass
|
|
|
-
|
|
|
print("-----------------2goods_no_dict---------------")
|
|
|
print(json.dumps(_goods_no_dict, ensure_ascii=False))
|
|
|
print("-----------------2goods_no_dict---------------")
|
|
|
@@ -790,13 +915,47 @@ class RunMain:
|
|
|
|
|
|
return_data["code"] = 0
|
|
|
return return_data
|
|
|
-
|
|
|
+ def sendAsyncMessage(self,msg="", goods_arts=[], status="",progress={}):
|
|
|
+ """异步发送消息"""
|
|
|
+ data = {
|
|
|
+ "code": 0,
|
|
|
+ "msg": msg,
|
|
|
+ "status": 2,
|
|
|
+ "data": {
|
|
|
+ "status": status,
|
|
|
+ "goods_art_nos": goods_arts,
|
|
|
+ },
|
|
|
+ "progress":{
|
|
|
+ "msg_type":"detail_progress",
|
|
|
+ "name":"详情页",
|
|
|
+ "goods_art_no":progress.get("goods_art_no"),
|
|
|
+ "status":progress.get("status"),
|
|
|
+ "current":progress.get("current",0),
|
|
|
+ "total":progress.get("total",0),
|
|
|
+ "error":progress.get("error",0),
|
|
|
+ "folder":progress.get("folder",None)
|
|
|
+ },
|
|
|
+ "msg_type": "detail_progress",
|
|
|
+ }
|
|
|
+ print("\033[1;32;40m 详情页消息 \033[0m",data)
|
|
|
+ message_queue.put_nowait(data)
|
|
|
def move_error_folders(self, one_path, target_folder, message=""):
|
|
|
if os.path.exists(one_path):
|
|
|
check_path(target_folder)
|
|
|
move_folders(path_list=[one_path], target_folder=target_folder)
|
|
|
-
|
|
|
- def check_for_detail_first_call_back(self, data):
|
|
|
+ '''
|
|
|
+ total_progress = len(all_goods_art_no_folder_data)
|
|
|
+ finish_progress = 0
|
|
|
+ error_progress = 0
|
|
|
+ progress = {"status":"正在处理",
|
|
|
+ "current":finish_progress,
|
|
|
+ "total":total_progress,
|
|
|
+ "error":error_progress}
|
|
|
+ sendAsyncMessage(
|
|
|
+ msg="开始处理抠图", goods_arts=goods_art_nos, status="开始处理",progress=progress
|
|
|
+ )
|
|
|
+ '''
|
|
|
+ def check_for_detail_first_call_back(self, data,request_parmas):
|
|
|
# 首次数据校验的信息返回
|
|
|
# self.show_message(text="22222222222222222222222")
|
|
|
# QMessageBox.critical(self, "警告", "1111111", QMessageBox.Ok)
|
|
|
@@ -867,7 +1026,7 @@ class RunMain:
|
|
|
# self.set_state(state_value=1)
|
|
|
getAllData = data["data"]
|
|
|
base_temp_name = getAllData["temp_name"]
|
|
|
- set_temp_name = getAllData.get("template_name", "")
|
|
|
+ # set_temp_name = getAllData.get("template_name", "")
|
|
|
kwargs = {
|
|
|
"config_data": config_data,
|
|
|
"_goods_no_dict": data["data"]["goods_no_dict"],
|
|
|
@@ -889,6 +1048,7 @@ class RunMain:
|
|
|
assigned_page_dict=kwargs["assigned_page_dict"],
|
|
|
excel_temp_goods_no_data=kwargs["excel_temp_goods_no_data"],
|
|
|
finally_goods_no_need_temps=kwargs["finally_goods_no_need_temps"],
|
|
|
+ request_parmas=request_parmas,
|
|
|
)
|
|
|
# self._w_3 = WorkerOneThread(func=new_func, name="_w_3")
|
|
|
# self._w_3.start()
|
|
|
@@ -908,6 +1068,7 @@ class RunMain:
|
|
|
assigned_page_dict,
|
|
|
excel_temp_goods_no_data,
|
|
|
finally_goods_no_need_temps,
|
|
|
+ request_parmas
|
|
|
):
|
|
|
"""
|
|
|
excel_temp_goods_no_data: {}, # 表格数据可能存在多模板,数据结构为一个款号下的多个模板的数据列表
|
|
|
@@ -922,19 +1083,44 @@ class RunMain:
|
|
|
image_dir = config_data["image_dir"]
|
|
|
|
|
|
# 详情图生成结果文件夹
|
|
|
- out_put_dir = "{}\软件-详情图生成".format(image_dir)
|
|
|
+ # out_put_dir = "{}\软件-详情图生成".format(image_dir)
|
|
|
+ out_put_dir = "{}".format(image_dir)
|
|
|
if settings.IS_TEST:
|
|
|
print("==============_goods_no_dict 打印=================")
|
|
|
|
|
|
print(json.dumps(_goods_no_dict))
|
|
|
|
|
|
print("==============_goods_no_dict 打印-end=================")
|
|
|
-
|
|
|
all_detail_path_list = []
|
|
|
out_put_dir_resp = ""
|
|
|
+ detail_total_progress = len(finally_goods_no_need_temps.items())
|
|
|
+ detail_finish_progress = 0
|
|
|
+ detail_error_progress = 0
|
|
|
+ detail_progress = {"status":"正在处理", "current":detail_finish_progress, "total":detail_total_progress, "error":detail_error_progress}
|
|
|
+ self.sendAsyncMessage(
|
|
|
+ msg="准备处理详情页",
|
|
|
+ goods_arts=[],
|
|
|
+ status="准备处理详情页",
|
|
|
+ progress=detail_progress
|
|
|
+ )
|
|
|
for goods_no, temp_name_list in finally_goods_no_need_temps.items():
|
|
|
for _temp_name in temp_name_list:
|
|
|
try:
|
|
|
+ detail_finish_progress+=1
|
|
|
+ detail_progress = {
|
|
|
+ "status":"正在处理",
|
|
|
+ "goods_art_no":goods_no,
|
|
|
+ "current":detail_finish_progress,
|
|
|
+ "total":detail_total_progress,
|
|
|
+ "error":detail_error_progress,
|
|
|
+ "folder":""
|
|
|
+ }
|
|
|
+ self.sendAsyncMessage(
|
|
|
+ msg="正在处理详情页",
|
|
|
+ goods_arts=[],
|
|
|
+ status="正在处理详情页",
|
|
|
+ progress=detail_progress
|
|
|
+ )
|
|
|
# if _temp_name != "xiaosushuoxie-4":
|
|
|
# continue
|
|
|
assigned_page_list = []
|
|
|
@@ -953,12 +1139,16 @@ class RunMain:
|
|
|
if _key in temp_info_data:
|
|
|
temp_info_data[_key] = _key_value
|
|
|
print("goods_no:{},_temp_name:{}".format(goods_no, _temp_name))
|
|
|
- out_put_dir_resp = "{}/详情模板{}/{}".format(
|
|
|
- out_put_dir, _temp_name, goods_no
|
|
|
- )
|
|
|
- all_detail_path_list.append(
|
|
|
- "{}/详情模板{}/{}".format(out_put_dir, _temp_name, goods_no)
|
|
|
+ # out_put_dir_resp = "{}/详情模板{}/{}".format(
|
|
|
+ # out_put_dir, _temp_name, goods_no
|
|
|
+ # )
|
|
|
+ out_put_dir_resp = "{}/详情图-{}".format(
|
|
|
+ out_put_dir, goods_no
|
|
|
)
|
|
|
+ # all_detail_path_list.append(
|
|
|
+ # "{}/详情模板{}/{}".format(out_put_dir, _temp_name, goods_no)
|
|
|
+ # )
|
|
|
+ all_detail_path_list.append(out_put_dir_resp)
|
|
|
# continue
|
|
|
self.detail_deal_one_data(
|
|
|
goods_no=goods_no,
|
|
|
@@ -973,6 +1163,13 @@ class RunMain:
|
|
|
config_data["success_handler"].append(
|
|
|
{"goods_art_no": goods_no, "success": True, "info": "处理成功"}
|
|
|
)
|
|
|
+ detail_progress["folder"] = out_put_dir_resp
|
|
|
+ self.sendAsyncMessage(
|
|
|
+ msg="开始处理详情页",
|
|
|
+ goods_arts=[],
|
|
|
+ status="开始处理详情页",
|
|
|
+ progress=detail_progress
|
|
|
+ )
|
|
|
recordDataPoint(
|
|
|
token=self.token,
|
|
|
uuid=self.uuid,
|
|
|
@@ -980,6 +1177,15 @@ class RunMain:
|
|
|
data={"goods_art_no": goods_no, "temp_name": _temp_name},
|
|
|
)
|
|
|
except BaseException as e:
|
|
|
+ print("详情页打印输出错误信息===>",e)
|
|
|
+ detail_error_progress+=1
|
|
|
+ detail_progress = {"status":"处理失败","goods_art_no":goods_no, "current":detail_finish_progress, "total":detail_total_progress, "error":detail_error_progress,"folder":""}
|
|
|
+ self.sendAsyncMessage(
|
|
|
+ msg="处理失败",
|
|
|
+ goods_arts=[],
|
|
|
+ status="处理失败",
|
|
|
+ progress=detail_progress
|
|
|
+ )
|
|
|
self.show_progress_detail(
|
|
|
{
|
|
|
"goods_art_no": goods_no,
|
|
|
@@ -987,7 +1193,6 @@ class RunMain:
|
|
|
"info": "款:{}生成详情异常:{}".format(goods_no, e),
|
|
|
}
|
|
|
)
|
|
|
- print(e)
|
|
|
# raise UnicornException("款:{}生成详情异常:{}".format(goods_no, e))
|
|
|
config_data["success_handler"].append(
|
|
|
{
|
|
|
@@ -1025,132 +1230,23 @@ class RunMain:
|
|
|
print("out_put_dir_resp", out_put_dir_resp)
|
|
|
# 打开文件夹
|
|
|
# os.startfile(out_put_dir)
|
|
|
-
|
|
|
+ detail_finish_progress = self.total_num - self.fail_num
|
|
|
+ text_status = "处理完成" if detail_finish_progress > 0 else "处理失败"
|
|
|
+ detail_progress = {
|
|
|
+ "status":text_status,
|
|
|
+ "current":detail_finish_progress,
|
|
|
+ "total":self.total_num,
|
|
|
+ "error":self.fail_num,
|
|
|
+ "folder":out_put_dir_resp[0] if text_status=="处理完成" else "",
|
|
|
+ }
|
|
|
+ self.sendAsyncMessage(
|
|
|
+ msg=text_status,
|
|
|
+ goods_arts=[],
|
|
|
+ status=text_status,
|
|
|
+ progress=detail_progress
|
|
|
+ )
|
|
|
return config_data
|
|
|
|
|
|
- def detail_run_by_thread11111(
|
|
|
- self,
|
|
|
- config_data,
|
|
|
- _goods_no_dict,
|
|
|
- temp_name,
|
|
|
- temp_name_list,
|
|
|
- assigned_page_dict,
|
|
|
- excel_temp_goods_no_data,
|
|
|
- finally_goods_no_need_temps,
|
|
|
- ):
|
|
|
- """
|
|
|
- excel_temp_goods_no_data: {}, # 表格数据可能存在多模板,数据结构为一个款号下的多个模板的数据列表
|
|
|
- finally_goods_no_need_temps: {}, # 每个款号需要生成的模板数据
|
|
|
- """
|
|
|
-
|
|
|
- # 开始处理
|
|
|
- self.n = 0
|
|
|
- self.total_num = len(_goods_no_dict)
|
|
|
- self.fail_num = 0
|
|
|
- is_use_excel = config_data["is_use_excel"]
|
|
|
- image_dir = config_data["image_dir"]
|
|
|
-
|
|
|
- # 详情图生成结果文件夹
|
|
|
- out_put_dir = "{}\软件-详情图生成".format(image_dir)
|
|
|
- if settings.IS_TEST:
|
|
|
- print("==============_goods_no_dict 打印=================")
|
|
|
-
|
|
|
- print(json.dumps(_goods_no_dict))
|
|
|
-
|
|
|
- print("==============_goods_no_dict 打印-end=================")
|
|
|
-
|
|
|
- if settings.IS_TEST:
|
|
|
- max_workers = 1
|
|
|
- else:
|
|
|
- max_workers = 1
|
|
|
-
|
|
|
- all_detail_path_list = []
|
|
|
-
|
|
|
- with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
|
|
|
- futures = []
|
|
|
- for goods_no, temp_name_list in finally_goods_no_need_temps.items():
|
|
|
- for _temp_name in temp_name_list:
|
|
|
- # if _temp_name != "xiaosushuoxie-4":
|
|
|
- # continue
|
|
|
-
|
|
|
- assigned_page_list = []
|
|
|
- if _temp_name in assigned_page_dict:
|
|
|
- assigned_page_list = assigned_page_dict[_temp_name]
|
|
|
- # 如果为使用表格,则获取表格中的数据作为款号的基础数据
|
|
|
- temp_info_data = copy.copy(_goods_no_dict[goods_no])
|
|
|
- if is_use_excel:
|
|
|
- # 将表格中的数据进行替换
|
|
|
- if goods_no in excel_temp_goods_no_data:
|
|
|
- if _temp_name in excel_temp_goods_no_data[goods_no]:
|
|
|
- # 将表格中的特定的模板的行,替换到goods_no的data中,因为不同的模板有数据特殊性
|
|
|
- print("xxxxxx====>", excel_temp_goods_no_data[goods_no])
|
|
|
- for _key, _key_value in excel_temp_goods_no_data[
|
|
|
- goods_no
|
|
|
- ][_temp_name].items():
|
|
|
- if _key in temp_info_data:
|
|
|
- temp_info_data[_key] = _key_value
|
|
|
-
|
|
|
- print("temp_info_data11111111111111111111111")
|
|
|
- print("goods_no:{},_temp_name:{}".format(goods_no, _temp_name))
|
|
|
- all_detail_path_list.append(
|
|
|
- "{}/{}/".format(out_put_dir, _temp_name, goods_no)
|
|
|
- )
|
|
|
- # continue
|
|
|
- futures.append(
|
|
|
- executor.submit(
|
|
|
- self.detail_deal_one_data,
|
|
|
- goods_no=goods_no,
|
|
|
- value=temp_info_data,
|
|
|
- out_put_dir=out_put_dir,
|
|
|
- temp_name=_temp_name,
|
|
|
- assigned_page_list=assigned_page_list,
|
|
|
- )
|
|
|
- )
|
|
|
-
|
|
|
- # for goods_no, value in _goods_no_dict.items():
|
|
|
- # _temp_name = temp_name
|
|
|
- # # 使用自定义的表格数据
|
|
|
- # if self.isUseTemplate is False:
|
|
|
- # if "模板名称" in value:
|
|
|
- # if value["模板名称"] in temp_name_list:
|
|
|
- # _temp_name = value["模板名称"]
|
|
|
- # assigned_page_list = []
|
|
|
- # if _temp_name in assigned_page_dict:
|
|
|
- # assigned_page_list = assigned_page_dict[_temp_name]
|
|
|
- #
|
|
|
- # futures.append(executor.submit(
|
|
|
- # self.deal_one_data,
|
|
|
- # goods_no=goods_no,
|
|
|
- # value=value,
|
|
|
- # out_put_dir=out_put_dir,
|
|
|
- # temp_name=_temp_name,
|
|
|
- # assigned_page_list=assigned_page_list,
|
|
|
- # ))
|
|
|
-
|
|
|
- # 使用 wait 方法等待所有任务完成
|
|
|
- done, not_done = concurrent.futures.wait(futures)
|
|
|
-
|
|
|
- # 处理完成的任务
|
|
|
- for future in done:
|
|
|
- if settings.IS_TEST:
|
|
|
- result = future.result()
|
|
|
-
|
|
|
- # ==============完成处理==============
|
|
|
- self.set_state(state_value=2)
|
|
|
- if self.total_num:
|
|
|
- if self.fail_num:
|
|
|
- self.show_progress_detail(
|
|
|
- "处理完成,-----------处理失败数据:{}个款".format(self.fail_num)
|
|
|
- )
|
|
|
- else:
|
|
|
- self.show_progress_detail("处理完成")
|
|
|
- else:
|
|
|
- self.show_progress_detail("没有任何数据")
|
|
|
-
|
|
|
- config_data["sign_text"] = "已结束详情处理"
|
|
|
- config_data["all_detail_path_list"] = all_detail_path_list
|
|
|
- self.run_end_sign.emit(config_data)
|
|
|
-
|
|
|
def show_progress_detail(self, text):
|
|
|
# self.show_progress_detail_sign.emit(text)
|
|
|
# self.windows.show_progress_detail(text)
|
|
|
@@ -1168,29 +1264,30 @@ class RunMain:
|
|
|
target_error_folder,
|
|
|
image_dir,
|
|
|
):
|
|
|
+ # 模板类型,0系统模板,1自定义模板
|
|
|
+ # 自定义模板数据
|
|
|
# if self.windows.state == 99:
|
|
|
# self.show_progress_detail("用户主动取消:{}".format(goods_no))
|
|
|
# return
|
|
|
self.show_progress_detail("正在生成:{},模板:{}".format(goods_no, temp_name))
|
|
|
is_deal_success = False
|
|
|
+ class_obj = temp_class[temp_name]
|
|
|
+ class_path = class_obj.get("cls")
|
|
|
+ template_type = class_obj.get("template_type")
|
|
|
print("=================deal_one_data=====================")
|
|
|
print("goods_no", goods_no)
|
|
|
print("模板:", temp_name)
|
|
|
print("value:", value)
|
|
|
print("temp_class:", temp_class)
|
|
|
- if settings.IS_TEST:
|
|
|
- temp_class[temp_name](
|
|
|
- goods_no,
|
|
|
- value,
|
|
|
- out_put_dir=out_put_dir,
|
|
|
- windows=self.windows,
|
|
|
- assigned_page_list=assigned_page_list,
|
|
|
- )
|
|
|
- is_deal_success = True
|
|
|
- else:
|
|
|
+ print("class_obj:", class_obj)
|
|
|
+ if temp_name not in temp_class or temp_class[temp_name] is None:
|
|
|
+ raise UnicornException(f"详情页模板 {temp_name} 未正确加载")
|
|
|
+ if template_type == 0:
|
|
|
+ # if not callable(class_path):
|
|
|
+ # raise UnicornException(f"详情页模板 {temp_name} 不是有效的可调用对象")
|
|
|
try:
|
|
|
# # 处理图片详情图生成
|
|
|
- temp_class[temp_name](
|
|
|
+ class_path(
|
|
|
goods_no,
|
|
|
value,
|
|
|
out_put_dir=out_put_dir,
|
|
|
@@ -1212,7 +1309,21 @@ class RunMain:
|
|
|
raise UnicornException(
|
|
|
"{}处理失败,失败原因:{}".format(goods_no, error_text)
|
|
|
)
|
|
|
-
|
|
|
+ else:
|
|
|
+ try:
|
|
|
+ is_deal_success = True
|
|
|
+ service = CustomerTemplateService()
|
|
|
+ save_path = f"{out_put_dir}/详情图-{goods_no}"
|
|
|
+ print("传递的class信息====>",class_path)
|
|
|
+ service.generateTemplate(value,class_path,temp_name,save_path)
|
|
|
+ except BaseException as e:
|
|
|
+ self.show_progress_detail("{}处理失败".format(goods_no))
|
|
|
+ error_text = "{}".format(e)
|
|
|
+ print("error_text",error_text)
|
|
|
+ print(f"发生错误的行号: {e.__traceback__.tb_lineno}")
|
|
|
+ print(
|
|
|
+ f"发生错误的文件: {e.__traceback__.tb_frame.f_globals['__file__']}"
|
|
|
+ )
|
|
|
self.n += 1
|
|
|
|
|
|
if not is_deal_success:
|