zhangdongming 3 жил өмнө
parent
commit
1c83e62300

+ 242 - 242
Controller/UnicomCombo/UnicomComboController.py

@@ -17,248 +17,248 @@ from django.views.generic.base import View
 from Model.models import UnicomDeviceInfo, UnicomCombo, Pay_Type
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
+from Object.UnicomObject import UnicomObjeect
 
 
 class UnicomComboView(View):
-    pass
-    # 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 == '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)
-    #     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 == 'device-bind':
-    #             return self.device_add(user_id, request_dict, response)
-    #         elif operation == 'combo-save':
-    #             return self.save_unicom_combo(request_dict, response)
-    #         elif operation == 'combo-list':
-    #             return self.query_package_list(response)
-    #
-    # @classmethod
-    # def device_add(cls, user_id, request_dict, response):
-    #     """
-    #     设备绑定iccid
-    #     @param user_id:
-    #     @param request_dict:
-    #     @param response:
-    #     @return:
-    #     """
-    #     iccid = request_dict.get('iccid', None)
-    #     uid = request_dict.get('uid', None)
-    #     if not all([iccid, uid]):
-    #         return response.json(444)
-    #     n_time = int(time.time())
-    #     try:
-    #         # 待完善代码 根据uid与用户id验证系统设备
-    #         unicom_device_qs = UnicomDeviceInfo.objects.filter(iccid=iccid)
-    #         if unicom_device_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 = {'user_id': user_id, 'iccid': iccid, 'uid': uid, '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_package(cls):
-    #     """
-    #     购买套餐
-    #     @return:
-    #     """
-    #     pass
-    #
-    # @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")
+    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 == '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)
+        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 == 'device-bind':
+                return self.device_add(user_id, request_dict, response)
+            elif operation == 'combo-save':
+                return self.save_unicom_combo(request_dict, response)
+            elif operation == 'combo-list':
+                return self.query_package_list(response)
+
+    @classmethod
+    def device_add(cls, user_id, request_dict, response):
+        """
+        设备绑定iccid
+        @param user_id:
+        @param request_dict:
+        @param response:
+        @return:
+        """
+        iccid = request_dict.get('iccid', None)
+        uid = request_dict.get('uid', None)
+        if not all([iccid, uid]):
+            return response.json(444)
+        n_time = int(time.time())
+        try:
+            # 待完善代码 根据uid与用户id验证系统设备
+            unicom_device_qs = UnicomDeviceInfo.objects.filter(iccid=iccid)
+            if unicom_device_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 = {'user_id': user_id, 'iccid': iccid, 'uid': uid, '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_package(cls):
+        """
+        购买套餐
+        @return:
+        """
+        pass
+
+    @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")

+ 256 - 257
Object/UnicomObject.py

@@ -1,257 +1,256 @@
-# # -*- encoding: utf-8 -*-
-# """
-# @File    : UnicomObject.py
-# @Time    : 2022/6/17 11:03
-# @Author  : stephen
-# @Email   : zhangdongming@asj6.wecom.work
-# @Software: PyCharm
-# """
-# import base64
-# import json
-#
-# import requests
-# from Crypto.Cipher import AES
-# from decimal import Decimal
-#
-# from pysmx.SM3 import hash_msg as sm3_msg
-#
-# from Ansjer.config import unicomAppUrl, unicomAppId, unicomAppSecret, unicomTenantId, \
-#     unicomEncodeKey, unicomIvKey, unicomUserName, unicomPassword, unicomPushKey
-# from Object.utils.SymmetricCryptoUtil import AESencrypt
-#
-# """
-# 联通4Gapi
-# 具体参数查看接口文档
-# https://www.showdoc.com.cn/unicomJYHapi/8158648460007467
-# """
-#
-#
-# class UnicomObjeect:
-#     def __init__(self):
-#         self.appUrl = unicomAppUrl
-#         self.appId = unicomAppId
-#         self.appSecret = unicomAppSecret
-#         self.tenantId = unicomTenantId
-#         self.encodeKey = unicomEncodeKey
-#         self.ivKey = unicomIvKey
-#         self.username = unicomUserName
-#         self.password = unicomPassword
-#         self.pushKey = unicomPushKey
-#         self.headers = {'Tenant': self.tenantId, 'content-type': 'application/x-www-form-urlencoded'}
-#
-#     # pip install snowland-smx
-#     def createSign(self, reverse=False, **sign_params):
-#         """
-#         调用接口(API)时需要对请求参数进行签名(sign)验证,
-#         算法:
-#         根据参数名称将你的所有请求参数按照字母先后顺序排序: key = value & key = value,对除签名外的所有请求参数按
-#         key
-#         做的升序排列。
-#         如:将
-#         foo = 1, bar = 2, baz = 3
-#         排序为
-#         bar = 2, baz = 3, foo = 1
-#         参数名和参数值链接后,得到拼装字符串(注意:参数名与参数值左右两边不能包含空格)
-#         bar = 2 & baz = 3 & foo = 1
-#         将
-#         pushkey拼接到参数字符尾部进行
-#         SM3
-#         加密,再转化成大写,格式是
-#         (SM3(key1=value1 & key2=value2 &...& key= pushKey)).upcase
-#         @param reverse:
-#         @param sign_params:
-#         @return:
-#         """
-#         dict_2 = dict(sorted(sign_params.items(), key=lambda item: item[0], reverse=reverse))
-#         data_list = []
-#         for item in dict_2.items():
-#             if item[0] and item[1]:
-#                 data_list.append("{}={}".format(item[0], item[1]))
-#         val = '&'.join(data_list)
-#         push_key = '&key={}'.format(self.pushKey)
-#         val = val + push_key
-#         return sm3_msg(val).upper()
-#
-#     def get_login_authorization(self):
-#         """
-#         获取登录授权
-#         注意登录认证Authorization和登录后的请求认证不一样
-#         算法:appId+":"+appSecret base64转码生成 前面加Basic
-#         @return: "Basic " + base64_data
-#         """
-#         voucher = self.appId + ':' + self.appSecret
-#         base64_data = str(base64.b64encode(voucher.encode("utf-8")), "utf-8")
-#         return "Basic " + base64_data
-#
-#     def get_encode_password(self):
-#         """
-#         获取对称加密
-#         @return: encrypt_pwd
-#         """
-#         aes = AESencrypt(self.encodeKey.encode('utf-8'), AES.MODE_CBC, self.ivKey.encode('utf-8'),
-#                          paddingMode="ZeroPadding",
-#                          characterSet='utf-8')
-#         encrypt_pwd = aes.encryptFromString(self.password)
-#         return encrypt_pwd
-#
-#     def generate_token(self):
-#         """
-#         生成令牌
-#         @return: token
-#         """
-#         url = self.appUrl + '/auc/oauth/token'
-#         pwd = self.get_encode_password()
-#         body = {'username': self.username, 'password': pwd, 'grant_type': 'password', 'scope': 'server'}
-#         headers = self.headers
-#         headers['Authorization'] = self.get_login_authorization()
-#         response_data = requests.post(url, data=body, headers=headers)
-#         response_data = json.loads(response_data.text)
-#         return response_data['access_token']
-#
-#     def refresh_token(self, refresh_token):
-#         """
-#         刷新令牌
-#         @param refresh_token:
-#         @return:
-#         """
-#         url = self.appUrl + '/auc/oauth/token?grant_type=refresh_token'
-#         body = {'refresh_token': refresh_token, 'grant_type': 'refresh_token'}
-#         headers = self.headers
-#         headers['Authorization'] = self.get_login_authorization()
-#         response_data = requests.post(url, data=body, headers=headers)
-#         return response_data.text
-#
-#     def business_unify_headers(self):
-#         """
-#         业务统一headers
-#         在请求头中增加key为Authorization,value为"Bearer " + token
-#         @return: headers
-#         """
-#         token = self.generate_token()
-#         headers = self.headers
-#         headers['Authorization'] = 'Bearer ' + token
-#         return headers
-#
-#     # 业务api  注意 get与post 请求数据类型不同 post使用:application/json
-#     def verify_device(self, **re_params):
-#         """
-#         验证设备
-#         @param re_params:
-#         @return:
-#         """
-#         url = self.appUrl + '/platform/api/device/verify-device'
-#         return requests.get(url, params=re_params, headers=self.business_unify_headers())
-#
-#     def query_device_status(self, **re_params):
-#         """
-#         查询设备状态
-#         @param re_params:
-#         @return:
-#         """
-#         url = self.appUrl + '/platform/api/device/device-status'
-#         return requests.get(url, params=re_params, headers=self.business_unify_headers())
-#
-#     def update_device_state(self, **re_data):
-#         """
-#         修改设备状态
-#         @param re_data:
-#         @return:
-#         """
-#         url = self.appUrl + '/platform/api/device/device-state'
-#         headers = self.business_unify_headers()
-#         headers['content-type'] = 'application/json'
-#         return requests.post(url, data=json.dumps(re_data), headers=headers)
-#
-#     def query_device_usage_history(self, **re_params):
-#         """
-#         查询设备用量历史
-#         @param re_params:
-#         @return:
-#         """
-#         url = self.appUrl + '/platform/api/usage/device-usage-history'
-#         return requests.get(url, params=re_params, headers=self.business_unify_headers())
-#
-#     def query_current_renew_list_usage_details(self, **re_params):
-#         """
-#         查询设备当前队列用量详情
-#         @param re_params:
-#         @return:
-#         """
-#         url = self.appUrl + '/platform/api/usage/current-renewlist-usage-details'
-#         return requests.get(url, params=re_params, headers=self.business_unify_headers())
-#
-#     def get_device_batch_detail(self, **re_data):
-#         """
-#         查询设备当前队列用量详情
-#         @return:
-#         """
-#         url = self.appUrl + '/platform/api/device/batch-detail'
-#         headers = self.business_unify_headers()
-#         headers['content-type'] = 'application/json'
-#         return requests.post(url, data=json.dumps(re_data), headers=headers)
-#
-#     def query_package_list(self, **re_params):
-#         """
-#         查询套餐列表
-#         @return:
-#         """
-#         url = self.appUrl + '/platform/api/package/list'
-#         return requests.get(url, params=re_params, headers=self.business_unify_headers())
-#
-#     def query_renewal_list(self, **re_params):
-#         """
-#         续费套餐列表
-#         @param re_params:
-#         @return:
-#         """
-#         url = self.appUrl + '/platform/api/package/list'
-#         return requests.get(url, params=re_params, headers=self.business_unify_headers())
-#
-#     def async_buy_package(self, **re_data):
-#         """
-#         查询设备当前队列用量详情
-#         @return:
-#         """
-#         url = self.appUrl + '/platform/api/package/async-buy-package'
-#         headers = self.business_unify_headers()
-#         headers['content-type'] = 'application/json'
-#         return requests.post(url, data=json.dumps(re_data), headers=headers)
-#
-#
-# if __name__ == '__main__':
-#     price = '12.13'
-#     print(float(price))
-#     discount = '6'
-#     dd = Decimal(price) - Decimal(discount)
-#     print(dd.quantize(Decimal('0.00')))
-#
-#     # data = {'foo': 1, 'bar': 2, 'baz': 3}
-#     # print(unicom_api.createSign(**data))
-#     unicom_api = UnicomObjeect()
-#     # result = unicom_api.generate_token()
-#     # result = unicom_api.refresh_token('5d0c0f30-99bd-4f17-9614-3524495b05d4')
-#     params = {'iccids': '89860620180077842020'}
-#     # response = unicom_api.verify_device(**params)
-#     # response = unicom_api.query_device_status(**params)
-#     # response = unicom_api.update_device_state(**params)
-#     # response = unicom_api.query_device_usage_history(**params)
-#     # response = unicom_api.query_current_renew_list_usage_details(**params)
-#     # unicom_api.get_device_batch_detail()
-#     response = unicom_api.query_package_list()
-#     # response = unicom_api.query_renewal_list(**params)
-#
-#     if response.status_code == 200:
-#         res_dict = json.loads(response.text)
-#         print(res_dict)
-#     response_json = {
-#         "success": True,
-#         "msg": "操作成功",
-#         "code": 0,
-#         "data": {
-#             "iccid": "8986062018007784202",
-#             "completeIccid": "89860620180077842020",
-#             "status": 1
-#         }
-#     }
-#     print(response_json['data']['iccid'])
-#     print(response.status_code)
+# -*- encoding: utf-8 -*-
+"""
+@File    : UnicomObject.py
+@Time    : 2022/6/17 11:03
+@Author  : stephen
+@Email   : zhangdongming@asj6.wecom.work
+@Software: PyCharm
+"""
+import base64
+import json
+
+import requests
+from Crypto.Cipher import AES
+from decimal import Decimal
+from Object.utils import SM3Util
+
+from Ansjer.config import unicomAppUrl, unicomAppId, unicomAppSecret, unicomTenantId, \
+    unicomEncodeKey, unicomIvKey, unicomUserName, unicomPassword, unicomPushKey
+from Object.utils.SymmetricCryptoUtil import AESencrypt
+
+"""
+联通4Gapi
+具体参数查看接口文档
+https://www.showdoc.com.cn/unicomJYHapi/8158648460007467
+"""
+
+
+class UnicomObjeect:
+    def __init__(self):
+        self.appUrl = unicomAppUrl
+        self.appId = unicomAppId
+        self.appSecret = unicomAppSecret
+        self.tenantId = unicomTenantId
+        self.encodeKey = unicomEncodeKey
+        self.ivKey = unicomIvKey
+        self.username = unicomUserName
+        self.password = unicomPassword
+        self.pushKey = unicomPushKey
+        self.headers = {'Tenant': self.tenantId, 'content-type': 'application/x-www-form-urlencoded'}
+
+    # pip install snowland-smx
+    def createSign(self, reverse=False, **sign_params):
+        """
+        调用接口(API)时需要对请求参数进行签名(sign)验证,
+        算法:
+        根据参数名称将你的所有请求参数按照字母先后顺序排序: key = value & key = value,对除签名外的所有请求参数按
+        key
+        做的升序排列。
+        如:将
+        foo = 1, bar = 2, baz = 3
+        排序为
+        bar = 2, baz = 3, foo = 1
+        参数名和参数值链接后,得到拼装字符串(注意:参数名与参数值左右两边不能包含空格)
+        bar = 2 & baz = 3 & foo = 1
+        将
+        pushkey拼接到参数字符尾部进行
+        SM3
+        加密,再转化成大写,格式是
+        (SM3(key1=value1 & key2=value2 &...& key= pushKey)).upcase
+        @param reverse:
+        @param sign_params:
+        @return:
+        """
+        dict_2 = dict(sorted(sign_params.items(), key=lambda item: item[0], reverse=reverse))
+        data_list = []
+        for item in dict_2.items():
+            if item[0] and item[1]:
+                data_list.append("{}={}".format(item[0], item[1]))
+        val = '&'.join(data_list)
+        push_key = '&key={}'.format(self.pushKey)
+        val = val + push_key
+        return SM3Util.sm3(val).upper()
+
+    def get_login_authorization(self):
+        """
+        获取登录授权
+        注意登录认证Authorization和登录后的请求认证不一样
+        算法:appId+":"+appSecret base64转码生成 前面加Basic
+        @return: "Basic " + base64_data
+        """
+        voucher = self.appId + ':' + self.appSecret
+        base64_data = str(base64.b64encode(voucher.encode("utf-8")), "utf-8")
+        return "Basic " + base64_data
+
+    def get_encode_password(self):
+        """
+        获取对称加密
+        @return: encrypt_pwd
+        """
+        aes = AESencrypt(self.encodeKey.encode('utf-8'), AES.MODE_CBC, self.ivKey.encode('utf-8'),
+                         paddingMode="ZeroPadding",
+                         characterSet='utf-8')
+        encrypt_pwd = aes.encryptFromString(self.password)
+        return encrypt_pwd
+
+    def generate_token(self):
+        """
+        生成令牌
+        @return: token
+        """
+        url = self.appUrl + '/auc/oauth/token'
+        pwd = self.get_encode_password()
+        body = {'username': self.username, 'password': pwd, 'grant_type': 'password', 'scope': 'server'}
+        headers = self.headers
+        headers['Authorization'] = self.get_login_authorization()
+        response_data = requests.post(url, data=body, headers=headers)
+        response_data = json.loads(response_data.text)
+        return response_data['access_token']
+
+    def refresh_token(self, refresh_token):
+        """
+        刷新令牌
+        @param refresh_token:
+        @return:
+        """
+        url = self.appUrl + '/auc/oauth/token?grant_type=refresh_token'
+        body = {'refresh_token': refresh_token, 'grant_type': 'refresh_token'}
+        headers = self.headers
+        headers['Authorization'] = self.get_login_authorization()
+        response_data = requests.post(url, data=body, headers=headers)
+        return response_data.text
+
+    def business_unify_headers(self):
+        """
+        业务统一headers
+        在请求头中增加key为Authorization,value为"Bearer " + token
+        @return: headers
+        """
+        token = self.generate_token()
+        headers = self.headers
+        headers['Authorization'] = 'Bearer ' + token
+        return headers
+
+    # 业务api  注意 get与post 请求数据类型不同 post使用:application/json
+    def verify_device(self, **re_params):
+        """
+        验证设备
+        @param re_params:
+        @return:
+        """
+        url = self.appUrl + '/platform/api/device/verify-device'
+        return requests.get(url, params=re_params, headers=self.business_unify_headers())
+
+    def query_device_status(self, **re_params):
+        """
+        查询设备状态
+        @param re_params:
+        @return:
+        """
+        url = self.appUrl + '/platform/api/device/device-status'
+        return requests.get(url, params=re_params, headers=self.business_unify_headers())
+
+    def update_device_state(self, **re_data):
+        """
+        修改设备状态
+        @param re_data:
+        @return:
+        """
+        url = self.appUrl + '/platform/api/device/device-state'
+        headers = self.business_unify_headers()
+        headers['content-type'] = 'application/json'
+        return requests.post(url, data=json.dumps(re_data), headers=headers)
+
+    def query_device_usage_history(self, **re_params):
+        """
+        查询设备用量历史
+        @param re_params:
+        @return:
+        """
+        url = self.appUrl + '/platform/api/usage/device-usage-history'
+        return requests.get(url, params=re_params, headers=self.business_unify_headers())
+
+    def query_current_renew_list_usage_details(self, **re_params):
+        """
+        查询设备当前队列用量详情
+        @param re_params:
+        @return:
+        """
+        url = self.appUrl + '/platform/api/usage/current-renewlist-usage-details'
+        return requests.get(url, params=re_params, headers=self.business_unify_headers())
+
+    def get_device_batch_detail(self, **re_data):
+        """
+        查询设备当前队列用量详情
+        @return:
+        """
+        url = self.appUrl + '/platform/api/device/batch-detail'
+        headers = self.business_unify_headers()
+        headers['content-type'] = 'application/json'
+        return requests.post(url, data=json.dumps(re_data), headers=headers)
+
+    def query_package_list(self, **re_params):
+        """
+        查询套餐列表
+        @return:
+        """
+        url = self.appUrl + '/platform/api/package/list'
+        return requests.get(url, params=re_params, headers=self.business_unify_headers())
+
+    def query_renewal_list(self, **re_params):
+        """
+        续费套餐列表
+        @param re_params:
+        @return:
+        """
+        url = self.appUrl + '/platform/api/package/list'
+        return requests.get(url, params=re_params, headers=self.business_unify_headers())
+
+    def async_buy_package(self, **re_data):
+        """
+        查询设备当前队列用量详情
+        @return:
+        """
+        url = self.appUrl + '/platform/api/package/async-buy-package'
+        headers = self.business_unify_headers()
+        headers['content-type'] = 'application/json'
+        return requests.post(url, data=json.dumps(re_data), headers=headers)
+
+
+if __name__ == '__main__':
+    price = '12.13'
+    print(float(price))
+    discount = '6'
+    dd = Decimal(price) - Decimal(discount)
+    print(dd.quantize(Decimal('0.00')))
+
+    # data = {'foo': 1, 'bar': 2, 'baz': 3}
+    # print(unicom_api.createSign(**data))
+    unicom_api = UnicomObjeect()
+    # result = unicom_api.generate_token()
+    # result = unicom_api.refresh_token('5d0c0f30-99bd-4f17-9614-3524495b05d4')
+    params = {'iccids': '89860620180077842020'}
+    # response = unicom_api.verify_device(**params)
+    # response = unicom_api.query_device_status(**params)
+    # response = unicom_api.update_device_state(**params)
+    # response = unicom_api.query_device_usage_history(**params)
+    # response = unicom_api.query_current_renew_list_usage_details(**params)
+    # unicom_api.get_device_batch_detail()
+    response = unicom_api.query_package_list()
+    # response = unicom_api.query_renewal_list(**params)
+
+    if response.status_code == 200:
+        res_dict = json.loads(response.text)
+        print(res_dict)
+    response_json = {
+        "success": True,
+        "msg": "操作成功",
+        "code": 0,
+        "data": {
+            "iccid": "8986062018007784202",
+            "completeIccid": "89860620180077842020",
+            "status": 1
+        }
+    }
+    print(response_json['data']['iccid'])
+    print(response.status_code)

+ 136 - 0
Object/utils/SM3Util.py

@@ -0,0 +1,136 @@
+# -*- encoding: utf-8 -*-
+"""
+@File    : SM3Util.py
+@Time    : 2022/6/28 8:34
+@Author  : stephen
+@Email   : zhangdongming@asj6.wecom.work
+@Software: PyCharm
+"""
+IV = [1937774191, 1226093241, 388252375, 3666478592, 2842636476, 372324522, 3817729613, 2969243214, ]
+Tj = [
+    2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169,
+    2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169,
+    2043430169, 2043430169, 2043430169, 2043430169, 2055708042, 2055708042,
+    2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
+    2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
+    2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
+    2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
+    2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
+    2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
+    2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
+    2055708042, 2055708042, 2055708042, 2055708042
+]
+
+
+def group(list, n):  ##分组
+    for i in range(0, len(list), n):
+        yield list[i:i + n]
+
+
+def xor(a, b):
+    a1 = int(a, 16)
+    b1 = int(b, 16)
+    A = '{:08x}'.format(int(a1 ^ b1))
+    return A
+
+
+def left_hex(list, n):
+    out1 = '{:032b}'.format(int(list, 16))
+    out2 = out1[n:] + out1[:n]
+    out_list = '{:08x}'.format(int(out2, 2))
+    return out_list
+
+
+def left_int(list, n):
+    out1 = '{:032b}'.format(list)
+    out2 = out1[n:] + out1[:n]
+    out_list = int(out2, 2)
+    return out_list
+
+
+def FFj(X, Y, Z, j):
+    if 0 <= j and j < 16:
+        return X ^ Y ^ Z
+    elif 16 <= j and j < 64:
+        return (X & Y) | (X & Z) | (Y & Z)
+
+
+def GGj(X, Y, Z, j):
+    if 0 <= j and j < 16:
+        return X ^ Y ^ Z
+    elif 16 <= j and j < 64:
+        return (X & Y) | ((~ X) & Z)
+
+
+def P0(X):
+    return X ^ left_int(X, 9) ^ left_int(X, 17)
+
+
+def P1(X):
+    return xor(xor(X, left_hex(X, 15)), left_hex(X, 23))
+
+
+def CF(V, data):
+    W = []
+    W1 = []
+    [W.append(data[i * 8:(i + 1) * 8]) for i in range(16)]
+    for i in range(16, 68):
+        w_in = xor(xor(P1(xor(xor(W[i - 16], W[i - 9]), left_hex(W[i - 3], 15))), left_hex(W[i - 13], 7)), W[i - 6])
+        w_out = '{:08x}'.format(int(w_in, 16))
+        W.append(w_out)
+    [W1.append(xor(W[i], W[i + 4])) for i in range(64)]
+    A, B, C, D, E, F, G, H = V
+    for i in range(0, 64):
+        ss1 = left_int((left_int(A, 12) + E + left_int(Tj[i], i % 32) & 0xffffffff), 7)
+        ss2 = ss1 ^ (left_int(A, 12))
+        tt1 = (FFj(A, B, C, i) + D + ss2 + int(W1[i], 16)) & 0xffffffff
+        tt2 = (GGj(E, F, G, i) + H + ss1 + int(W[i], 16)) & 0xffffffff
+        D = C
+        C = left_int(B, 9)
+        B = A
+        A = tt1
+        H = G
+        G = left_int(F, 19)
+        F = E
+        E = P0(tt2)
+    outV = [A ^ V[0], B ^ V[1], C ^ V[2], D ^ V[3], E ^ V[4], F ^ V[5], G ^ V[6], H ^ V[7]]
+    return outV
+
+
+def sm3(data):
+    l = len(data) // 2
+    byte = '{0:x}'.format(int(l * 8))
+    data_list = []
+    [data_list.append(i) for i in group(data, 128)]
+    m = l % 64
+    if m < 56 and m != 0:
+        data_list[-1] = (data_list[-1] + '80').ljust(112, '0') + str(byte).rjust(16, '0')
+    elif m >= 56:
+        data_list[-1] = (data_list[-1] + '80').ljust(128, '0')
+        data_list.append(112 * '0' + str(byte).rjust(16, '0'))
+    elif m == 0:
+        data_list.append('80' + 110 * '0' + str(byte).rjust(16, '0'))
+        V = IV
+    for i in range(0, len(data_list)):
+        V = CF(V, data_list[i])
+    for i in range(len(V)):
+        V[i] = '{:08x}'.format(V[i])
+    return ''.join(V)
+
+
+def sm3_hmac(data, key):
+    l = len(key) // 2
+    if l > 64:
+        key = sm3(key)
+    else:
+        pass
+    key = key.ljust(128, '0')
+    opad = '5c' * 64
+    ipad = '36' * 64
+    ipadkey = '%x' % (int(key, 16) ^ int(ipad, 16))
+    M = sm3(ipadkey + data)
+    opadkey = '%x' % (int(key, 16) ^ int(opad, 16))
+    out_data = sm3(opadkey + M)
+    return out_data
+
+