diff --git a/backend/dvadmin/utils/filters.py b/backend/dvadmin/utils/filters.py index f61fc62ed214d878693ee6f936b07209e331b101..174697bbe7477436469eb15aedb165f553b9ae74 100644 --- a/backend/dvadmin/utils/filters.py +++ b/backend/dvadmin/utils/filters.py @@ -25,35 +25,84 @@ from django_filters.conf import settings from dvadmin.system.models import Dept, ApiWhiteList, RoleMenuButtonPermission, MenuButton from dvadmin.utils.models import CoreModel + +def auto_parse_datetime(time_str): + """ + 自动解析日期/时间字符串,返回datetime.date或datetime.datetime对象 + """ + + # 尝试解析完整时间格式(包含时分秒) + try: + # 去掉时区信息 + dt = datetime.fromisoformat(time_str).replace(tzinfo=None) + return dt # 直接返回datetime对象 + except ValueError: + pass + + # 尝试解析纯日期格式 + try: + dt = date.fromisoformat(time_str) + return dt # 返回date对象 + except ValueError: + pass + + # 尝试解析纯时间格式 + try: + dt = time.fromisoformat(time_str) + return dt # 返回date对象 + except ValueError: + pass + + # 如果所有尝试失败 + raise ValueError(f"无法识别的日期格式: {time_str}") + + class CoreModelFilterBankend(BaseFilterBackend): """ 自定义时间范围过滤器 """ def filter_queryset(self, request, queryset, view): - create_datetime_after = request.query_params.get('create_datetime_after', None) - create_datetime_before = request.query_params.get('create_datetime_before', None) - update_datetime_after = request.query_params.get('update_datetime_after', None) - update_datetime_before = request.query_params.get('update_datetime_before', None) - if any([create_datetime_after, create_datetime_before, update_datetime_after, update_datetime_before]): - create_filter = Q() - if create_datetime_after and create_datetime_before: - create_filter &= Q(create_datetime__gte=create_datetime_after) & Q(create_datetime__lte=f'{create_datetime_before} 23:59:59') - elif create_datetime_after: - create_filter &= Q(create_datetime__gte=create_datetime_after) - elif create_datetime_before: - create_filter &= Q(create_datetime__lte=f'{create_datetime_before} 23:59:59') - - # 更新时间范围过滤条件 - update_filter = Q() - if update_datetime_after and update_datetime_before: - update_filter &= Q(update_datetime__gte=update_datetime_after) & Q(update_datetime__lte=update_datetime_before) - elif update_datetime_after: - update_filter &= Q(update_datetime__gte=update_datetime_after) - elif update_datetime_before: - update_filter &= Q(update_datetime__lte=update_datetime_before) - # 结合两个时间范围过滤条件 - queryset = queryset.filter(create_filter & update_filter) - return queryset + tmp_keys = list(request.query_params.keys()) + datetime_params = [] + for key, value in list(request.query_params.items()): + if key.endswith('_after'): + param_key = key.replace("_after", "") + before_key = f"{param_key}_before" + if before_key in tmp_keys: + # 有before参数, 处理日期格式,如果before 没有时间参数则自动补全为23:59:59 + before_time = auto_parse_datetime(request.query_params[before_key]) + if type(before_time) == date: + before_time = datetime(before_time.year, before_time.month, before_time.day, 23, 59, 59, 999999) + + datetime_params.append((param_key, auto_parse_datetime(value), before_time)) + # 防止触发仅before过滤器 + tmp_keys.remove(before_key) + else: + # 没有before参数 + datetime_params.append((param_key, auto_parse_datetime(value), None)) + + elif key.endswith('_before') and key in tmp_keys: + # 没有after参数 + param_key = key.replace("_before", "") + + # 处理日期格式,如果before 没有时间参数则自动补全为23:59:59 + before_time = auto_parse_datetime(request.query_params[param_key]) + if type(before_time) == date: + before_time = datetime(before_time.year, before_time.month, before_time.day, 23, 59, 59, 999999) + + datetime_params.append((param_key, None, before_time)) + + if datetime_params: + + datetime_filter = Q() + for key, after_value, before_value in datetime_params: + if after_value: + datetime_filter &= eval(f"Q({key}__gte=after_value)") + if before_value: + datetime_filter &= eval(f"Q({key}__lte=before_value)") + + queryset = queryset.filter(datetime_filter) + return queryset def get_dept(dept_id: int, dept_all_list=None, dept_list=None):