Files
his/openhis-ui-vue3/src/template/inHospitalSurgicalRecord.vue
2025-11-12 17:06:09 +08:00

555 lines
18 KiB
Vue
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.

<template>
<div class="medical-document">
<!-- 标题区域 -->
<div class="doc-header">
<h1 class="doc-title">{{ hospitalName }} 住院手术记录单</h1>
<div class="doc-subtitle">住院号: {{ formData.busNo || '待填写' }}</div>
</div>
<!-- 内容区域 -->
<el-form
ref="formRef"
:model="formData"
:rules="rules"
label-width="120px"
label-align="left"
class="doc-content"
style="height: 60vh; overflow: scroll;"
>
<!-- 患者与手术基础信息 -->
<section class="doc-section">
<h2 class="section-title">患者与手术基本信息</h2>
<div class="adaptive-grid">
<el-form-item label="患者姓名" prop="patientName" class="grid-item required">
<el-input v-model="formData.patientName" placeholder="请输入患者姓名" clearable />
</el-form-item>
<el-form-item label="性别" prop="gender" class="grid-item required">
<el-select v-model="formData.gender" placeholder="请选择性别">
<el-option label="男" value="男" />
<el-option label="女" value="女" />
</el-select>
</el-form-item>
<el-form-item label="年龄" prop="age" class="grid-item required">
<div class="input-with-unit">
<el-input v-model.number="formData.age" type="number" placeholder="请输入年龄" />
<span class="unit"></span>
</div>
</el-form-item>
<el-form-item label="科室" prop="department" class="grid-item required">
<el-input v-model="formData.department" placeholder="如:普外科" clearable />
</el-form-item>
<el-form-item label="病房/床号" prop="bedNo" class="grid-item required">
<el-input v-model="formData.bedNo" placeholder="如502-03" clearable />
</el-form-item>
<el-form-item label="手术日期/时间" prop="operationDateTime" class="grid-item required">
<el-date-picker
v-model="formData.operationDateTime"
type="datetime"
placeholder="选择手术日期时间"
value-format="YYYY-MM-DD HH:mm"
/>
</el-form-item>
</div>
</section>
<!-- 手术团队信息 -->
<section class="doc-section">
<h2 class="section-title">手术团队信息</h2>
<div class="adaptive-grid">
<el-form-item label="手术者" prop="surgeon" class="grid-item required">
<el-input v-model="formData.surgeon" placeholder="主刀医师姓名" clearable />
</el-form-item>
<el-form-item label="第一助手" prop="firstAssistant" class="grid-item required">
<el-input v-model="formData.firstAssistant" placeholder="第一助手姓名" clearable />
</el-form-item>
<el-form-item label="第二助手" prop="secondAssistant" class="grid-item">
<el-input v-model="formData.secondAssistant" placeholder="第二助手姓名" clearable />
</el-form-item>
<el-form-item label="麻醉医师" prop="anesthesiologist" class="grid-item required">
<el-input v-model="formData.anesthesiologist" placeholder="麻醉医师姓名" clearable />
</el-form-item>
<el-form-item label="巡回护士" prop="circulatingNurse" class="grid-item required">
<el-input v-model="formData.circulatingNurse" placeholder="巡回护士姓名" clearable />
</el-form-item>
<el-form-item label="器械护士" prop="scrubNurse" class="grid-item required">
<el-input v-model="formData.scrubNurse" placeholder="器械护士姓名" clearable />
</el-form-item>
</div>
</section>
<!-- 手术详情 -->
<section class="doc-section">
<h2 class="section-title">手术详情</h2>
<el-form-item label="手术名称" prop="operationName" class="full-width-item required">
<el-input v-model="formData.operationName" placeholder="规范手术名称(如:腹腔镜下胆囊切除术)" clearable />
</el-form-item>
<el-form-item label="手术方式" prop="operationMethod" class="full-width-item required">
<el-select v-model="formData.operationMethod" placeholder="选择手术方式">
<el-option label="开放手术" value="开放手术" />
<el-option label="微创手术" value="微创手术" />
<el-option label="介入手术" value="介入手术" />
</el-select>
</el-form-item>
<el-form-item label="手术入路" prop="surgicalApproach" class="full-width-item required">
<el-input v-model="formData.surgicalApproach" placeholder="如:右上腹经腹直肌切口" clearable />
</el-form-item>
<el-form-item label="术中发现" prop="intraoperativeFindings" class="full-width-item required">
<el-input
v-model="formData.intraoperativeFindings"
type="textarea"
placeholder="详细描述术中所见器官、病变情况"
autosize
maxlength="1000"
show-word-limit
/>
</el-form-item>
<el-form-item label="手术过程" prop="operationProcess" class="full-width-item required">
<el-input
v-model="formData.operationProcess"
type="textarea"
placeholder="按操作顺序描述手术步骤(如:游离胆囊三角→结扎胆囊管→切除胆囊..."
autosize
maxlength="1500"
show-word-limit
/>
</el-form-item>
</section>
<!-- 术后情况 -->
<section class="doc-section">
<h2 class="section-title">术后情况</h2>
<div class="adaptive-grid">
<el-form-item label="术中出血量" prop="bloodLoss" class="grid-item required">
<div class="input-with-unit">
<el-input v-model.number="formData.bloodLoss" type="number" placeholder="请输入出血量" />
<span class="unit">ml</span>
</div>
</el-form-item>
<el-form-item label="输血情况" prop="bloodTransfusion" class="grid-item">
<el-select v-model="formData.bloodTransfusion" placeholder="是否输血">
<el-option label="是" value="是" />
<el-option label="否" value="否" />
</el-select>
</el-form-item>
<el-form-item label="引流管放置" prop="drainageTube" class="grid-item">
<el-input v-model="formData.drainageTube" placeholder="如腹腔引流管1根" clearable />
</el-form-item>
<el-form-item label="标本处理" prop="specimenDisposal" class="grid-item required">
<el-input v-model="formData.specimenDisposal" placeholder="如:胆囊标本送病理检查" clearable />
</el-form-item>
<el-form-item label="手术结束时间" prop="operationEndTime" class="grid-item required">
<el-date-picker
v-model="formData.operationEndTime"
type="datetime"
placeholder="选择手术结束时间"
value-format="YYYY-MM-DD HH:mm"
/>
</el-form-item>
<el-form-item label="患者去向" prop="patientDestination" class="grid-item required">
<el-select v-model="formData.patientDestination" placeholder="选择去向">
<el-option label="ICU" value="ICU" />
<el-option label="普通病房" value="普通病房" />
</el-select>
</el-form-item>
</div>
</section>
<!-- 签署区域 -->
<section class="doc-section">
<h2 class="section-title">签署确认</h2>
<div class="adaptive-grid signature-area" style="grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));">
<el-form-item label="手术者签名" prop="surgeonSignature" class="grid-item required">
<el-input v-model="formData.surgeonSignature" placeholder="主刀医师签字" clearable />
<div class="signature-tip">请手术者亲笔签名</div>
</el-form-item>
<el-form-item label="记录者签名" prop="recorderSignature" class="grid-item required">
<el-input v-model="formData.recorderSignature" placeholder="记录者签字" clearable />
<div class="signature-tip">请记录者如第一助手签字</div>
</el-form-item>
<el-form-item label="记录日期" prop="recordDate" class="grid-item required">
<el-date-picker
v-model="formData.recordDate"
type="date"
placeholder="选择记录日期"
value-format="YYYY-MM-DD"
style="width: 100%;"
/>
</el-form-item>
</div>
</section>
</el-form>
<!-- 操作按钮 -->
<div class="btn-group">
<el-button type="primary" @click="submit">保存记录</el-button>
<el-button type="success" @click="handlePrint">打印记录</el-button>
<el-button type="warning" @click="handleReset">重置表单</el-button>
</div>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue';
import { ElMessage, ElMessageBox, ElForm, ElFormItem, ElInput, ElSelect, ElOption, ElDatePicker, ElButton } from 'element-plus';
// 医院名称
const hospitalName = '长春市朝阳区中医院';
defineOptions({
name: 'iInHospitalSurgicalRecord'
});
// 表单引用
const formRef = ref(null);
// 表单数据
const formData = reactive({
// 患者与手术基础信息
busNo: '',
patientName: '',
gender: '',
age: '',
department: '',
bedNo: '',
operationDateTime: '',// 手术日期时间
// 手术团队信息
surgeon: '',// 主刀医师
firstAssistant: '',// 第一助手
secondAssistant: '',// 第二助手
anesthesiologist: '',// 麻醉医师
circulatingNurse: '',// 巡回护士
scrubNurse: '',// 器械护士
// 手术详情
operationName: '',// 规范手术名称
operationMethod: '',// 手术方式
surgicalApproach: '',// 手术入路
intraoperativeFindings: '',// 术中发现
operationProcess: '',// 手术过程
// 术后情况
bloodLoss: '',// 术中出血量
bloodTransfusion: '',// 输血情况
drainageTube: '',// 引流管放置
specimenDisposal: '',// 标本处理
operationEndTime: '',// 手术结束时间
patientDestination: '',// 患者去向
// 签署信息
surgeonSignature: '',// 手术者签名
recorderSignature: '',// 记录者签名
recordDate: ''// 记录日期
});
// 表单验证规则
const rules = reactive({
busNo: [
{ required: true, message: '请填写住院号', trigger: ['blur', 'submit'] }
],
patientName: [
{ required: true, message: '请填写患者姓名', trigger: ['blur', 'submit'] }
],
gender: [
{ required: true, message: '请选择性别', trigger: ['change', 'submit'] }
],
age: [
{ required: true, message: '请填写年龄', trigger: ['blur', 'submit'] },
{ type: 'number', min: 0, max: 150, message: '年龄需在0-150之间', trigger: ['blur', 'submit'] }
],
department: [
{ required: true, message: '请填写科室', trigger: ['blur', 'submit'] }
],
bedNo: [
{ required: true, message: '请填写病房/床号', trigger: ['blur', 'submit'] }
],
operationDateTime: [
{ required: true, message: '请选择手术日期时间', trigger: ['change', 'submit'] }
],
surgeon: [
{ required: true, message: '请填写手术者姓名', trigger: ['blur', 'submit'] }
],
firstAssistant: [
{ required: true, message: '请填写第一助手姓名', trigger: ['blur', 'submit'] }
],
anesthesiologist: [
{ required: true, message: '请填写麻醉医师姓名', trigger: ['blur', 'submit'] }
],
circulatingNurse: [
{ required: true, message: '请填写巡回护士姓名', trigger: ['blur', 'submit'] }
],
scrubNurse: [
{ required: true, message: '请填写器械护士姓名', trigger: ['blur', 'submit'] }
],
operationName: [
{ required: true, message: '请填写手术名称', trigger: ['blur', 'submit'] }
],
operationMethod: [
{ required: true, message: '请选择手术方式', trigger: ['change', 'submit'] }
],
surgicalApproach: [
{ required: true, message: '请填写手术入路', trigger: ['blur', 'submit'] }
],
intraoperativeFindings: [
{ required: true, message: '请描述术中发现', trigger: ['blur', 'submit'] }
],
operationProcess: [
{ required: true, message: '请描述手术过程', trigger: ['blur', 'submit'] }
],
bloodLoss: [
{ required: true, message: '请填写术中出血量', trigger: ['blur', 'submit'] },
{ type: 'number', min: 0, message: '出血量不能为负数', trigger: ['blur', 'submit'] }
],
specimenDisposal: [
{ required: true, message: '请填写标本处理方式', trigger: ['blur', 'submit'] }
],
operationEndTime: [
{ required: true, message: '请选择手术结束时间', trigger: ['change', 'submit'] }
],
patientDestination: [
{ required: true, message: '请选择患者去向', trigger: ['change', 'submit'] }
],
surgeonSignature: [
{ required: true, message: '请手术者签名', trigger: ['blur', 'submit'] }
],
recorderSignature: [
{ required: true, message: '请记录者签名', trigger: ['blur', 'submit'] }
],
recordDate: [
{ required: true, message: '请选择记录日期', trigger: ['change', 'submit'] }
]
});
// 生命周期
onMounted(() => {
// 初始化日期为当前日期时间
const today = new Date();
formData.operationDateTime = formatDateTime(today);
formData.operationEndTime = formatDateTime(today);
formData.recordDate = formatDate(today);
});
// 提交表单
const submit = () => {
formRef.value.validate((valid) => {
if (valid) {
ElMessage.success('手术记录保存成功');
console.log('手术记录数据:', formData);
}
});
};
// 打印功能
const handlePrint = () => {
formRef.value.validate((valid) => {
if (valid) {
window.print();
} else {
ElMessageBox.warning('请先完善表单信息再打印');
}
});
};
// 重置表单
const handleReset = () => {
ElMessageBox.confirm(
'确定要重置表单吗?所有已填写内容将被清空',
'确认重置',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
formRef.value.resetFields();
const today = new Date();
formData.operationDateTime = formatDateTime(today);
formData.operationEndTime = formatDateTime(today);
formData.recordDate = formatDate(today);
ElMessage.success('表单已重置');
});
};
// 日期格式化工具
const formatDate = (date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
const formatDateTime = (date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hour = String(date.getHours()).padStart(2, '0');
const minute = String(date.getMinutes()).padStart(2, '0');
return `${year}-${month}-${day} ${hour}:${minute}`;
};
</script>
<style scoped>
/* 样式与原代码保持一致,无需修改 */
.medical-document {
max-width: 1200px;
margin: 20px auto;
padding: 30px;
background: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
font-family: 'SimSun', '宋体', serif;
}
.doc-header {
text-align: center;
margin-bottom: 30px;
}
.doc-title {
font-size: 22px;
margin: 0 0 10px;
font-weight: bold;
}
.doc-subtitle {
font-size: 16px;
color: #666;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 2px solid #333;
}
.doc-content {
width: 100%;
}
.doc-section {
margin-bottom: 25px;
padding-bottom: 15px;
border-bottom: 1px dashed #ccc;
}
.section-title {
font-size: 18px;
margin: 0 0 15px;
color: #333;
font-weight: bold;
}
.adaptive-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 15px 20px;
margin-bottom: 15px;
}
.grid-item {
margin-bottom: 0;
display: flex;
flex-direction: column;
}
.grid-item .el-form-item__content {
flex: 1;
min-width: 0;
}
.full-width-item {
width: 100%;
margin-bottom: 15px;
}
.input-with-unit {
display: flex;
align-items: center;
gap: 8px;
}
.unit {
white-space: nowrap;
color: #666;
}
.signature-area {
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.signature-tip {
font-size: 12px;
color: #f56c6c;
margin-top: 4px;
}
.btn-group {
display: flex;
justify-content: center;
gap: 15px;
margin-top: 30px;
padding-top: 20px;
border-top: 2px solid #333;
}
.required .el-form-item__label::before {
content: '*';
color: #ff4d4f;
margin-right: 4px;
}
@media (max-width: 768px) {
.medical-document {
padding: 15px;
}
.adaptive-grid {
grid-template-columns: 1fr;
}
.doc-title {
font-size: 18px;
}
.section-title {
font-size: 16px;
}
}
@media print {
.btn-group {
display: none;
}
.medical-document {
box-shadow: none;
margin: 0;
padding: 0;
}
.el-input__inner, .el-select__input, .el-textarea__inner {
border: none !important;
box-shadow: none !important;
background: transparent !important;
}
.el-form-item__label {
font-weight: bold !important;
}
}
</style>