写了公司签到按钮,上班前点击签到,下班点击下班签到,自动记录时间,按照工作时间结算工资!出错了!!

最终目标登陆后 点击上班签到 ,只要已经签到 就显示下班签到;
点击签到create控制器自动维护created_at时间 ;下班签到update控制器,自动维护updated_at时间;
就一个数据表,
id(自增id)
user_id(用户id)
sstore_id(所属店面id,考虑到多家店面)
sip(签到时候的ip)
estore_id(离开签到的id 也就是下班点击一下)
esip(离开的时候ip)
created_at(签到时间)
updated_at(离开时间也就是下班时间)
qi

public function create(Request $request)
    {
        return view('attendance_create');
    }
    public function store(Request $request)
    {
        $request->user()->attendances()->create([
            'sstore_id' => 1, //所属店面id会记录在数据表
            'sip' => $request->getClientIp(),//记录当前用户ip
        ]);
        return redirect()->back();
    }
    public function update(Request $request, Attendance $attendance)
    {
        $attendance->update([
            'estore_id' => 1,//下班签到的店面id 
            'eip' => $request->getClientIp(),//下班记录当前用户ip
        ]);
        return redirect()->back();
    }

因为这个签到没有单独页面只是在 首页导航上面有个 按钮,更新的时候需要一个得到数据库签到的id;

 @if (Auth::user()->attendances()->orderBy('created_at', 'desc')->first()->estore_id)
        <form action="{{route('attendance.store')}}" onsubmit="return confirm('你确定签到吗?')" method="post">
            @csrf

            <input type="submit" class="btn btn-success" value="上班签到">
        </form>
    @else

    <form action="{{route('attendance.update',Auth::user()->attendances()->orderBy('created_at', 'desc')->first()->id)}}" onsubmit="return confirm('离开下班吗?离开后无法修改')" method="post">
        @csrf
        @method('put')
        <input type="submit" class="btn btn-success" value="离开签到">
    </form>
    @endif

问题:退出之后从新登陆新的用户就提示当前用户没有estore_id 也就是找不到estore_id因为新用户没有签到记录。
请问下下面这个代码是否有其他判断方式?问题应该处在first() 查找不到就报错!

Auth::user()->attendances()->orderBy('created_at', 'desc')->first()->estore_id

因为是个后台系统 顶部导航栏中要加入这个签到 ,按照这个逻辑我需要在每个逻辑里面都要写入查询签到的这个代码,因为每个页面都要使用顶部导航,!
或者您有更好的解决方案/感谢!!

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
最佳答案

是的,确实是 first() 方法哪里的问题,在没有保证的前提下最好是不要直接在 first() 的后面直接引用数据,因为当数据库查不到数据的时候,first() 方法会返回 null 。这个时候如果引用数据,就相当于用 null 引用数据,肯定会出错。

解决方法

你可以这样写

 @if (($date = Auth::user()->attendances()->orderBy('created_at', 'desc')->first()) !== null)
    @if($date->estore_id)
        //签到代码
    @else
        //下班代码
    @endif
@else
    //没有找到数据
@endif

另外,建议这种数据库的操作不要放在blade模板里面,数据处理的代码尽量放在控制器里。这里的判断只需要通过控制器传递参数到视图就可以了。

4年前 评论
李小明 (楼主) 4年前
飞机飞过天空 (作者) 4年前
讨论数量: 6

看了你的描述,多加一个数据是否为空的的判断就可以了

4年前 评论
李小明 (楼主) 4年前

这样试试

if ($last = Auth::user()->attendances()->orderBy('created_at', 'desc')->first() and $last->estore_id) {
    //...
}
4年前 评论
李小明 (楼主) 4年前

感觉有没有签到记录的逻辑判断放到 controller 去做比较好,然后只给 view 传个标识

4年前 评论
李小明 (楼主) 4年前

是的,确实是 first() 方法哪里的问题,在没有保证的前提下最好是不要直接在 first() 的后面直接引用数据,因为当数据库查不到数据的时候,first() 方法会返回 null 。这个时候如果引用数据,就相当于用 null 引用数据,肯定会出错。

解决方法

你可以这样写

 @if (($date = Auth::user()->attendances()->orderBy('created_at', 'desc')->first()) !== null)
    @if($date->estore_id)
        //签到代码
    @else
        //下班代码
    @endif
@else
    //没有找到数据
@endif

另外,建议这种数据库的操作不要放在blade模板里面,数据处理的代码尽量放在控制器里。这里的判断只需要通过控制器传递参数到视图就可以了。

4年前 评论
李小明 (楼主) 4年前
飞机飞过天空 (作者) 4年前

Auth::user()->attendances()->orderBy('created_at', 'desc')->first()->estore_id 这个可以写在模型里,调用的时候也很简单 $model->estore_id,在模型中定义好,可以根据业务需要提前做好规划

4年前 评论
野犭

建议签到时间和签退时间另起两个字段,created_at 还好,但 updated_at 保不齐什么时候要更新其他字段就不准了

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!