import settings from .detail_func import * import json from .base import * # from .match_and_cutout_mode_control.base_deal_image_v2 import BaseDealImage # from module.view_control.MineQWidget import DialogShow, WorkerOneThread import threading from concurrent.futures import ThreadPoolExecutor import concurrent.futures from .data import DataModeGenerateDetail import time from PIL import Image from io import BytesIO import os, re from functools import partial # from multiprocessing import Process, Queue import pickle from .base_deal import BaseDealImage from middleware import UnicornException class RunMain(): # run_end_sign = Signal(dict) # show_dialog_sign = Signal(dict) # show_progress_detail_sign = Signal(str) # # 定义一个信号用于请求显示对话框 # show_dialog_signal = Signal() # # 定义一个信号用于返回对话框的结果 # dialog_result_signal = Signal(str) # dialog_result_signal = Signal(str) def __init__(self, windows, token): super().__init__() self.windows = windows self.token = token self.dialog_result = "" self.data_mode_generate_detail = DataModeGenerateDetail(token=token) # self.dialog_result_signal.connect(self.on_dialog_result) self.event = threading.Event() def set_state(self, state_value: int): # 0禁用 1进行中 2已结束 if state_value not in [0, 1, 2, 99]: return # self.windows.change_state_sign.emit(state_value) # self.windows.set_state(state_value) # 抠图前先做数据规整处理;类似详情图生成逻辑 def check_before_cutout(self, config_data): return_data = { "code": 99, "message": "", "data": { "all_goods_art_no_folder_data": [], "config_data": config_data, }, } image_dir = config_data["image_dir"] image_order = config_data["image_order"] is_check_number = config_data["is_check_number"] is_filter = config_data["cutout_is_pass"] resize_image_view = config_data["resize_image_view"] logo_path = config_data["logo_path"] cutout_mode = config_data["cutout_mode"] # 是否精细化抠图,默认为普通抠图 special_goods_art_no_folder_line = config_data["special_goods_art_no_folder_line"] # 自动处理红蜻蜓货号,进行重命名 # if settings.PROJECT == "红蜻蜓": # # 规整红蜻蜓货号图 # all_goods_art_no_folder_data = get_all_goods_art_no_folder(path=image_dir) # BaseDealImage().rename_folder_for_hqt(all_goods_art_no_folder_data=all_goods_art_no_folder_data) # 重新获取文件夹信息 all_goods_art_no_folder_data = get_all_goods_art_no_folder(path=image_dir) f = True is_do_other = False if is_do_other: for i in all_goods_art_no_folder_data: i["label"] = "不处理" is_filter = False specified_goods_art_no_folder = special_goods_art_no_folder_line specified_goods_art_no_folder = specified_goods_art_no_folder.strip() specified_goods_art_no_folder = specified_goods_art_no_folder.replace(",", ",") specified_goods_art_no_folder_list = specified_goods_art_no_folder.split(",") specified_goods_art_no_folder_list = [x for x in specified_goods_art_no_folder_list if x] if not specified_goods_art_no_folder_list: return_data["message"] += '请手动输入文件夹名称(多选),或关闭指定文件夹模式\n' else: for i in all_goods_art_no_folder_data: if i["folder_path"] in specified_goods_art_no_folder_list: i["label"] = "待处理" # 哪些数据不合规 all_folder_name_list = [x["folder_name"] for x in all_goods_art_no_folder_data] for goods_art_no_folder_name in specified_goods_art_no_folder_list: if goods_art_no_folder_name not in all_folder_name_list: return_data["message"] += '文件夹:{},在您选的目录下不存在\n'.format(goods_art_no_folder_name) f = False if not f: # raise UnicornException(return_data["message"]) self.set_state(state_value=2) return # 清空指定文件夹的已抠图文件 if is_do_other: for folder_data in all_goods_art_no_folder_data: goods_art_no_folder_path = "{}/原始图_已抠图".format(folder_data["folder_path"]) if os.path.exists(goods_art_no_folder_path): remove_all_file(goods_art_no_folder_path) return_data["data"]["succeed_folder_list"] = 1 # ==================检查填写的图片视角是否符合要求 res = BaseDealImage(token=self.token).getImageOrder( image_order=image_order, resize_image_view=resize_image_view ) if res['code'] != 0: return_data["message"] += "{}\n".format(res['msg']) # raise UnicornException(return_data["message"]) return return_data else: # 图片命名顺序 image_order_list = res['imageOrderList'] print("图片命名顺序", image_order_list) for goods_art_no_folder_data in all_goods_art_no_folder_data: if goods_art_no_folder_data["label"] != "待处理": continue goods_art_no_folder_data["image_order_list"] = image_order_list # ================是否过滤已有生成的文件夹 if is_filter: for goods_art_no_folder_data in all_goods_art_no_folder_data: if goods_art_no_folder_data["label"] != "待处理": continue folder_path = goods_art_no_folder_data["folder_path"] _p = "{}/800x800".format(folder_path) if os.path.exists(_p): if len(os.listdir(_p)): goods_art_no_folder_data["label"] = "不处理" # ================检查每个货号文件夹图片数量是否符合要求 all_goods_art_no_folder_data, message = BaseDealImage(token=self.token).check_folders_image_amount(all_goods_art_no_folder_data, image_order_list) if message: return_data["message"] += "{}\n".format(message) return_data["code"] = 0 return_data["data"]["all_goods_art_no_folder_data"] = all_goods_art_no_folder_data return_data["data"]["image_dir"] = image_dir return_data["data"]["resize_image_view"] = resize_image_view return_data["data"]["cutout_mode"] = cutout_mode return_data["data"]["image_order_list"] = image_order_list return_data["data"]["logo_path"] = logo_path return return_data # 抠图校验后的回调函数处理 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 text = "" all_goods_art_no_folder_data = return_data["data"]["all_goods_art_no_folder_data"] button_1, button_2, button_3 = None, None, None text += return_data["message"] # 存在错误文件夹 error_folder = [x for x in all_goods_art_no_folder_data if x["label"] == "错误"] todo_folder = [x for x in all_goods_art_no_folder_data if x["label"] == "待处理"] if error_folder: button_2 = "移除错误文件" if error_folder and todo_folder: button_1 = "移除并继续" button_3 = "继续(忽略其他)" if not error_folder and todo_folder: button_1 = "继续" # do_next = True text += "\n==================\n错误数据:{}个,校验无误数据:{}个".format(len(error_folder), len(todo_folder)) self.show_progress_detail(text) if button_1 is None and button_2 is None and button_3 is None: pass 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"] == "错误"]: self.move_error_folders( one_path=error_folder_data["folder_path"], target_folder="{}/软件-处理失败".format(config_data["image_dir"]), ) if "继续" in self.dialog_result: do_next = True if do_next: all_goods_art_no_folder_data = [x for x in all_goods_art_no_folder_data if x["label"] == "待处理"] print("===============all_goods_art_no_folder_data===============") print(all_goods_art_no_folder_data) new_func = partial(self.do_run_cutout_image, all_goods_art_no_folder_data=all_goods_art_no_folder_data, callback_func=self.show_progress_detail, image_order_list=return_data["data"]["image_order_list"], cutout_mode=return_data["data"]["cutout_mode"], resize_image_view=return_data["data"]["resize_image_view"], windows=None, logo_path=return_data["data"]["logo_path"], config_data=config_data) return new_func() # self.t = threading.Thread(target=self.do_run_cutout_image, # kwargs={"all_goods_art_no_folder_data": all_goods_art_no_folder_data, # "callback_func": self.show_progress_detail, # "image_order_list": return_data["data"]["image_order_list"], # "cutout_mode": return_data["data"]["cutout_mode"], # "resize_image_view": return_data["data"]["resize_image_view"], # "windows": self.windows, # "logo_path": return_data["data"]["logo_path"], # "config_data": config_data, # }) # self.t.start() else: # config_data["sign_text"] = "已结束抠图处理" # self.run_end_sign.emit(config_data) print("已结束抠图处理") return True def do_run_cutout_image(self, all_goods_art_no_folder_data, callback_func, image_order_list, cutout_mode, resize_image_view, windows, logo_path, config_data): print("BaseDealImage().run_main========>>>>") BaseDealImage(token=self.token).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, ) # ==============完成处理============== # self.set_state(state_value=2) callback_func("已结束抠图处理") return True # config_data["sign_text"] = "已结束抠图处理" # self.run_end_sign.emit(config_data) def do_run_cutout_image1111(self, all_goods_art_no_folder_data, callback_func, image_order_list, cutout_mode, resize_image_view, windows, logo_path, config_data): max_workers = 1 with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: futures = [] futures.append(executor.submit( BaseDealImage().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, )) # 使用 wait 方法等待所有任务完成 done, not_done = concurrent.futures.wait(futures, timeout=60) # 处理完成的任务 for future in done: if settings.IS_TEST: result = future.result() else: try: result = future.result() except BaseException as e: print("2039 图片处理失败.{}".format(e)) callback_func("2039 处理失败.{}".format(e)) # ==============完成处理============== # self.set_state(state_value=2) callback_func("已结束抠图处理") config_data["sign_text"] = "已结束抠图处理" self.run_end_sign.emit(config_data) def check_before_detail(self, config_data): # ============= # 整体数据校验,返回错误内容,以及 # temp_name:模板名称 """ 步骤: 1、 整体文件夹检查,并输出数据结构 2、数据进行对应规整(可能有excel,红蜻蜓等) 3、执行单个款数据处理 """ return_data = { "code": 99, "message": "", "data": { "error_folder_list": [], "goods_no_dict": {}, "succeed_folder_list": [], "temp_name": config_data["temp_name"], "temp_name_list": config_data["temp_name_list"], "assigned_page_dict": config_data["assigned_page_dict"], "excel_temp_goods_no_data": {}, # 表格数据可能存在多模板,数据结构为一个款号下的多个模板的数据列表 "finally_goods_no_need_temps": {}, # 每个款号需要生成的模板数据 "config_data": config_data, }, } temp_name = config_data["temp_name"] temp_name_list = config_data["temp_name_list"] assigned_page_dict = config_data["assigned_page_dict"] image_dir = config_data["image_dir"] is_use_excel = config_data["is_use_excel"] excel_path = config_data["excel_path"] temp_class = config_data["temp_class"] goods_art_no = config_data["goods_art_no"] is_check_color_is_all = config_data["is_check_color_is_all"] detail_is_pass = config_data["detail_is_pass"] error_folder_list = [] # 遍历货号获取所有货号--可能为编号 folder_name_list = get_all_dir_info( image_dir=image_dir, goods_art_no=goods_art_no ) if not folder_name_list: return_data["message"] += "不存在任何货号/编号文件夹\n" print("不存在任何货号/编号文件夹") return return_data # =========================组装数据---数据来源多种途径========================= _result = {"code": 99, "message": "无法解析到数据,请检查登录企业"} if not is_use_excel: if settings.PROJECT == "红蜻蜓": # goods_no_dict输出为文件夹下涉及到的所有款为key的字典,后续通过解析字典,进行提取对应文件夹 _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 ) # print("is_use_excel") else: keys = settings.keys _result = ( self.data_mode_generate_detail.get_basic_goods_art_data_form_excel( folder_name_list, excel_path, keys, ) ) if _result["code"] == 0: remote_data = _result["data"] else: print('_result["message"]====>', _result["message"]) return_data["message"] += _result["message"] + "\n" return return_data # print(json.dumps(remote_data)) # =========================拼接数据组合为款数据========================= """ 1、获取所有文件夹基础数据内容 2、结合上述返回结果进行数据组合拼接 3、输出结果为按款为主键信息 4、注意模板ID """ # 获取所有文件夹基础数据内容 检查不满足要求的文件不满足要求移动到错误文件夹 need_view_list = temp_class[temp_name].need_view _all_dir_info_data = get_all_dir_info_and_pic_info( image_dir, folder_name_list, need_view_list ) all_dir_info_data = {} for one_folder, value in _all_dir_info_data.items(): if "message" in value: if value["message"]: error_folder_list.append( { "folder_name": one_folder, "folder_path": "{}/{}".format(image_dir, one_folder), } ) return_data["message"] += "文件夹:{} 结构错误:{}\n".format( one_folder, value["message"] ) continue # 符合要求的数据处理 all_dir_info_data[one_folder] = value # 结合上述返回结果进行数据组合拼接 # 返回可能存在的情况:1、存在文件夹不匹配数据,2、存在货号数据缺失 goods_no_dict, error_folder_name_list = merge_local_and_remote_data( all_dir_info_data=all_dir_info_data, remote_data=remote_data ) # 文件在系统中没有匹配的结果 if error_folder_name_list: for one_folder in error_folder_name_list: error_folder_list.append( { "folder_name": one_folder, "folder_path": "{}/{}".format(image_dir, one_folder), } ) return_data["message"] += "文件夹:{} 找不到对应数据\n".format( one_folder ) print("===============goods_no_dict==================") if settings.IS_TEST: _text = json.dumps(goods_no_dict) print(goods_no_dict) create_folder("qt_test") with open("qt_test/goods_no_dict.txt", 'w', encoding='utf-8') as file: file.write(_text) print("===============goods_no_dict==================") # ===================================是否齐色检查============================================= # 如为红蜻蜓企业则还需要检查同款下是否齐全;数据返回结果为款号列表 error_data_dict = {} if is_check_color_is_all: if not is_use_excel: if settings.PROJECT == "红蜻蜓": error_data_dict = ( self.data_mode_generate_detail.check_goods_is_not_deficiency( goods_no_dict ) ) else: error_data_dict = self.data_mode_generate_detail.check_goods_is_not_deficiency_form_excel( goods_no_dict, excel_path ) if error_data_dict: print("----error_data_dict----") print(json.dumps(error_data_dict)) # 款号反向映射;因为部分key键格式为KUM9999999 _x = {} for i, v in goods_no_dict.items(): _x[v["款号"]] = i for goods_no, value in error_data_dict.items(): if goods_no in _x: goods_no = _x[goods_no] if goods_no in goods_no_dict: # =====移动到错误文件夹====== for _folder_name in [ x["文件夹名称"] for x in goods_no_dict[goods_no]["货号资料"] ]: error_folder_list.append( { "folder_name": _folder_name, "folder_path": "{}\{}".format( image_dir, _folder_name ), } ) return_data["message"] += "文件夹:{};{}\n".format( _folder_name, value["message"] ) # 从 正确 款下面进行数据剔除 goods_no_dict.pop(goods_no) print("-----------------1goods_no_dict---------------") print(json.dumps(goods_no_dict, ensure_ascii=False)) print("-----------------1goods_no_dict---------------") # 如果没有有效数据则进行退出 if not goods_no_dict: return_data["message"] += "没有任何有效数据\n" return return_data # 校验无误的文件夹数据 goods_no_dict为最终有效数据 for goods_no, value in goods_no_dict.items(): return_data["data"]["succeed_folder_list"].extend( [x["文件夹名称"] for x in goods_no_dict[goods_no]["货号资料"]] ) # 如果是表格数据,则获取表格数据中需要生成的货号 # 数据结构 # {“款号1”: # {“模板名称1”:data_dict1, # “模板名称2”:data_dict2, # }} if is_use_excel: excel_temp_goods_no_data = self.data_mode_generate_detail.get_basic_template_information( _goods_no_dict=goods_no_dict, excel_path=excel_path) else: excel_temp_goods_no_data = {} print("731===================excel_temp_goods_no_data,is_use_excel:{}".format(is_use_excel)) print(json.dumps(excel_temp_goods_no_data)) # ===========数据组装,统计每个款需要生成哪些模板============== # 不适用表格指定模板 goods_no_need_temps = {} # isUseTemplate 为false 表示使用excel表格数据 if not is_use_excel: for i in goods_no_dict: goods_no_need_temps[i] = [temp_name] else: for i in goods_no_dict: # i 为款号 if i in excel_temp_goods_no_data: # 获取 某个款号的所有允许生成的模板列表 goods_no_need_temps[i] = list(excel_temp_goods_no_data[i].keys()) # ========开始执行详情图生成=================== # _goods_no_dict = goods_no_dict _goods_no_dict = {} # assigned_page_dict 如存在对应模板的,则不管是否有过滤都需要生成 # 检查是否已存在模板,已存在的需要进行跳过;可能部分模板已存在,部分不存在。 finally_goods_no_need_temps = {} for goods_no, value in goods_no_dict.items(): 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) if not os.path.exists(_path): print("款号详情图不存在", _path) if goods_no not in finally_goods_no_need_temps: finally_goods_no_need_temps[goods_no] = [] _goods_no_dict[goods_no] = value # 需要生成的数据 finally_goods_no_need_temps[goods_no].append(__temp_name) else: print("款号详情图存在", _path) # 如果在指定模板中存在,则也需要生成 if __temp_name in assigned_page_dict: print("指定模板需要更新", _path) if goods_no not in finally_goods_no_need_temps: finally_goods_no_need_temps[goods_no] = [] _goods_no_dict[goods_no] = value # 需要生成的数据 finally_goods_no_need_temps[goods_no].append(__temp_name) else: # output/2025-04-03/软件-详情图生成/huilima-2/AQN141132 return_data["data"]["config_data"]["out_put_dir"] = _path if detail_is_pass: return_data["message"] += "\n款号:{},模板:{} 已存在".format(goods_no, __temp_name) else: if goods_no not in finally_goods_no_need_temps: finally_goods_no_need_temps[goods_no] = [] _goods_no_dict[goods_no] = value # 需要生成的数据 finally_goods_no_need_temps[goods_no].append(__temp_name) pass # _path = "{}/{}".format(self.image_dir, "软件-详情图生成") # if os.path.exists(_path): # _goods_no_dict = {} # # 数据返回为 已有的款数据,为款号列表 # is_pass_goods_no = detail_func.get_all_detail_info(_path) # for goods_no, value in goods_no_dict.items(): # if "软件" in goods_no: # continue # # if value["模板名称"] in assigned_page_dict: # need_todo = True # else: # if goods_no in is_pass_goods_no: # need_todo = False # else: # need_todo = True # if need_todo: # _goods_no_dict[goods_no] = value print("-----------------2goods_no_dict---------------") print(json.dumps(_goods_no_dict, ensure_ascii=False)) print("-----------------2goods_no_dict---------------") return_data["data"]["error_folder_list"] = error_folder_list if len(_goods_no_dict) == 0: return_data["message"] += "\n没有任何文件夹需要执行" return_data["data"]["goods_no_dict"] = _goods_no_dict return_data["data"]["excel_temp_goods_no_data"] = excel_temp_goods_no_data return_data["data"]["finally_goods_no_need_temps"] = finally_goods_no_need_temps return_data["code"] = 0 return return_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): # 首次数据校验的信息返回 # self.show_message(text="22222222222222222222222") # QMessageBox.critical(self, "警告", "1111111", QMessageBox.Ok) code = data["code"] config_data = data["data"]["config_data"] target_error_folder = config_data["target_error_folder"] print("635 check_for_detail_first_call_back") print(data) if code != 0: raise UnicornException(data["message"]) return False do_next = False if data["message"]: button_1, button_2, button_3 = None, None, None text = data["message"] if code == 0: if data["data"]: if data["data"]["error_folder_list"]: print("22----------error_folder_list------------") print(json.dumps(data["data"]["error_folder_list"])) button_2 = "移除错误文件" if data["data"]["goods_no_dict"]: if button_2: button_1 = "移除并继续" button_3 = "继续(忽略其他)" else: button_1 = "继续" if data["data"]["succeed_folder_list"]: text += "\n==================\n校验无误数据:{}个文件夹".format( len(data["data"]["succeed_folder_list"]) ) self.show_progress_detail(text=data["message"]) if button_1 is None and button_2 is None and button_3 is None: pass elif button_1 == "继续" and button_2 is None and button_3 is None: do_next = True else: print("runmain 642----------------") # todo 弹框修改处理等 _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.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 # ) print("my_dialog.flag_name", self.dialog_result) if "移除" in self.dialog_result: for error_folder_data in data["data"]["error_folder_list"]: self.move_error_folders( one_path=error_folder_data["folder_path"], target_folder=target_error_folder, ) if "继续" in self.dialog_result: do_next = True if data["data"]["goods_no_dict"] and not data["data"]["error_folder_list"]: do_next = True if do_next: # self.set_state(state_value=1) getAllData = data["data"] base_temp_name = getAllData["temp_name"] set_temp_name = getAllData.get("template_name", "") kwargs = { "config_data": config_data, "_goods_no_dict": data["data"]["goods_no_dict"], "temp_name": base_temp_name, "temp_name_list": data["data"]["temp_name_list"], "assigned_page_dict": data["data"]["assigned_page_dict"], "excel_temp_goods_no_data": data["data"]["excel_temp_goods_no_data"], # 表格数据可能存在多模板,数据结构为一个款号下的多个模板的数据列表 "finally_goods_no_need_temps": data["data"]["finally_goods_no_need_temps"], # 每个款号需要生成的模板数据 } # todo work new_func = partial(self.detail_run_by_thread, config_data=kwargs["config_data"], _goods_no_dict=kwargs["_goods_no_dict"], temp_name=kwargs["temp_name"], temp_name_list=kwargs["temp_name_list"], 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"]) # self._w_3 = WorkerOneThread(func=new_func, name="_w_3") # self._w_3.start() return new_func # threading.Thread(target=self.detail_run_by_thread, kwargs=kwargs).start() else: config_data["sign_text"] = "已结束详情处理" # self.run_end_sign.emit(config_data) return config_data def detail_run_by_thread(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=================") all_detail_path_list = [] out_put_dir_resp = "" for goods_no, temp_name_list in finally_goods_no_need_temps.items(): try: 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中,因为不同的模板有数据特殊性 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("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)) # continue 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, temp_class=config_data["temp_class"], target_error_folder=config_data["target_error_folder"], image_dir=config_data["image_dir"], ) except BaseException as e: self.show_progress_detail( "款:{}生成详情异常:{}".format(goods_no, e)) print(e) raise UnicornException("款:{}生成详情异常:{}".format(goods_no, e)) # ==============完成处理============== 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 config_data["out_put_dir"] = out_put_dir_resp print("out_put_dir_resp", out_put_dir_resp) # 打开文件夹 # os.startfile(out_put_dir) 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中,因为不同的模板有数据特殊性 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) print("text=====>", text) return text def detail_deal_one_data( self, goods_no, value, out_put_dir, temp_name, assigned_page_list, temp_class, target_error_folder, image_dir, ): # 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 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: try: # # 处理图片详情图生成 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 except BaseException as e: self.show_progress_detail("{}处理失败".format(goods_no)) error_text = "{}".format(e) if "Unable to allocate" in error_text: error_text = "电脑内存不足,生成失败" # self.show_progress_detail("失败原因:{}".format(error_text)) self.fail_num += 1 raise UnicornException("{}处理失败,失败原因:{}".format(goods_no,error_text)) self.n += 1 if not is_deal_success: goods_art_no_list = value["货号资料"] self.show_progress_detail("处理失败") self.show_progress_detail( "相关货号:{}".format([x["货号"] for x in goods_art_no_list]) ) # 将相关的文件夹统一移动至错误文件夹 move_folders( path_list=[ "{}/{}".format(image_dir, x) for x in [x["文件夹名称"] for x in goods_art_no_list] ], target_folder=target_error_folder, ) pass # 更新进度 print("更新进度============>",self.n, self.total_num) # self.windows.progress_sign.emit( # { # "type": "详情图生成", # "progress_bar_value": int(self.n / self.total_num * 100), # } # ) def check_serializable(self, obj): # 检查某个对象其中的属性哪些不能被序列化 for attr_name in dir(obj): if not attr_name.startswith('__'): try: attr_value = getattr(obj, attr_name) serialized = pickle.dumps(attr_value) print(f"属性 {attr_name} 是可序列化的。") except (TypeError, pickle.PicklingError): print(f"属性 {attr_name} 不可序列化。") def on_dialog_result(self, result): """处理对话框结果""" self.dialog_result = result print("972 处理对话框结果:{}".format(result)) # self.quit() # 结束事件循 self.event.set()