添加体检客户列表懒加载&搜索

This commit is contained in:
xianyi
2025-12-22 09:51:41 +08:00
parent b72765695d
commit 4bfb09b7d9
2 changed files with 288 additions and 112 deletions

View File

@@ -1,20 +1,19 @@
import { useEffect, useMemo, useState } from 'react';
import { useOutletContext } from 'react-router-dom';
import type { ExamClient, ExamModalTab } from '../data/mockData';
import { EXAM_TAGS } from '../data/mockData';
import { ExamSection } from '../components/exam/ExamSection';
import { ExamModal } from '../components/exam/ExamModal';
import type { MainLayoutContext } from '../layouts/MainLayout';
import { getPhysicalExamCustomerList } from '../api';
export const ExamPage = () => {
const { search } = useOutletContext<MainLayoutContext>();
const [searchValue, setSearchValue] = useState<string>('');
const [clients, setClients] = useState<ExamClient[]>([]);
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 [loading, setLoading] = useState(false);
// 将筛选标签映射为接口 filter_type
const filterType = useMemo(() => {
@@ -40,14 +39,61 @@ export const ExamPage = () => {
}
}, [examFilterTag]);
// 智能识别搜索内容类型
const getSearchParams = useMemo(() => {
const trimmed = searchValue.trim();
if (!trimmed) {
return {
customer_name: undefined,
phone: undefined,
id_no: undefined,
};
}
// 判断是否为手机号11位数字以1开头
if (/^1[3-9]\d{9}$/.test(trimmed)) {
return {
customer_name: undefined,
phone: trimmed,
id_no: undefined,
};
}
// 判断是否为身份证号15位或18位最后一位可能是X
if (/^(\d{15}|\d{17}[\dXx])$/.test(trimmed)) {
return {
customer_name: undefined,
phone: undefined,
id_no: trimmed,
};
}
// 判断是否为卡号纯数字长度在6-20位之间
if (/^\d{6,20}$/.test(trimmed)) {
// 接口中没有卡号字段,暂时使用 customer_name 搜索
// 如果后续接口支持卡号字段,可以添加 card_no 参数
return {
customer_name: trimmed,
phone: undefined,
id_no: undefined,
};
}
// 默认为姓名
return {
customer_name: trimmed,
phone: undefined,
id_no: undefined,
};
}, [searchValue]);
// 从接口拉取体检客户列表
useEffect(() => {
const payload = {
customer_name: search.trim() || undefined,
phone: undefined,
id_no: undefined,
...getSearchParams,
filter_type: filterType,
};
setLoading(true);
getPhysicalExamCustomerList(payload)
.then((res) => {
const list = res.Data || [];
@@ -96,8 +142,11 @@ export const ExamPage = () => {
})
.catch((err) => {
console.error('获取体检客户列表失败', err);
})
.finally(() => {
setLoading(false);
});
}, [search, filterType, examSelectedId]);
}, [getSearchParams, filterType, examSelectedId]);
const selectedExamClient: ExamClient | undefined = useMemo(
() => clients.find((c) => c.id === examSelectedId) || clients[0],
@@ -118,6 +167,9 @@ export const ExamPage = () => {
examFilterTag={examFilterTag}
onFilterChange={setExamFilterTag}
onOpenModal={handleOpenModal}
searchValue={searchValue}
onSearchChange={setSearchValue}
loading={loading}
/>
{examModalOpen && selectedExamClient && (