Using Laravel to implement content management system projects

Table of contents

Project Introduction

Install Laravel

Configuration file 

Introduce the required static files

1. Backend user login 

1. Create user table

2. Display the login page

3.Ajax interaction

4. Verify user login

 5. User exits

2. Backend home page

1.Backend page layout

2. Display the background homepage

3. Determine login status

3. Column management

1. Create column table

2. Add a column

3. Display column list

4. Edit column 

5. Delete column

4. Content Management

1. Create a table of contents

2. Add content

3. Upload pictures

4. Integrate UFditor

5. Display content list

6. Edit content

7. Delete content

5. Advertising space management

1. Create an ad slot table

2. Add advertising space

3. Display, edit and delete ad slot list

6. Advertising content management

1. Create an advertising content table

2. Add, display, edit, delete ads

 Conclusion

Front page

1. Page layout

2. Home page, column navigation, carousel images, advertising spaces, and column content display

Front desk user management

User registration, user login and user logout

Content list page

1. Content list

2. Breadcrumb navigation

1.Installation

2. Configure navigation

Content display

1. Content details page


Project Introduction

This project is divided into front-end and back-end . The functions of the front desk include user login and registration , content list , content detail page , advertising display , comments and popular content , etc. The background will automatically jump to the login page if you are not logged in . After entering the user name "admin" , password "123456" and verification code , click the "Login" button to log in. After logging in, the currently logged in user name "admin" and the "Exit" button are displayed on the right side of the top of the page. Click the "Exit" button to exit the backend system. There is a menu bar on the left side of the background page , and the user can select a menu item in the menu bar to operate. The technical points that need to be used in the project include file upload , paging and session technology . The entire project development is completed based on the steps to realize the function. First, the backend development is implemented, data support is provided, and then the front-end data display is completed.

Install Laravel

First select which file you want to install Laravel in, and then select that file to execute the installation Laravel command: composer create-project --prefer-dist laravel/laravel ./ 5.8.*

For example, if I want to download Laravel in phpstudy_pro->WWW  on the D drive  , select  the phpstudy_pro->WWW file on the D drive, then write cmd on the file and press the Enter key to enter the terminal of the file. , and then execute the command to install Laravel. The operation is shown in the figure below.

Configuration file 

After Laravel is installed, create a virtual host in Apache's conf\extra\httpd-vhosts.conf configuration file. The specific configuration is:

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

Then, edit Apache's hosts file and add a parsing record "127.0.0.1 cms.com". As shown below.

 Log in to the MySQL server, create the database cms , and use cms as the database of the content management system.

Open the project and change the database name to cms in the config\database.php database configuration file . 

Configure the correct database configuration information in the .env file . Once all is complete, the database can be accessed within the project. 

Introduce the required static files

1. Backend user login 

1. Create user table

(1) Execute the following command on the command line to create a migration file. The specific command is as follows:

php artisan make:migration create_admin_user_table

(2) After executing the above command, a file with the time prefix _create_admin_user_table.php will be generated in the database\migrations directory .

(3) Add table structure information in the up() method of the migration file. The specific code is as follows:

 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) After the migration file is created, use the following command to execute the migration

php artisan migrate

(5) The above command will execute the up() method in the migration file to complete the creation of the data table.

(6) Create a fill file, the specific command is as follows:

php artisan make:seeder AdminuserTableSeeder

(7) After executing the above command, the corresponding migration file will be generated in the database\seeds directory, and the file name will be AdminuserTableSeeder.php.

(8) Write the filling code in the run() method of the filling file:

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) Execute the fill file command:

php artisan db:seed --class=AdminuserTableSeeder

(10) After the database is successfully created, create the user model:

php artisan make:model Admin

(11) Open app\Admin.php and specify the table name to be operated on in the model. The specific code is as follows:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

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

2. Display the login page

(1) Create a User controller, the specific code is as follows:

php artisan make:controller Admin/UserController

(2) After executing the above command, UserController.php will be created in the app\Http\Controllers\Admin directory , and the namespace is App\Http\Controllers\Admin .

(3) Open UserController.php and create the login() method. The specific code is as follows:

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

(4) Add routing rules in the routes\web.php file. The specific code is as follows:

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

(5) Create the admin directory in the resources\views directory, which is used to store background-related template files. Create the login.blade.php file in the admin directory. The specific code is as follows:

<!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) Introduce static files in line 6 above. The specific code is as follows:

    <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) Define the login form under the comment login form. The specific code is as follows:

<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) Use Composer to load the mews/captcha verification code library. The specific code is as follows:

composer require mews/captcha=3.0

(9) Create a configuration file for the verification code. The specific commands are as follows:

php artisan vendor:publish

(10) After executing the above command, enter the serial number "9" in the command line and press the "Enter" key, the config\captcha.php file will be automatically generated .

(11) Edit the config\captcha.php file and change the number of characters to 4. The specific code is as follows:

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

(12) Register the verification code service to the server in config\app.php . The specific code is as follows:

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

(13) Register an alias for the verification code service in the config\app.php file. The specific code is as follows:

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

(14) Add the verification code in the login form, the specific code is as follows:

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

(15) Accessed through a browser, the page effect is as follows:

(16) To implement the function of replacing the verification code after the single-machine verification code image, write JavaScript code in the template. The specific code is as follows:

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

3.Ajax interaction

(1) Open the public\admin\js\main.js file and add the following code:

(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) Write the ajaxPost() method in the main object . The specific code is as follows:

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) Write the ajaxForm() method in main.js to change the form to Ajax submission method. The specific code is as follows:

 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. Verify user login

(1) Add routing rules in the routes\web.php file. The specific code is as follows:

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

(2) Create the check() method in UserController.php . The specific code is as follows:

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) Some classes used in the above code need to be imported into the namespace. The specific code is as follows:

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

(4) Add code in the <script> tag of login.blade.php . The specific code is as follows:

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

(5) Access through the browser and enter a password less than 6 digits, and the error message "The password must be at least 6 digits" appears on the page; if the verification code is entered incorrectly, the error message "The verification code is incorrect" appears on the page; if you submit the correct Username (admin) and password (123456), a "login successful" prompt will appear on the page.

 

 

 5. User exits

(1) Add the logout() method in the User controller. The specific code is as follows:

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

(2) Add routing rules in the routes\web.php file. The specific code is as follows:

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

(3) Access through a browser. After ensuring that the user has logged in, visit http://cms.com/index.php/admin/logout. The browser will automatically jump to the login page, indicating that the user has successfully logged out.

2. Backend home page

1.Backend page layout

(1) Create the admin.blade.php file in the layouts directory. The specific code is as follows:

<!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) Introduce static resources into the page, the specific code is as follows:

  <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) Define the left navigation bar in the page. The specific code is as follows:

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

(4) Add the homepage menu, the specific code is as follows:

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

(5) Add column menu, the specific code is as follows:

        <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) Add content form, the specific code is as follows:

        <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) Add an advertising form, the specific code is as follows:

         <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) Add a message form, the specific code is as follows:

@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) Add the <script> tag before the end of the <body> tag to control the display time of the message template. The specific code is as follows:

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

(10) Modify the public\admin\js\main.js file and write the layout() method. The specific code is as follows:

 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) Add the menuActive() method in main.js to set the specified menu item as selected. The specific code is as follows:

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) Call the layout() method in the <script> tag . The specific code is as follows:

main.layout();

2. Display the background homepage

(1) After the public file is created, create the backend homepage admin\index.blade.php. The specific code is as follows:

@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) Create an Index controller, the specific code is as follows:

php artisan make:controller Admin\IndexController

(3) Add the index() method in the Index controller . The specific code is as follows:

    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) In the above code, the sixth line of code calls the getMySQLVer() method to obtain the MySQL version and creates the getMySQLVer() method. The specific code is as follows:

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

 (5) In the getMySQLVer() method, use the DB class to execute SQL, obtain the MySQL version, and import the namespace of the DB class. The specific code is as follows:

use DB;

(6) Add routing rules in the routes\web.php file. The specific code is as follows:

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

 (7) Access the backend homepage through the browser, the effect is as follows:

3. Determine login status

(1) Create Admin middleware to verify whether the user is logged in. The specific code is as follows:

php artisan make:middleware Admin

(2) Open app\Http\Middleware\Admin.php and add the code to verify user login. The specific code is as follows:

 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) Register the routing middleware in the app\Http\Kernel.php file. The specific code is as follows:

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

(4) Modify the routing rules of the home page and add user verification to the background home page. The specific code is as follows:

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

3. Column management

1. Create column table

(1) The column table is also created through the command line. Follow the previous steps to create the migration file and fill file.

(2) Open the migration file of the column table and add the table structure information in the up() method of the file. The specific code is as follows:

 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) After the column table is created, in order to operate the column table in the project, create the model file corresponding to the column table. The specific code is as follows:

php artisan make:model Category

(4) Open the app\Category.php file, the specific code is as follows:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

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

2. Add a column

(1) Create a Category controller, the specific code is as follows:

php artisan make:controller Admin\CategoryController

(2) Add the add() method in the controller to implement the function of adding columns. The specific code is as follows:

<?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) Create the admin\category\add.blade.php view file. The specific code is as follows:

@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) Add routing rules in the routes\web.php file. The specific code is as follows:

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

(5) Modify the layout file admin.blade.php and add a link for the navigation of the added column. The specific code is as follows:

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

(6) Write the save() method in the Category controller to receive the form data for adding columns. The specific code is as follows:

 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) Add routing rules in the routing group of the column in the routes\web.php file. The specific code is as follows:

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

3. Display column list

(1) Create the index() method in the Category controller . The specific code is as follows:

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

(2) Add the getTreeListCheckLeaf() method and treeList() method to the Category model . The specific codes are as follows:

 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) Create the view file index.php , the specific code is as follows:

@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) Add the routing rules for the column list in the routing group of the column in the routes\web.php file. The specific code is as follows:

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

(5) Modify admin.blade.php and add links to the list menu items. The specific code is as follows:

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

(6) Accessed through a browser, the page effect of the column list is as shown below:

(7) In the column list page, in order to modify the sorting of columns, it is necessary to set the submission address of the form in the column list page. The specific code is as follows:

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

(8) Add sorted routing rules in the routing group of the column in the routes\web.php file. The specific code is as follows:

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

(9) Add the sort() method in the Category controller . The specific code is as follows:

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) Access through the browser and observe whether the column functions are executed correctly.

4. Edit column 

(1) Add a link to the "Edit" button in the list page. The specific code is as follows:

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

(2) Add the routing rules for the editing column in the routing group of the column in the routes\web.php file. The specific code is as follows:

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

(3) Add the edit() method in the Category controller. The specific code is as follows:

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) Create the view file edit.blade.php , the specific code is as follows:

@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) Modify the save() method to update the column content according to the column ID. The specific code is as follows:

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. Delete column

(1) Add a link to the "Delete" button in the list page. The specific code is as follows:

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

(2) Add the delete() method in the Category controller . The specific code is as follows:

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

(3) Add routing rules for deleting columns in the column routing group of the routes\web.php file. The specific code is as follows:

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

4. Content Management

1. Create a table of contents

(1) After creating the migration file corresponding to the content table according to the above steps, add the table structure information in the up() method of the migration file. The specific code is as follows:

 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) Create a model file corresponding to the content table. The specific code is as follows:

php artisan make:model Content

(3) After executing the above command, the app\Content.php file will be automatically created . The specific code is as follows:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

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

2. Add content

(1) Create a Content controller, the specific code is as follows:

php artisan make:controller Admin\ContentController

(2) The add() method is introduced in the controller to implement the function of adding content, and the save() method saves the added content. The specific code is as follows:

 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) Import the namespace of the Category model and the namespace of Content in the controller . The specific code is as follows:

use App\Category;
use App\Content;

(4) Create the resources\views\admin\content\add.blade.php view file. The specific code is as follows:

@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) Add the content management routing group in the routes\web.php file. The specific code is as follows:

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

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

(6) Modify admin.blade.php and add links to menu items for adding content. The specific code is as follows:

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

3. Upload pictures

(1) Add a button to upload pictures in the view of adding content. The specific code is as follows:

<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) Introduce the styles and JavaScript code required for uploading files into the view. The specific code is as follows:

<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) Write the upload() method in the Content controller. The specific code is as follows:

 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) Add routing rules for uploading images in the routing group of the content in the routes\web.php file. The specific code is as follows:

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

4. Integrate UFditor

(1) Create the public\admin\common\editor\main.editor.js file. The specific code is as follows:

(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) Introduce editor-related files into the add.blade.php file. The specific code is as follows:

<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. Display content list

(1) Write the index() method in the Content controller . The specific code is as follows:

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) When displaying content, the columns corresponding to the content need to be displayed, so add an association model to the Content model. The specific code is as follows:

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

(3) Create the resources\views\admin\content\index.blade.php file. The specific code is as follows:

@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) Add the route of the content list page in the routes\web.php file. The specific code is as follows:

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

6. Edit content

(1) Add a link to the "Edit" button in the content list page. The specific code is as follows:

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

(2) Add the edit() method in the Content controller. The specific code is as follows:

 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) Add the route of the content list page in the routes\web.php file. The specific code is as follows:

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

7. Delete content

(1) Add a link to the "Delete" button on the content list page. The specific code is as follows:

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

(2) Add a route to delete content in the routes\web.php file. The specific code is as follows:

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

(3) Add the delete() method in the Content controller . The specific code is as follows:

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

5. Advertising space management

1. Create an ad slot table

(1) After creating the migration file corresponding to the advertising slot table, add the table structure information in the up() method of the migration file. The specific code is as follows:

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

(2) Create a model file corresponding to the advertising slot table. The specific code is as follows:

php artisan make:model Adv

(3) After executing the above command, the app\Adv.php file will be automatically created . The specific code is as follows:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

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

2. Add advertising space

(1) Create Adv controller, the specific code is as follows:

php artisan make:controller Admin\AdvController

(2) Add the add() method in the controller to implement the function of adding advertising slots, and add the save() method to save the added advertising slots. The specific code is as follows:

  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) Introduce the Adv namespace into the controller. The specific code is as follows:

use App\Adv;

(4) Add the routing group for advertising space management in routes\web.php . The specific code is as follows:

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

3. Display, edit and delete ad slot list

(1) Modify admin.blade.php and add links to the advertising space menu items. The specific code is as follows:

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

(2) Add the route for the advertising slot list in routes\web.php . The specific code is as follows:

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

(3) Write the index() method and delete() method in the Adv controller . The specific code is as follows:

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) Create the index.blade.php file, the specific code is as follows:

@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) Access in the browser, the effect is as follows:

(6) Access through the browser, click the "Delete" button to delete the advertising space, and check whether the advertising space is successfully deleted.

6. Advertising content management

1. Create an advertising content table

(1) Create a migration file for the advertising content table, and add the table structure information in the up() method of the migration file. The specific code is as follows:

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) Create the model file corresponding to the content table below. The specific code is as follows:

php artisan make:model Advcontent

(3) After executing the above command, the app\Advcontent.php file will be automatically created , and the following code will be written in the file:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

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

2. Add, display, edit, delete ads

(1) Create Advcontent controller, the specific code is as follows:

php artisan make:controller Admin\AdvcontentController

(2) Add the add() method to the controller to implement the function of adding advertisements, add the save() method to save the advertisement content, add the upload() method to save the uploaded advertisement images, and add the index() method. Add delete() method, the specific code is as follows:

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) Introduce the namespace of the advertising space into the controller. The specific code is as follows:

use App\Advcontent;
use App\Adv;

(4) Create the resources\views\admin\advcontent\add.blade.php view file. The specific code is as follows:

@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) Create the index.php file, the specific code is as follows:

@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) Add the routing group for advertising space management in routes\web.php . The specific code is as follows:

//广告列表
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) Modify app\Advcontent.php , set the association model, and obtain advertising space information. The specific code is as follows:

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

(8) Introduce the Advcontent namespace in the Adv controller. The specific code is as follows:

use App\Content;

(9) Through browser access, you can display, edit, and delete advertising content.

 Conclusion

To sum up, the Laravel framework is used to implement the backend functions of the content management system. The project display picture is as follows:

 

 

Front page

1. Page layout

(1) Create a public directory in the resources\views directory, which is used to save public files. Create static.blade.php in this directory , which is used to save static files. The specific code is as follows:

<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) Create the header.blade.php file, the specific code is as follows:

<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) Create the resources\views\common\footer.blade.php file, which is used to save the content at the bottom of the page. The specific code is as follows:

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

2. Home page, column navigation, carousel images, advertising spaces, and column content display

(1) Create the homepage view and create index.blade.php in the resources\views directory . The specific code is as follows:

<!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) Create an Index controller, the specific code is as follows:

php artisan make:controller IndexController

(3) Add a method to the controller, the specific code is as follows:

<?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) Add routing rules in the routes\web.php file. The specific code is as follows:

// 首页
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) Modify app\Adv.php and set the association model. The specific code is as follows:

<?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) Modify app\Category.php and set the association model. The specific code is as follows:

<?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) Access through the browser to see if it is fully displayed.

Front desk user management

User registration, user login and user logout

(1) Add the registration form and login form in the header.blade.php view. The specific code is as follows:

<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) Create a User controller, the specific code is as follows:

php artisan make:controller UserController

(3) Add a method in the User controller, the specific code is as follows:

<?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('/');
    }

}

Content list page

1. Content list

(1) Create lists.blade.php in the resources\views directory . The specific code is as follows:

<!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) Access the content list page through a browser to see its effect.

2. Breadcrumb navigation

1.Installation

(1) Use Composer to load the laravel-breadcrumbs library. The specific code is as follows:

composer require davejamesmiller/laravel-breadcrumbs

(2) Register this service provider into Laravel in the config\app.php file. The specific code is as follows:

    'providers' => [

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

    ],

(3) Register an alias in the config\app.php file for ease of use. The specific code is as follows:

 'aliases' => [

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

    ],

2. Configure navigation

(1) Configure the navigation link on the homepage and create the routes\breadcrumbs.php file. The specific code is as follows:

<?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) Access the content list page through a browser to view the breadcrumb navigation effect.

Content display

1. Content details page

Create detail.blade.php in the resources\views directory . The specific code is as follows:

<!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>

Guess you like

Origin blog.csdn.net/qq_64047601/article/details/131222336
Recommended