使用Laravel实现内容管理系统项目

目录

项目介绍

安装Laravel

配置文件 

引入需要的静态文件

一、后台用户登录 

1.创建用户表

2.显示登录页面

3.Ajax交互

4.验证用户登录

 5.用户退出

二、后台首页

1.后台页面布局

2.显示后台首页

3.判断登录状态

三、栏目管理

1.创建栏目表

2.添加栏目

3.显示栏目列表

4.编辑栏目 

5.删除栏目

四.内容管理

1.创建内容表

2.添加内容

3.上传图片

4.整合UFditor

5.显示内容列表

6.编辑内容

7.删除内容

五.广告位管理

1.创建广告位表

2.添加广告位

3.显示、编辑、删除广告位列表

六.广告内容管理

1.创建广告内容表

2.添加、显示、编辑、删除广告

 结语

前台首页

一、页面布局

二、首页、栏目导航、轮播图、广告位、栏目内容展示

前台用户管理

用户注册、用户登录和用户退出

内容列表页

一、内容列表

二、面包屑导航

1.安装

2.配置导航

内容展示

一、内容详细页​​​​​​​


项目介绍

本项目分为前台后台。前台的功能包括用户登录与注册内容列表内容详细页广告展示评论热门内容等。后台在未登录的状态下会自动跳转至登录页面。输入用户名“admin”、密码“123456”验证码后,单击“登录”按钮,即可进行登录。登录后,页面顶部右侧显示了当前登录的用户名“admin”“退出”按钮,单击“退出”按钮即可退出后台系统。后台页面的左侧有一个菜单栏,用户可以在菜单栏中选择一个菜单项进行操作。项目中需要使用到的技术点包括文件上传分页会话技术。整个项目开发基于实现功能的步骤来完成,先实现后台开发,提供数据支持,再完成前台的数据展示。

安装Laravel

首先选择你想在的哪个文件安装Laravel,然后就选择那个文件执行安装Larave命令:composer create-project --prefer-dist laravel/laravel ./ 5.8.*

比如我想在D盘的 phpstudy_pro->WWW 里下载Laravel,则选择到D盘里的 phpstudy_pro->WWW 文件,然后在文件的上面写上cmd按下回车键,就可以进入到该文件的终端,然后执行安装Laravel的命令即可。操作如下图所示。

配置文件 

Laravel安装完成后,在Apache的conf\extra\httpd-vhosts.conf配置文件中创建一个虚拟主机。具体配置为:

<VirtualHost *:80>
    DocumentRoot "C:/web/apache2.4/htdocs/cms/public"
    ServerName cms.com
<VirtualHost>

然后,编辑Apache的hosts文件,添加一条解析记录“127.0.0.1 cms.com”。如下图所示。

 登录MySQL服务器,创建数据库cms,将cms作为内容管理系统的数据库。

打开项目,在config\database.php数据库配置文件中,将数据库名称修改为cms。 

.env文件中配置正确的数据库配置信息。全部完成后,即可在项目中访问数据库。 

引入需要的静态文件

一、后台用户登录 

1.创建用户表

(1)在命令行中执行如下命令创建迁移文件,具体命令如下:

php artisan make:migration create_admin_user_table

(2)执行完上述命令后,会在database\migrations目录下生成文件名称为时间前缀_create_admin_user_table.php的文件 。

(3)在迁移文件的up()方法中添加表结构信息,具体代码如下:

 public function up()
    {
        Schema::create('admin_user', function (Blueprint $table) {
            $table->increments('id')->comment('主键');
            $table->string('username', 32)->comment('用户名')->unique();
            $table->string('password', 32)->comment('密码');
            $table->char('salt', 32)->comment('密码salt');
            $table->timestamps();

        });
    }

(4)迁移文件创建完成后,使用如下命令来执行迁移

php artisan migrate

(5)上述命令会执行迁移文件中的up()方法,来完成数据表的创建。

(6)创建填充文件,具体命令如下:

php artisan make:seeder AdminuserTableSeeder

(7)执行完上述命令后,会在database\seeds目录下生成对应的迁移文件,文件名为AdminuserTableSeeder.php。

(8)在填充文件的run()方法中编写填充代码:

public function run()
{
    $salt = md5(uniqid(microtime(), true));
    $password = md5(md5('123456') . $salt);
    DB::table('admin_user')->insert([
        [
            'id' => 1,
            'username' => 'admin',
            'password' => $password,
            'salt' => $salt
        ],
    ]);
}

(9)执行填充文件命令:

php artisan db:seed --class=AdminuserTableSeeder

(10)数据库创建成功后,创建用户模型:

php artisan make:model Admin

(11)打开app\Admin.php,在模型中指定要操作的表名,具体代码如下:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Admin extends Model
{
    protected $table = 'admin_user';
    public $fillable = ['username', 'password'];
}

2.显示登录页面

(1)创建User控制器,具体代码如下:

php artisan make:controller Admin/UserController

(2)执行完上述命令后,会在app\Http\Controllers\Admin目录下创建UserController.php,命名空间为App\Http\Controllers\Admin

(3)打开UserController.php,创建login()方法,具体代码如下:

public function login(){
    return view('admin/login');
}

(4)在routes\web.php文件中添加路由规则,具体代码如下:

Route::get('/admin/login','Admin\UserController@login');

(5)在resources\views目录下创建admin目录,该目录用于存放后台相关的模板文件。在admin目录中创建login.blade.php文件,具体代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- 引入静态文件 -->
    <title>登录</title>
</head>
<body class="login">
<div class="container">
<!-- 登录表单 -->
</div>
</body>
</html>

(6)在上述的第6行引入静态文件,具体代码如下:

    <link rel="stylesheet" href="{{asset('admin')}}/common/twitter-bootstrap/4.4.1/css/bootstrap.min.css">
    <link rel="stylesheet" href="{{asset('admin')}}/common/font-awesome-4.2.0/css/font-awesome.min.css">
    <link rel="stylesheet" href="{{asset('admin')}}/common/toastr.js/2.1.4/toastr.min.css">
    <link rel="stylesheet" href="{{asset('admin')}}/css/main.css">
    <script src="{{asset('admin')}}/common/jquery/1.12.4/jquery.min.js"></script>
    <script src="{{asset('admin')}}/common/twitter-bootstrap/4.4.1/js/bootstrap.min.js"></script>
    <script src="{{asset('admin')}}/common/toastr.js/2.1.4/toastr.min.js"></script>
    <script src="{{asset('admin')}}/js/main.js"></script>

 (7)在注释登录表单下面定义登录表单,具体代码如下:

<form action="" method="post" class="j-login">
    <h1>后台管理系统</h1>
    <div class="form-group">
      <input type="text" name="username" class="form-control" placeholder="用户名" required>
    </div>
    <div class="form-group">
      <input type="password" name="password" class="form-control" placeholder="密码" required>
    </div>
    <div class="form-group">
      <input type="text" name="captcha" class="form-control" placeholder="验证码" required>
    </div>
    <!-- 验证码 -->
    <div class="form-group">
      {{csrf_field()}}
      <input type="submit" class="btn btn-lg btn-block btn-success" value="登录">
    </div>
</form>

(8)使用Composer载入mews/captcha验证码库,具体代码如下:

composer require mews/captcha=3.0

(9)创建验证码的配置文件 ,具体命令如下:

php artisan vendor:publish

(10)执行完上述命令后,在命令行中输入序号“9”并按"Enter"键,就会自动生成config\captcha.php文件。

(11)编辑config\captcha.php文件,将字符个数改为4,具体代码如下:

'default' => [
        'length' => 4, //字符个数
        'width' => 120, //图片宽度
        'height' => 36, //图片高度
        'quality' => 90, //图片质量
        'math' => false, //数学计算
    ],

(12)在config\app.php中将验证码服务注册到服务器中,具体代码如下:

'providers' => [
     ...(原有代码)
     Mews\Captcha\CaptchaServiceProvider::class,
     ...(原有代码)
]

(13)在config\app.php文件中给验证码服务注册别名,具体代码如下:

'aliases' => [
     ...(原有代码)
    'Captcha' =>Mews\Captcha\Facades\Captcha::class,
]

(14)在登录表单中添加验证码,具体代码如下:

<div class="form-group">
      <div class="login-captcha"><img src="{{ captcha_src() }}" alt="captcha"></div>
 </div>

(15)通过浏览器访问,其页面效果如下图:

(16)实现单机验证码图片后更换验证码功能,在模板中编写JavaScript代码,具体代码如下:

 <script>
    $('.login-captcha img').click(function() {
    $(this).attr('src', '{{ captcha_src()}}' + '?_=' + Math.random());
  });
</script> 

3.Ajax交互

(1)打开public\admin\js\main.js文件,添加如下代码:

(function (window, $, toastr) {
  window.main = {
    token: '',					// 保存令牌
    toastr: toastr,
    init: function (opt) {
      $.extend(this, opt);		// 将传入的opt对象合并到自身对象中
      toastr.options.positionClass = 'toast-top-center';
      return this;
    },
    ajax: function (opt, success, error) {
      opt = (typeof opt === 'string') ? {url: opt} : opt;
      var that = this;
      var options = {
        success: function (data, status, xhr) {
          that.hideLoading();
          if (!data) {
            toastr.error('请求失败,请重试。');
          } else if (data.code === 0) {
            toastr.error(data.msg);
            error && error(data);
          } else {
            success && success(data);
          }
          opt.success && opt.success(data, status, xhr);
        },
        error: function (xhr, status, err) {
          that.hideLoading();
          toastr.error('请求失败,请重试。');
          opt.error && opt.error(xhr, status, err);
        }
      };
      that.showLoading();
      $.ajax($.extend({}, opt, options));
    },
    showLoading: function() {
      $('.main-loading').show();
    },
    hideLoading: function() {
      $('.main-loading').hide();
    },
  };
})(this, jQuery, toastr);

(2)在main对象中编写ajaxPost()方法,具体代码如下:

ajaxPost: function(opt, success, error) {
      opt = (typeof opt === 'string') ? {url: opt} : opt;
      var that = this;
      var callback = opt.success;
      opt.type = 'POST';
      opt.success = function(data, status, xhr) {
        if (data && data.code === 1) {
          toastr.success(data.msg);
        }
        callback && callback(data, status, xhr);
      };
      that.ajax(opt, success, error);
    },

(3)在main.js中编写ajaxForm()方法,用于将表单改为Ajax提交方式,具体代码如下:

 ajaxForm: function (selector, success, error) {
      var form = $(selector);
      var that = this;
      form.submit(function (e) {
        e.preventDefault();
        that.ajaxPost({
          url: form.attr('action'),
          data: new FormData(form.get(0)),
          contentType: false,
          processData: false
        }, success, error);
      });
    },

4.验证用户登录

(1)在routes\web.php文件中添加路由规则,具体代码如下:

//登录验证
Route::post('/admin/check','Admin\UserController@check');

(2)在UserController.php中创建check()方法,具体代码如下:

public function check(Request $request)
    {
        //声明自动验证规则
        $rule = [
            'username' => 'required',
            'password' => 'required|min:6',
            'captcha' => 'required|captcha'
        ];
        // 声明自动验证规则对应的提示信息(验证失败返回信息)
        $message = [
            'username.required' => '用户名不能为空',
            'password.required' => '密码不能为空',
            'password.min'     => '密码最少为6位',
            'captcha.required' => '验证码不能为空',
            'captcha.captcha' => '验证码有误'
        ];
        //进行自动验证,验证表单提交数据
        $validator = Validator::make($request->all(), $rule, $message);
        // 输出验证结果并返回给浏览器
        if ($validator->fails()) {   //验证失败fails()方法
            foreach ($validator->getMessageBag()->toArray() as $v) {
                $msg = $v[0];
            }
            return response()->json(['code' => 0, 'msg' => $msg]);
        }
        // 获取用户输入的用户名、密码信息,以及数据表中用户名、密码信息
        $username = $request->get('username');
        $password = $request->get('password');
        $theUser = Admin::where('username',$username)->first();
        // 对用户输入的密码与数据库中的密码进行比较,如果密码正确则登录成功,并将用户信息保存在session中
        // 跳转至后台首页,如果登录失败,则显示“登录失败”
        if($theUser->password == md5(md5($password). $theUser->salt))
        {
            Session::put('user', ['id'=>$theUser->id,'name'=>$username]);
            return response()->json(['code' => 1, 'msg' => '登录成功']);
        }else{
            return response()->json(['code' => 0, 'msg' => '登录失败']);
        }
    }

(3)在上述代码中使用的一些类需要导入命名空间,具体代码如下:

use App\Admin;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;

(4)在login.blade.php的<script>标签中添加代码,具体代码如下:

 main.ajaxForm('.j-login', function() {
    location.href = '/index.php/admin/index';
  });

(5)通过浏览器访问,输入小于6位的密码,页面出现“密码最少为6位”的错误提示;输入验证码不正确,页面出现“验证码有误”的错误提示;如果提交正确的用户名(admin)和密码(123456),页面中会出现“登录成功”的提示。

 

 

 5.用户退出

(1)在User控制器中添加logout()方法,具体代码如下:

 public function logout(){
        if(request()->session()->has('user')){
            request()->session()->pull('user',session('user'));
        }
        return redirect('/admin/login');
    }

(2)在routes\web.php文件中添加路由规则,具体代码如下:

//用户退出
Route::get('/admin/logout','Admin\UserController@logout');

(3)通过浏览器访问,在确保用户已经登录以后,访问http://cms.com/index.php/admin/logout,浏览器会自动跳转到登录页面,说明已经成功退出。

二、后台首页

1.后台页面布局

(1)在layouts目录下创建admin.blade.php文件,具体代码如下 :

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--引入静态文件-->
  <title>@yield('title')</title>
</head>
<body>
<nav class="navbar navbar-expand-md navbar-light bg-light main-navbar">
  <a class="navbar-brand" href="#">后台管理系统</a>
  <div class="collapse navbar-collapse" id="navbarSupportedContent">
    <ul class="nav ml-auto main-nav-right">
      <li>
        <a href="#" class="j-layout-pwd">
          <i class="fa fa-user fa-fw"></i>{{session()->get('user.name')}}
        </a>
      </li>
      <li>
        <a href="{{url('admin/logout')}}">
          <i class="fa fa-power-off fa-fw"></i>退出
        </a>
      </li>
    </ul>
  </div>
</nav>
<!-- 后台页面的首页部分 -->
<div class="main-container">
  <div class="main-content">
    <div>@yield('main')</div>
  </div>
</div>
</body>
</html>

(2)在页面引入静态资源,具体代码如下:

  <link rel="stylesheet" href="{{asset('admin')}}/common/twitter-bootstrap/4.4.1/css/bootstrap.min.css">
  <link rel="stylesheet" href="{{asset('admin')}}/common/font-awesome-4.2.0/css/font-awesome.min.css">
  <link rel="stylesheet" href="{{asset('admin')}}/common/toastr.js/2.1.4/toastr.min.css">
  <link rel="stylesheet" href="{{asset('admin')}}/css/main.css">
  <script src="{{asset('admin')}}/common/jquery/1.12.4/jquery.min.js"></script>
  <script src="{{asset('admin')}}/common/twitter-bootstrap/4.4.1/js/bootstrap.min.js"></script>
  <script src="{{asset('admin')}}/common/toastr.js/2.1.4/toastr.min.js"></script>
  <script src="{{asset('admin')}}/js/main.js"></script>

 (3)在页面中定义左侧导航栏,具体代码如下:

<div class="main-sidebar">
      <ul class="nav flex-column main-menu">
      
</div>

(4)添加首页菜单,具体代码如下:

        <li class="">
          <a href="{{url('admin/index')}}" class="active">
            <i class="fa fa-home fa-fw"></i>首页
          </a>
        </li>

(5) 添加栏目菜单,具体代码如下:

        <li class="main-sidebar-collapse">  <!-- 被收起的双层项 -->
          <a href="#" class="main-sidebar-collapse-btn">   <!-- 链接用于展开或收起子菜单 -->
              <i class="fa fa-list-alt fa-fw"></i>栏目
              <span class="fa main-sidebar-arrow"></span>  <!-- 双层项的右侧小箭头 -->
          </a>
          <ul class="nav">
            <!-- 设置子菜单 -->
            <li>
              <a href="#" data-name="addcategory">
              <i class="fa fa-list fa-fw"></i>添加</a>
            </li>
            <li>
              <a href="#" data-name="category">
                <i class="fa fa-table fa-fw"></i>列表</a>
            </li>
          </ul>
        </li>

(6)添加内容表单,具体代码如下:

        <li class="main-sidebar-collapse">
          <a href="#" class="main-sidebar-collapse-btn">
            <i class="fa fa-list-alt fa-fw"></i>内容
            <span class="fa main-sidebar-arrow"></span>
          </a>
          <ul class="nav">
            <li>
              <a href="#" data-name="addcontent">
              <i class="fa fa-list fa-fw"></i>添加</a>
            </li>
            <li>
              <a href="#" data-name="content">
                <i class="fa fa-table fa-fw"></i>列表</a>
            </li>
          </ul>
        </li>

 (7)添加广告表单,具体代码如下:

         <li class="main-sidebar-collapse">
          <a href="#" class="main-sidebar-collapse-btn">
            <i class="fa fa-cog fa-fw"></i>广告
            <span class="fa main-sidebar-arrow"></span>
          </a>
          <ul class="nav">
            <li>
              <a href="#" data-name="adv">
                <i class="fa fa-list fa-fw"></i>广告位</a>
            </li>
            <li>
              <a href="#" data-name="advcontent">
                <i class="fa fa-list-alt fa-fw"></i>广告内容</a>
           </li>
          </ul>
        </li>

 (8)添加消息表单,具体代码如下:

@if(!empty(session('message')))
  <div class="alert alert-success" role="alert"
    style="text-align:center;margin:0 auto;width: 400px">
      {{session('message')}}
  </div>
@endif
@if(!empty(session('tip')))
  <div class="alert alert-warning" role="alert"
  style="text-align:center;margin:0 auto;width: 400px">
    {{session('tip')}}
  </div>
@endif

(9)在<body>标签结束前的位置添加<script>标签,控制消息模板的显示时间,具体代码如下:

<script>
  // setInterval(myFunction,myTimeLapse),每隔myTimeLapse(毫秒)执行一次myFunction()函数
  setInterval(function(){
    $('.alert').remove();
  },3000);
</script>

(10) 修改public\admin\js\main.js文件,编写layout()方法,具体代码如下:

 layout: function() {
      $('.main-sidebar-collapse-btn').click(function() {
        $(this).parent().find('.nav').slideToggle(200);
        $(this).parent().toggleClass('main-sidebar-collapse').siblings().
            addClass('main-sidebar-collapse').find('.nav').slideUp(200);
        return false;
      });
    },

(11)在main.js中增加menuActive()方法,用于将指定菜单项设为选中效果,具体代码如下:

menuActive: function(name) {
      var menu = $('.main-menu');
      menu.find('a').removeClass('active');
      menu.find('a[data-name=\'' + name + '\']').addClass('active');
      menu.find('a[data-name=\'' + name + '\']').parent().parent().show();
    }

(12)在<script>标签中调用layout()方法,具体代码如下:

main.layout();

2.显示后台首页

(1)公共文件创建完成后,接下来创建后台首页admin\index.blade.php,具体代码如下:

@extends('admin/layouts/admin')
@section('title', '后台首页')
@section('main')
  <div>
    <div class="main-title">
      <h2>首页</h2>
    </div>
    <div class="main-section">
      <div class="card">
        <div class="card-header">服务器信息</div>
        <ul class="list-group list-group-flush">
          <li class="list-group-item">系统环境:{{ $server_version }}</li>
          <li class="list-group-item">Laravel版本:{{ $laravel_version }}</li>
          <li class="list-group-item">MySQL版本:{{ $mysql_version }}</li>
          <li class="list-group-item">服务器时间:{{ $server_time }}</li>
          <li class="list-group-item">文件上传限制:{{ $upload_max_filesize }}</li>
          <li class="list-group-item">脚本执行时限:{{ $max_execution_time }}</li>
        </ul>
      </div>
    </div>
  </div>
@endsection

(2)创建Index控制器,具体代码如下:

php artisan make:controller Admin\IndexController

(3) 在Index控制器中添加index()方法,具体代码如下:

    public function index(Request $request){
        $data = [
            'server_version' => $request->server('SERVER_SOFTWARE'),
            'laravel_version' => app()::VERSION,
            'mysql_version' => $this->getMySQLVer(),
            'server_time' => date('Y-m-d H:i:s', time()),
            'upload_max_filesize' => ini_get('file_uploads') ?
                ini_get('upload_max_filesize') : '已禁用',
            'max_execution_time' => ini_get('max_execution_time') . '秒'
        ];
        return view('admin\index', $data);
    }

(4)在上述代码中,第六行代码调用getMySQLVer()方法获取MySQL版本,创建getMySQLVer()方法,具体代码如下:

private function getMySQLVer()
    {
        $res = DB::select('SELECT VERSION() AS ver');
        return $res[0]->ver ?? '未知';
    }

 (5)在getMySQLVer()方法中,使用DB类执行SQL,获取MySQL的版本,导入DB类的命名空间,具体代码如下:

use DB;

(6)在routes\web.php文件中添加路由规则,具体代码如下:

Route::get('/admin/index', 'Admin\IndexController@index');

 (7)通过浏览器访问后台首页,其效果如下图:

3.判断登录状态

(1)创建Admin中间件,用于验证用户是否登录,具体代码如下:

php artisan make:middleware Admin

(2)打开app\Http\Middleware\Admin.php,添加验证用户登录的代码,具体代码如下:

 public function handle($request, Closure $next)
    {
        if (request()->session()->has('user')) {
            $user = request()->session()->get('user');
            view()->share('user', $user);
        } else {
            return redirect('/admin/login');
        }
        return $next($request);
    }

(3)在app\Http\Kernel.php文件中注册路由中间件,具体代码如下:

protected $routeMiddleware = [
    ...(原有代码)
    'Admin' => \App\Http\Middleware\Admin::class,
];

(4)修改首页的路由规则,为后台首页添加用户验证,具体代码如下:

Route::get('/admin/index', 'Admin\IndexController@index')->middleware(['Admin']);

三、栏目管理

1.创建栏目表

(1)栏目表同样也是通过命令行来创建,按照前面的步骤创建迁移文件和填充文件。

(2)打开栏目表的迁移文件,在该文件的up()方法中添加表结构信息,具体代码如下:

 public function up()
    {
        
        Schema::create('category', function (Blueprint $table) {
            $table->increments('id')->comment('主键');
            $table->integer('pid')->comment('父类id') ->default('0');
            $table->string('name', 32)->comment('分类名称');
            $table->integer('sort')->comment('排序值') ->default('0');
            $table->timestamps();
        });


    }

(3)栏目表创建完成后,为了在项目中操作栏目表,下面创建栏目表对应的模型文件,具体代码如下:

php artisan make:model Category

(4)打开app\Category.php文件,具体代码如下:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    protected $table = "category";
    public $fillable = ['pid', 'name', 'sort'];
}

2.添加栏目

(1)创建Category控制器,具体代码如下:

php artisan make:controller Admin\CategoryController

(2)在控制器中添加add()方法,用于实现添加栏目的功能,具体代码如下:

<?php

namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Category;

class CategoryController extends Controller
{
    public function add(){
        $category = Category::where('pid', 0)->get();
        return view('admin.category.add', ['category' => $category] );
    }
}

(3)创建admin\category\add.blade.php视图文件,具体代码如下:

@extends('admin/layouts/admin')
@section('title', ' 添加栏目')
@section('main')
<div class="main-title"><h2>添加栏目</h2></div>
<div class="main-section">
  <div style="width:543px">
    <!-- 添加栏目表单 -->
    <form method="post" action="{{ url('/category/save') }}">
      <div class="form-group row">
        <label class="col-sm-2 col-form-label">序号</label>
        <div class="col-sm-10">
          <input type="number" name="sort" class="form-control" value="0" style="width:80px;">
        </div>
      </div>
      <div class="form-group row">
        <label class="col-sm-2 col-form-label">上级栏目</label>
        <div class="col-sm-10">
          <select name="pid" class="form-control" style="width:200px;">
            <option value="0">---</option>
            @foreach ($category as $v)
              <option value="{{ $v->id }}"> {{ $v->name }}</option>
            @endforeach
          </select>
        </div>
      </div>
      <div class="form-group row">
        <label class="col-sm-2 col-form-label">名称</label>
        <div class="col-sm-10">
          <input type="text" name="name" class="form-control" style="width:200px;">
        </div>
      </div>
      <div class="form-group row">
        <div class="col-sm-10">
          {{csrf_field()}}
          <button type="submit" class="btn btn-primary mr-2">提交表单</button>
          <a href="{{url('category')}}" class="btn btn-secondary">返回列表</a>
        </div>
      </div>
    </form>
  </div>
</div>
<script>
  main.menuActive('addcategory');
</script>
@endsection

(4)在routes\web.php文件中添加路由规则,具体代码如下:

// 栏目
Route::prefix('category')->namespace('Admin')->middleware(['Admin'])->group(function () {
    Route::get('add', 'CategoryController@add');
});

(5)修改布局文件admin.blade.php,为添加栏目的导航添加链接,具体代码如下:

<a href="{{ url('category/add') }}" data-name="addcategory"><i class="fa fa-list fa-fw"></i>添加</a>

(6)在Category控制器中编写save()方法,用于接收添加栏目的表单数据,具体代码如下:

 public function save(Request $request){
        $data = $request->all();
        $this->validate($request,[
            'name'=>'required|unique:category'.$rule,
        ],[
            'name.required'=>'栏目名称不能为空',
            'name.unique'=>'栏目名称不能重复'
        ]);
        $re = Category::create($data);
        if($re){
            return redirect('category')->with('message','添加成功');
        }else{
            return redirect('category/add')->with('tip','添加失败');
        }
    }

(7)在routes\web.php文件中栏目的路由组中添加路由规则,具体代码如下:

Route::post('save', 'CategoryController@save');

3.显示栏目列表

(1)在Category控制器中创建index()方法,具体代码如下:

    public function index(){
        $category = $this->getTreeListCheckLeaf($data);
        return view('admin.category.index', ['category' => $category]);
    }

(2)在Category模型中添加getTreeListCheckLeaf()方法和treeList()方法,具体代码如下:

 public function getTreeListCheckLeaf($data, $name = 'isLeaf')
    {
        $data = $this->treeList($data);
        foreach ($data as $k => $v) {
            foreach ($data as $vv) {
                $data[$k][$name] = true;
                if ($v['id'] === $vv['pid']) {
                    $data[$k][$name] = false;
                    break;
                }
            }
        }
        return $data;
    }

    public function treeList($data, $pid = 0, $level = 0, &$tree = [])
    {
        foreach ($data as $v) {
            if ($v['pid'] == $pid) {
                $v['level'] = $level;
                $tree[] = $v;
                $this->treeList($data, $v['id'], $level + 1, $tree);
            }
        }
        return $tree;
    }

(3)创建视图文件index.php,具体代码如下:

@extends('admin/layouts/admin')
@section('title', '栏目列表')
@section('main')
<div class="main-title"><h2>栏目管理</h2></div>
<div class="main-section form-inline">
  <a href="{{ url('category/add') }}" class="btn btn-success">+ 新增</a>
</div>
<div class="main-section">
  <form method="post" action="" class="j-form">
    <table class="table table-striped table-bordered table-hover">
      <thead>
      <tr>
        <th width="75">序号</th><th>名称</th><th width="100">操作</th>
      </tr>
      </thead>
      <tbody>
      <!-- 栏目列表 -->
      @foreach($category)
        <tr class="j-pid-{{ $v['pid'] }}"
          @if($v['level'])style="display:none"@endif>
          <td><input type="text" class="form-control j-sort" maxlength="5" value="{{$v['sort']}}" data-name="sort[{{$v['id']}}]" style="height:25px;font-size:12px;padding:0 5px;"></td>
          <td>
            @if($v['level'])
              <small class="text-muted">├──</small> {{$v['name']}}
            @else
              <a href="#" class="j-toggle" data-id="{{$v['id']}}">
                @if(!$v['isLeaf'])
                  <i class="fa fa-plus-square-o fa-minus-square-o fa-fw"></i>
                @endif
                {{$v['name']}}
              </a>
            @endif
          </td>
          <td>
            <a href="{{ url('category/edit', ['id' => $v['id']]) }}" style="margin-right:5px;">编辑</a>
            <a href="{{ url('category/delete', ['id' => $v['id']]) }}" class="j-del text-danger">删除</a>
          </td>
        </tr>
      @endforeach
      @if(empty($category))
        <tr><td colspan="4" class="text-center">还没有添加栏目</td></tr>
      @endif
      </tbody>
    </table>
    {{csrf_field()}}
    <input type="submit" value="改变排序" class="btn btn-primary">
  </form>
</div>
<script>
  main.menuActive('category');
  $('.j-toggle').click(function() {
    var id = $(this).attr('data-id');
    $(this).find('i').toggleClass('fa-plus-square-o');
    $('.j-pid-' + id).toggle();
    return false;
  });
  $('.j-sort').change(function() {
    $(this).attr('name', $(this).attr('data-name'));
  });
  $('.j-del').click(function() {
    if (confirm('您确定要删除此项?')) {
      var data = { _token: '{{ csrf_token() }}' };
      main.ajaxPost({url:$(this).attr('href'), data: data}, function(){
        location.reload();
      });
    }
    return false;
  });
</script>
@endsection

(4)在routes\web.php文件中栏目的路由组中添加栏目列表的路由规则,具体代码如下:

    Route::get('', 'CategoryController@index');

(5)修改admin.blade.php,为列表菜单项添加链接,具体代码如下:

<a href="{{ url('category') }}" data-name="category"><i class="fa fa-table fa-fw"></i>列表</a>

(6)通过浏览器访问,栏目列表的页面效果如下图所示:

(7) 在栏目列表页中,为了实现修改栏目的排序,需要设置栏目列表页中表单的提交地址,具体代码如下:

  <form method="post" action="{{ url('category/sort')}}" class="j-form">

(8)在routes\web.php文件中栏目的路由组中添加排序的路由规则,具体代码如下:

    Route::post('sort', 'CategoryController@sort');

(9)在Category控制器中添加sort()方法,具体代码如下:

public function sort(Request $request){
        $sort = $request->input('sort');
        foreach ($sort as $k => $v) {
            Category::where('id', (int)$k)->update(['sort' => (int)$v]);
        }
        return redirect('category')->with('message','改变排序成功');
    }

(10)通过浏览器访问,观察栏目功能是否正确执行。

4.编辑栏目 

(1)在列表页中为“编辑”按钮添加链接,具体代码如下:

<a href="{{ url('category/edit', ['id' => $v['id']]) }}" style="margin-right:5px;">编辑</a>

(2)在routes\web.php文件中栏目的路由组中添加编辑栏目的路由规则,具体代码如下:

    Route::get('edit/{id}', 'CategoryController@edit');

(3)在Category控制器中添加edit()方法,具体代码如下:

public function edit($id){
        $data = [];
        if ($id) {
            if (!$data = Category::find($id)) {
                return back()->with('tip', '记录不存在。');
            }
        }
        $category = Category::where('pid', 0)->get();
        return view('admin.category.edit', ['id'=>$id, 'data'=>$data, 'category' => $category]);
    }

(4)创建视图文件edit.blade.php,具体代码如下:

@extends('admin/layouts/admin')
@section('title', '栏目列表')
@section('main')
<div class="main-title"><h2>编辑分类</h2></div>
<div class="main-section">
  <div style="width:543px">
    <!-- 编辑表单 -->
    <form method="post" action="{{ url('/category/save') }}">
      <div class="form-group row">
        <label class="col-sm-2 col-form-label">序号</label>
        <div class="col-sm-10">
          <input type="number" name="sort" class="form-control" value="{{$data->sort}}" style="width:80px;">
        </div>
      </div>
      <div class="form-group row">
        <label class="col-sm-2 col-form-label">上级分类</label>
        <div class="col-sm-10">
          <select name="pid" class="form-control" style="width:200px;">
            <option value="0">---</option>
            @foreach($category as $v)
              <option value="{{ $v->id }}" @if($data['pid'] == $v['id']) selected @endif> {{ $v->name }}</option>
            @endforeach
          </select>
        </div>
      </div>
      <div class="form-group row">
        <label class="col-sm-2 col-form-label">名称</label>
        <div class="col-sm-10">
          <input type="text" name="name" class="form-control" value="{{$data->name}}" style="width:200px;">
        </div>
      </div>
      <div class="form-group row">
        <div class="col-sm-10">
          {{csrf_field()}}
          <input type="hidden" name="id" value="{{$id}}">
          <button type="submit" class="btn btn-primary mr-2">提交表单</button>
          <a href="{{url('category')}}" class="btn btn-secondary">返回列表</a>
          {{--<a href="{{url('category')}}">--}}
            {{--<button class="btn btn-secondary">返回列表</button>--}}
          {{--</a>--}}
        </div>
      </div>
    </form>
  </div>
</div>
<script>
  main.menuActive('category');
</script>
@endsection

(5)修改save()方法,根据栏目id更新栏目内容,具体代码如下:

public function save(Request $request){
        $data = $request->all();
        $rule = isset($data['id']) ? ',name,'.$data['id'] : '';
        $this->validate($request,[
            'name'=>'required|unique:category'.$rule,
        ],[
            'name.required'=>'栏目名称不能为空',
            'name.unique'=>'栏目名称不能重复'
        ]);
        if(isset($data['id'])){
            $id = $data['id'];
            unset($data['id']);
            unset($data['_token']);
            $res = Category::where('id',$id)->update($data);
            $type = $res ? "message" : "tip";
            $message = $res ? "修改成功" : "修改失败";
            return redirect('category')->with($type, $message);
        }
        $re = Category::create($data);
        if($re){
            return redirect('category')->with('message','添加成功');
        }else{
            return redirect('category/add')->with('tip','添加失败');
        }
    }

5.删除栏目

(1)在列表页中为“删除”按钮添加链接,具体代码如下:

<a href="{{ url('category/delete', ['id' => $v['id']]) }}" class="j-del text-danger">删除</a>

(2)在Category控制器中添加delete()方法,具体代码如下:

public function delete($id){
        if (!$category = Category::find($id)) {
            return response()->json(['code' => 0, 'msg' => '删除失败,记录不存在。' ]);
        }
        $category->delete();
        return response()->json(['code' => 1, 'msg' => '删除成功' ]);
    }

(3)在routes\web.php文件的栏目路由组中添加删除栏目的路由规则,具体代码如下:

    Route::post('delete/{id}', 'CategoryController@delete');

四.内容管理

1.创建内容表

(1)按照上述的步骤创建内容表对应的迁移文件后,在迁移文件的up()方法中添加表结构信息,具体代码如下:

 public function up()
    {
        Schema::create('content', function (Blueprint $table) {
            $table->increments('id')->comment('主键');
            $table->integer('cid')->comment('栏目id')->default(0);
            $table->string('title', 255)->comment('标题');
            $table->text('content', 255)->comment('内容');
            $table->char('image', 255)->comment('图片');
            $table->tinyInteger('status')->comment('状态默认1推荐2')->default(1);
            $table->timestamps();
        });

    }

(2)创建内容表对应的模型文件,具体代码如下:

php artisan make:model Content

(3)执行上述命令后,会自动创建app\Content.php文件,具体代码如下:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Content extends Model
{
    protected $table = "content";
    public $fillable = ['cid', 'title', 'content', 'image', 'status'];
}

2.添加内容

(1)创建Content控制器,具体代码如下:

php artisan make:controller Admin\ContentController

(2)在控制器中引入add()方法用于实现添加内容的功能,save()方法保存添加的内容,具体代码如下:

 public function add()
    {
        $data = Category::orderBy('sort', 'asc')->get()->toArray();
        $cate = new CategoryController();
        $category = $cate->getTreeListCheckLeaf($data);
        return view('admin.content.add', ['category' => $category]);
    }

    public function save(Request $request)
    {
        $data = $request->all();
        $this->validate($request,[
            'cid'=>'required',
            'title'=>'required'
        ],[
            'cid.require'=>'分类不能为空',
            'title.require'=>'标题不能为空'
        ]);
        if(isset($data['id'])){
            $id = $data['id'];
            unset($data['id']);
            unset($data['_token']);
            $res = Content::where('id',$id)->update($data);
            $type = $res ? "message" : "tip";
            $message = $res ? "修改成功" : "修改失败";
            return redirect('content')->with($type, $message);
        }

        $re = Content::create($data);
        if($re){
            return redirect('content')->with('message','添加成功');
        }else{
            return redirect('content/add')->with('tip','添加失败');
        }
    }

(3)在控制器中导入Category模型的命名空间Content的命名空间,具体代码如下:

use App\Category;
use App\Content;

(4)创建resources\views\admin\content\add.blade.php视图文件,具体代码如下:

@extends('admin/layouts/admin')
@section('title', '添加内容')
@section('main')
<div class="main-title"><h2>添加内容</h2></div>
<div class="main-section">
  <div style="width:80%">
    <!-- 添加内容表单 -->
    <form method="post" action="{{ url('/content/save') }}" class="j-form">
      <div class="form-group row">
        <label class="col-sm-2 col-form-label">所属分类</label>
        <div class="col-sm-10">
          <select name="cid" class="form-control" style="width:200px;">
            <!-- 分类下拉列表 -->
            @foreach($category as $v)
              @if($v['level'])
                <option value="{{$v['id']}}">
                  <small class="text-muted">├──</small>{{$v['name']}}
                </option>
              @else
                <option value="{{$v['id']}}"> {{$v['name']}}</option>
              @endif
            @endforeach
          </select>
        </div>
      </div>
      <div class="form-group row">
        <label class="col-sm-2 col-form-label">标题</label>
        <div class="col-sm-10">
          <input type="text" name="title" class="form-control" style="width:200px;">
        </div>
      </div>
      <!-- 上传图片按钮 -->
      <div class="form-group row">
        <label class="col-sm-2 col-form-label">图片</label>
        <div class="col-sm-10">
          <input type="file" id="file1" name="image" value="上传图片" multiple="true">
        </div>
        <div class="col-sm-10 offset-sm-2">
          <div class="upload-img-box" id="uploadImg"></div>
        </div>
      </div>
      <div class="form-group row">
        <label class="col-sm-2 col-form-label">简介</label>
        <div class="col-sm-10">
          <!-- <textarea class="j-goods-content" name="content" style="height:500px"></textarea> -->
          <script type="text/plain" class="j-goods-content" name="content" style="height:500px"></script>
        </div>
      </div>
      <div class="form-group row">
        <label class="col-sm-2 col-form-label">状态</label>
        <div class="col-sm-10">
          <div class="form-check form-check-inline" style="height:38px">
            <input class="form-check-input" id="inlineRadio1" type="radio" name="status" value="1" checked>
            <label class="form-check-label" for="inlineRadio1">默认</label>
          </div>
          <div class="form-check form-check-inline" style="height:38px">
            <input class="form-check-input" id="inlineRadio2" type="radio" name="status" value="2">
            <label class="form-check-label" for="inlineRadio2">推荐</label>
          </div>
        </div>
      </div>
      <div class="form-group row">
        <div class="col-sm-10">
          {{csrf_field()}}
          <button type="submit" class="btn btn-primary mr-2">提交表单</button>
          <a href="{{url('content')}}" class="btn btn-secondary">返回列表</a>
        </div>
      </div>
    </form>
  </div>
</div>
<link href="{{asset('admin')}}/common/uploader/uploadifive.css" rel="stylesheet" />
<script src="{{asset('admin')}}/common/uploader/jquery.uploadifive.js"></script>
<script src="{{asset('admin')}}/common/editor/ueditor1.4.3.3/ueditor.config.js"></script>
<script src="{{asset('admin')}}/common/editor/ueditor1.4.3.3/ueditor.all.min.js"></script>
<script src="{{asset('admin')}}/common/editor/main.editor.js"></script>
<script>
    main.menuActive('addcontent');
    $(function() {
      $('#file1').uploadifive({
        'auto'            : true,
        'fileObjName'     : 'image',
        'fileType'        : 'image',
        'buttonText'      : '上传图片',
        'formData'        : { '_token' : "{{ csrf_token() }}" },
        'method'          : 'post',
        'queueID'         : 'uploadImg',
        'removeCompleted' : true,
        'uploadScript'    : '{{ url('content/upload')}}',
        'onUploadComplete': uploadPicture_icon
      });
    });
    function uploadPicture_icon(file, data) {
      var obj = $.parseJSON(data);
      var src = '';
      if (obj.code) {
        filename = obj.data.filename;
        path = obj.data.path;
        $('.upload-img-box').empty();
        $('.upload-img-box').html(
          '<div class="upload-pre-item" style="max-height:100%;"><img src="' + path + '" style="width:100px;height:100px"/> <input type="hidden" name="image" value="'+filename+'" class="icon_banner"/></div>'
        );
      } else {
        alert(data.info);
      }
    }
    main.editor($('.j-goods-content'), 'goods_edit', function(opt) {
      opt.UEDITOR_HOME_URL = '{{asset('admin')}}/common/editor/ueditor1.4.3.3/';
    }, function(editor) {
      $('.j-form').submit(function() {
        editor.sync();
      });
    });
</script>
@endsection

(5)在routes\web.php文件在添加内容管理的路由组,具体代码如下:

Route::prefix('content')->namespace('Admin')->middleware(['Admin'])->group(function () {

    Route::get('add', 'ContentController@add');
    Route::post('save', 'ContentController@save');
});

(6)修改admin.blade.php,为添加内容的菜单项添加链接,具体代码如下:

<a href="{{ url('content/add') }}" data-name="addcontent">
              <i class="fa fa-list fa-fw"></i>添加</a>

3.上传图片

(1)在添加内容的视图中添加上传图片的按钮,具体代码如下:

<div class="form-group row">
        <label class="col-sm-2 col-form-label">图片</label>
        <div class="col-sm-10">
          <input type="file" id="file1" name="image" value="上传图片" multiple="true">
        </div>
        <div class="col-sm-10 offset-sm-2">
          <div class="upload-img-box" id="uploadImg"></div>
        </div>
      </div>

(2)在视图中引入上传文件所需的样式和JavaScript代码,具体代码如下:

<link href="{{asset('admin')}}/common/uploader/uploadifive.css" rel="stylesheet" />
<script src="{{asset('admin')}}/common/uploader/jquery.uploadifive.js"></script>
<script src="{{asset('admin')}}/common/uploader/jquery.uploadifive.min.js"></script>

(3)在Content控制器中编写upload()方法,具体代码如下:

 public function upload(Request $request)
    {
        if ($request->hasFile('image')) {
            $image = $request->file('image');
            if ($image->isValid()) {
                $name = md5(microtime(true)) . '.' . $image->extension();
                $image->move('static/upload', $name);
                $path = '/static/upload/' . $name;
                $returndata  = array(
                    'filename' => $name,
                    'path' => $path
                );
                $result = [
                    'code' => 1,
                    'msg'  => '上传成功',
                    'time' => time(),
                    'data' => $returndata,
                ];
                return response()->json($result);
            }
            return $image->getErrorMessage();
        }
        return '文件上传失败';
    }

(4)在routes\web.php文件中内容的路由组中添加上传图片的路由规则,具体代码如下:

    Route::post('upload', 'ContentController@upload');

4.整合UFditor

(1)创建public\admin\common\editor\main.editor.js文件,具体代码如下:

(function($, main) {
  var def = {
    UEDITOR_HOME_URL: '',       // UEditor URL
    serverUrl: '',				// UEditor内置上传地址设为空
    autoHeightEnabled: false,	// 关闭自动调整高度
    wordCount: false,			// 关闭字数统计
    toolbars: [['fullscreen', 'source', '|',  // 自定义工具栏按钮
     'undo', 'redo', '|',  'bold', 'italic', 'underline', 'strikethrough', 
     'forecolor', 'backcolor', 'fontfamily', 'fontsize', 'paragraph', 'link',
     'blockquote', 'insertorderedlist', 'insertunorderedlist', '|',
     'inserttable', 'insertrow', 'insertcol', '|', 'drafts']]
  };
  var instances = {};
  main.editor = function(obj, id, before, ready) {
    var opt = $.extend(true, {}, def);
    before(opt);
    if (instances[id]) {
      instances[id].destroy();
      $('#' + id).removeAttr('id');
    }
    return instances[id] = createEditor(obj, id, opt, ready);
  };
  function createEditor(obj, id, opt, ready) {
    obj.attr('id', id);
    var editor = UE.getEditor(id, opt);
    editor.ready(function() {
      ready(editor);
    });
    return editor;
  }
}(jQuery, main));

(2)在add.blade.php文件中引入编辑器相关的文件,具体代码如下:

<script src="{{asset('admin')}}/common/editor/ueditor1.4.3.3/ueditor.config.js"></script>
<script src="{{asset('admin')}}/common/editor/ueditor1.4.3.3/ueditor.all.min.js"></script>
<script src="{{asset('admin')}}/common/editor/main.editor.js"></script>

5.显示内容列表

(1)在Content控制器中编写index()方法,具体代码如下:

public function index($id = 0)
    {
        $data = Category::orderBy('sort', 'asc')->get()->toArray();
        $cate = new CategoryController();
        $category = $cate->getTreeListCheckLeaf($data);
        $content = Content::get();
        if ($id) {
            $content = Content::where('cid', $id)->get();
        }
        return view('admin.content.index', ['category' => $category, 'content' => $content, 'cid' => $id]);
    }

(2)在展示内容时,需显示内容对应的栏目,因此在Content模型中添加关联模型,具体代码如下:

public function category()
    {
        return $this->belongsTo('App\Category', 'cid', 'id');
    }

(3)创建resources\views\admin\content\index.blade.php文件,具体代码如下:

@extends('admin/layouts/admin')
@section('title', '内容列表')
@section('main')
  <div class="main-title"><h2>内容管理</h2></div>
  <div class="main-section form-inline">
    <a href="{{ url('content/add') }}" class="btn btn-success">+ 新增</a>
    <!-- 此处编写分类下拉菜单 -->
    <select class="j-select form-control" style="min-width:120px;margin-left:8px">
      <option value="{{ url('content', ['id' => 0]) }}">所有分类</option>
      @foreach($category as $v)
        @if($v['level'])
        <option value="{{ url('content', ['d' => $v['id']]) }}" data-id="{{$v['id']}}">
          <small class="text-muted">--</small> {{$v['name']}}
        </option>
        @else
        <option value="{{ url('content', ['id' => $v['id']]) }}" data-id="{{$v['id']}}">
          {{$v['name']}}
        </option>
        @endif
      @endforeach
    </select>
  </div>
  <div class="main-section">
    <form method="post" action="{{ url('category/sort')}}" class="j-form">
      <table class="table table-striped table-bordered table-hover">
        <thead>
        <tr>
          <th width="75">序号</th><th>分类</th><th>图片</th><th>标题</th>
          <th>状态</th><th>创建时间</th><th width="100">操作</th>
        </tr>
        </thead>
        <tbody>
        @foreach($content as $v)
          <!-- 此处编写内容列表代码 -->
          <tr class="j-pid-{{ $v->pid }}" @if($v->level)style="display:none"@endif>
            <td>{{ $v->id }}</td>
            <td>{{ $v->category->name}}</td>
            <td><img @if($v->image) src="/static/upload/{{ $v->image}}" @else src="{{asset('admin')}}/img/noimg.png" @endif width="50" height="50"></td>
            <td>{{ $v->title }}</td>
            <td>@if($v->status==1) 默认  @else 推荐 @endif</td>
            <td>{{ $v->created_at }}</td>
            <td><a href="{{ url('content/edit', ['id' => $v->id ]) }}" style="margin-right:5px;">编辑</a>
              <a href="{{ url('content/delete', ['id' => $v->id ]) }}" class="j-del text-danger">删除</a>
            </td>
          </tr>
        @endforeach
        @if(empty($content))
          <tr><td colspan="7" class="text-center">还没有添加内容</td></tr>
        @endif
        </tbody>
      </table>
      {{csrf_field()}}
    </form>
  </div>
  <script>
    main.menuActive('content');
    $('.j-select').change(function() {
      location.href = $(this).val();
    });
    $('option[data-id=' + {{$cid}} + ']').attr('selected', true);
    $('.j-del').click(function() {
      if (confirm('您确定要删除此项?')) {
        var data = { _token: '{{ csrf_token() }}' };
        main.ajaxPost({url:$(this).attr('href'), data: data}, function(){
          location.reload();
        });
      }
      return false;
    });
  </script>
@endsection

(4)在routes\web.php文件中添加内容列表页的路由,具体代码如下:

    Route::get('{id?}', 'ContentController@index');

6.编辑内容

(1)在内容列表页中为“编辑”按钮添加链接,具体代码如下:

<a href="{{ url('content/edit', ['id' => $v->id ]) }}" style="margin-right:5px;">编辑</a>

(2)在Content控制器中添加edit()方法,具体代码如下:

 public function edit(Request $request)
    {
        $id = $request->id;
        $data = Category::orderBy('sort', 'asc')->get()->toArray();
        $cate = new CategoryController();
        $category = $cate->getTreeListCheckLeaf($data);
        $content = Content::find($id);
        return view('admin.content.edit', ['category' => $category, 'content' => $content]);
    }

(3)在routes\web.php文件中添加内容列表页的路由,具体代码如下:

    Route::get('edit/{id}', 'ContentController@edit');

7.删除内容

(1)在内容列表页为“删除”按钮添加链接,具体代码如下:

<a href="{{ url('content/delete', ['id' => $v->id ]) }}" class="j-del text-danger">删除</a>

(2)在routes\web.php文件中添加删除内容的路由,具体代码如下:

    Route::post('delete/{id}', 'ContentController@delete');

(3)在Content控制器中添加delete()方法,具体代码如下:

 public function delete($id)
    {
        if (!$content = Content::find($id)) {
            return response()->json(['code' => 0, 'msg' => '删除失败,记录不存在。' ]);
        }
        $content->delete();
        return response()->json(['code' => 1, 'msg' => '删除成功' ]);
    }

五.广告位管理

1.创建广告位表

(1)创建广告位表对应的迁移文件后,在迁移文件的up()方法中添加表结构信息,具体代码如下:

 public function up()
    {
        Schema::create('adv', function (Blueprint $table) {
            $table->increments('id')->comment('主键');
            $table->string('name', 32)->comment('广告位名称');
            $table->timestamps();
        });
    }

(2)创建广告位表对应的模型文件,具体代码如下:

php artisan make:model Adv

(3)执行上述命令后,会自动创建app\Adv.php文件,具体代码如下:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Adv extends Model
{
    protected $table = "adv";
    public $fillable = ['name'];
}

2.添加广告位

(1)创建Adv控制器,具体代码如下:

php artisan make:controller Admin\AdvController

(2)在控制器中添加add()方法用于实现添加广告位的功能,添加save()方法用于保存添加的广告位,具体代码如下:

  public function add($id = 0){
        $data = [];
        if($id > 0){
            $data = Adv::find($id);
        }
        return view('admin.adv.add', ['data' => $data]);
    }

    public function save(Request $request){
        $data = $request->all();

        $this->validate($request,[
            'name'=>'required'
        ],[
            'name.require'=>'名称不能为空'
        ]);
        if(isset($data['id'])){
            $id = $data['id'];
            unset($data['id']);
            unset($data['_token']);
            $res = Adv::where('id',$id)->update($data);
            $type = $res ? "message" : "tip";
            $message = $res ? "修改成功" : "修改失败";
            return redirect('adv')->with($type, $message);
        }

        $re = Adv::create($data);
        if($re){
            return redirect('adv')->with('message','添加成功');
        }else{
            return redirect('adv/add')->with('tip','添加失败');
        }
    }

(3)在控制器中引入Adv的命名空间。具体代码如下:

use App\Adv;

(4)在routes\web.php中添加广告位管理的路由组,具体代码如下:

//广告
Route::prefix('adv')->namespace('Admin')->middleware(['Admin'])->group(function () {
    Route::get('add/{id?}', 'AdvController@add');
    Route::post('save', 'AdvController@save');
});

3.显示、编辑、删除广告位列表

(1)修改admin.blade.php,为广告位菜单项添加链接,具体代码如下:

<a href="{{url('adv')}}" data-name="adv">
    <i class="fa fa-list fa-fw"></i>广告位</a>

(2)在routes\web.php中添加广告位列表的路由,具体代码如下:

    Route::get('', 'AdvController@index');
    route::post('delete/{id}','AdvController@delete');

(3)在Adv控制器中编写index()方法和delete()方法,具体代码如下:

public function index(){
        $adv = Adv::all();
        return view('admin.adv.index', ['adv' => $adv]);
    }

 public function delete($id){

        if (!$content = Adv::find($id)) {
            return response()->json(['code' => 0, 'msg' => '删除失败,记录不存在。' ]);
        }
        if(Advcontent::where('advid', '=', $id)->exists()){
            return response()->json(['code' => 0, 'msg' => '该广告位下有广告记录,请先删除广告内容。' ]);
        }
        $content->delete();

        return response()->json(['code' => 1, 'msg' => '删除成功' ]);
    }

(4)创建index.blade.php文件,具体代码如下:

@extends('admin/layouts/admin')
@section('title', '广告位列表')
@section('main')
<div class="main-title"><h2>广告位管理</h2></div>
<div class="main-section form-inline">
  <a href="{{ url('adv/add') }}" class="btn btn-success">+ 新增</a>
</div>
<div class="main-section">
  <table class="table table-striped table-bordered table-hover">
    <thead>
      <tr>
        <th width="75">序号</th><th>广告位名称</th><th width="100">操作</th>
      </tr>
    </thead>
    <tbody>
      <!-- 广告位列表-->
      @foreach($adv as $v)
      <tr class="j-pid-{{ $v['pid'] }}">
        <td><input type="text" value="{{$v->id}}" class="form-control j-sort" maxlength="5" style="height:25px;font-size:12px;padding:0 5px;"></td>
        <td>{{$v->name}}</td>
        <td>
          <a href="{{ url('adv/add', ['id' => $v->id]) }}" style="margin-right:5px;">编辑</a>
          <a href="{{ url('adv/delete', ['id' => $v->id]) }}" class="j-del text-danger">删除</a>
        </td>
      </tr>
      @endforeach
      @if(empty($adv))
      <tr><td colspan="4" class="text-center">还没有添加广告位</td></tr>
      @endif
    </tbody>
  </table>
</div>
<script>
main.menuActive('adv');
$('.j-del').click(function() {
    if (confirm('您确定要删除此项?')) {
    var data = { _token: '{{ csrf_token() }}' };
    main.ajaxPost({url:$(this).attr('href'), data: data}, function(){
        location.reload();
    });
    }
    return false;
});
</script>
@endsection

(5)在浏览器访问,其效果如下图:

(6)通过浏览器访问,单机“删除”按钮删除广告位,查看广告位是否删除成功。

六.广告内容管理

1.创建广告内容表

(1)创建广告内容表的迁移文件,在迁移文件的up()方法中添加表结构信息,具体代码如下:

public function up()
    {
        Schema::create('adcontent', function (Blueprint $table) {
            $table->increments('id')->comment('主键');
            $table->integer('advid')->comment('广告位id');
            $table->integer('path')->comment('图片路径');
            $table->timestamps();
        });

    }

(2)下面创建内容表对应的模型文件,具体代码如下:

php artisan make:model Advcontent

(3)执行上述命令后,会自动创建app\Advcontent.php文件,在文件中编写如下代码:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Advcontent extends Model
{
    protected $table = "adcontent";
    public $fillable = ['advid','path'];
}

2.添加、显示、编辑、删除广告

(1)创建Advcontent控制器,具体代码如下:

php artisan make:controller Admin\AdvcontentController

(2)在控制器中添加add()方法用于实现添加广告的功能,添加save()方法用于保存广告内容,添加upload()方法用于保存上传的广告图片,添加index()方法,添加delete()方法,具体代码如下:

public function add($id = 0){
        $data = [];
        if($id > 0){
            $data = Advcontent::find($id);
            if($data['path']){
                $data['path'] = explode("|", $data['path']);
            }else{
                $data['path'] = [];
            }
        }
        $position = Adv::all();
        return view('admin.advcontent.add', ['data' => $data, 'position' => $position]);
    }

    public function save(Request $request){
        $data = $request->all();
        $path = '';
        foreach($data['path'] as $v){
            $path .= $v . "|";
        }
        $data['path'] = substr($path,0,-1);
        if(isset($data['id'])){
            $id = $data['id'];
            unset($data['id']);
            unset($data['_token']);
            $res = Advcontent::where('id',$id)->update($data);
            $type = $res ? "message" : "tip";
            $message = $res ? "修改成功" : "修改失败";
            return redirect('advcontent')->with($type, $message);
        }

        $re = Advcontent::create($data);
        if($re){
            return redirect('advcontent')->with('message','添加成功');
        }else{
            return redirect('advcontent/add')->with('tip','添加失败');
        }
    }

    public function upload(Request $request){
        if ($request->hasFile('image')) {
            $image = $request->file('image');
            if ($image->isValid()) {
                $name = md5(microtime(true)) . '.' . $image->extension();
                $image->move('static/upload', $name);
                $path = '/static/upload/' . $name;
                $returndata  = array(
                    'filename' => $name,
                    'path' => $path
                );
                $result = [
                    'code' => 1,
                    'msg'  => '上传成功',
                    'time' => time(),
                    'data' => $returndata,
                ];

                return response()->json($result);
            }
            return $image->getErrorMessage();
        }
        return '文件上传失败';

    }

    public function index(){
        $adv = Advcontent::all();
        foreach($adv as $v){
            if($v['path']){
                $v['path'] = explode("|", $v['path']);
            }else{
                $v['path'] = [];
            }
        }
        return view('admin.advcontent.index', ['adv' => $adv]);
    }

    public function delete($id){
        if (!$content = Advcontent::find($id)) {
            return response()->json(['code' => 0, 'msg' => '删除失败,记录不存在。' ]);
        }
        $content->delete();
        return response()->json(['code' => 1, 'msg' => '删除成功' ]);
    }

(3)在控制器中引入广告位的命名空间,具体代码如下:

use App\Advcontent;
use App\Adv;

(4)创建resources\views\admin\advcontent\add.blade.php视图文件,具体代码如下:

@extends('admin/layouts/admin')
@section('title', '添加广告')
@section('main')
<div class="main-title"><h2><div class="main-title"><h2>@if(!empty($data))编辑@else添加@endif广告</h2></div>
<div class="main-section">
  <div style="width:543px">
    <form method="post" action="{{ url('/advcontent/save') }}">
      <div class="form-group row">
        <label class="col-sm-3 col-form-label">选择广告位</label>
        <div class="col-sm-9">
          <!-- 广告位列表 -->
          <select name="advid" class="form-control" style="width:200px;">
            @foreach ($position as $v)
            <option value="{{ $v->id }}" @if(isset($data->advposid) && $data->advposid == $v->id) selected @endif>
              {{ $v->name }}
            </option>
            @endforeach
          </select>
        </div>
      </div>
      <div class="form-group row">
        <label class="col-sm-3 col-form-label">上传图片</label>
        <div class="col-sm-9">
          <input type="file" id="file1" name="path" value="上传图片">
        </div>
        <div class="col-sm-9 offset-sm-3">
          <div class="upload-img-box" id="uploadImg">
            @if(isset($data->path))
            <div class="upload-pre-item" style="max-height:100%;">
                @foreach ($data->path as $val)
                <img src="/static/upload/{{$val}}"
                    style="width:100px;height:100px"/>
                <input type="hidden" name="path[]" value="{{$val}}"
                        class="icon_banner"/>
                @endforeach
            </div>
            @endif
          </div>
        </div>
      </div>
      <div class="form-group row">
        <div class="col-sm-9">
          {{csrf_field()}}
          @if(isset($data['id'])) <input type="hidden" name="id" value="{{$data->id}}"> @endif
          <button type="submit" class="btn btn-primary mr-2">提交表单</button>
          <a href="{{ url('advcontent') }}" class="btn btn-secondary">返回列表</a>
        </div>
      </div>
    </form>
  </div>
</div>
<link href="{{asset('admin')}}/common/uploader/uploadifive.css" rel="stylesheet" />
<script src="{{asset('admin')}}/common/uploader/jquery.uploadifive.js"></script>
<script>
main.menuActive('advcontent');
$(function(){
  $('#file1').uploadifive({
    'auto'       : true,
    'fileObjName'    : 'image',
    'fileType'     : 'image',
    'buttonText'     : '上传图片',
    'formData'     : { '_token' : "{{ csrf_token() }}" },
    'method'       : 'post',
    'queueID'      : 'uploadImg',
    'removeCompleted'  : true,
    'uploadScript'   : '{{ url('advcontent/upload')}}',
    'onUploadComplete' : uploadPicture_icon
  });
});
function uploadPicture_icon(file, data) {
  var obj = $.parseJSON(data);
  var src = '';
  if (obj.code) {
    filename = obj.data.filename;
    path = obj.data.path;
    if ($('.upload-pre-item').length > 0) {
        $('.upload-pre-item').append(
            '<img src="' + path + '" style="width:100px;height:100px"/> <input type="hidden" name="path[]" value="'+filename+'" class="icon_banner"/>'
        );
    } else {
      $('.upload-img-box').append(
        '<div class="upload-pre-item" style="max-height:100%;"><img src="' + path + '" style="width:100px;height:100px"/> <input type="hidden" name="path[]" value="'+filename+'" class="icon_banner"/></div>'
      );
    }
  } else {
    alert(data.info);
  }
}
</script>
@endsection

(5)创建index.php文件,具体代码如下:

@extends('admin/layouts/admin')
@section('title', '广告内容管理')
@section('main')
<div class="main-title"><h2>广告内容管理</h2></div>
<div class="main-section form-inline">
  <a href="{{ url('advcontent/add') }}" class="btn btn-success">+ 新增</a>
</div>
<div class="main-section">
  <table class="table table-striped table-bordered table-hover">
    <thead>
    <tr>
      <th width="75">序号</th><th>广告位名称</th><th>广告图片</th><th width="100">操作</th>
    </tr>
    </thead>
    <tbody>
    <!-- 广告位列表 -->
    @foreach($adv as $v)
      <tr class="j-pid-{{ $v['pid'] }}">
        <td><input type="text" value="{{$v->id}}" class="form-control j-sort" maxlength="5" style="height:25px;font-size:12px;padding:0 5px;"></td>
        <td>{{$v->position->name}}</td>
        <td>
          @foreach($v->path as $val)
            <img src="/static/upload/{{$val}}" style="height:40px;width: 50px">
          @endforeach
        </td>
        <td><a href="{{ url('advcontent/add', ['id' => $v->id]) }}" style="margin-right:5px;">编辑</a>

          <a href="{{ url('advcontent/delete', ['id' => $v->id]) }}" class="j-del text-danger">删除</a>
        </td>
      </tr>
    @endforeach
    @if(empty($adv))
      <tr><td colspan="4" class="text-center">还没有添加广告内容</td></tr>
    @endif
    </tbody>
  </table>
</div>
<script>
  main.menuActive('advcontent');
  $('.j-del').click(function() {
    if (confirm('您确定要删除此项?')) {
      var data = { _token: '{{ csrf_token() }}' };
      main.ajaxPost({url:$(this).attr('href'), data: data}, function(){
        location.reload();
      });
    }
    return false;
  });
</script>
@endsection

(6)在routes\web.php中添加广告位管理的路由组,具体代码如下:

//广告列表
Route::prefix('advcontent')->namespace('Admin')->middleware(['Admin'])->group(function () {
    Route::get('add/{id?}', 'AdvcontentController@add');
    Route::post('save', 'AdvcontentController@save');
    Route::post('upload','AdvcontentController@upload');
    Route::get('', 'AdvcontentController@index');
    route::post('delete/{id}','AdvcontentController@delete');
});

(7)修改app\Advcontent.php,设置关联模型,获取广告位信息,具体代码如下:

  public function position()
    {
        return $this->belongsTo('App\Adv', 'advid', 'id');
    }

(8)在Adv控制器中引入Advcontent的命名空间,具体代码如下:

use App\Content;

(9)通过浏览器访问,可以对广告内容进行显示、编辑、删除的操作。

 结语

综上所述便是使用Laravel框架实现内容管理系统的后台功能。项目展示图片如下图:

 

 

前台首页

一、页面布局

(1)在resources\views目录下创建public目录,该目录用于保存公共文件,在该目录下创建static.blade.php,用于保存静态文件,具体代码如下:

<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{{asset('home')}}/common/twitter-bootstrap/4.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="{{asset('home')}}/common/font-awesome-4.2.0/css/font-awesome.min.css">
<link rel="stylesheet" href="{{asset('home')}}/css/main.css">
<script src="{{asset('home')}}/common/jquery/1.12.4/jquery.min.js"></script>
<script src="{{asset('home')}}/common/twitter-bootstrap/4.4.1/js/bootstrap.min.js"></script>

(2)创建header.blade.php文件,具体代码如下:

<div class="header">
  <header>
    <div class="container">
      <a href="{{url("/")}}" style="color:#000000">
        <div class="header-logo"><span>内容</span>管理系统</div>
      </a>
      <ul class="header-right">
        @if(session()->has('users.name'))
          <li>
            <a href="#" class="j-layout-pwd">
              <i class="fa fa-user fa-fw"></i>{{ session()->get('users.name') }}
            </a>
          </li>
          <li><a href="{{ url('logout') }}"><i class="fa fa-power-off fa-fw"></i>退出</a></li>
        @else
          <li><a href="#" data-toggle="modal" data-target="#loginModal">登录</a></li>
          <li><a href="#" data-toggle="modal" data-target="#registerModal">注册</a></li>
        @endif
      </ul>
    </div>
  </header>
  <!-- 栏目列表 -->
  <nav class="navbar navbar-expand-md navbar-dark">
    <div class="container">
      <div></div>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-expanded="false" aria-controls="navbarSupportedContent" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav mr-auto">
          <li class="nav-item">
            <a class="nav-link" href="/">首页</a>
          </li>
          @foreach($category as $v)
            @if(isset($v['sub']))
              <li class="nav-item dropdown">
                <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                  {{$v['name']}}
                </a>
                <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                  @foreach($v['sub'] as $val)
                    <a class="dropdown-item" href="{{url('lists', ['id' => $val['id']] )}}">{{$val['name']}}</a>
                  @endforeach
                </div>
              </li>
            @else
              <li class="nav-item">
                <a class="nav-link" href="{{url('lists', ['id' => $v['id']] )}}">{{$v['name']}}</a>
              </li>
            @endif
          @endforeach
        </ul>
      </div>
    </div>
  </nav>
</div>
<!-- 登录表单 --->
<div class="modal fade" id="loginModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">登录</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <div class="form-group">
          <label for="username">用户名</label>
          <input type="text" name="name" class="form-control" id="username">
        </div>
        <div class="form-group">
          <label for="password">密码</label>
          <input type="password" name="password" class="form-control" id="password">
        </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
        <button type="submit" class="btn btn-primary" id="login">登录
        </button>
      </div>
    </div>
  </div>
</div>
<!-- 注册表单 --->
<div class="modal fade" id="registerModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">注册</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <div class="form-group">
          <label for="username1">用户名</label>
          <input type="text" name="name" class="form-control" id="username1">
        </div>
        <div class="form-group">
          <label for="email">邮箱</label>
          <input type="email" name="email" class="form-control" id="email">
        </div>
        <div class="form-group">
          <label for="password1">密码</label>
          <input type="password" name="password" class="form-control" id="password1">
        </div>
        <div class="form-group">
          <label for="confirm">确认密码</label>
          <input type="password" class="form-control" id="confirm">
        </div>
      </div>
      <div class="modal-footer">
        {{csrf_field()}}
        <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
        <button type="submit" class="btn btn-primary" id="register">立即注册</button>
      </div>
    </div>
  </div>
</div>
<script>
  $("#login").bind("click",function(){
    var data = {
      'name'   : $("#username").val(),
      'password' : $("#password").val(),
      '_token'   : "{{ csrf_token() }}"
    };
    $.post("{{ url('login') }}", data, function(result){
      if (result.status == 1) {
        alert(result.msg);
        window.location.reload();
      } else {
        alert(result.msg);
        return;
      }
    });
  });
  $("#register").bind("click",function(){
    var data = {
      'name'           : $("#username1").val(),
      'email'          : $("#email").val(),
      'password'         : $("#password1").val(),
      ' password_confirmation' : $("#confirm").val(),
      '_token'         : "{{ csrf_token() }}"
    };
    $.post("{{ url('register') }}", data, function(result){
      if (result.status == 1) {
        alert(result.msg);
        $('#registerModal').modal('hide');
        location.reload();
      } else {
        alert(result.msg);
        return;
      }
    });
  });
</script>

(3)创建resources\views\common\footer.blade.php文件,该文件用于保存页面底部的内容,具体代码如下:

<div class="footer">
  <div class="container">内容管理系统</div>
</div>

二、首页、栏目导航、轮播图、广告位、栏目内容展示

(1)创建首页视图,在resources\views目录下创建index.blade.php,具体代码如下:

<!DOCTYPE html>
<html>
<head>
  @include('public/static')
  <title>首页</title>
</head>
<body>
@include('public/header')
<div class="main">
  <div class="container">
    <div class="row mt-4">
      <!-- 轮播图 -->
      <div class="col-md-6 main-carousel">
        <div id="carouselExampleCaptions" class="carousel slide" data-ride="carousel">
          <div class="carousel-inner">
            @foreach($recommend as $k=>$con)
              <div class="carousel-item @if($k==0) active @endif">
                <img src="/static/upload/{{$con->image}}" class="d-block w-100">
                <a href="{{url('detail', ['id'=> $con->id])}}">
                  <div class="carousel-caption d-none d-md-block">
                    <h5>{{$con->title}}</h5>
                    <p></p>
                  </div>
                </a>
              </div>
            @endforeach
          </div>
          <a class="carousel-control-prev" href="#carouselExampleCaptions" role="button" data-slide="prev">
            <span class="carousel-control-prev-icon" aria-hidden="true"></span>
            <span class="sr-only">Previous</span>
          </a>
          <a class="carousel-control-next" href="#carouselExampleCaptions" role="button" data-slide="next">
            <span class="carousel-control-next-icon" aria-hidden="true"></span>
            <span class="sr-only">Next</span>
          </a>
        </div>
      </div>
      <!-- 广告位 -->
      <div class="col-md-6">
        <div class="row main-imgbox">
          @foreach($adv as $adval)
            <div class="col-md-6">
              <a href="#"><img class="img-fluid" src="/static/upload/{{$adval}}"></a>
            </div>
          @endforeach
        </div>
      </div>
    </div>
    <div class="row">
      <div class="col-md-9">
        <div class="row">
          <!-- 栏目内容 -->
          @foreach($list as $value)
          <div class="col-md-6 mb-4">
            <div class="card main-card">
              <div class="card-header">
                <h2>{{$value->name}}</h2>
                <span class="float-right">
                  <a href="{{ url('lists', ['id' => $value->id ])}}">[ 查看更多 ]</a>
                </span>
              </div>
              @foreach($value->content as $val)
              <div class="card-body">
                <div class="main-card-pic">
                  <a href="{{url('detail', ['id'=> $val->id])}}">
                    <img class="img-fluid" src="/static/upload/{{$val->image}}">
                    <span><i class="fa fa-search"></i></span>
                  </a>
                </div>
                <div class="main-card-info">
                  <span><i class="fa fa-calendar"></i>
                  {{ date('Y-m-d', strtotime($val->created_at)) }}</span>
                </div>
                <h3><a href="{{url('detail', ['id'=> $val->id])}}">{{$val->title}}</a></h3>
                <div class="main-card-desc">{!!str_limit($val->content , 100)!!}</div>
              </div>
              @endforeach
            </div>
          </div>
          @endforeach
        </div>
      </div>
      <div class="col-md-3">
        <!-- 侧边栏 -->
        @include('public/sidebar')
      </div>
    </div>
  </div>
</div>
@include('public/footer')
</body>
</html>

(2)创建Index控制器,具体代码如下:

php artisan make:controller IndexController

(3)在控制器中添加方法,具体代码如下:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Category;
use App\Content;
use App\Adv;
use App\Like;
use App\Comment;
use Illuminate\Support\Facades\DB;

class IndexController extends Controller
{
    public function index()
    {
        $this->navBar();
        $this->hotContent();
        $recommend = Content::where('status', '2')->get();   // 新增代码
        $advcontent = [];
        $advlist = Adv::where('name', 'imgbox')->get();
        foreach ($advlist as $key => $value) {
            foreach ($value->content as $k => $v) {
                $advcontent= explode('|', $v->path);
            }
        }
        $list = Category::orderBy('id', 'desc')->get()->take(4);
        return view('index', ['recommend' => $recommend, 'adv' => $advcontent, 'list' => $list]);

    }

    protected function navBar(){
        $data = Category::orderBy('sort', 'asc')->get()->toArray();
        $category = $sub = [];
        foreach($data as $k=>$v){
            if ($v['pid'] != 0) {
                $sub[$v['id']] = $v;
            }
        }
        foreach($data as $key=>$val){
            if ($val['pid'] == 0) {
                $category[$key] = $val;
            }
            foreach($sub as $subv) {
                if ($subv['pid'] == $val['id']) {
                    $category[$key]['sub'][] = $subv;
                }
            }
        }
        return view()->share('category', $category);
    }

    public function lists($id)
    {
        if(!$id){
            return redirect('/')->with('tip','缺少参数');
        }
        $this->navBar();
        $this->hotContent();
        $content = Content::where('cid', $id)->paginate(4);
        return view('lists', ['id' => $id, 'content' => $content]);
    }

    public function detail($id)
    {
        if(!$id){
            return redirect('/')->with('tip','缺少参数');
        }
        $this->navBar();
        $this->hotContent();
        $content = Content::find($id);
        $count = Like::where('cid', $id)->get()->count();
        $comments = Comment::where('cid', $id)->get();
        return view('detail', ['id' => $content->id, 'cid' => $content->cid,
            'content' => $content, 'count' => $count, 'comments' => $comments]);
    }

    public function like($id)
    {
        if(!$id){
            return response()->json(['status'=>'2','msg'=>'缺少参数']);
        }
        @session_start();
        $data = array(
            'uid' => session()->get('users.id'),
            'cid' => $id
        );
        $re = Like::create($data);
        if($re){
            $count = Like::where('cid', $id)->get()->count();
            return response()->json(['status'=>'1', 'msg'=>'点赞成功', 'count'=>$count]);
        }else{
            return response()->json(['status'=>'2', 'msg'=>'点赞失败']);
        }
    }

    public function comment(Request $request)
    {
        $cid = $request->input('cid');
        $content = $request->input('content');
        $uid = session()->get('users.id');
        if(!$content){
            return response()->json(['status'=>'2', 'msg'=>'缺少参数']);
        }
        $data = array(
            'uid' => $uid,
            'cid' => $cid,
            'content' => $content,
        );
        $re = Comment::create($data);
        if ($re) {
            $theComment = Comment::where('cid', $cid)->where('uid', $uid)->orderBy('id','desc')->first();
            $theComment->created_time = date('Y-m-d', strtotime($theComment->created_at));
            $count = Comment::where('cid', $cid)->get()->count();
            $theComment->count = $count;
            $theComment->user = $theComment->user->name;
            return response()->json(['status' => '1', 'msg' => '评论成功',
                'data' => $theComment]);
        } else {
            return response()->json(['status' => '2', 'msg' => '评论失败']);
        }

    }

    protected function hotContent(){
        $hotContent = Like::select('cid',DB::raw('count(*) as num'))->orderBy('num', 'desc')->groupBy('cid')->get()->take(2);
        return view()->share('hotContent', $hotContent);
    }


}

(4)在routes\web.php文件中添加路由规则,具体代码如下:

// 首页
Route::get('/', 'IndexController@index');
Route::get('/lists/{id}', 'IndexController@lists');
Route::get('/detail/{id}', 'IndexController@detail');
Route::get('/like/{id}', 'IndexController@like');
Route::get('/comment', 'IndexController@comment');
Route::post('/register', 'UserController@register');
Route::post('/login', 'UserController@login');
Route::get('/logout', 'UserController@logout');

(5)修改app\Adv.php,设置关联模型,具体代码如下:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Adv extends Model
{
    protected $table = "adv";
    public $fillable = ['name'];

    public function content()
    {
        return $this->hasMany('App\Advcontent', 'advid', 'id');
    }

}

(6)修改app\Category.php,设置关联模型,具体代码如下:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    protected $table = "category";
    public $fillable = ['pid', 'name', 'sort'];
    public function content()
    {
        return $this->hasMany('App\Content', 'cid', 'id')->orderBy('id', 'desc')->limit(1);
    }
}

(7)通过浏览器访问,看看是否完整显示。

前台用户管理

用户注册、用户登录和用户退出

(1)在header.blade.php视图中添加注册表单、登录表单,具体代码如下:

<div class="header">
  <header>
    <div class="container">
      <a href="{{url("/")}}" style="color:#000000">
        <div class="header-logo"><span>内容</span>管理系统</div>
      </a>
      <ul class="header-right">
        @if(session()->has('users.name'))
          <li>
            <a href="#" class="j-layout-pwd">
              <i class="fa fa-user fa-fw"></i>{{ session()->get('users.name') }}
            </a>
          </li>
          <li><a href="{{ url('logout') }}"><i class="fa fa-power-off fa-fw"></i>退出</a></li>
        @else
          <li><a href="#" data-toggle="modal" data-target="#loginModal">登录</a></li>
          <li><a href="#" data-toggle="modal" data-target="#registerModal">注册</a></li>
        @endif
      </ul>
    </div>
  </header>
  <!-- 栏目列表 -->
  <nav class="navbar navbar-expand-md navbar-dark">
    <div class="container">
      <div></div>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-expanded="false" aria-controls="navbarSupportedContent" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav mr-auto">
          <li class="nav-item">
            <a class="nav-link" href="/">首页</a>
          </li>
          @foreach($category as $v)
            @if(isset($v['sub']))
              <li class="nav-item dropdown">
                <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                  {{$v['name']}}
                </a>
                <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                  @foreach($v['sub'] as $val)
                    <a class="dropdown-item" href="{{url('lists', ['id' => $val['id']] )}}">{{$val['name']}}</a>
                  @endforeach
                </div>
              </li>
            @else
              <li class="nav-item">
                <a class="nav-link" href="{{url('lists', ['id' => $v['id']] )}}">{{$v['name']}}</a>
              </li>
            @endif
          @endforeach
        </ul>
      </div>
    </div>
  </nav>
</div>
<!-- 登录表单 --->
<div class="modal fade" id="loginModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">登录</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <div class="form-group">
          <label for="username">用户名</label>
          <input type="text" name="name" class="form-control" id="username">
        </div>
        <div class="form-group">
          <label for="password">密码</label>
          <input type="password" name="password" class="form-control" id="password">
        </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
        <button type="submit" class="btn btn-primary" id="login">登录
        </button>
      </div>
    </div>
  </div>
</div>
<!-- 注册表单 --->
<div class="modal fade" id="registerModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">注册</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <div class="form-group">
          <label for="username1">用户名</label>
          <input type="text" name="name" class="form-control" id="username1">
        </div>
        <div class="form-group">
          <label for="email">邮箱</label>
          <input type="email" name="email" class="form-control" id="email">
        </div>
        <div class="form-group">
          <label for="password1">密码</label>
          <input type="password" name="password" class="form-control" id="password1">
        </div>
        <div class="form-group">
          <label for="confirm">确认密码</label>
          <input type="password" class="form-control" id="confirm">
        </div>
      </div>
      <div class="modal-footer">
        {{csrf_field()}}
        <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
        <button type="submit" class="btn btn-primary" id="register">立即注册</button>
      </div>
    </div>
  </div>
</div>
<script>
  $("#login").bind("click",function(){
    var data = {
      'name'   : $("#username").val(),
      'password' : $("#password").val(),
      '_token'   : "{{ csrf_token() }}"
    };
    $.post("{{ url('login') }}", data, function(result){
      if (result.status == 1) {
        alert(result.msg);
        window.location.reload();
      } else {
        alert(result.msg);
        return;
      }
    });
  });
  $("#register").bind("click",function(){
    var data = {
      'name'           : $("#username1").val(),
      'email'          : $("#email").val(),
      'password'         : $("#password1").val(),
      ' password_confirmation' : $("#confirm").val(),
      '_token'         : "{{ csrf_token() }}"
    };
    $.post("{{ url('register') }}", data, function(result){
      if (result.status == 1) {
        alert(result.msg);
        $('#registerModal').modal('hide');
        location.reload();
      } else {
        alert(result.msg);
        return;
      }
    });
  });
</script>

(2)创建User控制器,具体代码如下:

php artisan make:controller UserController

(3)在User控制器中添加方法,具体代码如下:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use App\User;
use Illuminate\Support\Facades\Session;


class UserController extends Controller
{
    public function register(Request $request)
    {
        $rule = [
            'name' => 'required|unique:users',
            'email' => 'required|email',
            'password' => 'required|min:6',
            'password_confirmation' => 'required'
        ];
        $message = [
            'name.require' => '用户名不能为空',
            'name.unique' => '用户名不能重复',
            'email.require' => '邮箱不能为空',
            'email.email' => '邮箱格式不符合规范',
            'password.require' => '密码不能为空',
            'password.min' => '密码最少为6位',
            'password.confirmed' => '密码和确认密码不一致'
        ];
        $validator = Validator::make($request->all(), $rule, $message);
        if ($validator->fails()) {
            foreach ($validator->getMessageBag()->toArray() as $v) {
                $msg = $v[0];
            }
            return response()->json(['status' => '2', 'msg' => $msg]);
        }
        $re = User::create($request->all());
        if ($re) {
            Session::put('users', ['id' => $re->id, 'name' => $re->name]); // 注册成功后保存登录状态
            return response()->json(['status' => '1', 'msg' => '注册成功']);
        } else {
            return response()->json(['status' => '2', 'msg' => '注册失败']);
        }

    }

    public function login(Request $request)
    {
        $rule = [
            'name' => 'required|bail',
            'password' => 'required|min:6'
        ];
        $message = [
            'name.required' => '用户名不能为空',
            'password.required' => '密码不能为空',
            'password.min' => '密码最少为6位'
        ];
        $validator = Validator::make($request->all(), $rule, $message);
        if ($validator->fails()) {
            foreach ($validator->getMessageBag()->toArray() as $v) {
                $msg = $v[0];
            }
            return response()->json(['status'=>'2', 'msg'=>$msg]);
        }
        $name = $request->get('name');
        $password = $request->get('password');
        $theUser = User::where('name', $name)->first();
        if ($theUser) {
            if ($password == $theUser->password) {
                Session::put('users', ['id' => $theUser->id,'name' => $name]);
                return response()->json(['status' => '1', 'msg' => '登录成功']);
            } else {
                return response()->json(['status' => '2', 'msg' => '密码错误']);
            }
        } else {
            return response()->json(['status' => '2', 'msg' => '用户不存在']);
        }
    }

    public function logout()
    {
        if (request()->session()->has('users')) {
            request()->session()->pull('users', session('users'));
        }
        return redirect('/');
    }

}

内容列表页

一、内容列表

(1)在resources\views目录下创建lists.blade.php,具体代码如下:

<!DOCTYPE html>
<html>
<head>
  @include('public/static')
  <title>列表页</title>
</head>
<body>
@include('public/header')
<div class="main">
  <div class="main-crumb">
    <div class="container">
      <!-- 面包屑导航 -->
      <nav aria-label="breadcrumb">
        {!! Breadcrumbs::render('category', $id); !!}
      </nav>
    </div>
  </div>
  <div class="container">
    <div class="row">
      <div class="col-md-9">
        <div class="row">
          <!-- 内容列表 -->
          @foreach($content as $con)
          <div class="col-md-6 mb-4">
            <div class="card main-card">
              <div class="main-card-pic">
                <a href="{{ url('detail', ['id' => $con->id ])}}">
                  <img class="img-fluid" src="@if($con->image)/static/upload/{{$con->image}}@else {{asset('admin')}}/img/noimg.png @endif">
                  <span><i class="fa fa-search"></i></span>
                </a>
              </div>
              <div class="card-body">
                <div class="main-card-info">
                  <span><i class="fa fa-calendar"></i>{{ date('Y-m-d', strtotime($con->created_at)) }}</span>
                  <span><i class="fa fa-comments"></i>{{$con->comments->count()}}</span>
                </div>
                <h3><a href="{{ url('detail', ['id' => $con->id ])}}">{{$con->title}}</a></h3>
                <div class="main-card-desc">{{str_limit(strip_tags($con->content),100)}}</div>
              </div>
              <a href="{{ url('detail', ['id' => $con->id ])}}" class="main-card-btn">阅读更多</a>
            </div>
          </div>
          @endforeach
        </div>
        {{ $content->links()}}
      </div>
      <div class="col-md-3">
        <!-- 侧边栏 -->
        @include('public/sidebar')
      </div>
    </div>
  </div>
</div>
@include('public/footer')
</body>
</html>

(2)通过浏览器访问内容列表页,可看到其效果。

二、面包屑导航

1.安装

(1)使用Composer载入laravel-breadcrumbs库,具体代码如下:

composer require davejamesmiller/laravel-breadcrumbs

(2)在config\app.php文件中将这个服务提供者注册到Laravel中,具体代码如下:

    'providers' => [

        ...(原有代码)
        DaveJamesMiller\Breadcrumbs\BreadcrumbsServiceProvider::class,

    ],

(3)在config\app.php文件中注册别名,以方便使用,具体代码如下:

 'aliases' => [

        ...(原有代码)
        'Breadcrumbs' => DaveJamesMiller\Breadcrumbs\Facades\Breadcrumbs::class,

    ],
2.配置导航

(1)配置首页的导航链接,创建routes\breadcrumbs.php文件,具体代码如下:

<?php
use DaveJamesMiller\Breadcrumbs\Facades\Breadcrumbs;
use App\Category;
use App\Content;

Breadcrumbs::register('home', function($breadcrumbs){
    $breadcrumbs->push('首页', route('home'));
});

Breadcrumbs::register('category', function ($breadcrumbs, $id) {
    $category = Category::find($id);
    $breadcrumbs->parent('home');
    $breadcrumbs->push($category->name, route('category', $id));
});

Breadcrumbs::register('detail', function ($breadcrumbs, $posts) {
    $content = Content::find($posts['id']);
    $breadcrumbs->parent('category', $posts['cid']);
    $breadcrumbs->push($content->title, route('detail', $posts['id']));
});

(2)通过浏览器访问内容列表页,查看面包屑导航效果。

内容展示

一、内容详细页

resources\views目录下创建detail.blade.php,具体代码如下:

<!DOCTYPE html>
<html>
<head>
  @include('public/static')
  <title>详细页</title>
</head>
<body>
@include('public/header')
<div class="main">
  <div class="main-crumb">
    <div class="container">
      <!-- 面包屑导航 -->
      <nav aria-label="breadcrumb">
        {!! Breadcrumbs::render('detail', ['id'=>$id,'cid'=>$cid]); !!}
      </nav>
    </div>
  </div>
  <div class="container">
    <div class="row">
      <div class="col-md-9">
        <!-- 内容区域 -->
        <article class="main-article">
          <header>
            <h1>{{$content->title}}</h1>
            <div>发表于{{ date('Y-m-d', strtotime($content->create_time)) }}</div>
          </header>
          <div class="main-article-content">
            <p><img class="img-fluid" src="/static/upload/{{$content->image}}"></p>
            <p>{!! $content->content !!}</p>
          </div>
          <!-- 点赞模块 -->
          @if(session()->has('users'))
            <div class="main-article-like">
              <span>
              <i class="fa fa-thumbs-up" aria-hidden="true">{{$count}}</i>
              </span>
            </div>
          @endif
        </article>
        <div class="main-comment">
          <!-- 评论列表 -->
          @if(!$comments->isEmpty())
            <div class="main-comment-header">
              <span id="count">{{$comments->count()}}</span> 条评论
            </div>
            @foreach($comments as $val)
              <div class="main-comment-item">
                <div class="main-comment-name">{{$val->user->name}}</div>
                <div class="main-comment-date">
                  {{ date('Y-m-d', strtotime($val->created_at)) }}</div>
                <div class="main-comment-content">{{$val->content}}</div>
              </div>
            @endforeach
          @endif
        </div>
        <!-- 发表评论模块 -->
        <div class="main-reply">
          @if(session()->has('users'))
            <div class="main-reply-header">发表评论</div>
            <div class="main-reply-title">评论内容</div>
            <div><textarea name="content" rows="8" id="content"></textarea></div>
            <div>
              <input type="hidden" id='c_id' value="{{$id}}">
              <input type="button" value="提交评论" id="publish">
            </div>
          @endif
        </div>
      </div>
      <div class="col-md-3">
        <!-- 侧边栏 -->
        @include('public/sidebar')
      </div>
    </div>
  </div>
</div>
@include('public/footer')
</body>
<script>
  $(document).ready(function() {
    $(".fa-thumbs-up").bind("click", function () {
      $.get("{{ url('like', $id) }}", {}, function (result) {
        var count = result.count;
        $(".fa-thumbs-up").html();
        $(".fa-thumbs-up").html(count);
      });
    });

    $('#publish').bind("click",function(){
      var data = {
        'cid' : $("#c_id").val(),
        'content' : $("#content").val()
      };
      $.get("{{ url('comment') }}",data, function(result){
        var data = result.data;
        var user = data.user;
        var html = '<div class="main-comment-item">';
        html += '<div class="main-comment-name">' + user['name'] + '</div>';
        html += '<div class="main-comment-date">';
        html += data['created_time'];
        html += '</div>';
        html += '<div class="main-comment-content">';
        html += data['content'] + '</div>';
        html += '</div>';
        $(".main-comment").append(html);
        $("#count").html();
        $("#count").html(data['count']);
      });
    });
  });
</script>
</html>

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,我可以为您提供一个简单的 Laravel 图书管理系统的概述。这个系统将包含以下功能: 1. 用户登录和注册 2. 图书列表和详情页面 3. 添加、编辑和删除图书 4. 用户借阅和归还图书 首先,您需要创建一个名为 "book_management_system" 的新 Laravel 项目。您可以使用以下命令创建: ``` composer create-project --prefer-dist laravel/laravel book_management_system ``` 接下来,您需要创建一个名为 "books" 的数据库表,其中包含以下列: - id - title - author - description - quantity 您可以使用 Laravel 的迁移工具创建此表。运行以下命令: ``` php artisan make:migration create_books_table --create=books ``` 然后,编辑 "database/migrations/xxxx_xx_xx_xxxxxx_create_books_table.php" 文件,添加如下列: ``` Schema::create('books', function (Blueprint $table) { $table->id(); $table->string('title'); $table->string('author'); $table->text('description'); $table->integer('quantity'); $table->timestamps(); }); ``` 接下来,运行以下命令来运行迁移: ``` php artisan migrate ``` 接下来,您需要创建一个名为 "Book" 的模型。运行以下命令: ``` php artisan make:model Book ``` 编辑 "app/Models/Book.php" 文件,添加以下代码: ``` namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Book extends Model { use HasFactory; protected $fillable = [ 'title', 'author', 'description', 'quantity', ]; } ``` 接下来,您需要创建一个名为 "BooksController" 的控制器。运行以下命令: ``` php artisan make:controller BooksController --resource ``` 编辑 "app/Http/Controllers/BooksController.php" 文件,添加以下代码: ``` namespace App\Http\Controllers; use App\Models\Book; use Illuminate\Http\Request; class BooksController extends Controller { public function index() { $books = Book::all(); return view('books.index', ['books' => $books]); } public function create() { return view('books.create'); } public function store(Request $request) { $book = Book::create($request->all()); return redirect()->route('books.show', ['book' => $book->id]); } public function show(Book $book) { return view('books.show', ['book' => $book]); } public function edit(Book $book) { return view('books.edit', ['book' => $book]); } public function update(Request $request, Book $book) { $book->update($request->all()); return redirect()->route('books.show', ['book' => $book->id]); } public function destroy(Book $book) { $book->delete(); return redirect()->route('books.index'); } } ``` 这个控制器将处理图书的增删改查操作。 接下来,您需要创建视图。创建以下视图文件: 1. "books/index.blade.php":显示所有图书列表 2. "books/show.blade.php":显示单独图书详情 3. "books/create.blade.php":显示添加图书的表单 4. "books/edit.blade.php":显示编辑图书的表单 在这些视图文件中,您需要使用 Laravel 的表单构建器来创建表单,以便用户可以添加、编辑和删除图书。 接下来,您需要创建路由。编辑 "routes/web.php" 文件,添加以下代码: ``` Route::get('/', function () { return view('welcome'); }); Route::get('/books', [BooksController::class, 'index'])->name('books.index'); Route::get('/books/create', [BooksController::class, 'create'])->name('books.create'); Route::post('/books', [BooksController::class, 'store'])->name('books.store'); Route::get('/books/{book}', [BooksController::class, 'show'])->name('books.show'); Route::get('/books/{book}/edit', [BooksController::class, 'edit'])->name('books.edit'); Route::put('/books/{book}', [BooksController::class, 'update'])->name('books.update'); Route::delete('/books/{book}', [BooksController::class, 'destroy'])->name('books.destroy'); ``` 这些路由将处理图书管理系统的各种操作。 最后,您可以在图书模型中添加 "borrower" 和 "borrowed_at" 两个列来实现用户借阅和归还图书的功能。然后,您可以在视图中添加相应的表单和路由来处理这些操作。 这是一个简单的 Laravel 图书管理系统的概述。当然,实际开发过程中需要更多的代码和配置,但这应该可以帮助您了解 Laravel 的基本结构和工作方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值