487 lines
12 KiB
Vue
487 lines
12 KiB
Vue
|
|
<template>
|
|||
|
|
<view class="medical-case-form">
|
|||
|
|
<view class="form-container">
|
|||
|
|
<!-- 门诊病历 -->
|
|||
|
|
<template v-if="caseType === 'outpatient'">
|
|||
|
|
<view class="form-item required">
|
|||
|
|
<view class="item-label">就诊机构</view>
|
|||
|
|
<input
|
|||
|
|
class="item-input"
|
|||
|
|
v-model="formData.hospital"
|
|||
|
|
placeholder="暂无"
|
|||
|
|
:disabled="!isEditing"
|
|||
|
|
/>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="form-item required">
|
|||
|
|
<view class="item-label">就诊日期</view>
|
|||
|
|
<picker
|
|||
|
|
mode="date"
|
|||
|
|
:value="formData.visitTime"
|
|||
|
|
@change="onDateChange('visitTime', $event)"
|
|||
|
|
:disabled="!isEditing"
|
|||
|
|
>
|
|||
|
|
<view class="picker-value">
|
|||
|
|
{{ formData.visitTime || '暂无' }}
|
|||
|
|
</view>
|
|||
|
|
</picker>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="form-item required">
|
|||
|
|
<view class="item-label">门诊诊断</view>
|
|||
|
|
<textarea
|
|||
|
|
class="item-textarea"
|
|||
|
|
v-model="formData.diagnosisName"
|
|||
|
|
placeholder="请输入"
|
|||
|
|
:disabled="!isEditing"
|
|||
|
|
/>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="form-item">
|
|||
|
|
<view class="item-label">治疗方案</view>
|
|||
|
|
<textarea
|
|||
|
|
class="item-textarea"
|
|||
|
|
v-model="formData.treatmentPlan"
|
|||
|
|
placeholder="请输入"
|
|||
|
|
:disabled="!isEditing"
|
|||
|
|
/>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<!-- 住院病历 -->
|
|||
|
|
<template v-if="caseType === 'inpatient'">
|
|||
|
|
<view class="form-item required">
|
|||
|
|
<view class="item-label">就诊机构</view>
|
|||
|
|
<input
|
|||
|
|
class="item-input"
|
|||
|
|
v-model="formData.hospital"
|
|||
|
|
placeholder="暂无"
|
|||
|
|
:disabled="!isEditing"
|
|||
|
|
/>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="form-item required">
|
|||
|
|
<view class="item-label">入院日期</view>
|
|||
|
|
<picker
|
|||
|
|
mode="date"
|
|||
|
|
:value="formData.inhosDate"
|
|||
|
|
@change="onDateChange('inhosDate', $event)"
|
|||
|
|
:disabled="!isEditing"
|
|||
|
|
>
|
|||
|
|
<view class="picker-value">
|
|||
|
|
{{ formData.inhosDate || '暂无' }}
|
|||
|
|
</view>
|
|||
|
|
</picker>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="form-item required">
|
|||
|
|
<view class="item-label">住院主诊断</view>
|
|||
|
|
<textarea
|
|||
|
|
class="item-textarea"
|
|||
|
|
v-model="formData.diagnosisName"
|
|||
|
|
placeholder="请输入"
|
|||
|
|
:disabled="!isEditing"
|
|||
|
|
/>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="form-item">
|
|||
|
|
<view class="item-label">手术名称</view>
|
|||
|
|
<textarea
|
|||
|
|
class="item-textarea"
|
|||
|
|
v-model="formData.operation"
|
|||
|
|
placeholder="请输入"
|
|||
|
|
:disabled="!isEditing"
|
|||
|
|
/>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="form-item">
|
|||
|
|
<view class="item-label">手术日期</view>
|
|||
|
|
<picker
|
|||
|
|
mode="date"
|
|||
|
|
:value="formData.operationDate"
|
|||
|
|
@change="onDateChange('operationDate', $event)"
|
|||
|
|
:disabled="!isEditing"
|
|||
|
|
>
|
|||
|
|
<view class="picker-value">
|
|||
|
|
{{ formData.operationDate || '暂无' }}
|
|||
|
|
</view>
|
|||
|
|
</picker>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="form-item">
|
|||
|
|
<view class="item-label">治疗方案</view>
|
|||
|
|
<textarea
|
|||
|
|
class="item-textarea"
|
|||
|
|
v-model="formData.treatmentPlan"
|
|||
|
|
placeholder="请输入"
|
|||
|
|
:disabled="!isEditing"
|
|||
|
|
/>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<!-- 体检记录 -->
|
|||
|
|
<template v-if="caseType === 'physicalExam'">
|
|||
|
|
<view class="form-item required">
|
|||
|
|
<view class="item-label">就诊机构</view>
|
|||
|
|
<input
|
|||
|
|
class="item-input"
|
|||
|
|
v-model="formData.hospital"
|
|||
|
|
placeholder="暂无"
|
|||
|
|
:disabled="!isEditing"
|
|||
|
|
/>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="form-item required">
|
|||
|
|
<view class="item-label">体检日期</view>
|
|||
|
|
<picker
|
|||
|
|
mode="date"
|
|||
|
|
:value="formData.inspectTime"
|
|||
|
|
@change="onDateChange('inspectTime', $event)"
|
|||
|
|
:disabled="!isEditing"
|
|||
|
|
>
|
|||
|
|
<view class="picker-value">
|
|||
|
|
{{ formData.inspectTime || '暂无' }}
|
|||
|
|
</view>
|
|||
|
|
</picker>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="form-item">
|
|||
|
|
<view class="item-label">体检小结</view>
|
|||
|
|
<textarea
|
|||
|
|
class="item-textarea"
|
|||
|
|
v-model="formData.inspectSummary"
|
|||
|
|
placeholder="请输入"
|
|||
|
|
:disabled="!isEditing"
|
|||
|
|
/>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="form-item">
|
|||
|
|
<view class="item-label">阳性发现及处理意见</view>
|
|||
|
|
<textarea
|
|||
|
|
class="item-textarea"
|
|||
|
|
v-model="formData.positiveFind"
|
|||
|
|
placeholder="请输入"
|
|||
|
|
:disabled="!isEditing"
|
|||
|
|
/>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<!-- 预问诊记录 -->
|
|||
|
|
<template v-if="caseType === 'preConsultation'">
|
|||
|
|
<view class="form-item">
|
|||
|
|
<view class="item-label">主诉</view>
|
|||
|
|
<textarea
|
|||
|
|
class="item-textarea"
|
|||
|
|
v-model="formData.chiefComplaint"
|
|||
|
|
placeholder="请输入"
|
|||
|
|
:disabled="!isEditing"
|
|||
|
|
/>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="form-item">
|
|||
|
|
<view class="item-label">现病史</view>
|
|||
|
|
<textarea
|
|||
|
|
class="item-textarea"
|
|||
|
|
v-model="formData.presentIllnessHistory"
|
|||
|
|
placeholder="请输入"
|
|||
|
|
:disabled="!isEditing"
|
|||
|
|
/>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="form-item">
|
|||
|
|
<view class="item-label">既往史</view>
|
|||
|
|
<textarea
|
|||
|
|
class="item-textarea"
|
|||
|
|
v-model="formData.pastMedicalHistory"
|
|||
|
|
placeholder="请输入"
|
|||
|
|
:disabled="!isEditing"
|
|||
|
|
/>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<view class="tips-box">
|
|||
|
|
<text class="tips-text">
|
|||
|
|
1、门诊、住院病历记录生成,生成后支持医生在线编辑,并保存至档案,或者重新生成;
|
|||
|
|
</text>
|
|||
|
|
<text class="tips-text">
|
|||
|
|
2、若未来集到有效信息则以模板字段中默认项写无内容生成,医生可以直接在存字段上进行编辑。
|
|||
|
|
</text>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="footer-buttons">
|
|||
|
|
<view class="btn-regenerate" @click="handleRegenerate">
|
|||
|
|
<text class="btn-text">重新生成</text>
|
|||
|
|
</view>
|
|||
|
|
<view class="btn-save" @click="handleSave">
|
|||
|
|
<text class="btn-text">保存至档案</text>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script setup>
|
|||
|
|
import { ref, onMounted } from 'vue';
|
|||
|
|
|
|||
|
|
const caseType = ref('');
|
|||
|
|
const formData = ref({});
|
|||
|
|
const isEditing = ref(true);
|
|||
|
|
const customerId = ref('');
|
|||
|
|
const groupId = ref('');
|
|||
|
|
|
|||
|
|
onMounted(() => {
|
|||
|
|
const pages = getCurrentPages();
|
|||
|
|
const currentPage = pages[pages.length - 1];
|
|||
|
|
const options = currentPage.options;
|
|||
|
|
|
|||
|
|
caseType.value = options.caseType || '';
|
|||
|
|
customerId.value = options.customerId || '';
|
|||
|
|
groupId.value = options.groupId || '';
|
|||
|
|
|
|||
|
|
// 从 options 中解析表单数据
|
|||
|
|
if (options.formData) {
|
|||
|
|
try {
|
|||
|
|
formData.value = JSON.parse(decodeURIComponent(options.formData));
|
|||
|
|
} catch (e) {
|
|||
|
|
console.error('解析表单数据失败:', e);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 设置页面标题
|
|||
|
|
const titles = {
|
|||
|
|
outpatient: '添加门诊病历',
|
|||
|
|
inpatient: '添加住院病历',
|
|||
|
|
physicalExam: '添加体检记录',
|
|||
|
|
preConsultation: '添加预问诊记录'
|
|||
|
|
};
|
|||
|
|
uni.setNavigationBarTitle({
|
|||
|
|
title: titles[caseType.value] || '添加病历'
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const onDateChange = (field, event) => {
|
|||
|
|
formData.value[field] = event.detail.value;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const handleRegenerate = () => {
|
|||
|
|
uni.showModal({
|
|||
|
|
title: '提示',
|
|||
|
|
content: '确定要重新生成吗?当前编辑的内容将被覆盖',
|
|||
|
|
success: (res) => {
|
|||
|
|
if (res.confirm) {
|
|||
|
|
// 返回上一页并触发重新生成
|
|||
|
|
uni.navigateBack({
|
|||
|
|
success: () => {
|
|||
|
|
uni.$emit('regenerateMedicalCase', {
|
|||
|
|
caseType: caseType.value,
|
|||
|
|
customerId: customerId.value,
|
|||
|
|
groupId: groupId.value
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const handleSave = async () => {
|
|||
|
|
// 验证必填项
|
|||
|
|
const requiredFields = getRequiredFields();
|
|||
|
|
const missingFields = requiredFields.filter(field => !formData.value[field.key]);
|
|||
|
|
|
|||
|
|
if (missingFields.length > 0) {
|
|||
|
|
uni.showToast({
|
|||
|
|
title: `请填写${missingFields[0].label}`,
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
uni.showLoading({ title: '保存中...' });
|
|||
|
|
|
|||
|
|
// 调用保存接口
|
|||
|
|
const api = (await import('@/utils/api.js')).default;
|
|||
|
|
const result = await api('addMedicalRecord', {
|
|||
|
|
customerId: customerId.value,
|
|||
|
|
caseType: caseType.value,
|
|||
|
|
...formData.value
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
uni.hideLoading();
|
|||
|
|
|
|||
|
|
if (result.success) {
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '保存成功',
|
|||
|
|
icon: 'success'
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
setTimeout(() => {
|
|||
|
|
uni.navigateBack();
|
|||
|
|
}, 1500);
|
|||
|
|
} else {
|
|||
|
|
uni.showToast({
|
|||
|
|
title: result.message || '保存失败',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
uni.hideLoading();
|
|||
|
|
console.error('保存病历失败:', error);
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '保存失败,请重试',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const getRequiredFields = () => {
|
|||
|
|
const fieldsMap = {
|
|||
|
|
outpatient: [
|
|||
|
|
{ key: 'hospital', label: '就诊机构' },
|
|||
|
|
{ key: 'visitTime', label: '就诊日期' },
|
|||
|
|
{ key: 'diagnosisName', label: '门诊诊断' }
|
|||
|
|
],
|
|||
|
|
inpatient: [
|
|||
|
|
{ key: 'hospital', label: '就诊机构' },
|
|||
|
|
{ key: 'inhosDate', label: '入院日期' },
|
|||
|
|
{ key: 'diagnosisName', label: '住院主诊断' }
|
|||
|
|
],
|
|||
|
|
physicalExam: [
|
|||
|
|
{ key: 'hospital', label: '就诊机构' },
|
|||
|
|
{ key: 'inspectTime', label: '体检日期' }
|
|||
|
|
],
|
|||
|
|
preConsultation: []
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return fieldsMap[caseType.value] || [];
|
|||
|
|
};
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style scoped lang="scss">
|
|||
|
|
.medical-case-form {
|
|||
|
|
min-height: 100vh;
|
|||
|
|
background-color: #f5f5f5;
|
|||
|
|
padding-bottom: 120rpx;
|
|||
|
|
|
|||
|
|
.form-container {
|
|||
|
|
background-color: #ffffff;
|
|||
|
|
padding: 32rpx;
|
|||
|
|
|
|||
|
|
.form-item {
|
|||
|
|
margin-bottom: 32rpx;
|
|||
|
|
|
|||
|
|
&.required .item-label::before {
|
|||
|
|
content: '*';
|
|||
|
|
color: #ff4d4f;
|
|||
|
|
margin-right: 8rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.item-label {
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
color: #333333;
|
|||
|
|
margin-bottom: 16rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.item-input,
|
|||
|
|
.picker-value {
|
|||
|
|
width: 100%;
|
|||
|
|
height: 80rpx;
|
|||
|
|
padding: 0 24rpx;
|
|||
|
|
background-color: #f8f9fa;
|
|||
|
|
border-radius: 8rpx;
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
color: #333333;
|
|||
|
|
|
|||
|
|
&[disabled] {
|
|||
|
|
color: #999999;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.picker-value {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
color: #999999;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.item-textarea {
|
|||
|
|
width: 100%;
|
|||
|
|
min-height: 160rpx;
|
|||
|
|
padding: 20rpx 24rpx;
|
|||
|
|
background-color: #f8f9fa;
|
|||
|
|
border-radius: 8rpx;
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
color: #333333;
|
|||
|
|
|
|||
|
|
&[disabled] {
|
|||
|
|
color: #999999;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.tips-box {
|
|||
|
|
margin-top: 32rpx;
|
|||
|
|
padding: 24rpx;
|
|||
|
|
background-color: #fffbe6;
|
|||
|
|
border-radius: 8rpx;
|
|||
|
|
|
|||
|
|
.tips-text {
|
|||
|
|
display: block;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
color: #666666;
|
|||
|
|
line-height: 1.6;
|
|||
|
|
margin-bottom: 8rpx;
|
|||
|
|
|
|||
|
|
&:last-child {
|
|||
|
|
margin-bottom: 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.footer-buttons {
|
|||
|
|
position: fixed;
|
|||
|
|
bottom: 0;
|
|||
|
|
left: 0;
|
|||
|
|
right: 0;
|
|||
|
|
display: flex;
|
|||
|
|
gap: 24rpx;
|
|||
|
|
padding: 24rpx 32rpx;
|
|||
|
|
background-color: #ffffff;
|
|||
|
|
box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.08);
|
|||
|
|
|
|||
|
|
.btn-regenerate,
|
|||
|
|
.btn-save {
|
|||
|
|
flex: 1;
|
|||
|
|
height: 88rpx;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
border-radius: 44rpx;
|
|||
|
|
|
|||
|
|
.btn-text {
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
font-weight: 500;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.btn-regenerate {
|
|||
|
|
background-color: #ffffff;
|
|||
|
|
border: 2rpx solid #1890ff;
|
|||
|
|
|
|||
|
|
.btn-text {
|
|||
|
|
color: #1890ff;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.btn-save {
|
|||
|
|
background-color: #1890ff;
|
|||
|
|
|
|||
|
|
.btn-text {
|
|||
|
|
color: #ffffff;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</style>
|