如何在Laravel表单中用if/else实现员工签到签出按钮切换
问题:考勤签到/签退按钮逻辑未按预期生效
我尝试在表单中通过if/else实现:员工timein字段为空时显示「Sign In」按钮,否则显示「Sign Out」按钮,但当前逻辑不生效。以下是相关代码及表结构,请帮忙排查。
1. 视图(set_attendance)代码
<table class="table table-bordered table-striped"> <thead> <tr> <th> {{ __(' SL') }}</th> <th> {{ __(' Employee Name') }}</th> <th> {{ __('Action') }}</th> </tr> </thead> <tbody> @foreach($attendances as $key => $attd) <tr> <td>{{$key+1}}</td> <td>{{ $attd['name'] }}</td> <td> <form action="{{ route('attendance.timeclock') }}" method="post" name="department_add_form"> {{ csrf_field() }} <input type="hidden" name="id" id="id" value="{{ $attd['id'] }}"> @if($timein[1]['timein'] == Null) <button type="submit" class="btn btn-primary btn-flat"><i class="icon fa fa-plus"></i> {{ __('Sign IN') }}</button> @else <button type="submit" class="btn btn-primary btn-flat"><i class="icon fa fa-plus"></i> {{ __('Sign Out') }}</button> @endif </form> </td> </tr> @endforeach </tbody> </table>
2. 控制器timeclockcreate方法代码
public function timeclockcreate(Request $request){ $id = $request->input('id'); $data['attendances'] = User::all()->toArray(); $data['timein'] = User::query() ->leftjoin('attendances', 'attendances.user_id', '=', 'users.id') ->select('attendances.*', 'users.*') ->orderBy('users.name', 'ASC') ->get() ->toArray(); return view('fms.attendances.set_attendance',$data)->with('id', $id)->with('message', 'Inserted successfully.'); }
3. attendance表结构
public function up() { Schema::create('attendances', function (Blueprint $table) { $table->increments('id'); $table->integer('created_by'); $table->integer('user_id')->unsigned(); $table->time('timein')->nullable(); $table->time('timeout')->nullable(); $table->date('logdate'); $table->string('status'); $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); $table->timestamps(); }); }
问题排查与修复方案
核心问题1:视图硬编码索引导致逻辑统一化
视图中@if($timein[1]['timein'] == Null)是固定取数组第2个元素的考勤状态,所有员工都会使用同一个人的timein值,完全忽略了当前循环的员工。
核心问题2:控制器数据关联冗余且无日期筛选
- 同时传递
attendances(纯用户数据)和timein(关联数据),视图循环纯用户数据时无法匹配对应考勤状态 select('attendances.*', 'users.*')会导致字段覆盖(比如id字段)- 未筛选当天的考勤记录,历史数据会干扰判断
修复后的代码
控制器代码(优化数据关联与筛选)
// 顶部引入Carbon处理日期:use Carbon\Carbon; public function timeclockcreate(Request $request){ $today = Carbon::today(); // 直接获取关联了当天考勤的用户数据 $data['users'] = User::query() ->leftJoin('attendances', function($join) use ($today) { $join->on('attendances.user_id', '=', 'users.id') ->where('attendances.logdate', '=', $today); }) // 明确指定字段避免覆盖 ->select('users.id', 'users.name', 'attendances.timein', 'attendances.id as attendance_id') ->orderBy('users.name', 'ASC') ->get(); return view('fms.attendances.set_attendance', $data) ->with('message', '操作成功'); }
视图代码(修正逻辑匹配)
<table class="table table-bordered table-striped"> <thead> <tr> <th> {{ __(' SL') }}</th> <th> {{ __(' Employee Name') }}</th> <th> {{ __('Action') }}</th> </tr> </thead> <tbody> @foreach($users as $key => $user) <tr> <td>{{$key+1}}</td> <td>{{ $user->name }}</td> <td> <form action="{{ route('attendance.timeclock') }}" method="post" name="department_add_form"> {{ csrf_field() }} <input type="hidden" name="user_id" value="{{ $user->id }}"> <!-- 传递已存在的考勤ID,方便签退时更新 --> @if($user->attendance_id) <input type="hidden" name="attendance_id" value="{{ $user->attendance_id }}"> @endif @if(empty($user->timein)) <button type="submit" class="btn btn-primary btn-flat"><i class="icon fa fa-plus"></i> {{ __('Sign IN') }}</button> @else <button type="submit" class="btn btn-danger btn-flat"><i class="icon fa fa-minus"></i> {{ __('Sign Out') }}</button> @endif </form> </td> </tr> @endforeach </tbody> </table>
额外说明
- 用
empty()判断timein状态,比直接判断== Null更严谨 - 区分签到/签退按钮样式,提升视觉辨识度
- 仅关联当天考勤记录,避免历史数据干扰逻辑判断
内容的提问来源于stack exchange,提问作者Kairaoi Ientumoa
相关产品推荐
相关产品推荐

