Compare commits
5 Commits
2e00caf336
...
2bb9b0a07f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2bb9b0a07f | ||
|
|
a9bd2516e3 | ||
|
|
4c3adfecaa | ||
|
|
34485b45ea | ||
|
|
83c4cce92c |
@@ -261,6 +261,11 @@ public class OpCreateScheduleDto {
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 费用类别
|
||||
*/
|
||||
private String feeType;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
|
||||
@@ -87,8 +87,11 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
|
||||
throw new ServiceException("请先配置当前时间段的执行科室");
|
||||
}
|
||||
|
||||
// 逐个校验activityList中的项目是否都配置了执行科室,避免部分通过后在循环中抛异常导致事务复杂化
|
||||
// 逐个校验activityList中的项目是否都配置了执行科室,并收集positionId供后续使用
|
||||
// 必须在任何数据库操作之前完成全部校验,避免部分保存后异常导致脏数据
|
||||
List<ActivitySaveDto> activityList = requestFormSaveDto.getActivityList();
|
||||
// 缓存校验结果,避免主循环中重复查询和可能出现的数据不一致
|
||||
java.util.Map<Long, Long> activityIdToPositionIdMap = new java.util.HashMap<>();
|
||||
if (activityList != null && !activityList.isEmpty()) {
|
||||
for (ActivitySaveDto activitySaveDto : activityList) {
|
||||
Long positionId = activityOrganizationConfig.stream()
|
||||
@@ -97,6 +100,7 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
|
||||
if (positionId == null) {
|
||||
throw new ServiceException(activitySaveDto.getAdviceDefinitionName() + "未配置当前时间段的执行科室");
|
||||
}
|
||||
activityIdToPositionIdMap.put(activitySaveDto.getAdviceDefinitionId(), positionId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,9 +183,7 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
|
||||
serviceRequest.setEncounterId(encounterId); // 就诊id
|
||||
serviceRequest.setAuthoredTime(curDate); // 请求签发时间
|
||||
|
||||
Long positionId = activityOrganizationConfig.stream()
|
||||
.filter(dto -> activitySaveDto.getAdviceDefinitionId().equals(dto.getActivityDefinitionId()))
|
||||
.map(ActivityOrganizationConfigDto::getOrganizationId).findFirst().orElse(null);
|
||||
Long positionId = activityIdToPositionIdMap.get(activitySaveDto.getAdviceDefinitionId());
|
||||
if (positionId == null) {
|
||||
throw new ServiceException(activitySaveDto.getAdviceDefinitionName() + "未配置当前时间段的执行科室");
|
||||
}
|
||||
|
||||
@@ -178,22 +178,25 @@ service.interceptors.request.use(config => {
|
||||
}
|
||||
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
|
||||
} else if (code === 500) {
|
||||
// 检查是否需要跳过错误提示
|
||||
if (!res.config?.skipErrorMsg) {
|
||||
ElMessage({ message: msg, type: 'error' })
|
||||
// 检查是否需要跳过错误提示(静默请求:返回响应让.then()处理)
|
||||
if (res.config?.skipErrorMsg) {
|
||||
return Promise.resolve(res.data)
|
||||
}
|
||||
ElMessage({ message: msg, type: 'error' })
|
||||
return Promise.reject(new Error(msg))
|
||||
} else if (code === 601) {
|
||||
// 检查是否需要跳过错误提示
|
||||
if (!res.config?.skipErrorMsg) {
|
||||
ElMessage({ message: msg, type: 'warning' })
|
||||
// 检查是否需要跳过错误提示(静默请求:返回响应让.then()处理)
|
||||
if (res.config?.skipErrorMsg) {
|
||||
return Promise.resolve(res.data)
|
||||
}
|
||||
ElMessage({ message: msg, type: 'warning' })
|
||||
return Promise.reject(new Error(msg))
|
||||
} else if (code !== 200) {
|
||||
// 检查是否需要跳过错误提示
|
||||
if (!res.config?.skipErrorMsg) {
|
||||
ElNotification.error({ title: msg })
|
||||
// 检查是否需要跳过错误提示(静默请求:返回响应让.then()处理)
|
||||
if (res.config?.skipErrorMsg) {
|
||||
return Promise.resolve(res.data)
|
||||
}
|
||||
ElNotification.error({ title: msg })
|
||||
return Promise.reject('error')
|
||||
} else {
|
||||
return Promise.resolve(res.data)
|
||||
|
||||
@@ -924,7 +924,8 @@ async function loadCategoryList() {
|
||||
categoryName: t.name,
|
||||
// “检查类型管理”里配置的执行科室(图三)
|
||||
performDeptName: t.department || '',
|
||||
items: []
|
||||
items: [],
|
||||
methods: [] // #428修复: 初始化 methods 数组,确保 Vue 响应式追踪
|
||||
});
|
||||
}
|
||||
const unclassified = [];
|
||||
@@ -1267,6 +1268,7 @@ async function handleMethodSelect(checked, method, cat) {
|
||||
if (method.packageId) {
|
||||
existingItem.isPackage = true;
|
||||
existingItem.packageId = method.packageId;
|
||||
existingItem.packageName = method.packageName || existingItem.packageName; // #428修复: 确保 packageName 同步
|
||||
// 预加载套餐明细
|
||||
loadPackageDetailsForItem(existingItem);
|
||||
}
|
||||
@@ -1294,12 +1296,13 @@ async function handleMethodSelect(checked, method, cat) {
|
||||
checkType: cat.typeName,
|
||||
nationalCode: targetItem.nationalCode || '',
|
||||
checked: true,
|
||||
methods: [method],
|
||||
methods: cat.methods || [method], // #428修复: 复制分类下全部方法,允许用户切换
|
||||
selectedMethod: method,
|
||||
expanded: false,
|
||||
// 从方法中获取套餐信息(优先级高于项目本身的 packageName)
|
||||
// 从方法或项目中获取套餐信息
|
||||
isPackage: !!method.packageId || !!targetItem.packageName,
|
||||
packageId: method.packageId || targetItem.packageId || null
|
||||
packageId: method.packageId || targetItem.packageId || null,
|
||||
packageName: method.packageName || targetItem.packageName || null // #428修复: 复制 packageName,确保套餐明细可加载
|
||||
};
|
||||
selectedItems.value.push(newItem);
|
||||
|
||||
|
||||
@@ -1552,6 +1552,8 @@ function handleMedicalAdvice(row) {
|
||||
// 过滤掉名称为空的项目
|
||||
const medicineName = item.adviceName || item.advice_name;
|
||||
if (!medicineName || medicineName.trim() === '') return false;
|
||||
// 🔧 修复 Bug #445: 过滤掉已生成医嘱的项目(已有 requestId 的不应出现在"待生成"列表)
|
||||
if (item.requestId) return false;
|
||||
// 根据药品请求ID去重,避免重复显示
|
||||
const itemId = item.requestId || item.id;
|
||||
if (itemId && seenIds.has(itemId)) return false;
|
||||
@@ -1739,15 +1741,27 @@ function handleTemporaryMedicalSubmit(data) {
|
||||
}
|
||||
})
|
||||
|
||||
// 同步更新计费药品列表:移除已生成医嘱的项目,避免数据重复显示
|
||||
const submittedIds = new Set(
|
||||
(data.temporaryAdvices || []).map(a => a.originalMedicine?.requestId || a.originalMedicine?.chargeItemId).filter(Boolean)
|
||||
// 🔧 修复 Bug #445: 使用稳定的字段组合匹配已提交项目,而不是依赖可能为空的 requestId/chargeItemId
|
||||
// 构建已提交项目的匹配键集合(药品名称 + 规格 + 数量)
|
||||
const submittedKeys = new Set(
|
||||
(data.temporaryAdvices || [])
|
||||
.map(a => {
|
||||
const om = a.originalMedicine || {}
|
||||
const name = om.medicineName || om.adviceName || om.advice_name || a.adviceName || ''
|
||||
const spec = om.specification || om.volume || ''
|
||||
const qty = om.quantity || 0
|
||||
return `${name}|||${spec}|||${qty}`
|
||||
})
|
||||
.filter(k => k !== '|||0') // 过滤掉空项
|
||||
)
|
||||
if (submittedIds.size > 0) {
|
||||
temporaryBillingMedicines.value = (data.billingMedicines || []).filter(
|
||||
m => !submittedIds.has(m.requestId || m.chargeItemId)
|
||||
)
|
||||
|
||||
if (submittedKeys.size > 0) {
|
||||
temporaryBillingMedicines.value = (temporaryBillingMedicines.value || []).filter(m => {
|
||||
const key = `${m.medicineName || ''}|||${m.specification || ''}|||${m.quantity || 0}`
|
||||
return !submittedKeys.has(key)
|
||||
})
|
||||
} else {
|
||||
// 如果没有任何匹配键,清空待生成列表(所有项目都已提交)
|
||||
temporaryBillingMedicines.value = []
|
||||
}
|
||||
|
||||
@@ -1807,7 +1821,8 @@ function handleQuoteBilling() {
|
||||
temporaryBillingMedicines.value = []
|
||||
temporaryAdvices.value = []
|
||||
|
||||
// 只保留药品类型(adviceType=1),过滤掉耗材(2)和诊疗项目(3)
|
||||
// 🔧 修复 Bug #445: 只保留药品类型(adviceType=1),过滤掉耗材(2)和诊疗项目(3)
|
||||
// 同时过滤掉已有 requestId 的项目(已生成医嘱的不需要再次显示在"待生成"列表中)
|
||||
const filteredItems = res.data.filter(item => {
|
||||
// 匹配 encounterId
|
||||
if (item.encounterId !== temporaryPatientInfo.value.visitId) return false;
|
||||
@@ -1815,7 +1830,10 @@ function handleQuoteBilling() {
|
||||
if (item.adviceType !== 1) return false;
|
||||
// 过滤掉名称为空的项目
|
||||
const medicineName = item.adviceName || item.advice_name;
|
||||
return medicineName && medicineName.trim() !== '';
|
||||
if (!medicineName || medicineName.trim() === '') return false;
|
||||
// 🔧 修复 Bug #445: 过滤掉已生成医嘱的项目(已有 requestId)
|
||||
if (item.requestId) return false;
|
||||
return true;
|
||||
})
|
||||
// 🔧 修复:限制返回数量,最多显示前100条,避免数据过多导致页面卡死
|
||||
const maxItems = 100
|
||||
|
||||
Reference in New Issue
Block a user