module_online_data.py 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879
  1. import base64
  2. import requests
  3. import settings
  4. import json, asyncio
  5. import numpy as np
  6. from utils.common import message_queue
  7. from middleware import UnicornException
  8. from PIL import Image
  9. import io, time
  10. class JsonEncoder(json.JSONEncoder):
  11. """Convert numpy classes to JSON serializable objects."""
  12. def default(self, obj):
  13. if isinstance(obj, (np.integer, np.floating, np.bool_)):
  14. return obj.item()
  15. elif isinstance(obj, np.ndarray):
  16. return obj.tolist()
  17. else:
  18. return super(JsonEncoder, self).default(obj)
  19. def download_image_with_pil(url, save_path):
  20. """通过url保存图片"""
  21. try:
  22. # 发送请求获取图片数据
  23. response = requests.get(url)
  24. image_data = response.content
  25. # 使用PIL处理下载的图片
  26. image = Image.open(io.BytesIO(image_data))
  27. image = image.convert("RGB")
  28. # 根据当前时间生成文件名
  29. # 保存图片
  30. image.save(save_path)
  31. return save_path
  32. except Exception as e:
  33. print("保存错误",e)
  34. return "error"
  35. class AIGCDataRequest(object):
  36. def __init__(self, token):
  37. self.s = requests.session()
  38. self.token = token
  39. self.post_headers = {
  40. "Authorization": token,
  41. }
  42. def uploadImage(self, local_path: str) -> str:
  43. post_headers = {"Authorization": self.token}
  44. url = settings.DOMAIN + "/api/upload"
  45. resultData = self.s.post(
  46. url, files={"file": open(local_path, "rb")}, headers=post_headers
  47. ).json()
  48. return resultData["data"]["url"]
  49. def center_paste_image(
  50. self, source_image_path, output_path, width=900, ratio=(3, 4)
  51. ):
  52. """
  53. 将一张PNG透明图片居中粘贴到指定尺寸和比例的背景上,保持透明度
  54. Args:
  55. source_image_path: 源PNG图片路径
  56. output_path: 输出图片路径
  57. width: 目标图片宽度
  58. ratio: 目标图片比例 (宽:高)
  59. """
  60. # 计算目标尺寸 (900 x 1200)
  61. target_width = width
  62. target_height = int(width * ratio[1] / ratio[0])
  63. # 创建透明背景图片(RGBA模式)
  64. background = Image.new(
  65. "RGBA", (target_width, target_height), (255, 255, 255, 0)
  66. )
  67. # 打开源图片
  68. source_img = Image.open(source_image_path)
  69. # 确保源图片是RGBA模式以保持透明度
  70. if source_img.mode != "RGBA":
  71. source_img = source_img.convert("RGBA")
  72. # 调整源图片大小以适应目标尺寸,保持原图比例
  73. source_width, source_height = source_img.size
  74. scale = min(target_width / source_width, target_height / source_height)
  75. new_width = int(source_width * scale)
  76. new_height = int(source_height * scale)
  77. # 调整源图片尺寸
  78. source_img_resized = source_img.resize(
  79. (new_width, new_height), Image.Resampling.LANCZOS
  80. )
  81. # 计算居中粘贴位置
  82. paste_x = (target_width - new_width) // 2
  83. paste_y = (target_height - new_height) // 2
  84. # 将调整后的源图片居中粘贴到背景上,保留透明度
  85. background.paste(source_img_resized, (paste_x, paste_y), source_img_resized)
  86. # 如果需要保存为PNG格式以保持透明度
  87. if output_path.lower().endswith(".png"):
  88. background.save(output_path, format="PNG")
  89. else:
  90. # 如果保存为JPG等不支持透明度的格式,转换为RGB并使用白色背景
  91. background = background.convert("RGB")
  92. background.save(output_path)
  93. return background
  94. def generateProductScene(self, local_path, prompt, save_path):
  95. imageUrl = self.uploadImage(local_path)
  96. print("imageUrl", imageUrl)
  97. data = {
  98. "site": 1,
  99. "base_image": imageUrl,
  100. "keyword": prompt,
  101. "model_type": 1,
  102. "gemini_model": "gemini-2.5-flash-image-preview",
  103. }
  104. """生成场景图"""
  105. url = settings.DOMAIN + "/api/ai_image/inspired/command_to_image"
  106. resultData = self.s.post(url, data=data, headers=self.post_headers).json()
  107. code = resultData.get("code", 0)
  108. message = resultData.get("message", "")
  109. if code != 0:
  110. raise UnicornException(message)
  111. image_arr = resultData.get("data", None).get("image", [])
  112. if len(image_arr) == 0:
  113. raise UnicornException("场景图生成失败")
  114. image_url = image_arr[0]
  115. save_image_path = download_image_with_pil(image_url, save_path)
  116. return save_image_path
  117. def searchProgress(self, id):
  118. """查询进度"""
  119. url = settings.DOMAIN + "/api/ai_image/main/search_bacth_progress"
  120. data = {"site": 1, "generate_ids": [id], "type": "aigc_pro"}
  121. resultData = self.s.post(url, json=data, headers=self.post_headers)
  122. resultData = resultData.json()
  123. code = resultData.get("code", 0)
  124. message = resultData.get("message", "")
  125. if code != 0:
  126. raise UnicornException(message)
  127. data_result = resultData.get("data", [])
  128. if len(data_result) == 0:
  129. return -1, None
  130. data_item = data_result[0]
  131. status = data_item.get("status", -1)
  132. if status in [0,1]:
  133. return status, None
  134. result_image_urls = data_item.get("result_image_urls", [])
  135. result_image = result_image_urls[0] if len(result_image_urls) > 0 else None
  136. return status, result_image
  137. def generateUpperShoes(self, local_path, model_id, save_path):
  138. """生成上脚图"""
  139. print("生成上脚图", local_path, model_id, save_path)
  140. imageUrl = self.uploadImage(local_path)
  141. data = {
  142. "site": 1,
  143. "model_template_id": model_id,
  144. "base_image": imageUrl,
  145. "creatClass": "鞋子上脚图-鞋子上脚图",
  146. "creatTimer": 40,
  147. "pname": "OnFeetImage",
  148. }
  149. """生成上脚图"""
  150. url = settings.DOMAIN + "/api/ai_image/main/upper_footer"
  151. resultData = self.s.post(url, data=data, headers=self.post_headers).json()
  152. code = resultData.get("code", 0)
  153. message = resultData.get("message", "")
  154. if code != 0:
  155. raise UnicornException(message)
  156. generate_ids = resultData.get("data", None).get("generate_ids", [])
  157. if len(generate_ids) == 0:
  158. raise UnicornException("模特图生成失败")
  159. generate_id = generate_ids[0]
  160. search_times = 60
  161. status = 0
  162. result_image = None
  163. print("generate_id", generate_id)
  164. while search_times > 0:
  165. print(f"查询第{search_times}次")
  166. status, result_image = self.searchProgress(generate_id)
  167. if status in [-1, 2]:
  168. break
  169. time.sleep(1)
  170. search_times -= 1
  171. if not result_image:
  172. raise UnicornException("模特图生成失败")
  173. save_image_path = download_image_with_pil(result_image, save_path)
  174. print("上脚图save_image_path",result_image, save_image_path)
  175. return save_image_path
  176. def generateModelFitting(self, local_path, model_id, face_type, save_path):
  177. """生成上脚图"""
  178. imageUrl = self.uploadImage(local_path)
  179. data = {
  180. "site": 1,
  181. "scene_key": model_id,
  182. "topsImg": imageUrl,
  183. "generate_type": 1,
  184. "face_type": face_type,
  185. "pname": "ModelFitting_clothing",
  186. }
  187. print("生成上脚图", local_path, model_id, save_path)
  188. print("生成上脚图==>data", data)
  189. """生成上脚图"""
  190. url = settings.DOMAIN + "/api/ai_image/clothing/model_fitting_vk"
  191. resultData = self.s.post(url, data=data, headers=self.post_headers)
  192. # print("模特图resultData", resultData.content)
  193. resultData = resultData.json()
  194. code = resultData.get("code", 0)
  195. message = resultData.get("message", "")
  196. if code != 0:
  197. raise UnicornException(message)
  198. generate_ids = resultData.get("data", None).get("generate_ids", [])
  199. if len(generate_ids) == 0:
  200. raise UnicornException("模特图生成失败")
  201. generate_id = generate_ids[0]
  202. search_times = 60
  203. status = 0
  204. result_image = None
  205. while search_times > 0:
  206. print(f"查询第{search_times}次")
  207. status, result_image = self.searchProgress(generate_id)
  208. if status in [-1, 2]:
  209. break
  210. time.sleep(1)
  211. search_times -= 1
  212. if not result_image:
  213. raise UnicornException("模特图生成失败")
  214. save_image_path = download_image_with_pil(result_image, save_path)
  215. print("上脚图save_image_path", result_image, save_image_path)
  216. return save_image_path
  217. def generateProductSceneQW(self, local_path, prompt, save_path):
  218. """千问生成场景图"""
  219. imageUrl = self.uploadImage(local_path)
  220. data = {
  221. "machine_type": 1, # 0鞋;1服装
  222. "generate_type": 0, # 生成类型,这里指代得是场景图还是模特图;0场景图;1模特图
  223. "base_image": imageUrl,
  224. "prompt": prompt,
  225. }
  226. """生成场景图"""
  227. url = settings.DOMAIN + "/api/ai_image/main/image_edit_generate"
  228. resultData = self.s.post(url, data=data, headers=self.post_headers).json()
  229. code = resultData.get("code", 0)
  230. message = resultData.get("message", "")
  231. if code != 0:
  232. raise UnicornException(message)
  233. image_url = resultData.get("data", None).get("image_url", "")
  234. if image_url == "" or image_url is None:
  235. raise UnicornException("场景图生成失败")
  236. save_image_path = download_image_with_pil(image_url, save_path)
  237. return save_image_path
  238. def generateModelclothingQW(self, local_path, model_id, save_path):
  239. """千问生成场景图"""
  240. imageUrl = self.uploadImage(local_path)
  241. data = {
  242. "machine_type": 1, # 0鞋;1服装
  243. "generate_type": 1, # 生成类型,这里指代得是场景图还是模特图;0场景图;1模特图
  244. "base_image": imageUrl,
  245. "model_template_id": model_id,
  246. }
  247. """生成场景图"""
  248. url = settings.DOMAIN + "/api/ai_image/main/image_edit_generate"
  249. resultData = self.s.post(url, data=data, headers=self.post_headers).json()
  250. code = resultData.get("code", 0)
  251. message = resultData.get("message", "")
  252. if code != 0:
  253. raise UnicornException(message)
  254. image_url = resultData.get("data", None).get("image_url", "")
  255. if image_url == "" or image_url is None:
  256. raise UnicornException("模特图生成失败")
  257. save_image_path = download_image_with_pil(image_url, save_path)
  258. return save_image_path
  259. class OnlineDataRequest(object):
  260. def __init__(self, token):
  261. self.s = requests.session()
  262. self.token = token
  263. self.post_headers = {
  264. "Authorization": token,
  265. # "Origin": settings.Headers["Origin"],
  266. # "Host": settings.Headers["Host"],
  267. "Content-Length": "0",
  268. "Content-Type": "application/json",
  269. "Accept": "application/json",
  270. }
  271. print("28 Authorization:", self.post_headers["Authorization"])
  272. def refresh_headers(self, token):
  273. self.post_headers = {
  274. "Authorization": token,
  275. # "Origin": settings.Headers["Origin"],
  276. # "Host": settings.Headers["Host"],
  277. "Content-Length": "0",
  278. "Content-Type": "application/json",
  279. "Accept": "application/json",
  280. }
  281. def auth_user(self):
  282. # 用户登录
  283. url = "{domain}/api/auth/user".format(domain=settings.DOMAIN)
  284. s = requests.session()
  285. _s = s.get(url=url, headers=settings.Headers)
  286. response_data = _s.json()
  287. return response_data
  288. def logout(self):
  289. url = "{domain}/api/auth/logout".format(domain=settings.DOMAIN)
  290. s = requests.session()
  291. _s = s.post(url=url, headers=settings.Headers)
  292. def get_change_bar_code(self, code):
  293. url = "{domain}/api/hct/open/sting_search_goods?string={code}".format(
  294. domain=settings.DOMAIN, code=code
  295. )
  296. try:
  297. s = requests.get(url)
  298. goods_art_no = s.json()["data"]["goods_art_no"]
  299. return goods_art_no
  300. except BaseException as e:
  301. print(e)
  302. return
  303. def get_goods_art_no_info(self, numbers_list=None, goods_art_list=None, token=None):
  304. # 获取商品基础信息,入参为商品的编号
  305. url = "{domain}/api/backend/produce/goods/info".format(domain=settings.DOMAIN)
  306. print("执行 get_goods_art_no_info ", url)
  307. if numbers_list:
  308. data = {"numbers": numbers_list}
  309. print("请求编码:", numbers_list)
  310. else:
  311. data = {"goods_art_nos": goods_art_list}
  312. print("请求货号:", goods_art_list)
  313. print("请求货号=====>", self.token)
  314. print("执行 get_goods_art_no_info----------------", data)
  315. post_headers = {
  316. "Authorization": token,
  317. # "Origin": settings.Headers["Origin"],
  318. # "Host": settings.Headers["Host"],
  319. "Content-Length": "",
  320. "Content-Type": "application/json",
  321. "Accept": "application/json",
  322. }
  323. data = json.dumps(data)
  324. post_headers["Content-Length"] = str(len(data))
  325. _s = self.s.post(url=url, data=data, headers=post_headers)
  326. # _s = self.s.get(url=url, params=params, headers=settings.Headers)
  327. response_data = _s.json()
  328. # print(response_data)
  329. # print("\n")
  330. goods_number_data = {}
  331. # ["", "", "", "", "", "", "", "", "", "", "", ]
  332. if "data" not in response_data:
  333. return {}
  334. for data in response_data["data"]:
  335. if numbers_list:
  336. number = data["number"]
  337. else:
  338. number = data["goods_art_no"].upper()
  339. goods_number_data[number] = {}
  340. goods_number_data[number]["商品面料"] = data["fabric"]
  341. goods_number_data[number]["商品内里"] = data["lining"]
  342. goods_number_data[number]["商品鞋底"] = data["sole"]
  343. goods_number_data[number]["后帮高"] = data["back_height"]
  344. goods_number_data[number]["前掌宽"] = data["forefoot_width"]
  345. goods_number_data[number]["鞋跟高"] = data["heel_height"]
  346. goods_number_data[number]["FAB介绍"] = data["fab_info"]
  347. goods_number_data[number]["编号"] = data["number"]
  348. goods_number_data[number]["商品货号"] = data["goods_art_no"].upper()
  349. goods_number_data[number]["款号"] = data["goods_number"].upper()
  350. goods_number_data[number]["颜色名称"] = data["color"]
  351. goods_number_data[number]["所属企划"] = data["projects"][0]
  352. goods_number_data[number]["设计方名称"] = data["purchasing_unit"]
  353. goods_number_data[number]["供应商"] = data["supplier_name"]
  354. goods_number_data[number]["供应商编码"] = data["supplier_code"].lstrip("0")
  355. goods_number_data[number]["供应商货号"] = data["supplier_goods_artno"]
  356. goods_number_data[number]["销售工厂"] = data["sales_factory_name"]
  357. goods_number_data[number]["销售组织"] = data["man_org_name"]
  358. goods_number_data[number]["是否SAP"] = data["source"]
  359. goods_number_data[number]["OEM报价"] = data["oem_price"]
  360. goods_number_data[number]["出厂价"] = data["ex_factory_price"]
  361. goods_number_data[number]["首单货期"] = data["earliest_delivery_date"]
  362. goods_number_data[number]["包装"] = data["package_specification"]
  363. goods_number_data[number]["创建日期"] = data["created_at"]
  364. goods_number_data[number]["货号图"] = data["image"]
  365. return goods_number_data
  366. def get_on_goods_all_art(self, number):
  367. # 获取商品基础信息,入参为商品的编号
  368. url = "{domain}/api/backend/produce/goods/query/numbers?number={number}".format(
  369. domain=settings.DOMAIN, number=number
  370. )
  371. _s = self.s.get(url=url, headers=self.post_headers)
  372. response_data = _s.json()
  373. print(number, response_data)
  374. """
  375. 14250230 {'data': {'goods_number': 'AC5200117', 'brother_goods_arts': [{'number': '14250232', 'goods_art_no': 'AC52001173', 'color': '杏色'}, {'number': '14250231', 'goods_art_no': 'AC52001172', 'color': '灰色'}, {'number': '14250230', 'goods_art_no': 'AC52001171', 'color': '黑色'}]}, 'code': 0, 'message': 'success'}
  376. """
  377. return (
  378. response_data["data"]["goods_number"],
  379. response_data["data"]["brother_goods_arts"],
  380. response_data["data"]["goods_art_no"],
  381. )
  382. def get_views(self, image_url):
  383. url = "http://{}/shoes_category".format(settings.VIEW_DEAL_DOMAIN)
  384. data = {
  385. "train_path": "./datasets/Shoes_Dataset/Train/angle",
  386. "model_filename": "./models/0320/output0320.pth",
  387. "validate_path": image_url,
  388. }
  389. _s = requests.post(
  390. url=url,
  391. data=json.dumps(data),
  392. )
  393. response_data = _s.json()
  394. return response_data["classify_result"]
  395. def uploadImage(self, local_path: str) -> str:
  396. post_headers = {"Authorization": self.token}
  397. url = settings.DOMAIN + "/api/upload"
  398. resultData = self.s.post(
  399. url, files={"file": open(local_path, "rb")}, headers=post_headers
  400. ).json()
  401. return resultData["data"]["url"]
  402. def get_current_menu(self):
  403. def get_menu(_menu_dict, _data):
  404. for menu in _data:
  405. _menu_dict[menu["key"]] = {}
  406. for mods in menu["mods_arr"]:
  407. _menu_dict[menu["key"]][mods["key"]] = mods["name"]
  408. if "_child" in menu:
  409. get_menu(_menu_dict, menu["_child"])
  410. return _menu_dict
  411. url = "{domain}/api/backend/basic/get_current_menu".format(
  412. domain=settings.DOMAIN,
  413. )
  414. _s = self.s.get(url=url, headers=settings.Headers)
  415. response_data = _s.json()
  416. try:
  417. menu_data = response_data["data"]["pc_menu"]
  418. menu_dict = {}
  419. menu_dict = get_menu(menu_dict, menu_data)
  420. except:
  421. menu_dict = {}
  422. # print(json.dumps(menu_dict,ensure_ascii=False))
  423. # raise 1
  424. return menu_dict
  425. # 获取所有资源的配置
  426. def get_resource_config(self):
  427. url = "{domain}/api/openai/query_client_addons".format(domain=settings.DOMAIN)
  428. _s = self.s.get(
  429. url=url, headers=self.post_headers, params={"type": "client_camera"}
  430. )
  431. response_data = _s.json()
  432. return response_data
  433. # 拍照日志上报
  434. def add_auto_photo_logs(self, data):
  435. url = "{domain}/api/openai/add_auto_photo_logs".format(domain=settings.DOMAIN)
  436. post_data = {
  437. "goods_no": data["goods_art_no"],
  438. "take_photo_created_at": data["take_photo_created_at"],
  439. "photo_created_at": data["photo_create_time"],
  440. "image_dispose_mode": data["image_deal_mode"],
  441. "photo_serial_number": data["image_index"],
  442. }
  443. post_data = json.dumps(post_data)
  444. _s = self.s.post(url=url, headers=self.post_headers, data=post_data)
  445. response_data = _s.json()
  446. if settings.IS_TEST:
  447. print("209-----拍照日志上报 add_auto_photo_logs")
  448. print(response_data)
  449. return response_data
  450. def upload_pic_list_data(self, data):
  451. url = "{domain}/api/backend/goods/save/images".format(domain=settings.DOMAIN)
  452. data = json.dumps(data)
  453. self.post_headers["Content-Length"] = str(len(data))
  454. _s = self.s.post(url=url, data=data, headers=self.post_headers)
  455. response_data = _s.json()
  456. try:
  457. if response_data["code"] == 0 and response_data["message"] == "success":
  458. return True
  459. else:
  460. print(data)
  461. print(response_data)
  462. return False
  463. except BaseException as e:
  464. print(data)
  465. print(e)
  466. print(response_data)
  467. return False
  468. def upload_pic(self, goods_data):
  469. # 检查货号图是否存在
  470. url = "{domain}/api/backend/upload".format(domain=settings.DOMAIN)
  471. # print(url)
  472. headers = {
  473. "Authorization": settings.Headers["Authorization"],
  474. "User-Agent": settings.Headers["User-Agent"],
  475. "Origin": settings.Headers["Origin"],
  476. "Host": settings.Headers["Host"],
  477. }
  478. files = [
  479. (
  480. "file",
  481. (
  482. goods_data["file_path"],
  483. goods_data["image_io"],
  484. "image/{}".format(goods_data["e"]),
  485. ),
  486. )
  487. ]
  488. _s = requests.post(url=url, headers=headers, files=files)
  489. response_data = _s.json()
  490. return response_data["data"]["url"]
  491. # 查询是否已有详情图
  492. def check_detail_image(self, goods_art_no, token):
  493. url = "{domain}/api/backend/goods/check_detail_image?number={number}".format(
  494. domain=settings.DOMAIN, number=goods_art_no
  495. )
  496. _s = self.s.get(url=url, headers=self.post_headers)
  497. response_data = _s.json()
  498. # print(response_data)
  499. return response_data["data"]["hasDetailImage"]
  500. # 调用API识别是否是拖鞋
  501. def yolo_shoes_category(self, image_url):
  502. url = "{domain}/api/ai_image/main/yolo_shoes_category".format(
  503. domain=settings.DOMAIN
  504. )
  505. post_data = {
  506. "image_url": image_url,
  507. }
  508. post_data = json.dumps(post_data)
  509. _s = self.s.post(url=url, headers=self.post_headers, data=post_data)
  510. response_data = _s.json()
  511. if settings.IS_TEST:
  512. print("278-----yolo_shoes_category")
  513. print(response_data)
  514. r_data = None
  515. try:
  516. r_data = response_data["data"]["category"]
  517. except BaseException as e:
  518. print("285", e)
  519. return r_data
  520. # 图片上传by IO
  521. def upload_image_by_io(self, image_io) -> str:
  522. post_headers = {"Authorization": settings.Authorization}
  523. url = settings.DOMAIN + "/api/upload"
  524. resultData = self.s.post(
  525. url, files={"file": image_io}, headers=post_headers
  526. ).json()
  527. return resultData["data"]["url"]
  528. def upload_goods_api(self, params):
  529. """上传商品api"""
  530. post_headers = {
  531. "Authorization": self.token,
  532. "Content-Type": "application/json",
  533. }
  534. url = settings.DOMAIN + "/api/ai_image/camera_machine/publish_goods"
  535. postData = json.dumps(params)
  536. # print("上传商品api==>url", url)
  537. # print("上传第三方数据打印", params)
  538. resultData = self.s.post(url, data=postData, headers=post_headers).json()
  539. print("上传商品api==>resultData", resultData)
  540. return resultData
  541. def sendSocketMessage(self, code=0, msg="", data=None, device_status=2,msg_type="upload_goods_progress"):
  542. data = {
  543. "code": code,
  544. "msg": msg,
  545. "status": device_status,
  546. "data": data,
  547. "msg_type": msg_type,
  548. }
  549. loop = asyncio.get_event_loop()
  550. loop.create_task(message_queue.put(data))
  551. def uploadGoods2ThirdParty(self, goods_no_dict=None, online_stores=[]):
  552. params = []
  553. message_type = "upload_goods_progress"
  554. if goods_no_dict == None:
  555. return
  556. success_goods_arts = []
  557. for store in online_stores:
  558. for goods_no in goods_no_dict.keys():
  559. goods_data = goods_no_dict[goods_no]
  560. detail_path = goods_data.get("detail_path", "")
  561. if detail_path == "":
  562. continue
  563. goods_title = goods_data.get("商品标题", "")
  564. if goods_title == "":
  565. continue
  566. goods_price = goods_data.get("商品价格", 0)
  567. if goods_price == '':
  568. goods_price = 0
  569. if goods_price == 0:
  570. continue
  571. skuList = []
  572. itemImageInfoList = []
  573. itemSkuImageList = []
  574. sku_list_basic = goods_data.get("货号资料", [])
  575. quantity = 9999
  576. skuPropValueList = []
  577. for skuIdx, sku_data in enumerate(sku_list_basic):
  578. sku_goods_art_no = sku_data.get("货号", "")
  579. color_name = sku_data.get("颜色名称", "")
  580. mainImages = sku_data.get("800x800", [])
  581. if not mainImages:
  582. continue
  583. success_goods_arts.append(sku_goods_art_no)
  584. mainImagePath = mainImages[0]
  585. imageUrl = self.uploadImage(local_path=mainImagePath)
  586. skuItemData = {
  587. "skuNo": sku_goods_art_no,
  588. "originalPrice": float(goods_price),
  589. "newSkuWeight": int(1),
  590. "skuMainImageUrl": str(imageUrl),
  591. "skuName": f"颜色:{color_name}",
  592. "sellingPrice": float(goods_price),
  593. "quantity": int(quantity),
  594. "showOrder": int(skuIdx + 1),
  595. }
  596. skuList.append(skuItemData)
  597. itemImage = {
  598. "imageUrl": str(imageUrl),
  599. "imageType": 0,
  600. "imageItem": int(skuIdx),
  601. "imageIndex": 10,
  602. }
  603. itemImageInfoList.append(itemImage)
  604. imageJson = {
  605. "imageUrl": str(imageUrl),
  606. "imageType": 1,
  607. "showOrder": 1,
  608. }
  609. skuPropValueList.append(
  610. {
  611. "imageJson": imageJson,
  612. "propValue": str(color_name),
  613. "showOrder": 1,
  614. }
  615. )
  616. itemSkuImageList.append(
  617. {
  618. "propName": "颜色",
  619. "isImageProp": 1,
  620. "propShowOrder": 1,
  621. "skuPropValueList": skuPropValueList,
  622. }
  623. )
  624. detailImageUrl = self.uploadImage(local_path=detail_path)
  625. category_info = "流行男鞋>>休闲鞋>>时尚休闲鞋"
  626. itemData = {
  627. "catePathName": category_info, # 分类
  628. "itemName": str(goods_title), # 商品标题
  629. "itemNo": str(goods_no),
  630. "brandName": store, # 品牌名称
  631. "sellingPrice": float(goods_price), # 售价(未划线价)
  632. "originalPrice": float(goods_price), # 划线价
  633. "quantity": int(quantity), # 库存数量
  634. "propInfoList": [
  635. {"propName": "品牌", "propIndex": 2, "propValue": "Vali"},
  636. {
  637. "propName": "平台类目",
  638. "propIndex": 3,
  639. "propValue": category_info,
  640. },
  641. ],
  642. "skuList": skuList,
  643. "itemImageInfoList": itemImageInfoList,
  644. "itemSkuImageList": itemSkuImageList,
  645. "wapDescription": f'<img src="{detailImageUrl}"/>',
  646. "pcDescription": f'<img src="{detailImageUrl}"/>',
  647. }
  648. params.append(itemData)
  649. json_params = str(params) # 直接转换为字符串表示
  650. print("json_params", json_params)
  651. # 使用base64编码
  652. encoded = base64.b64encode(json_params.encode("utf-8")).decode("utf-8")
  653. self.upload_goods_api({"bizcontent": encoded, "online_stores": online_stores})
  654. print("商品上传第三方成功")
  655. return True
  656. class GetOnlineDataHLM(OnlineDataRequest):
  657. def __init__(self, token):
  658. super().__init__(token)
  659. self.token = token
  660. def upload_pic(self, goods_data, token):
  661. # 检查货号图是否存在
  662. url = "{domain}/api/backend/upload".format(domain=settings.DOMAIN)
  663. # print(url)
  664. headers = {
  665. "Authorization": self.token,
  666. # 'User-Agent': settings.Headers["User-Agent"],
  667. # 'Origin': settings.Headers["Origin"],
  668. # 'Host': settings.Headers["Host"],
  669. }
  670. files = [
  671. (
  672. "file",
  673. (
  674. goods_data["file_path"],
  675. goods_data["image_io"],
  676. "image/{}".format(goods_data["e"]),
  677. ),
  678. )
  679. ]
  680. _s = requests.post(url=url, headers=headers, files=files)
  681. response_data = _s.json()
  682. return response_data["data"]["url"]
  683. def upload_pic_list_data(self, data, token):
  684. url = "{domain}/api/backend/goods/save/images".format(domain=settings.DOMAIN)
  685. data = json.dumps(data)
  686. self.post_headers["Content-Length"] = str(len(data))
  687. _s = self.s.post(url=url, data=data, headers=self.post_headers)
  688. response_data = _s.json()
  689. try:
  690. if response_data["code"] == 0 and response_data["message"] == "success":
  691. return True
  692. else:
  693. print(response_data)
  694. return False
  695. except BaseException as e:
  696. print(e)
  697. print(response_data)
  698. return False
  699. def get_goods_art_no_info(self, numbers_list=None, goods_art_list=None, token=None):
  700. # 获取商品基础信息,入参为商品的编号
  701. url = "{domain}/api/backend/goods_client/goods_query".format(
  702. domain=settings.DOMAIN
  703. )
  704. data = {"goods_art_list": goods_art_list}
  705. print("url:", url)
  706. print("请求货号:", goods_art_list)
  707. post_headers = {
  708. "Authorization": token,
  709. # "Origin": settings.Headers["Origin"],
  710. # "Host": settings.Headers["Host"],
  711. "Content-Length": "",
  712. "Content-Type": "application/json",
  713. "Accept": "application/json",
  714. }
  715. data = json.dumps(data)
  716. print(post_headers)
  717. print(data)
  718. # post_headers["Content-Length"] = str(len(data))
  719. _s = self.s.post(url=url, data=data, headers=post_headers)
  720. # _s = self.s.get(url=url, params=params, headers=settings.Headers)
  721. response_data = _s.json()
  722. print(response_data)
  723. print("\n")
  724. goods_number_data = {}
  725. # ["", "", "", "", "", "", "", "", "", "", "", ]
  726. if "data" not in response_data:
  727. return {}
  728. for data in response_data["data"]:
  729. goods_number_data[data["goods_art_no"]] = {}
  730. goods_number_data[data["goods_art_no"]]["商品货号"] = data[
  731. "goods_art_no"
  732. ].upper()
  733. goods_number_data[data["goods_art_no"]]["款号"] = data[
  734. "goods_number"
  735. ].upper()
  736. goods_number_data[data["goods_art_no"]]["商品面料"] = data["fabric"]
  737. goods_number_data[data["goods_art_no"]]["商品内里"] = data["lining"]
  738. goods_number_data[data["goods_art_no"]]["商品鞋底"] = data["sole"]
  739. goods_number_data[data["goods_art_no"]]["鞋垫"] = data["insole"]
  740. goods_number_data[data["goods_art_no"]]["颜色名称"] = data["color"]
  741. goods_number_data[data["goods_art_no"]]["商品标题"] = data["goods_title"]
  742. goods_number_data[data["goods_art_no"]]["商品价格"] = data["retail_price"]
  743. goods_number_data[data["goods_art_no"]]["性别"] = data["gender"]
  744. goods_number_data[data["goods_art_no"]]["token"] = self.token
  745. return goods_number_data
  746. def uploadImage(self, local_path: str) -> str:
  747. post_headers = {"Authorization": settings.Authorization}
  748. url = settings.DOMAIN + "/api/upload"
  749. resultData = self.s.post(
  750. url, files={"file": open(local_path, "rb")}, headers=post_headers
  751. ).json()
  752. return resultData["data"]["url"]
  753. # ============pixian抠图处理==========================
  754. def dispose_point(self, _type):
  755. # 扣分 sub;add为增加分数,每次操作一分
  756. url = "{domain}/api/ai_image/client/dispose_point".format(
  757. domain=settings.DOMAIN
  758. )
  759. data = {"type": _type}
  760. _s = self.s.post(
  761. url=url, headers=self.post_headers, data=json.dumps(data), timeout=10
  762. )
  763. response_data = _s.json()
  764. return response_data
  765. def send_message(self, text):
  766. # 发送钉钉消息
  767. url = "{domain}/api/ai_image/client/send_message".format(domain=settings.DOMAIN)
  768. data = {"message": text}
  769. _s = self.s.post(
  770. url=url, headers=self.post_headers, data=json.dumps(data), timeout=10
  771. )
  772. response_data = _s.json()
  773. return response_data
  774. def get_cutout_image_times(self):
  775. # 获取抠图剩余次数
  776. url = "{domain}/api/ai_image/client/search_company_balance".format(
  777. domain=settings.DOMAIN
  778. )
  779. _s = self.s.post(url=url, headers=self.post_headers, timeout=10)
  780. response_data = _s.json()
  781. if "data" not in response_data:
  782. return False
  783. else:
  784. return response_data["data"]
  785. def get_key_secret(self):
  786. # 获取抠图剩余次数
  787. url = "{domain}/api/ai_image/client/get_key_serect".format(
  788. domain=settings.DOMAIN
  789. )
  790. _s = self.s.post(url=url, headers=self.post_headers, timeout=10)
  791. response_data = _s.json()
  792. return response_data["data"]