梦入琼楼寒有月,行过石树冻无烟

📖 earlier posts 📖

安装R语言

R语言为我们提供了全平台的下载方式,其中主要分为Linux、Windows、Mac等操作系统,本书我们以Linux opensuse系统为例进行安装,如果您当前的发行系统不是opensuse,可以通过访问https://cloud.r-project.org/bin/linux/ 进行下载,r语言为我们提供了 debian、fedora、redhat、suse、ubuntu等发行版的下载。

R

https://cloud.r-project.org/bin/linux/suse/README.html 在这个页面之中选择当前opensuse版本进行下载,推荐使用火狐浏览器,因为可以直接识别出文件自动进行安装,安装之后打开终端输入 R即可,出现以下信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
R version 3.5.0 (2018-04-23) -- "Joy in Playing"
Copyright (C) 2018 The R Foundation for Statistical Computing
Platform: x86_64-suse-linux-gnu (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

Natural language support but running in an English locale

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

>

输出Hello,world!

1
2
3
> print("Hello,world!")
[1] "Hello,world!"
>

RStudio

RStudio是专注与R语言的集成开发环境,由JJ Allaire小组进行设计,我们可通过官网https://rstudio.com/进行下载,当然本书使用opensuse Linux系统环境,可以使用其自带的软件仓库直接进行安装:https://software.opensuse.org/package/rstudio

输出 hello,world!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
R version 3.5.0 (2018-04-23) -- "Joy in Playing"
Copyright (C) 2018 The R Foundation for Statistical Computing
Platform: x86_64-suse-linux-gnu (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

Natural language support but running in an English locale

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> print("hello,world!")
[1] "hello,world!"
>

什么是 R 语言

r语言主要用于进行统计分析、绘图,由Ross lhaka, Robert Gentleman进行开发,属于GNY系统的一个自由、免费、开源的统计计算和统计制图的主要用于绘制学术图表工具(说是说语言),而学术图表是为论文结论(conclusion)提供证据的一种视觉方式。

在数据分析和图表绘制及统计中,主要主要由R、python、matlab、sigmaplot、origin、graphpad prism、excel所立足,本书将详细见解R语言,对于其他语言或工具读者可自行进行学习等。

学术图表的作用

学术图表主要出现在一些学术论文中,通常是试验结果的核心和主要部分,通常试验结果由图表形式呈现。一般道行较深的会直接通过图表来判断这篇学术文章、论文是否值得进行阅读,古而言之“一图低千言”,
我们以Nature上的文章为例,首先我们关注的是论文的标题、其次是第一页最开始的摘要,然后我们被大量的学术图表所吸引。在每页的文章中,主要包含图名、图表总共会占整个页面的1/4~1/3.

图表的基本类别

通常学术期刊通常分为两部分,分别为黑白图表和彩色图表,由于彩色图表的印刷成本相对较高,所以大部分分期刊都是黑白的,通常不同的期刊也往往要求提交的学术图表为黑白颜色。当然如果你想保持彩色图表,出版社也许会通过加钱来对你收取额外的彩色出版费用,彩色图表和黑白图表的是数据标记区别
黑白图表
数据标记通常使用不同的填充纹理标记形状

彩色图表
使用不同的填充颜色标记形状

学术图表的绘制要求

通常每个学术期刊都会有自己对学术图表的基本要求,这里我们以nature为例,nature为提交稿件的作者编写了一系列的指南,提供了编辑的标准和程序、格式指南、提交前查询、首次提交、最终提交、补充说明、补充资料、表格和声明、问题出现、其他类型的提交、发布选项等一系列的指南供作者进行参考。

首先,学术图表要规范,且符合学术期刊的要求,之后在此基础上对图表进行美观和专业,通常主要注意几点:“1,规范、2,简洁、3,专业、4,美观”等四个绝对性质的要素。

Python 数据结构

python cookbook 是 python3&2 等版本中适合开发者进阶的一本书,其中主要讲解了核心语法,同时也是 Python3 的参考书,所有代码都是在 Python 3.3 的版本下进行编写和测试的。

此书主要对数据结构等进行非常详细的介绍和案例处理,基本上包含了目前所有 Python 可以涉猎的内容。

1
编写的主要目的就是在 Python cookbook 所忽视的基础问题上,增加一点描述和更加通俗的理解方便进行阅读。

解构器

解构序列赋值多个变量

1
现在有一个包含 N 个元素的元组或者是序列,怎样将它里面的值解构后同时赋值给 N 个变量?

首先我们需要知道,元组(tuple) 了类似于列表,元组的区别在于一旦赋值给元组,就无法更改元组的元素,而列表可以更改

1
元组是将所有元素放在括号中的,也就是 my_tuple = (1,2),括号是可选的,它可以包含 int、float、list、strig 等

而题目要求是将包含 n 个的元组变量或数据,来将它里面的值解构后复制给其他变量:

1
2
3
4
5
6
7
p = (4, 5)

# 将元组解构赋值给多个变量
x, y = p

print(x) # 4
print(y) # 5

在 python 中,任何序列或是可以 迭代 的对象,都可以通过赋值语句解构并赋值给多个变量,前提是变量和数量的序列是一样的,而且这适用于列表:

1
2
3
4
list = ['BNB', 'WBNB', 'BUSD']

get_bnb, get_wbnb, get_busd = list
print(get_bnb) #BNB

同时在书中也提供了一个列表(list) 包含 元组(tuple) 的示例,但数据类型是列表的序列:

1
2
3
4
5
6
7
data = [ 'ACME', 50, 91.1, (2012, 12, 21) ]

name, shares, price, date = data
print(date) # (2012, 12, 21)

name, shares, price, (year, mon, day) = data
print(year , mon , day) # 2012 12 21

实际上上述这种解构器复制可以用于任何可以 迭代的对象,包括字符串和文件等,同时对字符串则可以是:

1
2
3
4
str = 'Hello'
a, b, c, d, e = str

print(a,b,c,d,e, sep='') # H e l l o > Hello

上面我们使用了一个 python() 函数中的 sep 参数(只有 python() 函数可以使用),以此来去掉多余部分的空格,如何在Python中使用sep打印 (adamsmith.haus),在此连接中有较为详细的介绍。

假设有时候我们只需要解构一部分,而忽略掉其他的值,那么我们就可以通过使用 _ 的方式来进行忽略:

1
2
3
4
5
data = [ 'ACME', 50, 91.1, (2012, 12, 21) ]

_, shares, price, _ = data

print(shares) # 50
1
如果我们的元素个数,超出了变量的个数,那么将会抛出一个 ```ValueError: need more than 2 values to unpack``` 错误,为了避免此类问题,我们可以使用 ```*``` 解决

在书中,这一章节主要被称之为:“将可迭代的对象赋值给多个变量”,根据提议和问题来进行理解,就是说对象的数量太多,而变量的数量太少不对应所造成的问题,可以通过 * 进行解决,也就是说后面的对象,都解构给了 date 这个变量。

1
2
3
4
data = [ 'ACME', 91.1, (2012, 12, 21), (2022, 3, 18)  ]

name, pcrice, date = data
print(date) #[(2012, 12, 21), (2022, 3, 18)]

为了更好的展示数据类型的改变,我们直接使用书上所进行展示的元组(tuple) 来进行演示:

1
2
3
4
record = ('Dave', 'dave@example.com', '773-555-1212', '847-555-1212')

name, email, *phone = record
print(type(phone))

最后原来 recird 的元组通过使用 * 的方式,输出为了一个列表,上面 phone 解构出的也永远都是列表类型,因此在特殊时候我们还需要进行转换

解构在迭代器的使用

迭代解构是专门为解构不确定的个数或任意可迭代的对象而设计的,通过 * 可以很容易利用解构器的方式结构出元素:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
records = [  
('foo', 1, 2),
('bar', 'hey'),
('foo', 3, 4),
]


def do_foo(x, y):
print('do_foo', x, y)


def do_bar(s):
print('do_bar', s)


for tag, *args in records:
if tag == 'foo':
do_foo(*args)

elif tag == 'bar':
do_bar(*args)

如果根据上述 Code 运行以及输出后都不理解的话,我们可以看分解后的数据

我们可以将迭代器中的 for tag, *args in records 理解为 tag, *args = records,之后这样 tag 就对应了 foo,bar,foo*args 对应的就是之后的对象。

因为有时候 list 元素中,可能会有 1~2 个索引值,为了通用性所以写了 *,之后就是添加循环迭代以及在 if 语句中引入对应的函数即可循环迭代 list 中的数据。

Python 复合语句

Python 中的复合语句是包含其他语句或语句组,会以另一种方式影响或控制所包含的其他语句的执行,比如传统的 if\while\for\try\whth 等,用于实现传统的控制流程构造,

Python MySQL

Python MySQL

pymysql.err.OperationalError: (1045, “Access denied for user ‘root@localhost‘@’localhost’ (using password: YES)”)

​ 遇到此问题需要在终端界面中MySQL交互式模式中输入以下命令解决此问题。

1
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'New Password';

PyMySQL

1
pip3 install PyMySQL

​ 安装PyMySQL,可以在终端或者IDE集成开发环境中进行安装,之后就可以在开发环境中进行导入。

连接数据库例子

1
2
3
4
5
6
temysql = pymysql.connect(host='localhost',
port=3306 ,
user='root',
passwd='toor',
db='mysql',
charset='utf8')

游标

1
2
# 创建游标对象 cursor
cursor = temysql.cursor()

数据库操作

1
2
3
4
5
6
# MySQL 命令
cursor.execute('show databases;')
data = cursor.fetchone()

#输出
print('%s' % data)

关闭数据库和游标

1
2
3
4
5
# 关闭游标
cursor.close()

# 关闭数据库
temysql.close()

预处理语句

1
2
3
4
5
6
7
8
9
cursor.execute("DROP TABLE IF EXISTS EMPLOYEE")
data = """CREATE TABLE EMPLOYEE (
FIRST_NAME CHAR(20) NOT NULL,
LAST_NAME CHAR(20),
AGE INT, SEX CHAR(1),
INCOME FLOAT )"""

#输出
print('%s' % data)

提交数据 or 回滚

1
2
3
4
5
6
7
8
9
10
try:
# 执行语句
cursor.execute(data)

# 提交数据
temysql.commit()

except:
# 数据回滚
temysql.rollback()

连接池

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import time
import pymysql
import threading
from DBUtils.PooledDB import PooledDB, SharedDBConnection

Pool = PooledDB(creator=pymysql, # 使用模块
maxconnections=6, # 连接池允许的最大连接数, 0 or None表示不限制
mincached=2, # 在初始化时的连接池最大连接数
maxcached=5, # 最多限制链接,0 or None表示无限制
maxshared=3, # 连接池最多的共享链接数量,0 or None表示无限制 (无论设置多少,_maxshared永远的为0,所以都是共享的)
blocking=True, # 连接池如果没有可用的连接诶是否阻塞等待。(True 等待 False不等待)
maxusage=None, # 连接可重复次数(None = 无限制)
setsession=[], # 开始回话前执行的命令列表
ping=0, # 检查服务是否可用 (0 = 永不停止,1 = 每当请求时,2 = 创建游标时, 4 = 执行查询时,7 = 始终)
host='localhost', # MySQL地址
port=3306, # MySQL Port
user='root', # MySQL User
passwd='toor', # MySQL Password
db='mysql', # MySQL db
charset='utf8') # MySQL 字符集

Dcat Admin 工具栏按钮

Dcat Admin 在 DcatAdmin 数据表格之上为我们提供了工具栏按钮,使得我们可以在数据表格页面中自定义按下后的弹窗页面,通过 app/Admin/Actions/Tool 目录中定义菜单栏工具为 MovieShowTool.php ,并继承自 AbstractTool(Dcat\Admin\Grid\Tools\AbstractTool)

1
除了可以使用之前在数据表格中所使用到的页面脚手架之外,我们还可以使用 Artisan Cli 进行构建,数据表格、数据表单、数据详情和模型树,参考官方文档进行使用 [基本使用 | 动作 |《Dcat Admin 中文文档 2.x》| Laravel China 社区 (learnku.com)](https://learnku.com/docs/dcat-admin/2.x/basic-use/8124)

对于 Artisan Cli Command,我们可以通过 php artisan admin:action 来选择 show-tool 即 Dcat Admin 工具栏按钮自定义,然后输入类名称目录即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
>php artisan admin:action

Which type of action would you like to make?:
[0] default
[1] grid-batch
[2] grid-row
[3] grid-tool
[4] form-tool
[5] show-tool
[6] tree-row
[7] tree-tool
> 5

Please enter a name of action class:
> MovieOutherTools

Please enter the namespace of action class [App\Admin\Actions\Show]:
> App\Admin\Actions\Tool

App\Admin\Actions\Tool\MovieOutherTools created successfully.

1
数据表单是通过按钮、或者菜单进行调用的。

之后,我们通过工具表单的 Artisan Cli Commad php artisan admin:form MovieOutherForm 命令来生成一个名为 MovieOutherForm 类作为工具表单,在 app/Admin/Forms 目录内:

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
34
35
36
37
38
39
40
41
<?php  

namespace App\Admin\Forms;

use Dcat\Admin\Widgets\Form;

class MovieOutherForm extends Form
{
/**
* 处理表单提交请求 * * @param array $input
*
* @return mixed
*/
public function handle(array $input)
{ // dump($input);

// return $this->response()->error('Your error message.');
return $this
->response()
->success('Processed successfully.')
->refresh();
}

/**
* 构建表单. */
public function form()
{
$this->text('name')->required();
$this->email('email')->rules('email');
}

/**
* 表单的数据. * * @return array
*/
public function default()
{ return [
'name' => 'John Doe',
'email' => 'John.Doe@gmail.com',
];
}
}

此时 MovieOutherForm 就会集成 Form,即 Dcat\Admin\Widgets\Form 使得可以用来构建表单和提交数据,以及全方位的独立处理数据,且不需要注册额外路由。

1
2
3
通过 ```php artisan list``` 可以列出所有的 Laravel Artisan 命令,之后我们输入 ```php artisan list admin``` 来查看 Dcat Admin 的所有命令和语法。

此外,我们还可以通过使用 ```php artisan help make:console``` 来查看 Artisan make Console 的具体用法。

在此之前,我们通过 Admin | 代码生成器 网页脚手架所自动生成的控制器、模型以及数据仓库外,还可以通过 Illuminate\Database\Eloquent\Model | Laravel API 使得 app\Models\Shop 实现抽象模型,然后通过 Service 以此来中转数据。

Dcat Admin 数据表格

Dcat Admin 的数据表格直译过来就是将数据的数据,以列表的形式展示在 DcatAdmin 页面中,在 Dcat Admin 的官方文档中有大量的篇幅描写了基于 bootstrap 的特性,与 Laravel 相互结合的各种语法糖进行演示。

通过 Dcat Admin 所提供的数据表格我们可以通过 Dcat Admin 方法来在表格的基础上,添加工具栏、过滤查询、过滤器、搜索、筛选器、编辑、创建、时间、软删除、渲染等,同时也有数据表格的样式来进行选择。

Grid

在接触到 Dcat Admin 数据表格之前,我们需要了解到 Dcat\Admin\Grid 类,它主要通过数据模型来生成表格,在之前我们可以使用 Dcat Admin 所提供的 Repositories(数据仓库) ,也可以直接从数据库中调用 Model,都是可以的。

在数据表格中,我们会了解到 DcatAdmin 中的 Repositories 和 Models 以及 Admin Controller 的使用与构造,首先,Dcat Admin 并没有为我们提供诸如 Laravel-Admin 类似的命令。

你需要做的是,通过 Factory SQL 来创建一个 SQL model,具体的你可以参考下 Laravel Factory SQL | kunlsq (kunlunsiqu.github.io) 文档进行操作,然后使用 Admin | 代码生成器 选择已经创建的数据表,最后通过页面脚手架来进行操作。

点击提交后,我们可以清楚的看到 DcatAdmin 为我们构建了 Model、Controller、Repository,甚至是 Lang 语言文件等,在此之后,我们就可以通过《Dcat Admin 中文文档》 | Laravel China 社区 (learnku.com)官方文档中进行下一步的自定义。

1
由于官方文档主要起到的是参考作用,并不适用于从零开始构建一个 Dcat Admin 应用,因从我们建议你通过 [jqhph/dcat-admin-demo (github.com)](https://github.com/jqhph/dcat-admin-demo) 下载 [Admin | Dashboard](http://103.39.211.179:8080/admin) 的 Demo,根据需求进行自定义并参照官方文档,进行开发,会加快理解。

之后我们需要做的就是需要在 app/Admin/routes.php 中为我们刚刚所创建的 MovieController 加入一行路由,即:

1
$router->resource('movie','MovieController');

之后,你可以访问 Admin | 订单管理 来访问刚刚通过页面脚手架所创建的页面,但在此之前,我们还需要在 app/Admin/bootstrap.php 目录中加入菜单,即 DcatAdmin 左侧导航栏中的数据:

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
[<?php  

use Dcat\Admin\Admin;
use Dcat\Admin\Grid;
use Dcat\Admin\Form;
use Dcat\Admin\Grid\Filter;
use Dcat\Admin\Show;
use Dcat\Admin\Layout\Menu;
/**
* Dcat-admin - admin builder based on Laravel. * @author jqh <https://github.com/jqhph>
* * Bootstraper for Admin. * * Here you can remove builtin form field: * * extend custom field: * Dcat\Admin\Form::extend('php', PHPEditor::class); * Dcat\Admin\Grid\Column::extend('php', PHPEditor::class); * Dcat\Admin\Grid\Filter::extend('php', PHPEditor::class); * * Or require js and css assets: * Admin::css('/packages/prettydocs/css/styles.css'); * Admin::js('/packages/prettydocs/js/main.js'); * */
Admin::menu(function (Menu $menu) {
$menu->add([
[ 'id' => '1',
'title' => '亚马逊',
'icon' => 'fa fa-amazon',
'uri' => '',
'parent_id' => 0,
'permission_id' => 'test', // 权限绑定
'roles' => 'test-roles', // 角色绑定
],
[
'id' => '2',
'title' => '订单管理',
'icon' => 'fa-reorder',
'uri' => 'movie',
'parent_id' => '1'
]
]);
});](<%3C?php

use Dcat\Admin\Admin;
use Dcat\Admin\Grid;
use Dcat\Admin\Form;
use Dcat\Admin\Grid\Filter;
use Dcat\Admin\Show;
use Dcat\Admin\Layout\Menu;
/**
* Dcat-admin - admin builder based on Laravel.
* @author jqh <https://github.com/jqhph%3E
*
* Bootstraper for Admin.
*
* Here you can remove builtin form field:
*
* extend custom field:
* Dcat\Admin\Form::extend('php', PHPEditor::class);
* Dcat\Admin\Grid\Column::extend('php', PHPEditor::class);
* Dcat\Admin\Grid\Filter::extend('php', PHPEditor::class);
*
* Or require js and css assets:
* Admin::css('/packages/prettydocs/css/styles.css');
* Admin::js('/packages/prettydocs/js/main.js');
*
*/

Admin::menu(function (Menu $menu) {
$menu->add([
[
'id' => '1',
'title' => '亚马逊',
'icon' => 'fa fa-amazon',
'uri' => '',
'parent_id' => 0, // 菜单子集
'permission_id' => 'test', // 权限绑定
'roles' => 'test-roles', // 角色绑定
],
[
'id' => '2',
'title' => '订单管理',
'icon' => 'fa-reorder',
'uri' => 'movie',
'parent_id' => 1
],
]);
});>)

再次需要注意的是参数是调整菜单的上下级,以上面的 Code 举例,亚马逊是一级菜单,而订单管理是二级菜单,这主要通过 permission_id 来进行调整。

同样的,配置完菜单后,我们还需要对该页面的标题进行设置,进入到 \resources\lang\zh_CN\movie.php 然后更改对应的元素在该语言下的翻译即可。

最后你可以Admin | 订单管理 访问,来进行查看刚刚我们修改和创建后的页面即效果,然后按照官方文档,进一步根据场景来进行调整即可。

Dcat Admin 入门

Dcat Admin 是一个基于 Admin admin 二次开发的后台构建工具,支持页面一键生成 CURD 代码且具有丰富的后台组件。并拥有简洁的 API 和用户、权限、菜单管理,同时使用 PJAX 构建盒子模型(支持按需加载静态资源,可无限扩展但不影响性能)并采用松耦合的页面构建雨数据操作和涉及。

打牌自定义页面和主题配色,以及多主题的切换让其变得高颜值并支持插件、可视化代码生成器以及数据表格的构建,支持表头、数据导出和搜索等批量操作以及异步上传文件等。

对于构建 Dcat Admin 可以通过 composer 在构建完 Laravel 之后的操作,即使用

1
2
3
4
5
6
composer create-project --prefer-dist laravel/laravel dcat-admin

!!! ad-warning
title: Laravel 版本控制
collapse: close
同样的你可以通过 composer create-project --prefer-dist laravel/laravel dcat-admin 7.

之后通过 .env 配置文件,在此基础上填写 Mysql 文件以及安装 dcat-admin 等,在此基础上直接通过 composer require dcat/laravel-admin:"2.**" -vvv ,之后 php artisan admin:publish 完成后。

通过 composer install\composer update 完成依赖的安装,使用 php artisan migrate 完成 Model 的定义,并通过 php artisan admin:install 将 Dactadmin 的必要数据(user and pass)数据映射到数据库中。

之后 Dcat-admin 的所有配置都在 config/admin.php 文件夹和目录中,之后的后台目录 app/Admin 中来进行开发:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
app/Admin
├── Controllers //存放 Dcat-admin 启动文件
│ ├── AuthController.php //DcatAdmin 登录鉴权控制器
│ └── HomeController.php //DcatAdmin 首页控制器
├── Metrics //数据统计卡片 Demo
│ └── Examples
│ ├── NewDevices.php
│ ├── NewUsers.php
│ ├── ProductOrders.php
│ ├── Sessions.php
│ ├── Tickets.php
│ └── TotalUsers.php
├── bootstrap.php //Dcat-admin 启动文件
└── routes.php //后台路由文件
1
DcatAdmin 的前端静态文件在 ```/public/vendor/dcat-admin``` 目录下,同样的对应数据库迁移文件于同步文件在 ```/database/migrations/``` 目录中。

由于是基于 Laravel Admin 而二次开发的,因此他的语言文件包在 /resources/lang 目录中,可根据环境自行进行选择。

之后,我们还需要在开发环境中开启 Debug 模式,这主要是因为 DactAdmin 所提供的开发工具需要在 debug 下才可使用,我们只需要在 .env 配置文件中的 APP_DEBUG 值设置为 true 即可。

Controller 生成

可以通过访问 Admin | 代码生成器 新建并提交一个数据表文件,之后 DcatAdmin 会在 app/Admin/Controllers 中生成一个名为 UserController 的控制器,并会在 App\Models\ 中自动创建一个名为 User 的模型。

之后我们需要做的是只需要在 app/Admin/routes.php 加入一条路由语法 $router->resource('name' , 'UserController');,即可,就会生成一组数据列表 Admin | 管理员,在下一章节中将会详细讲解并使用 DcatAdmin 构建的表格。

1
之后打开 [Admin | 菜单](http://127.0.0.1:8000/admin/auth/menu) 就可以查看对应的 menu 即在管理后台左侧页面中查看用户管理的页面链接路口,同样的你还可以进行相应的编辑。

Repositories

Dcat Admin 在 Laravel Admin 中引入了一个新的概念,即 Dcat Admin 构建的页面并不直接依赖于 Model,而是直接引入 Repositories 作为中间层,不在与数据的读写产生强耦合的关系。

比如之前我们通过代码生成器所构建的 User,他也会在数据仓库即 app\Admin\Repositories\User 中创建同名的数据仓库文件,其内容为:

1
2
3
4
5
6
7
8
9
10
11
<?php

namespace App\Admin\Repositories;

use Dcat\Admin\Repositories\EloquentRepository;
use App\User as UserModel;

class User extends EloquentRepository
{
protected $eloquentClass = UserModel::class;
}

Import js

Dcat Admin 使用的是 jquery-pjax - npm (npmjs.com) 所构建的无刷页面, 你可以通过 集成 Pjax 实现网站无刷新加载 | Liuyib’s Blog 这一文档来了解 Pjax 的实现过程。因此引入 Js 的方式也与传统的引入方法不同。

由于 Dcat Admin 构建的是一个单页应用,加载 JS 只会被执行以此,所以在框架为问哦们提供的 Admin::script 方法的载入非常实用,主要分为两个场景,引入文件和引入 JS Code.

JS file import

DcatAdmin 所提供的两种方式,主要使用的是 Admin:script 以及 Dcat.ready ,主要使用的是 Renderable 契约来进行实现,对于文件官方给了一套详细的写法说明:

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
34
35
36
37
<?php

use Illuminate\Contracts\Support\Renderable;
use Dcat\Admin\Admin;

class Card implements Renderable
{
public static $js = [
// js脚本不能直接包含初始化操作,否则页面刷新后无效
'xxx/js/card.min.js',
];
public static $css = [
'xxx/css/card.min.css',
];

public function script()
{
return <<<JS
console.log('所有JS脚本都加载完了');
// 初始化操作
$('xxx').card();
JS;
}

public function render()
{
// 在这里可以引入你的js或css文件
Admin::js(static::$js);
Admin::css(static::$css);

// 需要在页面执行的JS代码,例如初始化代码
// 通过 Admin::script 设置的JS代码会自动在所有JS脚本都加载完毕后执行
Admin::script($this->script());

return view('...')->render();
}
}

之后即可通过刚刚写完的 Card 组件引入到 Controller 中,以此来使用 Card 组件,需要注意的是,Card 组件需要用到的静态文件只会在当前请求中加载,以此符合“按需引入”的概念。

1
需要注意的是 ```Card``` class 并没有强制要求的存放目录,理论上来说只要能加载,放在什么地方都可以。
1
2
3
4
5
6
7
8
9
10
11
12
13
use Dcat\Admin\Layout\Content;
use Card;

class HomeController
{
public function index(Content $content)
{
// 使用上面的Card组件
// Card组件需要用到的静态文件只会在当前请求加载
// 其他请求不会加载
return $content->body(new Card());
}
}

blade import JS

至于 Js Code 的引入则较为方便,直接在 Laravel模板文件中添加即可,但需要注意的是需要把 Js code 放入 Dcat.ready 中执行。

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
34
35
36
37
38
39
40
41
42
43
44
45
<?php
namespace App\Admin\Controllers;

use App\Admin\Metrics\Examples;
use App\Http\Controllers\Controller;
use Dcat\Admin\Http\Controllers\Dashboard;
use Dcat\Admin\Layout\Column;
use Dcat\Admin\Layout\Content;
use Dcat\Admin\Layout\Row;
use Dcat\Admin\Admin;

class HomeController extends Controller
{
public function index(Content $content)
{
return $content
-%3Eheader('Dashboard')
->description('Description...')
->body(function (Row $row) {
$row->column(6, function (Column $column) {
$column->row(Dashboard::title());
$column->row(new Examples\Tickets());
});

$row->column(6, function (Column $column) {
$column->row(function (Row $row) {
$row->column(6, new Examples\NewUsers());
$row->column(6, new Examples\NewDevices());
});

$column->row(new Examples\Sessions());
$column->row(new Examples\ProductOrders());
});

Admin::script(
<<<JS
(function () {
var name = 'test';
console.log('all end', name)
})()
JS
);
});
}
}>)

为了方便理解我们可以将上述代码分为两个部分,我们都知道,DactAdmin 主要使用了 Bootstrap + Jquery 主要满足了 Dact Admin 外观以及无刷加载、动画等方面的功能,因此,你可以将下面 Code 分为 Bootstrap 附加功能:

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
34
35
36
<?php  

namespace App\Admin\Controllers;

use App\Admin\Metrics\Examples;
use App\Http\Controllers\Controller;
use Dcat\Admin\Http\Controllers\Dashboard;
use Dcat\Admin\Layout\Column;
use Dcat\Admin\Layout\Content;
use Dcat\Admin\Layout\Row;
use Dcat\Admin\Admin;

class HomeController extends Controller
{
public function index(Content $content)
{ return $content
->header('Dashboard')
->description('Description...')
->body(function (Row $row) {
$row->column(6, function (Column $column) {
$column->row(Dashboard::title());
$column->row(new Examples\Tickets());
});

$row->column(6, function (Column $column) {
$column->row(function (Row $row) {
$row->column(6, new Examples\NewUsers());
$row->column(6, new Examples\NewDevices());
});

$column->row(new Examples\Sessions());
$column->row(new Examples\ProductOrders());
});
});
}
}

这主要是 Dact Admin 下的布局,也就是使用的 bootstap 的栅格系统,在此需要认清楚,row 是行的意思,而 column 是列的意思,至于详细的你可以访问 开发前必读 | 入门 |《Dcat Admin 中文文档 2.x》| Laravel China 社区 (learnku.com) 查阅 Dcat Admin 的官方文档。

而之后以 Admin::script 起头的 DcatAdmin 方法主要是引入 JS Code,而在此之后 DcatAdmin 还提供了类似于模板的语法操作 Dcat.ready 方法,但在此之前我们主要先了解下 Js Code 在 Controller 的使用:

1
2
3
4
5
6
 Admin::script(  
<<<JS
(function () {
var name = 'test'; console.log('javaScript code >', name)})()
JS
);

之后你就可以访问 Admin | Dashboard 页面来查看该 JavaSCript Code 的执行效果,而在此之后我们主要会在页面组件中去使用下一个方法。

Laravel 响应

在上一章节的上一章节中我们讲解到了Laravel的请求,而这次我们主要来讲解以下Laravel的响应,学过计算机网络的读者可能会对此联想到TCP/IP的三次握手,和四次挥手,本篇我们主要演示下Laravel的响应。

快速构建一个响应


如果要说响应,当我们请求过后,Server是不是需要给我们来一个响应信息,而本次我们主要使用Laravel路由来进行快速构建一个响应信息:

web.php

1
2
3
Route::get('/response', function () {
return "Hello,world!";
});


Laravel项目中,如果想将标头添加到Response之中,我们可以使用header()方法进行,且可以附加多个数据如:

web.php

1
2
3
4
Route::get('/response', function () {
return response('hello,world!',200)
->header('X-Header-One','This is 2021');
});

当然你也可以指定一些状态代码,比如1xx、2xx、3xx、4xx、5xx这些,分别对应临时响应、成功、重定向、请求错误、服务器错误等。如果想详细学习HTTP状态码的读者可参考菜鸟教程中的一篇文章:https://www.runoob.com/http/http-status-codes.html。在本文演示当中使用的```200```状态码意思为:请求成功。

withCookie


在本文中,我们可以附加带有响应的Cookie,并且使用withCookie方法进行实现,将其cookie附加到响应中,对于Laravel来说,这些cookie都是经过加密和签名的,因此他不具有修改性:

TestController

1
2
3
4
Route::get('/response', function () {
return response('hello,world!',200)
->withCookie('jiangxue','cookie');
});

Laravel 文件上传

文件上传是在项目开发中较为常用的一项功能,通常在用户界面中运用在了头像图片或者说在表单提交中的文件上传等相关场景,在本文中将会以Laravel为例。

hasFile (表单是否存在文件)


Laravel为我们提供了hasFile方法来用于检索表单中是否存在文件,在本文中,如果表单包含了文件则返回yes,否则将会返回no,需要配合前端、路由、控制器进行:

input.blade.php

1
2
3
4
5
6
7
8
9
10
11
12
<html>
<head>
<title>This is be Input up</title>
</head>
<body>
<form action="/user/name" method="post" enctype="multipart/form-data">
{{csrf_field()}}
<input type="file" name="images">
<button type="submit">up file</button>
</form>
</body>
</html>

TestController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php

namespace App\Http\Controllers;

use http\Cookie;
use Illuminate\Http\Request;

class TestController extends Controller
{
public function store(Request $request) {
if ($request->hasFile('images')) {
echo "yes";
} else {
echo "no";
}
}
}

web.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
return view('welcome');
});

Route::get('/input' ,function () {
return view('input');
});

Route::post('/user/name', array('uses'=>'TestController@store'));

Route::get('/user/name', 'TestController@store');

store


Laravel还为开发者提供了一种存储上传文件的方法为store,主要存储在/srv/www/htdocs/test_webapp/public/storage目录下,此目录默认情况下是不存在的,所以我们需要使用以下命令进行创建:

php artisan storage:link

TestController

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

namespace App\Http\Controllers;

use http\Cookie;
use Illuminate\Http\Request;

class TestController extends Controller
{
public function store(Request $request) {
$file = $request->file('images')->store('public/storage');
}
}

当我们访问“http://localhost:8000/input”的时候,此次我们上传一张图片,之后我们我们会在```/srv/www/htdocs/test_webapp/public/storage```下存储一张我们刚刚上传的照片并经过重命名处理过的:zV193WUEfZSvs00tc78TSu8WPeIbIQjfQnP82ufW.pngw

storeAs


storeAs在Laravel项目之中主要用于为上传的文件进行命名,如果你将名称写死那么他将会当你提交第二个文件的时候自动将第一张文件进行替换,当然读者也可以自行进行研究如何让他写活?

TestController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php

namespace App\Http\Controllers;

use http\Cookie;
use Illuminate\Http\Request;
use Illuminate\Http\Response;

class TestController extends Controller
{
public function store(Request $request) {
$file = $request->file('images')->storeAs('public/storage','jiangxue.jpg');
}
}
📖 more posts 📖