diff --git a/api_v1/views/printing/test_plate_order_api.py b/api_v1/views/printing/test_plate_order_api.py index da58408..f3e5924 100644 --- a/api_v1/views/printing/test_plate_order_api.py +++ b/api_v1/views/printing/test_plate_order_api.py @@ -531,6 +531,110 @@ class PlateOrderAPITestCase(TestCase): else: self.assertEqual(len(response.data), 1) self.assertEqual(response.data[0]['is_invalid'], False) + + def test_filter_by_plate_at_from(self): + """测试按开版时间起始筛选(带时分秒)""" + from django.utils import timezone + from datetime import timedelta + from urllib.parse import quote + + now = timezone.now() + # 创建两个订单,分别在不同时间点 + order1 = printing_models.PlateOrder.objects.create( + customer=self.customer, + design_code='DESIGN001', + plate_type='圆网', + plate_date=now - timedelta(hours=2), + ) + order2 = printing_models.PlateOrder.objects.create( + customer=self.customer, + design_code='DESIGN002', + plate_type='平网', + plate_date=now, + ) + + # 筛选 1 小时前之后的订单(应该只返回 order2) + one_hour_ago = quote((now - timedelta(hours=1)).isoformat()) + response = self.client.get(f'/api/v1/plate-orders/?plate_at_from={one_hour_ago}') + self.assertEqual(response.status_code, status.HTTP_200_OK) + if isinstance(response.data, dict): + ids = [r['id'] for r in response.data['results']] + else: + ids = [r['id'] for r in response.data] + self.assertIn(order2.id, ids) + self.assertNotIn(order1.id, ids) + + def test_filter_by_plate_at_to(self): + """测试按开版时间结束筛选(带时分秒)""" + from django.utils import timezone + from datetime import timedelta + from urllib.parse import quote + + now = timezone.now() + # 创建两个订单,分别在不同时间点 + order1 = printing_models.PlateOrder.objects.create( + customer=self.customer, + design_code='DESIGN001', + plate_type='圆网', + plate_date=now - timedelta(hours=2), + ) + order2 = printing_models.PlateOrder.objects.create( + customer=self.customer, + design_code='DESIGN002', + plate_type='平网', + plate_date=now, + ) + + # 筛选 1 小时前之前的订单(应该只返回 order1) + one_hour_ago = quote((now - timedelta(hours=1)).isoformat()) + response = self.client.get(f'/api/v1/plate-orders/?plate_at_to={one_hour_ago}') + self.assertEqual(response.status_code, status.HTTP_200_OK) + if isinstance(response.data, dict): + ids = [r['id'] for r in response.data['results']] + else: + ids = [r['id'] for r in response.data] + self.assertIn(order1.id, ids) + self.assertNotIn(order2.id, ids) + + def test_filter_by_plate_at_range(self): + """测试按开版时间范围筛选(带时分秒)""" + from django.utils import timezone + from datetime import timedelta + from urllib.parse import quote + + now = timezone.now() + # 创建三个订单,分别在不同时间点 + order1 = printing_models.PlateOrder.objects.create( + customer=self.customer, + design_code='DESIGN001', + plate_type='圆网', + plate_date=now - timedelta(hours=3), + ) + order2 = printing_models.PlateOrder.objects.create( + customer=self.customer, + design_code='DESIGN002', + plate_type='平网', + plate_date=now - timedelta(hours=1), + ) + order3 = printing_models.PlateOrder.objects.create( + customer=self.customer, + design_code='DESIGN003', + plate_type='圆网', + plate_date=now + timedelta(hours=1), + ) + + # 筛选 2 小时前到现在之间的订单(应该只返回 order2) + two_hours_ago = quote((now - timedelta(hours=2)).isoformat()) + now_iso = quote(now.isoformat()) + response = self.client.get(f'/api/v1/plate-orders/?plate_at_from={two_hours_ago}&plate_at_to={now_iso}') + self.assertEqual(response.status_code, status.HTTP_200_OK) + if isinstance(response.data, dict): + ids = [r['id'] for r in response.data['results']] + else: + ids = [r['id'] for r in response.data] + self.assertIn(order2.id, ids) + self.assertNotIn(order1.id, ids) + self.assertNotIn(order3.id, ids) def test_search_by_design_code(self): """测试按设计编号搜索""" diff --git a/api_v1/views/printing/views.py b/api_v1/views/printing/views.py index 706b5ef..5f67e21 100644 --- a/api_v1/views/printing/views.py +++ b/api_v1/views/printing/views.py @@ -564,6 +564,9 @@ class PlateOrderFilterSet(django_filters.FilterSet): style_name = django_filters.CharFilter(lookup_expr='icontains') plate_date_from = django_filters.DateFilter(field_name='plate_date', lookup_expr='gte') plate_date_to = django_filters.DateFilter(field_name='plate_date', method='filter_plate_date_to') + # plate_at_from / plate_at_to: 支持带时分秒的精确时间筛选(ISO 8601 格式) + plate_at_from = IsoDateTimeFilter(field_name='plate_date', lookup_expr='gte') + plate_at_to = IsoDateTimeFilter(field_name='plate_date', lookup_expr='lte') required_completion_date_from = IsoDateTimeFilter(field_name='required_completion_date', lookup_expr='gte') required_completion_date_to = IsoDateTimeFilter(field_name='required_completion_date', lookup_expr='lte') created_date_from = django_filters.DateFilter(field_name='created_at', lookup_expr='gte') @@ -643,8 +646,10 @@ class PlateOrderViewSet(LimitedModelViewSet): - is_mark_frame: 是否打样架(true/false) - fabric: 面料(模糊查询) - style_name: 款式名称(模糊查询) - - plate_date_from: 开版日期起始 - - plate_date_to: 开版日期结束 + - plate_date_from: 开版日期起始(仅日期) + - plate_date_to: 开版日期结束(仅日期,包含整天) + - plate_at_from: 开版时间起始(ISO 8601 格式,含时分秒,如 2024-01-01T08:00:00) + - plate_at_to: 开版时间结束(ISO 8601 格式,含时分秒) - required_completion_date_from: 要求完成时间起始(含时分秒) - required_completion_date_to: 要求完成时间结束 - created_date_from: 创建日期起始