抽离ant-design后台的公共查询设置

公司后台使用 antd 搭建,查询的大部分页面有相同的查询条件,于是想抽出公共部分查询条件配置,省的一通复制

以上是系统常用的通用条件。

逻辑每次会有微妙区别

说下各项的关系:

  • 学校决定部门
  • 年级依赖学校和部门 或者 学校和学段
  • 年级和科目默认是多选

说说逻辑:

经过和产品沟通,如果有全部选项,直接去掉全部选项,没传值就是全部。

  • 设置各个查询条件默认的column配置
  • 针对微小的变化,可以传入override参数,覆盖默认的配置
  • 年级依赖的字段,可以通过isOnDeptForGrade参数来决定是否依赖部门还是依赖学段

使用:

tsx 复制代码
import useBaseColumns from '@/hooks/useBaseColumns';
const { formRef, schoolIdColumn, deptCodeColumn, gradeCodesColumn } = useBaseColumns();
// formRef一定在proTable上 <ProTable formRef={formRef} />


// 有自定义配置的话,如果年级依赖学段设置isOnDeptForGrade,如果想覆盖默认column配置,可以传入overrides参数
const {formRef, schoolIdColumn, ...} = useBaseColumns({
  isOnDeptForGrade: false, // true是开启部门年级联动,false是开启学段年级联动
  overrides: {
    schoolIdConfig: { title: '自定义学校' },
    gradeCodesConfig: { dataIndex: 'gradeCodeList' },
  },
});

代码实现:

tsx 复制代码
// 导入React的useRef Hook和各类数据获取方法
import {
  getDeptList,
  getGradeListByDeptAndSchool,
  getGradeListByStageAndSchool,
  getSchoolList,
  getStageList,
  getSubjectList, // 获取科目列表
} from '@/services/getColumnsData';
import { useRef } from 'react';

// 定义参数类型
type IParams = {
  isOnDeptForGrade?: boolean; // 是否开启部门与年级联动(默认true)
  overrides?: {
    // 各字段的覆盖配置
    schoolIdConfig?: any; // 学校配置覆盖
    stageCodeConfig?: any; // 学段配置覆盖
    deptCodeConfig?: any; // 部门配置覆盖
    gradeCodesConfig?: any; // 年级配置覆盖
    subjectCodesConfig?: any; // 科目配置覆盖
  };
};

// 定义返回类型
type IUseBaseColumns = {
  formRef: any; // 表单ref引用
  schoolIdColumn: any; // 学校列配置
  deptCodeColumn: any; // 部门列配置
  stageCodeColumn: any; // 学段列配置
  gradeCodesColumn: any; // 年级列配置
  subjectCodesColumn: any; // 科目列配置
};
/**
 * 基础表单列配置生成Hook
 * 
 * 该Hook用于生成包含学校、学段、部门、年级、科目和时间等字段的表单配置,
 * 支持字段间的联动逻辑(如学校变更重置部门/学段/年级等)
 *  * @example
 * // 基本用法
 * import useBaseColumns from '@/hooks/useBaseColumns';
 * const { formRef, schoolIdColumn } = useBaseColumns();
 * // formRef一定在proTable上 <ProTable formRef={formRef} />
 * 
 * // 自定义配置,如果年级依赖学段设置isOnDeptForGrade,如果想覆盖默认column配置,可以传入overrides参数
 * const columns = useBaseColumns({
 *   isOnDeptForGrade: false, // true是开启部门年级联动,false是开启学段年级联动
 *   overrides: {
 *     schoolIdConfig: { title: '自定义学校' },
 *     gradeCodesConfig: { dataIndex: 'gradeCodeList' }, 
 *   }
 * });
 * 
 * @param {Object} params - 配置参数
 * @param {boolean} [params.isOnDeptForGrade=true] - 是否开启部门与年级联动模式
 *        true: 年级基于部门获取 | false: 年级基于学段获取
 * @param {Object} [params.overrides] - 各字段配置覆盖
 * @param {Object} [params.overrides.schoolIdConfig] - 学校字段配置覆盖
 * @param {Object} [params.overrides.stageCodeConfig] - 学段字段配置覆盖
 * @param {Object} [params.overrides.deptCodeConfig] - 部门字段配置覆盖
 * @param {Object} [params.overrides.gradeCodesConfig] - 年级字段配置覆盖
 * @param {Object} [params.overrides.subjectCodesConfig] - 科目字段配置覆盖
 * 
 * @returns {Object} 返回包含表单配置的对象
 * @property {React.RefObject} formRef - 表单引用,可用于操作表单实例
 * @property {Object} schoolIdColumn - 学校字段配置
 * @property {Object} deptCodeColumn - 部门字段配置
 * @property {Object} stageCodeColumn - 学段字段配置
 * @property {Object} gradeCodesColumn - 年级字段配置
 * @property {Object} subjectCodesColumn - 科目字段配置
 * 

 */
export function useBaseColumns({
  isOnDeptForGrade = true, // 默认开启部门年级联动
  overrides = {
    // 默认空配置覆盖
    schoolIdConfig: {},
    stageCodeConfig: {},
    deptCodeConfig: {},
    gradeCodesConfig: {},
    subjectCodesConfig: {},
    dateConfig: {},
  },
}: IParams = {}): IUseBaseColumns {
  // 使用useRef创建表单引用,用于后续操作表单
  const formRef = useRef<any>(null);

  // 解构覆盖配置
  const {
    schoolIdConfig,
    stageCodeConfig,
    deptCodeConfig,
    gradeCodesConfig,
    subjectCodesConfig,
    dateConfig,
  } = overrides;

  // 初始化各字段默认值,允许通过overrides覆盖
  const initialValue = {
    schoolId: schoolIdConfig?.initialValue ?? null,
    stageCode: stageCodeConfig?.initialValue ?? null,
    deptCode: deptCodeConfig?.initialValue ?? null,
    gradeCodes: gradeCodesConfig?.initialValue ?? [],
    subjectCodes: subjectCodesConfig?.initialValue ?? [],
  };

  // 定义各字段的dataIndex,允许通过overrides覆盖
  const dataIndex = {
    schoolId: schoolIdConfig?.dataIndex || 'schoolId',
    stageCode: stageCodeConfig?.dataIndex || 'stageCode',
    deptCode: deptCodeConfig?.dataIndex || 'deptCode',
    gradeCodes: gradeCodesConfig?.dataIndex || 'gradeCodes',
    subjectCodes: subjectCodesConfig?.dataIndex || 'subjectCodes',
  };

  /* 学校列配置 */
  const schoolIdColumn = {
    title: '学校',
    dataIndex: dataIndex.schoolId,
    hideInTable: true, // 不在表格中显示
    valueType: 'select', // 表单类型为下拉选择
    fieldProps: {
      showSearch: true, // 开启搜索功能
      onChange: (value: number) => {
        // 学校变更时重置部门、学段和年级
        formRef.current?.setFieldValue(
          dataIndex.deptCode,
          initialValue.deptCode,
        );
        formRef.current?.setFieldValue(
          dataIndex.stageCode,
          initialValue.stageCode,
        );
        formRef.current?.setFieldValue(
          dataIndex.gradeCodes,
          initialValue.gradeCodes,
        );
      },
    },
    request: getSchoolList, // 获取学校列表的方法
    initialValue: initialValue.schoolId,
    ...schoolIdConfig, // 合并覆盖配置
  };

  /* 学段列配置 */
  const stageCodeColumn = {
    title: '学段',
    dataIndex: dataIndex.stageCode,
    hideInTable: true,
    valueType: 'select',
    request: getStageList, // 获取学段列表的方法
    initialValue: initialValue.stageCode,
    fieldProps: {
      onChange: (value: number) => {
        // 学段变更时重置年级
        formRef.current?.setFieldValue(
          dataIndex.gradeCodes,
          initialValue.gradeCodes,
        );
      },
    },
    ...stageCodeConfig,
  };

  /* 部门列配置 */
  const deptCodeColumn = {
    title: '部门',
    dataIndex: dataIndex.deptCode,
    hideInTable: true,
    valueType: 'select',
    request: getDeptList, // 获取部门列表的方法
    initialValue: initialValue.deptCode,
    fieldProps: {
      onChange: (value: number) => {
        // 部门变更时重置年级
        formRef.current?.setFieldValue(
          dataIndex.gradeCodes,
          initialValue.gradeCodes,
        );
      },
    },
    ...deptCodeConfig,
  };

  /* 年级列配置(核心联动逻辑) */
  const gradeCodesColumn = {
    title: '年级',
    dataIndex: dataIndex.gradeCodes,
    hideInTable: true,
    valueType: 'select',
    fieldProps: { mode: 'multiple' }, // 多选模式
    // 依赖字段:根据isOnDeptForGrade决定依赖部门还是学段
    dependencies: [
      dataIndex.schoolId,
      isOnDeptForGrade ? dataIndex.deptCode : dataIndex.stageCode,
    ],
    // 根据isOnDeptForGrade选择不同的年级获取方法
    request: isOnDeptForGrade
      ? getGradeListByDeptAndSchool
      : getGradeListByStageAndSchool,
    initialValue: initialValue.gradeCodes,
  };

  /* 科目列配置 */
  const subjectCodesColumn = {
    title: '科目',
    dataIndex: dataIndex.subjectCodes,
    hideInTable: true,
    valueType: 'select',
    fieldProps: { mode: 'multiple' }, // 多选模式
    request: getSubjectList, // 获取科目列表的方法
    initialValue: initialValue.subjectCodes,
    ...subjectCodesConfig,
  };

  // 返回所有列配置和表单引用
  return {
    formRef,
    schoolIdColumn,
    deptCodeColumn,
    stageCodeColumn,
    gradeCodesColumn,
    subjectCodesColumn,
  };
}
export default useBaseColumns;

抛砖引玉,如果有类似需求的,可以参考(^▽^)

相关推荐
工业甲酰苯胺2 小时前
TypeScript枚举类型应用:前后端状态码映射的最简方案
javascript·typescript·状态模式
brzhang2 小时前
我操,终于有人把 AI 大佬们 PUA 程序员的套路给讲明白了!
前端·后端·架构
止观止3 小时前
React虚拟DOM的进化之路
前端·react.js·前端框架·reactjs·react
goms3 小时前
前端项目集成lint-staged
前端·vue·lint-staged
谢尔登3 小时前
【React Natve】NetworkError 和 TouchableOpacity 组件
前端·react.js·前端框架
Lin Hsüeh-ch'in3 小时前
如何彻底禁用 Chrome 自动更新
前端·chrome
augenstern4165 小时前
HTML面试题
前端·html
张可5 小时前
一个KMP/CMP项目的组织结构和集成方式
android·前端·kotlin
G等你下课6 小时前
React 路由懒加载入门:提升首屏性能的第一步
前端·react.js·前端框架
谢尔登6 小时前
【React Native】ScrollView 和 FlatList 组件
javascript·react native·react.js