Я разрабатываю весенний загрузочный MVC REST API для мобильного приложения. Система - это бронирование пациентов в клинике, я ищу лучшее решение проблемы отображения доступных времен врача.
определение проблемы: система должна позволять пользователю выбирать, клинику, врач и конкретную дату (год/месяц/день) из календаря, а система должна показывать доступные времена для выбора даты, продолжительность приема - 30 мин и от С 7:00 до 18:00.
более подробное разъяснение: система состоит из многих клиник и врачей, входящих в эти клиники. У каждого врача фиксированные часы, на которые пользователь может забронировать. Эти часы делятся на даты каждого получасового приема. Пользователи одновременно не могут забронировать у одного и того же врача.
Например: Пациент Джои забронировал встречу у Доктора Х, в 21 мая 2018 года 3:30, другой пациент-гнездо открыл заявку, чтобы записаться на прием, и он выбирает врача х, и он выбирает такую же дату, как и Джои (21 мая 2018 года) ) система должна показывать время, доступное с 7:00 до 18:00 (7: 00, 7:30, 8:00, 8:30......) исключает 3:30.
Решения попытались: 1) сделать работу в базе данных, которая заполняет доступные времена каждый год и отмечать время флагом. 2) когда клиент запрашивает доступные времена, система перебирает все назначения для врача и находит эти времена. 3) создайте статический список со временем и датами и когда пользователь запрашивает доступное время итерации по встречам и удаляет время из назначения из списка. 4) создать календарь базы данных. 5) пусть пользователь страницы администратора заполнит время вручную с страницы администратора. Я пробовал все эти возможные решения, но я не нашел их очень эффективными. Я ищу лучшее решение.
образец кода: раздел контроллера:
@RequestMapping(method = RequestMethod.GET , value = "/availabletimes")
public ResponseEntity<ResponseUtil> getAvailableTimes(@RequestParam String date){
try {
return new ResponseEntity<ResponseUtil> (new ResponseUtil(200, Constants.SUCCESS_STATUS, "Cancelled", service.getAvailableTimes(date)),HttpStatus.OK);
}catch (BackendException e) {
return new ResponseEntity<ResponseUtil> (new ResponseUtil(403, Constants.FAILED_STATUS, e.getMessage(), null),HttpStatus.FORBIDDEN);
}
}
Реализация услуг:
@Override
public List<String> getAvailableTimes(String date) {
List<String> availableTimes = findAvailableTimes(date);
if(availableTimes == null || availableTimes.isEmpty())
throw new BackendException("No times available for the given date");
return availableTimes;
}
private List<String> findAvailableTimes(String date){
//TODO write the logic for findding the available times
return null;
}
Репозиторий:
public interface AppointmentRepo extends IRepository<Appointment, Long> {
List<Appointment> findByCustomer(Customer customer);
}
юридическое лицо:
@Entity
public class Appointment extends BaseEntity {
/**
*
*/
private static final long serialVersionUID = 1L;
private Date appoitmentDate;
// Relations
@ManyToOne(fetch = FetchType.LAZY)
private Doctor doctor;
@ManyToOne(fetch = FetchType.LAZY)
private Clinic clinic;
@ManyToOne(fetch = FetchType.LAZY)
private Customer customer;
@ManyToOne(fetch = FetchType.LAZY)
private Follower follower;
@ManyToOne(fetch = FetchType.LAZY)
private AppointmentStatus appointmentStatus;
@OneToOne(fetch = FetchType.LAZY)
private Report report;
// Setters and Getters
public Doctor getDoctor() {
return doctor;
}
public void setDoctor(Doctor doctor) {
this.doctor = doctor;
}
public Clinic getClinic() {
return clinic;
}
public void setClinic(Clinic clinic) {
this.clinic = clinic;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public Follower getFollower() {
return follower;
}
public void setFollower(Follower follower) {
this.follower = follower;
}
public Date getAppoitmentDate() {
return appoitmentDate;
}
public void setAppoitmentDate(Date appoitmentDate) {
this.appoitmentDate = appoitmentDate;
}
public AppointmentStatus getAppointmentStatus() {
return appointmentStatus;
}
public void setAppointmentStatus(AppointmentStatus appointmentStatus) {
this.appointmentStatus = appointmentStatus;
}
public Report getReport() {
return report;
}
public void setReport(Report report) {
this.report = report;
}
}
У меня есть библиотека утилиты для рассылки с открытым исходным кодом (для Android), которая работает с часами работы и расписанием элементов. У этого есть возможность проверить двойные заказы, но пока у него нет прямого механизма для возвращения слотов назначения, но я буду добавлять это в качестве приоритета. Вы можете использовать массив этой библиотеки для разных клиник. Вы можете получить слоты опосредованно, используя механизм в библиотеке для получения следующего доступного слота в определенное время или после определенного времени и зацикливания каждой встречи. Целевая страница находится здесь: https://bitbucket.org/warwick/schedule_utils_demo/src/master/, а также демонстрационное приложение вместе с его исходным кодом. Вы также можете загрузить демонстрационное приложение из магазина Google Play: https://play.google.com/store/apps/details?id=com.WarwickWestonWright.ScheduleUtilsDemo. Хотя это и есть библиотека Android, очень легко превратить ее в стандартную библиотеку Java, как я ее построил с учетом этого. Я обновлю этот пост, когда добавлю механизм для получения списка доступных слотов.
Я думаю, что это не вопрос программирования, а вопрос о datadesign.
Сделайте таблицу (сущность) ClinicDoctorSchedule
с первичным ключом clinic_id, doctor_id
, timedate
и внешним ключом для patient_id
и поля state
. Поле состояния может иметь следующие значения: открыть, зарезервировать, использовать, не показывать. По умолчанию открыто
Заполните эту таблицу графиком (в Графике описано, в какой клинике, у кого есть время для врача) в течение следующих двух месяцев.
Это большая работа, но как только вы ее получите, вы можете обновлять таблицу еженедельно. (Сделайте шаг в неделю). Хотя это большая работа на начальном этапе, это также гибкое решение, поскольку изменение в расписании легко применять
Пациент выбирает weeknumber
и система возвращает форму ClinicDoctorSchedule
все timedates
где clinic_id
= выбранная клиника en doctor_id
= выбранный врач и время timedate
между firstweekdayhour
и lastweekdayhour
и state
= open.
Когда пациент выбирает datetime
две вещи:
patient_id
Надеюсь, это немного поможет.
(clinic, doctor, timedate)
и (clinic, doctor, timedate)
с patient
(или NULL, когда она еще доступна) вы получаете все необходимое с помощью одного SQL-запроса, так почему бы вам использовать два? Поскольку, вероятно, большинство слотов заполнено пациентом, вы не будете хранить бесполезные данные, поэтому для меня это звучит идеально. Просто добавьте индексы для обычных поисков. Все, что вам нужно, это работа по генерации новых слотов с течением времени на основе других таблиц (или файлов импорта), где администратор вводит планы врачей.