Lumen企业站内容管理实战 -文章分类更新状态和删除

文章分类更新状态和删除

状态的更新和删除,放在一起介绍了,因为简单,哈哈。

更改状态和删除的路由已经写好了, 在/routes/web.php文件中,

$router->post('/category/del/{id:[1-9]+}', 'CategoryController@del'); // 删除文章分类
$router->post('/category/status/{id:[1-9]+}', 'CategoryController@status'); // 更改状态status

这两个路由,要求传分类的id,并且是数字,不能为空。

写到这里,我发下之前做迁移的时候,少了一个开启和停用的状态字段,那我们现在加一个,打开/database/migrations/目录,修改category迁移,增加一个

$table->unsignedInteger('is_open')->default(1)->comment('是否开启,0:关闭,1:开启');

然后到命令行工具上,执行

php artisan migrate:rollback

这个命令是回滚操作。上个命令是新建category表,这次是删除表。这个命令使用的时候要小心。因为现在是开发阶段,并且是我一个人开发,所以回滚没问题,但是之前的数据没有了,但是我做这个操作之前,已经备份数据库了。如果后边有很多版本了,就不能这样操作了,后边我会专门介绍如何新增字段、修改字段、添加索引等。

然后再执行命令

php artisan migrate

这个是迁移,category表又新增好了。我会把数据导入进去的。Category模型中,也要添加一个is_open的字段。

打开/app/Models/category.php文件,这里加一个新的方法,用于处理开启和关闭。

public static function isOpen(Category $category)
    {
        $category->is_open = !$category->is_open;
        return $category->update();
    }

为什么is_open的值要等于自己的非呢?假如一个分类信息的is_open值是1,在前端的页面展示应该是开启,当你点击开启按钮,必然是为了关闭这条信息,当你点击关闭按钮,必然是为了开启这条信息,所以使用取非的操作。is_open的数据类型可以使用bit类型,只有0和1两种状态,在这里使用bit类型更合适。

再看看控制器,打开/app/Http/Controllers/Admin/CategoryController.php文件,增加一个方法

public function status(int $id, Request $request)
    {

        $category = Category::where('id', $id)->first();
        if (empty($category->id)) {
            $this->response->setMsg(400, '信息不存在');
            return $this->response->responseJSON();
        }


        Category::isOpen($category);

        $this->response->setData(['status' => (int)$category->is_open]);
        return $this->response->responseJSON();
    }

第一步检查信息是否存在,第二步更新is_open的值,第三步,把更新后的值返回给前端。当接口返回的status是1时,前端的开关按钮应该展示开启,当接口返回的status是0时,前端的开关按钮应该展示关闭。

我在category.blade.php文件中,增加一段js代码,用于更改开启和停用的状态,注意:任何ajax的请求,都因应该处理error回调信息,这段代码中我没有处理,之前的也没有处理,但是我知道是需要处理的,这里只是为了演示,简单起见不做处理。

// 切换开启和停用状态
        $('.layui-form-switch').on('click', function () {

            var that = $(this);
            var id = $(this).prev().attr('id');

            $.post('/admin/category/status/' + id, function (data) {
                console.log(data);
                if (data.data.status === 1) {
                    that.addClass('layui-form-onswitch');
                    that.html('<em>启用</em>')
                } else {
                    that.removeClass('layui-form-onswitch');
                    that.html('<em>停用</em>')
                }
            })

        });

效果如下

 第二部分,删除操作。

这个页面有两个删除,一个是批量删除,一个单个删除,我们把批量删除和单个删除复用一个删除接口,那么,原来我们写的路由要做个修改了,改成这样

 

打开Category的模型,增加一个方法

public static function del(array $ids)
    {

        return Category::whereIn('id', $ids)->update(['is_del' => 1]);
    }

很简单,就是批量的把is_del的值改为1,这样就标识该条信息被删除了。删除有两种,一种是物理性删除,一种是软删除。很好理解,物理性删除就彻底删除了,表中不再保存该信息了,软删除就是信息还在,但是用状态来表示被删除。laravel/lumen提供了一种软删除操作,它会给表加一个deleted_at字段,如果删除了,deleted_at的值就是删除的日期,用这种方式删除比较好,既可以记录到删除的时间,又能标识该信息被删除。这里我就不做演示,有兴趣的话,可以看软删除

打开Category的控制器,增加一个方法

public function del(Request $request)
    {

        Category::del($request->input('ids'));

        return $this->response->responseJSON();
    }

 非常简单,不做太多介绍。但是这里使用的是批量删除,并没有检查数组中的每一个id是否在数组表中是否存在,在某些业务情况下,是需要检查每一条信息的,那么应该做以下操作:

  1. 检查入参是不是数组
  2. 根据数组中id查询出表中的数据
  3. 查询出的信息条数和入参数组中的id元素数应该相等,并且一一对应,否则是有问题的
  4. 若以上没有问题,再批量删除或者一个一个删除

最后,把模型、控制器、视图的代码发出来。前端代码,相比之前我做了少许修改。

模型代码

<?php


namespace App\Models;


use Illuminate\Database\Eloquent\Model;

class Category extends Model
{

    public function child()
    {
        return $this->hasMany(Category::class, 'parent_id', 'id')
            ->select(['id', 'type', 'parent_id', 'name', 'dir_name', 'pic', 'is_open', 'is_nav', 'sort', 'is_del']);
    }

    public function parent()
    {
        return $this->belongsTo(Category::class, 'parent_id', 'id');
    }

    public static function add(array $data)
    {
        $category = new Category();
        !empty($data['type']) && $category->type = (int)$data['type'];
        !empty($data['parent_id']) && $category->parent_id = (int)$data['parent_id'];
        !empty($data['name']) && $category->name = $data['name'];
        !empty($data['dir_name']) && $category->dir_name = $data['dir_name'];
        !empty($data['pic']) && $category->pic = $data['pic'];
        !empty($data['is_open']) && $category->is_open = $data['is_open'];
        !empty($data['is_nav']) && $category->is_nav = (int)$data['is_nav'];
        !empty($data['sort']) && $category->sort = (int)$data['sort'];
        return $category->save();
    }

    public static function edit(Category $category, array $data)
    {
        !empty($data['type']) && $category->type = (int)$data['type'];
        !empty($data['parent_id']) && $category->parent_id = (int)$data['parent_id'];
        !empty($data['name']) && $category->name = $data['name'];
        !empty($data['dir_name']) && $category->dir_name = $data['dir_name'];
        !empty($data['pic']) && $category->pic = $data['pic'];
        !empty($data['is_open']) && $category->is_open = $data['is_open'];
        !empty($data['is_nav']) && $category->is_nav = (int)$data['is_nav'];
        !empty($data['sort']) && $category->sort = (int)$data['sort'];
        !empty($data['is_del']) && $category->is_del = (int)$data['is_del'];
        return $category->update();

    }

    public static function lists()
    {
        return Category::with('child.child')
            ->select(['id', 'type', 'parent_id', 'name', 'dir_name', 'pic', 'is_nav', 'sort', 'is_del', 'is_open'])
            ->where('parent_id', 0)
            ->where('is_del', 0)
            ->get();
    }

    public static function del(array $ids)
    {

        return Category::whereIn('id', $ids)->update(['is_del' => 1]);
    }

    public static function isOpen(Category $category)
    {
        $category->is_open = !$category->is_open;
        return $category->update();
    }


}

控制器代码

<?php


namespace App\Http\Controllers\Admin;


use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\Category\AddCategory;
use App\Models\Category;
use Illuminate\Http\Request;

class CategoryController extends Controller
{

    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \Illuminate\Validation\ValidationException
     */
    public function add(Request $request)
    {


        // 判断不是不post方式提交数据
        if ($request->post()) {

            // 对新增数据做验证
            $this->validate($request, AddCategory::rules(), AddCategory::msg(), AddCategory::attr());

            // 添加分类
            Category::add($request->input());
            return $this->response->responseJSON();
        }

        return view('admin.category.addCategory');

    }

    /**
     * @param int $id
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse|\Illuminate\View\View
     */
    public function addChild(int $id, Request $request)
    {

        // 同时获取父级的信息
        $category = Category::with('parent')->where('id', $id)->first();
//        if(empty($category->id)){
//            //跳转到错误页面
//        }

        // 判断不是不post方式提交数据
        if ($request->post()) {

            // 添加分类
            Category::add($request->input());
            return $this->response->responseJSON();
        }

        $data['category'] = $category;
        return view('admin.category.addChildCategory', $data);
    }

    /**
     * @param int $id
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function edit(int $id, Request $request)
    {

        $category = Category::where('id', $id)->first();
//        if(empty($category->id)){
//            //跳转到错误页面
//        }

        if ($request->post()) {

            // 添加分类
            Category::edit($category, $request->input());
            return $this->response->responseJSON();
        }

        $data['category'] = $category;
        return view('admin.category.editCategory', $data);
    }

    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function lists(Request $request)
    {

        $data['list'] = Category::lists();
        return view('admin.category.category', $data);
    }

    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function del(Request $request)
    {

        Category::del($request->input('ids'));

        return $this->response->responseJSON();
    }

    /**
     * @param int $id
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function status(int $id, Request $request)
    {

        $category = Category::where('id', $id)->first();
        if (empty($category->id)) {
            $this->response->setMsg(400, '删除的信息不存在');
            return $this->response->responseJSON();
        }


        Category::isOpen($category);

        $this->response->setData(['status' => (int)$category->is_open]);
        return $this->response->responseJSON();
    }
}

视图代码

<!DOCTYPE html>
<html class="x-admin-sm">

<head>
    <meta charset="UTF-8">
    <title>欢迎页面-X-admin2.2</title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport"
          content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi"/>
    <link rel="stylesheet" href="/css/font.css">
    <link rel="stylesheet" href="/css/xadmin.css">
    <script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
    <script src="/lib/layui/layui.js" charset="utf-8"></script>
    <script type="text/javascript" src="/js/xadmin.js"></script>
    <!-- 让IE8/9支持媒体查询,从而兼容栅格 -->
    <!--[if lt IE 9]>
    <script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
    <script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
    <style>
        .input_with {
            width: 500px;
        }
    </style>
</head>

<body>
<div class="x-nav">
            <span class="layui-breadcrumb">
                <a href="/admin/index">首页</a>
                <a>
                    <cite>文章分类</cite></a>
            </span>
    <a class="layui-btn layui-btn-small" style="line-height:1.6em;margin-top:3px;float:right"
       onclick="location.reload()" title="刷新">
        <i class="layui-icon layui-icon-refresh" style="line-height:30px"></i>
    </a>
</div>
<div class="layui-fluid">
    <div class="layui-row layui-col-space15">
        <div class="layui-col-md12">
            <div class="layui-card">

                <div class="layui-card-header">
                    <button class="layui-btn layui-btn-danger" onclick="delAll()">
                        <i class="layui-icon"></i>批量删除
                    </button>
                    <button class="layui-btn" onclick="xadmin.open('增加分类','/admin/category/add',500,500)" lay-submit=""
                            lay-filter="sreach"><i class="layui-icon"></i>增加分类
                    </button>
                </div>


                <div class="layui-card-body ">
                    <table class="layui-table layui-form">
                        <thead>
                        <tr>
                            <th width="20">
                                <input type="checkbox" id="checkbox-all" name="" lay-skin="primary">
                            </th>
                            <th width="70">ID</th>
                            <th>分类名</th>
                            <th width="50">排序</th>
                            <th width="80">状态</th>
                            <th width="250">操作</th>
                        </thead>
                        <tbody class="x-cate">

                        @foreach($list as $value)
                            <tr cate-id='{{ $value['id'] }}' fid='{{ $value['parent_id'] }}'>
                                <td>
                                    <input type="checkbox" name="{{ $value['id'] }}" lay-skin="primary">
                                </td>
                                <td>{{ $value['id'] }}</td>
                                <td>
                                    @if(count($value['child']) > 0)
                                        <i class="layui-icon x-show" status='true'>&#xe623;</i>@else &nbsp; @endif
                                    {{ $value['name'] }}
                                </td>
                                <td><input type="text" class="layui-input x-sort" name="order" value="1"></td>
                                <td>
                                    <input type="checkbox" name="switch" lay-text="开启|停用"
                                           @if($value['is_open'] == 1) checked @endif
                                           lay-skin="switch" id="{{ $value['id'] }}">
                                </td>
                                <td class="td-manage">
                                    <button class="layui-btn layui-btn layui-btn-xs"
                                            onclick="xadmin.open('编辑','/admin/category/edit/{{ $value['id'] }}',500,500)"><i
                                                class="layui-icon">&#xe642;</i>编辑
                                    </button>
                                    <button class="layui-btn layui-btn-warm layui-btn-xs"
                                            onclick="xadmin.open('添加子栏目','/admin/category/addChild/{{ $value['id'] }}',500,500)">
                                        <i class="layui-icon">&#xe642;</i>添加子栏目

                                    </button>
                                    <button class="layui-btn-danger layui-btn layui-btn-xs"
                                            onclick="delOne('{{ $value['id'] }}',this)" href="javascript:;"><i
                                                class="layui-icon">&#xe640;</i>删除
                                    </button>
                                </td>
                            </tr>
                            @foreach($value['child'] as $child)
                                <tr cate-id='{{ $child['id'] }}' fid='{{ $child['parent_id'] }}'>
                                    <td>
                                        <input type="checkbox" name="{{ $child['id'] }}" lay-skin="primary">
                                    </td>
                                    <td>{{ $child['id'] }}</td>
                                    <td>
                                        &nbsp;&nbsp;&nbsp;&nbsp;
                                        @if(count($child['child']) > 0)<i class="layui-icon x-show" status='true'>&#xe623;</i>@else
                                            ├ @endif
                                        {{ $child['name'] }}
                                    </td>
                                    <td><input type="text" class="layui-input x-sort" name="order" value="1"></td>
                                    <td>
                                        <input type="checkbox" name="switch" lay-text="开启|停用"
                                               @if($child['is_open'] == 1) checked @endif
                                               lay-skin="switch" id="{{ $child['id'] }}">
                                    </td>
                                    <td class="td-manage">
                                        <button class="layui-btn layui-btn layui-btn-xs"
                                                onclick="xadmin.open('编辑','/admin/category/edit/{{ $child['id'] }}',500,500)"><i
                                                    class="layui-icon">&#xe642;</i>编辑
                                        </button>
                                        <button class="layui-btn layui-btn-warm layui-btn-xs"
                                                onclick="xadmin.open('添加子栏目','/admin/category/addChild/{{ $child['id'] }}',500,500)">
                                            <i class="layui-icon">&#xe642;</i>添加子栏目
                                        </button>
                                        <button class="layui-btn-danger layui-btn layui-btn-xs"
                                                onclick="delOne('{{ $child['id'] }}',this)" href="javascript:;"><i
                                                    class="layui-icon">&#xe640;</i>删除
                                        </button>
                                    </td>
                                </tr>

                                @foreach($child['child'] as $cd)
                                    <tr cate-id='{{ $cd['id'] }}' fid='{{ $cd['parent_id'] }}'>
                                        <td>
                                            <input type="checkbox" name="{{ $cd['id'] }}" lay-skin="primary">
                                        </td>
                                        <td>{{ $cd['id'] }}</td>
                                        <td>
                                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                                            ├{{ $cd['name'] }}
                                        </td>
                                        <td><input type="text" class="layui-input x-sort" name="order" value="1"></td>
                                        <td>
                                            <input type="checkbox" name="switch" lay-text="开启|停用"
                                                   @if($cd['is_open'] == 1) checked @endif
                                                   lay-skin="switch" id="{{ $cd['id'] }}">
                                        </td>
                                        <td class="td-manage">
                                            <button class="layui-btn layui-btn layui-btn-xs"
                                                    onclick="xadmin.open('编辑','/admin/category/edit/{{ $cd['id'] }}',500,500)">
                                                <i class="layui-icon">&#xe642;</i>编辑
                                            </button>
                                            <button class="layui-btn layui-btn-warm layui-btn-xs"
                                                    onclick="xadmin.open('添加子栏目','/admin/category/addChild/{{ $cd['id'] }}',500,500)">
                                                <i class="layui-icon">&#xe642;</i>添加子栏目
                                            </button>
                                            <button class="layui-btn-danger layui-btn layui-btn-xs"
                                                    onclick="delOne('{{ $cd['id'] }}',this)" href="javascript:;"><i
                                                        class="layui-icon">&#xe640;</i>删除
                                            </button>
                                        </td>
                                    </tr>
                                @endforeach
                            @endforeach
                        @endforeach


                        </tbody>
                    </table>
                </div>

            </div>
        </div>
    </div>
</div>
<script>
    layui.use(['form'], function () {
        form = layui.form;

    });

    /*删除一个*/
    function delOne(id,obj) {
        var ids = [id];
        del(ids);
    }

    function delAll() {
        var ids = [];
        $('tbody .layui-form-checkbox').each(function (i, elm) {
            if ($(this).hasClass('layui-form-checked')) {
                var id = $(this).prev().attr('name');
                ids.push(id);
            }
        });

        console.log(ids);
        del(ids);
    }

    function del(ids, obj) {
        layer.confirm('确认要删除吗?', function (index) {
            $.post('/admin/category/del', {ids: ids}, function (data) {
                console.log(data);
                if (data.code === 200) {
                    if(obj) $(obj).parents("tr").remove();
                    layer.msg('已删除!', {icon: 1, time: 1000});
                } else {
                    layer.msg('已删除失败!', {icon: 1, time: 1000});
                }
            })
        });
    }

    // 分类展开收起的分类的逻辑
    //
    $(function () {
        $("tbody.x-cate tr[fid!='0']").hide();
        // 栏目多级显示效果
        $('.x-show').click(function () {
            if ($(this).attr('status') == 'true') {
                $(this).html('&#xe625;');
                $(this).attr('status', 'false');
                cateId = $(this).parents('tr').attr('cate-id');
                $("tbody tr[fid=" + cateId + "]").show();
            } else {
                cateIds = [];
                $(this).html('&#xe623;');
                $(this).attr('status', 'true');
                cateId = $(this).parents('tr').attr('cate-id');
                getCateId(cateId);
                for (var i in cateIds) {
                    $("tbody tr[cate-id=" + cateIds[i] + "]").hide().find('.x-show').html('&#xe623;').attr('status', 'true');
                }
            }
        });


        $('thead .layui-form-checkbox').on('click', function () {
            if ($(this).hasClass('layui-form-checked')) {
                $('tbody .layui-form-checkbox').addClass('layui-form-checked');
            } else {
                $('tbody .layui-form-checkbox').removeClass('layui-form-checked');
            }
        });


        // 切换开启和停用状态
        $('.layui-form-switch').on('click', function () {

            var that = $(this);
            var id = $(this).prev().attr('id');

            $.post('/admin/category/status/' + id, function (data) {
                console.log(data);
                if (data.data.status === 1) {
                    that.addClass('layui-form-onswitch');
                    that.html('<em>启用</em>')
                } else {
                    that.removeClass('layui-form-onswitch');
                    that.html('<em>停用</em>')
                }
            })

        });


    });

    var cateIds = [];

    function getCateId(cateId) {
        $("tbody tr[fid=" + cateId + "]").each(function (index, el) {
            id = $(el).attr('cate-id');
            cateIds.push(id);
            getCateId(id);
        });
    }

</script>
</body>
</html>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wangpeng52758

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值