Browse Source

优化获取序列号接口

locky 2 years ago
parent
commit
88a3b8f548
3 changed files with 117 additions and 121 deletions
  1. 72 103
      Controller/SerialNumberController.py
  2. 22 10
      Object/ResponseObject.py
  3. 23 8
      Service/CommonService.py

+ 72 - 103
Controller/SerialNumberController.py

@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
 import json
 import logging
 import time
@@ -7,7 +5,6 @@ import time
 import requests
 from bulk_update.helper import bulk_update
 from django.db import transaction
-from django.db.models import Count
 from django.views import View
 
 from Model.models import SerialNumberModel, UserModel, UserSerialNumberModel, CompanySerialModel, \
@@ -37,8 +34,8 @@ class SerialNumberView(View):
         response = ResponseObject()
         if operation == 'create':
             return self.do_create(request_dict, response)
-        elif operation == 'getSerial':
-            return self.do_get_serial_number(request_dict, request, response)
+        elif operation == 'getSerial':  # 获取序列号
+            return self.get_serial(request_dict, response)
 
         token = request_dict.get('token', None)
         token = TokenObject(token)
@@ -452,119 +449,91 @@ class SerialNumberView(View):
             print(e)
             return response.json(500)
 
-    # 提供给pc端获取序列号
-    def do_get_serial_number(self, request_dict, request, response):
-        quantity = 1  # 只能取一个
-        company_id = request_dict.get('company_id', None)
+    @staticmethod
+    def get_serial(request_dict, response):
+        """
+        获取序列号
+        @param request_dict: 请求数据
+        @param response: 响应
+        @return: response
+        """
         token = request_dict.get('token', None)
         time_stamp = request_dict.get('time_stamp', None)
-        mac = request_dict.get('mac', None)
+        company_secret = request_dict.get('company_id', None)
 
-        if not all([token, time_stamp, company_id]):
+        if not all([token, time_stamp, company_secret]):
             return response.json(444)
 
-        token = int(CommonService.decode_data(token))
-        time_stamp = int(time_stamp)
-
-        now_time = int(time.time())
-        distance = now_time - time_stamp
+        # 时间戳token校验
+        if not CommonService.check_time_stamp_token(token, time_stamp):
+            return response.json(13)
 
-        if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
-            return response.json(404)
-
-        redisObj = RedisObject()
+        redis_obj = RedisObject()
         # redis加锁,防止同时进行其他操作
         serial_operate_lock_key = 'serial_operate_lock'
-        isLock = redisObj.CONN.setnx(serial_operate_lock_key, 1)
-        if not isLock:
+        serial_operate_lock = redis_obj.CONN.setnx(serial_operate_lock_key, 1)
+        if not serial_operate_lock:
+            return response.json(5)
+        redis_obj.CONN.expire(serial_operate_lock_key, 60)
+
+        # 查询可用的序列号
+        company_serial_qs = CompanySerialModel.objects.filter(company__secret=company_secret, status=1).first()
+        if company_serial_qs is None:
+            redis_obj.del_data(key=serial_operate_lock_key)  # redis解锁
+            return response.json(14)
+
+        serial_number = company_serial_qs.serial_number
+        company_mark = company_serial_qs.company.mark
+
+        user_serial_number_qs = UserSerialNumberModel.objects.filter(user__id=3,
+                                                                     serial_number__serial_number=serial_number,
+                                                                     serial_number__use_status=1)
+        if not user_serial_number_qs.exists():
+            redis_obj.del_data(key=serial_operate_lock_key)  # redis解锁
+            return response.json(14)
+
+        # 防止重复获取序列号
+        serial_number_lock = redis_obj.CONN.setnx(serial_number + 'serial_number_lock', 1)
+        redis_obj.CONN.expire(serial_number + 'serial_number_lock', 60)
+        if not serial_number_lock:
             return response.json(5)
-        redisObj.CONN.expire(serial_operate_lock_key, 60)
-
-        user_qs = UserModel.objects.filter(id=3)
-        if not user_qs.exists():
-            redisObj.del_data(key=serial_operate_lock_key)  # redis解锁
-            return response.json(9)
 
-        user = user_qs[0]
-        result = UserSerialNumberModel.objects.filter(user__id=user.id, serial_number__use_status=1). \
-            aggregate(num=Count('serial_number__use_status'))
+        # 获取mac
+        mac_qs = MacModel.objects.filter(is_active=True).values('value')
+        if not mac_qs.exists():
+            return response.json(175)
 
-        us_qs = UserSerialNumberModel.objects.filter(user__id=user.id, serial_number__use_status=1). \
-            values('serial_number__serial_number')
+        mac = mac_qs[0]['value']
+        # 绑定mac地址成功后更新mac表
+        next_mac = CommonService.updateMac(mac)
+        now_time = int(time.time())
+        mac_data = {
+            'update_time': now_time
+        }
+        if next_mac:
+            mac_data['value'] = next_mac
+        else:
+            mac_data['is_active'] = False
 
-        sns = []
-        for us in us_qs:
-            sns.append(us['serial_number__serial_number'])
-
-        cs_qs = CompanySerialModel.objects.filter(serial_number__in=sns, status=1, company__secret=company_id).values(
-            'serial_number', 'company__mark')
-        sns = []
-        mark = ""
-        if cs_qs.exists():
-            for cs in cs_qs:
-                sns.append(cs['serial_number'])
-            mark = cs_qs[0]['company__mark']
-
-        # 判断是否还有可用的序列号
-        count = result['num']
-        sn_qs = SerialNumberModel.objects.filter(serial_number__in=sns)
-        if not sn_qs.exists() or count < quantity:
-            redisObj.del_data(key=serial_operate_lock_key)  # redis解锁
-            return response.json(444, '序列号不足')
+        # 操作日志数据
+        operation = '获取序列号:{}'.format(serial_number)
+        log = {
+            'user_id': 3,
+            'time': now_time,
+            'operation': operation,
+            'url': 'serialNumber/getSerial',
+        }
 
         try:
-            with transaction.atomic():  # 开启事务
-                sn_qs = sn_qs[0: quantity]
-                serial_number = sn_qs[0].serial_number
-                # 防止重复获取序列号
-                is_lock = redisObj.CONN.setnx(serial_number + 'serial_number_lock', 1)
-                redisObj.CONN.expire(serial_number + 'serial_number_lock', 60)
-                if not is_lock:
-                    return response.json(5)
-
-                if not mac:  # 不传入则分配mac
-                    mac_qs = MacModel.objects.filter().values('id', 'value', 'is_active')[0]
-                    if not mac_qs['is_active']:
-                        return response.json(175)
-                    mac = mac_qs['value']
-                    # 绑定mac地址成功后更新mac表
-                    next_mac = CommonService.updateMac(mac)  # mac地址值+1;后3个字节为FF时返回None
-                    if next_mac:
-                        MacModel.objects.filter().update(value=next_mac, update_time=now_time)  # 更新mac表的mac地址值
-                    else:
-                        MacModel.objects.filter().update(is_active=False, update_time=now_time)
-
-                # 更新序列号表数据
-                serialNumberModel = SerialNumberModel(
-                    id=sn_qs[0].id,
-                    serial_number=serial_number,
-                    status=sn_qs[0].status,
-                    use_status=2,
-                    add_time=now_time
-                )
-                updates = []
-                updates.append(serialNumberModel)
-                bulk_update(updates)
-
-                # 更新企业关联序列号状态
+            with transaction.atomic():
+                # 更新和创建数据
+                MacModel.objects.filter().update(**mac_data)
+                SerialNumberModel.objects.filter(serial_number=serial_number).update(use_status=2, add_time=now_time)
                 CompanySerialModel.objects.filter(serial_number=serial_number).update(status=2, update_time=now_time)
-
-                # 记录操作日志
-                ip = CommonService.get_ip_address(request)
-                content = json.loads(json.dumps(request.POST))
-                operation = '获取序列号:{}'.format(serial_number)
-                log = {
-                    'status': 200,
-                    'content': json.dumps(content),
-                    'ip': ip,
-                    'time': now_time,
-                    'url': 'serialNumber/getSerial',
-                    'operation': operation,
-                    'user': user_qs[0]
-                }
                 LogModel.objects.create(**log)
-                redisObj.del_data(key=serial_operate_lock_key)  # redis解锁
-                return response.json(0, {'serial_number': serial_number + mark, 'mac': mac})
+
+                redis_obj.del_data(key=serial_operate_lock_key)  # redis解锁
+                return response.json(0, {'serial_number': serial_number + company_mark, 'mac': mac})
         except Exception as e:
-            redisObj.del_data(key=serial_operate_lock_key)  # redis解锁
+            redis_obj.del_data(key=serial_operate_lock_key)  # redis解锁
             return response.json(500, repr(e))

+ 22 - 10
Object/ResponseObject.py

@@ -7,13 +7,18 @@ class ResponseObject(object):
     def __init__(self, lang='cn'):
         self.lang = lang
 
-    def data(self, code, res={}):
+    def data(self, code, res=None):
+        if res is None:
+            res = {}
+
         data_cn = {
             0: '成功',
             5: '请一分钟后再尝试',
             8: '用户账号已存在',
             9: '用户账号不存在',
             10: res,
+            13: '时间戳token校验失败',
+            14: '序列号不足',
             42: '两次输入的新密码错误',
             43: '客户端服务器已关闭,请下载新版本使用',
             44: '系统错误,发送邮件失败',
@@ -53,6 +58,8 @@ class ResponseObject(object):
             8: 'User accounts already exist',
             9: 'User accounts is not exist',
             10: res,
+            13: 'Timestamp token verification failed',
+            14: 'Inadequate serial number',
             42: 'The new password entered twice is incorrect',
             43: 'The client server is closed. Please download the new version for use',
             44: 'System error,send email fail!',
@@ -90,16 +97,21 @@ class ResponseObject(object):
             msg = data_cn
         else:
             msg = data_en
-        try:
-            message = msg[code]
-        except Exception as e:
-            message = '系统错误,code不存在'
-        return {'code': code, 'msg': message, 'res': res}
 
-    def formal(self, code, res={}):
+        reason = msg.get(code)
+        if reason is None:
+            reason = 'code不存在'
+
+        return {'code': code, 'msg': reason, 'res': res}
+
+    def formal(self, code, res=None):
+        if res is None:
+            res = {}
         formal_data = self.data(code, res)
-        return json.dumps(formal_data,ensure_ascii=False)
+        return json.dumps(formal_data, ensure_ascii=False)
 
-    def json(self, code, res={}):
+    def json(self, code, res=None):
+        if res is None:
+            res = {}
         result = self.formal(code, res)
-        return HttpResponse(result)
+        return HttpResponse(result)

+ 23 - 8
Service/CommonService.py

@@ -226,6 +226,11 @@ class CommonService:
 
     @staticmethod
     def updateMac(mac: str):
+        """
+        mac地址值+1;后3个字节为FF时返回None
+        :param mac: mac
+        :return:
+        """
         macArray = mac.split(':')
 
         macArray[0] = int(macArray[0], 16)
@@ -235,11 +240,6 @@ class CommonService:
         second = int(macArray[4], 16)
         three = int(macArray[3], 16)
 
-        # print(macArray)
-        # print(first)
-        # print(second)
-        # print(three)
-
         if first == 255 and second == 255 and three == 255:
             return None
 
@@ -256,10 +256,8 @@ class CommonService:
         macArray[3] = three
         macArray[4] = second
         macArray[5] = first
-        # print(macArray)
 
         tmp = ':'.join(map(lambda x: "%02x" % x, macArray))
-        # print(tmp)
         return tmp.upper()
 
     @staticmethod
@@ -282,4 +280,21 @@ class CommonService:
             return content
         except Exception as e:
             print(e)
-            return None
+            return None
+
+    @staticmethod
+    def check_time_stamp_token(token, time_stamp):
+        # 时间戳token校验
+        if not all([token, time_stamp]):
+            return False
+        try:
+            token = int(CommonService.decode_data(token))
+            time_stamp = int(time_stamp)
+            now_time = int(time.time())
+            distance = now_time - time_stamp
+            if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
+                return False
+            return True
+        except Exception as e:
+            print(e)
+            return False