# 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

# 安装 npm

# 初级化前端 
npm install --registry=https://registry.npm.taobao.org
1
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

# 配置 Laravel

config/app.php 时区与中文语言

'timezone' => 'Asia/Shanghai',
'locale' => 'zh-CN',
1
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

# 数据库

# 初始化

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

# 备份

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

# 建立数据库模型

  1. categories
    php artisan make:model Category -mrs
    php artisan make:model Archive -mrs
    
    1
    2
  2. Category 增加字段
    $table->string("name",50);
    $table->string("url",100);
    
    1
    2
  3. Archive 增加字段
    $table->bigInteger("category_id");
    $table->string("title",200);
    $table->text("content");
    $table->integer("hot");
    
    1
    2
    3
    4
  4. 建立一对多关系方便查询 app/Models/category.php
    public function archives(): HasMany
    {
        return $this->hasMany(archive::class, "category_id","id");
    }
    
    1
    2
    3
    4
  5. 对栏目页一对多进行反射 app/Models/archive.php
    public function category(): BelongsTo
    {
        return $this->BelongsTo(category::class);
    }
    
    1
    2
    3
    4
  6. 准备数据

    DatabaseSeeder.php

    // 调入其它两个填充
    $this->call(UserSeeder::class);
    $this->call(CategorySeeder::class);
    
    1
    2
    3

    CategorySeeder.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

# 增加三个模板文件

  • 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

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

# 安装 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

# 编写组件模板

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

# 引用组件

<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

# 写入 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

# 建立 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

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

# 引用组件

<x-layout.login></x-layout.login>
1

# 正则表达式

多行换成一行
[\n\r]{1,}   \n
加段落标记
^(.*)$  <p>$1</p>
1
2
3
4