UnicomComboTaskController.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. # -*- encoding: utf-8 -*-
  2. """
  3. @File : UnicomComboTaskController.py
  4. @Time : 2022/6/30 16:23
  5. @Author : stephen
  6. @Email : zhangdongming@asj6.wecom.work
  7. @Software: PyCharm
  8. """
  9. import datetime
  10. import logging
  11. import time
  12. from django.db import transaction
  13. from django.db.models import Q
  14. from django.views import View
  15. from decimal import Decimal
  16. from Model.models import UnicomComboOrderInfo, UnicomCombo, Order_Model, UnicomDeviceInfo, UnicomFlowPush
  17. from Object.ResponseObject import ResponseObject
  18. from Object.UnicomObject import UnicomObjeect
  19. class UnicomComboTaskView(View):
  20. def get(self, request, *args, **kwargs):
  21. request.encoding = 'utf-8'
  22. operation = kwargs.get('operation')
  23. return self.validation(request.GET, request, operation)
  24. def post(self, request, *args, **kwargs):
  25. request.encoding = 'utf-8'
  26. operation = kwargs.get('operation')
  27. return self.validation(request.POST, request, operation)
  28. def validation(self, request_dict, request, operation):
  29. response = ResponseObject()
  30. print(request)
  31. if operation == 'check-activate':
  32. return self.check_activate_combo(request_dict, response)
  33. elif operation == 'check-flow':
  34. return self.check_flow_usage(response)
  35. elif operation == 'check-flow-expire':
  36. return self.check_flow_expire(response)
  37. elif operation == 'check-expire':
  38. today = datetime.datetime.today()
  39. year = today.year
  40. month = today.month
  41. self.query_unused_combo_and_activate(request_dict.get('iccid'), year, month, '666')
  42. return response.json(0)
  43. @classmethod
  44. def check_activate_combo(cls, request_dict, response):
  45. """
  46. 定时检查是否有次月激活套餐
  47. @param request_dict:
  48. @param response:
  49. @return:
  50. """
  51. logger = logging.getLogger('info')
  52. print(request_dict)
  53. logger.info('--->进入监控次月激活联通套餐')
  54. now_time = int(time.time())
  55. combo_order_info_qs = UnicomComboOrderInfo.objects.filter(status=0, next_month_activate=True,
  56. activation_time__lte=now_time,
  57. expire_time__gte=now_time, is_del=0).values()
  58. if not combo_order_info_qs.exists():
  59. return response.json(0)
  60. try:
  61. today = datetime.datetime.today()
  62. year = today.year
  63. month = today.month
  64. with transaction.atomic():
  65. unicom_api = UnicomObjeect()
  66. for item in combo_order_info_qs:
  67. if item['order_id']:
  68. order_id = item['order_id']
  69. order_qs = Order_Model.objects.filter(orderID=order_id, status=1)
  70. if not order_qs.exists():
  71. continue
  72. combo_order_qs = UnicomComboOrderInfo.objects.filter(status=1, iccid=item['iccid'])
  73. # 当前已有套餐正在使用则跳出当前循环
  74. if combo_order_qs.exists():
  75. continue
  76. combo_id = item['combo_id']
  77. combo_qs = UnicomCombo.objects.filter(id=combo_id).values()
  78. if not combo_qs.exists():
  79. continue
  80. # 查询当月用量情况
  81. flow_total_usage = unicom_api.get_flow_usage_total(year, month, item['iccid'])
  82. flow_total_usage = str(flow_total_usage)
  83. iccid = item['iccid']
  84. # 检查激活iccid
  85. unicom_api.change_device_to_activate(iccid)
  86. cls.query_unused_combo_and_activate(iccid, year, month, flow_total_usage)
  87. logger.info('激活成功,订单编号:{}'.format(order_id))
  88. return response.json(0)
  89. except Exception as e:
  90. logger.info('出错了~次月激活套餐异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  91. return response.json(177, repr(e))
  92. @classmethod
  93. def check_flow_usage(cls, response):
  94. """
  95. 检查流量使用情况
  96. @return:
  97. """
  98. logger = logging.getLogger('info')
  99. logger.info('--->进入监控流量使用情况')
  100. try:
  101. unicom_api = UnicomObjeect()
  102. combo_order_qs = UnicomComboOrderInfo.objects.filter(status=1, is_del=False).values()
  103. if not combo_order_qs.exists():
  104. return response.json(0)
  105. today = datetime.datetime.today()
  106. year = today.year
  107. month = today.month
  108. now_time = int(time.time())
  109. for item in combo_order_qs:
  110. iccid = item['iccid']
  111. u_device_info_qs = UnicomDeviceInfo.objects.filter(iccid=iccid)
  112. if not u_device_info_qs.exists():
  113. continue
  114. u_device_info_qs = u_device_info_qs.first()
  115. usage_flow = float(item['flow_total_usage']) if item['flow_total_usage'] else 0.0
  116. combo_id = item['combo_id']
  117. combo_qs = UnicomCombo.objects.filter(id=combo_id).values()
  118. if not combo_qs.exists():
  119. continue
  120. combo_qs = combo_qs.first()
  121. flow_total = combo_qs['flow_total']
  122. # 查询当前月用量历史
  123. month_usage_flow = unicom_api.get_flow_usage_total(year, month, iccid)
  124. logger.info('--->{}-{},iccid:{};套餐总值:{},激活时当月用量值:{},月已用量:{}'
  125. .format(year, month, iccid, flow_total, usage_flow, month_usage_flow))
  126. is_expire = False
  127. if item['year'] == year and item['month'] == month:
  128. if month_usage_flow > 0:
  129. # 初始套餐已使用流量 + 套餐总流量
  130. flow = usage_flow + flow_total
  131. if month_usage_flow >= flow:
  132. is_expire = True
  133. usage = (month_usage_flow - usage_flow) if month_usage_flow > usage_flow else 0
  134. cls.flow_warning_push(u_device_info_qs.user_id, u_device_info_qs.serial_no, item['id'], flow_total,
  135. usage)
  136. else:
  137. activate_year = item['year']
  138. activate_month = item['month']
  139. # 上月使用流量
  140. last_usage_flow = unicom_api.get_flow_usage_total(activate_year, activate_month, iccid)
  141. # 上月套餐实际使用量
  142. actual_usage_flow = last_usage_flow - usage_flow
  143. # 剩余
  144. surplus_flow = flow_total - actual_usage_flow
  145. if month_usage_flow > 0:
  146. if month_usage_flow >= surplus_flow:
  147. is_expire = True
  148. usage = (month_usage_flow + last_usage_flow - usage_flow) \
  149. if (month_usage_flow + last_usage_flow) > usage_flow else 0
  150. cls.flow_warning_push(u_device_info_qs.user_id, u_device_info_qs.serial_no, item['id'], flow_total,
  151. usage)
  152. # 检查是否有当月未使用套餐 没有则停卡
  153. if is_expire:
  154. UnicomComboOrderInfo.objects.filter(id=item['id']).update(status=2, updated_time=now_time)
  155. activate_status = cls.query_unused_combo_and_activate(iccid, year, month,
  156. month_usage_flow)
  157. if not activate_status:
  158. # 停用
  159. unicom_api.change_device_to_disable(iccid)
  160. return response.json(0)
  161. except Exception as e:
  162. logger.info('出错了~检测流量用量详情异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  163. return response.json(177, repr(e))
  164. @staticmethod
  165. def flow_warning_push(app_user_id, serial_no, combo_order_id, flow_total, flow_usage):
  166. """
  167. 监控流量使用大于85%and小于96%进行消息推送提醒
  168. @param app_user_id: app用户id
  169. @param serial_no: 序列号
  170. @param combo_order_id: 当前套餐订单id
  171. @param flow_total: 流量总量
  172. @param flow_usage: 已使用流量
  173. @return:
  174. """
  175. logger = logging.getLogger('info')
  176. try:
  177. if not app_user_id:
  178. return False
  179. if 0 < flow_total and 0 < flow_usage < flow_total:
  180. res = flow_usage / flow_total * 100
  181. if 85 < res <= 95:
  182. flow_push = UnicomFlowPush.objects.filter(serial_no=serial_no, combo_order_id=combo_order_id)
  183. if not flow_push.exists():
  184. now_time = int(time.time())
  185. flow_usage = Decimal(flow_usage)
  186. flow_usage = flow_usage.quantize(Decimal('0.00'))
  187. flow_total = Decimal(flow_total)
  188. flow_total = flow_total.quantize(Decimal('0.00'))
  189. push_data = {'combo_order_id': str(combo_order_id), 'serial_no': serial_no,
  190. 'flow_total_usage': flow_usage, 'flow_total': flow_total, 'status': 0,
  191. 'updated_time': now_time,
  192. 'created_time': now_time, 'user_id': app_user_id}
  193. UnicomFlowPush.objects.create(**push_data)
  194. return True
  195. except Exception as e:
  196. logger.info('出错了~异常流量监控,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  197. @staticmethod
  198. def query_unused_combo_and_activate(iccid, year, month, usage_flow):
  199. """
  200. 查询未使用套餐并激活
  201. @param iccid:
  202. @param year:
  203. @param month:
  204. @param usage_flow:
  205. @return:
  206. """
  207. logger = logging.getLogger('info')
  208. try:
  209. now_time = int(time.time())
  210. combo_order_qs = UnicomComboOrderInfo.objects \
  211. .filter(expire_time__gt=now_time, activation_time__lte=now_time, status=0, iccid=iccid) \
  212. .order_by('created_time')
  213. if not combo_order_qs.exists():
  214. return False
  215. combo_order = combo_order_qs.first()
  216. if not combo_order.order_id:
  217. return False
  218. order_qs = Order_Model.objects.filter(orderID=combo_order.order_id, status=1)
  219. if not order_qs.exists():
  220. return False
  221. upd_data = {
  222. 'status': 1,
  223. 'year': year,
  224. 'month': month,
  225. 'flow_total_usage': str(usage_flow),
  226. 'updated_time': now_time,
  227. }
  228. UnicomComboOrderInfo.objects.filter(id=combo_order.id).update(**upd_data)
  229. return True
  230. except Exception as e:
  231. logger.info('出错了~检测流量用量详情异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  232. return False
  233. @classmethod
  234. def check_flow_expire(cls, response):
  235. """
  236. 检查流量到期停卡操作
  237. @param response:
  238. @return:
  239. """
  240. logger = logging.getLogger('info')
  241. logger.info('--->进入监控流量到期停卡或激活叠加包')
  242. now_time = int(time.time())
  243. combo_order_qs = UnicomComboOrderInfo.objects.filter(~Q(status=2), expire_time__lte=now_time,
  244. is_del=False).values()
  245. today = datetime.datetime.today()
  246. year = today.year
  247. month = today.month
  248. if not combo_order_qs.exists():
  249. return response.json(0)
  250. iccid_list = []
  251. with transaction.atomic():
  252. for item in combo_order_qs:
  253. try:
  254. icc_id = item['iccid']
  255. um_device_qs = UnicomDeviceInfo.objects.filter(iccid=icc_id)
  256. if not um_device_qs.exists():
  257. continue
  258. UnicomComboOrderInfo.objects.filter(id=item['id']).update(status=2)
  259. iccid_list.append(icc_id)
  260. logger.info('--->当前流量套餐已过期,iccid:{}'.format(icc_id))
  261. except Exception as e:
  262. logger.info('出错了~监控流量到期异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  263. continue
  264. # set无序不重复元素集
  265. iccid_list = list(set(iccid_list))
  266. unicom_api = UnicomObjeect()
  267. for item in iccid_list:
  268. activate_combo_qs = UnicomComboOrderInfo.objects.filter(iccid=item, status=1, expire_time__gt=now_time,
  269. is_del=False).values()
  270. if activate_combo_qs.exists():
  271. continue
  272. usage_flow = unicom_api.get_flow_usage_total(year, month, item)
  273. result = cls.query_unused_combo_and_activate(item, year, month, usage_flow)
  274. if not result:
  275. # 停用设备
  276. unicom_api.change_device_to_disable(item)
  277. else:
  278. unicom_api.change_device_to_activate(item)
  279. return response.json(0)