Files
template-10559/src/doctor/orders/selectPrescription.tsx
赵忠林 77c2df8d1f feat(clinic): 新增患者管理功能模块
- 新增患者管理页面,支持查看和管理患者信息
- 添加患者报备功能,支持新增和编辑患者资料- 实现患者列表展示,包含搜索、筛选和分页功能
- 支持患者状态跟踪和保护期计算- 集成电话拨打和号码复制功能
- 添加处方管理相关数据模型和接口定义
- 更新环境配置中的API地址指向新的生产环境- 优化医生端主页UI布局和功能导航
- 调整部分字段命名以提高代码一致性
-修复医生认证状态下的文案提示问题
2025-10-23 14:20:08 +08:00

236 lines
7.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;