# -*- encoding: utf-8 -*- """ @File : UnicomComboController.py @Time : 2022/6/23 9:18 @Author : stephen @Email : zhangdongming@asj6.wecom.work @Software: PyCharm """ import json import logging import time from django.db import transaction from django.http import HttpResponse, JsonResponse from django.views.generic.base import View from Model.models import UnicomDeviceInfo, UnicomCombo, Pay_Type, Order_Model, Store_Meal, AiStoreMeal, \ UnicomComboOrderInfo from Object.ResponseObject import ResponseObject from Object.TokenObject import TokenObject from Object.UnicomObject import UnicomObjeect from Object.utils import LocalDateTimeUtil from Object.utils.PayUtil import PayService from Service.CommonService import CommonService class UnicomComboView(View): def get(self, request, *args, **kwargs): request.encoding = 'utf-8' operation = kwargs.get('operation') return self.validation(request.GET, request, operation) def post(self, request, *args, **kwargs): request.encoding = 'utf-8' operation = kwargs.get('operation') return self.validation(request.POST, request, operation) def validation(self, request_dict, request, operation): if operation == 'buy-notify': return self.package_callback_notify(request_dict, request) elif operation == 'test-notify': order_id = request_dict.get('orderId', None) activate_type = request_dict.get('activateType', 0) iccid = request_dict.get('iccid', None) combo_id = request_dict.get('comboId', None) self.create_combo_order_info(order_id, int(activate_type), iccid, int(combo_id)) return HttpResponse('SUCCESS') elif operation == 'device-queue-monitoring': return self.device_queue_monitoring_push(request_dict, request) elif operation == 'device-status-change': return self.device_status_change_push(request_dict, request) elif operation == 'device-bind': response = ResponseObject('cn') return self.device_add(request_dict, response) else: token = TokenObject(request.META.get('HTTP_AUTHORIZATION')) lang = request_dict.get('lang', token.lang) response = ResponseObject(lang) if token.code != 0: return response.json(token.code) user_id = token.userID if operation == 'combo-save': return self.save_unicom_combo(request_dict, response) elif operation == 'combo-pay': return self.buy_unicom_combo(user_id, request_dict, request, response) elif operation == 'combo-list': return self.query_package_list(response) elif operation == 'get-device-info': return self.get_device_info(request_dict, response) @classmethod def get_device_info(cls, request_dict, response): """ 获取设备信息 @param request_dict: @param response: @return: """ serial_no = request_dict.get('serialNumber', None) if not serial_no: return response.json(444) unicom_device_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_no).values() if not unicom_device_info_qs.exists(): return response.json(173) return response.json(0, dict(unicom_device_info_qs.first())) @classmethod def device_add(cls, request_dict, response): """ 设备绑定iccid @param request_dict: @param response: @return: """ iccid = request_dict.get('iccid', None) serial_no = request_dict.get('serialNo', None) if not all([iccid, serial_no]): return response.json(444) n_time = int(time.time()) try: with transaction.atomic(): # 待完善代码 根据uid与用户id验证系统设备 unicom_device_qs = UnicomDeviceInfo.objects.filter(iccid=iccid) if unicom_device_qs.exists(): return response.json(174) unicom_device_serial_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_no) if unicom_device_serial_qs.exists(): return response.json(174) unicom_obj = UnicomObjeect() result = unicom_obj.verify_device(iccid=iccid) if result.status_code == 200 and result.text: res_dict = json.loads(result.text) if res_dict['success']: if res_dict['data']['status'] == 0: return response.json(173) params = {'iccid': iccid, 'serial_no': serial_no, 'updated_time': n_time, 'created_time': n_time} UnicomDeviceInfo.objects.create(**params) return response.json(0) else: return response.json(173) except Exception as e: print(e) return response.json(177, repr(e)) @classmethod def save_unicom_combo(cls, request_dict, response): """ 联通套餐保存 @param request_dict: @param response: @return: """ combo_id = request_dict.get('id', None) combo_name = request_dict.get('comboName', None) flow_total = request_dict.get('flowTotal', None) expiration_days = request_dict.get('expirationDays', None) expiration_type = request_dict.get('expirationType', None) price = request_dict.get('price', None) remark = request_dict.get('remark', None) pay_type = request_dict.get('payType', '').split(',') if not all([pay_type, combo_name, flow_total, expiration_days, expiration_type, price]): return response.json(444) try: flow_total = int(flow_total) expiration_days = int(expiration_days) expiration_type = int(expiration_type) with transaction.atomic(): re_data = { 'combo_name': combo_name, 'flow_total': flow_total, 'expiration_days': expiration_days, 'expiration_type': expiration_type, 'price': price, } if remark: re_data['remark'] = remark if combo_id: UnicomCombo.objects.filter(id=combo_id).update(**re_data) UnicomCombo.objects.get(id=combo_id).pay_type.set(pay_type) return response.json(0) UnicomCombo.objects.create(**re_data).pay_type.set(pay_type) return response.json(0) except Exception as e: print(e) return response.json(177, repr(e)) @classmethod def query_package_list(cls, response): """ 查询套餐列表 @return: """ try: combo_qs = UnicomCombo.objects.filter(is_show=1, status=0, is_del=False) \ .order_by('sort').values('id', 'combo_name', 'flow_total', 'expiration_days', 'expiration_type', 'price', 'remark') if not combo_qs.exists(): return response.json(0, []) combo_list = [] for item in combo_qs: # 获取支付方式列表 pay_type_qs = Pay_Type.objects.filter(unicomcombo=item['id']).values('id', 'payment') combo_list.append({ 'id': item['id'], 'comboName': item['combo_name'], 'flowTotal': item['flow_total'], 'expirationDays': item['expiration_days'], 'expirationType': item['expiration_type'], 'price': item['price'], 'remark': item['remark'], 'payTypes': list(pay_type_qs), }) return response.json(0, combo_list) except Exception as e: print(e) return response.json(177, repr(e)) @classmethod def buy_unicom_combo(cls, user_id, request_dict, request, response): """ 购买联通套餐 @return: """ try: with transaction.atomic(): iccid = request_dict.get('iccid', None) combo_id = request_dict.get('id', None) pay_type = request_dict.get('payType', None) activate_type = request_dict.get('activateType', 0) if not all([iccid, combo_id, pay_type]): return response.json(444) combo_id = int(combo_id) pay_type = int(pay_type) now_time = int(time.time()) unicom_combo_qs = UnicomCombo.objects.filter(id=combo_id, pay_type=pay_type, is_show=1, is_del=False, status=0) \ .values('id', 'combo_name', 'price', 'remark') if not unicom_combo_qs.exists(): return response.json(173) unicom_device_qs = UnicomDeviceInfo.objects.filter(iccid=iccid) \ .values('serial_no') if not unicom_device_qs.exists(): return response.json(173) unicom_combo_qs = unicom_combo_qs.first() price = unicom_combo_qs['price'] if not price: return response.json(173) unicom_device_qs = unicom_device_qs.first() device_uid = CommonService.query_uid_with_serial(unicom_device_qs['serial_no']) order_id = CommonService.createOrderID() rank_id, ai_rank_id = cls.get_cloud_or_ai_combo() order_dict = {'rank_id': rank_id, 'ai_rank_id': ai_rank_id, 'orderID': order_id, 'UID': device_uid, 'userID_id': user_id, 'desc': unicom_combo_qs['combo_name'], 'payType': pay_type, 'payTime': now_time, 'price': price, 'currency': 'CNY', 'addTime': now_time, 'updTime': now_time, 'unify_combo_id': str(unicom_combo_qs['id']), 'order_type': 2, } params = 'lang=cn' + '&activateType=' + activate_type result = {'result_code': 0, 'reason': 'success', 'error_code': 0} if pay_type == 2: # 支付宝 pay_price = PayService.get_two_float(price, 2) notify_url = 'unicom/wap/pay/ali-notify' order_dict['pay_url'] = PayService.create_alipay_payment(params, order_id, pay_price, unicom_combo_qs['combo_name'], notify_url, unicom_combo_qs['remark'], response) res_data = {'redirectUrl': order_dict['pay_url'], 'orderID': order_id} elif pay_type == 3: # 微信支付 notify_url = 'unicom/wap/pay/wechat-notify' ip = CommonService.get_ip_address(request) params = 'activateType=' + activate_type sign_params = PayService.create_wechat_payment(params, order_id, price, ip, notify_url, unicom_combo_qs['remark'], response) result['result'] = sign_params else: return response.json(444, {'param': 'pay_type'}) Order_Model.objects.create(**order_dict) if pay_type == 3: return JsonResponse(status=200, data=result) return response.json(0, res_data) except Exception as e: print(e) return response.json(500, repr(e)) @staticmethod def get_cloud_or_ai_combo(): """ 获取云存或者AI套餐id @return: """ rank_id = Store_Meal.objects.all().order_by('sort').values().first()['id'] ai_rank_id = AiStoreMeal.objects.all().values().first()['id'] return rank_id, ai_rank_id @classmethod def query_device_usage_history(cls): """ 查询用量历史 @return: """ @staticmethod def package_callback_notify(request_dict, request): """ 异步套餐订购回调 @param request_dict: @param request: @return: """ logger = logging.getLogger('info') try: logger.info('联通异步套餐订购回调参数{}'.format(request_dict)) body = request.body.decode("utf-8") if body: dict_data = json.loads(body) sign = dict_data['sign'] logger.info('设备订购异步回调请求参数{}'.format(dict_data)) dict_data.pop('sign') unicom_obj = UnicomObjeect() generate_sign = unicom_obj.createSign(**dict_data) logger.info('设备订购请求签名{}'.format(sign)) logger.info('设备订购生成签名{}'.format(generate_sign)) r_data = {'success': True, 'msg': '成功'} return HttpResponse(json.dumps(r_data, ensure_ascii=False), content_type="application/json,charset=utf-8") except Exception as e: print(repr(e)) r_data = {'success': False, 'msg': '失败'} return HttpResponse(json.dumps(r_data, ensure_ascii=False), content_type="application/json,charset=utf-8") @staticmethod def device_queue_monitoring_push(request_dict, request): """ 设备套餐队列用完或者到期推送 @param request_dict: @param request: @return: """ logger = logging.getLogger('info') try: logger.info('设备套餐队列推送{}'.format(request_dict)) body = request.body.decode("utf-8") if body: dict_data = json.loads(body) sign = dict_data['sign'] logger.info('设备套餐队列回调请求参数{}'.format(dict_data)) dict_data.pop('sign') unicom_obj = UnicomObjeect() generate_sign = unicom_obj.createSign(**dict_data) logger.info('设备套餐队列请求签名{}'.format(sign)) logger.info('设备套餐队列生成签名{}'.format(generate_sign)) r_data = {'success': True, 'msg': '成功'} return HttpResponse(json.dumps(r_data, ensure_ascii=False), content_type="application/json,charset=utf-8") except Exception as e: print(repr(e)) r_data = {'success': False, 'msg': '失败'} return HttpResponse(json.dumps(r_data, ensure_ascii=False), content_type="application/json,charset=utf-8") @staticmethod def device_status_change_push(request_dict, request): """ 设备状态变更推送执行场景说明 @param request_dict: @param request: @return: """ logger = logging.getLogger('info') try: logger.info('设备状态变更推送{}'.format(request_dict)) body = request.body.decode("utf-8") if body: dict_data = json.loads(body) sign = dict_data['sign'] logger.info('设备状态变更推送请求参数{}'.format(dict_data)) dict_data.pop('sign') unicom_obj = UnicomObjeect() generate_sign = unicom_obj.createSign(**dict_data) logger.info('设备状态变更推送请求签名{}'.format(sign)) logger.info('设备状态变更推送生成签名{}'.format(generate_sign)) r_data = {'success': True, 'msg': '成功'} return HttpResponse(json.dumps(r_data, ensure_ascii=False), content_type="application/json,charset=utf-8") except Exception as e: print(repr(e)) r_data = {'success': False, 'msg': '失败'} return HttpResponse(json.dumps(r_data, ensure_ascii=False), content_type="application/json,charset=utf-8") @classmethod def create_combo_order_info(cls, order_id, activate_type, iccid, combo_id): logger = logging.getLogger('info') logger.info('创建联通订单套餐信息,订单id{}'.format(order_id)) try: with transaction.atomic(): unicom_combo_qs = UnicomCombo.objects.filter(id=int(combo_id)).values() if unicom_combo_qs.exists(): unicom_combo = unicom_combo_qs.first() now_time = int(time.time()) combo_order_data = {'iccid': iccid, 'status': 0, 'combo_id': int(combo_id), 'updated_time': now_time, 'created_time': now_time} if order_id: combo_order_data['order_id'] = order_id # 有效期类型 1 等于自然月,0天数 if unicom_combo['expiration_type'] == 1: # 激活类型 1=下月激活 否则等于当月激活 if activate_type == 1: combo_order_data['next_month_activate'] = True next_start_time, end_time = cls.get_next_month_data_time() combo_order_data['activation_time'] = next_start_time combo_order_data['expire_time'] = end_time else: start_time, month_end_time = cls.get_month_start_and_end_time() combo_order_data['activation_time'] = start_time combo_order_data['expire_time'] = month_end_time combo_order_data['status'] = 1 elif unicom_combo['expiration_type'] == 0: days = unicom_combo['expiration_days'] zero_today, end_time = cls.get_data_time(days) combo_order_data['activation_time'] = zero_today combo_order_data['expire_time'] = end_time combo_order_data['status'] = 1 UnicomComboOrderInfo.objects.create(**combo_order_data) logger.info('保存信息success') return True except Exception as e: print(e) return False @staticmethod def get_next_month_data_time(): """ 获取下个月开始时间与结束时间戳 @return: next_start_time,end_time """ next_month_start = LocalDateTimeUtil.get_next_month_start() next_start_time, next_end_time = LocalDateTimeUtil.get_start_and_end_time(next_month_start, '%Y-%m-%d') next_month_end = LocalDateTimeUtil.get_next_month_end() start_time, end_time = LocalDateTimeUtil.get_start_and_end_time(next_month_end, '%Y-%m-%d') return next_start_time, end_time @staticmethod def get_data_time(days): """ 获取今天开始时间以及days后日期结束时间戳 @return: next_start_time,end_time """ zero_today, last_today = LocalDateTimeUtil.get_today_date(True) now_time = int(time.time()) after_time = LocalDateTimeUtil.get_after_days_timestamp(now_time, days) time_array = time.localtime(after_time) start_time, end_time = LocalDateTimeUtil.get_start_and_end_time(time.strftime("%Y-%m-%d", time_array), '%Y-%m-%d') return zero_today, end_time @staticmethod def get_month_start_and_end_time(): """ 获取当天开始时间与当月结束时间戳 @return: """ zero_today, last_today = LocalDateTimeUtil.get_today_date(True) month_end = LocalDateTimeUtil.get_cur_month_end() start_time, month_end_time = LocalDateTimeUtil.get_start_and_end_time(month_end, '%Y-%m-%d') return zero_today, month_end_time