Files
his/openhis-ui-vue3/src/template/tySurgicalRecord.vue
chenqi b65841c0cc fix(common): 统一异常处理并迁移打印功能到hiprint
- 替换所有System.out.println和printStackTrace为slf4j日志记录
- 在BeanUtils、AuditFieldUtil、DateUtils、ServletUtils等工具类中添加Logger实例
- 在Flowable相关控制器和服务中统一错误日志记录格式
- 在代码生成器中添加日志记录功能
- 将前端打印组件从Lodop迁移到hiprint打印方案
- 更新体温单打印功能使用hiprint预览打印
- 移除调试用的console.log语句
- 修复打印模板中线条元素类型定义
2026-03-06 22:16:44 +08:00

375 lines
9.1 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="btn-group">
<el-button type="success" @click="handlePrint">打印记录</el-button>
<!-- <el-button type="warning" @click="handleReset">重置表单</el-button> -->
</div>
<!-- 标题区域 -->
<div class="doc-header">
<h2 class="doc-title">{{ userStore.hospitalName}}</h2>
<h1 class="doc-title">手术记录</h1>
<div class="doc-subtitle">病历号: {{ formData.busNo || '待填写' }}</div>
</div>
<!-- 内容区域 -->
<el-form
ref="formRef"
:model="formData"
:rules="rules"
label-width="100px"
label-align="left"
class="doc-content"
style="height: 50vh;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" placeholder="请输入年龄" />
</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="operationDate" class="grid-item required">
<el-date-picker
v-model="formData.operationDate"
type="date"
placeholder="选择手术日期"
value-format="YYYY-MM-DD"
style="width: 100%;"
/>
</el-form-item>
</div>
</section>
<!-- 手术综合信息 -->
<section class="doc-section">
<h2 class="section-title">手术综合信息</h2>
<el-form-item label="详细记录" prop="surgicalDetails" class="full-width-item required">
<el-input
v-model="formData.surgicalDetails"
type="textarea"
placeholder="请整合记录:手术团队、手术名称、术中发现、术后情况、签署信息等"
autosize
/>
</el-form-item>
</section>
</el-form>
</div>
</template>
<script setup>
import {onMounted, reactive, ref} from 'vue';
import {
ElButton,
ElDatePicker,
ElForm,
ElFormItem,
ElInput,
ElMessage,
ElMessageBox,
ElOption,
ElSelect
} from 'element-plus';
import {patientInfo} from '../views/doctorstation/components/store/patient';
import useUserStore from '../store/modules/user';
// 迁移到 hiprint
import { previewPrint } from '@/utils/printUtils.js';
defineOptions({
name: 'tySurgicalRecord'
});
// 表单引用
const formRef = ref(null);
// // Props与事件,去掉props.patientInfo改为直接从store获取
// const props = defineProps({
// patientInfo: {
// type: Object,
// required: true,
// },
// });
const props = defineProps({});
const emits = defineEmits(['submitOk']);
const userStore = useUserStore();
const patient = patientInfo.value;
// 表单数据
const formData = reactive({
busNo: patient?.busNo || '',
patientName: patient?.patientName || '',
gender: patient?.genderEnum_enumText || '',
age: patient?.age || '',
department: '',
bedNo: '',
operationDate: '',
surgicalDetails: ''
});
// 表单验证规则
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'] }
// ],
operationDate: [
{ required: true, message: '请选择手术日期', trigger: ['change', 'submit'] }
],
surgicalDetails: [
{ required: true, message: '请填写手术综合信息', trigger: ['blur', 'submit'] }
]
});
// 提交表单
const submit = () => {
formRef.value.validate((valid) => {
if (valid) {
emits('submitOk', formData);
ElMessage.success('手术记录保存成功');
console.log('手术记录数据:', formData);
}
});
};
// 打印功能 - 使用 hiprint
const handlePrint = () => {
formRef.value.validate((valid) => {
if (valid) {
const printDom = document.querySelector('.form-container');
if (printDom) {
previewPrint(printDom);
} else {
ElMessage.warning('未找到打印内容');
}
} else {
ElMessage.warning('请先完善表单信息再打印');
}
});
};
// 重置表单
const handleReset = () => {
ElMessageBox.confirm(
'确定要重置表单吗?所有已填写内容将被清空',
'确认重置',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
formRef.value.resetFields();
const today = new Date();
formData.operationDate = 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 setFormData = (data) => {
if (data) {
Object.assign(formData, data);
}
};
// 生命周期
onBeforeMount(() => {});
onMounted(() => {
// 初始化手术日期为当前时间
console.log('patientInfo', patient);
console.log('userStore', userStore, formData.department);
if (!formData.operationDate) {
formData.operationDate = formatDate(new Date());
}
if(formData.department==='' ){
formData.department=userStore.orgName;
}
});
// 暴露接口
defineExpose({ formData, submit, setFormData });
</script>
<style scoped>
.medical-document {
max-width: 1200px;
height: auto;
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: 24px;
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: 30px;
padding-bottom: 20px;
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;
}
/* 按钮组强制靠右增加margin确保间距 */
.btn-group {
display: flex;
justify-content: flex-end;
gap: 20px;
margin-bottom: 30px;
width: 100%; /* 确保容器占满宽度,实现真正靠右 */
}
.required .el-form-item__label::before {
content: '*';
color: #ff4d4f;
margin-right: 4px;
}
.el-textarea__inner {
line-height: 1.6;
padding: 12px;
}
@media (max-width: 768px) {
.medical-document {
padding: 15px;
}
.adaptive-grid {
grid-template-columns: 1fr;
}
.doc-title {
font-size: 20px;
}
.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>