如何更好的设计会议室预定系统

会议室预定系统的问题

初步想到的做法是

存储记录1
日期:2023-03-26 
时段开始:14:30
时段结束:15:30

存储记录2
日期:2023-03-26 
时段开始:16:20
时段结束:17:00

然后查找匹配

会议室编号 = 会议室编号
and 
预定日期 = 已存储的预约日期
and 
用预定开始时间去查找匹配已存储的预定时段结束时间(当前预订开始时间 > 已存储预约的结束时间)
and 
同时再用预定的结束时间去对比已存储的时段开始时间(当前预订结束时间 < 已存储预约的开始时间)

意识到上面有BUG

解决办法,存储时多增加开始和结束小时的字段,如下

存储记录1
日期:2023-03-26 
时段开始:14:30
时段开始小时:14
时段结束:15:30
时段结束小时:15

存储记录2
日期:2023-03-26 
时段开始:16:20
时段开始小时:16
时段结束:17:00
时段结束小时:17

然后搜索逻辑

会议室编号 = 会议室编号
and
预定日期 = 已存储的预约日期
and 
当前预约开始小时 = 已存储预约结束小时 and 用预定开始时间去查找匹配已存储的预定时段结束时间(当前预订开始时间 > 已存储预约的结束时间)
and 
当前预约结束小时 = 已存储预约开始小时 and  同时再用预定的结束时间去对比已存储的时段开始时间(当前预订结束时间 < 已存储预约的开始时间)

第三次修改,考虑到跨天的问题

如遇特殊情况,例如双11那晚,预约会存在跨天的可能,上面的搜索逻辑进行调整

会议室编号 = 会议室编号
and
(
    预定开始日期 = 已存储的预约开始日期
    and 
    当前预约开始小时 = 已存储预约结束小时 and 用预定开始时间去查找匹配已存储的预定时段结束时间(当前预订开始时间 > 已存储预约的结束时间)
)
and 
(
    预定结束日期 = 已存储的预约结束日期
    and
    当前预约结束小时 = 已存储预约开始小时 and  同时再用预定的结束时间去对比已存储的时段开始时间(当前预订结束时间 < 已存储预约的开始时间)
)

感觉上面设计有点繁琐,不知道有没有更简便更优雅的设计

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 5

只能给你提供一下sql的思路,再这基础上在查询一下会议室就可以了,其实当初写完发现条件还可以简化,但是测试测完了,也不想让测试重新测一遍。

WHERE
    (
        (
            `started_at` >= 'start'
            AND `ended_at` <= 'end'
        )
        OR (
            `started_at` <= 'start'
            AND `ended_at` >= 'end'
        )
        OR (
            `started_at` <= 'start'
            AND `ended_at` > 'start'
        )
        OR (
            `started_at` < 'end'
            AND `ended_at` >= 'end'
        )
    )
where(function ($query){
    $query->orWhere(function ($query){
        $query->where('started_at', '>=', 'start')->where('ended_at', '<=', 'end');
    })->orWhere(function ($query){
        $query->where('started_at', '<=', 'start')->where('ended_at', '>=', 'end');
    })->orWhere(function ($query){
        $query->where('started_at', '<=', 'start')->where('ended_at', '>', 'start');
    })->orWhere(function ($query){
        $query->where('started_at', '<', 'end')->where('ended_at', '>=', 'end');
    });
})
1年前 评论

可以把一个会议室的整天时间按最小单位分成块儿 然后每一块儿 hasone 一个预约信息? 这样设计如何

1年前 评论

只要在预定时间内(时间戳范围内),其他人无法预定不就行了,很复杂吗.还是我考虑少了,关键是实际需求上的,是否要求必须在预定时间内结束然后排给下一波人

1年前 评论

为什么不把年月日时分用 DateTime 存储,Carbon 封装支持更丰富的操作,每次有人申请会议室的时候,把会议室当天的所有记录查出来,然后再 PHP 层通过:

if (!Carbon::parse($newStart)->between($oldStart, $oldEnd) && !Carbon::parse($newEnd)->between($oldStart, $oldEnd)) {
    // Create record.
}

挨个判断一下是否冲突就行了!

1年前 评论

都行,我的想法就是页面上展示会议室列表及其状态.然后自己选择房间号和时间段,然后查表不冲突就行

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!