You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel考勤系统:如何计算打卡时长并写入total列?

考勤系统时长计算问题修复方案

你的total方法无法正常运行主要有几个核心问题:

  • DB::table('attendance')->where('id')语法错误,未指定匹配的ID值,且完全没必要额外查询数据表——你已经通过firstOrFail()拿到了当前考勤记录
  • timeIn和timeOut是字符串格式的时间,直接用数据库原生相减无法得到正确时长差值
  • 当前流程需要手动调用total方法,逻辑割裂,应该在下班打卡(timeOut)时自动计算时长

修正后的代码实现

1. 优化User模型的timeOut方法(自动计算总时长)

直接在下班打卡时计算并更新total字段,无需单独的total方法:

public function timeOut()
{
    $manilaTime = Carbon::now('Asia/Manila');
    $attendance = $this->employeeAttendance()
                ->where('date', $manilaTime->toDateString())
                ->whereNull('timeOut')
                ->firstOrFail();

    // 解析时间并计算时长(转为小时,保留两位小数)
    $timeIn = Carbon::createFromFormat('H:i:s', $attendance->timeIn);
    $timeOut = Carbon::createFromFormat('H:i:s', $manilaTime->format('H:i:s'));
    $totalHours = $timeIn->diffInMinutes($timeOut) / 60;

    return $attendance->update([
        'timeOut' => $manilaTime->format('H:i:s'),
        'total' => round($totalHours, 2) // 可根据需求调整小数位数
    ]);
}

2. 简化timeIn方法(可选优化)

无需重复获取auth()->user()->name,当前模型即为登录用户,直接调用$this->name即可:

public function timeIn()
{
    $manilaTime = Carbon::now('Asia/Manila');

    return $this->employeeAttendance()->create([
        'name' => $this->name,
        'date' => $manilaTime->toDateString(),
        'timeIn' => $manilaTime->format('H:i:s'),
    ]);
}

3. 控制器代码保持不变

你的控制器逻辑无需修改:

public function store(Request $request)
{
    $request->user()->timeIn();

    return back();
}

public function update(Request $request)
{
    $request->user()->timeOut();

    return back();
}

关键改进说明

  • 用Carbon解析时间字符串,通过diffInMinutes计算分钟差后转为小时,确保时长计算准确
  • 在timeOut时自动更新total,避免手动调用额外方法,逻辑更连贯
  • 移除无效的重复数据库查询,直接操作已获取的考勤记录,提升性能

内容的提问来源于stack exchange,提问作者John Patrick Paguia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 05:22:24