80 门诊医生站检查申请单开单界面,排班的回显问题
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
package com.openhis.web.appointmentmanage.appservice.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.openhis.appointmentmanage.domain.DoctorSchedule;
|
||||
import com.openhis.appointmentmanage.domain.DoctorScheduleWithDateDto;
|
||||
import com.openhis.appointmentmanage.domain.SchedulePool;
|
||||
import com.openhis.appointmentmanage.domain.ScheduleSlot;
|
||||
import com.openhis.appointmentmanage.mapper.DoctorScheduleMapper;
|
||||
@@ -16,13 +17,9 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@@ -39,10 +36,6 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
||||
@Resource
|
||||
private DoctorScheduleMapper doctorScheduleMapper;
|
||||
|
||||
// 转换 LocalDateTime 为 Date 的通用方法
|
||||
Date now = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());
|
||||
Date tomorrow = Date.from(LocalDateTime.now().plusDays(1).atZone(ZoneId.systemDefault()).toInstant());
|
||||
|
||||
@Override
|
||||
public R<?> getDoctorScheduleList() {
|
||||
List<DoctorSchedule> list = doctorScheduleService.list();
|
||||
@@ -52,89 +45,46 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
||||
@Override
|
||||
public R<?> getDoctorScheduleListByDeptId(Long deptId) {
|
||||
List<DoctorSchedule> list = doctorScheduleService.list(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<DoctorSchedule>()
|
||||
.eq("dept_id", deptId)
|
||||
);
|
||||
new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<DoctorSchedule>()
|
||||
.eq("dept_id", deptId));
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> getDoctorScheduleListByDeptIdAndDateRange(Long deptId, String startDate, String endDate) {
|
||||
// 暂时返回所有科室的排班数据,直到我们确定日期范围过滤逻辑
|
||||
List<DoctorSchedule> list = doctorScheduleService.list(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<DoctorSchedule>()
|
||||
.eq("dept_id", deptId)
|
||||
);
|
||||
// 联表查询 adm_doctor_schedule LEFT JOIN adm_schedule_pool,
|
||||
// 通过 schedule_date 获取具体出诊日期,解决按星期匹配导致日期错位的问题
|
||||
List<DoctorScheduleWithDateDto> list = doctorScheduleMapper.selectScheduleWithDateByDeptAndRange(
|
||||
deptId, startDate, endDate);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Transactional(readOnly = true)
|
||||
@Override
|
||||
public R<?> getTodayDoctorScheduleList() {
|
||||
// 获取今天的日期
|
||||
LocalDate today = LocalDate.now();
|
||||
DayOfWeek dayOfWeek = today.getDayOfWeek();
|
||||
|
||||
// 将 Java 的 DayOfWeek 转换为字符串表示
|
||||
String weekdayStr = convertDayOfWeekToString(dayOfWeek);
|
||||
|
||||
// 查询今天排班的医生
|
||||
LambdaQueryWrapper<DoctorSchedule> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(DoctorSchedule::getWeekday, weekdayStr) // 根据星期几查询
|
||||
.eq(DoctorSchedule::getIsStopped, false); // 只查询未停止的排班
|
||||
|
||||
List<DoctorSchedule> list = doctorScheduleService.list(queryWrapper);
|
||||
// 联表查询 adm_schedule_pool,按今日具体日期查询排班,替代原来按星期匹配的方式
|
||||
String todayStr = LocalDate.now().toString(); // yyyy-MM-dd
|
||||
List<DoctorScheduleWithDateDto> list = doctorScheduleMapper.selectTodaySchedule(todayStr);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Transactional(readOnly = true)
|
||||
@Override
|
||||
public R<?> getTodayMySchedule() {
|
||||
// 获取今天的日期
|
||||
LocalDate today = LocalDate.now();
|
||||
DayOfWeek dayOfWeek = today.getDayOfWeek();
|
||||
// 联表查询 adm_schedule_pool,按今日具体日期 + 医生ID 查询个人排班
|
||||
String todayStr = LocalDate.now().toString(); // yyyy-MM-dd
|
||||
|
||||
// 将 Java 的 DayOfWeek 转换为字符串表示
|
||||
String weekdayStr = convertDayOfWeekToString(dayOfWeek);
|
||||
// 从 SecurityUtils 获取当前登录医生ID
|
||||
Long currentDoctorId = SecurityUtils.getLoginUser().getPractitionerId();
|
||||
|
||||
// 获取当前登录医生的ID(需要从SecurityUtils获取)
|
||||
// 如果没有SecurityUtils,可以从参数传入或使用其他方式获取
|
||||
// Long currentDoctorId = SecurityUtils.getLoginUser().getPractitionerId();
|
||||
|
||||
// 查询当前医生今天的排班
|
||||
LambdaQueryWrapper<DoctorSchedule> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(DoctorSchedule::getWeekday, weekdayStr) // 根据星期几查询
|
||||
// .eq(DoctorSchedule::getDoctorId, currentDoctorId) // 只查询当前医生的排班
|
||||
.eq(DoctorSchedule::getIsStopped, false); // 只查询未停止的排班
|
||||
|
||||
List<DoctorSchedule> list = doctorScheduleService.list(queryWrapper);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 DayOfWeek 转换为字符串表示
|
||||
* @param dayOfWeek DayOfWeek枚举
|
||||
* @return 对应的字符串表示
|
||||
*/
|
||||
private String convertDayOfWeekToString(DayOfWeek dayOfWeek) {
|
||||
switch (dayOfWeek) {
|
||||
case MONDAY:
|
||||
return "1"; // 或者 "星期一" 或 "Monday",取决于数据库中的实际存储格式
|
||||
case TUESDAY:
|
||||
return "2";
|
||||
case WEDNESDAY:
|
||||
return "3";
|
||||
case THURSDAY:
|
||||
return "4";
|
||||
case FRIDAY:
|
||||
return "5";
|
||||
case SATURDAY:
|
||||
return "6";
|
||||
case SUNDAY:
|
||||
return "7";
|
||||
default:
|
||||
return "1"; // 默认为星期一
|
||||
if (currentDoctorId != null) {
|
||||
List<DoctorScheduleWithDateDto> list = doctorScheduleMapper.selectTodayMySchedule(todayStr,
|
||||
currentDoctorId);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
// 如果未绑定医生,则返回空列表
|
||||
return R.ok(Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -157,10 +107,12 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
||||
newSchedule.setEndTime(doctorSchedule.getEndTime());
|
||||
newSchedule.setLimitNumber(doctorSchedule.getLimitNumber());
|
||||
// call_sign_record 字段不能为null,设置默认值为空字符串
|
||||
newSchedule.setCallSignRecord(doctorSchedule.getCallSignRecord() != null ? doctorSchedule.getCallSignRecord() : "");
|
||||
newSchedule.setCallSignRecord(
|
||||
doctorSchedule.getCallSignRecord() != null ? doctorSchedule.getCallSignRecord() : "");
|
||||
newSchedule.setRegisterItem(doctorSchedule.getRegisterItem() != null ? doctorSchedule.getRegisterItem() : "");
|
||||
newSchedule.setRegisterFee(doctorSchedule.getRegisterFee() != null ? doctorSchedule.getRegisterFee() : 0);
|
||||
newSchedule.setDiagnosisItem(doctorSchedule.getDiagnosisItem() != null ? doctorSchedule.getDiagnosisItem() : "");
|
||||
newSchedule
|
||||
.setDiagnosisItem(doctorSchedule.getDiagnosisItem() != null ? doctorSchedule.getDiagnosisItem() : "");
|
||||
newSchedule.setDiagnosisFee(doctorSchedule.getDiagnosisFee() != null ? doctorSchedule.getDiagnosisFee() : 0);
|
||||
newSchedule.setIsOnline(doctorSchedule.getIsOnline() != null ? doctorSchedule.getIsOnline() : true);
|
||||
newSchedule.setIsStopped(doctorSchedule.getIsStopped() != null ? doctorSchedule.getIsStopped() : false);
|
||||
@@ -180,7 +132,7 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
||||
if (poolSaved) {
|
||||
// 创建号源槽
|
||||
List<ScheduleSlot> slots = createScheduleSlots(pool.getId().intValue(), newSchedule.getLimitNumber(),
|
||||
newSchedule.getStartTime(), newSchedule.getEndTime());
|
||||
newSchedule.getStartTime(), newSchedule.getEndTime());
|
||||
boolean slotsSaved = scheduleSlotService.saveBatch(slots);
|
||||
|
||||
if (slotsSaved) {
|
||||
@@ -192,8 +144,7 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
||||
} else {
|
||||
throw new RuntimeException("创建号源槽失败");
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
throw new RuntimeException("创建号源池失败");
|
||||
}
|
||||
} else {
|
||||
@@ -221,10 +172,12 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
||||
newSchedule.setEndTime(doctorSchedule.getEndTime());
|
||||
newSchedule.setLimitNumber(doctorSchedule.getLimitNumber());
|
||||
// call_sign_record 字段不能为null,设置默认值为空字符串
|
||||
newSchedule.setCallSignRecord(doctorSchedule.getCallSignRecord() != null ? doctorSchedule.getCallSignRecord() : "");
|
||||
newSchedule.setCallSignRecord(
|
||||
doctorSchedule.getCallSignRecord() != null ? doctorSchedule.getCallSignRecord() : "");
|
||||
newSchedule.setRegisterItem(doctorSchedule.getRegisterItem() != null ? doctorSchedule.getRegisterItem() : "");
|
||||
newSchedule.setRegisterFee(doctorSchedule.getRegisterFee() != null ? doctorSchedule.getRegisterFee() : 0);
|
||||
newSchedule.setDiagnosisItem(doctorSchedule.getDiagnosisItem() != null ? doctorSchedule.getDiagnosisItem() : "");
|
||||
newSchedule
|
||||
.setDiagnosisItem(doctorSchedule.getDiagnosisItem() != null ? doctorSchedule.getDiagnosisItem() : "");
|
||||
newSchedule.setDiagnosisFee(doctorSchedule.getDiagnosisFee() != null ? doctorSchedule.getDiagnosisFee() : 0);
|
||||
newSchedule.setIsOnline(doctorSchedule.getIsOnline() != null ? doctorSchedule.getIsOnline() : true);
|
||||
newSchedule.setIsStopped(doctorSchedule.getIsStopped() != null ? doctorSchedule.getIsStopped() : false);
|
||||
@@ -244,7 +197,7 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
||||
if (poolSaved) {
|
||||
// 创建号源槽
|
||||
List<ScheduleSlot> slots = createScheduleSlots(pool.getId().intValue(), newSchedule.getLimitNumber(),
|
||||
newSchedule.getStartTime(), newSchedule.getEndTime());
|
||||
newSchedule.getStartTime(), newSchedule.getEndTime());
|
||||
boolean slotsSaved = scheduleSlotService.saveBatch(slots);
|
||||
|
||||
if (slotsSaved) {
|
||||
@@ -252,8 +205,7 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
||||
} else {
|
||||
throw new RuntimeException("创建号源槽失败");
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
throw new RuntimeException("创建号源池失败");
|
||||
}
|
||||
} else {
|
||||
@@ -367,7 +319,8 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
||||
/**
|
||||
* 创建号源槽
|
||||
*/
|
||||
private List<ScheduleSlot> createScheduleSlots(Integer poolId, Integer limitNumber, LocalTime startTime, LocalTime endTime) {
|
||||
private List<ScheduleSlot> createScheduleSlots(Integer poolId, Integer limitNumber, LocalTime startTime,
|
||||
LocalTime endTime) {
|
||||
List<ScheduleSlot> slots = new ArrayList<>();
|
||||
|
||||
// 计算时间间隔
|
||||
@@ -377,7 +330,7 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
||||
for (int i = 1; i <= limitNumber; i++) {
|
||||
ScheduleSlot slot = new ScheduleSlot();
|
||||
slot.setPoolId(poolId);
|
||||
slot.setSeqNo(i); // 序号
|
||||
slot.setSeqNo(i); // 序号
|
||||
slot.setStatus(0); // 0表示可用
|
||||
// 计算预计叫号时间,均匀分布在开始时间和结束时间之间
|
||||
LocalTime expectTime = startTime.plusMinutes(interval * (i - 1));
|
||||
@@ -411,14 +364,22 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
||||
*/
|
||||
private int getDayOfWeekNumber(String weekday) {
|
||||
switch (weekday) {
|
||||
case "周一": return 1;
|
||||
case "周二": return 2;
|
||||
case "周三": return 3;
|
||||
case "周四": return 4;
|
||||
case "周五": return 5;
|
||||
case "周六": return 6;
|
||||
case "周日": return 7;
|
||||
default: return 1; // 默认周一
|
||||
case "周一":
|
||||
return 1;
|
||||
case "周二":
|
||||
return 2;
|
||||
case "周三":
|
||||
return 3;
|
||||
case "周四":
|
||||
return 4;
|
||||
case "周五":
|
||||
return 5;
|
||||
case "周六":
|
||||
return 6;
|
||||
case "周日":
|
||||
return 7;
|
||||
default:
|
||||
return 1; // 默认周一
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,8 +393,7 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
||||
// 1. 根据排班ID找到关联的号源池
|
||||
List<SchedulePool> pools = schedulePoolService.list(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<SchedulePool>()
|
||||
.eq("schedule_id", doctorScheduleId)
|
||||
);
|
||||
.eq("schedule_id", doctorScheduleId));
|
||||
|
||||
if (ObjectUtil.isNotEmpty(pools)) {
|
||||
List<Long> poolIds = pools.stream().map(SchedulePool::getId).collect(java.util.stream.Collectors.toList());
|
||||
@@ -441,11 +401,11 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
||||
// 2. 根据号源池ID找到所有关联的号源槽
|
||||
List<ScheduleSlot> slots = scheduleSlotService.list(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<ScheduleSlot>()
|
||||
.in("pool_id", poolIds)
|
||||
);
|
||||
.in("pool_id", poolIds));
|
||||
|
||||
if (ObjectUtil.isNotEmpty(slots)) {
|
||||
List<Integer> slotIds = slots.stream().map(ScheduleSlot::getId).collect(java.util.stream.Collectors.toList());
|
||||
List<Integer> slotIds = slots.stream().map(ScheduleSlot::getId)
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
// 3. 逻辑删除所有号源槽
|
||||
scheduleSlotService.removeByIds(slotIds);
|
||||
}
|
||||
|
||||
@@ -73,5 +73,103 @@
|
||||
</set>
|
||||
WHERE id = #{id}
|
||||
</update>
|
||||
</mapper>
|
||||
|
||||
<!-- 联表查询:根据科室ID和日期范围查询排班信息(含具体出诊日期) -->
|
||||
<select id="selectScheduleWithDateByDeptAndRange"
|
||||
resultType="com.openhis.appointmentmanage.domain.DoctorScheduleWithDateDto">
|
||||
SELECT
|
||||
ds.id,
|
||||
ds.weekday,
|
||||
ds.time_period AS time_period,
|
||||
ds.doctor AS doctor_name,
|
||||
ds.clinic AS clinic,
|
||||
sp.clinic_room AS clinic_room,
|
||||
org.name AS dept_name,
|
||||
ds.start_time AS start_time,
|
||||
ds.end_time AS end_time,
|
||||
ds.limit_number AS limit_number,
|
||||
ds.call_sign_record AS call_sign_record,
|
||||
ds.register_item AS register_item,
|
||||
ds.register_fee AS register_fee,
|
||||
ds.diagnosis_item AS diagnosis_item,
|
||||
ds.diagnosis_fee AS diagnosis_fee,
|
||||
ds.is_online AS is_online,
|
||||
ds.is_stopped AS is_stopped,
|
||||
ds.stop_reason AS stop_reason,
|
||||
ds.dept_id AS dept_id,
|
||||
sp.doctor_id AS doctor_id,
|
||||
sp.schedule_date AS schedule_date
|
||||
FROM adm_doctor_schedule ds
|
||||
LEFT JOIN adm_schedule_pool sp ON sp.schedule_id = ds.id
|
||||
LEFT JOIN adm_organization org ON ds.dept_id = org.id
|
||||
WHERE ds.dept_id = #{deptId}
|
||||
AND sp.schedule_date BETWEEN #{startDate}::date AND #{endDate}::date
|
||||
ORDER BY sp.schedule_date, ds.time_period
|
||||
</select>
|
||||
|
||||
<!-- 联表查询:获取今日所有排班 -->
|
||||
<select id="selectTodaySchedule"
|
||||
resultType="com.openhis.appointmentmanage.domain.DoctorScheduleWithDateDto">
|
||||
SELECT
|
||||
ds.id,
|
||||
ds.weekday,
|
||||
ds.time_period AS time_period,
|
||||
ds.doctor AS doctor_name,
|
||||
ds.clinic AS clinic,
|
||||
sp.clinic_room AS clinic_room,
|
||||
org.name AS dept_name,
|
||||
ds.start_time AS start_time,
|
||||
ds.end_time AS end_time,
|
||||
ds.limit_number AS limit_number,
|
||||
ds.register_item AS register_item,
|
||||
ds.register_fee AS register_fee,
|
||||
ds.diagnosis_item AS diagnosis_item,
|
||||
ds.diagnosis_fee AS diagnosis_fee,
|
||||
ds.is_online AS is_online,
|
||||
ds.is_stopped AS is_stopped,
|
||||
ds.stop_reason AS stop_reason,
|
||||
ds.dept_id AS dept_id,
|
||||
sp.doctor_id AS doctor_id,
|
||||
sp.schedule_date AS schedule_date
|
||||
FROM adm_doctor_schedule ds
|
||||
INNER JOIN adm_schedule_pool sp ON sp.schedule_id = ds.id
|
||||
LEFT JOIN adm_organization org ON ds.dept_id = org.id
|
||||
WHERE sp.schedule_date = #{today}::date
|
||||
AND (ds.is_stopped = false OR ds.is_stopped IS NULL)
|
||||
ORDER BY ds.time_period
|
||||
</select>
|
||||
|
||||
<!-- 联表查询:获取指定医生今日排班 -->
|
||||
<select id="selectTodayMySchedule"
|
||||
resultType="com.openhis.appointmentmanage.domain.DoctorScheduleWithDateDto">
|
||||
SELECT
|
||||
ds.id,
|
||||
ds.weekday,
|
||||
ds.time_period AS time_period,
|
||||
ds.doctor AS doctor_name,
|
||||
ds.clinic AS clinic,
|
||||
sp.clinic_room AS clinic_room,
|
||||
org.name AS dept_name,
|
||||
ds.start_time AS start_time,
|
||||
ds.end_time AS end_time,
|
||||
ds.limit_number AS limit_number,
|
||||
ds.register_item AS register_item,
|
||||
ds.register_fee AS register_fee,
|
||||
ds.diagnosis_item AS diagnosis_item,
|
||||
ds.diagnosis_fee AS diagnosis_fee,
|
||||
ds.is_online AS is_online,
|
||||
ds.is_stopped AS is_stopped,
|
||||
ds.stop_reason AS stop_reason,
|
||||
ds.dept_id AS dept_id,
|
||||
sp.doctor_id AS doctor_id,
|
||||
sp.schedule_date AS schedule_date
|
||||
FROM adm_doctor_schedule ds
|
||||
INNER JOIN adm_schedule_pool sp ON sp.schedule_id = ds.id
|
||||
LEFT JOIN adm_organization org ON ds.dept_id = org.id
|
||||
WHERE sp.schedule_date = #{today}::date
|
||||
AND sp.doctor_id = #{doctorId}
|
||||
AND (ds.is_stopped = false OR ds.is_stopped IS NULL)
|
||||
ORDER BY ds.time_period
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.openhis.appointmentmanage.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
|
||||
/**
|
||||
* 医生排班(含具体日期)DTO
|
||||
* 通过 adm_doctor_schedule LEFT JOIN adm_schedule_pool 联表查询得到,
|
||||
* 在原排班信息基础上增加了号源池中的具体出诊日期字段。
|
||||
*
|
||||
* @date 2026-02-25
|
||||
*/
|
||||
@Data
|
||||
public class DoctorScheduleWithDateDto {
|
||||
|
||||
/** 排班记录ID */
|
||||
private Long id;
|
||||
|
||||
/** 星期 */
|
||||
private String weekday;
|
||||
|
||||
/** 时段(上午/下午) */
|
||||
private String timePeriod;
|
||||
|
||||
/** 开始时间 */
|
||||
private LocalTime startTime;
|
||||
|
||||
/** 结束时间 */
|
||||
private LocalTime endTime;
|
||||
|
||||
/** 限号数量 */
|
||||
private Integer limitNumber;
|
||||
|
||||
/** 号源记录 */
|
||||
private String callSignRecord;
|
||||
|
||||
/** 挂号项目 */
|
||||
private String registerItem;
|
||||
|
||||
/** 挂号费 */
|
||||
private Integer registerFee;
|
||||
|
||||
/** 诊查项目 */
|
||||
private String diagnosisItem;
|
||||
|
||||
/** 诊疗费 */
|
||||
private Integer diagnosisFee;
|
||||
|
||||
/** 线上挂号 */
|
||||
private Boolean isOnline;
|
||||
|
||||
/** 是否停诊 */
|
||||
private Boolean isStopped;
|
||||
|
||||
/** 停诊原因 */
|
||||
private String stopReason;
|
||||
|
||||
/** 关联科室ID */
|
||||
private Long deptId;
|
||||
|
||||
/** 医生姓名 */
|
||||
private String doctorName;
|
||||
|
||||
/** 诊室/位置 */
|
||||
@JsonProperty("clinicRoom")
|
||||
private String clinicRoom;
|
||||
|
||||
/** 医生排班表中设置的具体诊室位置 */
|
||||
private String clinic;
|
||||
|
||||
/** 科室名称 */
|
||||
private String deptName;
|
||||
|
||||
/** 科室位置 */
|
||||
private String deptLocation;
|
||||
|
||||
/** 医生ID(来自 adm_schedule_pool.doctor_id) */
|
||||
private Long doctorId;
|
||||
|
||||
/** 具体出诊日期(来自 adm_schedule_pool.schedule_date) */
|
||||
private LocalDate scheduleDate;
|
||||
}
|
||||
@@ -2,7 +2,11 @@ package com.openhis.appointmentmanage.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.openhis.appointmentmanage.domain.DoctorSchedule;
|
||||
import com.openhis.appointmentmanage.domain.DoctorScheduleWithDateDto;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface DoctorScheduleMapper extends BaseMapper<DoctorSchedule> {
|
||||
@@ -10,8 +14,43 @@ public interface DoctorScheduleMapper extends BaseMapper<DoctorSchedule> {
|
||||
* 自定义插入方法,排除id字段(数据库GENERATED ALWAYS)
|
||||
*/
|
||||
int insertWithoutId(DoctorSchedule doctorSchedule);
|
||||
|
||||
/**
|
||||
* 自定义更新方法
|
||||
*/
|
||||
int updateDoctorSchedule(DoctorSchedule doctorSchedule);
|
||||
|
||||
/**
|
||||
* 联表查询:根据科室ID和日期范围查询排班信息(含具体出诊日期)
|
||||
* 通过 LEFT JOIN adm_schedule_pool 获取 schedule_date 字段,
|
||||
* 解决原来只按星期匹配导致日期错位的问题。
|
||||
*
|
||||
* @param deptId 科室ID
|
||||
* @param startDate 起始日期(yyyy-MM-dd)
|
||||
* @param endDate 结束日期(yyyy-MM-dd)
|
||||
* @return 带具体日期的排班列表
|
||||
*/
|
||||
List<DoctorScheduleWithDateDto> selectScheduleWithDateByDeptAndRange(
|
||||
@Param("deptId") Long deptId,
|
||||
@Param("startDate") String startDate,
|
||||
@Param("endDate") String endDate);
|
||||
|
||||
/**
|
||||
* 联表查询:获取今日所有排班(通过 adm_schedule_pool.schedule_date = 今天)
|
||||
*
|
||||
* @param today 今日日期(yyyy-MM-dd)
|
||||
* @return 今日排班列表
|
||||
*/
|
||||
List<DoctorScheduleWithDateDto> selectTodaySchedule(@Param("today") String today);
|
||||
|
||||
/**
|
||||
* 联表查询:获取指定医生今日排班
|
||||
*
|
||||
* @param today 今日日期(yyyy-MM-dd)
|
||||
* @param doctorId 医生ID
|
||||
* @return 指定医生的今日排班列表
|
||||
*/
|
||||
List<DoctorScheduleWithDateDto> selectTodayMySchedule(
|
||||
@Param("today") String today,
|
||||
@Param("doctorId") Long doctorId);
|
||||
}
|
||||
|
||||
@@ -378,7 +378,7 @@ import {ElDialog, ElForm, ElFormItem, ElInput, ElMessage, ElMessageBox, ElOption
|
||||
import {DocumentRemove, EditPen, View, Delete} from '@element-plus/icons-vue'
|
||||
import {listDept, searchDept} from '@/api/appoinmentmanage/dept'
|
||||
import {getLocationTree, getPractitionerMetadata, getHealthcareMetadata} from '@/views/charge/outpatientregistration/components/outpatientregistration'
|
||||
import {addDoctorSchedule, addDoctorScheduleWithDate, updateDoctorSchedule, deleteDoctorSchedule, getRegisterOrganizations, getDoctorScheduleListByDeptId} from './api'
|
||||
import {addDoctorSchedule, addDoctorScheduleWithDate, updateDoctorSchedule, deleteDoctorSchedule, getRegisterOrganizations, getDoctorScheduleListByDeptId, getDoctorScheduleListByDeptIdAndDateRange} from './api'
|
||||
import {getClinicRoomList} from '@/api/appoinmentmanage/clinicRoom'
|
||||
import {getInitOption, getRegistrationItems, getClinicItems} from '@/views/basicservices/registrationfee/components/registrationfee'
|
||||
import { deptTreeSelect } from '@/api/system/user'
|
||||
@@ -1004,6 +1004,12 @@ const generateWeekSchedule = (startDate, workTimeConfig) => {
|
||||
return schedule
|
||||
}
|
||||
|
||||
// 格式化日期为 yyyy-MM-dd 字符串
|
||||
const formatDateStr = (date) => {
|
||||
const d = new Date(date)
|
||||
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
|
||||
}
|
||||
|
||||
// 重新加载排班数据
|
||||
const reloadScheduleData = async () => {
|
||||
const row = currentDept.value
|
||||
@@ -1012,23 +1018,31 @@ const reloadScheduleData = async () => {
|
||||
// 使用组件级别的 workTimeConfig
|
||||
const weekSchedule = generateWeekSchedule(filterParams.value.startDate, workTimeConfig.value)
|
||||
|
||||
// 获取该科室的现有排班数据
|
||||
// 计算当前周的起止日期,用于联表查询
|
||||
const startDateStr = formatDateStr(filterParams.value.startDate)
|
||||
const endDate = new Date(filterParams.value.startDate)
|
||||
endDate.setDate(endDate.getDate() + 6)
|
||||
const endDateStr = formatDateStr(endDate)
|
||||
|
||||
// 获取该科室在指定日期范围内的排班数据(联表查询 adm_schedule_pool 获取具体日期)
|
||||
try {
|
||||
const response = await getDoctorScheduleListByDeptId(row.id)
|
||||
const response = await getDoctorScheduleListByDeptIdAndDateRange(row.id, startDateStr, endDateStr)
|
||||
if (response.code === 200) {
|
||||
const actualData = response.data
|
||||
const deptSchedules = Array.isArray(actualData) ? actualData : (actualData && actualData.code === 200 ? actualData.data || [] : [])
|
||||
|
||||
// 创建一个映射表,提高查找效率
|
||||
// 以 "具体日期-时段" 为 key 创建映射表,替代原来的 "星期-时段"
|
||||
const scheduleMap = {}
|
||||
deptSchedules.forEach(schedule => {
|
||||
const key = `${schedule.weekday}-${schedule.timePeriod}`
|
||||
// scheduleDate 来自 adm_schedule_pool.schedule_date,是具体的出诊日期
|
||||
const key = `${schedule.scheduleDate}-${schedule.timePeriod}`
|
||||
scheduleMap[key] = schedule
|
||||
})
|
||||
|
||||
// 将现有排班数据合并到周计划中
|
||||
// 将现有排班数据合并到周计划中(以具体日期匹配)
|
||||
weekSchedule.forEach(slot => {
|
||||
const key = `${slot.weekday}-${slot.timeSlot}`
|
||||
// slot.date 是前端生成的具体日期(yyyy-MM-dd),与后端的 scheduleDate 一致
|
||||
const key = `${slot.date}-${slot.timeSlot}`
|
||||
const existingSchedule = scheduleMap[key]
|
||||
|
||||
if (existingSchedule) {
|
||||
@@ -1036,21 +1050,20 @@ const reloadScheduleData = async () => {
|
||||
slot.doctorName = existingSchedule.doctor
|
||||
slot.doctorId = String(existingSchedule.doctorId) // 确保为字符串
|
||||
|
||||
// --- 新增容错逻辑 ---
|
||||
// --- 容错逻辑:校验医生ID是否在当前医生列表中 ---
|
||||
const allAvailableDoctors = [...doctorOptions.value['普通'], ...doctorOptions.value['专家']];
|
||||
const matchedDoctorById = allAvailableDoctors.find(doc => doc.id === slot.doctorId);
|
||||
|
||||
if (!matchedDoctorById) { // 如果排班记录中的doctorId在当前医生列表中找不到
|
||||
if (!matchedDoctorById) {
|
||||
// 尝试根据医生姓名进行匹配
|
||||
const matchedDoctorByName = allAvailableDoctors.find(doc => doc.label === slot.doctorName);
|
||||
if (matchedDoctorByName) {
|
||||
slot.doctorId = matchedDoctorByName.id; // 使用当前医生列表中的正确ID
|
||||
slot.doctorId = matchedDoctorByName.id;
|
||||
console.warn(`【调试警告】排班记录doctorId ${existingSchedule.doctorId} (姓名: ${existingSchedule.doctor}) 与当前医生列表不匹配。已根据姓名修正为ID: ${matchedDoctorByName.id}`);
|
||||
} else {
|
||||
// 如果医生ID和姓名都匹配不上,则清空医生信息,避免显示错误数据
|
||||
slot.doctorId = null;
|
||||
slot.doctorName = '';
|
||||
console.error(`【调试错误】排班记录doctorId ${existingSchedule.doctorId} 和医生姓名 "${existingSchedule.doctor}" 都未在当前医生列表中找到。该医生信息可能已过时或错误。`);
|
||||
console.error(`【调试错误】排班记录doctorId ${existingSchedule.doctorId} 和医生姓名 "${existingSchedule.doctor}" 都未在当前医生列表中找到。`);
|
||||
}
|
||||
}
|
||||
// --- 结束容错逻辑 ---
|
||||
@@ -1066,7 +1079,7 @@ const reloadScheduleData = async () => {
|
||||
slot.online = existingSchedule.isOnline
|
||||
slot.stopClinic = existingSchedule.isStopped
|
||||
slot.stopReason = existingSchedule.stopReason
|
||||
slot.backendId = existingSchedule.id // 关键修复:保存后端ID
|
||||
slot.backendId = existingSchedule.id // 保存后端ID
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -904,11 +904,12 @@ const getTaskIcon = (category) => {
|
||||
// 获取日程数据(实际应用中应该从API获取)
|
||||
const fetchScheduleList = async () => {
|
||||
try {
|
||||
console.log('Fetching schedule list...')
|
||||
const response = await getTodayMySchedule()
|
||||
console.log('今日日程原始响应:', response)
|
||||
if (response.code === 200) {
|
||||
// 将API返回的数据转换为前端所需的格式
|
||||
const scheduleData = response.data.map((schedule, index) => {
|
||||
const scheduleData = (response.data || []).map((schedule, index) => {
|
||||
console.log(`排班记录[${index}]:`, schedule)
|
||||
// 根据排班类型设置标签类型
|
||||
let tagType = 'info'
|
||||
if (schedule.shift) {
|
||||
@@ -920,8 +921,15 @@ const fetchScheduleList = async () => {
|
||||
// 确定标题
|
||||
const title = schedule.doctorName ? `${schedule.doctorName}医生排班` : '医生排班'
|
||||
|
||||
// 确定位置
|
||||
const location = schedule.clinicRoom || schedule.deptId || '未知科室'
|
||||
// 按照用户最新要求:直接展示 adm_doctor_schedule 的 clinic 字段或诊室名(clinicRoom),优先于科室名称。
|
||||
// 增加对下划线命名的兼容性检查,防止后端映射异常。
|
||||
const clinic = schedule.clinic
|
||||
const roomName = schedule.clinicRoom || schedule.clinic_room
|
||||
const department = schedule.deptName || schedule.dept_name
|
||||
// 优先显示排班里设置的 clinic,其次是号源池的诊室名称,如果没有则显示科室名称,最后显示默认值
|
||||
const location = clinic || roomName || (department ? `${department}` : '院内')
|
||||
|
||||
console.log(`排班记录[${index}] 位置信息:`, { clinic, roomName, department, location })
|
||||
|
||||
return {
|
||||
id: schedule.id || index,
|
||||
|
||||
Reference in New Issue
Block a user