data.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. import settings
  2. from .data_metaclass import DataBaseModel
  3. from PIL import Image
  4. from io import BytesIO
  5. import copy
  6. import pandas as pd
  7. import settings
  8. import numpy as np
  9. class DataModeAutoDealPics(DataBaseModel):
  10. def __init__(self,token):
  11. super().__init__(token)
  12. def check_is_right_foot_by_api(self, image):
  13. image = image.convert('RGB')
  14. re_x = int(640)
  15. re_y = int(image.height * re_x / image.width)
  16. image = image.resize((re_x, re_y))
  17. e = "JPEG"
  18. img = BytesIO()
  19. image.save(img, format=e) # format: PNG or JPEG
  20. img.seek(0) # rewind to the start
  21. image_url = self.get_online_data.upload_image_by_io(image_io=img)
  22. if settings.IS_TEST:
  23. print("识别左右脚,{}".format(image_url))
  24. # 识别左右脚
  25. r_data = self.get_online_data.yolo_shoes_category(image_url=image_url)
  26. return r_data
  27. class DataModeGenerateDetail(DataBaseModel):
  28. def __init__(self, token):
  29. super().__init__(token)
  30. self.token = token
  31. self.get_online_data.refresh_headers(token)
  32. def get_real_color_name(self, color_name: str):
  33. _ = ["薄棉", "加厚", "厚棉"]
  34. for i in _:
  35. color_name = color_name.replace(i, "")
  36. return color_name
  37. def get_goods_art_no_info(self, numbers_list=None, goods_art_list=None):
  38. if goods_art_list:
  39. data_list = copy.deepcopy(goods_art_list)
  40. flag = "Goods_Art"
  41. else:
  42. data_list = copy.deepcopy(numbers_list)
  43. flag = "NUM"
  44. _list = []
  45. # 单次请求数少于20个
  46. goods_dict = {}
  47. while data_list:
  48. one_data = data_list.pop()
  49. _list.append(one_data)
  50. if len(_list) == 20 or len(data_list) == 0:
  51. if flag == "NUM":
  52. # 注意,红蜻蜓和惠利玛函数不同
  53. online_goods_art_data = self.get_online_data.get_goods_art_no_info(
  54. numbers_list=_list,
  55. token=self.token
  56. )
  57. else:
  58. online_goods_art_data = self.get_online_data.get_goods_art_no_info(
  59. goods_art_list=_list, token=self.token
  60. )
  61. if online_goods_art_data:
  62. for key in online_goods_art_data:
  63. # 映射为真实的文件夹名称
  64. goods_dict[key] = online_goods_art_data[key]
  65. _list = []
  66. return goods_dict
  67. def get_basic_goods_art_data_by_hqt_and_hlm(self, folder_name_list):
  68. """
  69. 查询红蜻蜓货号的对应数据,输入写入为编码,可能带有@,可能为货号等 NUN为编码
  70. """
  71. original_folder_name_list = copy.deepcopy(folder_name_list)
  72. # 编号与文件名映射表
  73. return_dict = {}
  74. for folder_name in original_folder_name_list:
  75. folder_name: str
  76. if "NUM" not in folder_name:
  77. # 即为货号
  78. return_dict[folder_name] = {
  79. "type": "goods_art_no",
  80. "name": folder_name.upper(),
  81. "文件夹名称": folder_name,
  82. "data": {},
  83. }
  84. else:
  85. if "@" not in folder_name:
  86. return_dict[folder_name] = {
  87. "type": "goods_number",
  88. "name": folder_name.upper().replace("NUM", ""),
  89. "文件夹名称": folder_name,
  90. "data": {},
  91. }
  92. else:
  93. return_dict[folder_name] = {
  94. "type": "goods_number",
  95. "name": folder_name.upper().replace("NUM", "").split("@")[1],
  96. "文件夹名称": folder_name,
  97. "data": {},
  98. }
  99. # -----------请求货号数据处理------------
  100. goods_art_no_list = [
  101. v["name"] for k, v in return_dict.items() if v["type"] == "goods_art_no"
  102. ]
  103. goods_art_no_all_data = self.get_goods_art_no_info(
  104. goods_art_list=goods_art_no_list
  105. )
  106. for folder_name, value in return_dict.items():
  107. if value["type"] == "goods_art_no":
  108. if value["name"] in goods_art_no_all_data:
  109. return_dict[folder_name]["data"] = goods_art_no_all_data[
  110. value["name"]
  111. ]
  112. # ------------请求编码数据----------------------
  113. goods_number_list = [
  114. v["name"] for k, v in return_dict.items() if v["type"] == "goods_number"
  115. ]
  116. goods_number_all_data = self.get_goods_art_no_info(
  117. numbers_list=goods_number_list
  118. )
  119. for folder_name, value in return_dict.items():
  120. if value["type"] == "goods_number":
  121. if value["name"] in goods_number_all_data:
  122. return_dict[folder_name]["data"] = goods_number_all_data[
  123. value["name"]
  124. ]
  125. # 清空没有值的数据
  126. error_key = []
  127. for folder_name, value in return_dict.items():
  128. if not value["data"]:
  129. error_key.append(folder_name)
  130. if error_key:
  131. for folder_name in error_key:
  132. return_dict.pop(folder_name)
  133. return {"code": 0, "message": "", "data": return_dict}
  134. def get_basic_goods_art_data_form_excel(self, folder_name_list, excel_path, keys):
  135. # =====创建虚拟表格并进行连表处理
  136. need_df = pd.DataFrame(columns=["文件夹名称"])
  137. for folder_name in folder_name_list:
  138. new_row = {
  139. "文件夹名称": str(folder_name),
  140. }
  141. need_df = need_df._append(new_row, ignore_index=True)
  142. need_df = need_df.fillna(value="")
  143. # 打开表格并进行匹配
  144. _df = pd.read_excel(excel_path, sheet_name=0, header=0)
  145. # 去重数据
  146. duplicates = _df.duplicated(subset=["文件夹名称"], keep="first")
  147. _df = _df.loc[~duplicates]
  148. _df = _df.fillna(value="")
  149. _df = _df.astype(str)
  150. # 数据匹配关联,左关联
  151. need_df = pd.merge(
  152. need_df,
  153. _df,
  154. on=["文件夹名称"],
  155. how="left",
  156. indicator=False,
  157. )
  158. # 补全字段
  159. header_list = need_df.columns.values.tolist()
  160. for key in keys:
  161. if key not in header_list:
  162. need_df[key] = ""
  163. need_df = need_df.fillna(value="")
  164. need_df = need_df.astype(str)
  165. # 数据转字典
  166. return_dict = {}
  167. message = ""
  168. for index, row in need_df.iterrows():
  169. if settings.PROJECT == "红蜻蜓":
  170. if row["商品货号"] and row["款号"] and row["编号"]:
  171. return_dict[row["文件夹名称"]] = {
  172. "type": "goods_art_no",
  173. "name": row["文件夹名称"].upper(),
  174. "文件夹名称": row["文件夹名称"],
  175. "template_name": row["模板名称"],
  176. "data": row.to_dict(),
  177. }
  178. else:
  179. message = "商品货号、款号、编号必须有值"
  180. else:
  181. if row["商品货号"] and row["款号"]:
  182. return_dict[row["文件夹名称"]] = {
  183. "type": "goods_art_no",
  184. "name": row["文件夹名称"].upper(),
  185. "文件夹名称": row["文件夹名称"],
  186. "template_name": row["模板名称"],
  187. "data": row.to_dict(),
  188. }
  189. print("return_dict", return_dict)
  190. if not return_dict:
  191. message += "\n没有找到任何匹配的数据"
  192. return {"code": 99, "message": message, "data": return_dict}
  193. else:
  194. return {"code": 0, "message": message, "data": return_dict}
  195. def check_goods_is_not_deficiency(self, goods_no_dict: dict):
  196. # 数据返回结果为款号列表
  197. error_data = {}
  198. for key, value in goods_no_dict.items():
  199. number = value["货号资料"][0]["编号"].replace("NUM", "")
  200. number_list = [x["编号"].replace("NUM", "") for x in value["货号资料"]]
  201. all_color_name = [
  202. self.get_real_color_name(x["颜色名称"]) for x in value["货号资料"]
  203. ] # 本地数据
  204. goods_no = key
  205. _t_goods_number, all_goods_number = (
  206. self.get_online_data.get_on_goods_all_art(number=number)
  207. )
  208. # all_goods_number------》 [{'number': '14250232', 'goods_art_no': 'AC52001173', 'color': '杏色'}]
  209. for i in all_goods_number:
  210. if i["number"] not in number_list:
  211. # 检查款号+颜色名称是否已经存在
  212. real_color = self.get_real_color_name(i["color"])
  213. if real_color not in all_color_name:
  214. if goods_no not in error_data:
  215. error_data[goods_no] = {"message": "颜色:"}
  216. error_data[goods_no]["message"] += "{}缺失 ".format(real_color)
  217. return error_data
  218. def get_basic_template_information(self, _goods_no_dict, excel_path: str):
  219. # 本地的文件夹数据形成一个虚拟表格
  220. original_df = pd.DataFrame(columns=["款号"])
  221. for goods_no in _goods_no_dict:
  222. new_row = {"款号": str(goods_no), "flag": "是"}
  223. original_df = original_df._append(new_row, ignore_index=True)
  224. original_df = original_df.fillna(value="")
  225. # EXCEL表格数据
  226. local_df = pd.read_excel(excel_path, sheet_name=0, header=0)
  227. values = {
  228. "模板名称": "任意",
  229. }
  230. # 确保所有模板都有名称
  231. local_df.fillna(value=values, inplace=True)
  232. # 分组后取第一个有效值(即不是NaN的值);此处用于获取某个款号的所有基础信息
  233. group_local_df = local_df.groupby(["模板名称", "款号"]).agg(
  234. lambda x: x.dropna().iloc[0] if not x.dropna().empty else np.nan
  235. )
  236. group_local_df = group_local_df.reset_index()
  237. # -----------数据匹配关联,左关联
  238. group_local_df = pd.merge(
  239. group_local_df,
  240. original_df,
  241. on=["款号"],
  242. how="left",
  243. indicator=False,
  244. )
  245. # -----------只取有标记的数据
  246. group_local_df = group_local_df.loc[~group_local_df["flag"].isnull(), :]
  247. group_local_df = group_local_df.loc[group_local_df["模板名称"] != "任意", :]
  248. # -----------数据规整
  249. group_local_df = group_local_df.fillna(value="")
  250. group_local_df = group_local_df.astype(str)
  251. # 组装成字典
  252. temp_goods_no_dict = {}
  253. for index, row in group_local_df.iterrows():
  254. goods_no = row["款号"]
  255. if goods_no not in temp_goods_no_dict:
  256. temp_goods_no_dict[goods_no] = {}
  257. temp_goods_no_dict[goods_no][row["模板名称"]] = row.to_dict()
  258. return temp_goods_no_dict
  259. def check_goods_is_not_deficiency_form_excel(
  260. self, goods_no_dict: dict, excel_path: str
  261. ):
  262. # 检查颜色是否齐全,基于Excel处理
  263. """
  264. 步骤:
  265. 1、goods_no_dict款号生成一个表格(款号+颜色)
  266. 2、excel表格数据进行款号+颜色去重
  267. 3、excel表格关联 上述的款号 进行标记,其他删除
  268. 4、excel表格关联 上述款号与颜色,进行标记
  269. 5、上述未标记的就是没有的颜色(有对应款号)。
  270. 6、对对应的款号进行设置为错误数据
  271. 返回数据结构
  272. {
  273. “A00001--款号”:{“message”:“这个款的错误原因”},
  274. “A00002--款号”:{“message”:“这个款的错误原因”},
  275. }
  276. """
  277. def change_to_int(x):
  278. if pd.isna(x):
  279. return 0
  280. else:
  281. try:
  282. x = int(x)
  283. return str(x)
  284. except:
  285. return x
  286. error_data = {}
  287. # -----------------goods_no_dict款号生成一个表格(款号+颜色)
  288. new_df = pd.DataFrame(columns=["款号", "颜色名称", "款色标记"])
  289. for key, value in goods_no_dict.items():
  290. goods_no = value["款号"]
  291. for color_name in [x["颜色名称"] for x in value["货号资料"]]:
  292. new_row = {
  293. "款号": goods_no,
  294. "颜色名称": self.get_real_color_name(color_name),
  295. "款色标记": 1,
  296. }
  297. new_df = new_df._append(new_row, ignore_index=True)
  298. new_df.drop_duplicates(subset=["款号", "颜色名称"], keep="first", inplace=True)
  299. # -------------参考的本地excel表格数据进行款号+颜色去重------------
  300. local_df = pd.read_excel(excel_path, sheet_name=0, header=0)
  301. local_df.fillna(
  302. value={
  303. "颜色名称": "",
  304. },
  305. inplace=True,
  306. )
  307. local_df = local_df.astype({"颜色名称": str})
  308. header_list = local_df.columns.values.tolist()
  309. for key in ["帮高", "鞋宽", "跟高"]:
  310. if key in header_list:
  311. local_df[key] = local_df[key].apply(change_to_int)
  312. # 颜色名称规整
  313. local_df["颜色名称"] = local_df["颜色名称"].apply(self.get_real_color_name)
  314. local_df.drop_duplicates(
  315. subset=["款号", "颜色名称"], keep="first", inplace=True
  316. )
  317. # ------------excel表格关联 上述的款号 进行标记,其他删除
  318. _df = new_df.drop_duplicates(subset=["款号"], keep="first", inplace=False)
  319. _df = _df[["款号"]]
  320. _df["对应款号"] = 1
  321. local_df = pd.merge(
  322. local_df,
  323. _df,
  324. on=["款号"],
  325. how="left",
  326. indicator=False,
  327. )
  328. local_df = local_df.loc[local_df["对应款号"] == 1, :]
  329. # ------------excel表格关联 上述款号与颜色,进行标记;取没有关联的颜色数据---------
  330. local_df = pd.merge(
  331. local_df,
  332. new_df,
  333. on=["款号", "颜色名称"],
  334. how="left",
  335. indicator=False,
  336. )
  337. local_df.fillna(
  338. value={
  339. "款色标记": 0,
  340. },
  341. inplace=True,
  342. )
  343. local_df = local_df.loc[local_df["款色标记"] == 0, :]
  344. print("local_df")
  345. print(local_df)
  346. # ------------数据分组,对对应的款号进行设置为错误数据---------------
  347. grouped_df = (
  348. local_df.groupby("款号")["颜色名称"]
  349. .apply(lambda x: "、".join(x))
  350. .reset_index()
  351. )
  352. for index, row in grouped_df.iterrows():
  353. error_data[row["款号"]] = {
  354. "message": "颜色:{}缺失".format(row["颜色名称"])
  355. }
  356. print("======error_data")
  357. print(json.dumps(error_data))
  358. return error_data
  359. class DataModeUploadPic(DataBaseModel):
  360. def __init__(self):
  361. super().__init__()
  362. self.get_online_data.refresh_headers()
  363. self.is_deal_goods_no = []
  364. def get_goods_art_no_info(self, numbers_list=None, goods_art_list=None):
  365. return self.get_online_data.get_goods_art_no_info(
  366. numbers_list=numbers_list, goods_art_list=goods_art_list
  367. )
  368. def upload_pic_list_data(self, data):
  369. return self.get_online_data.upload_pic_list_data(data)
  370. def upload_pic(self, goods_data):
  371. return self.get_online_data.upload_pic(goods_data)
  372. def check_is_uploaded(self, goods_art_no=None):
  373. return self.get_online_data.check_detail_image(goods_art_no)