feat(clinic): 添加患者头像和处方图片字段
- 在患者用户模型中添加 avatar 字段 - 在处方模型中添加 image 字段 - 更新新增诊所订单页面的表单结构 - 调整图片上传组件的样式和逻辑 - 优化表单验证规则和提示信息- 修改药方信息展示方式 - 更新页面跳转和数据获取逻辑
This commit is contained in:
@@ -12,6 +12,8 @@ export interface ClinicPatientUser {
|
||||
userId?: number;
|
||||
// 姓名
|
||||
realName?: string;
|
||||
// 头像
|
||||
avatar?: string;
|
||||
// 年龄
|
||||
age?: string;
|
||||
// 性别
|
||||
|
||||
@@ -24,6 +24,8 @@ export interface ClinicPrescription {
|
||||
treatmentPlan?: string;
|
||||
// 煎药说明
|
||||
decoctionInstructions?: string;
|
||||
// 图片
|
||||
image?: string;
|
||||
// 订单总金额
|
||||
orderPrice?: string;
|
||||
// 单价
|
||||
|
||||
@@ -1,16 +1,25 @@
|
||||
import {useEffect, useState, useRef} from "react";
|
||||
import {useRouter} from '@tarojs/taro'
|
||||
import {Loading, CellGroup, Input, Form, Cell,Button, Avatar, Tag, TextArea, ImagePreview} from '@nutui/nutui-react-taro'
|
||||
import {
|
||||
Loading,
|
||||
Button,
|
||||
Form,
|
||||
Cell,
|
||||
Avatar,
|
||||
Input,
|
||||
Space,
|
||||
TextArea
|
||||
} from '@nutui/nutui-react-taro'
|
||||
import {ArrowRight} from '@nutui/icons-react-taro'
|
||||
import {View, Text} from '@tarojs/components'
|
||||
import Taro from '@tarojs/taro'
|
||||
import FixedButton from "@/components/FixedButton";
|
||||
import navTo from "@/utils/common";
|
||||
import {getUser} from "@/api/system/user";
|
||||
import {User} from "@/api/system/user/model";
|
||||
import {ClinicPatientUser} from "@/api/clinic/clinicPatientUser/model";
|
||||
import {ClinicPrescription} from "@/api/clinic/clinicPrescription/model";
|
||||
import {TenantId} from "@/config/app";
|
||||
import {getClinicPatientUser} from "@/api/clinic/clinicPatientUser";
|
||||
import {addClinicOrder} from "@/api/clinic/clinicOrder";
|
||||
|
||||
// 图片数据接口
|
||||
interface UploadedImageData {
|
||||
@@ -24,24 +33,24 @@ interface UploadedImageData {
|
||||
|
||||
const AddClinicOrder = () => {
|
||||
const {params} = useRouter();
|
||||
const [toUser, setToUser] = useState<User>()
|
||||
const [toUser, setToUser] = useState<ClinicPatientUser>()
|
||||
const [loading, setLoading] = useState<boolean>(false)
|
||||
const formRef = useRef<any>(null)
|
||||
const [disabled, setDisabled] = useState<boolean>(false)
|
||||
const formRef = useRef<any>()
|
||||
const [fileList, setFileList] = useState<UploadedImageData[]>([]) // 图片文件列表
|
||||
const [showBdImgPreview, setShowBdImgPreview] = useState(false)
|
||||
const [fileList2, setFileList2] = useState<UploadedImageData[]>([]) // 图片文件列表
|
||||
|
||||
// 患者和处方状态
|
||||
const [selectedPatient, setSelectedPatient] = useState<ClinicPatientUser | null>(null)
|
||||
const [selectedPrescription, setSelectedPrescription] = useState<ClinicPrescription | null>(null)
|
||||
const [selectedPatient, setSelectedPatient] = useState<ClinicPatientUser>()
|
||||
const [selectedPrescription, setSelectedPrescription] = useState<ClinicPrescription>()
|
||||
|
||||
// 表单数据
|
||||
const [formData, setFormData] = useState({
|
||||
const [formData, setFormData] = useState<ClinicPrescription>({
|
||||
userId: undefined,
|
||||
doctorId: undefined,
|
||||
diagnosis: '',
|
||||
treatmentPlan: '',
|
||||
orderPrice: '',
|
||||
decoctionInstructions: '',
|
||||
content: '',
|
||||
items: [],
|
||||
image: '' // 添加image字段
|
||||
})
|
||||
|
||||
@@ -51,7 +60,7 @@ const AddClinicOrder = () => {
|
||||
|
||||
const reload = async () => {
|
||||
if (toUserId) {
|
||||
getUser(Number(toUserId)).then(data => {
|
||||
getClinicPatientUser(Number(toUserId)).then(data => {
|
||||
setToUser(data)
|
||||
})
|
||||
}
|
||||
@@ -60,6 +69,8 @@ const AddClinicOrder = () => {
|
||||
// 设置选中的患者(供其他页面调用)
|
||||
// @ts-ignore
|
||||
const setSelectedPatientFunc = (patient: ClinicPatientUser) => {
|
||||
console.log('设置选中的患者:', patient)
|
||||
setToUser(patient)
|
||||
setSelectedPatient(patient)
|
||||
}
|
||||
|
||||
@@ -77,7 +88,6 @@ const AddClinicOrder = () => {
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
// 选择并上传图片
|
||||
const handleChooseImage = () => {
|
||||
if (fileList.length >= 5) { // 修正最大图片数量为5
|
||||
@@ -218,10 +228,16 @@ const AddClinicOrder = () => {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 判断内容是否为空
|
||||
if (!values.content) {
|
||||
if (!values.diagnosis) {
|
||||
Taro.showToast({
|
||||
title: `请输入消息内容`,
|
||||
title: `请输入诊断结果`,
|
||||
icon: 'error'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!values.treatmentPlan) {
|
||||
Taro.showToast({
|
||||
title: `请输入治疗方案`,
|
||||
icon: 'error'
|
||||
});
|
||||
return false;
|
||||
@@ -252,7 +268,7 @@ const AddClinicOrder = () => {
|
||||
}
|
||||
|
||||
// 执行新增或更新操作
|
||||
// await addClinicOrder({});
|
||||
await addClinicOrder({});
|
||||
|
||||
Taro.showToast({
|
||||
title: `发送成功`,
|
||||
@@ -327,70 +343,73 @@ const AddClinicOrder = () => {
|
||||
return (
|
||||
<>
|
||||
{/* 显示已选择的用户(如果有的话) */}
|
||||
{toUser && (
|
||||
<Cell title={(
|
||||
<View className={'flex items-center'}>
|
||||
<Avatar src={toUser.avatar}/>
|
||||
<Avatar src={toUser?.avatar}/>
|
||||
<View className={'ml-2 flex flex-col'}>
|
||||
<Text>{toUser.alias || toUser.nickname}</Text>
|
||||
<Text className={'text-gray-300'}>{toUser.mobile}</Text>
|
||||
<Text>{toUser?.realName || '请选择'}</Text>
|
||||
<Text className={'text-gray-300'}>{toUser?.phone}</Text>
|
||||
</View>
|
||||
</View>
|
||||
)} extra={(
|
||||
<ArrowRight color="#cccccc" className={'mt-2'} size={20}/>
|
||||
)}/>
|
||||
)}
|
||||
|
||||
{/* 选择患者 */}
|
||||
<Cell
|
||||
title="选择患者"
|
||||
extra={selectedPatient ? (
|
||||
<View className={'flex items-center'}>
|
||||
<Text className={'mr-2'}>{selectedPatient.realName || '未知患者'}</Text>
|
||||
<ArrowRight color="#cccccc" size={18}/>
|
||||
</View>
|
||||
) : (
|
||||
<Text className={'text-gray-400'}>请选择患者</Text>
|
||||
)}
|
||||
onClick={() => navTo(`/doctor/orders/selectPatient`, true)}
|
||||
)} onClick={() => navTo(`/doctor/orders/selectPatient`, true)}
|
||||
/>
|
||||
|
||||
{/* 诊断结果 */}
|
||||
<CellGroup>
|
||||
<Cell title="诊断结果">
|
||||
<TextArea
|
||||
value={formData.diagnosis}
|
||||
onChange={(value) => handleFormChange('diagnosis', value)}
|
||||
placeholder="股骨头坏死"
|
||||
rows={2}
|
||||
maxLength={100}
|
||||
/>
|
||||
</Cell>
|
||||
<Cell title="治疗方案">
|
||||
{toUser && (
|
||||
<Form
|
||||
ref={formRef}
|
||||
divider
|
||||
initialValues={formData}
|
||||
labelPosition={'top'}
|
||||
onFinish={(values) => submitSucceed(values)}
|
||||
onFinishFailed={(errors) => submitFailed(errors)}
|
||||
>
|
||||
{/* 基本信息 */}
|
||||
<Form.Item
|
||||
name="diagnosis"
|
||||
label={'诊断结果'}
|
||||
required
|
||||
rules={[{required: true, message: '请填写诊断结果'}]}
|
||||
initialValue={formData.diagnosis}
|
||||
>
|
||||
<Input placeholder="请输入诊断结果" style={{
|
||||
backgroundColor: '#f9f9f9',
|
||||
padding: '4px',
|
||||
}}/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="treatmentPlan"
|
||||
label={'治疗方案'}
|
||||
required
|
||||
rules={[{required: true, message: '请填写治疗方案'}]}
|
||||
initialValue={formData.treatmentPlan}
|
||||
>
|
||||
<TextArea
|
||||
value={formData.treatmentPlan}
|
||||
onChange={(value) => handleFormChange('treatmentPlan', value)}
|
||||
placeholder="请填写治疗方案"
|
||||
rows={2}
|
||||
maxLength={100}
|
||||
style={{
|
||||
backgroundColor: '#f9f9f9',
|
||||
padding: '4px',
|
||||
}}
|
||||
/>
|
||||
</Cell>
|
||||
<Cell title="添加图片" extra={'可上传病例/舌苔/面相等'}>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={'拍照上传'}
|
||||
name="image"
|
||||
required
|
||||
rules={[{message: '请上传照片'}]}
|
||||
>
|
||||
<div style={{
|
||||
<View style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
gap: '12px',
|
||||
padding: '8px 0'
|
||||
gap: '8px',
|
||||
padding: '0'
|
||||
}}>
|
||||
{/* 显示已上传的图片 */}
|
||||
{fileList.map((file) => (
|
||||
<div key={file.uid} style={{
|
||||
<View key={file.uid} style={{
|
||||
position: 'relative',
|
||||
width: '80px',
|
||||
height: '80px',
|
||||
@@ -426,12 +445,12 @@ const AddClinicOrder = () => {
|
||||
>
|
||||
×
|
||||
</Button>
|
||||
</div>
|
||||
</View>
|
||||
))}
|
||||
|
||||
{/* 添加图片按钮 */}
|
||||
{fileList.length < 5 && (
|
||||
<div
|
||||
<View
|
||||
onClick={handleChooseImage}
|
||||
style={{
|
||||
width: '80px',
|
||||
@@ -450,25 +469,17 @@ const AddClinicOrder = () => {
|
||||
<span style={{fontSize: '10px', marginTop: '2px', color: '#666'}}>
|
||||
添加图片
|
||||
</span>
|
||||
</div>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
<View className="text-xs text-gray-500">
|
||||
可上传病例/舌苔/面相等,已上传{fileList.length}张图片
|
||||
</View>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
)}
|
||||
|
||||
{/* 显示上传数量提示 */}
|
||||
{fileList.length > 0 && (
|
||||
<div style={{
|
||||
width: '100%',
|
||||
fontSize: '12px',
|
||||
color: '#52c41a',
|
||||
textAlign: 'center',
|
||||
marginTop: '4px'
|
||||
}}>
|
||||
已上传{fileList.length}张图片(最多5张)
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Form.Item>
|
||||
</Cell>
|
||||
</CellGroup>
|
||||
|
||||
|
||||
{/* 选择处方 */}
|
||||
<Cell
|
||||
@@ -483,80 +494,34 @@ const AddClinicOrder = () => {
|
||||
)}
|
||||
onClick={() => navTo(`/doctor/orders/selectPrescription`, true)}
|
||||
/>
|
||||
|
||||
{/* 药方信息 */}
|
||||
{selectedPrescription && (
|
||||
<CellGroup>
|
||||
<Cell title="药方信息">
|
||||
<View className={'flex flex-wrap'}>
|
||||
<>
|
||||
<Cell extra={'药方信息'}>
|
||||
<View className={'flex flex-col'}>
|
||||
<View className={'py-3'}>RP: {selectedPrescription.prescriptionType === 0 ? '中药' : '西药'} 共{selectedPrescription.items?.length}味、共{selectedPrescription.orderPrice}元</View>
|
||||
<Space className={'flex flex-wrap'}>
|
||||
{selectedPrescription.items?.map(item => (
|
||||
<Tag key={item.id} className={'mr-2 mb-2'}>{item.medicineName}</Tag>
|
||||
<Button>{item.medicineName} 105克</Button>
|
||||
))}
|
||||
</Space>
|
||||
</View>
|
||||
</Cell>
|
||||
|
||||
{/* 煎药说明 */}
|
||||
<Cell title="煎药说明">
|
||||
<TextArea
|
||||
value={formData.decoctionInstructions}
|
||||
onChange={(value) => handleFormChange('decoctionInstructions', value)}
|
||||
placeholder="请填写煎药说明"
|
||||
placeholder="请填写用药说明"
|
||||
rows={2}
|
||||
maxLength={200}
|
||||
/>
|
||||
</Cell>
|
||||
</CellGroup>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* 消息内容 */}
|
||||
<CellGroup>
|
||||
<Cell title="消息内容">
|
||||
<TextArea
|
||||
value={formData.content}
|
||||
onChange={(value) => handleFormChange('content', value)}
|
||||
placeholder="请填写要发送的消息内容"
|
||||
rows={3}
|
||||
maxLength={300}
|
||||
/>
|
||||
</Cell>
|
||||
</CellGroup>
|
||||
|
||||
<Form
|
||||
ref={formRef}
|
||||
divider
|
||||
initialValues={formData}
|
||||
labelPosition="left"
|
||||
onFinish={(values) => submitSucceed(values)}
|
||||
onFinishFailed={(errors) => submitFailed(errors)}
|
||||
>
|
||||
<CellGroup style={{padding: '4px 0'}}>
|
||||
<Form.Item name="diagnosis" initialValue={formData.diagnosis}>
|
||||
<Input type="hidden"/>
|
||||
</Form.Item>
|
||||
<Form.Item name="treatmentPlan" initialValue={formData.treatmentPlan}>
|
||||
<Input type="hidden"/>
|
||||
</Form.Item>
|
||||
<Form.Item name="decoctionInstructions" initialValue={formData.decoctionInstructions}>
|
||||
<Input type="hidden"/>
|
||||
</Form.Item>
|
||||
<Form.Item name="content" initialValue={formData.content} required>
|
||||
<Input type="hidden"/>
|
||||
</Form.Item>
|
||||
<Form.Item name="image" initialValue={formData.image}>
|
||||
<Input type="hidden"/>
|
||||
</Form.Item>
|
||||
</CellGroup>
|
||||
</Form>
|
||||
|
||||
{/* 底部浮动按钮 */}
|
||||
<FixedButton text={'立即发送'} onClick={() => formRef.current?.submit()}/>
|
||||
<FixedButton text={'生成处方并发送给患者'} onClick={() => formRef.current?.submit()}/>
|
||||
|
||||
<ImagePreview
|
||||
autoPlay
|
||||
images={fileList2.filter(file => file.src).map(file => ({ src: file.src! }))}
|
||||
visible={showBdImgPreview}
|
||||
onClose={() => setShowBdImgPreview(false)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user