需求分析
- 科室信息(大科室与小科室树形展示),json数据,包含多层科室结构
- 排班日期,分页显示,根据上传排班数据聚合统计产生
- 点击排班日期对应的就诊医生信息
科室列表
- 根据医院编号,查询医院所有科室列表,在departmentController中添加方法
//根据医院编号,查询医院所有科室列表
@ApiOperation(value = "查询医院所有科室列表")
@GetMapping("getDeptList/{hoscode}")
public Result getDeptList(@PathVariable String hoscode) {
List<DepartmentVo> list = departmentService.findDeptTree(hoscode);
return Result.ok(list);
}
- serviceImpl中,为了实现树形结构:
- 查询所有科室的信息departmentList,其中包括大小科室。
- 根据大科室编号 bigcode 分组,获取每个大科室里面下级子科室,用map<Srting,List<department>>来存放子科室,String表示大科室编号。
- 遍历map集合,对大科室的信息进行封装,并且将对应的小科室封装到每个大科室的List<DepartmentVo> children中,DepartmentVo中包括3个属性depcode、depname、List<DepartmentVo> children
- 最终将大科室加到result中,返回一个List<DepartmentVo> result
//根据医院编号,查询医院所有科室列表
@Override
public List<DepartmentVo> findDeptTree(String hoscode) {
//创建list集合,用于最终数据封装
List<DepartmentVo> result = new ArrayList<>();
//根据医院编号,查询医院所有科室信息
Department departmentQuery = new Department();
departmentQuery.setHoscode(hoscode);
Example example = Example.of(departmentQuery);
//所有科室列表 departmentList 其中包括大科室和小科室
List<Department> departmentList = departmentRepository.findAll(example);
//根据大科室编号 bigcode 分组,获取每个大科室里面下级子科室
//departmentList先变成stream流,再用collect做分组 Collectors工具类的groupingBy方法·
Map<String, List<Department>> deparmentMap =
departmentList.stream().collect(Collectors.groupingBy(Department::getBigcode));
//遍历map集合 deparmentMap
for(Map.Entry<String,List<Department>> entry : deparmentMap.entrySet()) {
//大科室编号
String bigcode = entry.getKey();
//大科室编号对应的全局数据
List<Department> deparment1List = entry.getValue();
//封装大科室
DepartmentVo departmentVo1 = new DepartmentVo();
departmentVo1.setDepcode(bigcode);
departmentVo1.setDepname(deparment1List.get(0).getBigname());
//封装小科室
List<DepartmentVo> children = new ArrayList<>();
for(Department department: deparment1List) {
DepartmentVo departmentVo2 = new DepartmentVo();
departmentVo2.setDepcode(department.getDepcode());
departmentVo2.setDepname(department.getDepname());
//封装到list集合
children.add(departmentVo2);
}
//把小科室list集合放到大科室children里面
departmentVo1.setChildren(children);
//放到最终result里面
result.add(departmentVo1);
}
//返回
return result;
}
排班日期分页列表
- 新建ScheduleController,根据医院编号 和 科室编号 ,查询排班规则数据
//根据医院编号 和 科室编号 ,查询排班规则数据
@ApiOperation(value ="查询排班规则数据")
@GetMapping("getScheduleRule/{page}/{limit}/{hoscode}/{depcode}")
public Result getScheduleRule(@PathVariable long page,
@PathVariable long limit,
@PathVariable String hoscode,
@PathVariable String depcode) {
Map<String,Object> map
= scheduleService.getRuleSchedule(page,limit,hoscode,depcode);
return Result.ok(map);
}
- ScheduleServiceImpl 中使用mongodb对排版数据进行分组、聚合、分页查询,group,count,sort,skip,limit。
- 对workDate进行分组查询,目的是查到每一天的排班规则,在这个具体日期下,会统计该日剩余挂号数量和总挂号数量,以及所有workDate日期总的记录数。
- 将workDate转为对应的星期
//根据医院编号 和 科室编号 ,查询排班规则数据
@Override
public Map<String, Object> getRuleSchedule(long page, long limit, String hoscode, String depcode) {
//1 根据医院编号 和 科室编号 查询
Criteria criteria = Criteria.where("hoscode").is(hoscode).and("depcode").is(depcode);
//2 根据工作日workDate期进行分组
Aggregation agg = Aggregation.newAggregation(
Aggregation.match(criteria),//匹配条件
Aggregation.group("workDate")//分组字段
.first("workDate").as("workDate")//first是过滤显示的属性
//3 统计号源数量
.count().as("docCount")
.sum("reservedNumber").as("reservedNumber")
.sum("availableNumber").as("availableNumber"),
//排序
Aggregation.sort(Sort.Direction.DESC,"workDate"),
//4 实现分页
Aggregation.skip((page-1)*limit),
Aggregation.limit(limit)
);
//调用方法,最终执行
AggregationResults<BookingScheduleRuleVo> aggResults =
mongoTemplate.aggregate(agg, Schedule.class, BookingScheduleRuleVo.class);
List<BookingScheduleRuleVo> bookingScheduleRuleVoList = aggResults.getMappedResults();
//分组查询的总记录数
Aggregation totalAgg = Aggregation.newAggregation(
Aggregation.match(criteria),
Aggregation.group("workDate")
);
AggregationResults<BookingScheduleRuleVo> totalAggResults =
mongoTemplate.aggregate(totalAgg,
Schedule.class, BookingScheduleRuleVo.class);
int total = totalAggResults.getMappedResults().size();
//把日期对应星期获取
for(BookingScheduleRuleVo bookingScheduleRuleVo:bookingScheduleRuleVoList) {
Date workDate = bookingScheduleRuleVo.getWorkDate();
String dayOfWeek = this.getDayOfWeek(new DateTime(workDate));
bookingScheduleRuleVo.setDayOfWeek(dayOfWeek);
}
//设置最终数据,进行返回
Map<String, Object> result = new HashMap<>();
result.put("bookingScheduleRuleList",bookingScheduleRuleVoList);
result.put("total",total);
//获取医院名称
String hosName = hospitalService.getHospName(hoscode);
//其他基础数据
Map<String, String> baseMap = new HashMap<>();
baseMap.put("hosname",hosName);
result.put("baseMap",baseMap);
return result;
}
获取排班详情列表
根据医院编号 、科室编号和工作日期,查询排班详细信息
上一步是获得workDate的排版规则,现在要得到每个workDate对应的详细排班信息
- controller步骤略
- serviceImpl中通过对mongo对排班表的查询可以得到排班的相关信息,用一个scheduleList来封装排班信息,把 得到scheduleList集合遍历,向设置其他值:医院名称、科室名称、日期对应星期
- 为了进一步显示更丰富的信息,如排班表中没有的医院名称,科室名称,日期对应星期的信息,这是就要封装他们,因为schedule实体类继承于BaseMongoEntity,在BaseMongoEntity中有一个map,来表示其他参数
@ApiModelProperty(value = "其他参数")
@Transient //被该注解标注的,将不会被录入到数据库中。只作为普通的javaBean属性
private Map<String,Object> param = new HashMap<>();
我们可以利用这个param集合来封装这些想要的其他信息。
//根据医院编号 、科室编号和工作日期,查询排班详细信息
@Override
public List<Schedule> getDetailSchedule(String hoscode, String depcode, String workDate) {
//根据参数查询mongodb
List<Schedule> scheduleList =
scheduleRepository.findScheduleByHoscodeAndDepcodeAndWorkDate(hoscode,depcode,new DateTime(workDate).toDate());
//把得到list集合遍历,向设置其他值:医院名称、科室名称、日期对应星期
scheduleList.stream().forEach(item->{
this.packageSchedule(item);
});
return scheduleList;
}
//封装排班详情其他值 医院名称、科室名称、日期对应星期
private void packageSchedule(Schedule schedule) {
//设置医院名称
schedule.getParam().put("hosname",hospitalService.getHospName(schedule.getHoscode()));
//设置科室名称
schedule.getParam().put("depname",departmentService.getDepName(schedule.getHoscode(),schedule.getDepcode()));
//设置日期对应星期
schedule.getParam().put("dayOfWeek",this.getDayOfWeek(new DateTime(schedule.getWorkDate())));
}