【问题标题】:V-Calendar component in Vuetify; setting up events to scale across monthsVuetify 中的 V-Calendar 组件;设置事件以跨月扩展
【发布时间】:2020-11-06 11:22:49
【问题描述】:

我正在寻找有关在 Postgres 中存储事件日期的最佳方式的建议,以获取它们并将它们显示在日历上。我正在使用带有 postgres 的 node/expressjs 后端作为数据存储。在前端,我将 vue 与 vuetify/nuxt 一起使用。 Vuetify 有很多方便的 UI 组件,但更具体地说是 v-calendar 组件:

V-Calendar

我遇到了一些边缘情况,我很难理解。

我希望能够从数据库中获取当月的事件以及从一个月到下一个月以及下一个月溢出的事件,等等。最好的方法是什么?我应该如何为我的数据库表建模并获取记录(我正在使用 Postgres)?一个事件需要一个名称、开始和结束。我是否应该将事件的总持续时间存储在 unix 时间戳 中,并按给定月份持续时间(以秒为单位)之间的范围查询事件?

欢迎任何建议。

【问题讨论】:

    标签: javascript postgresql calendar vuetify.js


    【解决方案1】:

    将您的事件及其开始和结束日期存储在range type

    然后您可以使用重叠 && range operator 来确定哪些事件属于某个月份的日历。

    例如,如果您有一个事件,其中duration 类型为daterange 的列定义为'[2020-01-01, 2020-03-31]'::daterange,它将符合以下条件:

      where duration && '[2020-02-01, 2020-03-01)'
    

    请注意,关闭 ) 是故意的,因为它不包括范围的上限(在本例中为 3 月 1 日)。

    如果您不想将开始日期和结束日期存储在范围类型中,您可以随时构建一个:

      where daterange(start_date, end_date, '[]') && '[2020-02-01, 2020-03-01)'
    

    可以即时计算当前月份的范围:

    select daterange(
             date_trunc('month', now())::date, 
            (date_trunc('month', now()) + interval '1 month')::date, '[)'
           );
    
            daterange        
    -------------------------
     [2020-07-01,2020-08-01)
    (1 row)
    
    

    或者三个月的日历:

    select daterange(
             (date_trunc('month', now()) - interval '1 month')::date, 
             (date_trunc('month', now()) + interval '2 month')::date, '[)'
           );
    
            daterange        
    -------------------------
     [2020-06-01,2020-09-01)
    (1 row)
    
    

    【讨论】:

    • 非常感谢。我正在使用 knexjs,所以我将如何复制它,只需使用 knex.raw()?
    • @TheLoop 也许吧。我刚刚扫描了文档,看起来他们有一个您可以使用的whereRaw()。我更新了答案以显示如何获得当月的daterange() 而无需传递它。
    【解决方案2】:

    我们存储和检索事件的方式是,每次用户在日历中滚动时,我都会使用一种方法返回当前月份以及上个月和下个月的start_date_time。总共3个月。这样我们就可以捕捉到任何日历重叠。我们在后端使用 laravel,但您应该能够了解该方法的一般要点。我们的 tableify 方法只是为我们格式化数据。 我的DB结构如下(去掉主观数据):

    CREATE TABLE calendar_events (
        id bigserial NOT NULL,
        calendar_event_category_id int4 NOT NULL, 
        name varchar(512) NOT NULL,
        description text NULL,
        start_date_time timestamp(0) NOT NULL,
        end_date_time timestamp(0) NULL,
        "data" json NULL,
        user_id int4 NULL,
        created_at timestamp(0) NULL,
        updated_at timestamp(0) NULL,
        CONSTRAINT calendar_events_pkey PRIMARY KEY (id),
        CONSTRAINT calendar_events_calendar_event_category_id_foreign FOREIGN KEY (calendar_event_category_id) REFERENCES calendar_event_categories(id),
        CONSTRAINT calendar_events_user_id_foreign FOREIGN KEY (user_id) REFERENCES users(id)
    );
    

    我的索引方法:

    
    public function index(Request $request)
    {
        $currentDate = empty($request->filter_date) ? Carbon::now() : new Carbon($request->filter_date);
        if (! empty($request->filter_date)) {
            return api_response('Retrieved Calendar Events.',
                CalendarEvent::tableify($request,
                    CalendarEvent::where('start_date_time', '>=', $currentDate->subMonth(1)->isoFormat('YYYY-MM-DD'))->where('start_date_time', '<=', ($currentDate->addMonth(2)->isoFormat('YYYY-MM-DD')))->orderby('start_date_time', 'DESC')
                )
            );
        } else {
            return api_response('Retrieved Calendar Events.', CalendarEvent::tableify($request, CalendarEvent::orderby('start_date_time', 'DESC')));
        }
    }
    

    这就是我解决重叠问题的方法。每次用户滚动前端时,都会检查一个月是否发生了变化,如果是,它会使用最新的 3 个月块更新日历。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-14
      • 1970-01-01
      • 1970-01-01
      • 2020-08-12
      • 2019-11-05
      • 2021-02-12
      • 2022-07-02
      • 2017-12-18
      相关资源
      最近更新 更多