# Laraval 从零开始制作一个企业网站
# 安装环境
# 安装
# 安装 Laravel
mkdir D:/2023-05-30/
cd D:/2023-05-30/
composer create-project laravel/laravel=9.* travel
# 安装用户认证组件
composer require laravel/breeze --dev
# 初始化认证组件
php artisan breeze:install
php artisan migrate
php artisan db:seed
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 安装 npm
# 初级化前端
npm install --registry=https://registry.npm.taobao.org
1
2
2
# 建立版本库
git branch -m master main
git remote add origin git@git.zxjing.cn:study/laravel.git
git add .
git commit -m"init"
git push -u origin main
1
2
3
4
5
2
3
4
5
# 配置 Laravel
config/app.php 时区与中文语言
'timezone' => 'Asia/Shanghai',
'locale' => 'zh-CN',
1
2
2
配置 apache 主目录
DocumentRoot "D:/2023-05-30/travel/public"
<Directory "D:/2023-05-30/travel/public">
#
# Possible values for the Options directive are "None", "All",
# or any combination of:
# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
#
# Note that "MultiViews" must be named *explicitly* --- "Options All"
# doesn't give it to you.
#
# The Options directive is both complicated and important. Please see
# http://httpd.apache.org/docs/2.4/mod/core.html#options
# for more information.
#
Options Indexes FollowSymLinks Includes ExecCGI
#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
# AllowOverride FileInfo AuthConfig Limit
#
AllowOverride All
#
# Controls who can get stuff from this server.
#
Require all granted
</Directory>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 数据库
# 初始化
phpMyAdmin 管理地址:http://localhost/phpmyadmin/ (opens new window)
create database travel default charset utf8mb4;
grant all privileges on travel.* to travel@"%" identified by 'travel1234';
flush privileges;
1
2
3
2
3
# 备份
mysqldump -uroot -p --extended-insert --default-character-set=utf8mb4 travel > data.sql
1
# 在 laravel 中配置数据源
.env 文件
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=travel
DB_USERNAME=travel
DB_PASSWORD=travel1234
1
2
3
4
5
6
2
3
4
5
6
# 建立数据库模型
- categories
php artisan make:model Category -mrs php artisan make:model Archive -mrs
1
2 - Category 增加字段
$table->string("name",50); $table->string("url",100);
1
2 - Archive 增加字段
$table->bigInteger("category_id"); $table->string("title",200); $table->text("content"); $table->integer("hot");
1
2
3
4 - 建立一对多关系方便查询 app/Models/category.php
public function archives(): HasMany { return $this->hasMany(archive::class, "category_id","id"); }
1
2
3
4 - 对栏目页一对多进行反射 app/Models/archive.php
public function category(): BelongsTo { return $this->BelongsTo(category::class); }
1
2
3
4 - 准备数据
DatabaseSeeder.php
// 调入其它两个填充 $this->call(UserSeeder::class); $this->call(CategorySeeder::class);
1
2
3CategorySeeder.php
Category::create( [ "id" => 1, "name" => "首页", "url" => "/", "type" => 1, ]); Category::create([ "id" => 2, "name" => "要闻", "url" => "/category/2", "type" => 1, ]); Category::create([ "id" => 3, "name" => "文博", "url" => "/category/3", "type" => 1, ]); Category::create([ "id" => 4, "name" => "交通", "url" => "/category/4", "type" => 1, ]); Category::create([ "id" => 5, "name" => "攻略", "url" => "/category/5", "type" => 1, ]);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31迁移文件生成数据库
# 强行更新数据 php artisan migrate:refresh # 填充数据 php artisan db:seed
1
2
3
4
# 配置路由
# 建立 controller
php artisan make:controller IndexController
1
# 配置路由
Route::get('/', [IndexController::class,"index"]);
Route::get('/category/{id}', [IndexController::class,"category"]);
Route::get('/show/{id}', [IndexController::class,"show"]);
Route::get('/login', [UserController::class,"login"]);
Route::get('/categoryList', [AdminController::class,"categoryList"]);
Route::get('/contentList', [AdminController::class,"contentList"]);
Route::post('/loginForm', [UserController::class,"loginForm"]);
1
2
3
4
5
6
7
2
3
4
5
6
7
# 增加三个模板文件
- category.blade.php
- index.blade.php
- show.blade.php
# 前端
# 格式
- 时间显示格式
{{ date('Y-m-d', strtotime($yourDateVariable)) }}
1
# 建立布局文件
layouts/main-layout.blade.php 主布局文件
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link href="{{asset("bootstrap/css/bootstrap.css")}}" rel="stylesheet">
@vite(['resources/css/app.css'])
@stack("styles")
</head>
<body>
@include("layout.header")
@yield("content")
@include("layout.footer")
@vite(['resources/js/app.js'])
<script src="{{asset("bootstrap/js/bootstrap.min.js")}}"></script>
@stack("scripts")
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
layout/header.blade.php 头部文件
layout/footer.blade.php 脚部文件
# 套用主模板文件
resources/views/index.blade.php 建立 banner 轮播图
@extends("layout/main-layout")
@section("content")
<div class="container-fluid container-lg p-0">
<div id="banner" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item" style="background-image: url('{{ asset(" assets
/02_banner_02.jpg") }}')">
</div>
<div class="carousel-item" style="background-image: url('{{ asset(" assets
/02_banner_03.jpg") }}')">
</div>
<div class="carousel-item" style="background-image: url('{{ asset(" assets/02_banner_04.jpg") }}')">
</div>
<div class="carousel-item" style="background-image: url('{{ asset(" assets/02_banner_05.jpg") }}')">
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#banner" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#banner" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
</div>
@endsection
@push("scripts")
<script>
const carousel = new bootstrap.Carousel('#banner', {interval: 2000, pause: "hover"})
</script>
@endpush
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 安装 vite 环境
# 引入 bootstrap
- 把文件复制到 public 下的 boostrap 下
- 在主模块中引入
<link href="{{asset("bootstrap/css/bootstrap.min.css")}}" rel="stylesheet">
1<script type="javascript" src="{{asset("bootstrap/js/bootstrap.min.js")}}"
1
# 导入素材文件
把文件放到 public 下的 assets 下
# 制作头部
# 准备栏目数据
# 建立组件
php artisan make:component layout/nav
1
# 编写组件
View/Components/layout/nav.php
class nav extends Component
{
/**
* Create a new component instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\Contracts\View\View|\Closure|string
*/
public function render()
{
$data =[];
$data["nav_category"] = category::all();
return view('components.layout.nav',$data);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 编写组件模板
resources/views/components/layout/nav.blade.php
<div class="container-fluid container-lg p-0 main-bg" style="background-color: red">
<nav class="navbar navbar-expand-lg bg-body-emphasis main-bar">
<div class="container-fluid">
<button class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#main-menu"
aria-controls="main-menu"
aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon" style="color: #fcfcfd"></span>
</button>
<div class="collapse navbar-collapse" id="main-menu">
<ul class="navbar-nav">
@foreach($nav_category as $item)
<li class="nav-item">
<a class="nav-link active" aria-current="page"
href=" {{ $item['url'] }}">{{ $item["name"] }}</a>
</li>
@endforeach
</ul>
</div>
</div>
</nav>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 引用组件
<x-layout.nav></x-layout.nav>
1
# 制作 Login 状态
# 建立中间件
php artisan make:middleware LoginValid
1
app/Http/Middleware/LoginValid.php
class LoginValid
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next)
{
if ($request->session()->has(UserController::session_key)
&& $request->session()->get(UserController::session_key) ) {
return redirect('/login');
}
return $next($request);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 写入 session 记录登录
app/Http/Controllers/IndexController.php
public function loginForm(Request $request):RedirectResponse
{
$data = $request->only(['username', 'password']);
if ($data["username"] == "admin" && $data["password"] == "admin") {
$request->session()->put('login', true);
return redirect("/categoryList");
}
return redirect("/login");
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 建立 login 组件
php artisan make:component layout/login
1
app/View/Components/layout/login.php
public function render()
{
$login_status = LoginValid::isLogin();
return view('components.layout.login', ["login_status" => $login_status]);
}
1
2
3
4
5
2
3
4
5
resources/views/components/layout/login.blade.php
<div class="userInfo">
@if(!$login_status)
<a href="/login"> 登录 </a>
@endif
@if($login_status)
<a href="/categoryList"> 管理 </a>
<a href="/logout"> 退出 </a>
@endif
</div>
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 引用组件
<x-layout.login></x-layout.login>
1
# 正则表达式
多行换成一行
[\n\r]{1,} \n
加段落标记
^(.*)$ <p>$1</p>
1
2
3
4
2
3
4
← 安装