Как создать схему для системы бронирования с наличием / временными интервалами - PullRequest
0 голосов
/ 27 апреля 2020

Я работаю над личным проектом, и я застрял в том, как начать реализацию календаря для владельца магазина, где он может перечислить услуги и время доступности. То есть, скажем, я владелец магазина / парикмахер, и я предлагаю много услуг, и я работаю с 9 утра до 5 вечера с часовым перерывом и временными интервалами. скажем, стрижка займет 15 минут (продолжительность).

Как мне go реализовать это? Хорошо ли предварительно заполнять базу данных событиями? это означает, что владелец магазина может создать свой календарь и временные интервалы и вставить его в базу данных, и всякий раз, когда пользователь хочет забронировать, система проверяет доступность в соответствии с выбранной датой. если в этот конкретный месяц имеется свободный день в этот конкретный час, мы можем позволить ему забронировать, в противном случае мы показываем ему, что эта дата / день заполнена или забронирована, или что-то в этом роде. В качестве аргумента, скажем, я разрешаю пользователю предварительно заполнить базу данных списком дат, это хорошая практика, потому что если у вас есть 11 слотов в день на 7 дней * 4 недели, это было бы много, верно?

если это так, я могу позволить ему предварительно заселить его только на 2 месяца или около того.

Если кто-то может дать мне совет, с чего начать, было бы здорово.

Заранее спасибо

1 Ответ

0 голосов
/ 27 апреля 2020

Ваш вопрос открытый (людям здесь не нравится! XD). Нет идеального ответа, и это зависит от потребностей вашего "парикмахера". Я вижу два совершенно разных способа его реализации (но я тоже начинающий):

  1. Ваше предложение = фиксированные временные интервалы. Не беспокойтесь о предварительном заполнении этих временных интервалов "booked: false", так как даже год, полный из них 24/7, на самом деле является крошечной БД. Например, я работаю над временными интервалами в 1 минуту с загрузкой данных каждую минуту (торговый бот), и это все еще ~ 100 МБ БД на целый год!
  2. Мое предложение = создать новый документ БД только когда парикмахер на самом деле что-то заказывает. Большое преимущество: он может выбирать как начальный, так и конечный час за минуту. Теперь вопрос в том, как предотвратить перебронирование (хотя это работает на самолетах, так почему бы и нет!).

Я могу показать вам, как бы я начал это:

const bookingSchema = mongoose.Schema({
    _id: mongoose.Schema.Types.ObjectId,
    startTime: {type:Number, required:true},
    endTime: {type:Number, required:true},
    clientName: {type:String, required:true}
});

const Booking = mongoose.model('Booking', bookingSchema);

Я бы сохранил startTime и endTime как метки времени в миллисекундах, но это вопрос выбора. Вы можете go полностью сохранить Y / M / D / H / m в отдельных полях. Я предпочитаю логи c в моем коде, а не в моей БД.

Теперь, когда мы добавляем новое бронирование, мы можем использовать некоторые логи даты c (проще с временными метками), чтобы проверить, есть ли конфликт с ранее существовавшим бронированием:

var newStartTime = someTimestamp;
var newEndTime = someOtherTimestamp;
var newClientName = 'John Doe';

var conflictingBookings = await Booking.find()
    .where('startTime').lt(newEndTime)
    .where('endTime').gt(newStartTime)
    .exec();

// This selects all preexisting bookings which have both :
// ---> startTime < newEndTime
// ---> endTime > newStartTime
// You can check yourself : I think it handles all possible overlaps !

// Now, conflictingBookings is an array containing all documents in conflict.
// You can tell your barber the problems :

if (conflictingBookings.length === 0) {
    // everything ok, you can book it
    // here you add the new booking to your DB...
} else {

    conflictingBookings.forEach( booking => {
        console.log(`There is already a booking from ${convertToString(booking.startTime)} to ${convertToString(booking.endTime)} with ${booking.clientName} !`);
    });

    // convertToString() being your custom function to convert timestamps to readable dates (not discussed here).
    // we log all conflicting preexisting bookings to the console

}

И это хорошее начало. Я на самом деле благодарю вас, потому что скоро я буду кодировать такое мини-приложение для бронирования для своего бизнеса, и мне понадобится этот логин c!

Тем не менее, я должен посоветовать вам проверить, если какой-то более простой визуальный приложения, удовлетворяющие вашим потребностям, уже существуют, потому что сложная часть вашего проекта - это визуальный интерфейс пользователя, и я не знаю, как это сделать. Может быть, интегрировать ваш код / ​​базу данных с каким-либо Calendar API (Google Calendar или любым другим).

Удачи вам в этом, продолжайте попытки и расскажите нам, для чего вы решили go!


[РЕДАКТИРОВАТЬ: Реализация "временных интервалов", если вы действительно хотите их]

Идея "временных интервалов" не является реальностью для любой работы, которая работает по заказам / назначениям человеческое время (не говоря о бронировании мест / номеров здесь). Поскольку встречи никогда не занимают время, которое они должны, и потому, что работник знает лучше, чем кто-либо другой, может ли он добавить эту новую встречу между двумя другими встречами ...

Но если вы действительно хотите временные интервалы, я бы построил два отдельных коллекции / базы данных.

Первая БД содержит бронирования, как указано выше.

Вторая БД содержит временные интервалы, причем каждый временной интервал представляет собой наименьшее количество времени, которое потребуется работнику для точность его графика (может быть, 5, 10 и 15 млн ...). Это временные интервалы "atomi c". Давайте скажем 10 млн. Для этого примера. Вот схема БД:

const slotSchema = mongoose.Schema({
    _id: mongoose.Schema.Types.ObjectId,
    time: {type:Number, required:true, unique:true}, // starting timestamp of the slot
    booked: {type:Boolean, required:true}, // obvious !
    bookingId: {type:String} // if booked, the _id of the booking in the other DB
});

const Slot = mongoose.model('Slot', slotSchema);

Теперь вы можете предварительно заполнить эту БД с помощью циклов for (здесь не обсуждается).

Когда работник хочет добавить новое бронирование, он дает время начала и окончания, которое вы можете преобразовать в метки времени: startTime и endTime. Теперь вы можете забронировать соответствующие временные интервалы:

// superBarber wants to book from 10:30am to 11:10am
var startTime = /*the timestamp for 10:30am that day*/
var endTime = /*the timestamp for 11:10am that day*/

// You can check availability as I showed above...
// You insert a new booking in the Booking collection :
var yourNewBooking = await Booking./*do your update...*/;

// And now you can update your time slots :

var slotsToBook = await Slot.find()
    .where('time').gte(startTime).lt(endTime)
    .exec();

// slotsToBook = [10:30slot, 10:40slot, 10:50slot, 11:00slot]

slotsToBook.forEach(async (slot) => {
    if (slot.booked) {
        console.log(`Damn, the slot at ${slot.time} is already booked`); 
    } else {
        await Slot.findByIdAndUpdate(
            slot._id,
            {$set: {
                booked: true, 
                bookingId: yourNewBooking._id
            }}
        );
        console.log(`Just booked the ${slot.time} slot !`);
    }
});

// Note : here I assume you're working inside async functions and you know how to handle callbacks / promises / await. Another thing entirely...

Надеюсь, это поможет ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...