laravel框架后台内容管理系统项目搭建心得分享
Larvel框架可以开发各种不同类型的项目,内容管理系统( Contet Mangement Sstem, CMS )是一种比较典型的项目,常见的网站类型(如门户、新闻、博客、文章等)都可以利用CMS进行:搭建。CMS用于对信息进行分类管理,将信息有序、及时地呈现在用户面前,满足人们发布信息、获取信息的需求,保证信息的共享更加快捷和方便。本章将讲解如何使用Laravel框架开发内容管理系统。
(1)本项目分为前台和后台。前台的功能包括用户登录与注册、内容列表、内容详细页、广告展示、评论和热门内容等。
(2)后台在未登录的状态下会自动跳转至登录页面。输入用户名“admin”、密码“123456”和验证码后,单击“登录”按钮,即可进行登录。
(3)登录后,页面顶部右侧显示了当前登录的用户名“admin”和“退出”按钮,单击“退出”按钮即可退出后台系统。
(4)后台页面的左侧有一个菜单栏,用户可以在菜单栏中选择一个菜单项进行操作。
项目中需要使用到的技术点包括文件上传、分页和会话技术。整个项目开发基于实现功能的步骤来完成,先实现后台开发,提供数据支持,再完成前台的数据展示。
前期准备
(1)在C:\web\apache2.4\htdocs\cms目录下打开终端,执行如下命令,安装Laravel。
composer create-project --prefer-dist laravel/laravel ./ 5.8.*
或下载地址:https://getcomposer.org/download/
(2)Laravel安装完成后,在Apache的conf\extra\httpd-vhosts.conf配置文件中创建一个虚拟主机。然后,编辑Windows系统的hosts文件,添加一条解析记录“lhm.com”。
(3)在本书的配套源代码包中,将内容管理系统的前台和后台的静态资源复制到项目对应的目录下。
(4)登录MySQL服务器,创建数据库cms,将cms作为内容管理系统的数据库。
(5)打开项目,在config\database.php数据库配置文件中,将数据库名称修改为lhm。
(6)在.env文件中配置正确的数据库配置信息。完成上述步骤后,即可在项目中访问数据库。
目录 | 作用 |
---|---|
App | 包含了应用的核心代码,此外你为应用编写的代码绝大多数也会放到这里; |
Bootstrap | 用于框架的启动和自动载入配置; |
Config | 包含了应用所有的配置文件 |
Database | 包含了数据迁移及填充文件 |
Public | Public |
Resources | resources目录包含了视图文件及原生资源文件 |
Routes | 包含了应用的所有路由定义 |
Storage | 存放编译后的模板、session文件、缓存文件、日志文件等; |
Tests | 自动化测试文件 |
Vendor | 存放通过Composer加载的依赖 |
一、后台用户登录
1、创建用户表
(1)在命令行中执行如下命令创建迁移文件,具体命令如下:
php artisan make:migration create_admin_user_table
(2)执行完上述命令后,会在database\migrations目录下生成文件名称为时间前缀_create_admin_user_table.php的文件 。
(3)在迁移文件的up()方法中添加表结构信息,具体代码如下:
public function up()
{
Schema::create('admin_user', function (Blueprint $table) {
$table->increments('id')->comment('主键');
$table->string('username', 32)->comment('用户名')->unique();
$table->string('password', 32)->comment('密码');
$table->char('salt', 32)->comment('密码salt');
$table->timestamps();
});
}
(5)上述命令会执行迁移文件中的up()方法,来完成数据表的创建。
(6)创建填充文件,具体命令如下:
php artisan migrate
(7)执行完上述命令后,会在database\seeds目录下生成对应的迁移文件,文件名为AdminuserTableSeeder.php。
(8)在填充文件的run()方法中编写填充代码:
public function run()
{
$salt = md5(uniqid(microtime(), true));
$password = md5(md5('123456') . $salt);
DB::table('admin_user')->insert([
[
'id' => 1,
'username' => 'admin',
'password' => $password,
'salt' => $salt
],
]);
}
(9)执行填充文件命令:
php artisan db:seed --class=AdminuserTableSeeder
(10)数据库创建成功后,创建用户模型:
php artisan make:model Admin
(11)打开app\Admin.php,在模型中指定要操作的表名,具体代码如下:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Admin extends Model
{
protected $table = 'admin_user';
public $fillable = ['username', 'password'];
}
2、显示登录页面
(1)创建User控制器。
php artisan make:controller Admin/UserController
(2)打开UserController.php,创建login()方法。
public function login(){
return view('admin/login');
}
(3)在routes\web.php文件中添加路由规则。
Route::get('/admin/login','Admin\UserController@login');
(4)在resources\views目录下创建admin目录,该目录用于存放后台相关的模板文件。然后在admin目录中创建login.blade.php文件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 引入静态文件 -->
<title>登录</title>
</head>
<body class="login">
<div class="container">
<!-- 登录表单 -->
</div>
</body>
</html>
(5)在login.blade.php文件中引入静态文件。
<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>
(6)在login.blade.php文件中定义登录表单。
<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>
(7)使用Composer载入mews/captcha验证码库。
composer require mews/captcha=3.0
(8)创建验证码的配置文件。
php artisan vendor:publish
(9)编辑config\captcha.php文件,将字符个数改为4。
'default' => [
'length' => 4, //字符个数
'width' => 120, //图片宽度
'height' => 36, //图片高度
'quality' => 90, //图片质量
'math' => false, //数学计算
],
(10)在config\app.php文件中将验证码服务注册到服务容器中。
'providers' => [
...(原有代码)
Mews\Captcha\CaptchaServiceProvider::class,
...(原有代码)
]
(11)在config\app.php文件中给验证码服务注册别名。
'aliases' => [
...(原有代码)
'Captcha' =>Mews\Captcha\Facades\Captcha::class,
]
(12)在登录表单中添加验证码。
<div class="form-group">
<div class="login-captcha"><img src="{
{ captcha_src() }}" alt="captcha"></div>
</div>
(13)实现单击验证码图片后更换验证码的功能,在模板中编写JavaScript 代码。
<script>
$('.login-captcha img').click(function() {
$(this).attr('src', '{
{ captcha_src()}}' + '?_=' + Math.random());
});
</script>
(14)运行效果图如下:
3、Ajax交互
Ajax交互封装的开发思路:
① 将Ajax操作的代码封装到一个对象中,该对象可以随意命名,这里命名为main。
② 通过main.ajax()方法发送Ajax请求,该方法有3个参数,第1个参数可以是对象或字符串,如果是对象,则用于传递给$.ajax(),如果是字符串,则表示请求地址;第2个参数表示当服务器返回成功结果时执行的回调函数;第3个参数表示当服务器返回失败结果时执行的回调函数。
③ 当开始发送Ajax请求时,在页面中显示加载提示,并在收到服务器响应后,隐藏加载提示。
④ 当Ajax请求失败,或服务器响应错误信息时,通过toastr对象将错误信息显示在页面中。
在分析了要完成的主要功能后,下面开始进行代码编写:
① 打开public\admin\js\main.js文件,编写window.main对象。
② 在main对象中编写ajaxPost()方法,用于发送POST请求。
在main.js中编写ajaxForm()方法,用于将表单改为Ajax提交方式
ajax知识拓展:
Ajax (Asynchronous JavaScript and XML) 是一种使用已有的标准技术,通过 JavaScript 实现浏览器与服务器之间异步数据传输的方法。它的主要特点是在不刷新整个页面的情况下,可以与服务器交换数据并更新部分页面内容,从而提升用户体验。
Ajax 技术的核心是 XMLHttpRequest 对象,通过该对象可以实现异步请求数据和更新部分页面内容。当用户与 Web 应用程序交互时,JavaScript 会发送异步请求到服务器端,服务器响应请求并返回需要的数据,JavaScript 再根据返回的数据更新页面。
Ajax 技术的应用非常广泛,如实现自动补全、实时搜索等功能,提高了用户的体验感和操作效率。同时,Ajax 还可以用于异步上传文件、处理表单数据等场景。
4、验证用户登录
(1)设置<form>标签的action属性设置表单的提交地址,给登录表单的action属性添加属性值,指定表单的提交地址为“{ { url('admin/check') }}”,表示UserController的check()方法。
(2)编写代码完成验证用户登录。
① 在routes\web.php文件中添加路由规则。
//登录验证
Route::post('/admin/check','Admin\UserController@check');
② 在UserController.php中创建check()方法。
public function check(Request $request)
{
//声明自动验证规则
$rule = [
'username' => 'required',
'password' => 'required|min:6',
'captcha' => 'required|captcha'
];
// 声明自动验证规则对应的提示信息(验证失败返回信息)
$message = [
'username.required' => '用户名不能为空',
'password.required' => '密码不能为空',
'password.min' => '密码最少为6位',
'captcha.required' => '验证码不能为空',
'captcha.captcha' => '验证码有误'
];
//进行自动验证,验证表单提交数据
$validator = Validator::make($request->all(), $rule, $message);
// 输出验证结果并返回给浏览器
if ($validator->fails()) { //验证失败fails()方法
foreach ($validator->getMessageBag()->toArray() as $v) {
$msg = $v[0];
}
return response()->json(['code' => 0, 'msg' => $msg]);
}
// 获取用户输入的用户名、密码信息,以及数据表中用户名、密码信息
$username = $request->get('username');
$password = $request->get('password');
$theUser = Admin::where('username',$username)->first();
// 对用户输入的密码与数据库中的密码进行比较,如果密码正确则登录成功,并将用户信息保存在session中
// 跳转至后台首页,如果登录失败,则显示“登录失败”
if($theUser->password == md5(md5($password). $theUser->salt))
{
Session::put('user', ['id'=>$theUser->id,'name'=>$username]);
return response()->json(['code' => 1, 'msg' => '登录成功']);
}else{
return response()->json(['code' => 0, 'msg' => '登录失败']);
}
}
③ 导入Admin模型、Session、Validator的命名空间。
use App\Admin;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
(3)通过浏览器访问,输入小于6 位的密码,页面会出现“密码最少为6 位”的错误提示;如果提交正确的用户名(admin)和密码(123456),页面中会出现“登录成功”的提示。
5、用户退出
(1)在User控制器中添加logout()方法。
public function logout(){
if(request()->session()->has('user')){
request()->session()->pull('user',session('user'));
}
return redirect('/admin/login');
}
(2)在routes\web.php文件中添加路由规则。
//用户退出
Route::get('/admin/logout','Admin\UserController@logout');
通过浏览器访问,在确保用户已经登录以后,访问http://cms.test/admin/logout,浏览器会自动跳转到登录页面,说明当前用户已经成功退出。
二、后台首页
在用户登录成功后,就会进入到后台首页。网站的后台首页一般会显示一些欢迎信息、系统信息、统计数据等系统信息。本节将实现上述功能。
1、后台页面布局
在后台管理系统的页面中,一般都会包含顶部、菜单和内容区域这3 个部分,可将后台页面的顶部和左侧菜单提取出来,作为公共文件供其他模板调用,在 resources\views\admin下创建 layouts目录,此目录将作为公共文件的存放目录。开发步骤如下。
(1)在layouts目录下创建admin.blade.php文件。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--引入静态文件-->
<title>@yield('title')</title>
</head>
<body>
<nav class="navbar navbar-expand-md navbar-light bg-light main-navbar">
<a class="navbar-brand" href="#">后台管理系统</a>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="nav ml-auto main-nav-right">
<li>
<a href="#" class="j-layout-pwd">
<i class="fa fa-user fa-fw"></i>{
{session()->get('user.name')}}
</a>
</li>
<li>
<a href="{
{url('admin/logout')}}">
<i class="fa fa-power-off fa-fw"></i>退出
</a>
</li>
</ul>
</div>
</nav>
<!-- 后台页面的首页部分 -->
<div class="main-container">
<div class="main-content">
<div>@yield('main')</div>
</div>
</div>
</body>
</html>
(2)在页面中引入静态资源。
<link rel="stylesheet" href="{
{asset('admin')}}/common/twitter-bootstrap/4.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="{
{asset('admin')}}/common/font-awesome-4.2.0/css/font-awesome.min.css">
<link rel="stylesheet" href="{
{asset('admin')}}/common/toastr.js/2.1.4/toastr.min.css">
<link rel="stylesheet" href="{
{asset('admin')}}/css/main.css">
<script src="{
{asset('admin')}}/common/jquery/1.12.4/jquery.min.js"></script>
<script src="{
{asset('admin')}}/common/twitter-bootstrap/4.4.1/js/bootstrap.min.js"></script>
<script src="{
{asset('admin')}}/common/toastr.js/2.1.4/toastr.min.js"></script>
<script src="{
{asset('admin')}}/js/main.js"></script>
(3)在页面中定义左侧导航栏。
<div class="main-sidebar">
<ul class="nav flex-column main-menu">
</div>
(4)添加首页菜单。
<li class="">
<a href="{
{url('admin/index')}}" class="active">
<i class="fa fa-home fa-fw"></i>首页
</a>
</li>
(5)添加栏目菜单。
<li class="main-sidebar-collapse"> <!-- 被收起的双层项 -->
<a href="#" class="main-sidebar-collapse-btn"> <!-- 链接用于展开或收起子菜单 -->
<i class="fa fa-list-alt fa-fw"></i>栏目
<span class="fa main-sidebar-arrow"></span> <!-- 双层项的右侧小箭头 -->
</a>
<ul class="nav">
<!-- 设置子菜单 -->
<li>
<a href="#" data-name="addcategory">
<i class="fa fa-list fa-fw"></i&