tool_for_goods_demo_v3.py 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013
  1. # -*- codeing = utf-8 -*-
  2. # @Time : 2022/8/31 17:52
  3. # @Author : Clown
  4. # @File : tool_for_goods_demo.py
  5. # @Software : PyCharm
  6. import requests
  7. import random
  8. from datetime import datetime,timedelta
  9. import time
  10. import os
  11. import shutil
  12. import json
  13. from all_key_table import update_key_value_pair_7qiaoPlus
  14. import warnings
  15. import re
  16. import csv
  17. import pandas as pd
  18. from requests_toolbelt import MultipartEncoder,MultipartEncoderMonitor
  19. import pymysql
  20. import traceback
  21. from chardet.universaldetector import UniversalDetector
  22. # warnings.filterwarnings('ignore')
  23. def get_filelist(path):
  24. """
  25. 获取路径下所有csv文件的路径列表
  26. """
  27. Filelist = []
  28. for home, dirs, files in os.walk(path):
  29. for filename in files:
  30. if ".csv" in filename:
  31. Filelist.append(os.path.join(home, filename))
  32. return Filelist
  33. def read_file(file):
  34. """
  35. 逐个读取文件的内容
  36. """
  37. with open(file, 'rb') as f:
  38. return f.read()
  39. def get_encode_info(file):
  40. """
  41. 逐个读取文件的编码方式
  42. """
  43. with open(file, 'rb') as f:
  44. detector = UniversalDetector()
  45. for line in f.readlines():
  46. detector.feed(line)
  47. if detector.done:
  48. break
  49. detector.close()
  50. return detector.result['encoding']
  51. def convert_encode2utf8(file, original_encode, des_encode):
  52. """
  53. 将文件的编码方式转换为utf-8,并写入原先的文件中。
  54. """
  55. file_content = read_file(file)
  56. file_decode = file_content.decode(original_encode, 'ignore')
  57. file_encode = file_decode.encode(des_encode)
  58. with open(file, 'wb') as f:
  59. f.write(file_encode)
  60. def read_and_convert(path):
  61. """
  62. 读取文件并转换
  63. """
  64. Filelist = get_filelist(path=path)
  65. fileNum= 0
  66. for filename in Filelist:
  67. try:
  68. file_content = read_file(filename)
  69. encode_info = get_encode_info(filename)
  70. if encode_info != 'utf-8':
  71. fileNum +=1
  72. convert_encode2utf8(filename, encode_info, 'utf-8')
  73. # print('成功转换 %s 个文件 %s '%(fileNum,filename))
  74. except BaseException:
  75. print(filename,'->This file is error,Please recheck_again!')
  76. def recheck_again(path):
  77. """
  78. 再次判断文件是否为utf-8
  79. """
  80. # print('---------------------以下文件仍存在问题---------------------')
  81. Filelist = get_filelist(path)
  82. for filename in Filelist:
  83. encode_info_ch = get_encode_info(filename)
  84. if encode_info_ch != 'utf-8':
  85. print(filename,'--encoding_by(',encode_info_ch,") mark error ")
  86. # print('--------------------------检查结束--------------------------')
  87. # '以上为文件编码转换'
  88. def linkTomySql(host, passwd, db_name, port):
  89. '''连接至数据库返回【db】,v2新增local_infile=1 打开文件导入权限'''
  90. try:
  91. # 本地连接为:localhost 服务器连接为:124.222.188.59
  92. db = pymysql.connect (
  93. host=host, user="root",
  94. passwd=passwd,
  95. db=db_name,
  96. charset='utf8mb4',
  97. local_infile=1,
  98. port=port)
  99. # print ('\nconnect to mysql server 成功')
  100. # print ('---------------------------------------')
  101. except:
  102. print ("\nCould not connect to mysql server")
  103. db = "连接失败"
  104. return db
  105. def read_key_value_pair(db, brand_name, wm_plate, owner):
  106. '''按条件读取,数据库中all_key_table表里的key_value_pair字段中的值,以键值对的形式输出
  107. db:数据库,
  108. brand_name:品牌名,
  109. wm_plate:外卖平台MEITUAN或ELEME,
  110. owner:账号权限all或one
  111. '''
  112. cursor = db.cursor ()
  113. sql = f'SELECT key_value_pair FROM all_key_table WHERE brand_name = "{brand_name}" AND wm_plate = "{wm_plate}" AND owner = "{owner}";'
  114. cursor.execute (sql)
  115. pair = json.loads (cursor.fetchall ()[0][0])
  116. return pair
  117. #20220907更新order_bill
  118. def order_bill(mtinput,elminput,row_id):
  119. '''
  120. :param mtinput: 美团账单文件访问路径
  121. :param elminput: 饿了么账单文件访问路径
  122. :return: bill_dict,error_files 账单字典 美团{'row_id:row_id':{'ID:****':10.01}} or 饿了么{'row_id:row_id':{'id:****':10.01}},错误文件列表
  123. '''
  124. bill_dict = {}
  125. bill_id = 'row_id'+row_id
  126. bill_dict[bill_id]={}
  127. error_files = []
  128. try:
  129. # 读取美团文件
  130. for a, b, files in os.walk (mtinput, topdown=False):
  131. if len (files) == 0:
  132. print ('No Meituan files!')
  133. else:
  134. for file in files:
  135. try:
  136. data_m = pd.read_excel (mtinput + '/' + file, sheet_name='订单明细', dtype='str')
  137. df = data_m[data_m['交易类型'] == '外卖订单'] # 按列条件筛选数据
  138. cnt = len (df['交易类型'])
  139. for i in range (cnt):
  140. row = df.iloc[i]
  141. dingdanid = 'ID:' + str (row['订单号'])
  142. pingtaifuwufei = float (row['平台服务费']) + float (row['公益捐款'])
  143. bill_dict[bill_id][dingdanid] = round (pingtaifuwufei, 2)
  144. except Exception as me:
  145. error_files.append(file)
  146. print ('mt', me)
  147. for a, b, files in os.walk (elminput, topdown=False):
  148. if len (files) == 0:
  149. print ('No Eleme files!')
  150. else:
  151. for file in files:
  152. try:
  153. data_e = pd.read_excel (elminput + '/' + file, sheet_name='外卖订单明细', dtype='str')
  154. df = data_e[data_e['订单类型'] == '外卖订单'] # 按列条件筛选数据
  155. cnt = len (df['订单类型'])
  156. for i in range (cnt):
  157. row = df.iloc[i]
  158. dingdanid = 'id:' + str (row['订单编号'])
  159. jiesuanjine = float (row['结算金额'])
  160. bill_dict[bill_id][dingdanid] = round (jiesuanjine, 2)
  161. except Exception as ee:
  162. error_files.append (file)
  163. print ('elm', ee)
  164. except Exception as b_e:
  165. print('bill',b_e)
  166. # print(bill_dict)
  167. return bill_dict,error_files
  168. #20220907更新files_download
  169. def order_formgoods(mtinput, elminput, save_path, row_id, banner, bill_dict):
  170. '''
  171. :param mtinput: str 美团文件夹地址
  172. :param elminput: str 饿了么文件夹地址
  173. :param save_path: str 综合保存文件的地址
  174. :param row_id str
  175. :param banner: str 品牌名,默认为 空
  176. :return: formgoods_out_file_path(输出文件的访问地址),formgoods_out_file_name(输出的文件名称),error_files(解析失败文件list类型)
  177. '''
  178. mo = 0
  179. num =0
  180. # 20220907更新bill_id,bill_dict_list
  181. bill_id = 'row_id' + row_id
  182. bill_dict_list = bill_dict[bill_id]
  183. time_str = time.strftime("%Y%m%d%H%M%S", time.localtime())
  184. output = save_path +'/' + row_id + '/out'
  185. error_files = []
  186. # 20220907更新title '单品优惠后单价','单品实收单价'
  187. title = ["日期", '订单编号', '订单状态', '下单时段', '平台商品名称', '销量', "原价", '单品优惠后单价', '单品实收单价', '平台', '城市', '平台门店id', '平台门店名称']
  188. formgoods_out_file_path = output+"/%s"%str(banner)+"订单数据(商品信息)%s.csv"%str(time_str)
  189. formgoods_out_file_name = banner + "订单数据(商品信息)%s.csv"%str(time_str)
  190. with open(output+"/%s"%str(banner)+"订单数据(商品信息)%s.csv"%str(time_str),"a",newline='',encoding="utf-8-sig",errors="ignore") as t:#encoding="utf-8",
  191. writer = csv.writer(t)
  192. writer.writerow(title)
  193. #读取美团文件
  194. for a, b, files in os.walk (mtinput, topdown=False):
  195. if len (files) == 0:
  196. print('No Meituan files!')
  197. mf = 0
  198. else:
  199. for file in files:
  200. try:
  201. with open(mtinput+'/'+file,encoding="utf-8") as f:
  202. data = pd.read_csv(f,low_memory=False)#,low_memory=False
  203. list_1 = data['日期']
  204. no = 0
  205. for n in list_1:
  206. num += 1
  207. dingdan = data.iloc[no]
  208. dingdanid = dingdan['订单编号']
  209. # 20220907更新 新增拆解单品优惠后均价all_sale_count,all_sale_discount,discount_rate,income_rate
  210. all_sale_count = float (dingdan['商品原价'])
  211. all_sale_discount = float (dingdan['商品原价']) + float (dingdan['包装费']) - float (
  212. dingdan['商家活动支出'])
  213. discount_rate = all_sale_discount / all_sale_count
  214. try:
  215. pingtaifuwufei = bill_dict_list[dingdanid]
  216. all_sale_income = all_sale_discount + pingtaifuwufei
  217. income_rate = all_sale_income / all_sale_count
  218. except:
  219. income_rate = 'no_bill'
  220. try:
  221. riqi_o = time.strptime(str(dingdan['日期']),"%Y-%m-%d")
  222. riqi = time.strftime("%Y%m%d",riqi_o)
  223. except:
  224. try:
  225. riqi_o = time.strptime(str(dingdan['日期']), "%Y/%m/%d")
  226. riqi = time.strftime("%Y%m%d", riqi_o)
  227. except:
  228. riqi_o = time.strptime (str(dingdan['日期']), "%Y%m%d")
  229. riqi = time.strftime ("%Y%m%d", riqi_o)
  230. try:
  231. try:
  232. shiduan0 = datetime.strptime(dingdan['下单时间'],'%Y/%m/%d %H:%M:%S').strftime("%H") #下单时段
  233. except:
  234. shiduan0 = datetime.strptime (dingdan['下单时间'], '%Y/%m/%d %H:%M').strftime ("%H") # 下单时段
  235. except:
  236. try:
  237. shiduan0 = datetime.strptime(dingdan['下单时间'], '%Y-%m-%d %H:%M:%S').strftime("%H") # 下单时段
  238. except:
  239. shiduan0 = datetime.strptime (dingdan['下单时间'], '%Y-%m-%d %H:%M').strftime ("%H") # 下单时段
  240. try:
  241. try:
  242. shiduan1 = datetime.strptime(dingdan['下单时间'],'%Y/%m/%d %H:%M:%S').strftime("%M") #下单时段
  243. except:
  244. shiduan1 = datetime.strptime (dingdan['下单时间'], '%Y/%m/%d %H:%M').strftime ("%M") # 下单时段
  245. except:
  246. try:
  247. shiduan1 = datetime.strptime(dingdan['下单时间'], '%Y-%m-%d %H:%M:%S').strftime("%M") # 下单时段
  248. except:
  249. shiduan1 = datetime.strptime (dingdan['下单时间'], '%Y-%m-%d %H:%M').strftime ("%M") # 下单时段
  250. if int(shiduan1) < 30:
  251. shiduan1 = ':00'
  252. else:
  253. shiduan1 = ':30'
  254. shiduan = shiduan0 + shiduan1
  255. pingtai = "美团"
  256. city = dingdan['门店所在城市']
  257. shopid = dingdan['门店id']
  258. shop = dingdan['门店名称']
  259. xinxi = dingdan['商品信息']
  260. zhuangtai = dingdan['订单状态']
  261. no += 1
  262. p = r'[^\/].*?\,单价[0-9]*?\.[0-9]*?\*数量\d+'
  263. r = re.compile(p)
  264. cont = []
  265. cont.append(xinxi)
  266. for i in cont:
  267. a = r.finditer(i)
  268. for b in a:
  269. mo += 1
  270. m = b.group()
  271. shangpin = m.split(",单价")[0]
  272. danjia_no = m.split(",单价")[1]
  273. danjia = danjia_no.split("*数量")[0]
  274. shuliang = danjia_no.split("*数量")[1]
  275. # 20220907更新 新增拆解单品优惠后均价sale_discount,sale_income
  276. sale_discount = float (danjia) * discount_rate
  277. try:
  278. sale_income = round (float (danjia) * income_rate, 2)
  279. except:
  280. sale_income = 'no_bill'
  281. ms = [riqi, str (dingdanid), zhuangtai, shiduan, shangpin, shuliang, danjia,
  282. round (sale_discount, 2), sale_income, pingtai, city, shopid, shop]
  283. writer.writerow(ms)
  284. # print ('\r[美团]已拆解%s行,拆解出%s行' % (str (num), str (mo)), end='')
  285. except Exception as e:
  286. print(e)
  287. error_files.append(file)
  288. mf = 1
  289. #读取饿了么文件
  290. for a, b, files in os.walk (elminput, topdown=False):
  291. if len (files) == 0:
  292. print ('No ELeme files!')
  293. ef = 0
  294. else:
  295. for file in files:
  296. try:
  297. data = pd.read_excel(elminput+'/'+file)
  298. list_1 = data['日期']
  299. no = 0
  300. for n in list_1:
  301. num += 1
  302. dingdan = data.iloc[no]
  303. dingdanid = "id:" + str (dingdan['订单单号'])
  304. # 20220907更新 新增拆解单品优惠后均价all_sale_count,all_sale_discount,discount_rate
  305. all_sale_count = float (dingdan['菜品原价'])
  306. all_sale_discount = float (dingdan['菜品原价']) + float (dingdan['餐盒费']) - float (
  307. dingdan['商家成本'])
  308. discount_rate = all_sale_discount / all_sale_count
  309. try:
  310. jiesuanjine = bill_dict_list[dingdanid]
  311. income_rate = jiesuanjine / all_sale_count
  312. except:
  313. income_rate = 'no_bill'
  314. try:
  315. riqi_o = time.strptime (dingdan['日期'], "%Y-%m-%d")
  316. riqi = time.strftime ("%Y%m%d", riqi_o)
  317. except:
  318. riqi_o = time.strptime (dingdan['日期'], "%Y/%m/%d")
  319. riqi = time.strftime ("%Y%m%d", riqi_o)
  320. try:
  321. shiduan0 = datetime.strptime (dingdan['下单时间'], '%Y/%m/%dT%H:%M:%S').strftime ("%H") # 下单时段
  322. except:
  323. shiduan0 = datetime.strptime (dingdan['下单时间'], '%Y-%m-%dT%H:%M:%S').strftime ("%H") # 下单时段
  324. try:
  325. shiduan1 = datetime.strptime (dingdan['下单时间'], '%Y/%m/%dT%H:%M:%S').strftime ("%M") # 下单时段
  326. except:
  327. shiduan1 = datetime.strptime (dingdan['下单时间'], '%Y-%m-%dT%H:%M:%S').strftime ("%M") # 下单时段
  328. if int (shiduan1) < 30:
  329. shiduan1 = ':00'
  330. else:
  331. shiduan1 = ':30'
  332. shiduan = shiduan0 + shiduan1
  333. pingtai = "饿了么"
  334. city = dingdan['门店所在城市']
  335. shopid = dingdan['门店编号']
  336. shop = dingdan['门店名称']
  337. xinxi = dingdan['商品信息']
  338. zhuangtai = dingdan['订单状态']
  339. no += 1
  340. p = r'[^\+].*?\_\d+\*\d+\.\d+'
  341. r = re.compile (p)
  342. cont = []
  343. cont.append (xinxi)
  344. for i in cont:
  345. a = r.finditer (i)
  346. for b in a:
  347. mo += 1
  348. m = b.group ()
  349. shangpin = m.split ("_")[0]
  350. danjia_no = m.split ("_")[1]
  351. danjia = danjia_no.split ("*")[1]
  352. shuliang = danjia_no.split ("*")[0]
  353. # 20220907更新 新增拆解单品优惠后均价sale_discount,sale_income
  354. sale_discount = float (danjia) * discount_rate
  355. try:
  356. sale_income = round (float (danjia) * income_rate, 2)
  357. except:
  358. sale_income = 'no_bill'
  359. ms = [riqi, dingdanid, zhuangtai, shiduan, shangpin, shuliang, danjia,
  360. round (sale_discount, 2), sale_income,
  361. pingtai, city, shopid, shop]
  362. writer.writerow (ms)
  363. # print ('\r[饿了么]已拆解%s行,拆解出%s行' % (str (num), str (mo)), end='')
  364. except Exception as e:
  365. print(e)
  366. # print(e)
  367. error_files.append(file)
  368. ef = 1
  369. none_file = mf + ef #none_file = 0 #此参数用来判断是否上传文件,如果为0则不上传文件
  370. return formgoods_out_file_path,formgoods_out_file_name,error_files,none_file
  371. def order_actions_e(elminput, save_path, row_id, banner):
  372. '''
  373. :param elminput: str 饿了么文件夹地址
  374. :param save_path: str 综合保存文件的地址
  375. :param row_id str
  376. :param banner: str 品牌名,默认为 空
  377. :return: formactions_out_file_pathE(输出文件的访问地址),formactions_out_file_nameE(输出的文件名称),error_files(解析失败文件list类型)
  378. '''
  379. mo = 0
  380. num = 0
  381. time_str = time.strftime ("%Y%m%d%H%M%S", time.localtime ())
  382. output = save_path + '/' + row_id + '/out'
  383. formactions_out_file_pathE = output + "/" + banner + "elm订单数据(活动信息)%s.csv" % str (time_str)
  384. formactions_out_file_nameE = banner + "elm订单数据(活动信息)%s.csv" % str (time_str)
  385. error_files = []
  386. none_file = 1 # 此参数用来判断是否上传文件,如果为0则不上传文件
  387. title = ["日期", '门店名称', '门店id', '门店所在城市', '订单编号', '下单时间', "活动明细", "分类1", "分类2", "商家承担费用", '平台承担费用', '规则备注']
  388. with open (output + "/" + banner + "elm订单数据(活动信息)%s.csv" % str (time_str), "a", newline='',encoding="utf-8-sig",errors="ignore") as t:
  389. writer = csv.writer (t)
  390. writer.writerow (title)
  391. for a, b, files in os.walk (elminput, topdown=False):
  392. if len (files) == 0:
  393. print ('No ELeme files!')
  394. none_file = 0
  395. else:
  396. for file in files:
  397. try:
  398. data = pd.read_excel(elminput+'/'+file,dtype='str')
  399. list_1 = data['日期']
  400. no = 0
  401. for n in list_1:
  402. num += 1
  403. dingdan = data.iloc[no]
  404. riqi = dingdan['日期']
  405. shop = dingdan['门店名称']
  406. shopid = dingdan['门店编号']
  407. city = dingdan['门店所在城市']
  408. dingdanid = dingdan['订单单号']
  409. xiadanshijian = dingdan['下单时间']
  410. xinxi = dingdan['活动信息']
  411. no += 1
  412. try:
  413. xinxi_list = xinxi.split ('+')
  414. for b in xinxi_list:
  415. mo += 1
  416. try:
  417. p = r'【.*?】【.*?】'
  418. r = re.compile (p)
  419. fenlei = r.search (b).group ()
  420. except:
  421. p = r'【.*?】'
  422. r = re.compile (p)
  423. fenlei = r.search (b).group ()
  424. try:
  425. b1 = re.split (":", b)[0]
  426. p1 = r'【(.*)】【(.*)】(.*)'
  427. r1 = re.compile (p1)
  428. fenlei1 = r1.search (b1).group (3)
  429. except:
  430. b1 = re.split (":", b)[0]
  431. p1 = r'【(.*)】(.*)'
  432. r1 = re.compile (p1)
  433. fenlei1 = r1.search (b1).group (2)
  434. try:
  435. q = r'商户补贴\d+\.\d+'
  436. s = re.compile (q)
  437. cash = s.search (b).group ()
  438. cash_no = re.search ('\d+\.\d+', cash, flags=0).group ()
  439. except:
  440. cash_no = 0
  441. try:
  442. q1 = r'平台补贴\d+\.\d+'
  443. s1 = re.compile (q1)
  444. cash1 = s1.search (b).group ()
  445. cash_no1 = re.search ('\d+\.\d+', cash1, flags=0).group ()
  446. except:
  447. cash_no1 = 0
  448. try:
  449. rule = b.split ('规则:')[1]
  450. except:
  451. rule = ""
  452. ms = [[riqi, shop, shopid, city, (str (dingdanid) + "\t"), xiadanshijian, b, fenlei, fenlei1, cash_no, cash_no1, rule]]
  453. writer.writerows (ms)
  454. except:
  455. ms = [[riqi, shop, shopid, city, (str (dingdanid) + "\t"), xiadanshijian, "null", "null", "null", 0, 0, "null"]]
  456. writer.writerows (ms)
  457. # print ('\r 已拆解%s行,拆解出%s行' % (str (num), str (mo)), end='')
  458. except Exception as e:
  459. print(e)
  460. error_files.append('【活动信息无法解析】'+file)
  461. return formactions_out_file_pathE,formactions_out_file_nameE,error_files,none_file
  462. def order_actions_m(mtinput, save_path, row_id, banner):
  463. '''
  464. :param mtinput: str 美团文件夹地址
  465. :param save_path: str 综合保存文件的地址
  466. :param row_id str
  467. :param banner: str 品牌名,默认为 空
  468. :return: formactions_out_file_pathM(输出文件的访问地址),formactions_out_file_nameM(输出的文件名称),error_files(解析失败文件list类型)
  469. '''
  470. mo = 0
  471. num = 0
  472. time_str = time.strftime ("%Y%m%d%H%M%S", time.localtime ())
  473. output = save_path + '/' + row_id + '/out'
  474. formactions_out_file_pathM = output + "/" + banner + "mt订单数据(活动信息)%s.csv" % str (time_str)
  475. formactions_out_file_nameM = banner + "mt订单数据(活动信息)%s.csv" % str (time_str)
  476. error_files = []
  477. none_file = 1 # 此参数用来判断是否上传文件,如果为0则不上传文件
  478. title = ["日期", '门店名称', '门店id', '门店所在城市', '订单编号', '下单时间', "活动明细", "分类", "商家承担费用", '平台承担费用', '代理商承担费用', '折扣商品', '原价', '现价']
  479. with open (output + "/%s" % str (banner) + "mt订单数据(活动信息)%s.csv" % str (time_str), "a", newline='', encoding="utf-8-sig", errors="ignore") as t:
  480. writer = csv.writer (t)
  481. writer.writerow (title)
  482. for a, b, files in os.walk (mtinput, topdown=False):
  483. if len (files) == 0:
  484. print('No Meituan files!')
  485. none_file = 0
  486. else:
  487. for file in files:
  488. try:
  489. with open (mtinput + '/' + file,encoding='utf-8') as f:
  490. data = pd.read_csv (f, low_memory=False)
  491. list_1 = data['日期']
  492. no = 0
  493. for n in list_1:
  494. num += 1
  495. dingdan = data.iloc[no]
  496. riqi = dingdan['日期']
  497. shop = dingdan['门店名称']
  498. shopid = dingdan['门店id']
  499. city = dingdan['门店所在城市']
  500. dingdanid = dingdan['订单编号']
  501. xiadanshijian = dingdan['下单时间']
  502. xinxi = dingdan['活动信息']
  503. no += 1
  504. try:
  505. xinxi_list = xinxi.split ('/')
  506. for b in xinxi_list:
  507. mo += 1
  508. try:
  509. p = r'会员红包|减配|商家代金券|津贴|购买|支付红包|门店新客立减|平台新客立减|首单立减|跨店免运费'
  510. r = re.compile (p)
  511. fenlei = r.search (b).group ()
  512. except:
  513. try:
  514. p1 = r'满\d+\.\d+元减'
  515. r1 = re.compile (p1)
  516. fenlei1 = r1.search (b).group ()
  517. fenlei = "订单满减"
  518. except:
  519. p2 = r'满\d+\.\d+元赠'
  520. r2 = re.compile (p2)
  521. fenlei2 = r2.search (b).group ()
  522. fenlei = "订单满赠"
  523. try:
  524. q = r'商家承担:\d*?\.\d*?元'
  525. s = re.compile (q)
  526. cash = s.search (b).group ()
  527. cash_no = re.search ('\d+\.\d+', cash, flags=0).group ()
  528. except:
  529. cash_no = 0
  530. try:
  531. q11 = r'代理商承担:\d*?\.\d*?元'
  532. s11 = re.compile (q11)
  533. cash11 = s11.search (b).group ()
  534. cash_no11 = re.search ('\d+\.\d+', cash11, flags=0).group ()
  535. except:
  536. cash_no11 = 0
  537. try:
  538. q1 = r'新美大承担:\d*?\.\d*?元'
  539. s1 = re.compile (q1)
  540. cash1 = s1.search (b).group ()
  541. cash_no1 = re.search ('\d+\.\d+', cash1, flags=0).group ()
  542. except:
  543. cash_no1 = 0
  544. try:
  545. q2 = r'购买(.*)原价(.*)元现价(.*)元\['
  546. s2 = re.compile (q2)
  547. cash_no2 = s2.search (b).group (1)
  548. cash_no3 = s2.search (b).group (2)
  549. cash_no4 = s2.search (b).group (3)
  550. # cash_no2 = re.search('[^购买](.*)',cash2,flags=0).group()
  551. except:
  552. cash_no2 = ''
  553. cash_no3 = ''
  554. cash_no4 = ''
  555. ms = [[riqi, shop, shopid, city, dingdanid, xiadanshijian, b, fenlei, cash_no, cash_no1, cash_no11, cash_no2, cash_no3, cash_no4]]
  556. writer.writerows (ms)
  557. except:
  558. ms = [[riqi, shop, shopid, city, dingdanid, xiadanshijian, "null", "null", 0, 0, 0, "", "", ""]]
  559. writer.writerows (ms)
  560. # print ('\r 已拆解%s行,拆解出%s行' % (str (num), str (mo)), end='')
  561. except Exception as e:
  562. print(e)
  563. error_files.append('【活动信息无法解析】'+file)
  564. return formactions_out_file_pathM, formactions_out_file_nameM, error_files, none_file
  565. def update_7qiaoPlus_row(Token, applicationId, formModelId, variables, row_id, version):
  566. '''
  567. :param Token: str() 密钥
  568. :param applicationId: str() 应用id
  569. :param formModelId: str() 表单id
  570. :param variables: 参数键值对,传入需更新的内容{
  571. //"字段名" : "值"
  572. "fieldName": "fieldValue",
  573. "age": "22",
  574. "单行文本" : "文本内容",
  575. "数字" : 123,
  576. "单项选择" : "1",
  577. "多项选择" : ["1", "2", "3"],
  578. //人员、部门选择控件需要传入对应的id
  579. "人员单选" : "123412341243",
  580. "人员多选" : ["123","345","456"],
  581. "日期" : "2020-10-10",
  582. "日期时间" : "2020-10-10 10:10:00",
  583. "时间" : "10:10:00",
  584. "富文本" : "文本内容",
  585. //图片上传、文件上传、音频、视频可以通过调用文件上传接口,将返回的结果“data”值进行传参
  586. "图片上传" : "data",
  587. //手写签名可以通过调用文件上传接口,将返回的结果“fileUrl”值进行传参
  588. "手写签名" : "fileUrl"
  589. }
  590. :param row_id: 表单实例id
  591. :param version: 更新版本 需要通过函数 select_7qiaoPlus_row 获取
  592. :return:
  593. '''
  594. headers_api = {
  595. 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36',
  596. "Content-type": "application/json",
  597. "X-Auth0-Token": Token}
  598. url_update = f'https://qiqiao.do1.com.cn/plus/cgi-bin/open/applications/{applicationId}/forms/{formModelId}'
  599. param_json = {"variables": '',
  600. "id": row_id,
  601. "version": version,
  602. "loginUserId": "92874ed35ecb45f51a58adcf18e99b5e"
  603. }
  604. param_json['variables'] = variables
  605. try:
  606. resp = requests.put (url_update, json=param_json, headers=headers_api).json ()
  607. if resp['code'] != 0:
  608. print(resp['code'])
  609. else:
  610. ...
  611. # print('Done')
  612. except Exception as e:
  613. print(e)
  614. def select_7qiaoPlus_row(Token, applicationId, formModelId, row_id):
  615. '''
  616. :param Token: str() 密钥
  617. :param applicationId: str() 应用id
  618. :param formModelId: str() 表单id
  619. :param row_id: str() 表单实例id
  620. :return: resp json()格式
  621. '''
  622. headers_api = {
  623. 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36',
  624. "Content-type": "application/json",
  625. "X-Auth0-Token": Token}
  626. url_select = f'https://qiqiao.do1.com.cn/plus/cgi-bin/open/applications/{applicationId}/forms/{formModelId}/{row_id}'
  627. resp = requests.get (url_select, headers=headers_api).json ()
  628. return resp
  629. #20220907更新files_download
  630. def files_download(Token, applicationId, resp, save_path, row_id, fieldName):
  631. '''
  632. :param Token: str
  633. :param applicationId: str
  634. :param resp: dict
  635. :param save_path: str
  636. :param fieldName: str '输入文件'
  637. :return: version, save_path_e, save_path_m
  638. '''
  639. #创建文件夹用于存储下载的文件
  640. path = save_path + '/' + row_id
  641. save_path_e = save_path + '/' + row_id +'/elmsave'
  642. save_path_m = save_path + '/' + row_id +'/mtsave'
  643. os.mkdir (path)
  644. os.mkdir (save_path_e)
  645. os.mkdir (save_path_m)
  646. # 新增功能20220907
  647. save_path_e_bill = save_path + '/' + row_id + '/elmbillsave'
  648. save_path_m_bill = save_path + '/' + row_id + '/mtbillsave'
  649. os.mkdir (save_path_e_bill)
  650. os.mkdir (save_path_m_bill)
  651. version = resp['data']['version']
  652. files_info = resp['data']['variables'][fieldName]
  653. headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36',
  654. "Content-type": "application/json",
  655. "X-Auth0-Token": Token}
  656. for file_info in files_info:
  657. fileId = file_info['fileId']
  658. name = file_info['name']
  659. a = name.split('.')
  660. # 新增功能20220907 以下if...elif..elif..else
  661. if 'xlsx' in a and 'csv' not in a and 'xls' not in a:
  662. if '账单' in name:
  663. url_down = f'https://qiqiao.do1.com.cn/plus/cgi-bin/open/file_download/applications/{applicationId}/files/{fileId}'
  664. resp_down = requests.get (url_down, headers=headers).content
  665. with open (save_path_e_bill + '/%s' % str (name), mode='wb') as f:
  666. f.write (resp_down)
  667. print (name, 'bill->Download Over')
  668. else:
  669. url_down = f'https://qiqiao.do1.com.cn/plus/cgi-bin/open/file_download/applications/{applicationId}/files/{fileId}'
  670. resp_down = requests.get (url_down, headers=headers).content
  671. with open (save_path_e + '/%s' % str (name), mode='wb') as f:
  672. f.write (resp_down)
  673. print (name, '->Download Over')
  674. elif 'csv' in a and 'xlsx' not in a and 'xls' not in a:
  675. url_down = f'https://qiqiao.do1.com.cn/plus/cgi-bin/open/file_download/applications/{applicationId}/files/{fileId}'
  676. resp_down = requests.get (url_down, headers=headers).content
  677. with open (save_path_m + '/%s' % str (name), mode='wb') as f:
  678. f.write (resp_down)
  679. print (name, '->Download Over')
  680. elif 'xls' in a and 'xlsx' not in a and 'csv' not in a:
  681. url_down = f'https://qiqiao.do1.com.cn/plus/cgi-bin/open/file_download/applications/{applicationId}/files/{fileId}'
  682. resp_down = requests.get (url_down, headers=headers).content
  683. with open (save_path_m_bill + '/%s' % str (name), mode='wb') as f:
  684. f.write (resp_down)
  685. print (name, 'bill->Download Over')
  686. else:
  687. print ('file_name error!')
  688. # 新增功能20220907 return有更新
  689. return version, save_path_e, save_path_m, save_path_e_bill, save_path_m_bill
  690. def my_callback(monitor):
  691. # 进度条读取
  692. progress = (monitor.bytes_read / monitor.len) * 100
  693. # print("\r 文件上传进度:%d%%(%d/%d)" % (progress, monitor.bytes_read, monitor.len), end=" ")
  694. return progress
  695. def files_upload(Token, applicationId, formModelId, file_name, file_path):
  696. '''
  697. :param Token: str
  698. :param applicationId: str
  699. :param formModelId: str
  700. :param file_name: str 文件名
  701. :param file_path: str 文件打开路径
  702. :return: resp_upload: dict josn(格式) 常用取值方式: resp_upload['data']
  703. '''
  704. url_upload = f'https://qiqiao.do1.com.cn/plus/cgi-bin/open/file_upload/applications/{applicationId}/form_models/{formModelId}'
  705. params = 'fieldType=FILEUPLOAD'
  706. # 流文件上传方式
  707. data_upload = MultipartEncoder (
  708. {'files': (file_name, open (file_path, 'rb'), 'text/csv')})
  709. data_upload = MultipartEncoderMonitor (data_upload, my_callback)
  710. headers_upload = {
  711. 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36',
  712. "Content-type": data_upload.content_type,
  713. "X-Auth0-Token": Token}
  714. resp_upload = requests.post (url_upload, headers=headers_upload, params=params, data=data_upload).json ()
  715. return resp_upload
  716. #20220907更新tool_for_use
  717. def tool_for_use(row_id,gongneng):
  718. applicationId = 'c10510196559404b99b0f8591e8baa5b' # 测试
  719. formModelId = '6311c1161e8a542078bf5eff' # 文件上传下载
  720. fieldName = '输入文件' # 需提取文件的字段名
  721. # row_id = '6814692804769693696'
  722. save_path = '/home/python_flies/files_handle'
  723. banner = ''
  724. host = 'localhost'
  725. passwd = '111...Clown'
  726. db_name = 'zuzu_data'
  727. port = 63306
  728. db = linkTomySql (host, passwd, db_name, port)
  729. key_json = read_key_value_pair (db, '道一云', '7qiaoPlus', 'all')
  730. Token = key_json['data']
  731. try:
  732. shutil.rmtree (save_path + '/' + row_id)
  733. except:
  734. ...
  735. resp = select_7qiaoPlus_row (Token, applicationId, formModelId, row_id)
  736. code = resp['code']
  737. if code == -401:
  738. update_key_value_pair_7qiaoPlus (db, '道一云', '7qiaoPlus', 'all', '')
  739. key_json = read_key_value_pair (db, '道一云', '7qiaoPlus', 'all')
  740. Token = key_json['data']
  741. resp = select_7qiaoPlus_row (Token, applicationId, formModelId, row_id)
  742. else:
  743. ...
  744. # 20220907更新 version, save_path_e, save_path_m, save_path_e_bill, save_path_m_bill
  745. version, save_path_e, save_path_m, save_path_e_bill, save_path_m_bill = files_download (Token, applicationId,resp, save_path, row_id, fieldName)
  746. read_and_convert (save_path_m)
  747. recheck_again (save_path_m)
  748. print ('Encoding Translate Over!')
  749. out_files = []
  750. mark = 2
  751. output = save_path + '/' + row_id + '/out'
  752. os.mkdir (output)
  753. try:
  754. # 20220907更新 bill_dict
  755. bill_dict,error_files_bill = order_bill (save_path_m_bill, save_path_e_bill, row_id)
  756. if gongneng == '1':
  757. # 20220907更新 bill_dict
  758. file_path, file_name, error_files, none_file = order_formgoods (save_path_m, save_path_e, save_path, row_id,banner, bill_dict)
  759. if none_file >0:
  760. resp_upload = files_upload (Token, applicationId, formModelId, file_name, file_path)
  761. out_files.append(resp_upload['data'][0])
  762. else:
  763. ...
  764. error_file_list = error_files + error_files_bill
  765. if len (error_file_list) > 0:
  766. error_msg = '\n2.【下方为拆解失败的文件,请检查对应文件是否有误!】\n' + '\n'.join (error_files+ error_files_bill)
  767. else:
  768. error_msg = ''
  769. elif gongneng == '2':
  770. file_pathAE, file_nameAE, error_filesAE, none_fileAE = order_actions_e(save_path_e,save_path,row_id,banner)
  771. if none_fileAE == 1:
  772. resp_upload_AE = files_upload (Token, applicationId, formModelId, file_nameAE, file_pathAE)
  773. out_files.append (resp_upload_AE['data'][0])
  774. else:
  775. ...
  776. file_pathAM, file_nameAM, error_filesAM, none_fileAM = order_actions_m (save_path_m, save_path, row_id, banner)
  777. if none_fileAM == 1:
  778. resp_upload_AM = files_upload (Token, applicationId, formModelId, file_nameAM, file_pathAM)
  779. out_files.append (resp_upload_AM['data'][0])
  780. else:
  781. ...
  782. error_file_list = error_filesAE + error_filesAM + error_files_bill
  783. if len (error_file_list) > 0:
  784. error_msg = '\n2.【下方为拆解失败的文件,请检查对应文件是否有误!】\n' + '\n'.join ( error_filesAE + error_filesAM + error_files_bill)
  785. else:
  786. error_msg = ''
  787. elif gongneng == '3':
  788. # 20220907更新 bill_dict
  789. file_path, file_name, error_files, none_file = order_formgoods (save_path_m, save_path_e, save_path, row_id, banner, bill_dict)
  790. if none_file > 0:
  791. resp_upload = files_upload (Token, applicationId, formModelId, file_name, file_path)
  792. out_files.append (resp_upload['data'][0])
  793. else:
  794. ...
  795. file_pathAE, file_nameAE, error_filesAE, none_fileAE = order_actions_e (save_path_e, save_path, row_id, banner)
  796. if none_fileAE == 1:
  797. resp_upload_AE = files_upload (Token, applicationId, formModelId, file_nameAE, file_pathAE)
  798. out_files.append (resp_upload_AE['data'][0])
  799. else:
  800. ...
  801. file_pathAM, file_nameAM, error_filesAM, none_fileAM = order_actions_m (save_path_m, save_path, row_id, banner)
  802. if none_fileAM == 1:
  803. resp_upload_AM = files_upload (Token, applicationId, formModelId, file_nameAM, file_pathAM)
  804. out_files.append (resp_upload_AM['data'][0])
  805. else:
  806. ...
  807. error_file_list = error_files + error_filesAE + error_filesAM + error_files_bill
  808. if len(error_file_list) >0:
  809. error_msg = '\n2.【下方为拆解失败的文件,请检查对应文件是否有误!】\n'+'\n'.join(error_files+error_filesAE+error_filesAM + error_files_bill)
  810. else:
  811. error_msg = ''
  812. else:
  813. error_msg = '\n2.【请选择您要的功能】'
  814. mark = 1
  815. except Exception as eee:
  816. print(eee)
  817. error_msg = '\n2.【服务存在未知错误,请联系信息部】'
  818. mark = 1
  819. variables = {'输出文件': out_files,
  820. '执行结果': f'1.【请至输出文件下载】{error_msg}',
  821. '拆解状态':mark,
  822. '校验文件拆解按钮':'0'}
  823. update_7qiaoPlus_row (Token, applicationId, formModelId, variables, row_id, version)
  824. shutil.rmtree (save_path + '/' + row_id)
  825. print (f'\nTASK_ID【{row_id}】【function:{gongneng}】')
  826. if __name__ == '__main__':
  827. row_id = '6815966588991406080'
  828. tool_for_use (row_id)
  829. '''
  830. applicationId = '62cfb64cb433f27040103cca' # 测试
  831. formModelId = '630f1fb798c136661c4d03a6' # 文件上传下载
  832. fieldName = '输入文件' #需提取文件的字段名
  833. row_id = '6814692804769693696'
  834. save_path = 'C:/Users/ClownHe/Desktop/goods'
  835. banner = ''
  836. host = 'localhost'
  837. passwd = '111???clown'
  838. db_name = 'hexingxing'
  839. db = linkTomySql (host, passwd, db_name)
  840. update_key_value_pair_7qiaoPlus (db, '道一云', '7qiaoPlus', 'all', '')
  841. key_json = read_key_value_pair (db, '道一云', '7qiaoPlus', 'all')
  842. Token = key_json['data']
  843. resp = select_7qiaoPlus_row (Token, applicationId, formModelId, row_id)
  844. version, save_path_e, save_path_m = files_download (Token, applicationId, resp, save_path, row_id, fieldName)
  845. file_path,file_name = order_formgoods (save_path_m, save_path_e, save_path, row_id, banner)
  846. resp_upload = files_upload(Token, applicationId, formModelId, file_name, file_path)
  847. variables = {'输出文件':resp_upload['data'],
  848. '执行结果':'已拆解成功,请至输出文件下载!'}
  849. update_7qiaoPlus_row (Token, applicationId, formModelId, variables, row_id, version)
  850. shutil.rmtree(save_path+'/'+row_id)
  851. print('\nok')
  852. '''