581 【住院医生站-临床医嘱-手术】手术申请单缺失多项核心业务字段与强拦截逻辑,导致医疗安全制度无法落地且阻断手术室排班闭环
This commit is contained in:
@@ -48,6 +48,11 @@ public interface IOutpatientRegistrationAppService {
|
||||
IPage<PractitionerMetadata> getPractitionerMetadataByLocationId(Long orgId, String searchKey, Integer pageNo,
|
||||
Integer pageSize);
|
||||
|
||||
/**
|
||||
* 查询全院医生(不限科室),按角色过滤
|
||||
*/
|
||||
IPage<PractitionerMetadata> getAllDoctors(String searchKey, Integer pageNo, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 根据机构id筛选服务项目
|
||||
*
|
||||
|
||||
@@ -243,6 +243,22 @@ public class OutpatientRegistrationAppServiceImpl implements IOutpatientRegistra
|
||||
return practitionerMetadataPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询全院医生(不限科室),按角色过滤
|
||||
*/
|
||||
@Override
|
||||
public IPage<PractitionerMetadata> getAllDoctors(String searchKey, Integer pageNo, Integer pageSize) {
|
||||
QueryWrapper<PractitionerMetadata> queryWrapper = HisQueryUtils.buildQueryWrapper(null, searchKey,
|
||||
new HashSet<>(Arrays.asList("name", "py_str", "wb_str")), null);
|
||||
IPage<PractitionerMetadata> page =
|
||||
outpatientRegistrationAppMapper.getAllDoctorPage(new Page<>(pageNo, pageSize),
|
||||
PractitionerRoles.DOCTOR.getCode(), queryWrapper);
|
||||
page.getRecords().forEach(e -> {
|
||||
e.setGenderEnum_enumText(EnumUtils.getInfoByValue(AdministrativeGender.class, e.getGenderEnum()));
|
||||
});
|
||||
return page;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据机构id筛选服务项目
|
||||
*
|
||||
|
||||
@@ -87,6 +87,17 @@ public class OutpatientRegistrationController {
|
||||
iOutpatientRegistrationAppService.getPractitionerMetadataByLocationId(orgId, searchKey, pageNo, pageSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询全院医生(不限科室),用于手术申请等需跨科室选择医生的场景
|
||||
*/
|
||||
@GetMapping(value = "/all-doctors")
|
||||
public R<?> getAllDoctors(
|
||||
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize) {
|
||||
return R.ok(iOutpatientRegistrationAppService.getAllDoctors(searchKey, pageNo, pageSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据机构id筛选服务项目
|
||||
*/
|
||||
|
||||
@@ -24,6 +24,13 @@ public interface OutpatientRegistrationAppMapper {
|
||||
@Param("orgId") Long orgId, @Param("RoleCode") String RoleCode,
|
||||
@Param(Constants.WRAPPER) QueryWrapper<PractitionerMetadata> queryWrapper);
|
||||
|
||||
/**
|
||||
* 查询全院医生(不限科室),按角色过滤
|
||||
*/
|
||||
IPage<PractitionerMetadata> getAllDoctorPage(@Param("page") Page<PractitionerMetadata> page,
|
||||
@Param("RoleCode") String RoleCode,
|
||||
@Param(Constants.WRAPPER) QueryWrapper<PractitionerMetadata> queryWrapper);
|
||||
|
||||
/**
|
||||
* 根据病人id和科室id查询当日挂号次数
|
||||
*/
|
||||
|
||||
@@ -31,6 +31,34 @@
|
||||
${ew.customSqlSegment}
|
||||
</select>
|
||||
|
||||
<!-- 查询全院医生(不限科室),用于手术申请等需跨科室选择医生的场景 -->
|
||||
<select id="getAllDoctorPage" resultType="com.openhis.web.chargemanage.dto.PractitionerMetadata">
|
||||
SELECT T3.tenant_id,
|
||||
T3.ID,
|
||||
T3.NAME,
|
||||
T3.gender_enum,
|
||||
T3.py_str,
|
||||
T3.wb_str,
|
||||
T3.dr_profttl_code
|
||||
FROM (
|
||||
SELECT T1.tenant_id,
|
||||
T1.ID,
|
||||
T1.NAME,
|
||||
T1.gender_enum,
|
||||
T1.py_str,
|
||||
T1.wb_str,
|
||||
T1.dr_profttl_code
|
||||
FROM adm_practitioner AS T1
|
||||
WHERE T1.delete_flag = '0'
|
||||
AND EXISTS(SELECT 1
|
||||
FROM adm_practitioner_role AS T2
|
||||
WHERE T2.practitioner_id = T1.ID
|
||||
AND T2.delete_flag = '0'
|
||||
AND T2.ROLE_code = #{RoleCode})
|
||||
) AS T3
|
||||
${ew.customSqlSegment}
|
||||
</select>
|
||||
|
||||
<select id="getNumByPatientIdAndOrganizationId" resultType="Integer">
|
||||
SELECT COUNT
|
||||
(1)
|
||||
|
||||
@@ -111,6 +111,17 @@ export function getSurgery(data) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询全院医生(不限科室),用于手术申请
|
||||
*/
|
||||
export function getAllDoctors(params) {
|
||||
return request({
|
||||
url: '/charge-manage/register/all-doctors',
|
||||
method: 'get',
|
||||
params: params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 住院患者转科
|
||||
*/
|
||||
|
||||
@@ -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?.();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user