# SaiAdmin后端

# 系统架构介绍

经过大量开发实践,php后端分层为三层较为合适Controller,Logic,Model;额外增加了Validate验证器,对后端数据进行校验.

Controller 负责处理用户的输入和管理应用程序的流程;

Logic 负责应用的核心功能和规则,确保应用能够按照预期的方式工作;

Model 使应用程序的数据访问和操作逻辑组织得更加清晰和易于维护;

Validate 验证器,用于后端数据的校验;

TIP

在saiadmin中,已经针对这三层进行了基本功能的封装,开发新的功能时候,只需要继承对应的基类,即可非常便捷的进行开发; 我们新建一个简单的文章管理表,针对这个表进行分析说明

# 控制层

由于是通过webman插件形式进行安装,我们新开发功能可以在任意应用下进行开发,本案例,假设在webman的app目录下新建一个cms的应用,然后功能全部开发在这个应用下。

<?php
// +----------------------------------------------------------------------
// | saiadmin [ saiadmin快速开发框架 ]
// +----------------------------------------------------------------------
// | Author: your name
// +----------------------------------------------------------------------
namespace app\cms\controller\news;

use plugin\saiadmin\basic\BaseController;
use app\cms\logic\news\ArticleLogic;
use app\cms\validate\news\ArticleValidate;
use support\Request;
use support\Response;

/**
 * 文章管理控制器
 */
class ArticleController extends BaseController
{
    /**
     * 构造函数
     */
    public function __construct()
    {
        $this->logic = new ArticleLogic();
        $this->validate = new ArticleValidate;
        parent::__construct();
    }

    /**
     * 数据列表
     * @param Request $request
     * @return Response
     */
    public function index(Request $request): Response
    {
        $where = $request->more([
            ['title', ''],
            ['author', ''],
        ]);
        $query = $this->logic->search($where);
        $data = $this->logic->getList($query);
        return $this->success($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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

TIP

Hi guys,没看错,所有功能已经写完了,就这简单的代码,已经包括了基本的CRUD功能,还包含软删除,回收站数据,数据恢复的功能,如果要弄清楚,那么你可以去BaseController里面追查,如果需要自己实现,可以直接在控制器中重写对应的方法。

# 你以为这么简单就结束了?No,这里还有个大招。

在控制器中,我们的index是一个查询数据的方法,在这里我们获取了2个参数

A:“如果我告诉你别的地方不用写任何代码,就可以实现查询,你信吗?”

B:“不信!”

A:“什么?不信?不信也得信!因为这是SaiAdmin!”

# 别着急,还没完呢。

神奇的$this->logic,你可以直接把它当作model来调用模型的方法,因为这是SaiAdmin

# 逻辑层

逻辑层的好处是,可以将逻辑功能封装好,供给外部控制器调用,不管是常规的PC端,还是移动端,还是其他的控制器,都可以直接调用,这样可以大大降低代码的复杂度,提高开发效率。

<?php
// +----------------------------------------------------------------------
// | saiadmin [ saiadmin快速开发框架 ]
// +----------------------------------------------------------------------
// | Author: your name
// +----------------------------------------------------------------------
namespace app\cms\logic\news;

use plugin\saiadmin\basic\BaseLogic;
use plugin\saiadmin\exception\ApiException;
use plugin\saiadmin\utils\Helper;
use app\cms\model\news\Article;

/**
 * 文章管理逻辑层
 */
class ArticleLogic extends BaseLogic
{
    /**
     * @var bool 数据边界启用状态
     */
    protected $scope = false;

    /**
     * 构造函数
     */
    public function __construct()
    {
        $this->model = new Article();
    }
}
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

WARNING

什么,代码又写完了?,没错,不说了,要钻研的话去BaseLogic里面追查。

# 模型层

模型层主要是和数据库的表进行映射,一般一个模型对应一个数据表。详细参考 ThinkPHP (opens new window)

<?php
// +----------------------------------------------------------------------
// | saiadmin [ saiadmin快速开发框架 ]
// +----------------------------------------------------------------------
// | Author: your name
// +----------------------------------------------------------------------
namespace app\cms\model\news;

use plugin\saiadmin\basic\BaseModel;

/**
 * 文章管理模型
 */
class Article extends BaseModel
{
    /**
     * 数据表主键
     * @var string
     */
    protected $pk = 'id';

    /**
     * 数据库表名称
     * @var string
     */
    protected $table = 'eb_article';

    /**
     * 文章标题 搜索
     */
    public function searchTitleAttr($query, $value)
    {
        $query->where('title', 'like', '%'.$value.'%');
    }

    /**
     * 关联模型category
     */
    public function category()
    {
        return $this->belongsTo(ArticleCategory::class, 'category_id', 'id');
    }
}
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

DANGER

嗯,总算有点正常的模型层代码量了,要钻研的话去BaseModel里面追查。特别说一句,如果控制器中传递参数是通过“=”进行数据查询的,这里不用写搜索器,因为这是SaiAdmin,已经内置好了。什么是搜索器?,去看看ThinkORM。

# 校验器

校验器主要是对后端数据进行验证,增强数据的安全性。详细参考 think-validate (opens new window)

<?php
// +----------------------------------------------------------------------
// | saiadmin [ saiadmin快速开发框架 ]
// +----------------------------------------------------------------------
// | Author: your name
// +----------------------------------------------------------------------
namespace app\cms\validate\news;

use think\Validate;

/**
 * 文章管理验证器
 */
class ArticleValidate extends Validate
{
    /**
     * 定义验证规则
     */
    protected $rule =   [
        'category_id' => 'require',
        'title' => 'require',
        'content' => 'require',
    ];

    /**
     * 定义错误信息
     */
    protected $message  =   [
        'category_id' => '文章分类必须填写',
        'title' => '文章标题必须填写',
        'content' => '文章内容必须填写',
    ];

    /**
     * 定义场景
     */
    protected $scene = [
        'save' => [
            'category_id',
            'title',
            'content',
        ],
        'update' => [
            'category_id',
            'title',
            'content',
        ],
    ];

}
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

# Config配置文件

配置文件路径在plugin/saiadmin/config/saithink.php,代码如下:

return [
    // 跨域配置
    'cross' => [
        // token信息
        'token_name' => 'Authori-zation',
        // 过期时间 (小时)
        'token_expire' => 6,
    ],
    // 中间件白名单
    'white_list' => [
        '/core/captcha',
        '/core/login',
    ],
    // 是否开启后端接口权限认证
    'server_auth' => true,
    // 缓存配置
    'cache' => [
        // 开启缓存
        'enable' => true,
        // 驱动 redis或者file
        'type' =>'file',
        // 缓存前缀
        'prefix' =>'saithink_',
    ],
    // 验证码存储模式
    'captcha' => [
        // 验证码存储模式 session或者redis
        'mode' => 'session',
        // 验证码过期时间 (秒)
        'expire' => 300,
    ]
];
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