laravel文章增删改查

创建文章模型层

php artisan make:model Models/Article

继承Base

class Article extends Base {
    
    
    // 追加一个字段 集合访问器
    protected $appends = ['action'];

    // 访问器
    public function getActionAttribute() {
    
    
        return $this->editBtn('admin.article.edit').' '.$this->deleteBtn('admin.article.destroy');
    }
}

创建资源控制器

php artisan make:controller ArticleController

列表展示

  public function index(Request $request) {
    
    

        if ($request->header('X-Requested-With') == 'XMLHttpRequest') {
    
       // ajax请求

            // 排序
            //['column' => $column, 'dir' => $dir] = $request->get('order')[0];

            $orderArr = $request->get('order')[0];
            // 排序索引
            $column = $orderArr['column'];
            // 排序类型 升还是降
            $dir = $orderArr['dir'];
            // 排序字段
            $orderField = $request->get('columns')[$column]['data'];

            // 开启位置
            $start = $request->get('start', 0);
            // 开启时间
            $datemin = $request->get('datemin');
            // 结束时间
            $datemax = $request->get('datemax');
            // 搜索关键字
            $title = $request->get('title');

            // 查询对象
            $query = Article::where('id', '>', 0);
            // 日期
            if (!empty($datemin) && !empty($datemax)) {
    
    
                // 开始时间
                $datemin = date('Y-m-d H:i:s', strtotime($datemin . ' 00:00:00'));
                // 结束时间
                $datemax = date('Y-m-d H:i:s', strtotime($datemax . ' 23:59:59'));

                $query->whereBetween('created_at', [$datemin, $datemax]);
            }
            // 搜索关键词
            if (!empty($title)) {
    
    
                $query->where('title', 'like', "%{
      
      $title}%");
            }

            // 获取记录数
            $length = min(100, $request->get('length', 10));
            // 记录总数
            $total = $query->count();

            // 获取数据
            $data = $query->orderBy($orderField, $dir)->offset($start)->limit($length)->get();
            /*
            draw: 客户端调用服务器端次数标识
            recordsTotal: 获取数据记录总条数
            recordsFiltered: 数据过滤后的总数量
            data: 获得的具体数据
            注意:recordsTotal和recordsFiltered都设置为记录的总条数
            */
            $result = [
                'draw' => $request->get('draw'),
                'recordsTotal' => $total,
                'recordsFiltered' => $total,
                'data' => $data
            ];
            return $result;


        }
        // 取出所有的文章数据
        //$data = Article::all();

        return view('admin.article.index');


    }

添加文章显示

    public function create() {
    
    

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

图片上传

    public function upfile(Request $request) {
    
    
        // 封面图片
        $pic = config('up.pic');
        if ($request->hasFile('file')) {
    
    
            // 上传
            // 参数2 配置的节点名称
            $ret = $request->file('file')->store('', 'article');
            $pic = '/uploads/article/' . $ret;
        }
        return ['status' => 0, 'url' => $pic];
    }

添加处理

    public function store(AddArtRequest $request) {
    
    
        // 文件上传
        $post = $request->except(['_token', 'file']);
        // 添加到数据库
        Article::create($post);
        return redirect(route('admin.article.index'));
    }

文章修改展示


    /**
     * 文章修改显示
     */
    public function edit(Article $article) {
    
    
        return view('admin.article.edit', compact('article'));
    }

修改处理

    /**
     * 修改处理
     */
    public function update(Request $request, Article $article) {
    
    

        return $request->all();
        exit;

        $putData = $request->except(['action', 'created_at', 'updated_at', 'deleted_at', 'id']);
        $article->update($putData);
        return ['status'=>0,'url'=>route('admin.article.index')];
    }

文章删除

    // 删除
    public function destroy(Article $article) {
    
    
        // 软删除
        $article->delete();

        return ['id' => 1];
    }

编写视图层

@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

修改视图层

@extends('admin.common.main')

@section('css')
    {
    
    {
    
    -- webuploader上传样式 --}}
    <link rel="stylesheet" type="text/css" href="/webuploader/webuploader.css"/>
@endsection
@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.article.update',$article) }}" ref="frm" class="form form-horizontal">
            <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="title" v-model="info.title">
                </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="desn" v-model="info.desn">
                </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-4 col-sm-5">
                    <!-- 表单提交时的封面地址 -->
                    <input type="hidden" name="pic" id="pic" v-model="info.pic">
                    <div id="picker">上传文章封面</div>
                </div>
                <div class="formControls col-xs-4 col-sm-4">
                    <img :src="info.pic" id="img" style="width: 100px;">
                </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">
                    <textarea name="body" id="body" cols="30" rows="10"></textarea>
                </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="button" @click="dopost" value="修改文章">
                </div>
            </div>
        </form>
    </article>
@endsection
@section('js')
    <!-- 引入vue -->
    <script src="/js/vue.js"></script>

    <!-- webuploader上传js -->
    <script type="text/javascript" src="/webuploader/webuploader.js"></script>
    <!-- 配置文件 -->
    <script type="text/javascript" src="/ueditor/ueditor.config.js"></script>
    <!-- 编辑器源码文件 -->
    <script type="text/javascript" src="/ueditor/ueditor.all.js"></script>

    <!-- 实例化编辑器 -->
    <script>
      //vue管理
      new Vue({
    
    
        el: '.page-container',
        data: {
    
    
          info:{
    
    !! $article !!}
        },
        // 组件挂载完毕
        mounted() {
    
    
          // 富文本编辑器
          this.editor = UE.getEditor('body', {
    
    
            initialFrameHeight: 200
          });
          // 渲染完毕
          this.editor.addListener("ready", () => {
    
    
            // 设置富文本内容
            //this.editor.setContent(this.info.body)
          });
          // 上传
          // 初始化Web Uploader
          this.uploader = WebUploader.create({
    
    
            // 选完文件后,是否自动上传
            auto: true,
            // swf文件路径
            swf: '/webuploader/Uploader.swf',
            // 文件接收服务端 上传PHP的代码
            server: '{
    
    { route('admin.article.upfile') }}',
            // 文件上传是携带参数
            formData: {
    
    
              _token: '{
    
    {csrf_token()}}'
            },
            // 文件上传是的表单名称
            fileVal: 'file',
            // 选择文件的按钮
            pick: {
    
    
              id: '#picker',
              // 是否开启选择多个文件的能力
              multiple: false
            },
            // 压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
            resize: true
          });
          // 上传成功时的回调方法
          this.uploader.on('uploadSuccess', (file, ret) => {
    
    
            // 图片路径
            let src = ret.url;
            this.info.pic = src;
          });
        },
        methods: {
    
    
          dopost() {
    
    
            var frmData = new FormData(this.$refs.frm);
            frmData.append('_token','{
    
    { csrf_token() }}')

            fetch(this.$refs.frm.action, {
    
    
              method: 'PUT',
              body: frmData
            })
            /*// 获取内容
            this.info.body = this.editor.getContent();

            var frmData = new FormData(this.$refs.frm);

            // JSON字符串的转换
            //var frmData = JSON.stringify(this.info);
            let ret = await fetch(this.$refs.frm.action, {
              method: 'PUT',
              credentials: 'include',
              headers: {
                'X-CSRF-TOKEN': '{
    
    { csrf_token() }}',
                'Content-Type': 'application/x-www-form-urlencoded'
                //'Content-Type': 'application/json'
              },
              body: frmData
            });
            let json = await ret.json();
            //location.href = json.url;*/
          }
        }
      });
    </script>
@endsection


创建视图层

@extends('admin.common.main')

@section('css')
    {
    
    {
    
    -- webuploader上传样式 --}}
    <link rel="stylesheet" type="text/css" href="/webuploader/webuploader.css"/>
@endsection
@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.article.store') }}" method="post" class="form form-horizontal">
            @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="title">
                </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="desn">
                </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-4 col-sm-5">
                    <!-- 表单提交时的封面地址 -->
                    <input type="hidden" name="pic" id="pic" value="{
    
    { config('up.pic') }}">
                    <div id="picker">上传文章封面</div>
                </div>
                <div class="formControls col-xs-4 col-sm-4">
                    <img src="" id="img" style="width: 100px;">
                </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">
                    <textarea name="body" id="body" cols="30" rows="10"></textarea>
                </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')
    <!-- webuploader上传js -->
    <script type="text/javascript" src="/webuploader/webuploader.js"></script>
    <!-- 配置文件 -->
    <script type="text/javascript" src="/ueditor/ueditor.config.js"></script>
    <!-- 编辑器源码文件 -->
    <script type="text/javascript" src="/ueditor/ueditor.all.js"></script>
    <!-- 实例化编辑器 -->
    <script>
      // 富文本编辑器
      var ue = UE.getEditor('body', {
    
    
        initialFrameHeight: 200
      });

      // 初始化Web Uploader
      var uploader = WebUploader.create({
    
    
        // 选完文件后,是否自动上传
        auto: true,
        // swf文件路径
        swf: '/webuploader/Uploader.swf',
        // 文件接收服务端 上传PHP的代码
        server: '{
    
    { route('admin.article.upfile') }}',
        // 文件上传是携带参数
        formData: {
    
    
          _token: '{
    
    {csrf_token()}}'
        },
        // 文件上传是的表单名称
        fileVal: 'file',
        // 选择文件的按钮
        pick: {
    
    
          id: '#picker',
          // 是否开启选择多个文件的能力
          multiple: false
        },
        // 压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
        resize: true
      });
      // 上传成功时的回调方法
      uploader.on('uploadSuccess', function (file, ret) {
    
    
        // 图片路径
        let src = ret.url;
        // 给表单添加value值
        $('#pic').val(src);
        // 给图片添加src
        $('#img').attr('src',src);

      });

    </script>
@endsection


编写路由文件


        // 文章管理 admin/article/upfile
        Route::post('article/upfile','ArticleController@upfile')->name('article.upfile');
        // 资源路由
        Route::resource('article', 'ArticleController');

猜你喜欢

转载自blog.csdn.net/weixin_47716362/article/details/109279585