Compare commits

..

1 Commits

Author SHA1 Message Date
张飞
4092abfce9 Fix Bug #477: 住院医生工作站-住院检查申请详情弹窗中"发往科室"字段显示为短横线(-),未正常获取数据
根因分析:
1. 前端组件使用了错误的API获取科室列表:表单使用getDepartmentList(/app-common/department-list)
   保存的targetDepartment ID,但详情弹窗使用getOrgList(/base-data-manage/organization/organization)
   查询,两个接口返回的数据结构和ID不同,导致recursionFun无法匹配到科室名称
2. recursionFun中obj.children可能为null/undefined,直接遍历会抛TypeError
3. getLocationInfo是异步调用,handleViewDetail可能在科室数据加载完成前被调用

修复:
- 统一使用getDepartmentList(@/api/public.js)获取科室数据,与表单组件保持一致
- recursionFun增加children空值保护
- handleViewDetail改为async,打开详情前确保科室数据已加载
2026-05-13 00:05:17 +08:00
8 changed files with 17 additions and 78 deletions

View File

@@ -7,7 +7,6 @@ import com.core.common.utils.MessageUtils;
import com.openhis.administration.domain.Location;
import com.openhis.administration.domain.Organization;
import com.openhis.administration.domain.OrganizationLocation;
import com.openhis.workflow.domain.ActivityDefinition;
import com.openhis.administration.mapper.OrganizationLocationMapper;
import com.openhis.administration.service.ILocationService;
import com.openhis.administration.service.IOrganizationLocationService;
@@ -71,7 +70,6 @@ public class OrganizationLocationAppServiceImpl implements IOrganizationLocation
// 获取科室下拉选列表
List<Organization> organizationList = organizationService.getList(OrganizationType.DEPARTMENT.getValue(), null);
List<OrgLocInitDto.departmentOption> organizationOptions = organizationList.stream()
.filter(organization -> organization != null && organization.getName() != null)
.map(organization -> new OrgLocInitDto.departmentOption(organization.getId(), organization.getName()))
.collect(Collectors.toList());
initDto.setLocationFormOptions(chargeItemStatusOptions).setDepartmentOptions(organizationOptions);
@@ -133,18 +131,12 @@ public class OrganizationLocationAppServiceImpl implements IOrganizationLocation
@Override
public R<?> addOrEditOrgLoc(OrgLocQueryDto orgLocQueryDto) {
// Validate required fields before processing
if (orgLocQueryDto.getOrganizationId() == null) {
return R.fail("请选择执行科室");
}
OrganizationLocation orgLoc = new OrganizationLocation();
BeanUtils.copyProperties(orgLocQueryDto, orgLoc);
Long activityDefinitionId = orgLoc.getActivityDefinitionId();
ActivityDefinition activityDef = activityDefinitionId != null
? activityDefinitionMapper.selectById(activityDefinitionId) : null;
String activityName = activityDef != null ? activityDef.getName() : "";
String activityName = activityDefinitionId != null
? activityDefinitionMapper.selectById(activityDefinitionId).getName() : "";
List<OrganizationLocation> organizationLocationList =
organizationLocationService.getOrgLocListByOrgIdAndActivityDefinitionId(orgLoc.getActivityDefinitionId());

View File

@@ -341,28 +341,6 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
&& (DbOpType.INSERT.getCode().equals(e.getDbOpType()) || DbOpType.UPDATE.getCode().equals(e.getDbOpType())))
.collect(Collectors.toList());
// 防重复保存:对新增医嘱进行去重,避免签发单条长期医嘱时产生重复记录
Set<String> longUniqueKeySet = new HashSet<>();
List<RegAdviceSaveDto> longUniqueList = new ArrayList<>();
for (RegAdviceSaveDto adviceSaveDto : longInsertOrUpdateList) {
String uniqueKey = adviceSaveDto.getPatientId() + "_"
+ adviceSaveDto.getEncounterId() + "_"
+ adviceSaveDto.getAdviceDefinitionId() + "_"
+ adviceSaveDto.getDose() + "_"
+ adviceSaveDto.getMethodCode() + "_"
+ adviceSaveDto.getRateCode();
if (DbOpType.INSERT.getCode().equals(adviceSaveDto.getDbOpType()) && longUniqueKeySet.contains(uniqueKey)) {
log.warn("防重复保存:检测到重复长期医嘱,跳过保存 - patientId={}, encounterId={}, adviceDefinitionId={}, dose={}",
adviceSaveDto.getPatientId(), adviceSaveDto.getEncounterId(),
adviceSaveDto.getAdviceDefinitionId(), adviceSaveDto.getDose());
continue;
}
longUniqueKeySet.add(uniqueKey);
longUniqueList.add(adviceSaveDto);
}
log.info("防重复保存(长期):去重前{}条,去重后{}条", longInsertOrUpdateList.size(), longUniqueList.size());
longInsertOrUpdateList = longUniqueList;
for (RegAdviceSaveDto regAdviceSaveDto : longInsertOrUpdateList) {
boolean firstTimeSave = false;// 第一次保存
longMedicationRequest = new MedicationRequest();
@@ -428,29 +406,6 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
.getValue().equals(e.getTherapyEnum())
&& (DbOpType.INSERT.getCode().equals(e.getDbOpType()) || DbOpType.UPDATE.getCode().equals(e.getDbOpType())))
.collect(Collectors.toList());
// 防重复保存:对新增医嘱进行去重
Set<String> tempUniqueKeySet = new HashSet<>();
List<RegAdviceSaveDto> tempUniqueList = new ArrayList<>();
for (RegAdviceSaveDto adviceSaveDto : tempInsertOrUpdateList) {
String uniqueKey = adviceSaveDto.getPatientId() + "_"
+ adviceSaveDto.getEncounterId() + "_"
+ adviceSaveDto.getAdviceDefinitionId() + "_"
+ adviceSaveDto.getDose() + "_"
+ adviceSaveDto.getMethodCode() + "_"
+ adviceSaveDto.getRateCode();
if (DbOpType.INSERT.getCode().equals(adviceSaveDto.getDbOpType()) && tempUniqueKeySet.contains(uniqueKey)) {
log.warn("防重复保存:检测到重复临时医嘱,跳过保存 - patientId={}, encounterId={}, adviceDefinitionId={}, dose={}",
adviceSaveDto.getPatientId(), adviceSaveDto.getEncounterId(),
adviceSaveDto.getAdviceDefinitionId(), adviceSaveDto.getDose());
continue;
}
tempUniqueKeySet.add(uniqueKey);
tempUniqueList.add(adviceSaveDto);
}
log.info("防重复保存(临时):去重前{}条,去重后{}条", tempInsertOrUpdateList.size(), tempUniqueList.size());
tempInsertOrUpdateList = tempUniqueList;
for (RegAdviceSaveDto regAdviceSaveDto : tempInsertOrUpdateList) {
boolean firstTimeSave = false;// 第一次保存
tempMedicationRequest = new MedicationRequest();

View File

@@ -162,15 +162,11 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
serviceRequest.setEncounterId(encounterId); // 就诊id
serviceRequest.setAuthoredTime(curDate); // 请求签发时间
// 优先使用前端传来的 positionId用户手动选择的发往科室未传时从配置表查找
Long positionId = activitySaveDto.getPositionId();
Long positionId = activityOrganizationConfig.stream()
.filter(dto -> activitySaveDto.getAdviceDefinitionId().equals(dto.getActivityDefinitionId()))
.map(ActivityOrganizationConfigDto::getOrganizationId).findFirst().orElse(null);
if (positionId == null) {
positionId = activityOrganizationConfig.stream()
.filter(dto -> activitySaveDto.getAdviceDefinitionId().equals(dto.getActivityDefinitionId()))
.map(ActivityOrganizationConfigDto::getOrganizationId).findFirst().orElse(null);
if (positionId == null) {
throw new ServiceException(activitySaveDto.getAdviceDefinitionName() + "未配置当前时间段的执行科室");
}
throw new ServiceException(activitySaveDto.getAdviceDefinitionName() + "未配置当前时间段的执行科室");
}
serviceRequest.setOrgId(positionId); // 执行科室

View File

@@ -231,7 +231,7 @@
ae.priority_enum,
ae.organization_id,
ae.start_time AS in_hos_time,
COALESCE(bed.start_time, ae.start_time) AS start_time,
bed.start_time,
bed.location_id AS bed_id,
bed.location_name AS bed_name,
house.location_id AS house_id,

View File

@@ -992,9 +992,7 @@ function handleRowClick(row) {
selectedItems.value = [];
activeDetailTab.value = 'applyForm';
request({ url: `/exam/apply/${row.applyNo}`, method: 'get' }).then(async res => {
// Axios interceptor already returns res.data (AjaxResult body: {code, data, items})
// Don't double-unwrap: if res has 'code', use res directly; otherwise fall back to res.data
const d = (res && res.code !== undefined) ? res : (res.data || res);
const d = res.data || res;
if (d.data) Object.assign(form, d.data);
if (d.items && Array.isArray(d.items)) {
try {

View File

@@ -164,7 +164,7 @@ onMounted(() => {
* type(1watch监听类型 2:点击保存类型)
* selectProjectIds(选中项目的id数组)
* */
const projectWithDepartment = (selectProjectIds, type) => {
const projectWithDepartment = (selectProjectIds) => {
//1.获取选中的项目 2.判断项目的执行科室是否相同 3.判断执行科室是否配置 4.将项目的执行科室复值到执行科室下拉选位置
let isRelease = true;
// 选中项目的数组
@@ -225,13 +225,9 @@ const submit = () => {
if (transferValue.value.length == 0) {
return proxy.$message.error('请选择申请单');
}
// 🔧 Bug #516: 捕获用户手动选择的发往科室,避免 projectWithDepartment 将其覆盖为默认科室
const savedTargetDept = form.targetDepartment;
if (!projectWithDepartment(transferValue.value, 2)) {
return;
}
// 用户手动选择的发往科室优先于项目默认执行科室
const targetDept = savedTargetDept || form.targetDepartment;
let applicationListAllFilter = applicationListAll.value.filter((item) => {
return transferValue.value.includes(item.adviceDefinitionId);
});
@@ -242,7 +238,7 @@ const submit = () => {
unitCode: item.priceList[0].unitCode /** 请求单位编码 */,
unitPrice: item.priceList[0].price /** 单价 */,
totalPrice: item.priceList[0].price /** 总价 */,
positionId: targetDept || item.positionId, // 用户指定发往科室优先于项目默认执行科室
positionId: item.positionId || form.targetDepartment, //执行科室id未配置时使用用户手动选择的科室
ybClassEnum: item.ybClassEnum, //类别医保编码
conditionId: item.conditionId, //诊断ID
encounterDiagnosisId: item.encounterDiagnosisId, //就诊诊断id

View File

@@ -801,10 +801,8 @@ function clickRowDb(row, column, event) {
return;
}
row.showPopover = false;
// 允许所有 statusEnum==1 的医嘱进入编辑
// 1. 新医嘱(无 requestId):待保存
// 2. 护士退回医嘱(有 requestId退回后状态重置为 DRAFT(1),需允许医生编辑修改后重新签发
if (row.statusEnum == 1) {
// “待签发(已保存 requestId存在)”不允许再编辑;仅“待保存(无requestId)”允许编辑
if (row.statusEnum == 1 && !row.requestId) {
// 确保治疗类型为字符串,方便与单选框 label 对齐,默认为长期医嘱('1')
row.therapyEnum = String(row.therapyEnum ?? '1');
row.isEdit = true;

View File

@@ -19,10 +19,14 @@
<el-tab-pane label="检验申请" name="test">
<TestApplication ref="testApplicationRef" :show-status-column="true" />
</el-tab-pane>
```vue
<el-tab-pane label="检查申请" name="examine">
<ExamineApplication ref="examineApplicationRef" />
</el-tab-pane>
<!-- 汇总发药申请属于护士站职能医生站不显示 -->
```
<el-tab-pane label="汇总发药申请" name="summaryDrug">
<SummaryDrugApplication ref="summaryDrugApplicationRef" />
</el-tab-pane>
<el-tab-pane label="手术申请" name="surgery">
<SurgeryApplication ref="surgeryApplicationRef" />
</el-tab-pane>