在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);
    }
相关推荐
安妮的小熊呢4 天前
CRMEB BZ v6.0 使用教程:从安装部署到后台基础配置
php·thinkphp·电商系统·crmeb
withoutfear12 天前
Fastadmin中获取IP和手机号归属地信息
php·thinkphp·fastadmin·ip归属地·手机号归属地
qq31869299617 天前
ThinkPHP + Supervisor 队列任务丢失:僵尸 Worker 排查全记录
服务器·thinkphp·宝塔
linlinlove217 天前
前端uniapp、后端thinkphp股票系统开发功能展示、代码披露、HQChart
前端·uni-app·echarts·thinkphp·hqchart·配资·deepseek选股票
SuperherRo1 个月前
服务攻防-开发框架安全&ThinkPHP&Laravel&SpringBoot&Struts2&SpringCloud&复现
spring boot·laravel·thinkphp·struts2·框架安全
quweiie1 个月前
thinkphp8生成海报
thinkphp·海报
云游云记2 个月前
FastAdmin 路由完全开启教程:去掉 index 前缀 + 优雅路由配置
thinkphp
kertag2 个月前
ThinkPHP 8 多应用入口绑定:BIND_MODULE vs $http->name() 全面解析
php·thinkphp
妙码生花3 个月前
全新的 TP8+Workerman+BuildAdmin 整合方案,已有近 2000 次下载使用。
websocket·php·thinkphp