1. 程式人生 > 資料庫 >解決高併發-springboot-redis-mysql醫院預約系統專案超詳細講解--半個小時教你如何使用springboot完成預約專案-----第四章:預約掛號

解決高併發-springboot-redis-mysql醫院預約系統專案超詳細講解--半個小時教你如何使用springboot完成預約專案-----第四章:預約掛號

dao層
redisDaoImpl
三個方法
預約
獲取醫生預約次數
去重

    @Autowired
    private StringRedisTemplate redisTemplate; //對redis操作的物件
    //尾部新增資料
    //預約往redis儲存一個list型別,鍵名為 doctor:1:20210109 ,doctor:id:日期,值為患者id
    @Override
    public Integer listRpush(String key, String value) {
        return redisTemplate.opsForList().rightPush(key,value).intValue();
    }
  
    //獲取list的長度,list長度證明,被預約過多少次,醫生每天看病總數-預約總數等於剩餘預約數
    @Override
    public Integer listLen(String key) {
        return redisTemplate.opsForList().size(key).intValue();
    }
  //預約,去重,往set加值,預約成功加值,加不進去證明加過值了=預約失敗
    @Override
    public Integer setAdd(String key, String value) {
        return redisTemplate.opsForSet().add(key, value).intValue();
    }

service層
BookingServiceImpl
兩個方法
預約
獲取list長度

   @Autowired
    private RedisDao redisDao;

    @Override
    public Integer addOneBooking(Booking booking) {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
        String date = fmt.format(booking.getBookingDate()); //格式化date

        Integer patientId = booking.getPatient().getPatientId();
        Integer doctorId = booking.getDoctor().getDoctorId();
        String key = String.format("patient-set:%s", date);
		//key=patient-set:yyyyMMdd
        //若已掛號
        if (redisDao.setAdd(key, patientId.toString()) == 0) {
            return 0; //set加入不進值,預約過了,結束方法
        }

         key = String.format("doctor:%d:%s", doctorId, date);
		//	list的key=doctor:醫生id:日期 

        return redisDao.listRpush(key, patientId.toString());//往list加入患者id

    }

    @Override
    public Integer getBookingCount(Integer doctorId, Date bookingDate) {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
        String date = fmt.format(bookingDate);

        String key = String.format("doctor:%d:%s", doctorId, date);
      	//拼接list的key名
		
        return redisDao.listLen(key);
    }

controller層
預約方法:
與頁面ajax繫結函式
假設醫生12:00-14:00為休息時間算出看病時間

    @Autowired
    private BookingService bookingService;
    @Autowired
    private DoctorService doctorService;
    @RequestMapping("add_booking")
    @ResponseBody
     public Map<String, Object> addOneBooking(Integer doctorId,
                                                    @DateTimeFormat(pattern = "yyyy-MM-dd") Date bookingDate,
                                                    HttpSession session) {
        HashMap<String, Object> result = new HashMap<>();
        Doctor doctor = doctorService.getDoctorById(doctorId);
        Patient user = (Patient)session.getAttribute("user");
        if (user==null){ //沒有登陸
            result.put("success", false);
            result.put("message", "請登入後再預約");
            return result;
        }
        //查詢醫生當天被預約多少次
        Integer bookingCount = bookingService.getBookingCount(doctorId, bookingDate);
        //醫生還剩餘number次
        Integer number = doctor.getTotal()-bookingCount;
        if (number<=0){ // 沒有剩餘預約次數了
            result.put("success", false);
            result.put("message", "當天預約已滿");
            return result;
        }

        //計算預約時間
        Integer length = (8 * 60) / doctor.getTotal();
        Integer waitTime = bookingCount * length; //需等待時間
        Integer hour = 0, minute = 0;

        if (waitTime < 240) {
            hour = 8 + waitTime / 60;
            minute = waitTime % 60;
        }
        else {
            hour = 14 + (waitTime - 240) / 60;
            minute = (waitTime - 240) % 60;
        }
		//看病時間
        String visitTime = String.format("%02d:%02d:00", hour, minute);
        Booking booking = new Booking();
        booking.setDoctor(doctor);
        booking.setPatient(user);
        booking.setBookingDate(bookingDate);
        booking.setVisitTime(visitTime);
        if (bookingService.addOneBooking(booking) > 0) {
        bookingService.addOneBooking(booking);
         result.put("success", true);
            result.put("message", number - 1); //預約數-1
            result.put("time", visitTime);
        }
        else {
            result.put("success", false);
            result.put("message", "不能重複預約。"); 
        }
        return result;
    }

頁面ajax

按鈕繫結onclick事件

	function addBooking(doctorId) {
				var bookingDate = $("#booking-date").val();	//id選擇器獲取val

				$.ajax({
					url: 'add_booking?doctorId='+doctorId+"&bookingDate="+bookingDate, 
					type: 'post',
					dataType: "json",
					success: function (data) {
						if (data.success) {
							$("#total-"+doctorId).text(data.message);
							if (data.message <= 0) {
								$("#btn-booking").attr("disabled", "disabled");
							}
							alert("預約成功,請於"+data.time+"前來就診");
						}
						else {
							alert(data.message);
						}
					},
					error: function(error){    //失敗後回撥
						alert("伺服器連線失敗");
					}
				});
			}

效果
點選前
在這裡插入圖片描述
點選後
在這裡插入圖片描述
在這裡插入圖片描述