Laravel仪表盘新订单通知弹窗重复弹出问题修复
问题原因
- 点击「Ok, let me check」按钮跳转前,未将对应未读订单的
checked字段更新为已读状态,后端轮询接口始终能统计到checked=0的历史订单,返回仪表盘后会持续满足弹窗触发条件 - 前端轮询逻辑未做弹窗防重判断,每1秒轮询只要拿到新订单数大于0就直接触发弹窗,即使弹窗已经处于展示状态也会重复执行
- 无本地已提示状态标记,页面重新加载后轮询重启,会直接拉取未更新的未读订单数再次弹窗
修复步骤
1. 后端新增订单标记已读接口
首先在routes/web.php中新增路由:
Route::post('admin/order/mark-read', [OrderController::class, 'mark_order_read'])->name('admin-order-mark-read');
在对应控制器中添加标记已读的方法:
public function mark_order_read() { // 将所有未读订单批量更新为已读状态 DB::table('orders')->where(['checked' => 0])->update(['checked' => 1]); return response()->json(['success' => 1]); }
这一步是核心修复,从数据层面标记订单已经被管理员查看,从根源避免返回页面后重复统计到旧的未读订单。
2. 修改前端轮询与跳转逻辑
替换原有Ajax代码,增加弹窗防重标记,跳转前先调用已读接口:
<script> // 弹窗防重标记,避免同批次新订单重复触发弹窗 let hasShownNewOrderAlert = false; setInterval(function () { $.get({ url: '{{route('get-order-data')}}', dataType: 'json', success: function (response) { let data = response.data; // 仅当存在新订单、且当前未展示弹窗时触发提示 if (data.new_order > 0 && !hasShownNewOrderAlert) { playAudio(); hasShownNewOrderAlert = true; $('#popup-modal').appendTo("body").modal('show'); } // 无未读订单时重置标记,等待下一批新订单触发 if (data.new_order === 0) { hasShownNewOrderAlert = false; } }, }); }, 1000); function check_order() { // 先提交已读标记,再跳转订单列表 $.post({ url: '{{route('admin-order-mark-read')}}', data: {_token: '{{csrf_token()}}'}, success: function () { hasShownNewOrderAlert = false; location.href = '{{route('admin-order-pending')}}'; } }) } </script>
3. (可选优化)补全弹窗关闭场景的已读逻辑
如果管理员可能点击弹窗右上角关闭按钮、不通过查看按钮跳转,可新增弹窗关闭监听,避免关闭后反复弹出:
// 放在原有script标签内即可 $('#popup-modal').on('hidden.bs.modal', function () { $.post({ url: '{{route('admin-order-mark-read')}}', data: {_token: '{{csrf_token()}}'} }) hasShownNewOrderAlert = false; })
验证效果
- 新订单生成时正常触发提示音、弹出通知弹窗
- 点击「Ok, let me check」后自动标记当前所有未读订单为已读,正常跳转订单列表页
- 从订单列表返回仪表盘后,不会再弹出已查看过的旧订单通知
- 同页面停留时,不会因为1秒一次的轮询反复触发同一个弹窗
内容的提问来源于stack exchange,提问作者Deepu
相关产品推荐
相关产品推荐

