| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- import { useCallback } from 'react';
- import { Task } from '@/domain/work';
- interface UseMultiSelectionOptions {
- selectedIds: string[];
- selectedSecondaryIds?: string[]; // 可选
- onSelectionChange: ((ids: string[], secondaryIds?: string[]) => void);
- enableMultiSelect?: boolean;
- }
- /**
- * 自定义 Hook,处理表格多选逻辑
- * 支持桌面环境(Ctrl+点击)和触摸屏环境(单击选择/取消选择)
- */
- export const useMultiSelection = ({
- selectedIds,
- selectedSecondaryIds,
- onSelectionChange,
- enableMultiSelect = true,
- }: UseMultiSelectionOptions) => {
- const useDualIdMode = selectedSecondaryIds !== undefined;
- /**
- * 处理桌面环境的行点击事件
- * @param record - 点击的行数据
- * @param event - 鼠标事件对象
- */
- const handleRowClick = useCallback((record: Task, event: React.MouseEvent) => {
- if (!enableMultiSelect) {
- // 如果禁用多选,只选中当前项
- onSelectionChange([record.StudyID], useDualIdMode ? [record.entry_id ?? ''] : undefined);
- return;
- }
- const studyId = record.StudyID;
- const entryId = record.entry_id;
- if (event.ctrlKey || event.metaKey) {
- // 桌面环境:Ctrl+点击进行多选/取消多选
- let newSelectedIds;
- let newSelectedSecondaryIds;
- if (useDualIdMode) {
- if (studyId) {//本地task
- const index = selectedIds.indexOf(studyId);
- if (index > -1) {//说明已经在选中数组中了,需要取消选择
- newSelectedIds = selectedIds.splice(index, 1);
- newSelectedSecondaryIds = selectedSecondaryIds?.splice(index, 1);
- } else {
- newSelectedIds = [...selectedIds, studyId];
- newSelectedSecondaryIds = [...(selectedSecondaryIds ?? []), entryId ?? ''];
- }
- } else if (entryId) {//ris task
- const index = selectedSecondaryIds.indexOf(entryId);
- if (index > -1) {//说明已经在选中数组中了,需要取消选择
- newSelectedIds = selectedIds.splice(index, 1);
- newSelectedSecondaryIds = selectedSecondaryIds?.splice(index, 1);
- } else {
- newSelectedIds = [...selectedIds, studyId];
- newSelectedSecondaryIds = [...(selectedSecondaryIds ?? []), entryId ?? ''];
- }
- }
- } else {
- newSelectedIds = selectedIds.includes(studyId)
- ? selectedIds.filter(id => id !== studyId) // 取消选择
- : [...selectedIds, studyId]; // 添加选择
- }
- onSelectionChange(newSelectedIds, newSelectedSecondaryIds);
- } else {
- // 普通点击:清空其他选择,只选中当前项
- onSelectionChange([studyId], useDualIdMode ? [record.entry_id ?? ''] : undefined);
- }
- }, [selectedIds, onSelectionChange, enableMultiSelect]);
- /**
- * 处理触摸屏环境的行点击事件
- * @param record - 点击的行数据
- */
- const handleTouchClick = useCallback((record: Task) => {
- const studyId = record.StudyID;
- // 触摸屏环境:单击选中,再次单击取消选中
- const newSelectedIds = selectedIds.includes(studyId)
- ? selectedIds.filter(id => id !== studyId) // 取消选择
- : [studyId]; // 添加选择
- onSelectionChange(newSelectedIds, useDualIdMode ? [record.entry_id ?? ''] : undefined);
- }, [selectedIds, onSelectionChange]);
- /**
- * 处理行选择(通用方法,可根据设备类型选择具体实现)
- * @param record - 点击的行数据
- * @param event - 鼠标事件对象(可选)
- * @param isTouch - 是否为触摸设备
- */
- const handleRowSelect = useCallback((record: Task, event?: React.MouseEvent, isTouch = false) => {
- if (isTouch && !event) {
- // 触摸屏设备
- handleTouchClick(record);
- } else if (event) {
- // 桌面设备
- handleRowClick(record, event);
- } else {
- // 默认行为:只选中当前项
- onSelectionChange([record.StudyID], useDualIdMode ? [record.entry_id ?? ''] : undefined);
- }
- }, [handleRowClick, handleTouchClick, onSelectionChange]);
- return {
- handleRowClick,
- handleTouchClick,
- handleRowSelect,
- };
- };
|