Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
@@ -153,7 +153,7 @@ public class TicketAppServiceImpl implements ITicketAppService {
|
||||
dto.setIdCard(raw.getIdCard());
|
||||
dto.setDoctorId(raw.getDoctorId());
|
||||
dto.setDepartmentId(raw.getDepartmentId());
|
||||
dto.setRealPatientId(raw.getPatientId());
|
||||
dto.setRealPatientId(raw.getRealPatientId() != null ? raw.getRealPatientId() : raw.getPatientId());
|
||||
dto.setOrderId(raw.getOrderId());
|
||||
dto.setOrderNo(raw.getOrderNo());
|
||||
|
||||
|
||||
@@ -515,29 +515,28 @@ public class OutpatientRegistrationAppServiceImpl implements IOutpatientRegistra
|
||||
// 构建查询条件
|
||||
QueryWrapper<CurrentDayEncounterDto> queryWrapper = HisQueryUtils.buildQueryWrapper(null, searchKey,
|
||||
new HashSet<>(Arrays.asList("patient_name", "organization_name", "practitioner_name", "healthcare_name", "identifier_no")),
|
||||
request);
|
||||
null); // registerTimeSTime/ETime 已下推到 SQL 内层 WHERE,跳过 buildQueryWrapper 的自动 *STime/*ETime 处理
|
||||
|
||||
// 手动处理 statusEnum 参数(用于过滤退号记录)
|
||||
// 提取statusEnum参数,下推到内层WHERE(避免外层重复过滤)
|
||||
Integer statusFilter = null;
|
||||
String statusEnumParam = request.getParameter("statusEnum");
|
||||
if (statusEnumParam != null && !statusEnumParam.isEmpty()) {
|
||||
try {
|
||||
Integer statusEnum = Integer.parseInt(statusEnumParam);
|
||||
if (statusEnum == -1) {
|
||||
// -1 表示排除退号记录(正常挂号)
|
||||
queryWrapper.ne("status_enum", 6);
|
||||
} else {
|
||||
// 其他值表示精确匹配
|
||||
queryWrapper.eq("status_enum", statusEnum);
|
||||
}
|
||||
statusFilter = Integer.parseInt(statusEnumParam);
|
||||
} catch (NumberFormatException e) {
|
||||
// 忽略无效的参数值
|
||||
}
|
||||
}
|
||||
|
||||
// 提取日期范围参数,下推到内层WHERE以优化性能(避免全表JOIN后再过滤)
|
||||
String registerTimeSTime = request.getParameter("registerTimeSTime");
|
||||
String registerTimeETime = request.getParameter("registerTimeETime");
|
||||
|
||||
IPage<CurrentDayEncounterDto> currentDayEncounter = outpatientRegistrationAppMapper.getCurrentDayEncounter(
|
||||
new Page<>(pageNo, pageSize), EncounterClass.AMB.getValue(), EncounterStatus.IN_PROGRESS.getValue(),
|
||||
ParticipantType.ADMITTER.getCode(), ParticipantType.REGISTRATION_DOCTOR.getCode(), queryWrapper,
|
||||
ChargeItemContext.REGISTER.getValue(), PaymentStatus.SUCCESS.getValue());
|
||||
ChargeItemContext.REGISTER.getValue(), PaymentStatus.SUCCESS.getValue(),
|
||||
registerTimeSTime, registerTimeETime, statusFilter);
|
||||
|
||||
// 过滤候选池排除列表
|
||||
// 仅当调用方显式传 excludeFromCandidatePool=true 时才过滤,避免非分诊场景(挂号/收费)
|
||||
|
||||
@@ -54,7 +54,10 @@ public interface OutpatientRegistrationAppMapper {
|
||||
@Param("classEnum") Integer classEnum, @Param("statusEnum") Integer statusEnum,
|
||||
@Param("participantType1") String participantType1, @Param("participantType2") String participantType2,
|
||||
@Param(Constants.WRAPPER) QueryWrapper<CurrentDayEncounterDto> queryWrapper,
|
||||
@Param("register") Integer register, @Param("paymentStatus") Integer paymentStatus);
|
||||
@Param("register") Integer register, @Param("paymentStatus") Integer paymentStatus,
|
||||
@Param("registerTimeSTime") String registerTimeSTime,
|
||||
@Param("registerTimeETime") String registerTimeETime,
|
||||
@Param("statusFilter") Integer statusFilter);
|
||||
|
||||
/**
|
||||
* 查询item绑定的信息(耗材或诊疗)
|
||||
|
||||
@@ -451,10 +451,12 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
|
||||
// 删除费用项
|
||||
iChargeItemService.deleteByServiceTableAndId(CommonConstants.TableName.MED_MEDICATION_REQUEST,
|
||||
adviceSaveDto.getRequestId());
|
||||
// 删除代煎费
|
||||
iChargeItemService.remove(new LambdaQueryWrapper<ChargeItem>()
|
||||
.eq(ChargeItem::getPrescriptionNo, adviceSaveDto.getPrescriptionNo())
|
||||
.eq(ChargeItem::getProductId, sufferingDefinitionId));
|
||||
// 删除代煎费(按处方号精确清理)
|
||||
if (adviceSaveDto.getPrescriptionNo() != null) {
|
||||
iChargeItemService.remove(new LambdaQueryWrapper<ChargeItem>()
|
||||
.eq(ChargeItem::getPrescriptionNo, adviceSaveDto.getPrescriptionNo())
|
||||
.eq(ChargeItem::getProductId, sufferingDefinitionId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -614,7 +616,7 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
|
||||
Long encounterDiagnosisId = medicineList.get(0).getEncounterDiagnosisId();
|
||||
// 中药付数
|
||||
BigDecimal chineseHerbsDoseQuantity = medicineList.get(0).getChineseHerbsDoseQuantity();
|
||||
// 🔧 Bug Fix #668: 收集所有处方号(不同分组可能有不同处方号)
|
||||
// 收集所有处方号(不同分组可能有不同处方号)
|
||||
List<String> prescriptionNos = insertOrUpdateList.stream()
|
||||
.map(AdviceSaveDto::getPrescriptionNo)
|
||||
.filter(Objects::nonNull)
|
||||
@@ -628,12 +630,10 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
|
||||
AdviceBaseDto adviceBaseDto = new AdviceBaseDto();
|
||||
adviceBaseDto.setAdviceDefinitionId(sufferingDefinitionId); // 医嘱定义id
|
||||
|
||||
// 🔧 Bug Fix #668: 先删除所有处方号关联的中药代煎账单
|
||||
if (!prescriptionNos.isEmpty()) {
|
||||
iChargeItemService.remove(new LambdaQueryWrapper<ChargeItem>()
|
||||
.in(ChargeItem::getPrescriptionNo, prescriptionNos)
|
||||
.eq(ChargeItem::getProductId, sufferingDefinitionId));
|
||||
}
|
||||
// 先删除该就诊关联的所有中药代煎账单
|
||||
iChargeItemService.remove(new LambdaQueryWrapper<ChargeItem>()
|
||||
.eq(ChargeItem::getEncounterId, encounterId)
|
||||
.eq(ChargeItem::getProductId, sufferingDefinitionId));
|
||||
|
||||
// 对应的诊疗医嘱信息
|
||||
AdviceBaseDto activityAdviceBaseDto = iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, null,
|
||||
@@ -642,7 +642,7 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
|
||||
// 费用定价
|
||||
AdvicePriceDto advicePriceDto = activityAdviceBaseDto.getPriceList().get(0);
|
||||
if (advicePriceDto != null) {
|
||||
// 🔧 Bug Fix #668: 为每个处方号分别生成代煎账单
|
||||
// 为每个处方号分别生成代煎账单
|
||||
for (String prescriptionNo : prescriptionNos) {
|
||||
chargeItem = new ChargeItem();
|
||||
chargeItem.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue()); // 生成来源
|
||||
@@ -674,12 +674,10 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
|
||||
}
|
||||
}
|
||||
} else if (Whether.NO.getValue().equals(sufferingFlag)) {
|
||||
// 🔧 Bug Fix #668: 删除所有处方号关联的中药代煎账单
|
||||
if (!prescriptionNos.isEmpty()) {
|
||||
iChargeItemService.remove(new LambdaQueryWrapper<ChargeItem>()
|
||||
.in(ChargeItem::getPrescriptionNo, prescriptionNos)
|
||||
.eq(ChargeItem::getProductId, sufferingDefinitionId));
|
||||
}
|
||||
// 删除该就诊关联的所有中药代煎账单
|
||||
iChargeItemService.remove(new LambdaQueryWrapper<ChargeItem>()
|
||||
.eq(ChargeItem::getEncounterId, encounterId)
|
||||
.eq(ChargeItem::getProductId, sufferingDefinitionId));
|
||||
}
|
||||
|
||||
// 签发时,把草稿状态的账单更新为待收费[中医]
|
||||
|
||||
@@ -192,6 +192,9 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
// 提取requestStatus手动处理,支持COMPLETED(3)和CHECK_VERIFIED(10)同时查询
|
||||
Integer requestStatus = inpatientAdviceParam.getRequestStatus();
|
||||
inpatientAdviceParam.setRequestStatus(null);
|
||||
// Bug #714: 提取deadline手动处理,UNION子查询列名为end_time
|
||||
String deadline = inpatientAdviceParam.getDeadline();
|
||||
inpatientAdviceParam.setDeadline(null);
|
||||
// 构建查询条件
|
||||
QueryWrapper<InpatientAdviceParam> queryWrapper
|
||||
= HisQueryUtils.buildQueryWrapper(inpatientAdviceParam, null, null, null);
|
||||
@@ -223,6 +226,16 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
if (therapyEnum != null) {
|
||||
queryWrapper.and(w -> w.eq("therapy_enum", therapyEnum).or().isNull("therapy_enum"));
|
||||
}
|
||||
// Bug #714: 手动拼接deadline条件,按医嘱截止时间筛选
|
||||
if (deadline != null && !deadline.isEmpty()) {
|
||||
try {
|
||||
LocalDateTime deadlineTime = LocalDateTime.parse(deadline,
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
queryWrapper.le("end_time", deadlineTime);
|
||||
} catch (DateTimeParseException e) {
|
||||
// 忽略无效的日期格式
|
||||
}
|
||||
}
|
||||
// 患者医嘱分页列表
|
||||
Page<InpatientAdviceDto> inpatientAdvicePage
|
||||
= adviceProcessAppMapper.selectInpatientAdvicePage(new Page<>(pageNo, pageSize), queryWrapper,
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
-- Bug #735: 新医嘱签发后"停嘱医生"字段错误生成数据
|
||||
-- 原因:stopper_name 映射到 update_by 字段,签发时 MyBatis-Plus 自动填充导致错误赋值
|
||||
-- 修复:添加专用 stopper_id 字段,仅在停嘱操作时设置
|
||||
|
||||
-- 药品请求表添加停嘱医生ID字段
|
||||
ALTER TABLE med_medication_request ADD COLUMN IF NOT EXISTS stopper_id BIGINT;
|
||||
|
||||
-- 服务请求表添加停嘱医生ID字段
|
||||
ALTER TABLE wor_service_request ADD COLUMN IF NOT EXISTS stopper_id BIGINT;
|
||||
@@ -217,6 +217,11 @@
|
||||
WHERE T1.delete_flag = '0'
|
||||
AND T1.class_enum = #{classEnum}
|
||||
AND T10.context_enum = #{register}
|
||||
AND (#{registerTimeSTime} IS NULL OR T1.create_time >= CAST(#{registerTimeSTime} AS TIMESTAMP))
|
||||
AND (#{registerTimeETime} IS NULL OR T1.create_time <= CAST(#{registerTimeETime} AS TIMESTAMP))
|
||||
AND (#{statusFilter} IS NULL
|
||||
OR (#{statusFilter} >= 0 AND T1.status_enum = #{statusFilter})
|
||||
OR (#{statusFilter} = -1 AND T1.status_enum != 6))
|
||||
) AS T9
|
||||
${ew.customSqlSegment}
|
||||
ORDER BY T9.register_time DESC
|
||||
|
||||
@@ -108,8 +108,6 @@
|
||||
<if test="statusEnum == 18">
|
||||
T4.status_enum = #{submitted}
|
||||
</if>
|
||||
AND T4.summary_no IS NOT NULL
|
||||
AND T4.summary_no != ''
|
||||
) AS ii
|
||||
${ew.customSqlSegment}
|
||||
GROUP BY ii.encounter_id,
|
||||
@@ -268,8 +266,6 @@
|
||||
AND T15.delete_flag = '0'
|
||||
WHERE T1.delete_flag = '0'
|
||||
-- 因发药配药合并,前台只能看到待发药,已发药状态,但是后台配药发药状态都查
|
||||
AND T1.summary_no IS NOT NULL
|
||||
AND T1.summary_no != ''
|
||||
AND
|
||||
<if test="dispenseStatus == null">
|
||||
T1.status_enum IN (#{inProgress},#{completed},#{preparation},#{prepared},#{summarized})
|
||||
|
||||
@@ -222,8 +222,8 @@
|
||||
T1.based_on_id AS based_on_id,
|
||||
T1.medication_id AS advice_definition_id,
|
||||
T1.content_json::jsonb ->> 'remark' AS remark,
|
||||
T1.effective_dose_end AS stop_time,
|
||||
T1.update_by AS stop_user_name
|
||||
CASE WHEN T1.status_enum = 6 THEN T1.effective_dose_end ELSE NULL END AS stop_time,
|
||||
CASE WHEN T1.status_enum = 6 THEN T1.update_by ELSE NULL END AS stop_user_name
|
||||
FROM med_medication_request AS T1
|
||||
LEFT JOIN adm_practitioner AS ap ON ap.id = T1.practitioner_id AND ap.delete_flag = '0'
|
||||
LEFT JOIN med_medication_definition AS T2 ON T2.ID = T1.medication_id
|
||||
@@ -339,8 +339,8 @@
|
||||
T1.based_on_id AS based_on_id,
|
||||
T1.activity_id AS advice_definition_id,
|
||||
T1.remark AS remark,
|
||||
T1.occurrence_end_time AS stop_time,
|
||||
T1.update_by AS stop_user_name
|
||||
CASE WHEN T1.status_enum = 6 THEN T1.occurrence_end_time ELSE NULL END AS stop_time,
|
||||
CASE WHEN T1.status_enum = 6 THEN T1.update_by ELSE NULL END AS stop_user_name
|
||||
FROM wor_service_request AS T1
|
||||
LEFT JOIN adm_practitioner AS ap ON ap.id = T1.requester_id AND ap.delete_flag = '0'
|
||||
LEFT JOIN wor_activity_definition AS T2
|
||||
|
||||
@@ -21,6 +21,7 @@ public class TicketSlotDTO {
|
||||
private String patientName;
|
||||
private String medicalCard;
|
||||
private Long patientId;
|
||||
private Long realPatientId;
|
||||
private String phone;
|
||||
private Integer orderStatus;
|
||||
private Long orderId;
|
||||
|
||||
@@ -111,6 +111,7 @@
|
||||
o.order_no AS orderNo,
|
||||
COALESCE(CAST(o.gender AS VARCHAR), CAST(pinfo.gender_enum AS VARCHAR)) AS patientGender,
|
||||
pinfo.gender_enum AS genderEnum,
|
||||
pinfo.id AS realPatientId,
|
||||
pinfo.id_card AS idCard,
|
||||
o.appointment_time AS appointmentTime,
|
||||
<include refid="orderStatusNormExpr" /> AS orderStatus,
|
||||
@@ -230,6 +231,7 @@
|
||||
o.order_no AS orderNo,
|
||||
COALESCE(CAST(o.gender AS VARCHAR), CAST(pinfo.gender_enum AS VARCHAR)) AS patientGender,
|
||||
pinfo.gender_enum AS genderEnum,
|
||||
pinfo.id AS realPatientId,
|
||||
pinfo.id_card AS idCard,
|
||||
o.appointment_time AS appointmentTime,
|
||||
<include refid="orderStatusNormExpr" /> AS orderStatus,
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
ref="patientListRef"
|
||||
height="620"
|
||||
:data="patientList"
|
||||
:row-config="{ keyField: 'encounterId', keyField: 'id' }"
|
||||
:row-config="{ keyField: 'encounterId' }"
|
||||
@cell-click="clickRow"
|
||||
>
|
||||
<vxe-column
|
||||
@@ -447,7 +447,8 @@ function checkSelectable(row, index) {
|
||||
/**
|
||||
* 点击患者列表行 获取处方列表
|
||||
*/
|
||||
function clickRow(row) {
|
||||
function clickRow(params) {
|
||||
const row = params.row || params;
|
||||
patientInfo.value = row;
|
||||
chargeLoading.value = true;
|
||||
encounterId.value = row.encounterId;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<template>
|
||||
<template>
|
||||
<div
|
||||
v-loading="readCardLoading"
|
||||
class="app-container"
|
||||
@@ -122,6 +122,7 @@
|
||||
<patientList
|
||||
:searchkey="patientSearchKey"
|
||||
@selsect-patient="selsectPatient"
|
||||
@mousedown.prevent
|
||||
/>
|
||||
<template #reference>
|
||||
<el-input
|
||||
@@ -2079,10 +2080,20 @@ async function confirmCheckIn() {
|
||||
// 每次开始新的签到流程先清理残留 slotId,避免历史脏值串单
|
||||
currentSlotId.value = null;
|
||||
|
||||
// 防御性校验:确保关键字段存在
|
||||
if (!patient.departmentId) {
|
||||
ElMessage.error('该号源缺少科室信息,无法完成签到,请联系管理员');
|
||||
return;
|
||||
}
|
||||
if (!patient.realPatientId) {
|
||||
ElMessage.error('该号源缺少患者信息,无法完成签到,请联系管理员');
|
||||
return;
|
||||
}
|
||||
|
||||
// 弹出确认提示
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`确认为患者【${patient.patientName}】办理签到挂号?\n` +
|
||||
`确认为患者【${patient.patientName || '未知患者'}】办理签到挂号?\n` +
|
||||
`科室:${patient.department || '-'}\n` +
|
||||
`医生:${patient.doctor || '-'}\n` +
|
||||
`费用:¥${patient.fee || '0.00'}`,
|
||||
@@ -2215,7 +2226,7 @@ async function confirmCheckIn() {
|
||||
* 点击患者列表给表单赋值
|
||||
*/
|
||||
function selsectPatient(row) {
|
||||
form.value = { ...form.value, ...row };
|
||||
Object.assign(form.value, row);
|
||||
form.value.patientId = row.id;
|
||||
form.value.searchKey = row.name;
|
||||
form.value.name = row.name;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
v-model="type"
|
||||
@change="handleRadioChange"
|
||||
>
|
||||
<el-radio :value="THERAPY_TYPE_ALL">
|
||||
<el-radio :value="0">
|
||||
全部
|
||||
</el-radio>
|
||||
<el-radio :value="1">
|
||||
@@ -26,15 +26,13 @@
|
||||
临时
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
<span style="flex-shrink: 0;">截止时间:</span>
|
||||
<el-date-picker
|
||||
v-model="deadline"
|
||||
type="datetime"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="选择截止时间"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
:clearable="false"
|
||||
style="width: 200px;"
|
||||
style="width: 200px"
|
||||
/>
|
||||
<el-button
|
||||
type="primary"
|
||||
@@ -346,8 +344,7 @@ import {RequestStatus} from '@/utils/medicalConstants';
|
||||
const activeNames = ref([]);
|
||||
const prescriptionList = ref([]);
|
||||
const deadline = ref(formatDateStr(new Date(), 'YYYY-MM-DD') + ' 23:59:59');
|
||||
const THERAPY_TYPE_ALL = 0;
|
||||
const type = ref(THERAPY_TYPE_ALL);
|
||||
const type = ref(0);
|
||||
const backReasonVisible = ref(false);
|
||||
const backReasonForm = ref({ reason: '' });
|
||||
const backReasonFormRef = ref(null);
|
||||
@@ -447,8 +444,8 @@ function handleGetPrescription() {
|
||||
getPrescriptionList({
|
||||
encounterIds: encounterIds,
|
||||
requestStatus: props.requestStatus,
|
||||
...(type.value !== THERAPY_TYPE_ALL ? { therapyEnum: type.value } : {}),
|
||||
deadline: deadline.value,
|
||||
...(type.value !== 0 ? { therapyEnum: type.value } : {}),
|
||||
...(deadline.value ? { deadline: deadline.value } : {}),
|
||||
pageSize: 10000,
|
||||
pageNo: 1,
|
||||
}).then((res) => {
|
||||
|
||||
Reference in New Issue
Block a user