@@ -4,20 +4,28 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R ;
import com.openhis.administration.domain.Patient ;
import com.openhis.administration.service.IPatientService ;
import com.openhis.appointmentmanage.domain.DoctorSchedule ;
import com.openhis.appointmentmanage.mapper.DoctorScheduleMapper ;
import com.openhis.appointmentmanage.service.IDoctorScheduleService ;
import com.openhis.clinical.domain.Order ;
import com.openhis.clinical.domain.Ticket ;
import com.openhis.clinical.mapper.OrderMapper ;
import com.openhis.clinical.service.ITicketService ;
import com.openhis.web.appointmentmanage.appservice.IDoctorScheduleAppService ;
import com.openhis.web.appointmentmanage.appservice.ITicketAppService ;
import com.openhis.web.appointmentmanage.dto.TicketDto ;
import org.springframework.stereotype.Service ;
import javax.annotation.Resource ;
import java.text.SimpleDateFormat ;
import java.time.* ;
import java.util.ArrayList ;
import java.util.Date ;
import java.util.HashMap ;
import java.util.List ;
import java.util.Map ;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
/**
* 号源管理应用服务实现类
*
@@ -31,145 +39,14 @@ public class TicketAppServiceImpl implements ITicketAppService {
@Resource
private IPatientService patientService ;
@Resource
private IDoctorScheduleAppService doctorScheduleAppService ;
@Resource
private DoctorScheduleMapper doctorScheduleMapper ;
@Resource
private OrderMapper orderMapper ;
/**
* 查询号源列表
*
* @param params 查询参数
* @return 号源列表
*/
@Override
public R < ? > listTicket ( Map < String , Object > params ) {
// 调试日志:打印所有参数
System . out . println ( " === listTicket方法收到的所有参数: === " ) ;
for ( Map . Entry < String , Object > entry : params . entrySet ( ) ) {
System . out . println ( entry . getKey ( ) + " : " + entry . getValue ( ) ) ;
}
System . out . println ( " ================================= " ) ;
// 构建查询条件
Ticket ticket = new Ticket ( ) ;
// 设置查询参数
// 处理日期参数
if ( params . containsKey ( " date " ) ) {
String date = ( String ) params . get ( " date " ) ;
try {
// 将日期字符串转换为Date类型, 设置到appointmentDate字段
SimpleDateFormat sdf = new SimpleDateFormat ( " yyyy-MM-dd " ) ;
Date appointmentDate = sdf . parse ( date ) ;
ticket . setAppointmentDate ( appointmentDate ) ;
System . out . println ( " 设置的appointmentDate: " + appointmentDate ) ;
} catch ( Exception e ) {
// 日期格式错误,忽略该参数
System . out . println ( " 日期格式错误,忽略该参数: " + date + " ,错误信息: " + e . getMessage ( ) ) ;
}
}
// 处理状态参数
if ( params . containsKey ( " status " ) ) {
String status = ( String ) params . get ( " status " ) ;
System . out . println ( " 接收到的status参数: " + status ) ;
if ( ! " all " . equals ( status ) & & ! " 全部 " . equals ( status ) ) {
// 将中文状态转换为英文状态
if ( " 未预约 " . equals ( status ) ) {
ticket . setStatus ( " unbooked " ) ;
} else if ( " 已预约 " . equals ( status ) ) {
ticket . setStatus ( " booked " ) ;
} else if ( " 已取号 " . equals ( status ) ) {
ticket . setStatus ( " checked " ) ;
} else if ( " 已取消 " . equals ( status ) ) {
ticket . setStatus ( " cancelled " ) ;
} else if ( " 已锁定 " . equals ( status ) ) {
ticket . setStatus ( " locked " ) ;
} else {
ticket . setStatus ( status ) ;
}
System . out . println ( " 设置的status: " + ticket . getStatus ( ) ) ;
}
}
if ( params . containsKey ( " name " ) ) {
String name = ( String ) params . get ( " name " ) ;
ticket . setPatientName ( name ) ;
}
if ( params . containsKey ( " card " ) ) {
String card = ( String ) params . get ( " card " ) ;
ticket . setMedicalCard ( card ) ;
}
if ( params . containsKey ( " phone " ) ) {
String phone = ( String ) params . get ( " phone " ) ;
ticket . setPhone ( phone ) ;
}
if ( params . containsKey ( " type " ) ) {
String type = ( String ) params . get ( " type " ) ;
System . out . println ( " 前端传递的type参数值: " + type ) ;
if ( ! " all " . equals ( type ) ) {
// 类型映射转换:前端传递英文类型,数据库存储中文类型
if ( " general " . equals ( type ) ) {
ticket . setTicketType ( " 普通 " ) ;
} else if ( " expert " . equals ( type ) ) {
ticket . setTicketType ( " 专家 " ) ;
} else if ( " 普通 " . equals ( type ) ) {
ticket . setTicketType ( " 普通 " ) ;
} else if ( " 专家 " . equals ( type ) ) {
ticket . setTicketType ( " 专家 " ) ;
} else {
ticket . setTicketType ( type ) ;
}
System . out . println ( " 转换后的ticketType值: " + ticket . getTicketType ( ) ) ;
}
}
// 手动实现分页查询, 避免MyBatis-Plus自动COUNT查询的问题
int pageNum = params . get ( " page " ) ! = null ? Integer . valueOf ( params . get ( " page " ) . toString ( ) ) : 1 ;
int pageSize = params . get ( " limit " ) ! = null ? Integer . valueOf ( params . get ( " limit " ) . toString ( ) ) : 10 ;
// 调试:输出构建的查询条件
System . out . println ( " 构建的查询条件: ticketType= " + ticket . getTicketType ( ) + " , status= " + ticket . getStatus ( ) + " , appointmentDate= " + ticket . getAppointmentDate ( ) ) ;
// 1. 获取所有符合条件的记录
List < Ticket > allTickets = ticketService . selectTicketList ( ticket ) ;
// 调试:输出查询到的所有记录
System . out . println ( " 查询到的所有记录: " + allTickets ) ;
if ( ! allTickets . isEmpty ( ) ) {
for ( Ticket t : allTickets ) {
System . out . println ( " 记录详情: id= " + t . getId ( ) + " , ticketType= " + t . getTicketType ( ) + " , status= " + t . getStatus ( ) + " , appointmentDate= " + t . getAppointmentDate ( ) + " , deleteFlag= " + t . getDeleteFlag ( ) ) ;
}
}
// 2. 计算总记录数
long total = allTickets . size ( ) ;
System . out . println ( " 手动计算的总记录数: " + total ) ;
// 3. 手动分页
int start = ( pageNum - 1 ) * pageSize ;
int end = Math . min ( start + pageSize , allTickets . size ( ) ) ;
List < Ticket > pageTickets ;
if ( start > = end ) {
pageTickets = new ArrayList < > ( ) ;
} else {
pageTickets = allTickets . subList ( start , end ) ;
}
// 4. 转换为DTO
List < TicketDto > dtoList = pageTickets . stream ( ) . map ( this : : convertToDto ) . toList ( ) ;
// 5. 构建响应数据,符合前端预期格式
Map < String , Object > result = new HashMap < > ( ) ;
result . put ( " list " , dtoList ) ;
result . put ( " records " , dtoList ) ; // 兼容前端框架( 如Element UI) 可能使用的records字段
result . put ( " total " , total ) ;
result . put ( " page " , pageNum ) ;
result . put ( " current " , pageNum ) ; // 兼容前端框架可能使用的current字段
result . put ( " limit " , pageSize ) ;
result . put ( " pageSize " , pageSize ) ; // 兼容前端框架可能使用的pageSize字段
result . put ( " size " , pageSize ) ; // 兼容前端框架可能使用的size字段
result . put ( " pageNum " , pageNum ) ; // 兼容前端框架可能使用的pageNum字段
result . put ( " pages " , ( int ) Math . ceil ( ( double ) total / pageSize ) ) ; // 计算总页数
// 调试:输出响应数据
System . out . println ( " 返回的响应数据: " + result ) ;
return R . ok ( result ) ;
}
private static final Logger log = LoggerFactory . getLogger ( TicketAppServiceImpl . class ) ;
/**
* 预约号源
@@ -179,35 +56,73 @@ public class TicketAppServiceImpl implements ITicketAppService {
*/
@Override
public R < ? > bookTicket ( Map < String , Object > params ) {
// 1. 获取 ticketId 和 slotId
Long ticketId = null ;
Long slotId = null ;
if ( params . get ( " ticketId " ) ! = null ) {
ticketId = Long . valueOf ( params . get ( " ticketId " ) . toString ( ) ) ;
}
if ( ticketId = = null ) {
return R . fail ( " 参数错误 " ) ;
if ( params . get ( " slotId " ) ! = null ) {
slotId = Long . valueOf ( params . get ( " slotId " ) . toString ( ) ) ;
}
// 2. 参数校验
if ( ticketId = = null | | slotId = = null ) {
return R . fail ( " 参数错误: ticketId 或 slotId 不能为空 " ) ;
}
try {
// 3. 执行原有的预约逻辑
int result = ticketService . bookTicket ( params ) ;
return R . ok ( result > 0 ? " 预约成功 " : " 预约失败 " ) ;
if ( result > 0 ) {
// 4. 预约成功后,更新排班表状态
DoctorSchedule schedule = new DoctorSchedule ( ) ;
schedule . setId ( Math . toIntExact ( slotId ) ) ; // 对应 XML 中的 WHERE id = #{id}
schedule . setIsStopped ( true ) ; // 设置为已预约
schedule . setStopReason ( " booked " ) ; // 设置停用原因
// 执行更新
int updateCount = doctorScheduleMapper . updateDoctorSchedule ( schedule ) ;
if ( updateCount > 0 ) {
return R . ok ( " 预约成功并已更新排班状态 " ) ;
} else {
// 如果更新失败,可能需要根据业务逻辑决定是否回滚预约
return R . ok ( " 预约成功,但排班状态更新失败 " ) ;
}
} else {
return R . fail ( " 预约失败 " ) ;
}
} catch ( Exception e ) {
return R . fail ( e . getMessage ( ) ) ;
// e.printStackTrace() ;
log . error ( e . getMessage ( ) ) ;
return R . fail ( " 系统异常: " + e . getMessage ( ) ) ;
}
}
/**
* 取消预约
*
* @param ticketId 号源 ID
* @param slotId 医生排班 ID
* @return 结果
*/
@Override
public R < ? > cancelTicket ( Long ticke tId) {
if ( ticke tId = = null ) {
public R < ? > cancelTicket ( Long slo tId) {
if ( slo tId = = null ) {
return R . fail ( " 参数错误 " ) ;
}
try {
int result = ticketService . cancelTicket ( ticke tId) ;
return R . ok ( res ult > 0 ? " 取消成功 " : " 取消失败 " ) ;
ticketService . cancelTicket ( slo tId) ;
DoctorSchedule sched ule = new DoctorSchedule ( ) ;
schedule . setId ( Math . toIntExact ( slotId ) ) ; // 对应 WHERE id = #{id}
schedule . setIsStopped ( false ) ; // 设置为 false (数据库对应 0)
schedule . setStopReason ( " " ) ; // 将原因清空 (设为空字符串)
// 3. 调用自定义更新方法
int updateCount = doctorScheduleMapper . updateDoctorSchedule ( schedule ) ;
if ( updateCount > 0 ) {
return R . ok ( " 取消成功 " ) ;
} else {
return R . ok ( " 取消成功 " ) ;
}
} catch ( Exception e ) {
return R . fail ( e . getMessage ( ) ) ;
}
@@ -253,31 +168,87 @@ public class TicketAppServiceImpl implements ITicketAppService {
@Override
public R < ? > listAllTickets ( ) {
// 创建固定的测试数据,用于验证前端是否能展示 数据
List < TicketDto > t estTickets = new ArrayList < > ( ) ;
// 创建5条测试数据
for ( int i = 1 ; i < = 5 ; i + + ) {
TicketDto dto = new TicketDto ( ) ;
dto . setSlot_id ( ( long ) i ) ;
dto . setBusNo ( " TEST0000 " + i ) ;
dto . setDepartment ( " 内科 " ) ;
dto . setDoctor ( " 张三 " ) ;
dto . setTicketType ( " expert " ) ;
dto . setDateTime ( " 08:00-08:50 " ) ;
dto . setStatus ( " 未预约 " ) ;
dto . setFee ( " 150 " ) ;
dto . setAppointmentDate ( new Date ( ) ) ;
testTickets . add ( dto ) ;
// 1. 从 AppService 获取排班 数据
R < ? > r esponse = doctorScheduleAppService . getDoctorScheduleList ( ) ;
// 获取返回的 List 数据 (假设 R.ok 里的数据是 List<DoctorSchedule>)
List < DoctorSchedule > scheduleList = ( List < DoctorSchedule > ) response . getData ( ) ;
// 2. 转换数据为 TicketDto
List < TicketDto > tickets = new ArrayList < > ( ) ;
if ( scheduleList ! = null ) {
for ( DoctorSchedule schedule : scheduleList ) {
TicketDto dto = new TicketDto ( ) ;
// 基础信息映射
dto . setSlot_id ( Long . valueOf ( schedule . getId ( ) ) ) ; // Integer 转 Long
dto . setBusNo ( String . valueOf ( schedule . getId ( ) ) ) ; // 生成一个业务编号
dto . setDepartment ( String . valueOf ( schedule . getDeptId ( ) ) ) ; // 如果有科室名建议关联查询, 这里暂填ID
dto . setDoctor ( schedule . getDoctor ( ) ) ;
// 号源类型处理:根据挂号项目判断是普通号还是专家号
String registerItem = schedule . getRegisterItem ( ) ;
if ( registerItem ! = null & & registerItem . contains ( " 专家 " ) ) {
dto . setTicketType ( " expert " ) ;
} else {
dto . setTicketType ( " general " ) ;
}
// 时间处理:格式化为日期+时间范围,如 "2025-12-01 08:00-12:00"
String currentDate = LocalDate . now ( ) . toString ( ) ; // 或者从schedule中获取具体日期
String timeRange = schedule . getStartTime ( ) + " - " + schedule . getEndTime ( ) ;
dto . setDateTime ( currentDate + " " + timeRange ) ;
LocalTime nowTime = LocalTime . now ( ) ;
LocalTime endTime = schedule . getEndTime ( ) ;
String stopReason1 = schedule . getStopReason ( ) ;
if ( " cancelled " . equals ( stopReason1 ) | | ( endTime ! = null & & nowTime . isAfter ( endTime ) ) ) {
dto . setStatus ( " 已停诊 " ) ;
} else if ( Boolean . TRUE . equals ( schedule . getIsStopped ( ) ) ) {
// 获取原因并处理可能的空值
String stopReason = schedule . getStopReason ( ) ;
// 使用 .equals() 比较内容,并将常量放在前面防止空指针
if ( " booked " . equals ( stopReason ) ) {
dto . setStatus ( " 已预约 " ) ;
// --- 新增:获取患者信息 ---
List < Order > Order = orderMapper . selectOrderBySlotId ( Long . valueOf ( schedule . getId ( ) ) ) ;
Order latestOrder = Order . get ( 0 ) ;
if ( latestOrder ! = null ) {
dto . setPatientName ( latestOrder . getPatientName ( ) ) ;
dto . setPatientId ( String . valueOf ( latestOrder . getPatientId ( ) ) ) ;
dto . setPhone ( latestOrder . getPhone ( ) ) ;
}
// -----------------------
} else if ( " checked " . equals ( stopReason ) ) {
dto . setStatus ( " 已取号 " ) ;
} else {
// 兜底逻辑:如果 is_stopped 为 true 但没有匹配到原因
dto . setStatus ( " 不可预约 " ) ;
}
} else {
// is_stopped 为 false 或 null 时
dto . setStatus ( " 未预约 " ) ;
}
// 费用处理 (挂号费 + 诊疗费)
int totalFee = schedule . getRegisterFee ( ) + schedule . getDiagnosisFee ( ) ;
dto . setFee ( String . valueOf ( totalFee ) ) ;
// 日期处理: LocalDateTime 转 Date
if ( schedule . getCreateTime ( ) ! = null ) {
ZonedDateTime zdt = schedule . getCreateTime ( ) . atZone ( ZoneId . systemDefault ( ) ) ;
dto . setAppointmentDate ( Date . from ( zdt . toInstant ( ) ) ) ;
}
tickets . add ( dto ) ;
}
}
// 构建响应数据
// 3. 封装分页响应结 构
Map < String , Object > result = new HashMap < > ( ) ;
result . put ( " list " , testT ickets ) ;
result . put ( " total " , testT ickets . size ( ) ) ;
result . put ( " list " , tickets ) ;
result . put ( " total " , tickets . size ( ) ) ;
result . put ( " page " , 1 ) ;
result . put ( " limit " , 20 ) ;
return R . ok ( result ) ;
}
@@ -322,9 +293,6 @@ public class TicketAppServiceImpl implements ITicketAppService {
case " cancelled " :
dto . setStatus ( " 已取消 " ) ;
break ;
case " locked " :
dto . setStatus ( " 已锁定 " ) ;
break ;
default :
dto . setStatus ( status ) ;
}