添加体检客户列表懒加载&搜索
This commit is contained in:
@@ -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 && (
|
||||
|
||||
Reference in New Issue
Block a user