import settings from module.view_control.generate_goods_no_detail_pic import detail_func import json from base import * from import_qt_mode import * from module.view_control.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 module.view_control.generate_goods_no_detail_pic.data import DataModeGenerateDetail, DataModeUploadPic from module.view_control.generate_goods_no_detail_pic.detail_func import create_folder 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 class RunMain(QThread): 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): super().__init__() self.windows = windows self.dialog_result = "" self.data_mode_generate_detail = DataModeGenerateDetail() 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: 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().getImageOrder(image_order=image_order, resize_image_view=resize_image_view) if res['code'] != 0: return_data["message"] += "{}\n".format(res['msg']) return return_data else: # 图片命名顺序 image_order_list = res['imageOrderList'] 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().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, # } # self.show_dialog_sign.emit(_dialog_dict) # self.event.wait() # return 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=self.windows, logo_path=return_data["data"]["logo_path"], config_data=config_data) self._w_3 = WorkerOneThread(func=new_func, name="_w_3") self._w_3.start() # 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) 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): 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, ) # ==============完成处理============== # self.set_state(state_value=2) callback_func("已结束抠图处理") 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"] 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 = detail_func.get_all_dir_info(image_dir=image_dir) 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 ) 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: 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 = detail_func.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 = detail_func.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: 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: # self.windows.show_message(data["message"]) # my_dialog = DialogShow(self.windows.windows, text=data["message"]) # ret = my_dialog.exec() self.show_progress_detail(text=data["message"]) _dialog_dict = {"text": data["message"], "windows": self, } self.show_dialog_sign.emit(_dialog_dict) self.event.wait() # self.windows.set_state(2) config_data["sign_text"] = "已结束详情处理" self.run_end_sign.emit(config_data) return 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() # threading.Thread(target=self.detail_run_by_thread, kwargs=kwargs).start() else: config_data["sign_text"] = "已结束详情处理" self.run_end_sign.emit(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 = [] 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("temp_info_data") print("goods_no:{},_temp_name:{}".format(goods_no, _temp_name)) 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) except BaseException as e: self.show_progress_detail( "款:{}生成详情异常:{}".format(goods_no, e)) print(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 # 打开文件夹 os.startfile(out_put_dir) self.run_end_sign.emit(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_data") 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) def detail_deal_one_data(self, goods_no, value, out_put_dir, temp_name, assigned_page_list): 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) if settings.IS_TEST: d = self.windows.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: # # 处理图片详情图生成 d = self.windows.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 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]) ) # 将相关的文件夹统一移动至错误文件夹 detail_func.move_folders( path_list=[ "{}/{}".format(self.windows.image_dir, x) for x in [x["文件夹名称"] for x in goods_art_no_list] ], target_folder=self.windows.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()