在php8.3下签到、签退打卡的实现

环境:tp8.0, php8.3, nesbot/carbon3.11;

php 复制代码
    /**
     * 通用签到/签退方法
     *
     * @param string $type 打卡类型 'in'=签到, 'out'=签退
     * @param string $signInTime 规则签到时间,格式 'H:i:s'
     * @param string $signOutTime 规则签退时间,格式 'H:i:s'
     * @return Json
     */
    public function signInOut(string $type, string $signInTime, string $signOutTime): Json
    {
        $date = Carbon::today()->toDateString();

        // 规则时间转 Carbon
        $ruleSignIn  = Carbon::parse("$date $signInTime");
        $ruleSignOut = Carbon::parse("$date $signOutTime");

        $now = Carbon::parse('2026-3-23 11:59:59');

        // 使用 match 简化 if/elseif
        $data = match ($type) {
            'in' => [
                'lateMinutes'  => $now->gt($ruleSignIn) ? (int) ceil($ruleSignIn->diffInSeconds($now) / 60) : 0,
                'signInStatus' => $now->gt($ruleSignIn)
                    ? '迟到 ' . (int) ceil($ruleSignIn->diffInSeconds($now) / 60) . ' 分钟'
                    : '正常签到',
            ],
            'out' => [
                'earlyMinutes'  => $now->lt($ruleSignOut) ? (int) ceil($now->diffInSeconds($ruleSignOut) / 60) : 0,
                'signOutStatus' => $now->lt($ruleSignOut)
                    ? '早退 ' . (int) ceil($now->diffInSeconds($ruleSignOut) / 60) . ' 分钟'
                    : '正常签退',
            ],
            default => null
        };

        if ($data === null) {
            return json([
                'code' => 400,
                'msg'  => '打卡类型错误,必须是 in 或 out',
                'data' => []
            ]);
        }

        return json(['code' => 200, 'msg' => 'success', 'data' => $data]);
    }
php 复制代码
    /**
     * 判断两个日期区间是否冲突
     *
     * @param array $date1 [start, end]
     * @param array $date2 [start, end]
     * @return bool|Json
     */
    public function timeConflict(array $date1, array $date2): bool|Json
    {
        // 参数校验
        if (count($date1) !== 2 || count($date2) !== 2) {
            return json(['code'=>400, 'msg'=>'参数格式错误', 'data'=>[]]);
        }

        [$start1, $end1] = $date1;
        [$start2, $end2] = $date2;

        // 转 Carbon(按天)
        $start1 = Carbon::parse($start1)->startOfDay();
        $end1   = Carbon::parse($end1)->endOfDay();

        $start2 = Carbon::parse($start2)->startOfDay();
        $end2   = Carbon::parse($end2)->endOfDay();

        // 核心判断:是否重叠
        return $start1->lte($end2) && $start2->lte($end1);
    }
相关推荐
vipxieliang3 天前
ThinkORM 3.0 入门:强类型模型定义与查询构造器
后端·php·thinkphp
vipxieliang8 天前
ThinkPHP 8.0 注解路由实战:PHP 8 原生 Attribute 方案
php·thinkphp
vipxieliang10 天前
ThinkPHP 8.0 路由完全重写:新写法与迁移适配指南
php·thinkphp
vipxieliang20 天前
ThinkPHP MVC 模式入门:从控制器到视图的完整实践
后端·php·thinkphp
2301_32241428041 个月前
基于web的校园失物招领管理系统59695-计算机毕设 原创(免费领源码+部署教程+开发环境)
mysql·nginx·php·apache·thinkphp·phpstudy·wampserver
VX_bysjlw9851 个月前
基于PHP的论坛系统设计与实现 35136-计算机毕设原创(免费领源码+带部署教程)
开发语言·php·apache·laravel·thinkphp·phpstudy·wampserver
ymwlchina2 个月前
phpStudy 如何部署符号象客户关系管理系统(ThinkPHP 8)记录
crm·thinkphp·phpstudy·网站部署·小皮面板·客户关系管理系统
在呢3 个月前
ThinkPHP 事务机制详解
thinkphp
安妮的小熊呢5 个月前
CRMEB BZ v6.0 使用教程:从安装部署到后台基础配置
php·thinkphp·电商系统·crmeb
withoutfear5 个月前
Fastadmin中获取IP和手机号归属地信息
php·thinkphp·fastadmin·ip归属地·手机号归属地