feat(doctor): 添加订单诊断和治疗方案表单功能
- 引入 TextArea 组件用于多行文本输入- 新增诊断结果、治疗方案和煎药说明表单项 - 实现表单数据状态管理和字段变更处理- 更新消息内容拼接逻辑,包含诊断和治疗信息- 支持从本地存储恢复选中的患者和处方数据 - 移除调试日志并优化表单提交流程 - 调整界面布局,增强药方信息展示效果- 修改组件名称从 AddMessage 为 AddOrder
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import {useEffect, useState, useRef} from "react";
|
import {useEffect, useState, useRef} from "react";
|
||||||
import {useRouter} from '@tarojs/taro'
|
import {useRouter} from '@tarojs/taro'
|
||||||
import {Loading, CellGroup, Input, Form, Cell, Avatar, Tag, TextArea} from '@nutui/nutui-react-taro'
|
import {Loading, CellGroup, Input, Form, Cell,Button, Avatar, Tag, TextArea, ImagePreview} from '@nutui/nutui-react-taro'
|
||||||
import {ArrowRight} from '@nutui/icons-react-taro'
|
import {ArrowRight} from '@nutui/icons-react-taro'
|
||||||
import {View, Text} from '@tarojs/components'
|
import {View, Text} from '@tarojs/components'
|
||||||
import Taro from '@tarojs/taro'
|
import Taro from '@tarojs/taro'
|
||||||
@@ -11,17 +11,32 @@ import {getUser} from "@/api/system/user";
|
|||||||
import {User} from "@/api/system/user/model";
|
import {User} from "@/api/system/user/model";
|
||||||
import {ClinicPatientUser} from "@/api/clinic/clinicPatientUser/model";
|
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";
|
||||||
|
|
||||||
|
// 图片数据接口
|
||||||
|
interface UploadedImageData {
|
||||||
|
url?: string;
|
||||||
|
src?: string;
|
||||||
|
name?: string;
|
||||||
|
uid?: string;
|
||||||
|
message?: string;
|
||||||
|
type?: string;
|
||||||
|
}
|
||||||
|
|
||||||
const AddOrder = () => {
|
const AddOrder = () => {
|
||||||
const {params} = useRouter();
|
const {params} = useRouter();
|
||||||
const [toUser, setToUser] = useState<User>()
|
const [toUser, setToUser] = useState<User>()
|
||||||
const [loading, setLoading] = useState<boolean>(true)
|
const [loading, setLoading] = useState<boolean>(true)
|
||||||
const formRef = useRef<any>(null)
|
const formRef = useRef<any>(null)
|
||||||
|
const [disabled, setDisabled] = useState<boolean>(false)
|
||||||
|
const [fileList, setFileList] = useState<UploadedImageData[]>([]) // 图片文件列表
|
||||||
|
const [showBdImgPreview, setShowBdImgPreview] = useState(false)
|
||||||
|
const [fileList2, setFileList2] = useState<UploadedImageData[]>([]) // 图片文件列表
|
||||||
|
|
||||||
// 患者和处方状态
|
// 患者和处方状态
|
||||||
const [selectedPatient, setSelectedPatient] = useState<ClinicPatientUser | null>(null)
|
const [selectedPatient, setSelectedPatient] = useState<ClinicPatientUser | null>(null)
|
||||||
const [selectedPrescription, setSelectedPrescription] = useState<ClinicPrescription | null>(null)
|
const [selectedPrescription, setSelectedPrescription] = useState<ClinicPrescription | null>(null)
|
||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const [formData, setFormData] = useState({
|
const [formData, setFormData] = useState({
|
||||||
diagnosis: '',
|
diagnosis: '',
|
||||||
@@ -35,13 +50,15 @@ const AddOrder = () => {
|
|||||||
const toUserId = params.id ? Number(params.id) : undefined
|
const toUserId = params.id ? Number(params.id) : undefined
|
||||||
|
|
||||||
const reload = async () => {
|
const reload = async () => {
|
||||||
if(toUserId){
|
if (toUserId) {
|
||||||
getUser(Number(toUserId)).then(data => {
|
getUser(Number(toUserId)).then(data => {
|
||||||
setToUser(data)
|
setToUser(data)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setDisabled(true);
|
||||||
|
|
||||||
// 设置选中的患者(供其他页面调用)
|
// 设置选中的患者(供其他页面调用)
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const setSelectedPatientFunc = (patient: ClinicPatientUser) => {
|
const setSelectedPatientFunc = (patient: ClinicPatientUser) => {
|
||||||
@@ -53,7 +70,7 @@ const AddOrder = () => {
|
|||||||
const setSelectedPrescriptionFunc = (prescription: ClinicPrescription) => {
|
const setSelectedPrescriptionFunc = (prescription: ClinicPrescription) => {
|
||||||
setSelectedPrescription(prescription)
|
setSelectedPrescription(prescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理表单字段变化
|
// 处理表单字段变化
|
||||||
const handleFormChange = (field: string, value: string) => {
|
const handleFormChange = (field: string, value: string) => {
|
||||||
setFormData(prev => ({
|
setFormData(prev => ({
|
||||||
@@ -62,13 +79,141 @@ const AddOrder = () => {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 选择并上传图片
|
||||||
|
const handleChooseImage = () => {
|
||||||
|
if (fileList.length >= 20) {
|
||||||
|
Taro.showToast({
|
||||||
|
title: '最多只能上传20张图片',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Taro.chooseImage({
|
||||||
|
count: 5 - fileList.length, // 剩余可选择的数量
|
||||||
|
sizeType: ['compressed'],
|
||||||
|
sourceType: ['album', 'camera'],
|
||||||
|
success: (res) => {
|
||||||
|
console.log('选择图片成功:', res)
|
||||||
|
|
||||||
|
// 逐个上传选中的图片
|
||||||
|
res.tempFilePaths.forEach((filePath, index) => {
|
||||||
|
uploadSingleImage(filePath, index)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.log('选择图片失败:', err)
|
||||||
|
Taro.showToast({
|
||||||
|
title: '选择图片失败',
|
||||||
|
icon: 'error'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理文件删除
|
||||||
|
const handleFileRemove = (file: any) => {
|
||||||
|
console.log('删除文件:', file)
|
||||||
|
const newFileList = fileList.filter(f => f.uid !== file.uid)
|
||||||
|
setFileList(newFileList)
|
||||||
|
|
||||||
|
// 更新表单数据 - 使用JSON格式存储
|
||||||
|
if (newFileList.length === 0) {
|
||||||
|
setFormData(prev => ({
|
||||||
|
...prev,
|
||||||
|
image: undefined
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
const imageData: UploadedImageData[] = newFileList.map(f => ({
|
||||||
|
url: f.url,
|
||||||
|
src: f.url,
|
||||||
|
name: f.name,
|
||||||
|
uid: f.uid
|
||||||
|
}))
|
||||||
|
setFormData(prev => ({
|
||||||
|
...prev,
|
||||||
|
image: JSON.stringify(imageData)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传单张图片
|
||||||
|
const uploadSingleImage = (filePath: any, index: number) => {
|
||||||
|
|
||||||
|
Taro.uploadFile({
|
||||||
|
url: 'https://server.websoft.top/api/oss/upload',
|
||||||
|
filePath: filePath,
|
||||||
|
name: 'file',
|
||||||
|
header: {
|
||||||
|
'content-type': 'application/json',
|
||||||
|
TenantId
|
||||||
|
},
|
||||||
|
success: (res) => {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(res.data);
|
||||||
|
console.log('上传成功', data)
|
||||||
|
if (data.code === 0) {
|
||||||
|
// 更新文件列表
|
||||||
|
const newFile = {
|
||||||
|
name: `图片${Date.now()}_${index}`,
|
||||||
|
url: data.data.url,
|
||||||
|
status: 'success',
|
||||||
|
message: '上传成功',
|
||||||
|
type: 'image',
|
||||||
|
uid: `${Date.now()}_${index}`,
|
||||||
|
}
|
||||||
|
|
||||||
|
setFileList(prev => {
|
||||||
|
const newList = [...prev, newFile]
|
||||||
|
// 同时更新表单数据 - 使用JSON格式存储
|
||||||
|
const imageData: UploadedImageData[] = newList.map(f => ({
|
||||||
|
url: f.url,
|
||||||
|
name: f.name,
|
||||||
|
uid: f.uid
|
||||||
|
}))
|
||||||
|
setFormData(prevForm => ({
|
||||||
|
...prevForm,
|
||||||
|
image: JSON.stringify(imageData)
|
||||||
|
}))
|
||||||
|
return newList
|
||||||
|
})
|
||||||
|
|
||||||
|
Taro.showToast({
|
||||||
|
title: '上传成功',
|
||||||
|
icon: 'success'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Taro.showToast({
|
||||||
|
title: data.message || '上传失败',
|
||||||
|
icon: 'error'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('解析响应失败:', error)
|
||||||
|
Taro.showToast({
|
||||||
|
title: '上传失败',
|
||||||
|
icon: 'error'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.log('上传请求失败', err);
|
||||||
|
Taro.showToast({
|
||||||
|
title: '上传失败',
|
||||||
|
icon: 'error'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 提交表单
|
// 提交表单
|
||||||
const submitSucceed = async (values: any) => {
|
const submitSucceed = async (values: any) => {
|
||||||
try {
|
try {
|
||||||
console.log('提交数据:', values)
|
console.log('提交数据:', values)
|
||||||
|
|
||||||
// 参数校验
|
// 参数校验
|
||||||
if(!toUser && !selectedPatient){
|
if (!toUser && !selectedPatient) {
|
||||||
Taro.showToast({
|
Taro.showToast({
|
||||||
title: `请选择发送对象或患者`,
|
title: `请选择发送对象或患者`,
|
||||||
icon: 'error'
|
icon: 'error'
|
||||||
@@ -95,16 +240,16 @@ const AddOrder = () => {
|
|||||||
if (selectedPrescription) {
|
if (selectedPrescription) {
|
||||||
content = `[处方: ${selectedPrescription.orderNo || '未知'}] ${content}`;
|
content = `[处方: ${selectedPrescription.orderNo || '未知'}] ${content}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加诊断结果和治疗方案到消息内容
|
// 添加诊断结果和治疗方案到消息内容
|
||||||
if (values.diagnosis) {
|
if (values.diagnosis) {
|
||||||
content = `诊断结果: ${values.diagnosis}\n` + content;
|
content = `诊断结果: ${values.diagnosis}\n` + content;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (values.treatmentPlan) {
|
if (values.treatmentPlan) {
|
||||||
content = `治疗方案: ${values.treatmentPlan}\n` + content;
|
content = `治疗方案: ${values.treatmentPlan}\n` + content;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (values.decoctionInstructions) {
|
if (values.decoctionInstructions) {
|
||||||
content = `煎药说明: ${values.decoctionInstructions}\n` + content;
|
content = `煎药说明: ${values.decoctionInstructions}\n` + content;
|
||||||
}
|
}
|
||||||
@@ -149,14 +294,14 @@ const AddOrder = () => {
|
|||||||
Taro.getCurrentInstance().page.setSelectedPatient = setSelectedPatientFunc;
|
Taro.getCurrentInstance().page.setSelectedPatient = setSelectedPatientFunc;
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
Taro.getCurrentInstance().page.setSelectedPrescription = setSelectedPrescriptionFunc;
|
Taro.getCurrentInstance().page.setSelectedPrescription = setSelectedPrescriptionFunc;
|
||||||
|
|
||||||
// 从本地存储获取之前选择的患者和处方
|
// 从本地存储获取之前选择的患者和处方
|
||||||
const storedPatient = Taro.getStorageSync('selectedPatient');
|
const storedPatient = Taro.getStorageSync('selectedPatient');
|
||||||
if (storedPatient) {
|
if (storedPatient) {
|
||||||
setSelectedPatient(JSON.parse(storedPatient));
|
setSelectedPatient(JSON.parse(storedPatient));
|
||||||
Taro.removeStorageSync('selectedPatient');
|
Taro.removeStorageSync('selectedPatient');
|
||||||
}
|
}
|
||||||
|
|
||||||
const storedPrescription = Taro.getStorageSync('selectedPrescription');
|
const storedPrescription = Taro.getStorageSync('selectedPrescription');
|
||||||
if (storedPrescription) {
|
if (storedPrescription) {
|
||||||
setSelectedPrescription(JSON.parse(storedPrescription));
|
setSelectedPrescription(JSON.parse(storedPrescription));
|
||||||
@@ -205,24 +350,113 @@ const AddOrder = () => {
|
|||||||
<TextArea
|
<TextArea
|
||||||
value={formData.diagnosis}
|
value={formData.diagnosis}
|
||||||
onChange={(value) => handleFormChange('diagnosis', value)}
|
onChange={(value) => handleFormChange('diagnosis', value)}
|
||||||
placeholder="请填写诊断结果"
|
placeholder="股骨头坏死"
|
||||||
rows={2}
|
rows={2}
|
||||||
maxLength={200}
|
maxLength={100}
|
||||||
/>
|
/>
|
||||||
</Cell>
|
</Cell>
|
||||||
</CellGroup>
|
|
||||||
|
|
||||||
{/* 治疗方案 */}
|
|
||||||
<CellGroup>
|
|
||||||
<Cell title="治疗方案">
|
<Cell title="治疗方案">
|
||||||
<TextArea
|
<TextArea
|
||||||
value={formData.treatmentPlan}
|
value={formData.treatmentPlan}
|
||||||
onChange={(value) => handleFormChange('treatmentPlan', value)}
|
onChange={(value) => handleFormChange('treatmentPlan', value)}
|
||||||
placeholder="请填写治疗方案"
|
placeholder="请填写治疗方案"
|
||||||
rows={2}
|
rows={2}
|
||||||
maxLength={200}
|
maxLength={100}
|
||||||
/>
|
/>
|
||||||
</Cell>
|
</Cell>
|
||||||
|
<Cell title="添加图片" extra={'可上传病例/舌苔/面相等'}>
|
||||||
|
<Form.Item
|
||||||
|
label={'拍照上传'}
|
||||||
|
name="image"
|
||||||
|
required
|
||||||
|
rules={[{message: '请上传照片'}]}
|
||||||
|
>
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
gap: '12px',
|
||||||
|
padding: '8px 0'
|
||||||
|
}}>
|
||||||
|
{/* 显示已上传的图片 */}
|
||||||
|
{fileList.map((file) => (
|
||||||
|
<div key={file.uid} style={{
|
||||||
|
position: 'relative',
|
||||||
|
width: '80px',
|
||||||
|
height: '80px',
|
||||||
|
borderRadius: '8px',
|
||||||
|
overflow: 'hidden',
|
||||||
|
border: '1px solid #d9d9d9'
|
||||||
|
}}>
|
||||||
|
<img
|
||||||
|
src={file.url}
|
||||||
|
alt={file.name}
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
objectFit: 'cover'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
type="default"
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: '-8px',
|
||||||
|
right: '-8px',
|
||||||
|
width: '20px',
|
||||||
|
height: '20px',
|
||||||
|
borderRadius: '10px',
|
||||||
|
fontSize: '12px',
|
||||||
|
minWidth: '20px',
|
||||||
|
padding: 0,
|
||||||
|
lineHeight: '20px'
|
||||||
|
}}
|
||||||
|
onClick={() => handleFileRemove(file)}
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* 添加图片按钮 */}
|
||||||
|
{fileList.length < 5 && (
|
||||||
|
<div
|
||||||
|
onClick={handleChooseImage}
|
||||||
|
style={{
|
||||||
|
width: '80px',
|
||||||
|
height: '80px',
|
||||||
|
borderRadius: '8px',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
border: '2px dashed #d9d9d9',
|
||||||
|
backgroundColor: '#fafafa',
|
||||||
|
cursor: 'pointer'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span style={{fontSize: '20px', color: '#d9d9d9'}}>+</span>
|
||||||
|
<span style={{fontSize: '10px', marginTop: '2px', color: '#666'}}>
|
||||||
|
添加图片
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 显示上传数量提示 */}
|
||||||
|
{fileList.length > 0 && (
|
||||||
|
<div style={{
|
||||||
|
width: '100%',
|
||||||
|
fontSize: '12px',
|
||||||
|
color: '#52c41a',
|
||||||
|
textAlign: 'center',
|
||||||
|
marginTop: '4px'
|
||||||
|
}}>
|
||||||
|
已上传{fileList.length}张图片(最多5张)
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Form.Item>
|
||||||
|
</Cell>
|
||||||
</CellGroup>
|
</CellGroup>
|
||||||
|
|
||||||
{/* 选择处方 */}
|
{/* 选择处方 */}
|
||||||
@@ -249,7 +483,7 @@ const AddOrder = () => {
|
|||||||
))}
|
))}
|
||||||
</View>
|
</View>
|
||||||
</Cell>
|
</Cell>
|
||||||
|
|
||||||
{/* 煎药说明 */}
|
{/* 煎药说明 */}
|
||||||
<Cell title="煎药说明">
|
<Cell title="煎药说明">
|
||||||
<TextArea
|
<TextArea
|
||||||
@@ -286,24 +520,32 @@ const AddOrder = () => {
|
|||||||
>
|
>
|
||||||
<CellGroup style={{padding: '4px 0'}}>
|
<CellGroup style={{padding: '4px 0'}}>
|
||||||
<Form.Item name="diagnosis" initialValue={formData.diagnosis}>
|
<Form.Item name="diagnosis" initialValue={formData.diagnosis}>
|
||||||
<Input type="hidden" />
|
<Input type="hidden"/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item name="treatmentPlan" initialValue={formData.treatmentPlan}>
|
<Form.Item name="treatmentPlan" initialValue={formData.treatmentPlan}>
|
||||||
<Input type="hidden" />
|
<Input type="hidden"/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item name="decoctionInstructions" initialValue={formData.decoctionInstructions}>
|
<Form.Item name="decoctionInstructions" initialValue={formData.decoctionInstructions}>
|
||||||
<Input type="hidden" />
|
<Input type="hidden"/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item name="content" initialValue={formData.content} required>
|
<Form.Item name="content" initialValue={formData.content} required>
|
||||||
<Input type="hidden" />
|
<Input type="hidden"/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</CellGroup>
|
</CellGroup>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
{/* 底部浮动按钮 */}
|
{/* 底部浮动按钮 */}
|
||||||
<FixedButton text={'立即发送'} onClick={() => formRef.current?.submit()}/>
|
<FixedButton text={'立即发送'} onClick={() => formRef.current?.submit()}/>
|
||||||
|
|
||||||
|
<ImagePreview
|
||||||
|
autoPlay
|
||||||
|
// @ts-ignore
|
||||||
|
images={fileList2}
|
||||||
|
visible={showBdImgPreview}
|
||||||
|
onClose={() => setShowBdImgPreview(false)}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AddOrder;
|
export default AddOrder;
|
||||||
|
|||||||
Reference in New Issue
Block a user