Write the Code. Change the World.

分类目录
1月 27

做好之前的功能,现在开始做权限管理以及后台。权限管理这里使用第三方扩展包 laravel-permission

laravel-permission github

https://docs.spatie.be/laravel-permission/v3/installation-laravel/

按照文档,进行常规操作。

安装使用 laravel-permission

基本步骤如下

composer require spatie/laravel-permission

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"

为了更好的使用权限,在 权限表中加了一些额外的字段

# permissions 迁移中加入下边字段
$table->string('display_name');
$table->string('route')->nullable();
$table->integer('icon_id')->nullable();
$table->integer('parent_id')->default(0);
$table->integer('sort')->default(0);

# roles 迁移中加入下边字段
$table->string('display_name');

因为会用到 icon,所以得额外加一个 icons 表。生成一个额外的迁移文件

php artisan make:migration create_icons_tabel --create=icons

# 填充迁移文件
        Schema::create('icons', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('unicode')->nullable();
            $table->string('class')->nullable();
            $table->string('name')->nullable();
            $table->integer('sort')->default(0);
            $table->nullableTimestamps();
        });

# 执行迁移
php artisan migrate

怎么使用呢,看 wiki https://docs.spatie.be/laravel-permission/v3/basic-usage/basic-usage/

  1. 在模型中加入 Spatie\Permission\Traits\HasRoles trait,可以是 User 模型也可以是其他,看你怎么用。
  2. 虽然可以给单独模型赋予权限,不建议这样做。建议通过 role 来实现。先给 role 赋予权限,再给用户赋予角色。这样更好管理和控制权限。

完成了上边的操作,我们还需要做两个数据填充(Seeders),一个 IconSeeder 和 PermissionSeeder 。

php artisan make:seeder IconSeeder

php artisan make:seeder PermissionSeeder

既然要整 icon ,那我们就用阿里的 iconfonts 。去 https://www.iconfont.cn/ 操作一波。

制作好了之后,先创建 json 文件:

vim public/backstage/json/icons.json

# 填充以下内容(以3个icon为例)
[{"unicode": "", "name": "控制台", "class": "icon-kongzhitai"},
 {"unicode": "", "name": "权限", "class": "icon-quanxian"},
 {"unicode": "", "name": "仪表盘", "class": "icon-yibiaopan"}]

再去编辑 IconSeeder。

# 创建 icon
php artisan make:model Models/Icon

# 白名单
protected $fillable = ['unicode','class','name','sort'];

# IconSeeder
<?php

use Illuminate\Database\Seeder;
use App\Models\Icon;

class IconSeeder extends Seeder
{
    public function run()
    {
        Icon::truncate();
        $file = file_get_contents(public_path().'/backstage/json/icons.json');
        $icons = json_decode($file, true);
        foreach ($icons as $icon){
            Icon::create($icon);
        }
    }
}

PermissionSeeder 的迁移文件可参考: https://docs.spatie.be/laravel-permission/v3/advanced-usage/seeding/

根据需求,先暂时建立几个权限以及角色。迁移文件如下:

php artisan make:model Models/Permission

php artisan make:model Models/Role

# Permission Model
<?php

namespace App\Models;

use Spatie\Permission\Models\Permission as SPermission;

class Permission extends SPermission
{
    //菜单图标
    public function icon()
    {
        return $this->belongsTo('App\Models\Icon', 'icon_id', 'id');
    }

    //子权限
    public function childs()
    {
        return $this->hasMany('App\Models\Permission', 'parent_id', 'id');
    }
}

# Role Model
<?php

namespace App\Models;

use Spatie\Permission\Models\Role as SRole;

class Role extends SRole
{

}

然后,permission seeder。

<?php

use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
use Spatie\Permission\PermissionRegistrar;
use App\Models\User;
use App\Models\Permission;
use App\Models\Role;
use DB;
use Hash;

class PermissionSeeder extends Seeder
{
    public function run()
    {
        app(PermissionRegistrar::class)->forgetCachedPermissions();

        $tableNames = config('permission.table_names');
        Model::unguard();
        foreach ($tableNames as $tableName) {
            DB::table($tableName)->delete();
        }
        Model::reguard();

        $user = User::where('account', '13671638524')->first();
        if (!$user) {
            $user = User::create([
                'account' => '13671638524',
                'password' => Hash::make('w123456'),
                'email' => 'lichking_lin86@qq.com',
                'phone' => '13671638524'
            ]);
        }

        $role = Role::create([
            'name' => 'root',
            'display_name' => '站长'
        ]);

        $user->assignRole($role);

        $permissions = [
            [
                'name' => 'home.manager',
                'display_name' => '主页',
                'route' => '',
                'icon_id' => '1',
                'child' => [
                    [
                        'name' => 'home',
                        'display_name' => '控制台',
                        'route' => 'admin.home',
                        'icon_id' => '12',
                        'child' => []
                    ]
                ]
            ],
            [
                'name' => 'system.manage',
                'display_name' => '系统管理',
                'route' => '',
                'icon_id' => '2',
                'child' => [
                    [
                        'name' => 'system.permission',
                        'display_name' => '权限管理',
                        'route' => 'admin.system.permission',
                        'icon_id' => '2',
                        'child' => [
                            ['name' => 'system.permission.create', 'display_name' => '添加权限', 'route' => 'admin.system.permission.create'],
                            ['name' => 'system.permission.edit', 'display_name' => '编辑权限', 'route' => 'admin.system.permission.edit'],
                            ['name' => 'system.permission.destroy', 'display_name' => '删除权限', 'route' => 'admin.system.permission.destroy'],
                        ]
                    ],
                    [
                        'name' => 'system.role',
                        'display_name' => '角色管理',
                        'route' => 'admin.system.role',
                        'icon_id' => '3',
                        'child' => [
                            ['name' => 'system.role.create', 'display_name' => '添加角色', 'route' => 'admin.system.role.create'],
                            ['name' => 'system.role.edit', 'display_name' => '编辑角色', 'route' => 'admin.system.role.edit'],
                            ['name' => 'system.role.destroy', 'display_name' => '删除角色', 'route' => 'admin.system.role.destroy'],
                            ['name' => 'system.role.permission', 'display_name' => '分配权限', 'route' => 'admin.system.role.permission'],
                        ]
                    ],
                    [
                        'name' => 'system.manager',
                        'display_name' => '管理员',
                        'route' => 'admin.system.manager',
                        'icon_id' => '123',
                        'child' => [
                            ['name' => 'system.manager.create', 'display_name' => '添加管理', 'route' => 'admin.system.manager.create'],
                            ['name' => 'system.manager.edit', 'display_name' => '编辑管理', 'route' => 'admin.system.manager.edit'],
                            ['name' => 'system.manager.destroy', 'display_name' => '删除管理', 'route' => 'admin.system.manager.destroy'],
                            ['name' => 'system.manager.role', 'display_name' => '分配角色', 'route' => 'admin.system.manager.role'],
                            ['name' => 'system.manager.permission', 'display_name' => '分配权限', 'route' => 'admin.system.manager.permission'],
                        ]
                    ]
                ]
            ]
        ];

        foreach ($permissions as $pem1) {
            //生成一级权限
            $p1 = Permission::create([
                'name' => $pem1['name'],
                'display_name' => $pem1['display_name'],
                'route' => $pem1['route'] ?? '',
                'icon_id' => $pem1['icon_id'] ?? 1,
            ]);
            //为角色添加权限
            $role->givePermissionTo($p1);
            if (isset($pem1['child'])) {
                foreach ($pem1['child'] as $pem2) {
                    //生成二级权限
                    $p2 = Permission::create([
                        'name' => $pem2['name'],
                        'display_name' => $pem2['display_name'],
                        'parent_id' => $p1->id,
                        'route' => $pem2['route'] ?? 1,
                        'icon_id' => $pem2['icon_id'] ?? 1,
                    ]);
                    //为角色添加权限
                    $role->givePermissionTo($p2);
                    if (isset($pem2['child'])) {
                        foreach ($pem2['child'] as $pem3) {
                            //生成三级权限
                            $p3 = \App\Models\Permission::create([
                                'name' => $pem3['name'],
                                'display_name' => $pem3['display_name'],
                                'parent_id' => $p2->id,
                                'route' => $pem3['route'] ?? '',
                                'icon_id' => $pem3['icon_id'] ?? 1,
                            ]);
                            //为角色添加权限
                            $role->givePermissionTo($p3);
                        }
                    }
                }
            }
        }

        //初始化的角色
        $roles = [
            ['name' => 'manager', 'display_name' => '管理员']
        ];

        foreach ($roles as $role) {
            Role::create($role);
        }
    }
}

再在 DatabaseSeeder 中加入:

        $this->call(IconSeeder::class);
        $this->call(PermissionSeeder::class);

# 然后迁移回滚操作
php artisan migrate:refresh --seed -v

添加中间件。在 app/Http/Kernel.php 中的 routeMiddleware 增加映射

        'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
        'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
1月 26

完成了注册和登录,现在来完成完整邮箱验证

参考

https://blog.vini123.com/288

https://blog.vini123.com/333

按照上述参考操作,先将 User 模型实现 MustVerifyEmail,再修改路由,加入中间件 verified

Route::namespace('Web')->middleware(['verified'])->group(function() {

    Route::get('/', 'PageController@home')->name('home');

    Route::get('search', 'PageController@search')->name('search');

    Route::get('/users/{user}', 'UserController@index')->name('users.show');

    Route::group(['middleware' => 'auth'], function() {
        Route::get('/users/{user}/edit', 'UserController@edit')->name('users.edit');
    });
});

访问首页,发现会自动跳转到验证邮箱页面。然后点击重新发送验证。会发现有下边的报错:

Expected response code 250 but got code "530", with message "530 5.7.1 Authentication required
 "

这个是 email 相关的配置没好,我们可以使用 qq 邮箱、163邮箱等进行 SMTP 发送邮件。以 qq 邮箱来说,首先得去自己的 qq 邮箱里去申请开通。这里直接列出邮箱的配置数据。

vim .env

# 填充好下边的配置
MAIL_DRIVER=smtp
MAIL_HOST=smtp.qq.com
MAIL_PORT=465
MAIL_USERNAME=xxx@xxxx.com
MAIL_PASSWORD=xxxxx
MAIL_ENCRYPTION=ssl
MAIL_FROM_ADDRESS=xxxx@xxxx.com
MAIL_FROM_NAME=xxxxxx

当这些配置好了,再发送时,提示 新的验证链接已发送到您的 E-mail。 邮件已经发送。点击,跳转验证。

如果想验证成功后出现提示,可以在 EventServiceProvider中增加:

        \Illuminate\Auth\Events\Verified::class => [
            \App\Listeners\EmailVerified::class,
        ],

然后,自定义 mailVerified 类。添加好上边的,再执行 php artisan event:generate 会自动生成,然后填充方法。

    public function handle(Verified $event)
    {
        // 会话里闪存认证成功后的消息提醒
        session()->flash('success', '邮箱验证成功 ^_^');
    }

之前,弄的样式以及 layouts/app.blade.php 有问题,需要稍微修改。这里懒的弄了。下一步,权限管理,使用 spatie/laravel-permission

1月 25

上边完成了基本布局,发现某些 js,css缺失。这个时候,需要补进来。然后,完成服务端的注册登录逻辑,以及 gee 验证。

修补

加入以下文件

static/style/css/nprogress.css
static/style/css/nprogress.min.css

static/style/js/fn.js
static/style/js/gt.js
static/style/js/nprogress.min.js

部分调整

  1. 将 nprogress.min.js 和 app.js 的加载顺序更换一下。因为 app.js 中会使用到 nprogress 的封装
git add .
git commit -m '修复引入js,css不存在的bug'

认证脚手架

php artisan ui:auth

# 因为之前已经有了 layouts 相关的文件,这个时候会提示是否要覆盖,输入 no 回车。这个时候,会补入和修改相关的文件

# 查看变更的文件
git status 

# 删掉其他新增文件,只保留 resources/views/auth/ 下的文件
# web.php  路由也处理一下。之前就已经好了,这次注入是重复的,可以删掉重复的部分。

做好上边这些,然后开始修改 user 表的迁移文件,以及将 User模型移动到 app\Models\ 下。
继续阅读

1月 19

构建 bootstrap 框架,并定制好基本布局

composer require laravel/ui --dev

php artisan ui bootstrap

以上命令做了以下事情:

  1. 在 npm 依赖配置文件 package.json 中引入 bootstrap、jquery、popper.js 作为依赖;
  2. 修改 resources/js/bootstrap.js ,在此文件中初始化 Bootstrap UI 框架的 JS 部分;
  3. 修改 resources/sass/app.scss 以加载 Bootstrap 的样式文件;
  4. 新增 resources/sass/_variables.scss 样式配置文件。

运行 Laravel Mix

Laravel Mix 一款前端任务自动化管理工具,使用了工作流的模式对制定好的任务依次执行。Mix 提供了简洁流畅的 API,让你能够为你的 Laravel 应用定义 Webpack 编译任务。Mix 支持许多常见的 CSS 与 JavaScript 预处理器,通过简单的调用,你可以轻松地管理前端资源。

使用 Mix 很简单,首先你需要使用以下命令安装 npm 依赖即可。我们将使用 Yarn 来安装依赖,在这之前,因为国内的网络原因,我们还需为 NPM 和 Yarn 配置安装加速:

npm config set registry=https://registry.npm.taobao.org
yarn config set registry https://registry.npm.taobao.org

# 查看镜像
npm get registry 
yarn config get registry

yarn install

yarn run watch-poll

下边进行基础布局
继续阅读

1月 19

从零开始构建 laravel 项目

包裹以下功能:

  1. web 页面(可能是商城,可能是论坛,可能是其他)
  2. 接口功能(一套接口(jwt),提供给 app,小程序 或其他)
  3. 后台功能 (不再使用 layui admin ,使用 ant design pro。权限控制,laravel 自己的权限控制很好,ant design pro 不熟,不知两边的权限能否融洽。就是只使用服务端的权限,不去耦合 antdesignpro 的权限)
  4. 额外。 微信授权、站点地图、elastsearch、定时任务、swoole等。

开始

开发环境依然是 homestead。虽然 docker 很火热, 但总用不好。还有,如果真是线上环境,宁愿一个一个去编译安装所用软件(个数不多)。因为不熟悉,所以不敢放心去使用。

homestead 配置域名:admin.com

laravel 版本为最新版本 6.8.*

# 创建 laravel 6.8 项目
composer create-project laravel/laravel --prefer-dist admin.com "6.8.*"

cd admin.com

# 去掉原本的 readme,添加简单的 readme
rm -rf README.md

echo 'laravel 6.8 initialize' >> Readme.md

# 初始化 git
git init

# 添加,并 commit
git add .

git commit -m 'laravel 6.8 initialize'

为了保证代码风格,安装使用 editorcofig 。配置文件 laravel 项目里边已经有了再稍微改一点点。如下,保存提交版本。

修改根目录下的 .editorconfig

root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false

[*.yml]
indent_size = 2

[*.{js,html,blade.php,css,scss}]
indent_style = space
indent_size = 2

然后提交版本:

git add .
git commit -m '增加 editorconfig 配置'

修改时区以及语言版本

# vim config/app.php

'timezone' => 'Asia/Shanghai',

'locale' => 'zh-CN',

# git
git add .

git commit -m '设置时区以及默认语言版本'

添加辅助函数

# 在 app 目录下,添加 helpers.php 文件,辅助函数都放在该文件里。
touch app/helpers.php

# 修改 composer.json,让 autoload 的时候载入辅助函数

{
    ...

    "autoload": {
        "psr-4": {
            "App\\": "app/"
        },
        "classmap": [
            "database/seeds",
            "database/factories"
        ],
        "files": [
            "app/helpers.php"
        ]
    }
    ...
}

# 重新加载文件
composer dump-autoload

git提交

git add .

git commit -m '新增辅助函数文件'

现在 helpers.php 文件还是空的,但后续可以添加你需要的。比如 curl 等。

1月 18

站点地图有助于 seo 优化,一般站点都会制作站点地图。 Laravel 项目,有制作站点地图的插件 Laravelium-sitemap。拿来用即可。

laravelium-sitemap wiki

看文档,根据不同的 laravel 版本安装不同的包。

了解点

  1. 可以直接展示站点地图或分包展示地图。也就是直接 xml 或 sitemap index。

做一做

composer require laravelium/sitemap

php artisan vendor:publish --provider="Laravelium\Sitemap\SitemapServiceProvider"
  1. 可以缓存。不是每次请求都要生一个。

  2. 可以添加图片,视频等资源。

实践产品

逻辑里边,两种展示方式都添加了。只是选择了直接使用 xml
https://www.yuepaibao.net/sitemap.xml

1月 10

准备好基础框架后,就可以开始准备起接口了。准备最最基础的登录注册接口。

需要做以下处理:

  1. 准备 user 表的迁移文件。
  2. 准备 jwt
  3. 准备好路由以及文件结构
  4. 相关注册逻辑。

先准备 user 表的迁移文件

默认就有了 user 表的迁移,我们直接修改它就好。

$table->bigIncrements('id');
$table->string('account', 16)->unique();
$table->string('password');
$table->unsignedInteger('viewid')->unique();
$table->string('phone', 16)->unique();
$table->string('email')->nullable();
$table->string('nickname');
$table->string('avatar')->default('app/public/upload/image/avatar/default.jpg');
$table->string('signture')->nullable();
$table->timestamp('email_verified_at')->nullable();
$table->rememberToken();
$table->nullableTimestamps();

# 执行迁移
php artisan migrate

创建 Models 目录。

# App 目录下创建 Models 文件夹,并将 User 模型移动到该文件夹下
mkdir App/Models
mv App/User.php App/Models/User.php

再修改 User 的命名空间,并将整个框架的 User 的命名空间变更。

安装 jwt

# 安装
composer require tymon/jwt-auth:1.0.0-rc.5

# 生成 jwt 的 secret
php artisan jwt:secret

jwt-auth 有两个重要的参数,可以在 .env 中进行设置
JWT_TTL 生成的 token 在多少分钟后过期,默认 60 分钟
JWT_REFRESH_TTL 生成的 token,在多少分钟内,可以刷新获取一个新 token,默认 20160 分钟,14 天。

这里需要理解一下 JWT 的过期和刷新机制,过期很好理解,超过了这个时间,token 就无效了。刷新时间一般比过期时间长,只要在这个刷新时间内,即使 token 过期了, 依然可以换取一个新的 token,以达到应用长期可用,不需要重新登录的目的。

# 编辑 .env 增加 jwt 的过期配置和刷新配置
vim .env
# 增加下边两个配置
JWT_TTL= 10080
JWT_REFRESH_TTL=20160

修改完善 User 模型,使其继承 Tymon\JWTAuth\Contracts\JWTSubject 接口,并实现接口的两个方法 getJWTIdentifier()getJWTCustomClaims()

于是 User 模型中的类容为:

<?php

namespace App\Models;

use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements JWTSubject
{
    use Notifiable;


    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    public function getJWTCustomClaims()
    {
        return [];
    }

    protected $fillable = [
        'account', 'password', 'viewid', 'phone', 'email', 'nickname', 'avatar', 'signture'
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];

    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

我们启动 tinker,先创建一个用户,再尝试获取 jwt token。

# 启动 tinker
php artisan tinker

use App\Models\User;
use Hash;
use Auth;

$user = [
    'account' => '1367163xxxx',
    'password' => Hash::make('123456'),
    'phone' => '1367163xxxx',
    'nickname' => '七月羽歌',
    'signture' => '美的事物是永恒的喜悦'
];

# 创建用户
User::create($data);

# 获取用户
$user = User::first();

# 获取 token
Auth::guard('api')->login($user);

新建用户登录注册控制器

# 创建控制器
php artisan make:controller Api/AuthorizationsController

# 创建 request
php artisan make:request Api/AuthorizationRequest

然后编辑 request

<?php

namespace App\Http\Requests\Api;

use Illuminate\Foundation\Http\FormRequest;

class AuthorizationRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'account' => 'required|regex:/^1[1-9]\d{9}$/',
            'password' => 'required|alpha_dash|min:6'
        ];
    }
}

控制器代码

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Requests\Api\AuthorizationRequest;
use Illuminate\Auth\AuthenticationException;
use Auth;

class AuthorizationsController extends Controller
{
    public function login(AuthorizationRequest $request)
    {
        $data = $request->only(['account', 'password']);

        if (!$token = Auth::guard('api')->attempt($data)) {
            throw new AuthenticationException('用户名或密码错误');
        }

        return $this->respondWithToken($token)->setStatusCode(200);
    }

    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'Bearer',
            'expires_in' => auth('api')->factory()->getTTL() * 60
        ]);
    }
}

路由

Route::namespace('Api')->group(function () {
    Route::post('authorizations/login', 'AuthorizationsController@login')->name('api.authorizations.login');
});

然后使用 postman 测试下

登录好了,下一步就处理 ant design pro 框架。构建基础的功能以及去掉不需要的功能,美化页面。

有用的参考

如果多端,多表授权可以点这里

https://www.jianshu.com/p/344c5e540eaa

https://www.cnblogs.com/freely/p/10874297.html

https://www.cnblogs.com/lihuijuan/p/11242976.html

1月 09

laravel 好用, ant design pro 不仅好用还好看。那么,laravel + ant design pro 做出来的项目也会很好用,很好看。

创建初始化 laravel 项目以及 ant design pro 项目

先创建 laravel 项目

# 创建 最新版本的 laravel 项目,并且指定项目文件名为 lreact.com
composer create-project laravel/laravel=6.* --prefer-dist lreact.com

# 删除原本的 readme
rm -rf README.md

# 使用新的 readme,简洁
echo '### Laravel 6.* initialize' >> Readme.md

# 初始化 git 仓库
git init
git add .
git commit -m 'Laravel 6.* initialize'

再创建 ant design pro 项目

在 `laravel` 的 `resources` 目录下,新建文件夹 `antdesign`
cd resources

mkdir antdesign

npm create umi
# 依次选择 ant design pro -> javascript

# 当前版本 v4

git add .

git commit -m 'ant design pro v4 initialize'

npm install

安装完成后,需要稍微修改,并打包

部署请参考 https://pro.ant.design/docs/deploy-cn

# 修改输出目录(antdesign 目录下)
vim config/config.js

# 添加指定目录 base 以及 publicPath

export default {
  base: '/dashboard/',
  publicPath: '/dashboard/',
  plugins,
  hash: false,

# 编译
npm run build

# 将打包好的文件复制到 laravel 的 public 目录
mv dist ../../public/dashboard

# 访问站点
https://www.lrect.com/dashboard

能正常访问,但是授权登录错误。先到这来。

如果你不想每次都移来移去,可以在 config/config.js 里追加配置 outputPath
参考

于是,配置为

export default {
  base: '/dashboard/',
  publicPath: '/dashboard/',
  outputPath: '../../public/dashboard',
  plugins,
  hash: false,

再打包。文件就会打包到 laravel 项目下的 public 下的 dashboard 目录下。

修改 request

ant design pro 的请求都放在 services 下。在这里你可以定义和修改请求。但,这里的请求用的是 umi-request, 而这里对 umi-request 的引用放在 utils/request.js 中。这里你可以添加 header,加入拦截器等等。请看 umi-request 文档。

https://github.com/umijs/umi-request/blob/master/README_zh-CN.md

这里添加空的拦截器(request,response),还有添加请求前缀。完整的 request.js 如下。后边,会对拦截器进一步完善。

/**
 * request 网络请求工具
 * 更详细的 api 文档: https://github.com/umijs/umi-request
 */
import { extend } from 'umi-request';
import { notification } from 'antd';
const codeMessage = {
  200: '服务器成功返回请求的数据。',
  201: '新建或修改数据成功。',
  202: '一个请求已经进入后台排队(异步任务)。',
  204: '删除数据成功。',
  400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
  401: '用户没有权限(令牌、用户名、密码错误)。',
  403: '用户得到授权,但是访问是被禁止的。',
  404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
  406: '请求的格式不可得。',
  410: '请求的资源被永久删除,且不会再得到的。',
  422: '当创建一个对象时,发生一个验证错误。',
  500: '服务器发生错误,请检查服务器。',
  502: '网关错误。',
  503: '服务不可用,服务器暂时过载或维护。',
  504: '网关超时。',
};
/**
 * 异常处理程序
 */

const errorHandler = error => {
  const { response } = error;

  if (response && response.status) {
    const errorText = codeMessage[response.status] || response.statusText;
    const { status, url } = response;
    notification.error({
      message: `请求错误 ${status}: ${url}`,
      description: errorText,
    });
  } else if (!response) {
    notification.error({
      description: '您的网络发生异常,无法连接服务器',
      message: '网络异常',
    });
  }

  return response;
};

/**
 * 配置request请求时的默认参数
 */
const request = extend({
  prefix: '/dashboard',
  errorHandler,
  // 默认错误处理
  credentials: 'include', // 默认请求是否带上cookie
});

// request拦截器, 改变url 或 options.
request.interceptors.request.use(async (url, options) => {
  const headers = {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  };

  return (
    {
      url: url,
      options: { ...options, headers: headers },
    }
  );
})

// response拦截器, 处理response
request.interceptors.response.use((response, options) => {
  return response;
});

export default request;

到目前为止,输出目录,接口前缀,都是手动写的。分别写在了三个地方。如果想修改,必须得每个地方改一次。如果定义一个常量,直接使用常量不就好了么。下边进行常量定义。不过,定义了常量,那就必须保证你的需求里这三个地方的值是一样的。

定义常量,方便输出以及接口调用

在 config/config.js 中,定义常量 BASE , 设置好值。

const BASE = '/dashboard';

然后在 define 中进行注册该值。只有注册了,其他 js 才能访问的到,并且不需要加 window,请看这里文档。
https://pro.ant.design/docs/environment-variables-cn#%E5%A4%84%E7%90%86%E5%9C%A8-lint-%E4%B8%AD%E7%9A%84%E6%8A%A5%E9%94%99

于是 config/config.js 是这样

const BASE = '/dashboard';
…
export default {
  base: BASE,
  publicPath: `${BASE}/`,
  outputPath: `../../public/${BASE}/`,
  plugins,
  hash: false,
  targets: {
    ie: 11,
  },

…

utils/request.js 是这样

const request = extend({
  prefix: BASE,
  errorHandler,
  // 默认错误处理
  credentials: 'include', // 默认请求是否带上cookie
});

好了,提交 git 暂时先到这一步。

git add .

git commit -m '定义BASE作为项的输出路径和Api前缀'

最后又多一句,还是可以使用 npm start 进行奔跑的。

可参考

https://pro.ant.design/docs/getting-started-cn

https://www.yuque.com/yuxuanbeishui/zog1rm

https://learnku.com/articles/32218

https://umijs.org/zh/config/#uglifyjsoptions

https://www.codercto.com/a/26106.html

12月 20

虽然 homestead 用的很习惯,还是想尝试新东西 docker 。也不是新东西了,出来有些年了。既然用 laravel ,那么就用 laradock

熟悉 virtualBox + vagrant + homestead 的朋友,对于 laradock 上手也会很快。当初,装 homestead 需要安装 virtualBox(也可以是vm等) 和 vagrant,然后是使用 homestead 来实现环境的配置安装。对于 docker 可以这样理解,docker 就是 virtualBox + vagrant,或是 vagrant。 我们只需要安装一个 docker 就可以了。然后下载 laradock 即可以开始安装了。

步骤

安装使用,一步到位,初观全局

laradock: https://github.com/laradock/laradock

这里以 win 为例子:

# 先选定一个磁盘位置,用来存放 laradock 并且相邻文件夹做为 www 目录(当然也可以其他位置)
cd /e/
mkdir service
cd service

git clone https://github.com/laradock/laradock.git

cd laradock

# 准备配置文件
cp env-example .env

# 修改配置文件
vim .env
# 修改 APP_CODE_PATH_HOST = '../www'

# 创建并启动
docker-compose up -d nginx php-fpm mysql redis workspace

# 重启
docker-compose restart

# 进入服务器
winpty docker-compose exec workspace bash

# 退出 
exec 

上边的过程,可能有些长久。先创建 laravel 项目。

# 默认安装最新版本。当前版本 6.8
composer create-project laravel/laravel --prefer-dist docker.cn

再配置 nginx,创建默认 laravel 项目

cd service/laradock/nginx/sites

# 复制一份配置出来。命名一定要以 .conf 作为后缀
cp app.conf.example docker.cn.conf 

# 修改 docker.cn.conf
vim docker.cn.conf

# 通常会修改 server 下的 server_name 和 root。将 server_name 修改为你想要指定的域名。比如 docker.cn。 root修改为映射的文件目录。比如 /var/www/study/docker.cn/public 。保存退出。

# 每个对象都是一个容器
# 比如 修改了 nginx 只需要单独启动 nginx 即可
docker-compose up -d nginx

然后再执行 winpty docker-compose exec workspace bash 。如果发现还是访问不了。可以 docker-compose restart 再执行 winpty docker-compose exec workspace bash 

配置 host

# 修改 host 文件,再末尾加入 
vim hosts
GG
127.0.0.1 docker.cn

###
https://xueyuanjun.com/post/9608

https://www.cnblogs.com/itfenqing/p/10972603.html

https://blog.csdn.net/lfm940624/article/details/86678698