feat(clinic): 新增患者管理功能模块
- 新增患者管理页面,支持查看和管理患者信息 - 添加患者报备功能,支持新增和编辑患者资料- 实现患者列表展示,包含搜索、筛选和分页功能 - 支持患者状态跟踪和保护期计算- 集成电话拨打和号码复制功能 - 添加处方管理相关数据模型和接口定义 - 更新环境配置中的API地址指向新的生产环境- 优化医生端主页UI布局和功能导航 - 调整部分字段命名以提高代码一致性 -修复医生认证状态下的文案提示问题
This commit is contained in:
236
src/doctor/orders/selectPrescription.tsx
Normal file
236
src/doctor/orders/selectPrescription.tsx
Normal file
@@ -0,0 +1,236 @@
|
||||
import {useState, useEffect, useCallback} from 'react'
|
||||
import {View, Text} from '@tarojs/components'
|
||||
import Taro, {useDidShow} from '@tarojs/taro'
|
||||
import {Loading, InfiniteLoading, Empty, Space, SearchBar, Button} from '@nutui/nutui-react-taro'
|
||||
import {
|
||||
pageClinicPrescription
|
||||
} from "@/api/clinic/clinicPrescription";
|
||||
import {ClinicPrescription} from "@/api/clinic/clinicPrescription/model";
|
||||
|
||||
const SelectPrescription = () => {
|
||||
const [list, setList] = useState<ClinicPrescription[]>([])
|
||||
const [loading, setLoading] = useState<boolean>(false)
|
||||
const [searchValue, setSearchValue] = useState<string>('')
|
||||
const [displaySearchValue, setDisplaySearchValue] = useState<string>('')
|
||||
const [page, setPage] = useState(1)
|
||||
const [hasMore, setHasMore] = useState(true)
|
||||
|
||||
// 获取处方数据
|
||||
const fetchPrescriptionData = useCallback(async (resetPage = false, targetPage?: number) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const currentPage = resetPage ? 1 : (targetPage || page);
|
||||
|
||||
// 构建API参数
|
||||
const params: any = {
|
||||
page: currentPage
|
||||
};
|
||||
|
||||
// 添加搜索关键词
|
||||
if (displaySearchValue.trim()) {
|
||||
params.keywords = displaySearchValue.trim();
|
||||
}
|
||||
|
||||
const res = await pageClinicPrescription(params);
|
||||
|
||||
if (res?.list && res.list.length > 0) {
|
||||
// 如果是重置页面或第一页,直接设置新数据;否则追加数据
|
||||
if (resetPage || currentPage === 1) {
|
||||
setList(res.list);
|
||||
} else {
|
||||
setList(prevList => prevList.concat(res.list));
|
||||
}
|
||||
|
||||
// 正确判断是否还有更多数据
|
||||
const hasMoreData = res.list.length >= 10; // 假设每页10条数据
|
||||
setHasMore(hasMoreData);
|
||||
} else {
|
||||
if (resetPage || currentPage === 1) {
|
||||
setList([]);
|
||||
}
|
||||
setHasMore(false);
|
||||
}
|
||||
|
||||
setPage(currentPage);
|
||||
} catch (error) {
|
||||
console.error('获取处方数据失败:', error);
|
||||
Taro.showToast({
|
||||
title: '加载失败,请重试',
|
||||
icon: 'none'
|
||||
});
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [page, displaySearchValue]);
|
||||
|
||||
const reloadMore = async () => {
|
||||
if (loading || !hasMore) return; // 防止重复加载
|
||||
const nextPage = page + 1;
|
||||
await fetchPrescriptionData(false, nextPage);
|
||||
}
|
||||
|
||||
// 防抖搜索功能
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => {
|
||||
setDisplaySearchValue(searchValue);
|
||||
}, 300); // 300ms 防抖
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, [searchValue]);
|
||||
|
||||
// 初始化数据
|
||||
useEffect(() => {
|
||||
fetchPrescriptionData(true).then();
|
||||
}, [displaySearchValue]);
|
||||
|
||||
// 监听页面显示,当从其他页面返回时刷新数据
|
||||
useDidShow(() => {
|
||||
// 刷新数据
|
||||
setList([]);
|
||||
setPage(1);
|
||||
setHasMore(true);
|
||||
fetchPrescriptionData(true);
|
||||
});
|
||||
|
||||
// 选择处方
|
||||
const selectPrescription = (prescription: ClinicPrescription) => {
|
||||
// 将选中的处方信息传递回上一个页面
|
||||
const pages = Taro.getCurrentPages();
|
||||
if (pages.length > 1) {
|
||||
const prevPage = pages[pages.length - 2];
|
||||
// @ts-ignore
|
||||
if (prevPage && typeof prevPage.setSelectedPrescription === 'function') {
|
||||
// @ts-ignore
|
||||
prevPage.setSelectedPrescription(prescription);
|
||||
}
|
||||
}
|
||||
Taro.navigateBack();
|
||||
};
|
||||
|
||||
// 渲染处方项
|
||||
const renderPrescriptionItem = (prescription: ClinicPrescription) => (
|
||||
<View key={prescription.id} className="bg-white rounded-lg p-4 mb-3 shadow-sm">
|
||||
<View className="flex items-center mb-3">
|
||||
<View className="flex-1">
|
||||
<View className="flex items-center justify-between mb-1">
|
||||
<Text className="font-semibold text-gray-800 mr-2">
|
||||
处方编号: {prescription.orderNo || '无编号'}
|
||||
</Text>
|
||||
</View>
|
||||
<View className="flex items-center mb-1">
|
||||
<Space direction="vertical">
|
||||
<Text className="text-xs text-gray-500">
|
||||
处方类型: {prescription.prescriptionType === 0 ? '中药' : prescription.prescriptionType === 1 ? '西药' : '未知'}
|
||||
</Text>
|
||||
<Text className="text-xs text-gray-500">
|
||||
诊断结果: {prescription.diagnosis || '无'}
|
||||
</Text>
|
||||
<Text className="text-xs text-gray-500">
|
||||
创建时间: {prescription.createTime || '未知'}
|
||||
</Text>
|
||||
</Space>
|
||||
</View>
|
||||
|
||||
{/* 显示备注字段 */}
|
||||
<View className="flex items-center">
|
||||
<Text className="text-xs text-gray-500">备注: {prescription.comments || '暂无'}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 选择按钮 */}
|
||||
<Button
|
||||
size="small"
|
||||
onClick={() => selectPrescription(prescription)}
|
||||
style={{backgroundColor: '#1890ff', color: 'white'}}
|
||||
>
|
||||
选择此处方
|
||||
</Button>
|
||||
</View>
|
||||
);
|
||||
|
||||
// 渲染处方列表
|
||||
const renderPrescriptionList = () => {
|
||||
const isSearching = displaySearchValue.trim().length > 0;
|
||||
|
||||
return (
|
||||
<View className="flex-1">
|
||||
{/* 搜索结果统计 */}
|
||||
{isSearching && (
|
||||
<View className="bg-white px-4 py-2 border-b border-gray-100">
|
||||
<Text className="text-sm text-gray-600">
|
||||
搜索 "{displaySearchValue}" 的结果,共找到 {list.length} 条记录
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
<View className="p-4" style={{
|
||||
height: isSearching ? 'calc(90vh - 40px)' : '90vh',
|
||||
overflowY: 'auto',
|
||||
overflowX: 'hidden'
|
||||
}}>
|
||||
<InfiniteLoading
|
||||
target="scroll"
|
||||
hasMore={hasMore}
|
||||
onLoadMore={reloadMore}
|
||||
onScroll={() => {
|
||||
// 滚动事件处理
|
||||
}}
|
||||
onScrollToUpper={() => {
|
||||
// 滚动到顶部事件处理
|
||||
}}
|
||||
loadingText={
|
||||
<>
|
||||
加载中...
|
||||
</>
|
||||
}
|
||||
loadMoreText={
|
||||
list.length === 0 ? (
|
||||
<Empty
|
||||
style={{backgroundColor: 'transparent'}}
|
||||
description={loading ? "加载中..." : "暂无处方数据"}
|
||||
/>
|
||||
) : (
|
||||
<View className={'h-3 flex items-center justify-center'}>
|
||||
<Text className="text-gray-500 text-sm">没有更多了</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
>
|
||||
{loading && list.length === 0 ? (
|
||||
<View className="flex items-center justify-center py-8">
|
||||
<Loading/>
|
||||
<Text className="text-gray-500 mt-2 ml-2">加载中...</Text>
|
||||
</View>
|
||||
) : (
|
||||
list.map(renderPrescriptionItem)
|
||||
)}
|
||||
</InfiniteLoading>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<View className="min-h-screen bg-gray-50">
|
||||
{/* 搜索栏 */}
|
||||
<View className="bg-white py-2 border-b border-gray-100">
|
||||
<SearchBar
|
||||
value={searchValue}
|
||||
placeholder="搜索处方编号、诊断结果"
|
||||
onChange={(value) => setSearchValue(value)}
|
||||
onClear={() => {
|
||||
setSearchValue('');
|
||||
setDisplaySearchValue('');
|
||||
}}
|
||||
clearable
|
||||
/>
|
||||
</View>
|
||||
|
||||
{/* 处方列表 */}
|
||||
{renderPrescriptionList()}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default SelectPrescription;
|
||||
Reference in New Issue
Block a user