【预约挂号】(内附源码)

页面预览

预约挂号

  • 根据预约周期,展示可预约日期,根据有号、无号、约满等状态展示不同颜色,以示区分
  • 可预约最后一个日期为即将放号日期
  • 选择一个日期展示当天可预约列表

image-20230227202834422

预约确认

image-20230227203321417

image-20230227203620732

image-20230226175848111

第01章-预约挂号

接口分析

(1)根据预约周期,展示可预约日期数据

(2)选择日期展示当天可预约列表

1、获取可预约日期接口

1.1、Controller

service-hosp微服务创建FrontScheduleController

package com.atguigu.syt.hosp.controller.front;

@Api(tags = "排班")
@RestController
@RequestMapping("/front/hosp/schedule")
public class FrontScheduleController {

    @Resource
    private ScheduleService scheduleService;

    @ApiOperation(value = "获取可预约排班日期数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "hoscode",value = "医院编码", required = true),
            @ApiImplicitParam(name = "depcode",value = "科室编码", required = true)})
    @GetMapping("getBookingScheduleRule/{hoscode}/{depcode}")
    public Result<Map<String, Object>> getBookingSchedule(
            @PathVariable String hoscode,
            @PathVariable String depcode) {

        Map<String, Object> result = scheduleService.getBookingScheduleRule(hoscode, depcode);
        return Result.ok(result);
    }

}

1.2、辅助方法

在ScheduleServiceImpl中添加两个辅助方法

/**
     * 根据日期对象和时间字符串获取一个日期时间对象
     * @param dateTime
     * @param timeString
     * @return
     */
private DateTime getDateTime(DateTime dateTime, String timeString) {
    String dateTimeString = dateTime.toString("yyyy-MM-dd") + " " + timeString;
    return DateTimeFormat.forPattern("yyyy-MM-dd HH:mm").parseDateTime(dateTimeString);
}
/**
     * 根据预约规则获取可预约日期列表
     */
private List<Date> getDateList(BookingRule bookingRule) {
    //预约周期
    int cycle = bookingRule.getCycle();
    //当天放号时间
    DateTime releaseTime = this.getDateTime(new DateTime(), bookingRule.getReleaseTime());
    //如果当天放号时间已过,则预约周期后一天显示即将放号,周期加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());
    }
    return dateList;
}

1.3、Service

接口:ScheduleService

/**
     * 根据医院编码和科室编码查询医院排班日期列表
     * @param hoscode
     * @param depcode
     * @return
     */
Map<String, Object> getBookingScheduleRule(String hoscode, String depcode);

实现:ScheduleServiceImpl

@Resource
private HospitalRepository hospitalRepository;

@Resource
private DepartmentRepository departmentRepository;
@Override
public Map<String, Object> getBookingScheduleRule(String hoscode, String depcode) {
    //获取医院
    Hospital hospital = hospitalRepository.findByHoscode(hoscode);
    //获取预约规则
    BookingRule bookingRule = hospital.getBookingRule();
    //根据预约规则获取可预约日期列表
    List<Date> dateList = this.getDateList(bookingRule);
    //查询条件:根据医院编号、科室编号以及预约日期查询
    Criteria criteria = Criteria.where("hoscode").is(hoscode).and("depcode").is(depcode).and("workDate").in(dateList);
    //根据工作日workDate期进行分组
    Aggregation agg = Aggregation.newAggregation(
        //查询条件
        Aggregation.match(criteria),
        Aggregation
        //按照日期分组 select workDate as workDate from schedule group by workDate
        .group("workDate").first("workDate").as("workDate")
        //剩余预约数
        .sum("availableNumber").as("availableNumber")
    );
    //执行查询
    AggregationResults<BookingScheduleRuleVo> aggResults = mongoTemplate.aggregate(agg, Schedule.class, BookingScheduleRuleVo.class);
    //获取查询结果
    List<BookingScheduleRuleVo> list = aggResults.getMappedResults();
    //将list转换成Map,日期为key,BookingScheduleRuleVo对象为value
    Map<Date, BookingScheduleRuleVo> scheduleVoMap = new HashMap<>();
    if (!CollectionUtils.isEmpty(list)) {
        scheduleVoMap = list.stream().collect(
            Collectors.toMap(bookingScheduleRuleVo -> bookingScheduleRuleVo.getWorkDate(), bookingScheduleRuleVo -> bookingScheduleRuleVo)
        );
    }
    //获取可预约排班规则
    List<BookingScheduleRuleVo> bookingScheduleRuleVoList = new ArrayList<>();
    int size = dateList.size();
    for (int i = 0; i < size; i++) {
        Date date = dateList.get(i);
        BookingScheduleRuleVo bookingScheduleRuleVo = scheduleVoMap.get(date);
        if (bookingScheduleRuleVo == null) { // 说明当天没有排班数据
            bookingScheduleRuleVo = new BookingScheduleRuleVo();
            bookingScheduleRuleVo.setWorkDate(date);
            //科室剩余预约数  -1表示无号
            bookingScheduleRuleVo.setAvailableNumber(-1);
        }
        bookingScheduleRuleVo.setWorkDateMd(date);
        //计算当前预约日期为周几
        String dayOfWeek = DateUtil.getDayOfWeek(new DateTime(date));
        bookingScheduleRuleVo.setDayOfWeek(dayOfWeek);
        if (i == size - 1) { //最后一条记录为即将放号
            bookingScheduleRuleVo.setStatus(1);
        } else {
            bookingScheduleRuleVo.setStatus(0);
        }

        //设置预约状态: 0正常; 1即将放号; -1当天已停止挂号
        if (i == 0) { //当天如果过了停挂时间, 则不能挂号
            DateTime stopTime = this.getDateTime(new DateTime(), bookingRule.getStopTime());
            if (stopTime.isBeforeNow()) {
                bookingScheduleRuleVo.setStatus(-1);//停止挂号
            }
        }
        bookingScheduleRuleVoList.add(bookingScheduleRuleVo);
    }
    //医院基本信息
    Map<String, String> info = new HashMap<>();
    //医院名称
    info.put("hosname", hospitalRepository.findByHoscode(hoscode).getHosname());
    //科室
    Department department = departmentRepository.findByHoscodeAndDepcode(hoscode, depcode);
    //大科室名称
    info.put("bigname", department.getBigname());
    //科室名称
    info.put("depname", department.getDepname());
    //当前月份
    info.put("workDateString", new DateTime().toString("yyyy年MM月"));
    //放号时间
    info.put("releaseTime", bookingRule.getReleaseTime());
    Map<String, Object> result = new HashMap<>();
    //可预约日期数据
    result.put("bookingScheduleList", bookingScheduleRuleVoList);//排班日期列表
    result.put("info", info);//医院基本信息
    return result;
}

2、获取排班数据接口

2.1、Controller

在FrontScheduleController添加方法

@ApiOperation("获取排班数据")
@ApiImplicitParams({
            @ApiImplicitParam(name = "hoscode",value = "医院编码", required = true),
            @ApiImplicitParam(name = "depcode",value = "科室编码", required = true),
            @ApiImplicitParam(name = "workDate",value = "排班日期", required = true)})
@GetMapping("getScheduleList/{hoscode}/{depcode}/{workDate}")
public Result<List<Schedule>> getScheduleList(
    @PathVariable String hoscode,
    @PathVariable String depcode,
    @PathVariable String workDate) {
    List<Schedule> scheduleList = scheduleService.getScheduleList(hoscode, depcode, workDate);
    return Result.ok(scheduleList);
}

2.2、Service

之前已经实现的业务

注意:如果我们在MongoDB集合的实体中使用了ObjectId作为唯一标识,那么需要对数据进行如下转换,以便将字符串形式的id传到前端

@Override
public List<Schedule> getScheduleList(String hoscode, String depcode, String workDate) {

    //注意:最后一个参数需要进行数据类型的转换
    List<Schedule> scheduleList = scheduleRepository.findByHoscodeAndDepcodeAndWorkDate(
            hoscode,
            depcode,
            new DateTime(workDate).toDate());//数据类型的转换

    //id为ObjectId类型时需要进行转换
    scheduleList.forEach(schedule -> {
        schedule.getParam().put("id", schedule.getId().toString());
    });

    return scheduleList;
}

3、前端整合

3.1、预约挂号页面跳转

修改/pages/hospital/_hoscode.vue组件的schedule方法

添加模块引用:

import cookie from 'js-cookie'
import userInfoApi from '~/api/userInfo'

methods中添加如下方法:

schedule(depcode) {
  //window.location.href = '/hospital/schedule?hoscode=' + this.$route.params.hoscode + "&depcode="+ depcode
  // 登录判断
  let token = cookie.get('refreshToken')
  if (!token) {
    this.$alert('请先进行用户登录', { type: 'warning' })
    return
  }
  //判断认证
  userInfoApi.getUserInfo().then((response) => {
    let authStatus = response.data.authStatus
    // 状态为2认证通过
    if (authStatus != 2) {
      this.$alert('请先进行用户认证', {
        type: 'warning',
        callback: () => {
          window.location.href = '/user'
        },
      })
      return
    }
    window.location.href =
      '/hospital/schedule?hoscode=' +
      this.$route.params.hoscode +
      '&depcode=' +
      depcode
  })
}

3.2、api

在api/hosp.js添加方法

//获取可预约排班日期列表
getBookingScheduleRule(hoscode, depcode) {
  return request({
    url: `/front/hosp/schedule/getBookingScheduleRule/${hoscode}/${depcode}`,
    method: 'get'
  })
},

//获取排班数据
getScheduleList(hoscode, depcode, workDate) {
  return request({
    url: `/front/hosp/schedule/getScheduleList/${hoscode}/${depcode}/${workDate}`,
    method: 'get'
  })
},

3.3、页面渲染

/pages/hospital/schedule.vue

第02章-预约确认

1、后端接口

1.1、Controller

在FrontScheduleController中添加方法

@ApiOperation("获取预约详情")
@ApiImplicitParam(name = "id",value = "排班id", required = true)
@GetMapping("getScheduleDetail/{id}")
public Result<Schedule> getScheduleDetail(@PathVariable String id) {
    Schedule schedule = scheduleService.getDetailById(id);
    return Result.ok(schedule);
}

1.2、Service

接口:ScheduleService

/**
     * 排班记录详情
     * @param id
     * @return
     */
Schedule getDetailById(String id);

实现:ScheduleServiceImpl

@Override
public Schedule getDetailById(String id) {
    Schedule schedule = scheduleRepository.findById(new ObjectId(id)).get();
    return this.packSchedule(schedule);
}

辅助方法

/**
     * 封装医院名称,科室名称和周几
     * @param schedule
     * @return
     */
private Schedule packSchedule(Schedule schedule) {
    //医院名称
    String hosname = hospitalRepository.findByHoscode(schedule.getHoscode()).getHosname();
    //科室名称
    String depname = departmentRepository.findByHoscodeAndDepcode(schedule.getHoscode(),schedule.getDepcode()).getDepname();
    //周几
    String dayOfWeek = DateUtil.getDayOfWeek(new DateTime(schedule.getWorkDate()));
    
    Integer workTime = schedule.getWorkTime();
    String workTimeString = workTime.intValue() == 0 ? "上午" : "下午";
    
    schedule.getParam().put("hosname",hosname);
    schedule.getParam().put("depname",depname);
    schedule.getParam().put("dayOfWeek",dayOfWeek);
    schedule.getParam().put("workTimeString", workTimeString);
    
  	//id为ObjectId类型时需要进行转换
    schedule.getParam().put("id",schedule.getId().toString());
    return schedule;
}

2、前端整合

2.1、api

在api/hosp.js添加方法

//获取预约详情
getScheduleDetail(id) {
    return request({
        url: `/front/hosp/schedule/getScheduleDetail/${id}`,
        method: 'get'
    })
}

2.2、页面渲染

pages/hospital/booking.vue

源码:https://gitee.com/dengyaojava/guigu-syt-parent

posted @ 2023-06-18 13:19  自律即自由-  阅读(646)  评论(0编辑  收藏  举报