581 【住院医生站-临床医嘱-手术】手术申请单缺失多项核心业务字段与强拦截逻辑,导致医疗安全制度无法落地且阻断手术室排班闭环

This commit is contained in:
wangjian963
2026-06-02 13:22:09 +08:00
parent ac0d563274
commit cde58cf18f
8 changed files with 120 additions and 21 deletions

View File

@@ -111,6 +111,17 @@ export function getSurgery(data) {
});
}
/**
* 查询全院医生(不限科室),用于手术申请
*/
export function getAllDoctors(params) {
return request({
url: '/charge-manage/register/all-doctors',
method: 'get',
params: params,
});
}
/**
* 住院患者转科
*/

View File

@@ -129,6 +129,8 @@ const showApplicationFormDialog = (name) => {
applicationFormNameRef?.value.getLocationInfo();
// 诊断目录列表
applicationFormNameRef?.value.getDiagnosisList();
// 医生列表(手术申请单专用)
applicationFormNameRef?.value.loadDoctorOptions?.();
}, 150);
} else {
applicationFormName.value = components.value[name];
@@ -140,6 +142,8 @@ const showApplicationFormDialog = (name) => {
applicationFormNameRef?.value.getLocationInfo();
// 诊断目录列表
applicationFormNameRef?.value.getDiagnosisList();
// 医生列表(手术申请单专用)
applicationFormNameRef?.value.loadDoctorOptions?.();
});
}
};

View File

@@ -173,7 +173,7 @@
v-model="form.mainSurgeonId"
filterable
clearable
placeholder="请选择主刀医生(支持搜索)"
placeholder="请输入关键字搜索医生"
style="width: 100%"
>
<el-option
@@ -196,7 +196,7 @@
v-model="form.assistant1Id"
filterable
clearable
placeholder="请选择第一助手(支持搜索)"
placeholder="请输入关键字搜索医生"
style="width: 100%"
>
<el-option
@@ -219,7 +219,7 @@
v-model="form.assistant2Id"
filterable
clearable
placeholder="请选择第二助手(支持搜索)"
placeholder="请输入关键字搜索医生"
style="width: 100%"
>
<el-option
@@ -331,21 +331,22 @@
</div>
</template>
<script setup name="Surgery">
import {computed, getCurrentInstance, onBeforeMount, onMounted, reactive, ref, watch} from 'vue';
import {computed, defineEmits, getCurrentInstance, onBeforeMount, onMounted, reactive, ref, watch} from 'vue';
import {patientInfo} from '../../../store/patient.js';
import {getDepartmentList} from '@/api/public.js';
import {getEncounterDiagnosis} from '../../api.js';
import {getSurgeryPage, saveSurgery} from './api';
import {getAllDoctors, getSurgeryPage, saveSurgery} from './api';
import {ElMessage} from 'element-plus';
import {getDicts} from '@/api/system/dict/data';
import {listUser} from '@/api/system/user';
import useUserStore from '@/store/modules/user';
const { proxy } = getCurrentInstance();
const emits = defineEmits(['submitOk']);
const userStore = useUserStore();
// 模块级缓存:避免每次打开弹窗都重新请求手术项目列表
// 模块级缓存:避免每次打开弹窗都重新请求
let surgeryRecordsCache = null; // 原始 API 记录
let surgeryMappedCache = null; // 映射后的 el-transfer 数据
let doctorCache = null; // 医生列表(含默认主刀医生 ID
const transferRef = ref(null);
const dbTotal = ref(0); // 数据库中的手术项目总数
const checkedCount = computed(() => transferValue.value.length);
@@ -476,7 +477,11 @@ const form = reactive({
primaryDiagnosisList: [], //主诊断目录
otherDiagnosisList: [], //其他断目录
});
const rules = reactive({});
const rules = reactive({
surgeryLevel: [{ required: true, message: '请选择手术等级', trigger: 'change' }],
anesthesiaType: [{ required: true, message: '请选择麻醉方式', trigger: 'change' }],
surgerySite: [{ required: true, message: '请选择手术部位', trigger: 'change' }],
});
const state = reactive({});
// 字典选项
const surgeryLevelOptions = ref([]);
@@ -525,29 +530,32 @@ const loadDictOptions = async () => {
};
/**
* 加载医生选项列表
* 加载医生列表(全院 doctor 角色)+ 模块级缓存
* 后端 SQL 直接过滤 role_code='doctor',无需前端过滤,快且数据完整
*/
const loadDoctorOptions = async () => {
if (doctorCache) {
doctorOptions.value = doctorCache.list;
if (doctorCache.defaultId) form.mainSurgeonId = doctorCache.defaultId;
return;
}
try {
const res = await listUser({ pageNo: 1, pageSize: 1000 });
const res = await getAllDoctors({ pageNo: 1, pageSize: 200 });
if (res.code === 200) {
const data = res.data?.records || res.rows || res.data || [];
if (Array.isArray(data)) {
doctorOptions.value = data.map(item => ({
id: item.practitionerId || item.id || item.userId,
name: item.nickName || item.name || item.userName,
id: item.id,
name: item.name,
}));
}
}
// 默认主刀医生设为当前登录用户
let defaultId = '';
if (userStore.nickName) {
const currentUser = doctorOptions.value.find(
doc => doc.name === userStore.nickName
);
if (currentUser) {
form.mainSurgeonId = currentUser.id;
}
const cur = doctorOptions.value.find(d => d.name === userStore.nickName);
if (cur) { defaultId = cur.id; form.mainSurgeonId = defaultId; }
}
doctorCache = { list: doctorOptions.value, defaultId };
} catch (e) {
console.error('加载医生列表失败:', e);
}
@@ -624,10 +632,19 @@ const submit = () => {
}
});
};
/** 递归规范化树形科室 ID 为字符串,确保与 el-tree-select / findTreeItem 兼容 */
const normalizeOrgTreeIds = (nodes) => {
if (!Array.isArray(nodes)) return [];
return nodes.map((node) => ({
...node,
id: node.id != null ? String(node.id) : node.id,
children: node.children?.length ? normalizeOrgTreeIds(node.children) : undefined,
}));
};
/** 查询科室 */
const getLocationInfo = () => {
getDepartmentList().then((res) => {
orgOptions.value = res.data || [];
orgOptions.value = normalizeOrgTreeIds(res.data || []);
});
};
// 获取诊断目录
@@ -664,7 +681,7 @@ function getDiagnosisList() {
}
});
}
defineExpose({ state, submit, getLocationInfo, getDiagnosisList, getList });
defineExpose({ state, submit, getLocationInfo, getDiagnosisList, getList, loadDoctorOptions });
</script>
<style lang="scss" scoped>
.surgery-container {