Laravel创建健身房客户周考勤表异常问题求助
健身房客户周考勤表格全部显示X的问题
我在Laravel中开发健身房客户一周(周一至周六)考勤展示表格,每行显示客户姓名,每列对应周一到周六,客户当日签到显示Y,未签到显示X,但测试时所有单元格均显示X。
现有实现代码
后端控制器方法
public function weekCheckIn(){ $startWeek = Carbon::now()->startOfWeek(Carbon::MONDAY); $endWeek = Carbon::now()->endOfWeek(Carbon::SATURDAY); $clientWeek = Client::with(['client_scans' => function($query) use ($startWeek, $endWeek){$query->whereBetween('user_check_in',[$startWeek,$endWeek]);}])->get(); return $clientWeek; }
Blade模板代码
<table> <tr> <th></th> @for ($i = 0; $i < 6; $i++) <th>{{ Carbon\Carbon::now()->startOfWeek(Carbon\Carbon::MONDAY)->addDays($i)->format('D') }}</th> @endfor </tr> @foreach ($weekStatus as $client) <tr> <td><b>{{ $client->name }}</b> {{ $client->surname }}</td> @for ($i = 0; $i < 6; $i++) <td> @if (in_array(Carbon\Carbon::now()->startOfWeek(Carbon\Carbon::MONDAY)->addDays($i)->format('Y-m-d'), $client->client_scans->pluck('user_check_in')->toArray())) Y @else X @endif </td> @endfor </tr> </tr> @endforeach </table>
注:使用dump()查看in_array参数结果,数据由Eloquent Factories生成。
问题原因及解决方法
1. 变量名不匹配
控制器中查询得到的变量是$clientWeek,但模板中遍历的是$weekStatus,导致模板无法获取正确的客户数据。
修复:
修改控制器,将查询结果赋值给$weekStatus并传递到视图:
public function weekCheckIn(){ $startWeek = Carbon::now()->startOfWeek(Carbon::MONDAY); $endWeek = Carbon::now()->endOfWeek(Carbon::SATURDAY); $weekStatus = Client::with(['client_scans' => function($query) use ($startWeek, $endWeek){ $query->whereBetween('user_check_in',[$startWeek,$endWeek]); }])->get(); // 替换为你的实际视图名称 return view('attendance.week', compact('weekStatus')); }
2. 日期格式不匹配
client_scans表的user_check_in字段是datetime类型,pluck('user_check_in')得到的是带时间的字符串(如2024-05-20 09:30:00)或Carbon实例,而模板中用format('Y-m-d')生成的是纯日期字符串(如2024-05-20),两者无法匹配。
修复方案一(模板内处理):
将签到日期统一转换为Y-m-d格式后再进行匹配:
@if (in_array(Carbon\Carbon::now()->startOfWeek(Carbon\Carbon::MONDAY)->addDays($i)->format('Y-m-d'), $client->client_scans->pluck('user_check_in')->map(function($date) { return Carbon\Carbon::parse($date)->format('Y-m-d'); })->toArray())) Y @else X @endif
修复方案二(控制器预处理,更高效):
在控制器中提前转换签到日期格式,减少模板内的计算:
public function weekCheckIn(){ $startWeek = Carbon::now()->startOfWeek(Carbon::MONDAY); $endWeek = Carbon::now()->endOfWeek(Carbon::SATURDAY); $weekStatus = Client::with(['client_scans' => function($query) use ($startWeek, $endWeek){ $query->whereBetween('user_check_in',[$startWeek,$endWeek]); }])->get()->map(function($client) { // 预转换签到日期为Y-m-d格式 $client->check_in_dates = $client->client_scans->pluck('user_check_in') ->map(fn($date) => Carbon\Carbon::parse($date)->format('Y-m-d')); return $client; }); // 同时计算一周的日期数组,优化模板代码 $weekDates = []; for ($i = 0; $i < 6; $i++) { $date = Carbon::now()->startOfWeek(Carbon::MONDAY)->addDays($i); $weekDates[] = [ 'day_name' => $date->format('D'), 'date_str' => $date->format('Y-m-d') ]; } return view('attendance.week', compact('weekStatus', 'weekDates')); }
对应的模板优化:
<table> <tr> <th></th> @foreach ($weekDates as $day) <th>{{ $day['day_name'] }}</th> @endforeach </tr> @foreach ($weekStatus as $client) <tr> <td><b>{{ $client->name }}</b> {{ $client->surname }}</td> @foreach ($weekDates as $day) <td>{{ in_array($day['date_str'], $client->check_in_dates->toArray()) ? 'Y' : 'X' }}</td> @endforeach </tr> @endforeach </table>
内容的提问来源于stack exchange,提问作者cdBreak
相关产品推荐
相关产品推荐

