diff --git a/backend/dvadmin/utils/filters.py b/backend/dvadmin/utils/filters.py index 13ab42f..72915a8 100644 --- a/backend/dvadmin/utils/filters.py +++ b/backend/dvadmin/utils/filters.py @@ -14,13 +14,14 @@ from functools import reduce import six from django.db.models import Q, F from django.db.models.constants import LOOKUP_SEP -from django_filters import utils -from django_filters.filters import CharFilter +from django_filters import utils, FilterSet +from django_filters.filters import CharFilter, DateTimeFromToRangeFilter from django_filters.rest_framework import DjangoFilterBackend from django_filters.utils import get_model_field from rest_framework.filters import BaseFilterBackend from dvadmin.system.models import Dept, ApiWhiteList, RoleMenuButtonPermission +from dvadmin.utils.models import CoreModel def get_dept(dept_id: int, dept_all_list=None, dept_list=None): diff --git a/backend/dvadmin/utils/viewset.py b/backend/dvadmin/utils/viewset.py index a20b9be..b95dc09 100644 --- a/backend/dvadmin/utils/viewset.py +++ b/backend/dvadmin/utils/viewset.py @@ -7,6 +7,8 @@ @Remark: 自定义视图集 """ from django.db import transaction +from django_filters import DateTimeFromToRangeFilter +from django_filters.rest_framework import FilterSet from drf_yasg import openapi from drf_yasg.utils import swagger_auto_schema from rest_framework.decorators import action @@ -16,11 +18,23 @@ from dvadmin.utils.filters import DataLevelPermissionsFilter from dvadmin.utils.import_export_mixin import ExportSerializerMixin, ImportSerializerMixin from dvadmin.utils.json_response import SuccessResponse, ErrorResponse, DetailResponse from dvadmin.utils.permission import CustomPermission -from dvadmin.utils.models import get_custom_app_models +from dvadmin.utils.models import get_custom_app_models, CoreModel from dvadmin.system.models import FieldPermission, MenuField from django_restql.mixins import QueryArgumentsMixin +class CoreModelFliterSet(FilterSet): + """ + 封装一个时间范围过滤器: + 使用方式: + {'create_datetime_after': '2024-01-01 8:00', 'create_datetime_before': '2024-01-05 10:00'} + """ + create_datetime = DateTimeFromToRangeFilter() + update_datetime = DateTimeFromToRangeFilter() + class Meta: + model = None + fields = "__all__" + class CustomModelViewSet(ModelViewSet, ImportSerializerMixin, ExportSerializerMixin, QueryArgumentsMixin): """ 自定义的ModelViewSet: @@ -38,6 +52,7 @@ class CustomModelViewSet(ModelViewSet, ImportSerializerMixin, ExportSerializerMi filter_fields = '__all__' search_fields = () extra_filter_class = [DataLevelPermissionsFilter] + filterset_class = CoreModelFliterSet permission_classes = [CustomPermission] import_field_dict = {} export_field_label = {} diff --git a/web/src/utils/commonCrud.ts b/web/src/utils/commonCrud.ts index dd977b8..426f6af 100644 --- a/web/src/utils/commonCrud.ts +++ b/web/src/utils/commonCrud.ts @@ -1,6 +1,7 @@ -import { dict } from "@fast-crud/fast-crud"; +import {dict} from "@fast-crud/fast-crud"; import {shallowRef} from 'vue' import deptFormat from "/@/components/dept-format/index.vue"; + export const commonCrudConfig = (options = { create_datetime: { form: false, @@ -51,7 +52,7 @@ export const commonCrudConfig = (options = { align: 'center', width: 300, show: options.dept_belong_id?.table || false, - component:{ + component: { name: shallowRef(deptFormat), vModel: "modelValue", } @@ -62,7 +63,7 @@ export const commonCrudConfig = (options = { multiple: false, clearable: true, props: { - checkStrictly:true, + checkStrictly: true, props: { // 为什么这里要写两层props // 因为props属性名与fs的动态渲染的props命名冲突,所以要多写一层 @@ -132,7 +133,53 @@ export const commonCrudConfig = (options = { title: '更新时间', type: 'datetime', search: { - show: options.update_datetime?.search || false + show: options.update_datetime?.search || false, + col: {span: 8}, + component: { + type: 'datetimerange', + props: { + 'start-placeholder': '开始时间', + 'end-placeholder': '结束时间', + 'value-format': 'YYYY-MM-DD HH:mm:ss', + 'picker-options': { + shortcuts: [{ + text: '最近一周', + onClick(picker) { + const end = new Date(); + const start = new Date(); + start.setTime(start.getTime() - 3600 * 1000 * 24 * 7); + picker.$emit('pick', [start, end]); + } + }, { + text: '最近一个月', + onClick(picker) { + const end = new Date(); + const start = new Date(); + start.setTime(start.getTime() - 3600 * 1000 * 24 * 30); + picker.$emit('pick', [start, end]); + } + }, { + text: '最近三个月', + onClick(picker) { + const end = new Date(); + const start = new Date(); + start.setTime(start.getTime() - 3600 * 1000 * 24 * 90); + picker.$emit('pick', [start, end]); + } + }] + } + } + }, + valueResolve(context: any) { + const {key, value} = context + //value解析,就是把组件的值转化为后台所需要的值 + //在form表单点击保存按钮后,提交到后台之前执行转化 + if (value) { + context.form.update_datetime_after = value[0] + context.form.update_datetime_before = value[1] + } + // ↑↑↑↑↑ 注意这里是form,不是row + } }, column: { width: 160, @@ -149,14 +196,60 @@ export const commonCrudConfig = (options = { title: '创建时间', type: 'datetime', search: { - show: options.create_datetime?.search || false + show: options.create_datetime?.search || false, + col: {span: 8}, + component: { + type: 'datetimerange', + props: { + 'start-placeholder': '开始时间', + 'end-placeholder': '结束时间', + 'value-format': 'YYYY-MM-DD HH:mm:ss', + 'picker-options': { + shortcuts: [{ + text: '最近一周', + onClick(picker) { + const end = new Date(); + const start = new Date(); + start.setTime(start.getTime() - 3600 * 1000 * 24 * 7); + picker.$emit('pick', [start, end]); + } + }, { + text: '最近一个月', + onClick(picker) { + const end = new Date(); + const start = new Date(); + start.setTime(start.getTime() - 3600 * 1000 * 24 * 30); + picker.$emit('pick', [start, end]); + } + }, { + text: '最近三个月', + onClick(picker) { + const end = new Date(); + const start = new Date(); + start.setTime(start.getTime() - 3600 * 1000 * 24 * 90); + picker.$emit('pick', [start, end]); + } + }] + } + } + }, + valueResolve(context: any) { + const {key, value} = context + //value解析,就是把组件的值转化为后台所需要的值 + //在form表单点击保存按钮后,提交到后台之前执行转化 + if (value) { + context.form.create_datetime_after = value[0] + context.form.create_datetime_before = value[1] + } + // ↑↑↑↑↑ 注意这里是form,不是row + } }, column: { width: 160, show: options.create_datetime?.table || false, }, form: { - show: false, + show: false }, viewForm: { show: true diff --git a/web/src/views/system/log/loginLog/crud.tsx b/web/src/views/system/log/loginLog/crud.tsx index e8a50be..a3fd92c 100644 --- a/web/src/views/system/log/loginLog/crud.tsx +++ b/web/src/views/system/log/loginLog/crud.tsx @@ -1,5 +1,6 @@ import * as api from './api'; import { UserPageQuery, AddReq, DelReq, EditReq, CreateCrudOptionsProps, CreateCrudOptionsRet, dict } from '@fast-crud/fast-crud'; +import {commonCrudConfig} from "/@/utils/commonCrud"; export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet { const pageRequest = async (query: UserPageQuery) => { @@ -325,6 +326,11 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp }, }, }, + ...commonCrudConfig({ + create_datetime: { + search: true + } + }) }, }, };