Laravel FilamentPHP 3表格如何将签到签出显示在同一行?
在FilamentPHP表格中合并员工签到签出记录为单行显示
要实现将同一员工同一天的签到、签出信息显示在同一行,核心是先通过数据库查询合并数据,再在Filament表格中配置对应列,具体步骤如下:
1. 基础场景实现(单次签到签出)
利用MySQL聚合函数,按employee_id和date分组,提取当天最早时间作为签到时间、最晚时间作为签出时间,直接在Filament Resource中重写表格查询逻辑:
use Illuminate\Support\Facades\DB; use Filament\Tables\Table; use App\Models\Attendance; // 在你的AttendanceResource类中 public static function table(Table $table): Table { return $table // 分组合并数据的查询逻辑 ->query(fn () => Attendance::query() ->select([ 'employee_id', 'date', DB::raw('MIN(time) as check_in_time'), // 取当天最早时间为签到 DB::raw('MAX(time) as check_out_time'), // 取当天最晚时间为签出 ]) ->groupBy('employee_id', 'date')) // 配置表格列 ->columns([ TextColumn::make('employee_id') ->label('员工ID'), TextColumn::make('date') ->label('日期') ->date('Y-m-d'), TextColumn::make('check_in_time') ->label('签到时间') ->time('H:i:s'), TextColumn::make('check_out_time') ->label('签出时间') ->time('H:i:s') ->default('未签出'), // 处理仅签到未签出的异常情况 ]); }
2. 复杂场景适配(多次签到签出)
如果员工同一天存在多轮签到签出(如中途外出返回),上述方法会取全天首尾时间,若需要精准配对每一次签到和签出,可使用MySQL窗口函数关联相邻记录:
// 替换上述query方法中的查询逻辑 ->query(fn () => Attendance::query() ->select([ 'employee_id', 'date', 'time as check_in_time', // 关联下一条记录的时间作为对应签出时间 DB::raw('LEAD(time) OVER (PARTITION BY employee_id, date ORDER BY time) as check_out_time'), ]) // 仅保留每对记录中的签到行 ->whereRaw('MOD(ROW_NUMBER() OVER (PARTITION BY employee_id, date ORDER BY time), 2) = 1'))
内容的提问来源于stack exchange,提问作者Madushan Serasinghe
相关产品推荐
相关产品推荐

