Merge branch 'zhaoyun' of http://192.168.110.253:3000/wangyizhe/his into zhaoyun

# Conflicts:
#	openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/appservice/impl/RequestFormManageAppServiceImpl.java
#	openhis-ui-vue3/src/views/inpatientDoctor/home/components/order/index.vue
This commit is contained in:
2026-05-22 09:47:44 +08:00
5 changed files with 68 additions and 20 deletions

View File

@@ -25,3 +25,11 @@
1. `initData()`: Add `formData.executeTime = formatDateTime(new Date())` after line 899
2. `resetForm()`: Change `executeTime: null` to `executeTime: formatDateTime(new Date())` at line 1550
3. `loadApplicationToForm()`: Fix `isPackage` logic at line 2000
修复结果:✅ 成功5行改动
### 修改内容
1. `initData()` (line ~898): 新增 `formData.executeTime = formatDateTime(new Date())` — 新增检验申请单时执行时间自动填充当前时间
2. `resetForm()` (line ~1552): `executeTime: null``executeTime: formatDateTime(new Date())` — 重置表单/新增时执行时间默认当前时间
3. `loadApplicationToForm()` (line ~2002): `isPackage` 判定从 `item.feePackageId != null || item.itemName?.includes('套餐')` 改为 `item.feePackageId != null && item.feePackageId !== '' && item.feePackageId !== 'null' && item.packageName` — 与 `loadCategoryItems()` 保持一致,只有真正的套餐项目才显示"套餐"标签

36
bug556-analysis.md Normal file
View File

@@ -0,0 +1,36 @@
# Bug #556 分析报告
## Bug 描述
【门诊医生站-检验】新增检验申请单时就诊卡号/执行时间未自动回显,且项目列表冗余显示"套餐"文字
## 根因分析
### 问题1就诊卡号字段为空
**根因**`formData.medicalrecordNumber` 绑定到前端"就诊卡号"字段,但数据来源映射错误。
- `initData()` 第886行`formData.medicalrecordNumber = props.patientInfo.identifierNo || ''`
- `resetForm()` 第1526行`medicalrecordNumber: props.patientInfo.identifierNo || ''`
`identifierNo` 是身份证号/标识号字段,通常为空。实际的就诊卡号/业务编号是 `props.patientInfo.busNo`。代码中 `formData.visitNo` 已经正确映射了 `busNo`,但 `medicalrecordNumber` 映射到了错误的字段。
### 问题2执行时间未自动填充
**根因**`formData.executeTime` 初始值为 `null`第978行`initData()``resetForm()` 中均未赋予默认值。
- 对比:`applyTime``startApplyTimeTimer()` 实时更新定时器第1489行`executeTime` 没有类似初始化。
- 用户期望:新增申请单时执行时间应默认填充当前系统时间。
### 问题3项目列表冗余显示"套餐"文字
**根因**`loadApplicationToForm()` 第2000行的 `isPackage` 判断条件过于宽松。
- 第2000行`const isPackage = item.feePackageId != null || item.itemName?.includes('套餐')`
- 对比:`loadCategoryItems()` 第1190行已经做了正确修复`item.feePackageId != null && ... && item.packageName`
- 差异第2000行只用 `feePackageId != null` 判断,缺少 `packageName` 联合判断。如果后端返回的非套餐项目 `feePackageId` 有值但 `packageName` 为空,仍会被误标为套餐。
## 修复方案
### 修复1就诊卡号映射
`medicalrecordNumber` 的数据源从 `props.patientInfo.identifierNo` 改为 `props.patientInfo.busNo`
涉及位置:`initData()` 第886行、`resetForm()` 第1526行
### 修复2执行时间默认值
`initData()``resetForm()` 中,将 `executeTime` 设置为当前时间。使用 `formatDateTime(new Date())` 格式化为 `YYYY-MM-DD HH:mm:ss`
### 修复3套餐标识判断
`loadApplicationToForm()` 第2000行的 `isPackage` 判断条件与 `loadCategoryItems()` 第1190行保持一致增加 `item.packageName` 联合判断。

View File

@@ -73,9 +73,6 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
@Resource
ISpecimenService iSpecimenService;
@Resource
com.openhis.lab.mapper.SpecimenMapper specimenMapper;
/**
* 校验当前用户是否有权操作该申请单(申请者本人或管理员)
*/
@@ -94,13 +91,15 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
/**
* 校验关联医嘱是否已采证(存在已采集/已接收标本则不可撤回)
* 注意lab_specimen 表无 delete_flag 列,不能使用 MyBatis-Plus LambdaQueryWrapper会自动加 delete_flag 条件导致 SQL 报错)
*/
private boolean hasCollectedSpecimen(List<Long> serviceRequestIds) {
if (serviceRequestIds == null || serviceRequestIds.isEmpty()) {
return false;
}
long count = specimenMapper.countCollectedByServiceIds(serviceRequestIds, SpecCollectStatus.COLLECTED.getValue());
long count = iSpecimenService.count(
new LambdaQueryWrapper<Specimen>()
.in(Specimen::getServiceId, serviceRequestIds)
.ge(Specimen::getCollectionStatusEnum, SpecCollectStatus.COLLECTED.getValue()));
return count > 0;
}
@@ -641,22 +640,18 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
return R.fail("标本已采集,无法撤回");
}
// 校验:至少有一条已签发(status=2)的申请单可撤回
boolean anyActive = serviceRequests.stream()
.anyMatch(sr -> RequestStatus.ACTIVE.getValue().equals(sr.getStatusEnum()));
if (!anyActive) {
return R.fail("有已签发的诊疗医嘱,无法撤回");
// 校验:只有已签发(status=2)的申请单可撤回
boolean allActive = serviceRequests.stream()
.allMatch(sr -> RequestStatus.ACTIVE.getValue().equals(sr.getStatusEnum()));
if (!allActive) {
return R.fail("有已签发且未采证的申请单可撤回");
}
// 将已签发的 ServiceRequest 状态改回待签发,与申请单展示状态同步
List<Long> activeServiceRequestIds = serviceRequests.stream()
.filter(sr -> RequestStatus.ACTIVE.getValue().equals(sr.getStatusEnum()))
.map(ServiceRequest::getId)
.collect(Collectors.toList());
// 将所有 ServiceRequest 状态改回待签发,与申请单展示状态同步
iServiceRequestService.update(
new ServiceRequest().setStatusEnum(RequestStatus.DRAFT.getValue()),
new LambdaUpdateWrapper<ServiceRequest>()
.in(ServiceRequest::getId, activeServiceRequestIds));
.in(ServiceRequest::getId, serviceRequestIds));
log.info("检验申请单撤回成功requestFormId={}, prescriptionNo={}", requestFormId, prescriptionNo);
return R.ok("撤回成功");

View File

@@ -904,7 +904,7 @@ const initData = async () => {
formData.visitNo = props.patientInfo.busNo || ''
formData.patientId = props.patientInfo.patientId || ''
formData.patientName = props.patientInfo.patientName || ''
formData.medicalrecordNumber = props.patientInfo.identifierNo || ''
formData.medicalrecordNumber = props.patientInfo.visitNo || props.patientInfo.busNo || ''
formData.applyDepartment = props.patientInfo.organizationName || ''
formData.applyDocName = userNickName.value || userName.value || ''
formData.applyDocCode = userId.value || ''
@@ -916,6 +916,8 @@ const initData = async () => {
// 申请单号在保存时由后端生成,此处显示"自动生成"
formData.applyNo = '自动生成'
// 执行时间默认填充当前系统时间
formData.executeTime = formatDateTime(new Date())
// 申请日期实时更新(启动定时器)
startApplyTimeTimer()
// 执行时间默认当前系统时间(精确到分钟)
@@ -1551,7 +1553,7 @@ const resetForm = async () => {
applicationId: null,
applyOrganizationId: props.patientInfo.orgId || '',
patientName: props.patientInfo.patientName || '',
medicalrecordNumber: props.patientInfo.identifierNo || '',
medicalrecordNumber: props.patientInfo.visitNo || props.patientInfo.busNo || '',
natureofCost: 'self',
applyTime: '', // 申请日期由定时器实时更新
applyDepartment: props.patientInfo.organizationName || '',
@@ -1625,7 +1627,7 @@ const handleSave = () => {
// 修复【#406】保存前尝试从 props 同步患者信息,避免因加载时序导致信息缺失
if ((!formData.patientName?.trim() || !formData.medicalrecordNumber?.trim()) && props.patientInfo && props.patientInfo.encounterId) {
formData.patientName = props.patientInfo.patientName || ''
formData.medicalrecordNumber = props.patientInfo.identifierNo || ''
formData.medicalrecordNumber = props.patientInfo.visitNo || props.patientInfo.busNo || ''
formData.encounterId = props.patientInfo.encounterId || ''
formData.visitNo = props.patientInfo.busNo || ''
formData.patientId = props.patientInfo.patientId || ''
@@ -2025,7 +2027,7 @@ const loadApplicationToForm = async (row) => {
// Bug #387修复: 套餐项目默认展开,并自动加载明细
selectedInspectionItems.value = detail.labApplyItemList.map(item => {
const itemId = item.activityId || item.itemId || item.id || Math.random().toString(36).substring(2, 11)
const isPackage = item.feePackageId != null || item.itemName?.includes('套餐')
const isPackage = item.feePackageId != null && item.feePackageId !== '' && item.feePackageId !== 'null' && item.packageName
return {
itemId: itemId,

View File

@@ -1676,6 +1676,13 @@ function handleSaveGroup(orderGroupList) {
if (newRows.length > 0) {
prescriptionList.value.splice(originalLength); // 移除循环中追加到末尾的临时行
prescriptionList.value.unshift(...newRows);
// 排序:确保没有 requestTime 的新行始终排在最前面
prescriptionList.value.sort((a, b) => {
if (!a.requestTime && !b.requestTime) return 0;
if (!a.requestTime) return -1;
if (!b.requestTime) return 1;
return new Date(b.requestTime) - new Date(a.requestTime);
});
proxy.$modal.msgSuccess(`成功添加 ${successCount} 个医嘱项`);
}
}