diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointmentmanage/appservice/impl/TicketAppServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointmentmanage/appservice/impl/TicketAppServiceImpl.java index 7c00ceec..8fc6bd76 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointmentmanage/appservice/impl/TicketAppServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointmentmanage/appservice/impl/TicketAppServiceImpl.java @@ -71,10 +71,39 @@ public class TicketAppServiceImpl implements ITicketAppService { } try { - // 3. 执行原有的预约逻辑 + // 3. 号源列表来自排班表(adm_doctor_schedule),需确保clinical_ticket中存在对应记录 + Ticket existingTicket = ticketService.selectTicketById(ticketId); + if (existingTicket == null) { + DoctorSchedule schedule = doctorScheduleMapper.selectById(slotId); + if (schedule == null) { + return R.fail("排班记录不存在"); + } + Ticket newTicket = new Ticket(); + newTicket.setId(slotId); + newTicket.setDoctor(schedule.getDoctor()); + newTicket.setDepartment(String.valueOf(schedule.getDeptId())); + newTicket.setDoctorId(schedule.getDoctorId()); + newTicket.setDepartmentId(schedule.getDeptId()); + String registerItem = schedule.getRegisterItem(); + if (registerItem != null && registerItem.contains("专家")) { + newTicket.setTicketType("expert"); + } else { + newTicket.setTicketType("general"); + } + newTicket.setStatus("unbooked"); + int totalFee = (schedule.getRegisterFee() != null ? schedule.getRegisterFee() : 0) + + (schedule.getDiagnosisFee() != null ? schedule.getDiagnosisFee() : 0); + newTicket.setFee(String.valueOf(totalFee)); + String timeRange = schedule.getStartTime() + "-" + schedule.getEndTime(); + newTicket.setTime(LocalDate.now() + " " + timeRange); + // 使用MyBatis-Plus的save方法,支持手动设置ID + ticketService.save(newTicket); + } + + // 4. 执行预约逻辑 int result = ticketService.bookTicket(params); if (result > 0) { - // 4. 预约成功后,更新排班表状态 + // 5. 预约成功后,更新排班表状态 DoctorSchedule schedule = new DoctorSchedule(); schedule.setId(slotId); // 对应 XML 中的 WHERE id = #{id} schedule.setIsStopped(true); // 设置为已预约 @@ -86,14 +115,12 @@ public class TicketAppServiceImpl implements ITicketAppService { if (updateCount > 0) { return R.ok("预约成功并已更新排班状态"); } else { - // 如果更新失败,可能需要根据业务逻辑决定是否回滚预约 return R.ok("预约成功,但排班状态更新失败"); } } else { return R.fail("预约失败"); } } catch (Exception e) { - // e.printStackTrace(); log.error(e.getMessage()); return R.fail("系统异常:" + e.getMessage()); } diff --git a/openhis-ui-vue3/src/views/appoinmentmanage/outpatientAppointment/index.vue b/openhis-ui-vue3/src/views/appoinmentmanage/outpatientAppointment/index.vue index e8d12851..81b85466 100644 --- a/openhis-ui-vue3/src/views/appoinmentmanage/outpatientAppointment/index.vue +++ b/openhis-ui-vue3/src/views/appoinmentmanage/outpatientAppointment/index.vue @@ -177,8 +177,8 @@ {{ index + 1 }} {{ patient.name }} - {{ patient.medicalCard }} - {{ patient.gender || '-' }} + {{ patient.id || patient.medicalCard }} + {{ getGenderText(patient.genderEnum_enumText || patient.genderEnum || patient.gender || patient.sex) }} {{ patient.idCard }} {{ patient.phone }} @@ -436,7 +436,7 @@ export default { records = response; } - this.patients = records; + this.patients = records; // 在前端进行额外的模糊匹配过滤(以防后端API不支持完整的模糊匹配) if (hasSearchCriteria) { this.patients = this.patients.filter(patient => { @@ -599,40 +599,17 @@ export default { ElMessage.error('患者数据未加载,请先搜索患者'); return; } - + this.selectedPatientId = patientId; // 保存选择的患者对象 - 使用idCard作为唯一标识,但增加容错性 this.selectedPatient = this.patients.find(patient => { - // 尝试多种匹配方式 const matchByIdCard = patient.idCard === patientId; const matchById = patient.id === patientId; const matchByMedicalCard = patient.medicalCard === patientId; - const match = matchByIdCard || matchById || matchByMedicalCard; - return match; + return matchByIdCard || matchById || matchByMedicalCard; }); if (this.selectedPatient) { - // 使用 ElMessageBox.confirm 进行二次确认 - ElMessageBox.confirm( - `确认选择患者 ${this.selectedPatient.name} 进行预约?`, - '患者确认', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'info' - } - ).then(() => { - // 用户点击确定,自动滚动到确认按钮 - ElMessage.success('已选择患者: ' + this.selectedPatient.name); - const confirmBtn = document.querySelector('.confirm-btn'); - if (confirmBtn) { - confirmBtn.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); - } - }).catch(() => { - // 用户取消选择,清空已选患者 - this.selectedPatientId = null; - this.selectedPatient = null; - ElMessage.info('已取消患者选择'); - }); + ElMessage.success('已选中患者: ' + this.selectedPatient.name); } else { ElMessage.error('未找到该患者,请重新选择'); this.selectedPatientId = null; @@ -643,59 +620,68 @@ export default { ElMessage.error('请选择患者'); return; } - + if (!this.currentTicket) { ElMessage.error('预约信息错误,请重新选择号源'); this.closePatientSelectModal(); return; } - + + // 再次验证号源是否仍处于可预约状态 + if (this.currentTicket.status !== '未预约') { + ElMessage.error('该号源已被预约,请选择其他号源'); + this.closePatientSelectModal(); + return; + } + try { const userStore = useUserStore(); const appointmentData = { - slotId: this.currentTicket.slot_id, // 添加号源ID - ticketId: Number(this.currentTicket.slot_id), + ticketId: this.currentTicket.slot_id, // 号源ID,保持原始类型避免大数字精度丢失 + slotId: this.currentTicket.slot_id, // 号源ID patientId: this.selectedPatientId, // 使用身份证号作为患者ID,不需要转换为数字 patientName: this.selectedPatient.name, - medicalCard: this.selectedPatient.medicalCard, + medicalCard: this.selectedPatient.medicalCard || this.selectedPatient.id, phone: this.selectedPatient.phone, - gender: this.selectedPatient.gender, + gender: this.getGenderValueForBackend(this.selectedPatient), fee: Number(this.currentTicket.fee) || 0, regType: this.currentTicket.ticketType === 'general' ? '普通' : '专家', tenant_id: userStore.tenantId || '1' // 修改为tenant_id以匹配后端数据库字段名 }; - + // 验证必填字段 - if (!appointmentData.ticketId || isNaN(appointmentData.ticketId)) { + if (!appointmentData.ticketId) { ElMessage.error('号源ID无效'); return; } - + if (!appointmentData.patientId) { ElMessage.error('患者ID无效'); return; } // 调用真实API进行预约 - bookTicket(appointmentData).then(response => { + bookTicket(appointmentData).then(response => { const ticketIndex = this.tickets.findIndex(t => t.slot_id === this.currentTicket.slot_id); if (ticketIndex !== -1) { this.tickets[ticketIndex].status = '已预约'; this.tickets[ticketIndex].patientName = this.selectedPatient.name; - this.tickets[ticketIndex].patientId = this.selectedPatient.medicalCard; - this.tickets[ticketIndex].patientGender = this.selectedPatient.gender; - + this.tickets[ticketIndex].patientId = this.selectedPatient.medicalCard || this.selectedPatient.id; + this.tickets[ticketIndex].patientGender = this.selectedPatient.genderEnum_enumText || this.selectedPatient.genderEnum || this.selectedPatient.gender || this.selectedPatient.sex; + // 更新医生号源列表中的余号数量 this.updateDoctorsList(); } - + this.closePatientSelectModal(); - + // 重新加载号源数据,确保显示最新状态 this.onSearch(); - + ElMessage.success('预约成功,号源已锁定。患者到院签到时需缴费取号。'); }).catch(error => { - ElMessage.error('预约失败,请稍后重试。'); + // 显示具体的错误信息 + const errorMessage = error.response?.data?.msg || error.response?.data?.message || '预约失败,请稍后重试。'; + ElMessage.error(errorMessage); }); } catch (error) { ElMessage.error('预约信息格式错误,请重新操作。'); @@ -710,6 +696,56 @@ export default { toggleSidebar() { this.showSidebar = !this.showSidebar; }, + // 获取性别文本 + getGenderText(genderValue) { + // 如果值为null或undefined,返回'-' + if (genderValue === null || genderValue === undefined) { + return '-'; + } + + // 将值转换为字符串进行比较 + const strValue = String(genderValue).toLowerCase(); + + // 处理男性值 + if (strValue === '0' || strValue === '男' || strValue === 'male' || strValue === 'm' || + strValue === 'malegender' || strValue === 'man' || strValue === 'boy' || + strValue === '男性' || strValue === '男士') { + return '男'; + } + + // 处理女性值 + if (strValue === '1' || strValue === '女' || strValue === 'female' || strValue === 'f' || + strValue === 'femalegender' || strValue === 'woman' || strValue === 'girl' || + strValue === '女性' || strValue === '女士') { + return '女'; + } + + // 如果都不是,返回原值或'-' + return '-'; + }, + // 获取用于后端的性别值 + getGenderValueForBackend(patient) { + // 优先使用数字类型的genderEnum或gender字段 + if (patient.genderEnum !== undefined && patient.genderEnum !== null) { + return patient.genderEnum; + } + if (patient.gender !== undefined && patient.gender !== null) { + return patient.gender; + } + + // 如果genderEnum_enumText是"男性"或"女性",转换为对应的数字 + if (patient.genderEnum_enumText) { + const text = patient.genderEnum_enumText.toLowerCase(); + if (text === '男性' || text === '男') { + return 0; + } else if (text === '女性' || text === '女') { + return 1; + } + } + // 默认返回0(男性) + return 0; + }, + // 检测是否为移动设备 checkMobileDevice() { this.isMobile = window.innerWidth <= 768;