UnicomComboController.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. # -*- encoding: utf-8 -*-
  2. """
  3. @File : UnicomComboController.py
  4. @Time : 2022/6/23 9:18
  5. @Author : stephen
  6. @Email : zhangdongming@asj6.wecom.work
  7. @Software: PyCharm
  8. """
  9. import json
  10. import logging
  11. import time
  12. from django.db import transaction
  13. from django.http import HttpResponse, JsonResponse
  14. from django.views.generic.base import View
  15. from Model.models import UnicomDeviceInfo, UnicomCombo, Pay_Type, Order_Model, Store_Meal, AiStoreMeal, \
  16. UnicomComboOrderInfo
  17. from Object.ResponseObject import ResponseObject
  18. from Object.TokenObject import TokenObject
  19. from Object.UnicomObject import UnicomObjeect
  20. from Object.utils import LocalDateTimeUtil
  21. from Object.utils.PayUtil import PayService
  22. from Service.CommonService import CommonService
  23. class UnicomComboView(View):
  24. def get(self, request, *args, **kwargs):
  25. request.encoding = 'utf-8'
  26. operation = kwargs.get('operation')
  27. return self.validation(request.GET, request, operation)
  28. def post(self, request, *args, **kwargs):
  29. request.encoding = 'utf-8'
  30. operation = kwargs.get('operation')
  31. return self.validation(request.POST, request, operation)
  32. def validation(self, request_dict, request, operation):
  33. if operation == 'buy-notify':
  34. return self.package_callback_notify(request_dict, request)
  35. elif operation == 'test-notify':
  36. order_id = request_dict.get('orderId', None)
  37. activate_type = request_dict.get('activateType', 0)
  38. iccid = request_dict.get('iccid', None)
  39. combo_id = request_dict.get('comboId', None)
  40. self.create_combo_order_info(order_id, int(activate_type), iccid, int(combo_id))
  41. return HttpResponse('SUCCESS')
  42. elif operation == 'device-queue-monitoring':
  43. return self.device_queue_monitoring_push(request_dict, request)
  44. elif operation == 'device-status-change':
  45. return self.device_status_change_push(request_dict, request)
  46. elif operation == 'device-bind':
  47. response = ResponseObject('cn')
  48. return self.device_add(request_dict, response)
  49. else:
  50. token = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
  51. lang = request_dict.get('lang', token.lang)
  52. response = ResponseObject(lang)
  53. if token.code != 0:
  54. return response.json(token.code)
  55. user_id = token.userID
  56. if operation == 'combo-save':
  57. return self.save_unicom_combo(request_dict, response)
  58. elif operation == 'combo-pay':
  59. return self.buy_unicom_combo(user_id, request_dict, request, response)
  60. elif operation == 'combo-list':
  61. return self.query_package_list(response)
  62. elif operation == 'get-device-info':
  63. return self.get_device_info(request_dict, response)
  64. @classmethod
  65. def get_device_info(cls, request_dict, response):
  66. """
  67. 获取设备信息
  68. @param request_dict:
  69. @param response:
  70. @return:
  71. """
  72. serial_no = request_dict.get('serialNumber', None)
  73. if not serial_no:
  74. return response.json(444)
  75. unicom_device_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_no).values()
  76. if not unicom_device_info_qs.exists():
  77. return response.json(173)
  78. return response.json(0, dict(unicom_device_info_qs.first()))
  79. @classmethod
  80. def device_add(cls, request_dict, response):
  81. """
  82. 设备绑定iccid
  83. @param request_dict:
  84. @param response:
  85. @return:
  86. """
  87. iccid = request_dict.get('iccid', None)
  88. serial_no = request_dict.get('serialNo', None)
  89. if not all([iccid, serial_no]):
  90. return response.json(444)
  91. n_time = int(time.time())
  92. try:
  93. with transaction.atomic():
  94. # 待完善代码 根据uid与用户id验证系统设备
  95. unicom_device_qs = UnicomDeviceInfo.objects.filter(iccid=iccid)
  96. if unicom_device_qs.exists():
  97. return response.json(174)
  98. unicom_device_serial_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_no)
  99. if unicom_device_serial_qs.exists():
  100. return response.json(174)
  101. unicom_obj = UnicomObjeect()
  102. result = unicom_obj.verify_device(iccid=iccid)
  103. if result.status_code == 200 and result.text:
  104. res_dict = json.loads(result.text)
  105. if res_dict['success']:
  106. if res_dict['data']['status'] == 0:
  107. return response.json(173)
  108. params = {'iccid': iccid, 'serial_no': serial_no, 'updated_time': n_time,
  109. 'created_time': n_time}
  110. UnicomDeviceInfo.objects.create(**params)
  111. return response.json(0)
  112. else:
  113. return response.json(173)
  114. except Exception as e:
  115. print(e)
  116. return response.json(177, repr(e))
  117. @classmethod
  118. def save_unicom_combo(cls, request_dict, response):
  119. """
  120. 联通套餐保存
  121. @param request_dict:
  122. @param response:
  123. @return:
  124. """
  125. combo_id = request_dict.get('id', None)
  126. combo_name = request_dict.get('comboName', None)
  127. flow_total = request_dict.get('flowTotal', None)
  128. expiration_days = request_dict.get('expirationDays', None)
  129. expiration_type = request_dict.get('expirationType', None)
  130. price = request_dict.get('price', None)
  131. remark = request_dict.get('remark', None)
  132. pay_type = request_dict.get('payType', '').split(',')
  133. if not all([pay_type, combo_name, flow_total, expiration_days, expiration_type, price]):
  134. return response.json(444)
  135. try:
  136. flow_total = int(flow_total)
  137. expiration_days = int(expiration_days)
  138. expiration_type = int(expiration_type)
  139. with transaction.atomic():
  140. re_data = {
  141. 'combo_name': combo_name,
  142. 'flow_total': flow_total,
  143. 'expiration_days': expiration_days,
  144. 'expiration_type': expiration_type,
  145. 'price': price,
  146. }
  147. if remark:
  148. re_data['remark'] = remark
  149. if combo_id:
  150. UnicomCombo.objects.filter(id=combo_id).update(**re_data)
  151. UnicomCombo.objects.get(id=combo_id).pay_type.set(pay_type)
  152. return response.json(0)
  153. UnicomCombo.objects.create(**re_data).pay_type.set(pay_type)
  154. return response.json(0)
  155. except Exception as e:
  156. print(e)
  157. return response.json(177, repr(e))
  158. @classmethod
  159. def query_package_list(cls, response):
  160. """
  161. 查询套餐列表
  162. @return:
  163. """
  164. try:
  165. combo_qs = UnicomCombo.objects.filter(is_show=1, status=0, is_del=False) \
  166. .order_by('sort').values('id', 'combo_name',
  167. 'flow_total',
  168. 'expiration_days',
  169. 'expiration_type', 'price',
  170. 'remark')
  171. if not combo_qs.exists():
  172. return response.json(0, [])
  173. combo_list = []
  174. for item in combo_qs:
  175. # 获取支付方式列表
  176. pay_type_qs = Pay_Type.objects.filter(unicomcombo=item['id']).values('id', 'payment')
  177. combo_list.append({
  178. 'id': item['id'],
  179. 'comboName': item['combo_name'],
  180. 'flowTotal': item['flow_total'],
  181. 'expirationDays': item['expiration_days'],
  182. 'expirationType': item['expiration_type'],
  183. 'price': item['price'],
  184. 'remark': item['remark'],
  185. 'payTypes': list(pay_type_qs),
  186. })
  187. return response.json(0, combo_list)
  188. except Exception as e:
  189. print(e)
  190. return response.json(177, repr(e))
  191. @classmethod
  192. def buy_unicom_combo(cls, user_id, request_dict, request, response):
  193. """
  194. 购买联通套餐
  195. @return:
  196. """
  197. try:
  198. with transaction.atomic():
  199. iccid = request_dict.get('iccid', None)
  200. combo_id = request_dict.get('id', None)
  201. pay_type = request_dict.get('payType', None)
  202. activate_type = request_dict.get('activateType', 0)
  203. if not all([iccid, combo_id, pay_type]):
  204. return response.json(444)
  205. combo_id = int(combo_id)
  206. pay_type = int(pay_type)
  207. now_time = int(time.time())
  208. unicom_combo_qs = UnicomCombo.objects.filter(id=combo_id, pay_type=pay_type, is_show=1, is_del=False,
  209. status=0) \
  210. .values('id', 'combo_name', 'price', 'remark')
  211. if not unicom_combo_qs.exists():
  212. return response.json(173)
  213. unicom_device_qs = UnicomDeviceInfo.objects.filter(iccid=iccid) \
  214. .values('serial_no')
  215. if not unicom_device_qs.exists():
  216. return response.json(173)
  217. unicom_combo_qs = unicom_combo_qs.first()
  218. price = unicom_combo_qs['price']
  219. if not price:
  220. return response.json(173)
  221. unicom_device_qs = unicom_device_qs.first()
  222. device_uid = CommonService.query_uid_with_serial(unicom_device_qs['serial_no'])
  223. order_id = CommonService.createOrderID()
  224. rank_id, ai_rank_id = cls.get_cloud_or_ai_combo()
  225. order_dict = {'rank_id': rank_id, 'ai_rank_id': ai_rank_id, 'orderID': order_id, 'UID': device_uid,
  226. 'userID_id': user_id, 'desc': unicom_combo_qs['combo_name'], 'payType': pay_type,
  227. 'payTime': now_time, 'price': price, 'currency': 'CNY', 'addTime': now_time,
  228. 'updTime': now_time,
  229. 'unify_combo_id': str(unicom_combo_qs['id']), 'order_type': 2,
  230. }
  231. params = 'lang=cn' + '&activateType=' + activate_type
  232. result = {'result_code': 0, 'reason': 'success', 'error_code': 0}
  233. if pay_type == 2: # 支付宝
  234. pay_price = PayService.get_two_float(price, 2)
  235. notify_url = 'unicom/wap/pay/ali-notify'
  236. order_dict['pay_url'] = PayService.create_alipay_payment(params, order_id, pay_price,
  237. unicom_combo_qs['combo_name'],
  238. notify_url,
  239. unicom_combo_qs['remark'], response)
  240. res_data = {'redirectUrl': order_dict['pay_url'], 'orderID': order_id}
  241. elif pay_type == 3: # 微信支付
  242. notify_url = 'unicom/wap/pay/wechat-notify'
  243. ip = CommonService.get_ip_address(request)
  244. params = 'activateType=' + activate_type
  245. sign_params = PayService.create_wechat_payment(params, order_id,
  246. price, ip,
  247. notify_url,
  248. unicom_combo_qs['remark'],
  249. response)
  250. result['result'] = sign_params
  251. else:
  252. return response.json(444, {'param': 'pay_type'})
  253. Order_Model.objects.create(**order_dict)
  254. if pay_type == 3:
  255. return JsonResponse(status=200, data=result)
  256. return response.json(0, res_data)
  257. except Exception as e:
  258. print(e)
  259. return response.json(500, repr(e))
  260. @staticmethod
  261. def get_cloud_or_ai_combo():
  262. """
  263. 获取云存或者AI套餐id
  264. @return:
  265. """
  266. rank_id = Store_Meal.objects.all().order_by('sort').values().first()['id']
  267. ai_rank_id = AiStoreMeal.objects.all().values().first()['id']
  268. return rank_id, ai_rank_id
  269. @classmethod
  270. def query_device_usage_history(cls):
  271. """
  272. 查询用量历史
  273. @return:
  274. """
  275. @staticmethod
  276. def package_callback_notify(request_dict, request):
  277. """
  278. 异步套餐订购回调
  279. @param request_dict:
  280. @param request:
  281. @return:
  282. """
  283. logger = logging.getLogger('info')
  284. try:
  285. logger.info('联通异步套餐订购回调参数{}'.format(request_dict))
  286. body = request.body.decode("utf-8")
  287. if body:
  288. dict_data = json.loads(body)
  289. sign = dict_data['sign']
  290. logger.info('设备订购异步回调请求参数{}'.format(dict_data))
  291. dict_data.pop('sign')
  292. unicom_obj = UnicomObjeect()
  293. generate_sign = unicom_obj.createSign(**dict_data)
  294. logger.info('设备订购请求签名{}'.format(sign))
  295. logger.info('设备订购生成签名{}'.format(generate_sign))
  296. r_data = {'success': True, 'msg': '成功'}
  297. return HttpResponse(json.dumps(r_data, ensure_ascii=False), content_type="application/json,charset=utf-8")
  298. except Exception as e:
  299. print(repr(e))
  300. r_data = {'success': False, 'msg': '失败'}
  301. return HttpResponse(json.dumps(r_data, ensure_ascii=False), content_type="application/json,charset=utf-8")
  302. @staticmethod
  303. def device_queue_monitoring_push(request_dict, request):
  304. """
  305. 设备套餐队列用完或者到期推送
  306. @param request_dict:
  307. @param request:
  308. @return:
  309. """
  310. logger = logging.getLogger('info')
  311. try:
  312. logger.info('设备套餐队列推送{}'.format(request_dict))
  313. body = request.body.decode("utf-8")
  314. if body:
  315. dict_data = json.loads(body)
  316. sign = dict_data['sign']
  317. logger.info('设备套餐队列回调请求参数{}'.format(dict_data))
  318. dict_data.pop('sign')
  319. unicom_obj = UnicomObjeect()
  320. generate_sign = unicom_obj.createSign(**dict_data)
  321. logger.info('设备套餐队列请求签名{}'.format(sign))
  322. logger.info('设备套餐队列生成签名{}'.format(generate_sign))
  323. r_data = {'success': True, 'msg': '成功'}
  324. return HttpResponse(json.dumps(r_data, ensure_ascii=False), content_type="application/json,charset=utf-8")
  325. except Exception as e:
  326. print(repr(e))
  327. r_data = {'success': False, 'msg': '失败'}
  328. return HttpResponse(json.dumps(r_data, ensure_ascii=False), content_type="application/json,charset=utf-8")
  329. @staticmethod
  330. def device_status_change_push(request_dict, request):
  331. """
  332. 设备状态变更推送执行场景说明
  333. @param request_dict:
  334. @param request:
  335. @return:
  336. """
  337. logger = logging.getLogger('info')
  338. try:
  339. logger.info('设备状态变更推送{}'.format(request_dict))
  340. body = request.body.decode("utf-8")
  341. if body:
  342. dict_data = json.loads(body)
  343. sign = dict_data['sign']
  344. logger.info('设备状态变更推送请求参数{}'.format(dict_data))
  345. dict_data.pop('sign')
  346. unicom_obj = UnicomObjeect()
  347. generate_sign = unicom_obj.createSign(**dict_data)
  348. logger.info('设备状态变更推送请求签名{}'.format(sign))
  349. logger.info('设备状态变更推送生成签名{}'.format(generate_sign))
  350. r_data = {'success': True, 'msg': '成功'}
  351. return HttpResponse(json.dumps(r_data, ensure_ascii=False), content_type="application/json,charset=utf-8")
  352. except Exception as e:
  353. print(repr(e))
  354. r_data = {'success': False, 'msg': '失败'}
  355. return HttpResponse(json.dumps(r_data, ensure_ascii=False), content_type="application/json,charset=utf-8")
  356. @classmethod
  357. def create_combo_order_info(cls, order_id, activate_type, iccid, combo_id):
  358. logger = logging.getLogger('info')
  359. logger.info('创建联通订单套餐信息,订单id{}'.format(order_id))
  360. try:
  361. with transaction.atomic():
  362. unicom_combo_qs = UnicomCombo.objects.filter(id=int(combo_id)).values()
  363. if unicom_combo_qs.exists():
  364. unicom_combo = unicom_combo_qs.first()
  365. now_time = int(time.time())
  366. combo_order_data = {'iccid': iccid, 'status': 0, 'combo_id': int(combo_id),
  367. 'updated_time': now_time,
  368. 'created_time': now_time}
  369. if order_id:
  370. combo_order_data['order_id'] = order_id
  371. # 有效期类型 1 等于自然月,0天数
  372. if unicom_combo['expiration_type'] == 1:
  373. # 激活类型 1=下月激活 否则等于当月激活
  374. if activate_type == 1:
  375. combo_order_data['next_month_activate'] = True
  376. next_start_time, end_time = cls.get_next_month_data_time()
  377. combo_order_data['activation_time'] = next_start_time
  378. combo_order_data['expire_time'] = end_time
  379. else:
  380. start_time, month_end_time = cls.get_month_start_and_end_time()
  381. combo_order_data['activation_time'] = start_time
  382. combo_order_data['expire_time'] = month_end_time
  383. combo_order_data['status'] = 1
  384. elif unicom_combo['expiration_type'] == 0:
  385. days = unicom_combo['expiration_days']
  386. zero_today, end_time = cls.get_data_time(days)
  387. combo_order_data['activation_time'] = zero_today
  388. combo_order_data['expire_time'] = end_time
  389. combo_order_data['status'] = 1
  390. UnicomComboOrderInfo.objects.create(**combo_order_data)
  391. logger.info('保存信息success')
  392. return True
  393. except Exception as e:
  394. print(e)
  395. return False
  396. @staticmethod
  397. def get_next_month_data_time():
  398. """
  399. 获取下个月开始时间与结束时间戳
  400. @return: next_start_time,end_time
  401. """
  402. next_month_start = LocalDateTimeUtil.get_next_month_start()
  403. next_start_time, next_end_time = LocalDateTimeUtil.get_start_and_end_time(next_month_start, '%Y-%m-%d')
  404. next_month_end = LocalDateTimeUtil.get_next_month_end()
  405. start_time, end_time = LocalDateTimeUtil.get_start_and_end_time(next_month_end, '%Y-%m-%d')
  406. return next_start_time, end_time
  407. @staticmethod
  408. def get_data_time(days):
  409. """
  410. 获取今天开始时间以及days后日期结束时间戳
  411. @return: next_start_time,end_time
  412. """
  413. zero_today, last_today = LocalDateTimeUtil.get_today_date(True)
  414. now_time = int(time.time())
  415. after_time = LocalDateTimeUtil.get_after_days_timestamp(now_time, days)
  416. time_array = time.localtime(after_time)
  417. start_time, end_time = LocalDateTimeUtil.get_start_and_end_time(time.strftime("%Y-%m-%d", time_array),
  418. '%Y-%m-%d')
  419. return zero_today, end_time
  420. @staticmethod
  421. def get_month_start_and_end_time():
  422. """
  423. 获取当天开始时间与当月结束时间戳
  424. @return:
  425. """
  426. zero_today, last_today = LocalDateTimeUtil.get_today_date(True)
  427. month_end = LocalDateTimeUtil.get_cur_month_end()
  428. start_time, month_end_time = LocalDateTimeUtil.get_start_and_end_time(month_end, '%Y-%m-%d')
  429. return zero_today, month_end_time