UnicomComboController.py 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845
  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 datetime
  10. import json
  11. import logging
  12. import time
  13. import traceback
  14. from decimal import Decimal
  15. from django.db import transaction
  16. from django.http import HttpResponse, JsonResponse
  17. from django.views.generic.base import View
  18. from Model.models import UnicomDeviceInfo, UnicomCombo, Pay_Type, Order_Model, Store_Meal, AiStoreMeal, \
  19. UnicomComboOrderInfo, UnicomComboExperienceHistory, UnicomDeviceStatusChangePush, SysMsgModel, UnicomFlowPush
  20. from Object.RedisObject import RedisObject
  21. from Object.ResponseObject import ResponseObject
  22. from Object.TokenObject import TokenObject
  23. from Object.UnicomObject import UnicomObjeect
  24. from Object.utils import LocalDateTimeUtil
  25. from Object.utils.PayUtil import PayService
  26. from Service.CommonService import CommonService
  27. class UnicomComboView(View):
  28. def get(self, request, *args, **kwargs):
  29. request.encoding = 'utf-8'
  30. operation = kwargs.get('operation')
  31. return self.validation(request.GET, request, operation)
  32. def post(self, request, *args, **kwargs):
  33. request.encoding = 'utf-8'
  34. operation = kwargs.get('operation')
  35. return self.validation(request.POST, request, operation)
  36. def validation(self, request_dict, request, operation):
  37. response = ResponseObject('cn')
  38. if operation == 'query-usage-history':
  39. return self.query_device_usage_history(request_dict, response)
  40. elif operation == 'test-notify':
  41. order_id = request_dict.get('orderId', None)
  42. activate_type = request_dict.get('activateType', 0)
  43. iccid = request_dict.get('iccid', None)
  44. combo_id = request_dict.get('comboId', None)
  45. self.create_combo_order_info(order_id, int(activate_type), iccid, int(combo_id))
  46. return HttpResponse('SUCCESS')
  47. elif operation == 'device-queue-monitoring':
  48. return self.device_queue_monitoring_push(request_dict, request)
  49. elif operation == 'device-status-change':
  50. return self.device_status_change_push(request_dict, request)
  51. elif operation == 'device-bind':
  52. return self.device_add(request_dict, response)
  53. elif operation == 'device-status':
  54. return self.update_device_status(request_dict, response)
  55. elif operation == 'update-card':
  56. return self.update_device_card_type(request_dict, response)
  57. elif operation == 'xxx-sign':
  58. return self.get_test_sign(request_dict, response)
  59. else:
  60. token = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
  61. lang = request_dict.get('lang', token.lang)
  62. response = ResponseObject(lang)
  63. if token.code != 0:
  64. return response.json(token.code)
  65. user_id = token.userID
  66. if operation == 'combo-save':
  67. return self.save_unicom_combo(request_dict, response)
  68. elif operation == 'combo-pay':
  69. return self.buy_unicom_combo(user_id, request_dict, request, response)
  70. elif operation == 'combo-list':
  71. return self.query_package_list(response)
  72. elif operation == 'get-device-info':
  73. return self.get_device_info(request_dict, response)
  74. elif operation == 'user-combo-query':
  75. return self.user_combo_query(user_id, request_dict, response)
  76. @classmethod
  77. def user_combo_query(cls, user_id, request_dict, response):
  78. """
  79. 查询套餐流量列表与正在使用流量详情
  80. @param user_id:
  81. @param request_dict:
  82. @param response:
  83. @return:
  84. """
  85. try:
  86. iccid = request_dict.get('iccid', None)
  87. if not iccid:
  88. return response.json(444)
  89. unicom_device_info_qs = UnicomDeviceInfo.objects.filter(iccid=iccid)
  90. if not unicom_device_info_qs.exists():
  91. return response.json(173)
  92. now_time = int(time.time())
  93. if not unicom_device_info_qs[0].user_id:
  94. unicom_device_info_qs.update(user_id=user_id, updated_time=now_time)
  95. unicom_api = UnicomObjeect()
  96. combo_order_qs = UnicomComboOrderInfo.objects.filter(iccid=iccid, status=1, is_del=False) \
  97. .values('iccid', 'status', 'combo__status', 'combo__combo_name', 'combo__combo_type',
  98. 'combo__flow_total', 'combo__remark', 'combo__expiration_days', 'combo__expiration_type',
  99. 'year', 'month', 'flow_total_usage', 'expire_time', 'activation_time', 'combo__is_unlimited')
  100. if combo_order_qs.exists():
  101. combo_order = combo_order_qs.first()
  102. flow_details = {
  103. 'flowInvalid': 0,
  104. 'iccid': iccid,
  105. 'status': combo_order['status'],
  106. 'isUnlimited': combo_order['combo__is_unlimited'],
  107. 'comboName': combo_order['combo__combo_name'],
  108. 'comboType': combo_order['combo__combo_type'],
  109. 'flowTotal': combo_order['combo__flow_total'],
  110. 'comboRemark': combo_order['combo__remark'],
  111. 'expirationDays': combo_order['combo__expiration_days'],
  112. 'expirationType': combo_order['combo__expiration_type'],
  113. 'flowTotalUsage': combo_order['flow_total_usage'],
  114. 'activationTime': combo_order['activation_time'],
  115. 'expireTime': combo_order['expire_time'],
  116. 'year': combo_order['year'],
  117. 'month': combo_order['month'],
  118. }
  119. activate_flow = float(flow_details['flowTotalUsage'])
  120. flow_total_usage = unicom_api.get_flow_usage_total(iccid)
  121. flow = 0 if flow_total_usage <= 0 else flow_total_usage - activate_flow
  122. # 因APP问题,usableFlow可用流量替换为,已用流量值
  123. flow_details['usableFlow'] = 0 if flow == 0 else flow
  124. flow_details['usableFlow'] = flow_details['flowTotal'] \
  125. if flow_details['usableFlow'] > flow_details['flowTotal'] \
  126. else flow_details['usableFlow']
  127. flow_details['usableFlow'] = Decimal(flow_details['usableFlow']).quantize(Decimal('0.00'))
  128. flow_details.pop('flowTotalUsage')
  129. cls.update_combo_order_sort(iccid)
  130. flow_details['comboList'] = cls.get_combo_order_list(iccid)
  131. return response.json(0, flow_details)
  132. else:
  133. flow_details = {'iccid': iccid, 'flowInvalid': 1, 'comboList': cls.get_combo_order_list(iccid)}
  134. cls.update_combo_order_sort(iccid)
  135. return response.json(0, flow_details)
  136. except Exception as e:
  137. print(e.args)
  138. ex = traceback.format_exc()
  139. print(ex)
  140. return response.json(177, ex)
  141. @classmethod
  142. def get_combo_order_list(cls, iccid):
  143. """
  144. 查询套餐列表
  145. @param iccid:
  146. @return:
  147. """
  148. combo_list = []
  149. now_time = int(time.time())
  150. before_days = LocalDateTimeUtil.get_before_days_timestamp(now_time, 90)
  151. combo_order_qs = UnicomComboOrderInfo.objects.filter(iccid=iccid, is_del=False, created_time__gt=before_days) \
  152. .values('iccid', 'status', 'combo__combo_name', 'combo__flow_total',
  153. 'combo__remark', 'combo__expiration_days', 'combo__expiration_type', 'flow_total_usage',
  154. 'expire_time', 'combo__is_unlimited').order_by('sort')
  155. for item in combo_order_qs:
  156. combo_list.append({
  157. 'iccid': iccid,
  158. 'status': item['status'],
  159. 'comboName': item['combo__combo_name'],
  160. 'isUnlimited': item['combo__is_unlimited'],
  161. 'flowTotal': item['combo__flow_total'],
  162. 'comboRemark': item['combo__remark'],
  163. 'expirationDays': item['combo__expiration_days'],
  164. 'expirationType': item['combo__expiration_type'],
  165. 'expireTime': item['expire_time'],
  166. })
  167. return combo_list
  168. @classmethod
  169. def update_combo_order_sort(cls, iccd):
  170. """
  171. 修改套餐排序
  172. @param iccd: 联通20位ICCID
  173. @return:
  174. """
  175. combo_order_qs = UnicomComboOrderInfo.objects.filter(iccid=iccd, is_del=False)
  176. if combo_order_qs.exists():
  177. unused_qs = combo_order_qs.filter(status=0)
  178. if unused_qs.exists():
  179. unused_qs.update(sort=50)
  180. used_qs = combo_order_qs.filter(status=1)
  181. if used_qs.exists():
  182. used_qs.update(sort=1)
  183. expire_qs = combo_order_qs.filter(status=2)
  184. if expire_qs.exists():
  185. expire_qs.update(sort=100)
  186. @classmethod
  187. def update_device_status(cls, request_dict, response):
  188. """
  189. 修改绑定设备状态,如产生免费套餐用量则删除
  190. @param request_dict:
  191. @param response:
  192. @return:
  193. """
  194. logger = logging.getLogger('info')
  195. serial_no = request_dict.get('serialNo', None)
  196. time_stamp = request_dict.get('timeStamp', None)
  197. sign = request_dict.get('sign', None)
  198. if not all([serial_no, sign, time_stamp]):
  199. return response.json(444)
  200. logger.info('PC工具进入重置ICCID{}'.format(serial_no))
  201. try:
  202. if not CommonService.check_time_stamp_token(sign, time_stamp):
  203. return response.json(13)
  204. now_time = int(time.time())
  205. redis = RedisObject()
  206. with transaction.atomic():
  207. device_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_no)
  208. if device_info_qs.exists():
  209. iccid = device_info_qs.first().iccid
  210. if device_info_qs.first().card_type == 1:
  211. cls.reset_telecom_user(serial_no)
  212. device_info_qs.update(updated_time=now_time, user_id='')
  213. return response.json(0)
  214. key = 'ASJ:UNICOM:RESET:{}'.format(serial_no)
  215. flow_push_qs = UnicomFlowPush.objects.filter(serial_no=serial_no)
  216. if flow_push_qs.exists():
  217. flow_push_qs.delete()
  218. sys_msg_qs = SysMsgModel.objects.filter(uid=serial_no)
  219. if sys_msg_qs.exists():
  220. sys_msg_qs.delete()
  221. device_info_qs.update(status=1, updated_time=now_time, user_id='')
  222. combo_order_qs = UnicomComboOrderInfo.objects.filter(iccid=iccid)
  223. if combo_order_qs.exists():
  224. combo_order_qs.delete()
  225. combo_experience_history_qs = UnicomComboExperienceHistory.objects.filter(iccid=iccid)
  226. if combo_experience_history_qs.exists():
  227. combo_experience_history_qs.delete()
  228. redis.set_data(key, iccid, 60 * 30)
  229. UnicomObjeect().change_device_to_activate(iccid)
  230. return response.json(0)
  231. except Exception as e:
  232. print(e.args)
  233. ex = traceback.format_exc()
  234. print(ex)
  235. logger.info('PC工具重置异常ICCID{},msg={}'.format(iccid, ex))
  236. return response.json(177, ex)
  237. @staticmethod
  238. def reset_telecom_user(serial_no):
  239. """
  240. 重置电信用户 消息记录
  241. @param serial_no:
  242. @return:
  243. """
  244. sys_msg_qs = SysMsgModel.objects.filter(uid=serial_no)
  245. if sys_msg_qs.exists():
  246. sys_msg_qs.delete()
  247. return True
  248. @classmethod
  249. def update_device_card_type(cls, request_dict, response):
  250. """
  251. 修改设备卡类型(0:内置卡,1:外插卡)
  252. """
  253. serial_no = request_dict.get('serialNo', None)
  254. time_stamp = request_dict.get('timeStamp', None)
  255. sign = request_dict.get('sign', None)
  256. main_card = request_dict.get('type', None)
  257. if not all([serial_no, main_card, sign, time_stamp]):
  258. return response.json(444)
  259. try:
  260. if not CommonService.check_time_stamp_token(sign, time_stamp):
  261. return response.json(13)
  262. now_time = int(time.time())
  263. with transaction.atomic():
  264. unicom_device_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_no)
  265. if not unicom_device_qs.exists():
  266. return response.json(173)
  267. unicom_device_qs.update(main_card=int(main_card), updated_time=now_time)
  268. return response.json(0)
  269. except Exception as e:
  270. print(e.args)
  271. ex = traceback.format_exc()
  272. print(ex)
  273. return response.json(177, ex)
  274. @classmethod
  275. def get_device_info(cls, request_dict, response):
  276. """
  277. 获取设备信息
  278. @param request_dict:
  279. @param response:
  280. @return:
  281. """
  282. iccid = request_dict.get('iccid', None)
  283. if not iccid:
  284. return response.json(444)
  285. unicom_device_info_qs = UnicomDeviceInfo.objects.filter(iccid=iccid).values()
  286. if not unicom_device_info_qs.exists():
  287. return response.json(173)
  288. return response.json(0, dict(unicom_device_info_qs.first()))
  289. @classmethod
  290. def device_add(cls, request_dict, response):
  291. """
  292. 设备绑定iccid
  293. @param request_dict:
  294. @param response:
  295. @return:
  296. """
  297. iccid = request_dict.get('iccid', None)
  298. serial_no = request_dict.get('serialNo', None)
  299. time_stamp = request_dict.get('timeStamp', None)
  300. sign = request_dict.get('sign', None)
  301. sim = int(request_dict.get('sim', 1))
  302. logger = logging.getLogger('info')
  303. logger.info('--->设备调用4G注册接口')
  304. if not all([iccid, serial_no, sign, time_stamp]):
  305. return response.json(444)
  306. # 时间戳token校验
  307. if not CommonService.check_time_stamp_token(sign, time_stamp):
  308. return response.json(13)
  309. n_time = int(time.time())
  310. try:
  311. logger.info('--->参数验证通过,sign验证通过')
  312. redis = RedisObject()
  313. with transaction.atomic():
  314. # 待完善代码 根据uid与用户id验证系统设备
  315. unicom_device_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_no)
  316. if unicom_device_qs.exists():
  317. if unicom_device_qs.first().status == 1:
  318. key = 'ASJ:UNICOM:RESET:{}'.format(serial_no)
  319. reset_cache = redis.get_data(key)
  320. if reset_cache:
  321. logger.info('--->三十分后再次访问接口生效赠送流量套餐')
  322. return response.json(0, 'Thirty minutes later to visit again take effect')
  323. cls.user_activate_flow(iccid)
  324. unicom_device_qs.update(main_card=sim, updated_time=n_time)
  325. return response.json(0)
  326. if sim == 0:
  327. return response.json(0, '外置卡不保存相关信息{}'.format(serial_no))
  328. unicom_obj = UnicomObjeect()
  329. params = {'iccid': iccid, 'serial_no': serial_no, 'updated_time': n_time,
  330. 'created_time': n_time, 'main_card': sim}
  331. if cls.check_iccid(iccid):
  332. params['card_type'] = 1
  333. params['status'] = 2
  334. UnicomDeviceInfo.objects.create(**params)
  335. return response.json(0)
  336. result = unicom_obj.verify_device(iccid=iccid)
  337. if result.status_code == 200 and result.text:
  338. res_dict = json.loads(result.text)
  339. if res_dict['success']:
  340. if res_dict['data']['status'] == 0:
  341. logger.info('--->设备请求绑定{}验证不存在{}'.format(iccid, res_dict))
  342. return response.json(173)
  343. unicom_obj.change_device_to_activate(iccid)
  344. UnicomDeviceInfo.objects.create(**params)
  345. return response.json(0)
  346. else:
  347. logger.info('--->设备请求绑定{}验证失败'.format(iccid))
  348. return response.json(173)
  349. except Exception as e:
  350. print(e)
  351. ex = traceback.format_exc()
  352. logger.info('--->设备调用4G注册接口异常:{}'.format(ex))
  353. return response.json(177, repr(e))
  354. @classmethod
  355. def check_iccid(cls, iccid):
  356. """
  357. 检查ICCID是否是五兴科技卡
  358. @return: True or False
  359. """
  360. if not iccid:
  361. return False
  362. iccid = iccid[0:6]
  363. arr_list = ['898603', '898611']
  364. if iccid in arr_list:
  365. return True
  366. return False
  367. @classmethod
  368. def user_activate_flow(cls, iccid):
  369. """
  370. 用户激活初始化流量套餐
  371. @param iccid:
  372. @return:
  373. """
  374. logger = logging.getLogger('info')
  375. try:
  376. while transaction.atomic():
  377. now_time = int(time.time())
  378. unicom_device_info_qs = UnicomDeviceInfo.objects.filter(iccid=iccid)
  379. if not unicom_device_info_qs.exists():
  380. return False
  381. unicom_device_info_qs = unicom_device_info_qs.first()
  382. if unicom_device_info_qs.status != 1:
  383. logger.info('---->用户激活iccid={},业务系统状态为{}'.format(iccid, unicom_device_info_qs.status))
  384. return False
  385. # 联通业务逻辑
  386. unicom_api = UnicomObjeect()
  387. unicom_api.change_device_to_activate(iccid)
  388. # 查看是否体验过免费套餐
  389. experience_history_qs = UnicomComboExperienceHistory.objects.filter(iccid=iccid)
  390. if not experience_history_qs.exists():
  391. logger.info('---->用户首次激活iccid={}'.format(iccid))
  392. combo_qs = UnicomCombo.objects.filter(combo_type=1, status=0, is_del=False) \
  393. .values('id', 'expiration_type', 'expiration_days', 'combo_type')
  394. if combo_qs.exists():
  395. combo_qs = combo_qs.first()
  396. # 保存体验记录
  397. experience_history_vo = {'iccid': iccid, 'experience_type': 0, 'do_time': now_time}
  398. UnicomComboExperienceHistory.objects.create(**experience_history_vo)
  399. # 保存套餐激活信息
  400. cls.create_combo_order_info('', 0, iccid, combo_qs['id'])
  401. # 修改业务联通卡设备激活信息
  402. UnicomDeviceInfo.objects.filter(iccid=iccid).update(status=2, updated_time=now_time,
  403. created_time=now_time)
  404. return True
  405. except Exception as e:
  406. print(e)
  407. ex = traceback.format_exc()
  408. logger.info('--->用户首次激活异常:{}'.format(ex))
  409. return False
  410. @classmethod
  411. def save_unicom_combo(cls, request_dict, response):
  412. """
  413. 联通套餐保存
  414. @param request_dict:
  415. @param response:
  416. @return:
  417. """
  418. combo_id = request_dict.get('id', None)
  419. combo_name = request_dict.get('comboName', None)
  420. flow_total = request_dict.get('flowTotal', None)
  421. expiration_days = request_dict.get('expirationDays', None)
  422. expiration_type = request_dict.get('expirationType', None)
  423. price = request_dict.get('price', None)
  424. remark = request_dict.get('remark', None)
  425. pay_type = request_dict.get('payType', '').split(',')
  426. if not all([pay_type, combo_name, flow_total, expiration_days, expiration_type, price]):
  427. return response.json(444)
  428. try:
  429. flow_total = int(flow_total)
  430. expiration_days = int(expiration_days)
  431. expiration_type = int(expiration_type)
  432. with transaction.atomic():
  433. re_data = {
  434. 'combo_name': combo_name,
  435. 'flow_total': flow_total,
  436. 'expiration_days': expiration_days,
  437. 'expiration_type': expiration_type,
  438. 'price': price,
  439. }
  440. if remark:
  441. re_data['remark'] = remark
  442. if combo_id:
  443. UnicomCombo.objects.filter(id=combo_id).update(**re_data)
  444. UnicomCombo.objects.get(id=combo_id).pay_type.set(pay_type)
  445. return response.json(0)
  446. UnicomCombo.objects.create(**re_data).pay_type.set(pay_type)
  447. return response.json(0)
  448. except Exception as e:
  449. print(e)
  450. return response.json(177, repr(e))
  451. @classmethod
  452. def query_package_list(cls, response):
  453. """
  454. 查询套餐列表
  455. @return:
  456. """
  457. try:
  458. combo_qs = UnicomCombo.objects.filter(is_show=1, status=0, is_del=False) \
  459. .order_by('sort').values('id', 'combo_name',
  460. 'flow_total',
  461. 'expiration_days',
  462. 'expiration_type', 'price',
  463. 'remark', 'virtual_price')
  464. if not combo_qs.exists():
  465. return response.json(0, [])
  466. combo_list = []
  467. for item in combo_qs:
  468. # 获取支付方式列表
  469. pay_type_qs = Pay_Type.objects.filter(unicomcombo=item['id']).values('id', 'payment')
  470. combo_list.append({
  471. 'id': item['id'],
  472. 'comboName': item['combo_name'],
  473. 'flowTotal': item['flow_total'],
  474. 'expirationDays': item['expiration_days'],
  475. 'expirationType': item['expiration_type'],
  476. 'price': item['price'],
  477. 'virtualPrice': item['virtual_price'] if item['virtual_price'] else '',
  478. 'remark': item['remark'],
  479. 'payTypes': list(pay_type_qs),
  480. })
  481. return response.json(0, combo_list)
  482. except Exception as e:
  483. print(e)
  484. return response.json(177, repr(e))
  485. @classmethod
  486. def buy_unicom_combo(cls, user_id, request_dict, request, response):
  487. """
  488. 购买联通套餐
  489. @return:
  490. """
  491. logger = logging.getLogger('info')
  492. try:
  493. with transaction.atomic():
  494. iccid = request_dict.get('iccid', None)
  495. combo_id = request_dict.get('id', None)
  496. pay_type = request_dict.get('payType', None)
  497. activate_type = request_dict.get('activateType', 0)
  498. if not all([iccid, combo_id, pay_type]):
  499. return response.json(444)
  500. combo_id = int(combo_id)
  501. pay_type = int(pay_type)
  502. now_time = int(time.time())
  503. unicom_combo_qs = UnicomCombo.objects.filter(id=combo_id, pay_type=pay_type, is_show=1, is_del=False,
  504. status=0) \
  505. .values('id', 'combo_name', 'price', 'remark')
  506. if not unicom_combo_qs.exists():
  507. return response.json(173)
  508. unicom_device_qs = UnicomDeviceInfo.objects.filter(iccid=iccid) \
  509. .values('serial_no')
  510. if not unicom_device_qs.exists():
  511. return response.json(173)
  512. unicom_combo_qs = unicom_combo_qs.first()
  513. price = unicom_combo_qs['price']
  514. if not price:
  515. return response.json(173)
  516. unicom_device_qs = unicom_device_qs.first()
  517. device_uid = CommonService.query_uid_with_serial(unicom_device_qs['serial_no'])
  518. order_id = CommonService.createOrderID()
  519. rank_id, ai_rank_id = cls.get_cloud_or_ai_combo()
  520. order_dict = {'rank_id': rank_id, 'ai_rank_id': ai_rank_id, 'orderID': order_id, 'UID': device_uid,
  521. 'userID_id': user_id, 'desc': unicom_combo_qs['combo_name'], 'payType': pay_type,
  522. 'payTime': now_time, 'price': price, 'currency': 'CNY', 'addTime': now_time,
  523. 'updTime': now_time,
  524. 'unify_combo_id': str(unicom_combo_qs['id']), 'order_type': 2,
  525. 'store_meal_name': unicom_combo_qs['combo_name']
  526. }
  527. params = 'lang=cn' + '&activateType=' + activate_type
  528. logger.info('激活类型:{}'.format(activate_type))
  529. result = {'result_code': 0, 'reason': 'success', 'error_code': 0}
  530. if pay_type == 2: # 支付宝
  531. pay_price = PayService.get_two_float(price, 2)
  532. notify_url = 'unicom/wap/pay/ali-notify'
  533. order_dict['pay_url'] = PayService.create_alipay_payment(params, order_id, pay_price,
  534. unicom_combo_qs['combo_name'],
  535. notify_url,
  536. unicom_combo_qs['remark'], response)
  537. res_data = {'redirectUrl': order_dict['pay_url'], 'orderID': order_id}
  538. elif pay_type == 3: # 微信支付
  539. notify_url = 'unicom/wap/pay/wechat-notify'
  540. ip = CommonService.get_ip_address(request)
  541. params = 'activateType=' + activate_type
  542. sign_params = PayService.create_wechat_payment(params, order_id,
  543. price, ip,
  544. notify_url,
  545. unicom_combo_qs['remark'],
  546. response)
  547. result['result'] = sign_params
  548. else:
  549. return response.json(444, {'param': 'pay_type'})
  550. Order_Model.objects.create(**order_dict)
  551. if pay_type == 3:
  552. return JsonResponse(status=200, data=result)
  553. return response.json(0, res_data)
  554. except Exception as e:
  555. print(e)
  556. return response.json(500, repr(e))
  557. @staticmethod
  558. def get_cloud_or_ai_combo():
  559. """
  560. 获取云存或者AI套餐id
  561. @return:
  562. """
  563. rank_id = Store_Meal.objects.all().order_by('sort').values().first()['id']
  564. ai_rank_id = AiStoreMeal.objects.all().values().first()['id']
  565. return rank_id, ai_rank_id
  566. @classmethod
  567. def query_device_usage_history(cls, request_dict, response):
  568. """
  569. 查询实时已用总流量API
  570. @return:
  571. """
  572. iccid = request_dict.get('iccid', None)
  573. if not iccid:
  574. return response.json(444)
  575. unicom_api = UnicomObjeect()
  576. flow = unicom_api.get_flow_usage_total(iccid)
  577. return response.json(0, flow)
  578. @staticmethod
  579. def package_callback_notify(request_dict, request):
  580. """
  581. 异步套餐订购回调
  582. @param request_dict:
  583. @param request:
  584. @return:
  585. """
  586. logger = logging.getLogger('info')
  587. try:
  588. logger.info('联通异步套餐订购回调参数{}'.format(request_dict))
  589. body = request.body.decode("utf-8")
  590. if body:
  591. dict_data = json.loads(body)
  592. sign = dict_data['sign']
  593. logger.info('设备订购异步回调请求参数{}'.format(dict_data))
  594. dict_data.pop('sign')
  595. unicom_obj = UnicomObjeect()
  596. generate_sign = unicom_obj.createSign(**dict_data)
  597. logger.info('设备订购请求签名{}'.format(sign))
  598. logger.info('设备订购生成签名{}'.format(generate_sign))
  599. r_data = {'success': True, 'msg': '成功'}
  600. return HttpResponse(json.dumps(r_data, ensure_ascii=False), content_type="application/json,charset=utf-8")
  601. except Exception as e:
  602. print(repr(e))
  603. r_data = {'success': False, 'msg': '失败'}
  604. return HttpResponse(json.dumps(r_data, ensure_ascii=False), content_type="application/json,charset=utf-8")
  605. @staticmethod
  606. def device_queue_monitoring_push(request_dict, request):
  607. """
  608. 设备套餐队列用完或者到期推送
  609. @param request_dict:
  610. @param request:
  611. @return:
  612. """
  613. logger = logging.getLogger('info')
  614. try:
  615. logger.info('设备套餐队列推送{}'.format(request_dict))
  616. body = request.body.decode("utf-8")
  617. if body:
  618. dict_data = json.loads(body)
  619. sign = dict_data['sign']
  620. logger.info('设备套餐队列回调请求参数{}'.format(dict_data))
  621. dict_data.pop('sign')
  622. unicom_obj = UnicomObjeect()
  623. generate_sign = unicom_obj.createSign(**dict_data)
  624. logger.info('设备套餐队列请求签名{}'.format(sign))
  625. logger.info('设备套餐队列生成签名{}'.format(generate_sign))
  626. r_data = {'success': True, 'msg': '成功'}
  627. return HttpResponse(json.dumps(r_data, ensure_ascii=False), content_type="application/json,charset=utf-8")
  628. except Exception as e:
  629. print(repr(e))
  630. r_data = {'success': False, 'msg': '失败'}
  631. return HttpResponse(json.dumps(r_data, ensure_ascii=False), content_type="application/json,charset=utf-8")
  632. @staticmethod
  633. def device_status_change_push(request_dict, request):
  634. """
  635. 设备状态变更推送执行场景说明
  636. @param request_dict:
  637. @param request:
  638. @return:
  639. """
  640. logger = logging.getLogger('info')
  641. try:
  642. logger.info('设备状态变更推送{}'.format(request_dict))
  643. body = request.body.decode("utf-8")
  644. if body:
  645. dict_data = json.loads(body)
  646. sign = dict_data['sign']
  647. logger.info('设备状态变更推送请求参数{}'.format(dict_data))
  648. dict_data.pop('sign')
  649. unicom_obj = UnicomObjeect()
  650. generate_sign = unicom_obj.createSign(**dict_data)
  651. logger.info('联通设备状态变更推送请求签名{}'.format(sign))
  652. logger.info('联通设备状态变更推送生成签名{}'.format(generate_sign))
  653. # assert generate_sign == sign
  654. now_time = int(time.time())
  655. re_data = {
  656. 'iccid': dict_data['iccid'],
  657. 'sign': sign,
  658. 'type': dict_data['status'],
  659. 'time': dict_data['time'],
  660. 'serial_no': dict_data['operationId'],
  661. 'updated_time': now_time,
  662. 'created_time': now_time
  663. }
  664. UnicomDeviceStatusChangePush.objects.create(**re_data)
  665. r_data = {'success': True, 'msg': '成功'}
  666. return HttpResponse(json.dumps(r_data, ensure_ascii=False), content_type="application/json,charset=utf-8")
  667. except Exception as e:
  668. logger.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  669. r_data = {'success': False, 'msg': '失败'}
  670. return HttpResponse(json.dumps(r_data, ensure_ascii=False), content_type="application/json,charset=utf-8")
  671. @classmethod
  672. def create_combo_order_info(cls, order_id, activate_type, iccid, combo_id):
  673. """
  674. 创建套餐生效记录
  675. @param order_id: 订单id
  676. @param activate_type: 激活类型
  677. @param iccid: 联通20位iccid
  678. @param combo_id: 套餐id
  679. @return: True Or False
  680. """
  681. logger = logging.getLogger('info')
  682. logger.info('创建联通订单套餐信息,订单id{}'.format(order_id))
  683. try:
  684. today = datetime.datetime.today()
  685. year = today.year
  686. month = today.month
  687. with transaction.atomic():
  688. unicom_combo_qs = UnicomCombo.objects.filter(id=int(combo_id)).values()
  689. if unicom_combo_qs.exists():
  690. unicom_combo = unicom_combo_qs.first()
  691. now_time = int(time.time())
  692. combo_order_qs = UnicomComboOrderInfo.objects.filter(status=1, iccid=iccid)
  693. status = 0
  694. if not combo_order_qs.exists():
  695. status = 1
  696. combo_order_data = {'iccid': iccid, 'status': status, 'combo_id': int(combo_id),
  697. 'updated_time': now_time,
  698. 'created_time': now_time,
  699. 'year': year, 'month': month}
  700. if order_id:
  701. combo_order_data['order_id'] = order_id
  702. # 有效期类型 1 等于自然月,0天数
  703. if unicom_combo['expiration_type'] == 1:
  704. # 激活类型 1=下月激活 否则等于当月激活
  705. if activate_type == 1:
  706. combo_order_data['next_month_activate'] = True
  707. next_start_time, end_time = cls.get_next_month_data_time()
  708. combo_order_data['activation_time'] = next_start_time
  709. combo_order_data['expire_time'] = end_time
  710. combo_order_data['status'] = 0
  711. else:
  712. start_time, month_end_time = cls.get_month_start_and_end_time()
  713. combo_order_data['activation_time'] = now_time
  714. combo_order_data['expire_time'] = month_end_time
  715. elif unicom_combo['expiration_type'] == 0:
  716. days = unicom_combo['expiration_days']
  717. if activate_type == 1:
  718. combo_order_data['next_month_activate'] = True
  719. start_time, end_time = cls.get_times(days)
  720. combo_order_data['activation_time'] = start_time
  721. combo_order_data['expire_time'] = end_time
  722. combo_order_data['status'] = 0
  723. else:
  724. zero_today, end_time = cls.get_data_time(days)
  725. combo_order_data['activation_time'] = now_time
  726. combo_order_data['expire_time'] = end_time
  727. logger.info('激活类型{}'.format(activate_type))
  728. # 调用联通API查询物联卡是否已激活,未激活则修改为激活状态
  729. unicom_api = UnicomObjeect()
  730. if status == 1:
  731. unicom_api.change_device_to_activate(iccid)
  732. flow_total_usage = unicom_api.get_flow_usage_total(iccid)
  733. if flow_total_usage > 0:
  734. flow_total_usage = Decimal(flow_total_usage)
  735. flow_total_usage = flow_total_usage.quantize(Decimal('0.00'))
  736. else:
  737. flow_total_usage = 0
  738. combo_order_data['flow_total_usage'] = str(flow_total_usage)
  739. UnicomComboOrderInfo.objects.create(**combo_order_data)
  740. logger.info('保存套餐支付信息success')
  741. return True
  742. except Exception as e:
  743. print(e)
  744. return False
  745. @staticmethod
  746. def get_next_month_data_time():
  747. """
  748. 获取下个月开始时间与结束时间戳
  749. @return: next_start_time,end_time
  750. """
  751. next_month_start = LocalDateTimeUtil.get_next_month_start()
  752. next_start_time, next_end_time = LocalDateTimeUtil.get_start_and_end_time(next_month_start, '%Y-%m-%d')
  753. next_month_end = LocalDateTimeUtil.get_next_month_end()
  754. start_time, end_time = LocalDateTimeUtil.get_start_and_end_time(next_month_end, '%Y-%m-%d')
  755. return next_start_time, end_time
  756. @staticmethod
  757. def get_data_time(days):
  758. """
  759. 获取今天开始时间以及days后日期结束时间戳
  760. @return: next_start_time,end_time
  761. """
  762. zero_today, last_today = LocalDateTimeUtil.get_today_date(True)
  763. now_time = int(time.time())
  764. after_time = LocalDateTimeUtil.get_after_days_timestamp(now_time, days)
  765. time_array = time.localtime(after_time)
  766. start_time, end_time = LocalDateTimeUtil.get_start_and_end_time(time.strftime("%Y-%m-%d", time_array),
  767. '%Y-%m-%d')
  768. return zero_today, end_time
  769. @staticmethod
  770. def get_times(days_after):
  771. """
  772. 获取下月开始时间与指定天数后结束时间
  773. @return:
  774. """
  775. next_start_time, end_time = UnicomComboView.get_next_month_data_time()
  776. after_time = LocalDateTimeUtil.get_after_days_timestamp(next_start_time, days_after)
  777. time_array = time.localtime(after_time)
  778. start_time, end_time = LocalDateTimeUtil.get_start_and_end_time(time.strftime("%Y-%m-%d", time_array),
  779. '%Y-%m-%d')
  780. return next_start_time, end_time
  781. @staticmethod
  782. def get_month_start_and_end_time():
  783. """
  784. 获取当天开始时间与当月结束时间戳
  785. @return:
  786. """
  787. zero_today, last_today = LocalDateTimeUtil.get_today_date(True)
  788. month_end = LocalDateTimeUtil.get_cur_month_end()
  789. start_time, month_end_time = LocalDateTimeUtil.get_start_and_end_time(month_end, '%Y-%m-%d')
  790. return zero_today, month_end_time
  791. @classmethod
  792. def get_test_sign(cls, request_dict, response):
  793. """
  794. 测试盐加密解密
  795. @param request_dict:
  796. @param response:
  797. @return:
  798. """
  799. verify = request_dict.get('verify', False)
  800. if verify:
  801. sign = request_dict.get('sign')
  802. time_stamp = request_dict.get('timeStamp')
  803. sign = CommonService.check_time_stamp_token(sign, time_stamp)
  804. if not sign:
  805. return response.json(13)
  806. return response.json(0)
  807. now_time = int(time.time())
  808. sign = CommonService.encode_data(str(now_time))
  809. return response.json(0, {'sign': sign, 'timeStamp': now_time})