0%

考勤日统计功能实现

背景

​ 因业务系统需要支持一些简单的考勤功能,好在公司有现成并且成熟的商业OA系统供参考,当然,只是功能参考而已,并无任何源码。

​ 其中让我比较好奇的是,公司OA系统的考勤日统计是怎么做的?当然,好奇的同时,我还需要在自身的业务系统复刻此功能。

image-20230830225707128

如图,此时间段,我还未入职,却一样能统计我的考勤情况,至于为什么是23条记录,也就是23天?去除休息日8天可不就剩23天!

也就是说不管有没有实际入职,有没有实际考勤打卡,系统会一天不落的统计职工每天的考勤情况,并且支持分页显示。

思考

初步探索

如果需要实现这种效果,能直接想到的似乎就如下1种方法:

  • 根据查询的时间范围后台动态生成数据,并且使用假分页返回数据。

但此种方法很显然不可取,有以下弊端:

  1. 代码复杂度高
  2. 不利于查询,排序
  3. 不利于环保(因为跑起来费电)

进阶

比如输入 时间范围:2023-08-01至2023-08-31,将此时间范围的31天生成31个日期到某一个临时表里面?利用数据库连表查询的笛卡尔积不就能实现此功能了吗?

确实能实现此功能,而且相比上面说的动态生成方法更靠谱,利于查询、排序,而且…更省电!

但同样的,动态生成日期到临时表同样不靠谱,10个用户查询总不能生成10个临时表?用户要查询2年的数据,总不能就生成365x2=730条日期数据?用户每次的查询时间范围都不同,总不能每次生成一张新的临时表?

因此现在的问题变成:“如何减少生成临时表的次数,如何减少生成日期的次数”

这个似乎简单,不用临时表,那我直接生成一张辅助表,这张表提前生成过去10年,未来10年每一天的日期数据 365*20年=7300条日期数据。能完美解决这个需求!

一个系统能用10年也是烧高香了,似乎够用了,但我们要有点追求!

系统能不能定期检查一下辅助表中最大的日期和当前日期做对比,然后又生成未来5年10年的日期数据?

当然可以!机智如你!

最终解决方案

其实上面说的方法已经能很好的解决这个需求了,高效且方便,我猜公司OA系统用的就是此方法。

但年轻人就是不听劝,有没有更好的,或者不次于上面方法的方法?

也许有,个人认为!

image-20230830235131295

只要生成一张如上的辅助表就行了,priority是按1步进的,不用生成具体的日期,利用数据库的date_add函数,根据用户查询的时间范围就能动态生成日期了,此种方法能减少辅助表的数据量,但由于使用数据库函数的关系,连表查询时效率较低。

综上所述,各有各的好,看你喜欢哪种。

总结

有些问题一旦点破,会让人觉得似乎如此的简单。

致谢名单:

1.公司OA系统

坚持原创技术分享,您的支持将鼓励我继续创作!
YANG 微信支付

微信支付

YANG 支付宝

支付宝