如何在 Laravel 中根据图书可用数量自动切换状态开关

千敏姑娘_7186

千敏姑娘_7186

2026-10-24

234人浏览

原创

如何在 Laravel 中根据图书可用数量自动切换状态开关

本文介绍如何在 laravel 项目中,基于图书剩余可借数量(available = 可用数)动态控制 bootstrap toggle 开关状态:当可用数为 0 时强制设为 inactive 并禁用操作,否则允许正常切换。

本文介绍如何在 laravel 项目中,基于图书剩余可借数量(available = 可用数)动态控制 bootstrap toggle 开关状态:当可用数为 0 时强制设为 inactive 并禁用操作,否则允许正常切换。

在实际图书管理系统中,业务逻辑常要求“库存归零即自动下架”——即当 Available: 0 时,无论用户如何操作开关,状态都必须锁定为 Inactive。原代码虽支持手动切换,但未校验业务约束。下面提供一套健壮、可维护的解决方案。

✅ 核心实现思路

  1. 前端实时校验:在 change 事件触发时,立即解析当前行的 Available 数值;
  2. 强制状态干预:若可用数为 0,则重置开关状态为 off,并同步更新 status 值为 0;
  3. 视觉与数据一致:使用 .bootstrapToggle('on'/'off') 主动控制 UI,避免用户误操作;
  4. 后端兜底(强烈建议):前端校验仅为体验优化,关键逻辑仍需在 Laravel 控制器中二次验证。

? 完整优化代码(含注释)

@foreach($booksData as $book)
    <tr>
<td id="total">
            {{ $book->number_books }}
            <br><h6 class="text-success" data-id="{{ $book->id }}">
                Available: {{ $available = $book->number_books - $book->number_borrowedbooks }}
            </h6>
        </td>
        <td style="width: 25px;">
            <input type="checkbox" class="toggle-class" data-id="{{ $book->id }}" data-forwhat="books" data-onstyle="success" data-offstyle="danger" data-toggle="toggle" data-on="Active" data-off="Inactive" :>status ? 'checked' : '') }}
                {{ $available === 0 ? 'disabled' : '' }}
            >
        </td>
    </tr>
@endforeach

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script><script src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js"></script><script>
jQuery(document).ready(function ($) {
    console.log('jQuery & Bootstrap Toggle loaded.');

    $('.toggle-class').change(function () {
        const $this = $(this);
        const id = $this.data('id');
        const forwhat = $this.data('forwhat') || 'books';
        const token = $('meta[name="csrf-token"]').attr('content');

        // ? 解析本行可用数量(正则提取数字,更鲁棒)
        const $availableEl = $this.closest('tr').find('.text-success');
        const availableText = $availableEl.text();
        const availableMatch = availableText.match(/Available:\s*(\d+)/);
        const available = availableMatch ? parseInt(availableMatch[1], 10) : 0;

        let status;
        if (available === 0) {
            // ❌ 强制设为 Inactive,且视觉同步
            $this.bootstrapToggle('off');
            status = 0;
            // 可选:提示用户
            alert('⚠️ 该图书暂无库存,状态已自动设为 Inactive。');
        } else {
            // ✅ 允许按用户选择切换
            status = $this.prop('checked') ? 1 : 0;
            $this.bootstrapToggle(status ? 'on' : 'off');
        }

        // ? 发送 AJAX 请求(注意:URL 应使用 Laravel route() 辅助函数更安全)
        $.ajax({
            type: 'POST', // 推荐改为 POST + _method=PUT 或 PATCH
            url: '/books/' + id + '/toggle-status',
            data: {
                status: status,
                forwhat: forwhat,
                _token: token,
                _method: 'PUT'
            },
            dataType: 'json',
            success: function (res) {
                console.log('Status updated:', res.message);
                // 可在此处刷新局部 UI 或显示 Toast
            },
            error: function (xhr) {
                console.error('Update failed:', xhr.responseJSON?.message || xhr.statusText);
                // 恢复开关至原始状态(防止 UI 与服务端不一致)
                $this.bootstrapToggle(status ? 'off' : 'on');
            }
        });
    });
});
</script>

⚠️ 关键注意事项

  • 禁止仅依赖前端校验:恶意用户可绕过 JS,务必在 Laravel 控制器的 changeStatus 方法中再次校验:

    // BookController.php
    public function toggleStatus(Request $request)
    {
        $book = Book::findOrFail($request->id);
        $available = $book->number_books - $book->number_borrowedbooks;
    
        if ($available === 0 && $request->status == 1) {
            return response()->json(['error' => 'Cannot activate book with zero availability.'], 400);
        }
    
        $book->status = $request->status;
        $book->save();
    
        return response()->json(['success' => 'Status updated.']);
    }
  • HTML 属性语义化:为 <input> 添加 disabled 属性(如上所示),从 DOM 层面禁用交互,提升可访问性(a11y)和防误触能力。

  • 路由安全性:避免使用 /changeStatus 这类泛型 GET 路由(易被 CSRF 利用),改用资源路由(如 PUT /books/{id}/status)并启用 Laravel 的 CSRF 和方法伪造保护。

    laravel-specialist
    laravel-specialist

    精通 Laravel 10+,遵循现代 PHP 实践的 Laravel 专家。擅长优雅语法、Eloquent ORM、队列系统及企业级特性...

    下载
  • 性能提示:若列表较长,建议将 available 计算逻辑移至 Eloquent Accessor,例如在 Book 模型中定义:

    protected $appends = ['available'];
    public function getAvailableAttribute() { return $this->number_books - $this->number_borrowedbooks; }

通过以上改造,你的状态开关不仅符合业务规则,也具备生产环境所需的健壮性、安全性和用户体验。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

laravel

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
js获取数组长度的方法
js获取数组长度的方法

在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.20

5146

5

js刷新当前页面
js刷新当前页面

js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

2023.07.04

1269

3

js四舍五入
js四舍五入

js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

2023.07.04

5084

6

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

2023.09.01

980

4

JavaScript转义字符
JavaScript转义字符

JavaScript中的转义字符是反斜杠和引号,可以在字符串中表示特殊字符或改变字符的含义。本专题为大家提供转义字符相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

1916

5

js生成随机数的方法
js生成随机数的方法

js生成随机数的方法有:1、使用random函数生成0-1之间的随机数;2、使用random函数和特定范围来生成随机整数;3、使用random函数和round函数生成0-99之间的随机整数;4、使用random函数和其他函数生成更复杂的随机数;5、使用random函数和其他函数生成范围内的随机小数;6、使用random函数和其他函数生成范围内的随机整数或小数。

2023.09.04

3625

4

如何启用JavaScript
如何启用JavaScript

JavaScript启用方法有内联脚本、内部脚本、外部脚本和异步加载。详细介绍:1、内联脚本是将JavaScript代码直接嵌入到HTML标签中;2、内部脚本是将JavaScript代码放置在HTML文件的`<script>`标签中;3、外部脚本是将JavaScript代码放置在一个独立的文件;4、外部脚本是将JavaScript代码放置在一个独立的文件。

2023.09.12

4713

6

Js中Symbol类详解
Js中Symbol类详解

javascript中的Symbol数据类型是一种基本数据类型,用于表示独一无二的值。Symbol的特点:1、独一无二,每个Symbol值都是唯一的,不会与其他任何值相等;2、不可变性,Symbol值一旦创建,就不能修改或者重新赋值;3、隐藏性,Symbol值不会被隐式转换为其他类型;4、无法枚举,Symbol值作为对象的属性名时,默认是不可枚举的。

2023.09.20

3080

5

java访问控制修饰符介绍
java访问控制修饰符介绍

java访问控制修饰符有四种,分别是public、protected、private、默认访问修饰符。详细介绍:1、public,public是最宽松的访问控制修饰符,被修饰的类、方法和变量可以被任何其他类访问,当一个类、方法或变量被声明为public时,它们可以在任何地方被访问,无论是同一个包中的类还是不同包中的类;2、protected修饰符等等。

2023.09.20

988

7

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
如何安装 Composer
如何安装 Composer

共1课时 | 212人学习

Composer手册
Composer手册

共0课时 | 0人学习