276 lines
11 KiB
Vue
Raw Normal View History

2025-05-20 16:34:38 +08:00
<template>
<div class="compact-form">
<el-col :span="24" :xs="24">
<el-form :model="labPat" label-width="100px" class="compact-form" label-position="left">
<el-form-item label="病人来源" label-width="70px">
<el-col :span="16">
2025-09-17 10:19:20 +08:00
<dict-input v-model="labPat.brly" :dict-type="'PT'" placeholder="请输入病人来源" :fetch-dict="fetchDict"
@update:labelValue="(label) => labPat.brlyLabel = label" dialog-title="选择病人来源"
@blur="handleFieldChange"
@keyup.enter="handleFieldChange"
@select="handleDictSelect"
/>
2025-05-20 16:34:38 +08:00
</el-col>
<el-col :span="8">
2025-09-17 10:19:20 +08:00
<el-switch v-model="jzbzSwitch" active-text="急诊" active-color="#FD0101" @change="handleFieldChange"></el-switch>
2025-05-20 16:34:38 +08:00
</el-col>
</el-form-item>
<el-form-item label="病 历 号" label-width="70px">
2025-09-17 10:19:20 +08:00
<el-input v-model="labPat.brdh" placeholder="请输入病历号"
@blur="handleFieldChange"
@keyup.enter="handleFieldChange"></el-input>
2025-05-20 16:34:38 +08:00
</el-form-item>
<el-form-item label="姓 名" label-width="70px">
2025-09-17 10:19:20 +08:00
<el-input v-model="labPat.brxm" placeholder="请输入姓名"
@blur="handleFieldChange"
@keyup.enter="handleFieldChange"></el-input>
2025-05-20 16:34:38 +08:00
</el-form-item>
<el-form-item label="性 别" label-width="70px">
<el-col :span="8">
2025-09-17 10:19:20 +08:00
<dict-input v-model="labPat.brxb" placeholder="性别" :dict-type="'SX'" :fetch-dict="fetchDict"
@update:labelValue="(label) => labPat.brxbLabel = label"
@blur="handleFieldChange"
@keyup.enter="handleFieldChange"
@select="handleDictSelect"
/>
2025-05-20 16:34:38 +08:00
</el-col>
<el-col :span="4"><div>年龄</div></el-col>
<el-col :span="6">
2025-09-17 10:19:20 +08:00
<el-input v-model="labPat.nl" placeholder="年龄"
@blur="handleFieldChange"
@keyup.enter="handleFieldChange"></el-input>
2025-05-20 16:34:38 +08:00
</el-col>
<el-col :span="6">
2025-09-17 10:19:20 +08:00
<dict-input v-model="labPat.nldw" placeholder="年月" :dict-type="'AU'" :fetch-dict="fetchDict"
@update:labelValue="(label) => labPat.nldwLabel = label"
@blur="handleFieldChange"
@keyup.enter="handleFieldChange"
@select="handleDictSelect"
/>
2025-05-20 16:34:38 +08:00
</el-col>
</el-form-item>
<el-form-item label="送检科室" label-width="70px">
2025-09-17 10:19:20 +08:00
<dict-input v-model="labPat.ksdh" placeholder="请输入科室" :dict-type="'DP'" :fetch-dict="fetchDict"
@update:labelValue="(label) => labPat.ksdhLabel = label"
@blur="handleFieldChange"
@keyup.enter="handleFieldChange"
@select="handleDictSelect"
/>
2025-05-20 16:34:38 +08:00
</el-form-item>
<el-form-item label="床 号" label-width="70px">
2025-09-17 10:19:20 +08:00
<el-input v-model="labPat.ch" placeholder="请输入床号"
@blur="handleFieldChange"
@keyup.enter="handleFieldChange"
></el-input>
2025-05-20 16:34:38 +08:00
</el-form-item>
<el-form-item label="样本类型" label-width="70px">
2025-09-17 10:19:20 +08:00
<dict-input v-model="labPat.yblx" placeholder="请输入样本类型" :dict-type="'BT'" :fetch-dict="fetchDict"
@update:labelValue="(label) => labPat.yblxLabel = label"
@blur="handleFieldChange"
@keyup.enter="handleFieldChange"
@select="handleDictSelect"
/>
2025-05-20 16:34:38 +08:00
</el-form-item>
<el-form-item label="申请医生" label-width="70px">
2025-09-17 10:19:20 +08:00
<dict-input v-model="labPat.sjys" placeholder="请输入申请医生" :dict-type="'SRD'" :fetch-dict="fetchDict"
@update:labelValue="(label) => labPat.sjysLabel = label"
@blur="handleFieldChange"
@keyup.enter="handleFieldChange"
@select="handleDictSelect"
/>
2025-05-20 16:34:38 +08:00
</el-form-item>
<el-form-item label="上机时间" label-width="70px">
2025-09-17 10:19:20 +08:00
<el-date-picker v-model="labPat.sqsj" type="datetime" placeholder="上机时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
@blur="handleFieldChange"
@keyup.enter="handleFieldChange"
></el-date-picker>
2025-05-20 16:34:38 +08:00
</el-form-item>
<el-form-item label="采样时间" label-width="70px">
2025-09-17 10:19:20 +08:00
<el-date-picker v-model="labPat.cyrq" type="datetime" placeholder="采样时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
@blur="handleFieldChange"
@keyup.enter="handleFieldChange"
></el-date-picker>
2025-05-20 16:34:38 +08:00
</el-form-item>
<el-form-item label="报告时间" label-width="70px">
2025-09-17 10:19:20 +08:00
<el-date-picker v-model="labPat.dysj" type="datetime" placeholder="报告时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
@blur="handleFieldChange"
@keyup.enter="handleFieldChange"
></el-date-picker>
2025-05-20 16:34:38 +08:00
</el-form-item>
<el-form-item label="临床诊断" label-width="70px">
2025-09-17 10:19:20 +08:00
<el-input v-model="labPat.zd" placeholder="请输入临床诊断" @blur="handleFieldChange" @keyup.enter="handleFieldChange"></el-input>
2025-05-20 16:34:38 +08:00
</el-form-item>
<el-form-item label="备 注" label-width="70px">
2025-09-17 10:19:20 +08:00
<el-input v-model="labPat.bz" placeholder="请输入备注" @blur="handleFieldChange" @keyup.enter="handleFieldChange"></el-input>
2025-05-20 16:34:38 +08:00
</el-form-item>
<el-form-item label="检验医生" label-width="70px">
2025-09-17 10:19:20 +08:00
<el-input v-model="labPat.yhdh" placeholder="请输入检验医生" @blur="handleFieldChange" @keyup.enter="handleFieldChange"></el-input>
2025-05-20 16:34:38 +08:00
</el-form-item>
<el-form-item label="审核医生" label-width="70px">
2025-09-17 10:19:20 +08:00
<el-input v-model="labPat.hdys" placeholder="请输入审核医生" @blur="handleFieldChange" @keyup.enter="handleFieldChange"></el-input>
2025-05-20 16:34:38 +08:00
</el-form-item>
<el-form-item label="审核状态" >
<el-radio-group v-model="labPat.jgbz">
<el-radio :label="0">未审核</el-radio>
<el-radio :label="2">已审核</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div class="compact-form">
<el-button type="primary" @click="saveMain">保存</el-button>
<el-button @click="resetMain">重置</el-button>
</div>
</el-col>
</div>
</template>
<script setup>
import DictInput from './DictInput.vue';
2025-09-17 10:19:20 +08:00
import {changepatcolumn, updateLabPat} from "@/api/liswork/work/LisWork.js";
const loading = ref(true);
2025-05-20 16:34:38 +08:00
const props = defineProps({
labPat: {
type: Object,
required: true
},
//结果主键
labPatKey:{
type: Array,
default: () => []
}
});
2025-09-17 10:19:20 +08:00
// 计算属性:将布尔值转换为 0/1 绑定到 labPat.jzbz
const jzbzSwitch = computed({
get() {
// 后端返回的 0/1 转换为布尔值(供开关显示)
return props.labPat.jzbz == "1";
},
set(checked) {
// 开关的 true/false 转换为 1/0 存到实体中
props.labPat.jzbz = checked ? "1" : "0";
}
});
2025-05-20 16:34:38 +08:00
const emit = defineEmits(['update:labPat']);
// 通过inject获取全局方法
const comDict = inject('comDict');
2025-09-17 10:19:20 +08:00
const lastValue = ref(JSON.stringify(props.labPat));
const prevFieldState = ref(null); // 记录当前修改的字段及旧值 { field: '字段名', oldValue: 旧值 }
/**
* 通用字段变化处理(失焦、回车触发)
*/
const handleFieldChange = async () => {
await triggerApiUpdate();
};
/**
* 字典选择完成处理(弹窗选择后触发)
*/
const handleDictSelect = async () => {
// 字典选择后直接触发更新
await triggerApiUpdate();
};
/**
* 对比新旧对象,找出修改的字段及旧值
* @param oldObj 旧对象
* @param newObj 新对象
* @returns { field: string, oldValue: any } | null
*/
const getChangedField = (oldObj, newObj) => {
const oldKeys = Object.keys(oldObj);
for (const key of oldKeys) {
if (newObj[key] !== oldObj[key]) {
return { field: key, oldValue: oldObj[key], newValue: newObj[key] };
}
}
return null;
};
/**
* 触发API更新的核心方法
*/
const triggerApiUpdate = async () => {
const currentLabPat = toRaw(props.labPat);
const currentValue = JSON.stringify(currentLabPat);
const oldValue = lastValue.value;
// 只有值发生变化时才调用API
if (currentValue !== lastValue.value) {
// 2. 找出修改的字段及旧值(用于回滚)
const oldObj = JSON.parse(oldValue);
const changedField = getChangedField(oldObj, currentLabPat);
prevFieldState.value = changedField; // 记录修改前的状态
console.log('prevFieldState:', prevFieldState.value)
console.log('labPatKey:', props.labPatKey)
try {
loading.value = true;
changepatcolumn({...props.labPatKey,column:changedField?.field,value:changedField?.newValue}).then(response => {
console.log('response:', response)
console.log('表单更新成功');
lastValue.value = currentValue;
loading.value = false;
}) .catch(error => {
console.error('表单更新失败', error);
loading.value = false;
if (prevFieldState.value) {
const { field, oldValue,newValue } = prevFieldState.value;
// 回滚字段值(通过emit触发父组件更新,避免直接修改props)
emit('update:labPat', {
...toRaw(props.labPat),
[field]: oldValue
});
} else {
// 若未找到具体字段,整体回滚
emit('update:labPat', JSON.parse(oldValue));
}
// 回滚后更新缓存
lastValue.value = oldValue;
2025-05-20 16:34:38 +08:00
2025-09-17 10:19:20 +08:00
});
} catch (error) {
console.error('更新接口调用失败:', error);
}finally {
loading.value = false;
prevFieldState.value = null; // 清空临时记录
}
}
};
// 手动保存
const saveMain = async () => {
await triggerApiUpdate();
2025-05-20 16:34:38 +08:00
};
// 重置方法
const resetMain = () => {
2025-09-17 10:19:20 +08:00
const resetData = {
...props.labPat,
2025-05-20 16:34:38 +08:00
brly: '',
brlyLabel: '',
ksdh: '',
ksdhLabel: '',
brxb: '',
brxbLabel: '',
nldw: '',
nldwLabel: '',
2025-09-17 10:19:20 +08:00
jzbz: 0,
jgbz: 0
};
emit('update:labPat', resetData);
lastValue.value = JSON.stringify(resetData);
};
2025-05-20 16:34:38 +08:00
// 字典获取方法(适配子组件)
const fetchDict = async (dictType) => {
const dictRefs = await comDict(dictType);
// 根据实际字典结构返回数组(需与子组件匹配)
return dictRefs[dictType]?.value || [];
};
</script>
<style scoped lang="scss">
.compact-form .el-form-item {
margin-bottom: 10px;
}
.compact-form .el-form-item__label {
padding-bottom: 5px;
}
</style>