一、预约挂号详情
1、需求分析
1、接口分析
(1)根据预约周期,展示可预约日期数据,按分页展示
(2)选择日期展示当天可预约列表(该接口后台已经实现过)
2、页面展示分析
(1)分页展示可预约日期,根据有号、无号、约满等状态展示不同颜色,以示区分
(2)可预约最后一个日期为即将放号日期,根据放号时间页面展示倒计时
2、后台api接口
2.3 添加controller方法
在HospitalApiController类添加方法
@Autowired
private ScheduleService scheduleService;
@ApiOperation(value = "获取可预约排班数据")
@GetMapping("auth/getBookingScheduleRule/{page}/{limit}/{hoscode}/{depcode}")
public Result getBookingSchedule(
@ApiParam(name = "page", value = "当前页码", required = true)
@PathVariable Integer page,
@ApiParam(name = "limit", value = "每页记录数", required = true)
@PathVariable Integer limit,
@ApiParam(name = "hoscode", value = "医院code", required = true)
@PathVariable String hoscode,
@ApiParam(name = "depcode", value = "科室code", required = true)
@PathVariable String depcode) {
return Result.ok(scheduleService.getBookingScheduleRule(page, limit, hoscode, depcode));
}
@ApiOperation(value = "获取排班数据")
@GetMapping("auth/findScheduleList/{hoscode}/{depcode}/{workDate}")
public Result findScheduleList(
@ApiParam(name = "hoscode", value = "医院code", required = true)
@PathVariable String hoscode,
@ApiParam(name = "depcode", value = "科室code", required = true)
@PathVariable String depcode,
@ApiParam(name = "workDate", value = "排班日期", required = true)
@PathVariable String workDate) {
return Result.ok(scheduleService.getDetailSchedule(hoscode, depcode, workDate));
}
当天放号时间一到,则预约周期加一(预约时间要始终保持10天,所以需要加一);
假设预约周期是1天,若医院12点放号,那么在12点前进行预约,可以预约今天的号;在12点之后进行预约,预约周期就要+1,只能预约明天的号
dateList->总的可预约日期的集合,pageDateList->当前页可预约天数的集合,start->当前页的首个天数的索引,end-1->当前页最后一个天数的索引
当前页iPage对象若要包含位置正确的各个天数对象(比如:属于第二页第二个位置的应该是哪个Date对象),需要借助start与end来从dataList中复制对应位置的Date对象到自己的集合中
//封装的是 获取可预约日期的分页信息
private IPage<Date> getListDate(Integer page, Integer limit, BookingRule bookingRule) {
//1. 获取当天new Date()放号时间 :时间戳形式,
DateTime releaseTime = this.getDateTime(new Date(), bookingRule.getReleaseTime());//每天放号时间,如早上八点30分
//2. 获取预约周期
Integer cycle = bookingRule.getCycle();
//如果当天放号时间已经过去,预约周期从后一天开始计算,周期+1
if(releaseTime.isBeforeNow()){//超过当前时间点
cycle += 1;
}
//dateList->总的可预约日期的集合,注意这里根据业务需要只显示日期的,如09-09
//所以我们需要截取DateTime的日期部分
//3. 获取可预约的所有日期,如10天,最后一天显示即将放号倒计时
List<Date> dateList = new ArrayList<>();//需要按照时间顺序显示的
for(int i =0;i < cycle; i++){//遍历预约周期次
//每 循环一次,增加一天
DateTime curDateTime = new DateTime().plusDays(i);//DateTime增加一天的方法
System.out.println("curDateTime:"+curDateTime);
//将DateTime转成string,并截取日期
String dateString = curDateTime.toString("yyyy-MM-dd");
//将DateTime(string 形式的date) 转成 Date 并添加到dateList
dateList.add(new DateTime(dateString).toDate() );
}
//4. 因为预约周期不同,每页显示日期最多7天数据,超过7天进行分页
List<Date> pageDateList = new ArrayList<>();
//每页开始位置
int start = (page - 1) * limit;
//每页结束的位置
int end = (page - 1) * limit + limit;//增加一个limit的容量周期
//如果可以显示数据小于7,直接显示
if(end > dateList.size()){//直接显示
end = dateList.size();
}
//5. 将dateList数据放到pageDateList
for (int i = start; i < end; i++) {
//将dateList数据放到pageDateList
pageDateList.add(dateList.get(i));
}
// 6. 如果可以显示的数据大于7,进行分页
//Page(long current, long size, long total)
IPage<Date> iPage
= new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(
page, 7, dateList.size()
);
//7. IPage<T> setRecords(List<T> records)
iPage.setRecords(pageDateList);
return iPage;
}
@Override
public Map<String, Object> getBookingScheduleRule(int page, int limit, String hoscode, String depcode) {
Map<String, Object> result = new HashMap<>();
//获取预约规则
Hospital hospital = hospitalService.getByHoscode(hoscode);
if(null == hospital) {
throw new YyghException(ResultCodeEnum.DATA_ERROR);
}
BookingRule bookingRule = hospital.getBookingRule();
//获取可预约日期分页数据
IPage iPage = this.getListDate(page, limit, bookingRule);
//当前页可预约日期
List<Date> dateList = iPage.getRecords();
//获取可预约日期科室剩余预约数
Criteria criteria = Criteria.where("hoscode").is(hoscode).and("depcode").is(depcode).and("workDate").in(dateList);
//Java中用Aggregation对Mongo聚合查询
Aggregation agg = Aggregation.newAggregation(
Aggregation.match(criteria),
Aggregation.group("workDate")//分组字段
.first("workDate").as("workDate")//first () : 获取group by 后的某个字段的首个值
.count().as("docCount")
.sum("availableNumber").as("availableNumber")
.sum("reservedNumber").as("reservedNumber")
);
AggregationResults<BookingScheduleRuleVo> aggregationResults = mongoTemplate.aggregate(agg, Schedule.class, BookingScheduleRuleVo.class);
List<BookingScheduleRuleVo> scheduleVoList = aggregationResults.getMappedResults();
//获取科室剩余预约数
//合并数据 将统计数据ScheduleVo根据“安排日期”合并到BookingRuleVo
Map<Date, BookingScheduleRuleVo> scheduleVoMap = new HashMap<>();
if(!CollectionUtils.isEmpty(scheduleVoList)) {
scheduleVoMap = scheduleVoList.stream().collect(Collectors.toMap(BookingScheduleRuleVo::getWorkDate, BookingScheduleRuleVo -> BookingScheduleRuleVo));
}
//获取可预约排班规则
List<BookingScheduleRuleVo> bookingScheduleRuleVoList = new ArrayList<>();
for(int i=0, len=dateList.size(); i<len; i++) {
Date date = dateList.get(i);
BookingScheduleRuleVo bookingScheduleRuleVo = scheduleVoMap.get(date);
if(null == bookingScheduleRuleVo) { // 说明当天没有排班医生
bookingScheduleRuleVo = new BookingScheduleRuleVo();
//就诊医生人数
bookingScheduleRuleVo.setDocCount(0);
//科室剩余预约数 -1表示无号
bookingScheduleRuleVo.setAvailableNumber(-1);
}
bookingScheduleRuleVo.setWorkDate(date);
bookingScheduleRuleVo.setWorkDateMd(date);
//计算当前预约日期为周几
String dayOfWeek = this.getDayOfWeek(new DateTime(date));
bookingScheduleRuleVo.setDayOfWeek(dayOfWeek);
//最后一页最后一条记录为即将预约 状态 0:正常 1:即将放号 -1:当天已停止挂号
if(i == len-1 && page == iPage.getPages()) {
bookingScheduleRuleVo.setStatus(1);
} else {
bookingScheduleRuleVo.setStatus(0);
}
//当天预约如果过了停号时间, 不能预约
if(i == 0 && page == 1) {
DateTime stopTime = this.getDateTime(new Date(), bookingRule.getStopTime());
if(stopTime.isBeforeNow()) {
//停止预约
bookingScheduleRuleVo.setStatus(-1);
}
}
bookingScheduleRuleVoList.add(bookingScheduleRuleVo);
}
//可预约日期规则数据
result.put("bookingScheduleList", bookingScheduleRuleVoList);
result.put("total", iPage.getTotal());
//其他基础数据
Map<String, String> baseMap = new HashMap<>();
//医院名称
baseMap.put("hosname", hospitalService.getHospName(hoscode));
//科室
Department department =departmentService.getDepartment(hoscode, depcode);
//大科室名称
baseMap.put("bigname", department.getBigname());
//科室名称
baseMap.put("depname", department.getDepname());
//月
baseMap.put("workDateString", new DateTime().toString("yyyy年MM月"));
//放号时间
baseMap.put("releaseTime", bookingRule.getReleaseTime());
//停号时间
baseMap.put("stopTime", bookingRule.getStopTime());
result.put("baseMap", baseMap);
return result;
}
/**
* 获取可预约日期分页数据
*/
private IPage<Date> getListDate(int page, int limit, BookingRule bookingRule) {
//当天放号时间
DateTime releaseTime = this.getDateTime(new Date(), bookingRule.getReleaseTime());
//预约周期
int cycle = bookingRule.getCycle();
//如果当天放号时间已过,则预约周期后一天为即将放号时间,周期加1
if(releaseTime.isBeforeNow()) cycle += 1;
//可预约所有日期,最后一天显示即将放号倒计时
List<Date> dateList = new ArrayList<>();
for (int i = 0; i < cycle; i++) {
//计算当前预约日期
DateTime curDateTime = new DateTime().plusDays(i);
String dateString = curDateTime.toString("yyyy-MM-dd");
dateList.add(new DateTime(dateString).toDate());
}
//日期分页,由于预约周期不一样,页面一排最多显示7天数据,多了就要分页显示
List<Date> pageDateList = new ArrayList<>();
int start = (page-1)*limit;
int end = (page-1)*limit+limit;
if(end >dateList.size()) end = dateList.size();
for (int i = start; i < end; i++) {
pageDateList.add(dateList.get(i));
}
IPage<Date> iPage = new com.baomidou.mybatisplus.extension.plugins.pagination.Page(page, 7, dateList.size());
iPage.setRecords(pageDateList);
return iPage;
}
/**
* 将Date日期(yyyy-MM-dd HH:mm)转换为DateTime
*/
private DateTime getDateTime(Date date, String timeString) {
String dateTimeString = new DateTime(date).toString("yyyy-MM-dd") + " "+ timeString;
DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm").parseDateTime(dateTimeString);
return dateTime;
}