laravel框架RBAC增删改查

佟和平
2023-12-01

编写表字段

node表

Schema::create('nodes', function (Blueprint $table) {
       $table->bigIncrements('id');

       $table->string('name',50)->comment('节点名称');
       $table->string('route_name',100)->nullable()->default('')->comment('路由别名,权限认证标识');
       $table->unsignedInteger('pid')->default(0)->comment('上级ID');
       $table->enum('is_menu',['0','1'])->default('0')->comment('是否为菜单0否,1是');

       $table->timestamps();
       $table->softDeletes();
   });

roles角色表

Schema::create('roles', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name','20')->comment('角色名称');
            $table->timestamps();
            // 软删除
            $table->softDeletes();
        });

role_node中间表

 Schema::create('role_node', function (Blueprint $table) {
     // 角色ID
     $table->unsignedInteger('role_id')->default(0)->comment('角色ID');
     // 节点ID
     $table->unsignedInteger('node_id')->default(0)->comment('节点ID');
 });

创建模型层

php artisan make:model Admin\Role
php artisan make:model Admin\Node

编写Node模型层方法

    // 修改器 route_name   RouteName  set字段名Attribute 字段名首字母大写,遇下划线后字母大写
    public function setRouteNameAttribute($value) {
        // 如果字段值为null,则设置为空字符串  修改和添加时生效  create 或 update
        $this->attributes['route_name'] = empty($value) ? '' : $value;
    }

访问器menu

    // 访问器  menu Menu
    public function getMenuAttribute() {
        return $this->is_menu == '1' ? '<span class="label label-success radius">是</span>' : '<span class="label label-danger radius">否</span>';
    }

获取全部数据

    // 获取全部的数据
    public function getAllList() {
        $data = self::get()->toArray();
        return $this->treeLevel($data);
    }

获取层级关系


    /**
     * 获取层级的数据
     * @param $allow_node 用户有的权限
     * @return array
     */
    public function treeData($allow_node) {
        $query = Node::where('is_menu', '1');
        if (is_array($allow_node)) {
            $query->whereIn('id', array_keys($allow_node));
        }
        $menuData = $query->get()->toArray();

        return $this->subTree($menuData);
    }

编写Role模型层方法

    // 角色与权限  多对多
    public function nodes() {
        // 参1 关联模型
        // 参2 中间表的表名,没有前缀
        // 参3 本模型对应的外键ID
        // 参4 关联模型对应的外键ID
        return $this->belongsToMany(Node::class,'role_node','role_id','node_id');
    }

创建控制器

php artisan make:controller RoleController  --resource
php artisan make:controller NodeController  --resource

编写RoleController 方法

节点列表

    /**
     * 节点列表
     */
    public function index() {
        // 获取所有的节点 返回是数组
        $data =(new Node)->getAllList();
        return view('admin.node.index', compact('data'));
    }

添加

    public function create() {
        // 获取所有的顶部
        $data = Node::where('pid', 0)->get();
        return view('admin.node.create', compact('data'));
    }

添加处理

    public function store(Request $request) {
        // 表单验证
        // try() catch()
        // 入库
        /*$data = $request->except('_token');
        $data['route_name'] = empty()*/
        Node::create($request->except('_token'));
        return ['status' => 0, 'msg' => '添加权限成功'];
    }

编写RoleController方法

列表

    /**
     * 列表
     */
    public function index(Request $request) {
        // 获取搜索框
        $name = $request->get('name', '');

        // 分页 搜索
        // 参数1, 变量值存在。则执行 参数2--->匿名函数
        $data = Role::when($name, function ($query) use ($name) {
            $query->where('name', 'like', "%{$name}%");
        })->paginate($this->pagesize);
        return view('admin.role.index', compact('data', 'name'));
    }

添加显示

    /**
     * 添加显示
     */
    public function create() {

        return view('admin.role.create');
    }

添加处理

    /**
     * 添加处理
     */
    public function store(Request $request) {
        // 异常处理
        try {
            $this->validate($request, [
                'name' => 'required|unique:roles,name'
            ]);
        } catch (\Exception $e) {
            return ['status' => 1000, 'msg' => '验证不通过'];
        }
        // 接受 all 接受所有的数据
        Role::create($request->only('name'));

        return ['status' => 0, 'msg' => '添加角色成功'];
    }

修改显示

    /**
     * 修改显示
     */
    public function edit(int $id) {
        $model = Role::find($id);
        return view('admin.role.edit', compact('model'));
    }

修改处理

/**
     * 修改处理
     */
    public function update(Request $request, int $id) {
        // 异常处理
        try {
            $this->validate($request, [
                // unique:表名,唯一字段,[排除行的值,以那个字段来排除]
                // 排除id=3的哪行名为name的字段值
                'name' => 'required|unique:roles,name,' . $id . ',id'
            ]);
        } catch (\Exception $e) {
            return ['status' => 1000, 'msg' => '验证不通过'];
        }
        // 修改角色入库
        //Role::where('id', $id)->update($request->only(['name']));
        Role::where([['id', '=', $id]])->update($request->only(['name']));
        return ['status' => 0, 'msg' => '修改用户成功'];
    }

给角色分配权限

   public function node(Role $role) {
        //dump($role->nodes->toArray());
        //dump($role->nodes()->pluck('name','id')->toArray());
        // 读取出所有的权限
        $nodeAll = (new Node())->getAllList();
        // 读取当前角色所拥有的权限
        $nodes = $role->nodes()->pluck('id')->toArray();

        return view('admin.role.node',compact('role','nodeAll','nodes'));
    }

分配处理

    public function nodeSave(Request $request,Role $role) {
        // 关联模型的数据同步
        $role->nodes()->sync($request->get('node'));
        return redirect(route('admin.role.node',$role));
    }

编写路由

        // 角色管理
        // 分配权限
        Route::get('role/node/{role}', 'RoleController@node')->name('role.node');
        Route::post('role/node/{role}', 'RoleController@nodeSave')->name('role.node');
        // 资源路由 /admin/role/xxx
        Route::resource('role', 'RoleController');

        // 节点管理
        Route::resource('node', 'NodeController');

其中用到的视图层,可以自己写,我这里用的H-ui里的视图,可以供大家测试一下!
role中的视图
index

@extends('admin.common.main')


@section('cnt')
    <nav class="breadcrumb">
        <i class="Hui-iconfont">&#xe67f;</i> 首页
        <span class="c-gray en">&gt;</span> 用户中心
        <span class="c-gray en">&gt;</span> 权限列表
        <a class="btn btn-success radius r" style="line-height:1.6em;margin-top:3px" href="javascript:location.replace(location.href);" title="刷新"><i class="Hui-iconfont">&#xe68f;</i></a>
    </nav>
    {{-- 消息提示 --}}
    @include('admin.common.msg')

    <div class="page-container">
        <form method="get" class="text-c"> 输入想要搜索的角色名称:
            <input type="text" class="input-text" style="width:250px" placeholder="角色" value="{{ $name }}" name="name" autocomplete="off">
            <button type="submit" class="btn btn-success radius"><i class="Hui-iconfont">&#xe665;</i> 搜角色</button>
        </form>
        <div class="cl pd-5 bg-1 bk-gray mt-20">
        <span class="l">
            <a href="{{ route('admin.role.create') }}" class="btn btn-primary radius">
                <i class="Hui-iconfont">&#xe600;</i> 添加角色
            </a>
        </span>
        </div>
        <div class="mt-20">
            <table class="table table-border table-bordered table-hover table-bg table-sort">
                <thead>
                <tr class="text-c">
                    <th width="80">ID</th>
                    <th width="100">角色名称</th>
                    <th width="100">查看权限</th>
                    <th width="130">加入时间</th>
                    <th width="100">操作</th>
                </tr>
                </thead>
                <tbody>
                @foreach($data as $item)
                    <tr class="text-c">
                        <td>{{ $item->id }}</td>
                        <td>{{ $item->name }}</td>
                        <td>
                            <a class="label label-success radius" href="{{ route('admin.role.node',$item) }}">权限</a>
                        </td>
                        <td>{{ $item->created_at }}</td>
                        <td class="td-manage">
                            <a href="{{ route('admin.role.edit',$item) }}" class="label label-secondary radius">修改</a>
                            <a href="{{ route('admin.role.destroy',['id'=>$item->id]) }}" class="label label-warning radius">删除</a>
                        </td>
                    </tr>
                @endforeach
                </tbody>
            </table>
            {{-- 分页 支持搜索功能 --}}
            {{ $data->appends(request()->except('page'))->links() }}
        </div>
    </div>
@endsection
@section('js')
    <!--请在下方写此页面业务相关的脚本-->
    <script type="text/javascript" src="/admin/lib/My97DatePicker/4.8/WdatePicker.js"></script>
    <script type="text/javascript" src="/admin/lib/datatables/1.10.0/jquery.dataTables.min.js"></script>
    <script type="text/javascript" src="/admin/lib/laypage/1.2/laypage.js"></script>
    <script>
      // 生成一个token crsf
      const _token = "{{ csrf_token() }}";
      // 给删除按钮绑定事件
      $('.delbtn').click(function (evt) {
        // 得到请求的url地址
        let url = $(this).attr('href');
        // 发起一个delete请求
        $.ajax({
          url,
          data: {_token},
          type: 'DELETE',
          dataType: 'json'
        }).then(({status, msg}) => {
          if (status == 0) {
            // 提示插件
            layer.msg(msg, {time: 2000, icon: 1}, () => {
              // 删除当前行
              $(this).parents('tr').remove();
            });
          }
        });
        // jquery取消默认事件
        return false;
      });

      // 全选删除
      function deleteAll() {
        // 询问框
        layer.confirm('您是真的要删除选中的用户吗?', {
          btn: ['确认删除', '思考一下']
        }, () => {
          // 选中的用户
          let ids = $('input[name="id[]"]:checked');
          // 删除的ID
          let id = [];
          // 循环
          $.each(ids, (key, val) => {
            // dom对象 转为 jquery对象 $(dom对象)
            // id.push($(val).val());
            id.push(val.value);
          });
          if (id.length > 0) {
            // 发起ajax
            $.ajax({
              url: "{{ route('admin.user.delall') }}",
              data: {id, _token},
              type: 'DELETE'
            }).then(ret => {
              if (ret.status == 0) {
                layer.msg(ret.msg, {time: 2000, icon: 1}, () => {
                  location.reload();
                })
              }
            })
          }
        });
      }
    </script>
@endsection

edit

@extends('admin.common.main')

@section('cnt')
    <nav class="breadcrumb">
        <i class="Hui-iconfont">&#xe67f;</i> 首页
        <span class="c-gray en">&gt;</span> 用户中心
        <span class="c-gray en">&gt;</span> 修改角色
        <a class="btn btn-success radius r" style="line-height:1.6em;margin-top:3px" href="javascript:location.replace(location.href);" title="刷新"><i class="Hui-iconfont">&#xe68f;</i></a>
    </nav>
    <article class="page-container">
        <form action="{{ route('admin.role.update',$model) }}" method="post" class="form form-horizontal" id="form-member-add">
            {{--@method('put')--}}
            @csrf
            <div class="row cl">
                <label class="form-label col-xs-4 col-sm-3"><span class="c-red">*</span>角色名称:</label>
                <div class="formControls col-xs-8 col-sm-9">
                    <input type="text" class="input-text" name="name" value="{{ $model->name }}">
                </div>
            </div>
            <div class="row cl">
                <div class="col-xs-8 col-sm-9 col-xs-offset-4 col-sm-offset-3">
                    <input class="btn btn-primary radius" type="submit" value="修改角色">
                </div>
            </div>
        </form>
    </article>
@endsection

@section('js')
    <script type="text/javascript" src="/admin/lib/jquery.validation/1.14.0/jquery.validate.js"></script>
    <script type="text/javascript" src="/admin/lib/jquery.validation/1.14.0/validate-methods.js"></script>
    <script type="text/javascript" src="/admin/lib/jquery.validation/1.14.0/messages_zh.js"></script>
    <script>
      // 前端表单验证
      // https://www.runoob.com/jquery/jquery-plugin-validate.html
      $("#form-member-add").validate({
        // 规则
        rules: {
          // 表单元素名称
          name: {
            // 验证规则
            required: true
          }
        },
        // 取消键盘事件
        onkeyup: false,
        // 验证成功后的样式
        success: "valid",
        // 验证通过后,处理的方法 form dom对象
        submitHandler: function (form) {
          // 表单提交地址
          let url = $(form).attr('action');
          // 表单序列化   _token=aaa&name=fewflew
          let data = $(form).serialize();

          // jquery put提交
          $.ajax({
            url,
            data,
            type: 'PUT'
          }).then(({status, msg}) => {
            if (status == 0) {
              layer.msg(msg, {icon: 1, time: 2000}, () => {
                location.href = "{{ route('admin.role.index') }}";
              })
            } else {
              layer.msg(msg, {icon: 2, time: 2000});
            }
          });
        }
      });
    </script>

@endsection


node

@extends('admin.common.main')

@section('cnt')
    <nav class="breadcrumb">
        <i class="Hui-iconfont">&#xe67f;</i> 首页
        <span class="c-gray en">&gt;</span> 用户中心
        <span class="c-gray en">&gt;</span> 给角色分配权限
        <a class="btn btn-success radius r" style="line-height:1.6em;margin-top:3px" href="javascript:location.replace(location.href);" title="刷新"><i class="Hui-iconfont">&#xe68f;</i></a>
    </nav>
    <article class="page-container">
        <form action="{{ route('admin.role.node',$role) }}" method="post" class="form form-horizontal" id="form-member-add">
            @csrf
            @foreach($nodeAll as $item)
            <div>
                <input type="checkbox" name="node[]" value="{{ $item['id'] }}"
                @if(in_array($item['id'],$nodes)) checked @endif
                >
                {{ $item['html'] }}{{ $item['name'] }}
            </div>
            @endforeach


            <div class="row cl">
                <div class="col-xs-8 col-sm-9 col-xs-offset-4 col-sm-offset-3">
                    <input class="btn btn-primary radius" type="submit" value="分配权限">
                </div>
            </div>
        </form>
    </article>
@endsection

@section('js')
@endsection


create

@extends('admin.common.main')

@section('cnt')
    <nav class="breadcrumb">
        <i class="Hui-iconfont">&#xe67f;</i> 首页
        <span class="c-gray en">&gt;</span> 用户中心
        <span class="c-gray en">&gt;</span> 添加角色
        <a class="btn btn-success radius r" style="line-height:1.6em;margin-top:3px" href="javascript:location.replace(location.href);" title="刷新"><i class="Hui-iconfont">&#xe68f;</i></a>
    </nav>
    <article class="page-container">
        <form action="{{ route('admin.role.store') }}" method="post" class="form form-horizontal" id="form-member-add">
            @csrf
            <div class="row cl">
                <label class="form-label col-xs-4 col-sm-3"><span class="c-red">*</span>角色名称:</label>
                <div class="formControls col-xs-8 col-sm-9">
                    <input type="text" class="input-text" name="name" autocomplete="off">
                </div>
            </div>
            <div class="row cl">
                <div class="col-xs-8 col-sm-9 col-xs-offset-4 col-sm-offset-3">
                    <input class="btn btn-primary radius" type="submit" value="添加角色">
                </div>
            </div>
        </form>
    </article>
@endsection

@section('js')
    <script type="text/javascript" src="/admin/lib/jquery.validation/1.14.0/jquery.validate.js"></script>
    <script type="text/javascript" src="/admin/lib/jquery.validation/1.14.0/validate-methods.js"></script>
    <script type="text/javascript" src="/admin/lib/jquery.validation/1.14.0/messages_zh.js"></script>
    <script>
      // 前端表单验证
      // https://www.runoob.com/jquery/jquery-plugin-validate.html
      $("#form-member-add").validate({
        // 规则
        rules: {
          // 表单元素名称
          name: {
            // 验证规则
            required: true
          }
        },
        // 取消键盘事件
        onkeyup: false,
        // 验证成功后的样式
        success: "valid",
        // 验证通过后,处理的方法 form dom对象
        submitHandler: function (form) {
          // 表单提交地址
          let url = $(form).attr('action');
          // 表单序列化   _token=aaa&name=fewflew
          let data = $(form).serialize();

          // jquery post提交
          $.post(url,data).then(({status,msg})=>{
            if(status == 0){
              layer.msg(msg,{icon:1,time:2000},()=>{
                location.href = "{{ route('admin.role.index') }}";
              })
            }else{
              layer.msg(msg,{icon:2,time:2000});
            }
          })
        }
      });
    </script>

@endsection


node中视图层
create

@extends('admin.common.main')

@section('cnt')
    <nav class="breadcrumb">
        <i class="Hui-iconfont">&#xe67f;</i> 首页
        <span class="c-gray en">&gt;</span> 用户中心
        <span class="c-gray en">&gt;</span> 添加节点
        <a class="btn btn-success radius r" style="line-height:1.6em;margin-top:3px" href="javascript:location.replace(location.href);" title="刷新"><i class="Hui-iconfont">&#xe68f;</i></a>
    </nav>
    <article class="page-container">
        {{-- 表单验证提示 --}}
        @include('admin.common.validate')

        <form action="{{ route('admin.node.store') }}" method="post" class="form form-horizontal" @submit.prevent="dopost">
            <div class="row cl">
                <label class="form-label col-xs-4 col-sm-3"><span class="c-red">*</span>是否顶级:</label>
                <div class="formControls col-xs-8 col-sm-9">
                    <span class="select-box">
                        <select class="select" @change="changePid">
                            <option value="0">==顶级==</option>
                            @foreach($data as $item)
                                <option value="{{ $item->id }}">{{ $item->name }}</option>
                            @endforeach
                        </select>
                    </span>
                </div>
            </div>
            <div class="row cl">
                <label class="form-label col-xs-4 col-sm-3"><span class="c-red">*</span>节点名称:</label>
                <div class="formControls col-xs-8 col-sm-9">
                    <!--- lazy 延时绑定 -->
                    <input type="text" class="input-text" name="name" v-model.lazy="info.name">
                </div>
            </div>
            <div class="row cl">
                <label class="form-label col-xs-4 col-sm-3">路由别名:</label>
                <div class="formControls col-xs-8 col-sm-9">
                    <input type="text" class="input-text" name="route_name" v-model="info.route_name">
                </div>
            </div>
            <div class="row cl">
                <label class="form-label col-xs-4 col-sm-3"><span class="c-red">*</span>是否菜单:</label>
                <div class="formControls col-xs-8 col-sm-9 skin-minimal">
                    <div class="radio-box">
                        <input type="radio" value="0" v-model="info.is_menu">
                        <label for="sex-1">否</label>
                    </div>
                    <div class="radio-box">
                        <input type="radio" value="1" v-model="info.is_menu">
                        <label for="sex-2">是</label>
                    </div>
                </div>
            </div>
            <div class="row cl">
                <div class="col-xs-8 col-sm-9 col-xs-offset-4 col-sm-offset-3">
                    <input class="btn btn-primary radius" type="submit" value="添加节点">
                </div>
            </div>
        </form>
    </article>
@endsection

@section('js')
    <script src="/js/vue.js"></script>
    <script>
      new Vue({
        el: '.page-container',
        data: {
          info: {
            _token: "{{ csrf_token() }}",
            pid: 0,
            name: '',
            route_name: '',
            is_menu: 0
          }
        },
        methods: {
          /*dopost(evt) {
            //console.log(evt.target.action);
            //console.log(evt.target.getAttribute('action'));
            let url = evt.target.action;
            $.post(url, this.info).then(ret => {
              console.log(ret);
            })
          }*/
          // 异步变同步 es7 async await
          async dopost(evt) {
            let url = evt.target.action;
            let {status, msg} = await $.post(url, this.info);
            if (status === 0) {
              location.href = "{{ route('admin.node.index') }}";
            } else {
              layer.msg(msg, {icon: 2, time: 1000});
            }
          },
          // 下拉
          changePid(evt) {
            console.log(evt.target.value);
            // 下拉的值 evt.target select 的dom对象
            this.info.pid = evt.target.value || 0;
          }
        }
      });


    </script>

@endsection


index

@extends('admin.common.main')


@section('cnt')
    <nav class="breadcrumb">
        <i class="Hui-iconfont">&#xe67f;</i> 首页
        <span class="c-gray en">&gt;</span> 用户中心
        <span class="c-gray en">&gt;</span> 节点列表
        <a class="btn btn-success radius r" style="line-height:1.6em;margin-top:3px" href="javascript:location.replace(location.href);" title="刷新"><i class="Hui-iconfont">&#xe68f;</i></a>
    </nav>
    {{-- 消息提示 --}}
    @include('admin.common.msg')

    <div class="page-container">
        <form method="get" class="text-c"> 输入想要搜索的权限名称:
            <input type="text" class="input-text" style="width:250px" placeholder="节点" value="{{ request()->get('name') }}" name="name" autocomplete="off">
            <button type="submit" class="btn btn-success radius"><i class="Hui-iconfont">&#xe665;</i> 搜节点</button>
        </form>
        <div class="cl pd-5 bg-1 bk-gray mt-20">
        <span class="l">
            <a href="{{ route('admin.node.create') }}" class="btn btn-primary radius">
                <i class="Hui-iconfont">&#xe600;</i> 添加节点
            </a>
        </span>
        </div>
        <div class="mt-20">
            <table class="table table-border table-bordered table-hover table-bg table-sort">
                <thead>
                <tr class="text-c">
                    <th width="80">ID</th>
                    <th width="100">节点名称</th>
                    <th width="100">路由别名</th>
                    <th width="100">是否菜单</th>
                    <th width="130">加入时间</th>
                    <th width="100">操作</th>
                </tr>
                </thead>
                <tbody>
                @foreach($data as $item)
                    <tr class="text-c">
                        <td>{{ $item['id'] }}</td>
                        <td class="text-l">
                            {{ $item['html'] }}
                            {{ $item['name'] }}</td>
                        <td>{{ $item['route_name'] }}</td>
                        <td>
                            {{-- html解析输出 --}}
                            {{--@{{ 解决vue符号冲突问题 }} --}}
                            {{--{!! $item['menu'] !!} --}}
                            @if($item['is_menu'])
                                <span class="label label-success radius">是</span>
                            @else
                                <span class="label label-danger radius">否</span>
                            @endif
                        </td>
                        <td>{{ $item['created_at'] }}</td>
                        <td class="td-manage">
                            <a href="{{ route('admin.node.edit',['id'=>$item['id']]) }}" class="label label-secondary radius">修改</a>
                            <a href="{{ route('admin.node.destroy',['id'=>$item['id']]) }}" class="label label-warning radius">删除</a>
                        </td>
                    </tr>
                @endforeach
                </tbody>
            </table>
        </div>
    </div>
@endsection
@section('js')
    <!--请在下方写此页面业务相关的脚本-->
    <script type="text/javascript" src="/admin/lib/My97DatePicker/4.8/WdatePicker.js"></script>
    <script type="text/javascript" src="/admin/lib/datatables/1.10.0/jquery.dataTables.min.js"></script>
    <script type="text/javascript" src="/admin/lib/laypage/1.2/laypage.js"></script>
    <script>
    </script>
@endsection

edit

@extends('admin.common.main')

@section('cnt')
    <nav class="breadcrumb">
        <i class="Hui-iconfont">&#xe67f;</i> 首页
        <span class="c-gray en">&gt;</span> 用户中心
        <span class="c-gray en">&gt;</span> 修改用户
        <a class="btn btn-success radius r" style="line-height:1.6em;margin-top:3px" href="javascript:location.replace(location.href);" title="刷新"><i class="Hui-iconfont">&#xe68f;</i></a>
    </nav>
    <article class="page-container">
        {{-- 表单验证提示 --}}
        @include('admin.common.validate')

        <form action="{{ route('admin.user.edit',$model) }}" method="post" class="form form-horizontal" id="form-member-add">
            {{--{{ method_field('PUT') }}--}}
            {{-- 让表单模拟put提交 --}}
            @method('PUT')
            @csrf

            <div class="row cl">
                <label class="form-label col-xs-4 col-sm-3"><span class="c-red">*</span>姓名:</label>
                <div class="formControls col-xs-8 col-sm-9">
                    <input type="text" class="input-text" name="truename" value="{{ $model->truename }}">
                </div>
            </div>
            <div class="row cl">
                <label class="form-label col-xs-4 col-sm-3">账号:</label>
                <div class="formControls col-xs-8 col-sm-9">
                    {{ $model->username }}
                </div>
            </div>
            <div class="row cl">
                <label class="form-label col-xs-4 col-sm-3"><span class="c-red">*</span>原密码:</label>
                <div class="formControls col-xs-8 col-sm-9">
                    <input type="text" class="input-text" name="spassword" autocomplete="off">
                </div>
            </div>
            <div class="row cl">
                <label class="form-label col-xs-4 col-sm-3">密码:</label>
                <div class="formControls col-xs-8 col-sm-9">
                    <input type="text" class="input-text" name="password" id="password" autocomplete="off">
                </div>
            </div>
            <div class="row cl">
                <label class="form-label col-xs-4 col-sm-3">确认密码:</label>
                <div class="formControls col-xs-8 col-sm-9">
                    <input type="text" class="input-text" name="password_confirmation" autocomplete="off">
                </div>
            </div>
            <div class="row cl">
                <label class="form-label col-xs-4 col-sm-3"><span class="c-red">*</span>性别:</label>
                <div class="formControls col-xs-8 col-sm-9 skin-minimal">
                    <div class="radio-box">
                        <input name="sex" type="radio" value="先生" checked>
                        <label for="sex-1">先生</label>
                    </div>
                    <div class="radio-box">
                        <input type="radio" value="女士" name="sex">
                        <label for="sex-2">女士</label>
                    </div>
                </div>
            </div>
            <div class="row cl">
                <label class="form-label col-xs-4 col-sm-3"><span class="c-red">*</span>手机:</label>
                <div class="formControls col-xs-8 col-sm-9">
                    <input type="text" class="input-text" name="phone" value="{{ $model->phone }}">
                </div>
            </div>
            <div class="row cl">
                <label class="form-label col-xs-4 col-sm-3"><span class="c-red">*</span>邮箱:</label>
                <div class="formControls col-xs-8 col-sm-9">
                    <input type="email" class="input-text" name="email" value="{{ $model->email }}">
                </div>
            </div>
            <div class="row cl">
                <div class="col-xs-8 col-sm-9 col-xs-offset-4 col-sm-offset-3">
                    <input class="btn btn-primary radius" type="submit" value="修改用户">
                </div>
            </div>
        </form>
    </article>
@endsection

@section('js')
    <script type="text/javascript" src="/admin/lib/jquery.validation/1.14.0/jquery.validate.js"></script>
    <script type="text/javascript" src="/admin/lib/jquery.validation/1.14.0/validate-methods.js"></script>
    <script type="text/javascript" src="/admin/lib/jquery.validation/1.14.0/messages_zh.js"></script>

    <script>
      // 单选框样式
      $('.skin-minimal input').iCheck({
        checkboxClass: 'icheckbox-blue',
        radioClass: 'iradio-blue',
        increaseArea: '20%'
      });

      // 前端表单验证
      // https://www.runoob.com/jquery/jquery-plugin-validate.html
      $("#form-member-add").validate({
        // 规则
        rules: {
          // 表单元素名称
          truename: {
            // 验证规则
            required: true
          },
          spassword:{
            required:true
          },
          password_confirmation: {
            // 两次密码一致写法有点点不一样 用的是和谁一致的ID名称
            equalTo: '#password'
          },
          email: {
            email: true
          },
          phone: {
            phone: true
          }
        },
        // 消息提示
        messages: {
          truename: {
            required: '真实的名称必须要写,不能不写'
          }
        },
        // 取消键盘事件
        onkeyup: false,
        // 验证成功后的样式
        success: "valid",
        // 验证通过后,处理的方法 form dom对象
        submitHandler: function (form) {
          // 表单提交
          form.submit();
        }
      });

      // 自定义验证规则
      // 邮政编码验证
      jQuery.validator.addMethod("phone", function (value, element) {
        +86 - 12345
        var reg1 = /^\+86-1[3-9]\d{9}$/;
        var reg2 = /^1[3-9]\d{9}$/;
        var ret = reg1.test(value) || reg2.test(value);
        return this.optional(element) || ret;
      }, "请输入正确的手机号码");


    </script>

@endsection


文章视图

@extends('admin.common.main')

@section('cnt')
    <nav class="breadcrumb">
        <i class="Hui-iconfont">&#xe67f;</i> 首页
        <span class="c-gray en">&gt;</span> 文章管理
        <span class="c-gray en">&gt;</span> 文章列表
        <a class="btn btn-success radius r" style="line-height:1.6em;margin-top:3px" href="javascript:location.replace(location.href);" title="刷新"><i class="Hui-iconfont">&#xe68f;</i></a>
    </nav>
    {{-- 消息提示 --}}
    @include('admin.common.msg')

    <div class="page-container">
        <form method="get" class="text-c" onsubmit="return dopost()">
            <input type="text" onfocus="WdatePicker({ maxDate:'#F{$dp.$D(\'datemax\')||\'%y-%M-%d\'}' })" id="datemin" class="input-text Wdate" style="width:120px;">
            -
            <input type="text" onfocus="WdatePicker({ minDate:'#F{$dp.$D(\'datemin\')}',maxDate:'%y-%M-%d' })" id="datemax" class="input-text Wdate" style="width:120px;">
            文章标题:
            <input type="text" class="input-text" style="width:250px" placeholder="文章标题" value="{{ request()->get('title') }}" id="title" autocomplete="off">
            <button type="submit" class="btn btn-success radius"><i class="Hui-iconfont">&#xe665;</i> 搜索文章</button>
        </form>
        <div class="cl pd-5 bg-1 bk-gray mt-20">
        <span class="l">
            <a href="{{ route('admin.article.create') }}" class="btn btn-primary radius">
                <i class="Hui-iconfont">&#xe600;</i> 添加文章
            </a>
        </span>
        </div>
        <div class="mt-20">
            <table class="table table-border table-bordered table-hover table-bg table-sort">
                <thead>
                <tr class="text-c">
                    <th width="80">ID</th>
                    <th width="100">文章标题</th>
                    <th width="130">加入时间</th>
                    <th width="100">操作</th>
                </tr>
                </thead>
            </table>
        </div>
    </div>
@endsection
@section('js')
    <script>
      // 列表显示
      var dataTable = $('.table-sort').DataTable({
        // 下接的分页数量
        lengthMenu: [5, 10, 15, 20, 100],
        // 隐藏搜索
        searching: false,
        columnDefs: [
          // 索引第3列,不进行排序
          {targets: [3], orderable: false}
        ],
        // 开启服务器端分页 开启ajax
        serverSide: true,
        // 进行ajax请求
        ajax: {
          // 请求地址
          url: '{{ route('admin.article.index') }}',
          // 请求方式
          type: 'get',
          // 参数 动态获取表单数据用 function
          data: function (ret) {
            ret.datemin = $('#datemin').val();
            ret.datemax = $('#datemax').val();
            ret.title = $.trim($('#title').val());
          }
        },
        // 指定每一列显示的数据
        columns: [
          //{'data': '字段名称1', "defaultContent": "默认值", 'className': '类名'},
          {data: 'id', className: 'text-c'},
          {data: 'title'},
          {data: 'created_at'},
          {data: 'aaa', defaultContent: '默认值'}
        ],
        // 回调方法
        // row 当前行的dom对象
        // 当前行的数据
        // 当前行的数据索引
        createdRow: function (row, data, dataIndex) {
          // 当前id
          var id = data.id;
          // 行的最后一列
          var td = $(row).find('td:last-child');
          // 显示的html内容
          var html = `
            <a href="/admin/article/${id}/edit" class="label label-secondary radius">修改</a>
            <a href="/admin/article/${id}" onclick="return delArticle(event,this)" class="label label-warning radius">删除</a>
          `;
          // html添加到td中
          td.html(html);
        }
      });

      // 表单提交
      function dopost() {
        // 手动调用一次dataTable插件请求
        dataTable.ajax.reload();
        // 取消表单默认行为
        return false;
      }

      // 删除
      function delArticle2(obj) {
        // 请求的URL地址
        let url = $(obj).attr('href');
        // 发起ajax
        /*let ret = fetch(url, {
          method: 'delete',
          headers: {
            'X-CSRF-TOKEN': '{{csrf_token()}}'
          },
          body:'aa=bb&id=1'
        });
        ret.then(res=>{
          // 文本 promise
          //console.log(res.text());
          // json对象
          res.json().then(data=>console.log(data))
        })*/

        // 原生的,浏览自带
        fetch(url, {
          method: 'delete',
          headers: {
            'X-CSRF-TOKEN': '{{csrf_token()}}'
          },
          body: 'aa=bb&id=1'
        }).then(res => {
          return res.json();
        }).then(data => {
          console.log(data)
        });
        // 取消默认行为
        return false;
      }

      // async await  promise  异步变同步
      async function delArticle(evt, obj) {
        evt.preventDefault();
        // 请求的URL地址
        let url = $(obj).attr('href');
        // 发起ajax
        // 原生的,浏览自带
        let ret = await fetch(url, {
          method: 'delete',
          headers: {
            'X-CSRF-TOKEN': '{{csrf_token()}}'
          }
        });
        let json = await ret.json();
        console.log(json);
        // 取消默认行为
        return false;
      }
    </script>
@endsection

转载至https://blog.csdn.net/nanlula/article/details/109456324

 类似资料: