Pārlūkot izejas kodu

优化加密IC UID代码

zhangdongming 2 nedēļas atpakaļ
vecāks
revīzija
ca6a445d90
2 mainītis faili ar 191 papildinājumiem un 51 dzēšanām
  1. 190 51
      AdminController/UIDBurnManageController.py
  2. 1 0
      AgentModel/models.py

+ 190 - 51
AdminController/UIDBurnManageController.py

@@ -16,7 +16,6 @@ from datetime import datetime
 from typing import Dict, Any
 from uuid import uuid4
 
-from django.core import serializers
 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
 from django.db import transaction
 from django.db.models import Q
@@ -24,7 +23,7 @@ from django.http import QueryDict
 from django.views import View
 from openpyxl import load_workbook
 
-from AgentModel.models import BurnRecord, BurnEncryptedICUID
+from AgentModel.models import BurnRecord, BurnEncryptedICUID, BurnBatch
 from Ansjer.config import LOGGER
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
@@ -80,16 +79,100 @@ class UIDBurnManageView(View):
         elif operation == 'importBatchUids':
             return self.import_batch_uids(request, response)
         elif operation == 'addBurnRecord':
-            return self.add_burn_record(request,request_dict, response)
-        elif operation == 'getBurnUidsPage':
-            return self.get_burn_uids_page(request_dict, response)
+            return self.add_burn_record(request, request_dict, response)
+        elif operation == 'batchPageUids':
+            return self.batch_page_uids(request_dict, response)
         elif operation == 'getImportProgress':
             return self.get_import_progress(request_dict, response)
         elif operation == 'getImportTaskList':
             return self.get_import_task_list(request_dict, response)
+        elif operation == 'getBatchRecordsPage':
+            return self.get_batch_records_page(request_dict, response)
         else:
             return response.json(414)
 
+    @classmethod
+    def get_batch_records_page(cls, request_dict: Dict[str, Any], response) -> Any:
+        """
+        分页查询批次记录(带统计信息)
+        :param request_dict: 请求参数字典
+        :param response: 响应对象
+        :return: JSON响应
+        """
+        # 1. 分页参数处理
+        try:
+            page = int(request_dict.get('page', 1))
+            page_size = int(request_dict.get('pageSize', 10))
+            page = max(page, 1)
+            page_size = max(1, min(page_size, 100))
+        except (ValueError, TypeError):
+            return response.json(444, "分页参数错误(必须为整数)")
+
+        # 2. 构建查询条件
+        query = Q()
+        batch_number = request_dict.get('batch_number', '').strip()
+        if batch_number:
+            query &= Q(batch_number__icontains=batch_number)
+
+        # 3. 查询并分页
+        batch_qs = BurnBatch.objects.filter(query).order_by('-created_time').values(
+            'id', 'batch_number', 'purpose', 'manager', 'total_uid', 'created_time'
+        )
+
+        paginator = Paginator(batch_qs, page_size)
+        try:
+            page_obj = paginator.page(page)
+        except PageNotAnInteger:
+            page_obj = paginator.page(1)
+        except EmptyPage:
+            page_obj = paginator.page(paginator.num_pages)
+
+        # 4. 获取统计信息并构建结果
+        redis_obj = RedisObject()
+        batch_list = []
+        
+        for batch in page_obj:
+            batch_id = batch['id']
+            cache_key = f"batch_stats:{batch_id}"
+            
+            # 尝试从缓存获取统计信息
+            cached_stats = redis_obj.get_data(cache_key)
+            if cached_stats:
+                stats = json.loads(cached_stats)
+            else:
+                # 查询数据库统计
+                burned_count = BurnEncryptedICUID.objects.filter(
+                    batch_id=batch_id, 
+                    status=1
+                ).count()
+                unburned_count = BurnEncryptedICUID.objects.filter(
+                    batch_id=batch_id, 
+                    status=0
+                ).count()
+                
+                stats = {
+                    'burned_count': burned_count,
+                    'unburned_count': unburned_count
+                }
+                # 设置缓存,过期时间1小时
+                redis_obj.set_data(cache_key, json.dumps(stats), 3600)
+            
+            # 合并批次信息和统计信息
+            batch_info = dict(batch)
+            batch_info.update(stats)
+            batch_list.append(batch_info)
+
+        return response.json(
+            0,
+            {
+                'list': batch_list,
+                'total': paginator.count,
+                'currentPage': page_obj.number,
+                'totalPages': paginator.num_pages,
+                'pageSize': page_size
+            }
+        )
+
     @classmethod
     def get_burn_records_page(cls, request_dict: Dict[str, Any], response) -> Any:
         """
@@ -142,11 +225,10 @@ class UIDBurnManageView(View):
             }
         )
 
-
     @classmethod
     def import_batch_uids(cls, request, response) -> Any:
         """
-        导入批次UID - 异步优化版
+        导入批次UID - 异步优化版(适配新表结构)
         :param request: HttpRequest对象(包含上传文件)
         :param response: 响应对象
         :return: JSON响应
@@ -214,7 +296,7 @@ class UIDBurnManageView(View):
 
     @classmethod
     def _process_import_batch_async(cls, task_id, file_path, redis_key, batch_number):
-        """后台线程处理批量导入任务"""
+        """后台线程处理批量导入任务(适配新表结构)"""
 
         redis_obj = RedisObject()
 
@@ -234,9 +316,21 @@ class UIDBurnManageView(View):
             task_data['start_time'] = int(time.time())
             redis_obj.set_data(redis_key, json.dumps(task_data))
 
-            # 2. 分批处理UID数据(每批500条)
-            batch_size = 500
+            # 2. 创建批次记录
             current_time = int(time.time())
+            with transaction.atomic():
+                batch = BurnBatch(
+                    batch_number=batch_number,
+                    purpose='批次导入',
+                    created_time=current_time,
+                    manager='system',  # 默认系统导入
+                    total_uid=0  # 初始为0,处理完成后更新
+                )
+                batch.save()
+                batch_id = batch.id
+
+            # 3. 分批处理UID数据(每批500条)
+            batch_size = 500
             processed = 0
             success_count = 0
             uids_batch = []
@@ -260,7 +354,7 @@ class UIDBurnManageView(View):
                         if len(uids_batch) >= batch_size:
                             success = cls._import_uids_batch(
                                 uids_batch,
-                                batch_number,
+                                batch_id,
                                 current_time,
                                 redis_key
                             )
@@ -271,12 +365,16 @@ class UIDBurnManageView(View):
             if uids_batch:
                 success = cls._import_uids_batch(
                     uids_batch,
-                    batch_number,
+                    batch_id,
                     current_time,
                     redis_key
                 )
                 success_count += success
 
+            # 更新批次总UID数
+            with transaction.atomic():
+                BurnBatch.objects.filter(id=batch_id).update(total_uid=success_count)
+
             # 更新最终状态
             task_data['status'] = 'completed'
             task_data['progress'] = 100
@@ -303,8 +401,8 @@ class UIDBurnManageView(View):
             redis_obj.set_data(redis_key, json.dumps(task_data))
 
     @classmethod
-    def _import_uids_batch(cls, uids_batch, batch_number, current_time, redis_key):
-        """批量导入UID记录"""
+    def _import_uids_batch(cls, uids_batch, batch_id, current_time, redis_key):
+        """批量导入UID记录(适配新表结构)"""
 
         redis_obj = RedisObject()
 
@@ -316,9 +414,8 @@ class UIDBurnManageView(View):
                 # 创建记录
                 records = [
                     BurnEncryptedICUID(
-                        batch_number=batch_number,
+                        batch_id=batch_id,
                         uid=uid,
-                        purpose='批次导入',
                         created_time=current_time,
                         updated_time=current_time,
                         status=0  # 未烧录状态
@@ -333,6 +430,10 @@ class UIDBurnManageView(View):
                 task_data['success_count'] = task_data.get('success_count', 0) + len(records)
                 redis_obj.set_data(redis_key, json.dumps(task_data))
 
+                # 清除批次统计缓存
+                cache_key = f"batch_stats:{batch_id}"
+                redis_obj.del_data(cache_key)
+
                 return len(records)
 
         except Exception as e:
@@ -344,7 +445,7 @@ class UIDBurnManageView(View):
             return 0
 
     @classmethod
-    def add_burn_record(cls, request,request_dict, response) -> Any:
+    def add_burn_record(cls, request, request_dict, response) -> Any:
         """
         新增烧录记录(带UID文件) - Redis字符串优化版
         :param request_dict:
@@ -500,6 +601,15 @@ class UIDBurnManageView(View):
             task_data['end_time'] = int(time.time())
             redis_obj.set_data(redis_key, json.dumps(task_data))
 
+            # 查询受影响的批次ID并清除缓存
+            batch_ids = BurnEncryptedICUID.objects.filter(
+                burn_id=burn_record.id
+            ).values_list('batch_id', flat=True).distinct()
+            
+            for batch_id in batch_ids:
+                cache_key = f"batch_stats:{batch_id}"
+                redis_obj.del_data(cache_key)
+
             LOGGER.info(f"处理烧录记录完成,任务ID: {task_id}, 处理UID数量: {processed}")
 
             # 清理临时文件
@@ -524,6 +634,11 @@ class UIDBurnManageView(View):
 
         try:
             with transaction.atomic():
+                # 先查询出受影响的批次ID
+                batch_ids = BurnEncryptedICUID.objects.filter(
+                    uid__in=uids_batch
+                ).values_list('batch_id', flat=True).distinct()
+
                 updated = BurnEncryptedICUID.objects.filter(
                     uid__in=uids_batch
                 ).update(
@@ -536,6 +651,11 @@ class UIDBurnManageView(View):
                 task_data['processed'] = task_data.get('processed', 0) + len(uids_batch)
                 redis_obj.set_data(redis_key, json.dumps(task_data))
 
+                # 清除受影响批次的统计缓存
+                for batch_id in batch_ids:
+                    cache_key = f"batch_stats:{batch_id}"
+                    redis_obj.del_data(cache_key)
+
         except Exception as e:
             LOGGER.error(f"批量更新UID失败: {str(e)}")
             raise
@@ -555,34 +675,34 @@ class UIDBurnManageView(View):
         task_id = request_dict.get('task_id')
         if not task_id:
             return response.json(444, "缺少task_id参数")
-            
+
         task_type = request_dict.get('type', 'import').lower()
         if task_type not in ['import', 'burn']:
             return response.json(444, "type参数必须是'import'或'burn'")
-            
+
         # 2. 构建Redis key
         redis_key = f"{task_type}_task:{task_id}"
-        
+
         try:
             # 3. 从Redis获取任务数据
             redis_obj = RedisObject()
             task_data_str = redis_obj.get_data(redis_key)
-            
+
             if not task_data_str:
                 return response.json(173, "任务不存在或已过期")
-                
+
             # 4. 解析任务数据
             if isinstance(task_data_str, bytes):
                 task_data_str = task_data_str.decode('utf-8')
             task_data = json.loads(task_data_str)
-            
+
             # 5. 计算耗时(秒)
             current_time = int(time.time())
             start_time = task_data.get('start_time', current_time)
             elapsed = current_time - start_time
             if task_data.get('end_time'):
                 elapsed = task_data['end_time'] - start_time
-                
+
             # 6. 构建基础响应数据
             result = {
                 'status': task_data.get('status', 'unknown'),
@@ -595,13 +715,33 @@ class UIDBurnManageView(View):
                 'error': task_data.get('error'),
                 'task_type': task_type
             }
-            
+
             # 7. 根据任务类型添加特定字段
             if task_type == 'import':
-                result.update({
-                    'batch_number': task_data.get('batch_number', ''),
-                    'success_count': task_data.get('success_count', 0)
-                })
+                # 从Redis获取批次号并查询批次信息
+                batch_number = task_data.get('batch_number', '')
+                if batch_number:
+                    try:
+                        batch = BurnBatch.objects.filter(batch_number=batch_number).first()
+                        if batch:
+                            result.update({
+                                'batch_number': batch_number,
+                                'success_count': task_data.get('success_count', 0),
+                                'purpose': batch.purpose,
+                                'manager': batch.manager,
+                                'total_uid': batch.total_uid
+                            })
+                        else:
+                            result.update({
+                                'batch_number': batch_number,
+                                'success_count': task_data.get('success_count', 0)
+                            })
+                    except Exception as e:
+                        LOGGER.error(f"查询批次信息失败: {str(e)}")
+                        result.update({
+                            'batch_number': batch_number,
+                            'success_count': task_data.get('success_count', 0)
+                        })
             else:  # burn task
                 result.update({
                     'order_number': task_data.get('order_number', ''),
@@ -609,9 +749,9 @@ class UIDBurnManageView(View):
                     'burn_count': task_data.get('burn_count', 0),
                     'burn_record_id': task_data.get('burn_record_id')
                 })
-                
+
             return response.json(0, result)
-            
+
         except json.JSONDecodeError:
             LOGGER.error(f"任务数据解析失败, redis_key: {redis_key}")
             return response.json(500, "任务数据格式错误")
@@ -677,24 +817,13 @@ class UIDBurnManageView(View):
             return response.json(500, "获取任务列表失败")
 
     @classmethod
-    def get_burn_uids_page(cls, request_dict: Dict[str, Any], response) -> Any:
+    def batch_page_uids(cls, request_dict: Dict[str, Any], response) -> Any:
         """
         根据burn_id分页查询烧录UID记录
         :param request_dict: 请求参数字典
         :param response: 响应对象
         :return: JSON响应
         """
-        # 1. 参数验证
-        burn_id = request_dict.get('burn_id')
-        if not burn_id:
-            return response.json(444, "缺少burn_id参数")
-
-        try:
-            burn_id = int(burn_id)
-        except ValueError:
-            return response.json(444, "burn_id必须是整数")
-
-        # 2. 分页参数处理
         try:
             page = int(request_dict.get('page', 1))
             page_size = int(request_dict.get('pageSize', 10))
@@ -703,9 +832,22 @@ class UIDBurnManageView(View):
         except (ValueError, TypeError):
             return response.json(444, "分页参数错误(必须为整数)")
 
-        # 3. 查询并分页
-        query = Q(burn_id=burn_id)
-        uid_qs = BurnEncryptedICUID.objects.filter(query).order_by('-created_time')
+        # 3. 构建查询条件
+        query = Q()
+        
+        # 添加batch_id筛选条件
+        batch_id = request_dict.get('batch_id')
+        if batch_id:
+            try:
+                batch_id = int(batch_id)
+                query &= Q(batch_id=batch_id)
+            except ValueError:
+                return response.json(444, "batch_id必须是整数")
+
+        # 4. 查询并分页
+        uid_qs = BurnEncryptedICUID.objects.filter(query).order_by('-created_time').values(
+            'id', 'uid', 'batch_id', 'status', 'created_time', 'updated_time'
+        )
 
         paginator = Paginator(uid_qs, page_size)
         try:
@@ -715,11 +857,8 @@ class UIDBurnManageView(View):
         except EmptyPage:
             page_obj = paginator.page(paginator.num_pages)
 
-        uid_list = serializers.serialize(
-            'python',
-            page_obj,
-            fields=['id', 'uid', 'batch_number', 'status', 'created_time', 'updated_time']
-        )
+        # 转换为列表
+        uid_list = list(page_obj)
 
         return response.json(
             0,

+ 1 - 0
AgentModel/models.py

@@ -253,6 +253,7 @@ class BurnBatch(models.Model):
 class BurnEncryptedICUID(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='自增标记ID')
     batch_id  = models.IntegerField(default=0, verbose_name='UID批次ID')
+    burn_id = models.IntegerField(default=0, verbose_name='烧录记录ID')
     uid = models.CharField(default='', db_index=True, max_length=32, verbose_name='设备UID')
     status = models.IntegerField(default=0, verbose_name='0:已下载,1:烧录成功,2:失败')
     created_time = models.IntegerField(default=0, verbose_name='创建时间')