一、预约挂号详情
1、需求分析
1、接口分析
(1)根据预约周期,展示可预约日期数据,按分页展示
(2)选择日期展示当天可预约列表(该接口后台已经实现过)
2、页面展示分析
(1)分页展示可预约日期,根据有号、无号、约满等状态展示不同颜色,以示区分
(2)可预约最后一个日期为即将放号日期,根据放号时间页面展示倒计时
2、后台api接口
2.3 添加controller方法
在HospitalApiController类添加方法
@Autowiredprivate 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();//如果当天放号时间已经过去,预约周期从后一天开始计算,周期+1if(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 并添加到dateListdateList.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数据放到pageDateListfor (int i = start; i < end; i++) {//将dateList数据放到pageDateListpageDateList.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;}
@Overridepublic 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根据“安排日期”合并到BookingRuleVoMap<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();//如果当天放号时间已过,则预约周期后一天为即将放号时间,周期加1if(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;}