Browse Source

首页通过分组查询设备、优化分组设备数量统计

zhangdongming 3 weeks ago
parent
commit
dbc5386975

+ 29 - 17
Controller/DeviceManagement/DeviceGroupController.py

@@ -2,9 +2,10 @@
 # @File      : DeviceGroupController.py
 # @Time      : 2025/1/22 9:51
 from django.db import transaction
+from django.db.models import Count
 from django.db.models import Q
 from django.views import View
-from django.db.models import Count, Sum
+
 from Model.models import DeviceGroup, Device_Info
 from Service.CommonService import CommonService
 
@@ -44,28 +45,39 @@ class DeviceGroupView(View):
     @staticmethod
     def query_group_quantity(request_dict, user_id, response):
         """
-        查询分组数量
+        查询分组数量(优化版:减少数据库查询次数,提升性能)
         @param request_dict: 请求参数
         @param user_id: 用户ID
         @param response: 响应对象
-        @return: res 包含分组信息和设备总数的响应
+        @return: 包含分组信息和设备总数的响应
         """
 
-        # 一次查询获取所有分组及对应的设备数量
-        device_group_qs = DeviceGroup.objects.filter(user_id=user_id) \
-            .annotate(device_quantity=Count('device_info', distinct=True)) \
-            .values('id', 'group_name', 'device_quantity')
-
-        # 计算设备总数
-        total_result = device_group_qs.aggregate(total=Sum('device_quantity'))
-        device_total = total_result['total'] or 0  # 处理没有分组的情况
-
-        res = {
+        # 1. 一次查询获取所有分组ID和名称(仅1次数据库查询)
+        device_groups = list(DeviceGroup.objects.filter(user_id=user_id).values('id', 'group_name'))
+        if not device_groups:
+            return response.json(0, {'total': 0, 'device_groups': []})
+
+        # 2. 提取所有分组ID,批量查询设备数量(仅1次数据库查询)
+        group_ids = [group['id'] for group in device_groups]
+        device_counts = dict(
+            Device_Info.objects.filter(device_group_id__in=group_ids)
+            .values('device_group_id')
+            .annotate(count=Count('id'))  # 聚合计算每个分组的设备数
+            .values_list('device_group_id', 'count')  # 转换为(id, count)格式
+        )
+
+        # 3. 内存中组装数据(无额外数据库查询)
+        device_total = 0
+        for group in device_groups:
+            # 从字典中获取数量,默认0(避免不存在的分组ID报错)
+            count = device_counts.get(group['id'], 0)
+            group['device_quantity'] = count
+            device_total += count
+
+        return response.json(0, {
             'total': device_total,
-            'device_groups': list(device_group_qs)  # 直接转换为列表
-        }
-
-        return response.json(0, res)
+            'device_groups': device_groups
+        })
 
     @staticmethod
     def query_group_device(request_dict, user_id, response):

+ 2 - 1
Controller/EquipmentManagerV3.py

@@ -823,8 +823,9 @@ class EquipmentManagerV3(View):
         if tko.code != 0:
             return response.json(tko.code)
         userID = tko.userID
+        group_id = int(request_dict.get('groupId', 0))
         # 查询设备列表以及设备uid集合
-        dv_list, uid_list = UserDeviceService.query_device_list(userID, uid, NickName, page, line)
+        dv_list, uid_list = UserDeviceService.query_device_list(userID, uid, NickName, page, line, group_id)
         ub_qs = UserDeviceService.query_device_uid_bucket(uid_list)  # 根据uid集合查询云存套餐
         up_qs = UserDeviceService.query_device_preview(uid_list)  # 根据uid集合查询设备预览图
         auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)

+ 3 - 1
Service/UserDeviceService.py

@@ -20,7 +20,7 @@ LOGGER = logging.getLogger('info')
 class UserDeviceService:
 
     @classmethod
-    def query_device_list(cls, user_id, uid, nickname, page, line):
+    def query_device_list(cls, user_id, uid, nickname, page, line, group_id=0):
         """
         查询设备列表
         @param user_id: 用户user_id
@@ -37,6 +37,8 @@ class UserDeviceService:
             dv_qs = dv_qs.filter(NickName=nickname)
         if uid:
             dv_qs = dv_qs.filter(UID=uid)
+        if group_id > 0:
+            dv_qs = dv_qs.filter(device_group_id=group_id)
         # 周视首页过滤网关以及插座类型
         dv_qs = dv_qs.exclude(Type__in=[200, 201])
         dv_qs = dv_qs.values('id', 'userID', 'NickName', 'UID', 'View_Account', 'View_Password', 'ChannelIndex',