讲师中心 微信公众号
AI工具推荐 视频效率加速

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

千敏姑娘_7186

千敏姑娘_7186

发布时间:2026-10-24 11:04:02

|

234人浏览过

|

来源于php中文网

原创

如何在 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" 
                {{ $available === 0 ? '' : ($book->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)和防误触能力。

    laravel-specialist
    laravel-specialist

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

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

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

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

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

热门AI工具

更多
Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

相关专题

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

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

5146

2023.06.20

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

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

1269

2023.07.04

js四舍五入
js四舍五入

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

5084

2023.07.04

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

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

980

2023.09.01

JavaScript转义字符
JavaScript转义字符

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

1916

2023.09.04

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

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

3625

2023.09.04

如何启用JavaScript
如何启用JavaScript

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

4713

2023.09.12

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

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

3080

2023.09.20

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

0

2026.10.22

热门下载

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

精品课程

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

共1课时 | 212人学习

Composer手册
Composer手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn