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

最终目标登陆后 点击上班签到 ,只要已经签到 就显示下班签到;
点击签到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

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

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
最佳答案

是的,确实是 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年前 评论

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