在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);
    }
相关推荐
天宁2 个月前
Workerman + ThinkPHP 8 结合使用
php·thinkphp
云游云记2 个月前
ThinkPHP 队列扩展 (topthink/think-queue) 使用笔记
php·thinkphp·think-queue
用户14644605033792 个月前
PHP 多维数组处理利器:array_column() 用法详解
php·thinkphp
用户3074596982073 个月前
ThinkPHP 6.0 多应用模式下的中间件机制详解
后端·thinkphp
行思理3 个月前
小游戏系统提供二开服务
layui·游戏程序·小游戏·thinkphp
xmode4 个月前
常用自定义函数laravel版+thinkphp版
后端·php·laravel·thinkphp
mooyuan天天4 个月前
内网渗透之Thinkphp5提权实战+reGeorg代理横向移动(CVE-2018-20062)
内网渗透·横向移动·thinkphp·regeorg·cve-2018-20062·thinkphp代码执行漏洞
蹦极的考拉4 个月前
夜间无法登录:ThinkPHP api接口 23:00 准时罢工的排查全纪录
小程序·thinkphp·api接口·无法登陆
青茶3604 个月前
ThinkCMF是一个开源的内容管理框架
php·cms·thinkphp