feat(clinic): 完善处方管理功能

- 处方模型增加患者基本信息字段(姓名、性别、年龄、身高、体重)- 处方列表页优化UI展示,增加处方类型、状态标签和药品数量显示
- 实现处方分页查询功能,替换原有列表查询接口
- 添加处方编辑和删除功能,支持跳转到编辑页面
- 处方列表项增加诊断结果、治疗方案、订单金额等信息展示
-优化空状态提示文案和新增按钮样式
- 页面标题文案调整,统一为“处方”相关表述
- 在医生端首页添加跳转到处方管理页面的入口
- 移除冗余的订单创建逻辑,专注处方核心功能
- 在应用配置中注册处方相关页面路由
This commit is contained in:
2025-11-03 04:15:01 +08:00
parent ca3ff9dc9e
commit a5efb6250f
8 changed files with 232 additions and 53 deletions

View File

@@ -10,6 +10,16 @@ export interface ClinicPrescription {
id?: number; id?: number;
// 患者 // 患者
userId?: number; userId?: number;
// 姓名
realName?: string;
// 性别 0男 1女
sex?: number;
// 年龄
age?: string;
// 身高
height?: string;
// 体重
weight?: string;
// 医生 // 医生
doctorId?: number; doctorId?: number;
// 订单编号 // 订单编号

View File

@@ -105,7 +105,9 @@ export default {
"pages": [ "pages": [
"index", "index",
"clinicPatientUser/add", "clinicPatientUser/add",
"clinicDoctorUser/add" "clinicDoctorUser/add",
"clinicPrescription/index",
"clinicPrescription/add",
] ]
}, },
{ {

View File

@@ -1,5 +1,4 @@
export default definePageConfig({ export default definePageConfig({
navigationBarTitleText: '新增处方主表 navigationBarTitleText: '新增处方主表',
',
navigationBarTextStyle: 'black' navigationBarTextStyle: 'black'
}) })

View File

@@ -1,5 +1,4 @@
export default definePageConfig({ export default definePageConfig({
navigationBarTitleText: '处方主表 navigationBarTitleText: '处方',
管理',
navigationBarTextStyle: 'black' navigationBarTextStyle: 'black'
}) })

View File

@@ -1,20 +1,26 @@
import {useState} from "react"; import {useState} from "react";
import Taro, {useDidShow} from '@tarojs/taro' import Taro, {useDidShow} from '@tarojs/taro'
import {Button, Cell, CellGroup, Space, Empty, ConfigProvider, Divider} from '@nutui/nutui-react-taro' import {Button, Cell, CellGroup, Space, Empty, ConfigProvider, Tag, Divider} from '@nutui/nutui-react-taro'
import {Dongdong, ArrowRight, CheckNormal, Checked} from '@nutui/icons-react-taro' import {Del, Edit} from '@nutui/icons-react-taro'
import {View} from '@tarojs/components' import {View, Text} from '@tarojs/components'
import {ClinicPrescription} from "@/api/clinic/clinicPrescription/model"; import {ClinicPrescription} from "@/api/clinic/clinicPrescription/model";
import {listClinicPrescription, removeClinicPrescription, updateClinicPrescription} from "@/api/clinic/clinicPrescription"; import {
pageClinicPrescription,
removeClinicPrescription
} from "@/api/clinic/clinicPrescription";
import FixedButton from "@/components/FixedButton";
const ClinicPrescriptionList = () => { const ClinicPrescriptionList = () => {
const [list, setList] = useState<ClinicPrescription[]>([]) const [list, setList] = useState<ClinicPrescription[]>([])
const [loading, setLoading] = useState<boolean>(false)
const reload = () => { const reload = () => {
listClinicPrescription({ setLoading(true)
pageClinicPrescription({
// 添加查询条件 // 添加查询条件
}) })
.then(data => { .then(data => {
setList(data || []) setList(data?.list || [])
}) })
.catch(() => { .catch(() => {
Taro.showToast({ Taro.showToast({
@@ -22,44 +28,231 @@ const ClinicPrescriptionList = () => {
icon: 'error' icon: 'error'
}); });
}) })
.finally(() => {
setLoading(false)
})
} }
const onDel = async (item: ClinicPrescription) => {
const res = await Taro.showModal({
title: '确认删除',
content: `确定要删除处方编号「${item.orderNo}」吗?`,
})
const onDel = async (id?: number) => { if (res.confirm) {
await removeClinicPrescription(id) try {
Taro.showToast({ await removeClinicPrescription(item.id)
title: '删除成功', Taro.showToast({
icon: 'success' title: '删除成功',
}); icon: 'success'
reload(); });
reload();
} catch (error) {
Taro.showToast({
title: '删除失败',
icon: 'error'
});
}
}
}
const onEdit = (item: ClinicPrescription) => {
Taro.navigateTo({
url: `/clinic/clinicPrescription/add?id=${item.id}`
})
}
// 获取处方类型文本
const getPrescriptionTypeText = (type?: number) => {
return type === 0 ? '中药' : type === 1 ? '西药' : '未知'
}
// 获取状态文本
const getStatusText = (status?: number) => {
switch (status) {
case 0:
return '正常'
case 1:
return '已完成'
case 2:
return '已支付'
case 3:
return '已取消'
default:
return '未知'
}
}
// 获取状态颜色
const getStatusType = (status?: number): 'primary' | 'success' | 'danger' | 'warning' | 'default' => {
switch (status) {
case 0:
return 'primary'
case 1:
return 'success'
case 2:
return 'success'
case 3:
return 'danger'
default:
return 'default'
}
}
const getSexName = (sex?: number) => {
return sex === 0 ? '男' : sex === 1 ? '女' : ''
} }
useDidShow(() => { useDidShow(() => {
reload() reload()
}); });
if (list.length == 0) { if (list.length === 0 && !loading) {
return ( return (
<ConfigProvider> <ConfigProvider>
<div className={'h-full flex flex-col justify-center items-center'} style={{ <View className={'h-full flex flex-col justify-center items-center'} style={{
height: 'calc(100vh - 300px)', height: 'calc(100vh - 300px)',
}}> }}>
<Empty <Empty
style={{ style={{
backgroundColor: 'transparent' backgroundColor: 'transparent'
}} }}
description="暂无数据" description="暂无处方数据"
/> />
<Space> <Space style={{ marginTop: '20px' }}>
<Button onClick={() => Taro.navigateTo({url: '/clinic/clinicPrescription/add'})}> <Button
</Button> type="primary"
onClick={() => Taro.navigateTo({url: '/clinic/clinicPrescription/add'})}
>
</Button>
</Space> </Space>
</div> </View>
</ConfigProvider> </ConfigProvider>
) )
} }
return ( return (
<> <>
{list.map((item, _) => ( <View className="p-3">
<Cell.Group key={item. {list.map((item) => (
<CellGroup key={item.id} className="mb-3">
<Cell
title={
<View className="flex items-center justify-between">
<Space>
<Text className="font-medium">{item.realName}</Text>
<Text className="font-medium">{item.age}</Text>
<Text className="font-medium">{getSexName(item.sex)}</Text>
</Space>
<Tag type={getStatusType(item.status)}>
{getStatusText(item.status)}
</Tag>
</View>
}
/>
<Cell
title="处方类型"
extra={
<Tag type="info">
{getPrescriptionTypeText(item.prescriptionType)}
</Tag>
}
/>
{item.diagnosis && (
<Cell
title="诊断结果"
extra={
<Text className="text-gray-600 text-sm">
{item.diagnosis.length > 20
? `${item.diagnosis.substring(0, 20)}...`
: item.diagnosis}
</Text>
}
/>
)}
{item.treatmentPlan && (
<Cell
title="治疗方案"
extra={
<Text className="text-gray-600 text-sm">
{item.treatmentPlan.length > 20
? `${item.treatmentPlan.substring(0, 20)}...`
: item.treatmentPlan}
</Text>
}
/>
)}
<Cell
title="订单金额"
extra={
<Text className="text-red-500 font-medium">
¥{item.orderPrice || '0.00'}
</Text>
}
/>
{item.items && item.items.length > 0 && (
<Cell
title="药品数量"
extra={
<Tag type="warning">
{item.items.length}
</Tag>
}
/>
)}
<Cell
title="创建时间"
extra={
<Text className="text-gray-500 text-xs">
{item.createTime}
</Text>
}
/>
{item.comments && (
<Cell
title="备注"
extra={
<Text className="text-gray-600 text-sm">
{item.comments.length > 30
? `${item.comments.substring(0, 30)}...`
: item.comments}
</Text>
}
/>
)}
<Divider />
<Cell>
<Space className="w-full justify-end">
<Button
size="small"
type="primary"
icon={<Edit />}
onClick={() => onEdit(item)}
>
</Button>
<Button
size="small"
type="danger"
icon={<Del />}
onClick={() => onDel(item)}
>
</Button>
</Space>
</Cell>
</CellGroup>
))}
</View>
<FixedButton
text="开处方"
onClick={() => Taro.navigateTo({url: '/clinic/clinicPrescription/add'})}
/>
</>
)
}
export default ClinicPrescriptionList;

View File

@@ -163,7 +163,7 @@ const DealerIndex: React.FC = () => {
</View> </View>
</Grid.Item> </Grid.Item>
<Grid.Item text={'处方管理'} onClick={() => navigateToPage('/doctor/orders/index')}> <Grid.Item text={'处方管理'} onClick={() => navigateToPage('/clinic/clinicPrescription/index')}>
<View className="text-center"> <View className="text-center">
<View className="w-12 h-12 bg-orange-50 rounded-xl flex items-center justify-center mx-auto mb-2"> <View className="w-12 h-12 bg-orange-50 rounded-xl flex items-center justify-center mx-auto mb-2">
<Orderlist color="#f59e0b" size="20"/> <Orderlist color="#f59e0b" size="20"/>

View File

@@ -19,7 +19,6 @@ import {ClinicPatientUser} from "@/api/clinic/clinicPatientUser/model";
import {ClinicPrescription} from "@/api/clinic/clinicPrescription/model"; import {ClinicPrescription} from "@/api/clinic/clinicPrescription/model";
import {TenantId} from "@/config/app"; import {TenantId} from "@/config/app";
import {getClinicPatientUser} from "@/api/clinic/clinicPatientUser"; import {getClinicPatientUser} from "@/api/clinic/clinicPatientUser";
import {addClinicOrder} from "@/api/clinic/clinicOrder";
// 图片数据接口 // 图片数据接口
interface UploadedImageData { interface UploadedImageData {

View File

@@ -139,30 +139,7 @@ const DoctorOrderConfirm = () => {
console.log('处方明细创建成功') console.log('处方明细创建成功')
} }
// 第三步创建订单记录关联处方ID console.log('处方创建完成处方ID:', prescriptionId)
console.log('开始创建订单记录...')
const clinicOrderData = {
userId: orderData.patient.userId,
doctorId: doctorId,
type: 0, // 订单类型:诊所订单
title: `${orderData.patient.realName}的处方订单`,
totalPrice: getTotalPrice(),
payPrice: getTotalPrice(),
buyerRemarks: `诊断:${orderData.diagnosis}`,
merchantRemarks: orderData.treatmentPlan,
comments: JSON.stringify({
prescriptionId: prescriptionId, // 关联处方ID
prescriptionNo: createdPrescription.orderNo, // 处方编号
patientName: orderData.patient.realName,
patientAge: orderData.patient.age
}),
payStatus: '0', // 未付款
orderStatus: 0, // 待支付
deliveryStatus: 10, // 未发货
}
await addClinicPrescription(clinicOrderData)
console.log('订单创建成功')
// 清除临时数据 // 清除临时数据
Taro.removeStorageSync('tempOrderData') Taro.removeStorageSync('tempOrderData')