添加多条件筛选

This commit is contained in:
xianyi
2025-12-25 11:10:07 +08:00
parent 385bf8fa81
commit 842946d08e
2 changed files with 45 additions and 19 deletions

View File

@@ -9,7 +9,7 @@ import { cls } from '../../utils/cls';
interface ExamSectionProps {
filteredClients: ExamClient[];
selectedExamClient: ExamClient | undefined;
examFilterTag: (typeof EXAM_TAGS)[number];
examFilterTags: Set<(typeof EXAM_TAGS)[number]>;
onFilterChange: (tag: (typeof EXAM_TAGS)[number]) => void;
onOpenModal: (id: string, tab: ExamModalTab) => void;
searchValue: string;
@@ -23,7 +23,7 @@ const LOAD_MORE_COUNT = 9; // 每次加载更多时的数量
export const ExamSection = ({
filteredClients,
selectedExamClient,
examFilterTag,
examFilterTags,
onFilterChange,
onOpenModal,
searchValue,
@@ -87,7 +87,7 @@ export const ExamSection = ({
// 当 filteredClients 变化时,重置显示数量
useEffect(() => {
setDisplayCount(INITIAL_LOAD_COUNT);
}, [filteredClients.length, searchValue, examFilterTag]);
}, [filteredClients.length, searchValue, examFilterTags]);
// 懒加载:使用 Intersection Observer 监听底部元素
useEffect(() => {
@@ -158,8 +158,10 @@ export const ExamSection = ({
key={tag}
onClick={() => onFilterChange(tag)}
className={cls(
'px-3 py-1 rounded-2xl border',
examFilterTag === tag ? 'bg-gray-900 text-white border-gray-900' : 'bg-white text-gray-700',
'px-3 py-1 rounded-2xl border transition-colors',
examFilterTags.has(tag)
? 'bg-gray-900 text-white border-gray-900'
: 'bg-white text-gray-700 border-gray-200 hover:border-gray-300',
)}
>
{tag}

View File

@@ -12,24 +12,48 @@ export const ExamPage = () => {
const [examSelectedId, setExamSelectedId] = useState<string>('');
const [examPanelTab, setExamPanelTab] = useState<ExamModalTab>('detail');
const [examModalOpen, setExamModalOpen] = useState(false);
const [examFilterTag, setExamFilterTag] = useState<(typeof EXAM_TAGS)[number]>('全部');
const [examFilterTags, setExamFilterTags] = useState<Set<(typeof EXAM_TAGS)[number]>>(new Set(['全部']));
const [loading, setLoading] = useState(false);
// 处理筛选标签切换(支持多选)
const handleFilterChange = (tag: (typeof EXAM_TAGS)[number]) => {
setExamFilterTags((prev) => {
const next = new Set(prev);
if (tag === '全部') {
// 点击"全部"时,清空其他选择,只保留"全部"
return new Set(['全部']);
} else {
// 点击其他标签时,移除"全部",添加/移除当前标签
next.delete('全部');
if (next.has(tag)) {
next.delete(tag);
// 如果所有标签都被取消,则默认选择"全部"
if (next.size === 0) {
return new Set(['全部']);
}
} else {
next.add(tag);
}
}
return next;
});
};
// 构建接口请求参数
const getRequestPayload = useMemo(() => {
const trimmed = searchValue.trim();
const query_text = trimmed || null;
// 根据筛选标签设置标志位
const is_all = examFilterTag === '全部' ? 1 : 0;
const is_morning = examFilterTag === '上午' ? 1 : 0;
const is_afternoon = examFilterTag === '下午' ? 1 : 0;
const is_high_customer = examFilterTag === '高客' ? 1 : 0;
const is_general_customer = examFilterTag === '普客' ? 1 : 0;
const is_registered = examFilterTag === '已登记' ? 1 : 0;
const is_not_registered = examFilterTag === '未登记' ? 1 : 0;
const is_individual_customer = examFilterTag === '散客' ? 1 : 0;
const is_group_customer = examFilterTag === '团客' ? 1 : 0;
// 根据选中的筛选标签设置标志位(支持多选)
const is_all = examFilterTags.has('全部') ? 1 : 0;
const is_morning = examFilterTags.has('上午') ? 1 : 0;
const is_afternoon = examFilterTags.has('下午') ? 1 : 0;
const is_high_customer = examFilterTags.has('高客') ? 1 : 0;
const is_general_customer = examFilterTags.has('普客') ? 1 : 0;
const is_registered = examFilterTags.has('已登记') ? 1 : 0;
const is_not_registered = examFilterTags.has('未登记') ? 1 : 0;
const is_individual_customer = examFilterTags.has('散客') ? 1 : 0;
const is_group_customer = examFilterTags.has('团客') ? 1 : 0;
return {
query_text,
@@ -43,7 +67,7 @@ export const ExamPage = () => {
is_individual_customer,
is_group_customer,
};
}, [searchValue, examFilterTag]);
}, [searchValue, examFilterTags]);
// 从接口拉取体检客户列表
useEffect(() => {
@@ -118,8 +142,8 @@ export const ExamPage = () => {
<ExamSection
filteredClients={clients}
selectedExamClient={selectedExamClient}
examFilterTag={examFilterTag}
onFilterChange={setExamFilterTag}
examFilterTags={examFilterTags}
onFilterChange={handleFilterChange}
onOpenModal={handleOpenModal}
searchValue={searchValue}
onSearchChange={setSearchValue}