demo_ADCluesInspection.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. # -*- codeing = utf-8 -*-
  2. # @Time : 2023/12/18 16:44
  3. # @Author : Clown
  4. # @File : demo_ADCluesInspection.py
  5. # @Software : PyCharm
  6. import pymysql
  7. import requests
  8. import json
  9. from datetime import datetime,timedelta,time
  10. from dateutil.parser import parse
  11. from EC_招商CRM import runTrajectory,selectCustomsInfo,get_sign
  12. import time as tms
  13. def linkTomySql(host, passwd, db_name, port):
  14. '''连接至数据库返回【db】,v2新增local_infile=1 打开文件导入权限'''
  15. try:
  16. # 本地连接为:localhost 服务器连接为:124.222.188.59
  17. db = pymysql.connect (
  18. host=host, user="root",
  19. passwd=passwd,
  20. db=db_name,
  21. port=port,
  22. charset='utf8mb4',
  23. local_infile=1)
  24. print ('\nconnect to mysql server 成功')
  25. print ('---------------------------------------')
  26. except:
  27. print ("\ncould not connect to mysql server")
  28. db = "连接失败"
  29. return db
  30. def read_key_value_pair(db, brand_name, wm_plate, owner):
  31. '''按条件读取,数据库中all_key_table表里的key_value_pair字段中的值,以键值对的形式输出
  32. db:数据库,
  33. brand_name:品牌名,
  34. wm_plate:外卖平台MEITUAN或ELEME,
  35. owner:账号权限all或one
  36. '''
  37. cursor = db.cursor ()
  38. sql = f'SELECT key_value_pair FROM all_key_table WHERE brand_name = "{brand_name}" AND wm_plate = "{wm_plate}" AND owner = "{owner}";'
  39. cursor.execute (sql)
  40. pair = json.loads (cursor.fetchall ()[0][0])
  41. return pair
  42. def sendMsgToRot(url,msg_txt):
  43. params_json = {
  44. "msgtype": "markdown",
  45. "markdown": {
  46. "content": msg_txt,
  47. "mentioned_list":["@all"]
  48. }}
  49. resp = requests.post(url,json=params_json).text
  50. print(resp)
  51. #更新客户跟进人
  52. def updateCsFollower(corpid,sign,timestamp,crmId,followUserIds):
  53. url = 'https://open.workec.com/v2/customer/change/user'
  54. headers = {'Content-Type': 'application/json',
  55. 'X-Ec-Cid': corpid,
  56. 'X-Ec-Sign': sign,
  57. 'X-Ec-TimeStamp': timestamp}
  58. json_params = {'optUserId': 17409174,
  59. 'crmIds': crmId,
  60. 'followUserId': followUserIds}
  61. resp = requests.post (url, headers=headers, json=json_params).json ()
  62. success = resp['data']['success']
  63. return success
  64. # 查询计时器时间,输出起始时间
  65. def selectcycle_time_meter(db,minutes):
  66. cursor = db.cursor ()
  67. sql = f'SELECT * FROM cycle_time_meter WHERE id = 1;'
  68. cursor.execute (sql)
  69. lastCatchTime_ago = cursor.fetchall ()[0][0]
  70. lastCatchTime_ago_s = (lastCatchTime_ago + timedelta(seconds=1)).strftime('%Y-%m-%d %H:%M:%S')
  71. # 更新间隔
  72. lastCatchTime_now_s = (lastCatchTime_ago + timedelta(minutes=minutes)).strftime('%Y-%m-%d %H:%M:%S')
  73. cursor.close()
  74. return lastCatchTime_ago_s,lastCatchTime_now_s
  75. # 更新计时器时间
  76. def updatecycle_time_meter(db,lastCatchTime_now_s):
  77. cursor = db.cursor ()
  78. sql = f'UPDATE cycle_time_meter SET lastCatchTime = "{lastCatchTime_now_s}" WHERE id = 1;'
  79. cursor.execute(sql)
  80. db.commit()
  81. cursor.close()
  82. # 线索流传状态查询
  83. def ad_clues_inspection(crmIds):
  84. # url = 'http://clownted.top:63307/trajectory'
  85. params = {'crmIds': crmIds,
  86. 'memo': '0',
  87. 'lastContactTime': '0'}
  88. # headers = {"Content-Type": "application/json;charset=UTF-8"}
  89. # resp = requests.post(url, json = params, headers = headers).text
  90. resp = runTrajectory(params)
  91. return resp
  92. # 将线索资源写入数据库ad_clues_inspection_cycle
  93. def update_ad_clues_inspection(db,data_to_update):
  94. cursor = db.cursor()
  95. row_data = data_to_update
  96. sql = '''REPLACE INTO ad_clues_inspection_cycle VALUES (%s,%s,%s,%s,%s,%s,%s);'''
  97. cursor.execute(sql, row_data)
  98. db.commit ()
  99. def select_ad_clues_inspection(db,cluePhoneNumber):
  100. cursor = db.cursor()
  101. sql = f'''SELECT * FROM ad_clues_inspection_cycle WHERE cluePhoneNumber = '{cluePhoneNumber}';'''
  102. cursor.execute(sql)
  103. value_out_list = cursor.fetchall()
  104. cursor.close ()
  105. if len (value_out_list) == 0:
  106. result = 0
  107. else:
  108. result = 1
  109. return result
  110. def select_ad_clues_to_cycle(db,s_datetime,e_datetime):
  111. cursor = db.cursor()
  112. beginTime = '2023-12-25 09:30:00'
  113. sql = f'''SELECT * FROM ad_clues_inspection_cycle WHERE movingTime >= '{s_datetime}' and movingTime <= '{e_datetime}' and crmIdCreateTime >= '{beginTime}';'''
  114. # print(sql)
  115. cursor.execute(sql)
  116. value_out_list = cursor.fetchall()
  117. cursor.close()
  118. out_list = []
  119. for row in value_out_list:
  120. clue_phone = row[0]
  121. out_list.append(clue_phone)
  122. return out_list
  123. def select_ad_clues_error_state(db):
  124. cursor = db.cursor()
  125. sql = f'''SELECT * FROM (SELECT * FROM ad_clues_inspection_cycle WHERE crmId is NULL OR memo -> '$.result' = 'error')t1 WHERE SUBSTRING(cluePhoneNumber, 1, 1) <> '0';'''
  126. cursor.execute(sql)
  127. value_out_list = cursor.fetchall()
  128. cursor.close()
  129. out_list = []
  130. for row in value_out_list:
  131. clue_phone = row[0]
  132. out_list.append(clue_phone)
  133. return out_list
  134. def add_clues_to_cycle_list(db,s_datetime,e_datetime,cycle_hours):
  135. key_json = read_key_value_pair(db, '道一云', '7qiaoPlus', 'all')
  136. applicationId = '63631ee57005c0103426fdc7'
  137. Token = key_json['data']
  138. formModelId = '63631ef07c997625a7627ac1'
  139. s_datetime = (parse(s_datetime).timestamp()-60*20) * 1000
  140. e_datetime = parse(e_datetime).timestamp() * 1000
  141. page = 0
  142. pages = 1
  143. clue_photo_num_list = []
  144. while page < pages:
  145. page += 1
  146. url = f'https://qiqiao.do1.com.cn/plus/cgi-bin/open/applications/{applicationId}/forms/{formModelId}/query?page={page}'
  147. headers_api = {
  148. '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',
  149. "Content-type": "application/json",
  150. "X-Auth0-Token": Token}
  151. # params = [{"fieldName": "录入时间", "logic": "ge", "value": int(s_datetime)},
  152. # {"fieldName": "录入时间", "logic": "le", "value": int(e_datetime)}]
  153. params = [{"fieldName": "录入时间", "logic": "between", "value": f'{int(s_datetime)},{int(e_datetime)}'}]
  154. print(params)
  155. resp = requests.post(url, headers = headers_api, json = params)
  156. # print(resp.text)
  157. resp_json = resp.json()
  158. pages = resp_json['data']['totalPage']
  159. currPage = resp_json['data']['currPage']
  160. clues_list = resp_json['data']['list']
  161. for clue_info in clues_list:
  162. # print(clue_info)
  163. clue_photo_num = clue_info['variables']['客户手机']
  164. clue_photo_num_list.append(clue_photo_num)
  165. clue_photo_num_list = clue_photo_num_list + select_ad_clues_error_state(db)
  166. clue_photo_num_list = list(set(clue_photo_num_list))
  167. for clue_phone in clue_photo_num_list:
  168. result = select_ad_clues_inspection(db, clue_phone)
  169. if result == 0:
  170. clue_data = (str(clue_phone), None, None, None, None, None, '首次创建')
  171. update_ad_clues_inspection(db, clue_data)
  172. else:
  173. ...
  174. x = 50
  175. n = int((len(clue_photo_num_list) - 0) / x)
  176. print(n)
  177. clue_photo_num_group = []
  178. for i in range(n + 1):
  179. # print(i*x,(i+1)*x)
  180. # print(len(clue_photo_num_list[i*x:(i+1)*x]))
  181. group = ','.join(clue_photo_num_list[i * x:(i + 1) * x])
  182. clue_photo_num_group.append(group)
  183. # print(clue_photo_num_group)
  184. insert_list = selectCustomsInfo(clue_photo_num_list, cycle_hours)
  185. for insert_data in insert_list:
  186. insert_data = insert_data[:5] + (
  187. json.dumps(ad_clues_inspection(insert_data[1]), ensure_ascii = False),) + insert_data[6:]
  188. # print(insert_data)
  189. if "电话" in insert_data[5]:
  190. insert_data = insert_data[:6] + ('正常保留',)
  191. else:
  192. insert_data = insert_data[:6] + ('异常流转0',)
  193. update_ad_clues_inspection(db, insert_data)
  194. def cycle_clues_to_m(db,s_datetime,e_datetime,cycle_hours,followUserIds):
  195. corpid = '17409173'
  196. timestamp = str(int(round(tms.time() * 1000)))
  197. app_id = '914890189023739904'
  198. app_secret = 'Ur2K41t71RrxYn7eWhN'
  199. sign = get_sign(app_id, app_secret, str(timestamp))
  200. cycle_phone_num_list = select_ad_clues_to_cycle(db, s_datetime, e_datetime)
  201. x = 50
  202. n = int((len(cycle_phone_num_list) - 0) / x)
  203. print(n)
  204. clue_photo_num_group = []
  205. for i in range(n + 1):
  206. # print(i*x,(i+1)*x)
  207. # print(len(clue_photo_num_list[i*x:(i+1)*x]))
  208. group = ','.join(cycle_phone_num_list[i * x:(i + 1) * x])
  209. clue_photo_num_group.append(group)
  210. # print(clue_photo_num_group)
  211. insert_list = selectCustomsInfo(cycle_phone_num_list, cycle_hours)
  212. for insert_data in insert_list:
  213. insert_data = insert_data[:5] + (
  214. json.dumps(ad_clues_inspection(insert_data[1]), ensure_ascii = False),) + insert_data[6:]
  215. # print(insert_data)
  216. if "电话" in insert_data[5]:
  217. insert_data = insert_data[:6] + ('正常保留',)
  218. else:
  219. insert_data = insert_data[:6] + ('异常流转1',)
  220. crmId = insert_data[1]
  221. url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=48eaf1ae-1e29-4a7d-9279-b2aaa0e218cf'
  222. name = json.loads(insert_data[5])['followerName']
  223. msg_txt = f'来自【{name}】的线索【{insert_data[0]}】已超过15小时未跟进'
  224. # sendMsgToRot(url, msg_txt)
  225. # updateCsFollower(corpid, sign, timestamp, crmId, followUserIds)
  226. update_ad_clues_inspection(db, insert_data)
  227. def run_cycle(db):
  228. # 初始化时间周期
  229. # 更新间隔
  230. minute = 10
  231. f_now = datetime.now()
  232. f_mm = f_now.strftime("%M")
  233. f_ss = f_now.strftime("%S")
  234. f_c = int(f_mm) % minute
  235. wait_s = (minute - f_c - 1) * 60 + 59 - int(f_ss)
  236. tms.sleep(wait_s)
  237. # 执行循环
  238. while True:
  239. now = datetime.now()
  240. mm = now.strftime("%M")
  241. ss = now.strftime("%S")
  242. c = int(mm) % minute
  243. if c == 0 and ss == '01':
  244. s = tms.time()
  245. # print(now)
  246. cycle_hours = 15 # 重新轮转间隔小时
  247. # minutes = 10 # 时间间隔分钟
  248. followUserIds = '19710025'
  249. s_datetime, e_datetime = selectcycle_time_meter(db, minute)
  250. print(s_datetime, e_datetime)
  251. add_clues_to_cycle_list(db, s_datetime, e_datetime, cycle_hours)
  252. cycle_clues_to_m(db, s_datetime, e_datetime, cycle_hours, followUserIds)
  253. updatecycle_time_meter(db,e_datetime)
  254. tms.sleep(minute * 60 - 0.5 - (tms.time() - s))
  255. if __name__ == '__main__':
  256. # host = 'clownted.top'
  257. # passwd = '111...Clown'
  258. # db_name = 'zuzu_data'
  259. # port = 63306
  260. host = 'localhost'
  261. passwd = '111???clown'
  262. db_name = 'hexingxing'
  263. port = 3306
  264. db = linkTomySql(host, passwd, db_name, port)
  265. cycle_hours = 15 #重新轮转间隔小时
  266. minutes = 10 # 时间间隔分钟
  267. followUserIds = '19710025'
  268. lastCatchTime_ago_s, lastCatchTime_now_s = selectcycle_time_meter(db, minutes)
  269. cnt = int((datetime.now().timestamp() - parse(lastCatchTime_ago_s).timestamp()) / 60 / minutes) * minutes - minutes
  270. if cnt > 0:
  271. s_datetime,e_datetime = selectcycle_time_meter(db,cnt)
  272. # e_datetime = '2023-12-25 23:59:59'
  273. print(s_datetime,e_datetime)
  274. add_clues_to_cycle_list(db, s_datetime, e_datetime, cycle_hours)
  275. cycle_clues_to_m(db, s_datetime, e_datetime, cycle_hours,followUserIds)
  276. updatecycle_time_meter(db, e_datetime)
  277. else:
  278. print('正式执行')
  279. tms.sleep(10)
  280. run_cycle(db)
  281. # ad_clues_inspection()
  282. if 1==0:
  283. key_json = read_key_value_pair (db, '道一云', '7qiaoPlus', 'all')
  284. applicationId = '63631ee57005c0103426fdc7'
  285. Token = key_json['data']
  286. formModelId = '63631ef07c997625a7627ac1'
  287. s_datetime = parse('2023-12-25 09:30:00').timestamp()*1000
  288. e_datetime = parse('2023-12-25 23:59:59').timestamp()*1000
  289. cycle_hours = 15
  290. # print(s_datetime,e_datetime)
  291. page = 0
  292. pages = 1
  293. clue_photo_num_list = []
  294. while page < pages:
  295. page += 1
  296. url = f'https://qiqiao.do1.com.cn/plus/cgi-bin/open/applications/{applicationId}/forms/{formModelId}/query?page={page}'
  297. headers_api = {
  298. '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',
  299. "Content-type": "application/json",
  300. "X-Auth0-Token": Token}
  301. params = [ {"fieldName":"录入时间", "logic": "ge", "value":int(s_datetime)},{"fieldName":"录入时间", "logic": "le", "value":int(e_datetime)}]
  302. resp = requests.post(url,headers = headers_api,json=params)
  303. print(resp.text)
  304. resp_json = resp.json()
  305. pages = resp_json['data']['totalPage']
  306. currPage = resp_json['data']['currPage']
  307. clues_list = resp_json['data']['list']
  308. for clue_info in clues_list:
  309. # print(clue_info)
  310. clue_photo_num = clue_info['variables']['客户手机']
  311. clue_photo_num_list.append(clue_photo_num)
  312. clue_photo_num_list = list(set(clue_photo_num_list))
  313. for clue_phone in clue_photo_num_list:
  314. clue_data = (str(clue_phone),None,None,None,None,None,'首次创建')
  315. update_ad_clues_inspection(db, clue_data)
  316. if 1==1:
  317. x = 50
  318. n = int((len(clue_photo_num_list)-0)/x)
  319. print(n)
  320. clue_photo_num_group = []
  321. for i in range(n+1):
  322. # print(i*x,(i+1)*x)
  323. # print(len(clue_photo_num_list[i*x:(i+1)*x]))
  324. group = ','.join(clue_photo_num_list[i*x:(i+1)*x])
  325. clue_photo_num_group.append(group)
  326. print(clue_photo_num_group)
  327. insert_list = selectCustomsInfo(clue_photo_num_list,cycle_hours)
  328. for insert_data in insert_list:
  329. insert_data = insert_data[:5]+(json.dumps(ad_clues_inspection(insert_data[1]),ensure_ascii = False),)+insert_data[6:]
  330. print(insert_data)
  331. if "电话" in insert_data[5]:
  332. insert_data = insert_data[:6] + ('正常保留',)
  333. else:
  334. insert_data = insert_data[:6] + ('异常流转',)
  335. update_ad_clues_inspection(db, insert_data)
  336. db.close()