Răsfoiți Sursa

优化电量统计趋势列表

zhangdongming 2 luni în urmă
părinte
comite
b6b341775b
1 a modificat fișierele cu 31 adăugiri și 22 ștergeri
  1. 31 22
      Controller/UserDevice/DeviceReportController.py

+ 31 - 22
Controller/UserDevice/DeviceReportController.py

@@ -134,51 +134,60 @@ class DeviceReportView(View):
             device_id = request_dict.get('device_id')
             if not device_id:
                 return response.json(444, "设备ID不能为空")
-            tz_offset = float(request_dict.get('tz', 0))  # 允许小数时区如5.5
+
+            tz_offset = float(request_dict.get('tz', 0))
             if not (-12 <= tz_offset <= 14):
-                raise ValueError
-            tz = pytz.FixedOffset(int(tz_offset * 60))  # 转换为分钟偏移
+                raise ValueError("时区偏移超出范围")
+            tz = pytz.FixedOffset(int(tz_offset * 60))
 
-            # 计算日期范围(关键修改:end_time取昨日23:59:59)
+            # 计算日期范围:查询的是客户端时区下的历史数据
             query_days = int(request_dict.get('days', 7))
             client_now = datetime.now(tz)
-            end_time = client_now.replace(
-                hour=23, minute=59, second=59
-            ) - timedelta(days=1)  # 截止到客户端昨日
 
-            start_time = end_time - timedelta(days=query_days - 1)
-            start_time = start_time.replace(hour=0, minute=0, second=0)
+            # 关键修改:数据日期范围 = [今天 - query_days, 昨天]
+            # 因为设备上报的是前一天的数据
+            end_date = (client_now - timedelta(days=1)).date()  # 昨天
+            start_date = end_date - timedelta(days=query_days - 1)  # 起始日期
+
+            # 转换查询范围到UTC时间戳 (包含整个日期范围)
+            start_utc = int(tz.localize(
+                datetime.combine(start_date, datetime.min.time())
+            ).astimezone(pytz.utc).timestamp())
 
-            # 转换时间范围到UTC时间戳
-            start_utc_timestamp = int(start_time.astimezone(pytz.utc).timestamp())
-            end_utc_timestamp = int(end_time.astimezone(pytz.utc).timestamp())
+            end_utc = int(tz.localize(
+                datetime.combine(end_date + timedelta(days=1), datetime.min.time())
+            ).astimezone(pytz.utc).timestamp())
 
             # 查询数据库
             records = DeviceDailyReport.objects.filter(
                 device_id=device_id,
                 type=1,
-                report_time__gte=start_utc_timestamp,
-                report_time__lte=end_utc_timestamp
+                report_time__gte=start_utc,
+                report_time__lt=end_utc  # 不包含结束时间戳
             ).order_by('report_time')
 
-            # 构建日期-电量映射(按客户端时区)
+            # 构建日期-电量映射 (按数据实际归属的日期)
             date_battery_map = {}
             for record in records:
-                local_date = datetime.fromtimestamp(record.report_time, tz).date()
-                date_str = local_date.strftime("%Y-%m-%d")
-                date_battery_map[date_str] = record.battery_level
+                # 关键修改:上报时间转客户端时区后减去1天 = 数据实际归属日期
+                record_date = datetime.fromtimestamp(record.report_time, tz).date()
+                data_date = record_date - timedelta(days=1)  # 数据属于前一天
+
+                # 只记录查询范围内的数据
+                if start_date <= data_date <= end_date:
+                    date_battery_map[data_date.isoformat()] = record.battery_level
 
-            # 生成完整日期序列
+            # 生成完整日期序列 (按客户端时区)
             report_data = []
             for day_offset in range(query_days):
-                current_date = (end_time.date() - timedelta(days=query_days - 1 - day_offset))
+                current_date = start_date + timedelta(days=day_offset)
                 report_data.append({
                     "index": current_date.day - 1,  # 日期下标从0开始
-                    "battery": date_battery_map.get(current_date.strftime("%Y-%m-%d"), 0),
+                    "battery": date_battery_map.get(current_date.isoformat(), 0),
                     "time": current_date.strftime("%Y-%m-%d")
                 })
 
             return response.json(0, report_data)
         except Exception as e:
-            LOGGER.error('查询设备电量上报列表异常error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            LOGGER.error(f'查询设备电量上报列表异常: {e}')
             return response.json(0, {})