### 目录结构说明
* 目前,apiex主要包含了如下几个核心文件,即apiex和apiex的traits。
* 核心功能目录如下:
```
// 继承api基类的apiex控制器
\\application\\common\\controller\\Apiex.php
// apiex控制器的traits
\\application\\common\\library\\traits\\Apiex.php
// apiex用户权限类 AuthForApiex及其 对应的trait AuthExtend
\\application\\common\\library\\AuthForApiex.php
\\application\\common\\library\\traits\\AuthExtend.php
// 其他扩展功能目录(如果不需要,可以直接删除,不影响apiex核心功能)
// 对thinkphp的model类中的某些方法扩展和新功能添加
\\application\\common\\library\\traits\\ModelExtend.php
// 对thinkphp的validate类中的某些方法扩展和新功能添加
\\application\\common\\library\\traits\\ValidateExtend.php
// URL 解析类
\\application\\common\\library\\Urlparse.php
// 页码计算器
\\application\\common\\library\\PageCalculator.php
```
### 使用说明:
* apiex是对api的继承和扩展,因而,只要在原始使用api的控制器中引入apiex并改为继承apiex即可。
* 其他的功能扩展需要在对应的model和validate中引入对应trait。
* 注意:apiex原则上不会影响已经开发完成的功能,即不会与原始api产生冲突,可放心使用。
### 功能说明
* apiex无法独立存在,它是依附于api基类存在的,是对 api 在 数据库操作方面 和 接口安全 的扩展。、
* 基础的代码逻辑与backend一致,即:在后台怎么使用backend,就怎么使用apiex。
* 由于后台的权限是基于admin表进行控制,而api部分是基于user表进行控制,因而,有些权限方面的开发会有缺失。针对这一方面,尽量进行了弥补,即,可以在数据表中,加入 user\_id ,然后,在控制器中,设置protected $dataLimit = 'personal'; 来实现用户对于数据的权限控制,目前,由于user表逻辑中,不存在上下级关系,因而,只能实现person逻辑,而无法具备 auth 逻辑。
### 其他扩展功能说明
* 对于“对thinkphp的model类中的某些方法扩展和新功能添加方面”方面
* 此功能扩展主要是对model中的场景验证进行完善。
* 增加“实时设置场景验证方法”和“重写“自动验证数据”,使得验证类可以支持实时的场景验证。”
* 所谓“实时设置场景验证方法”,与现有的场景验证不同的是,当前场景验证是对前台提交的数据进行“死规则验证”(所谓死规则验证就是指验证规则一旦写死,将不能对某些参数值进行修改)。这样的验证不具有灵活性,不能结合控制器中的逻辑判断进行进一步验证。
* 示例:现在前台提交了用户的文章信息,后台所有用户的文章均保存在同一张表中,此时,要求对于同一用户,不允许出现文章标题重复,而不同的用户可以实现标题重复。
* 分析:面对这样的要求,只是使用简单的字段唯一性验证已经不能满足,而使用tp提供的多字段唯一验证的前提条件是,前台提交的数据包含了所有需要进行唯一性验证的数据。具体来说,我们这里要判断 user\_id,title 两个字段同时相同时,才认为此数据是重复数据,而依照fastadmin的权限验证逻辑,前台是无需提交 user\_id的,而只需要提交token或者账号密码,当然,如果非要说我就是要求前台提交user\_id,那么也可以,但是,如果现在就只要求前台提交token或账号密码信息,则此时我们只能从auth类中获取user\_id,那么,这就要求我们的验证规则中的user\_id部分必须是动态的。
* 解决:
```
// 增加“实时设置场景验证方法”。
/**
* 实时设置场景验证方法
* @param Array $sence \[description\]
*/
public function setCurrentScene(Array $scene)
// 使用方法:
// 在对应需要此验证方法的model中,引入此traits
/**
* 引入对thinkphp的model类中的某些方法扩展和新功能添加的traits
*/
use \\app\\common\\library\\traits\\ModelExtend;
// 在对应控制器的方法中,添加如下场景设置:
$name = str\_replace("\\\\model\\\\", "\\\\validate\\\\", get\_class($this->model));
$validate = is\_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
//设置添加时的场景验证
$currentScene = [
'add' => [
"name" => "require|unique:monitoring_plan,name,'','',".$params['user_id'].",user_id,deletetime",
'first_keywords' => "requireIf:second_keywords^third_keywords,''^''",
'second_keywords' => "requireIf:first_keywords^third_keywords,''^''",
'third\_keywords' => "requireIf:second\_keywords^first\_keywords,''^''",
],
];
//设置验证类的基础验证信息
$this->model->validate($validate)->setCurrentScene($currentScene);
// 此场景验证只能设置一个场景,如只设置 add 或 edit ,不能一起设置,毕竟是为了实时场景进行的验证。
// 设置实时的场景验证时,需要依赖对validate的重写traits,具体的调用方法看下面的“对thinkphp的validate类中的某些方法扩展和新功能添加”的说明即可。
```
* 对于“对thinkphp的validate类中的某些方法扩展和新功能添加”方面
* 目前,主要是对已有方法的重写,但是,为了兼容其原始功能,保留了其原始功能和使用方法的基础上,进行了二次开发。所以,不会破坏已有的判断逻辑。
* 重写的方法如下:
* requireIf
* unique
* scene
* 具体重写后的功能和使用方法可以参考对应代码注释
* 引入和使用方法:
```
//在对应已有的validate中,进入此traits
/**
* 对thinkphp的validate类中的某些方法扩展和新功能添加的traits\
*/
use \\app\\common\\library\\traits\\ValidateExtend;
// 此时,由于traits的作用,使得原始的验证方法失效,转而使用重写的方法,当然,重写后的方法仍然支持官方提供的调用方法和使用逻辑,可以放心使用。
```
* 对于“URL 解析类”方面
* 此解析类的出现,是为了弥补php本身parse_url函数的功能缺失问题。
* 目前,parse_url 在进行url分析后,只能获取携带主机信息的完整域名信息,但是无法获取根域名,因而,对应给出了此解析类。
* 目前,此解析类提供两种方法
* 根据URL提取根域名:getBaseDomain(string $url)
* 判断是否为正确域名:isDomain($domain)
* 使用方法:
```
// 为了方便作为工具类使用,getBaseDomain使用了静态方法定义,如下调用即可:
// 调用URL 解析类中的根据URL提取根域名方法,分析并获取用户输入的根域名
$domain = \\app\\common\\library\\Urlparse::getBaseDomain($url);
```
* 对于“页码计算器”方面
* 页码计算器时为了面向对于一批数据进行分页时,需要计算开始位置和给出总页数而设计的简单工具类。
* 目前已有的方法:
* 计算总页数:pageAll($dataCount, $pageShow)
* 根据传入的分页要求,计算后给出limit开始位置: pageStart($dataCount, $pageShow, $page)
* 使用方法:由于两个方法均使用静态方法定义,因而可以通过直接调用使用。
```
// 计算总页数:
$totalPage = \\app\\common\\library\\PageCalculator::pageAll($dataCount, $pageShow);
// 获取页码开始位置:
$limitStart = \\app\\common\\library\\PageCalculator::pageStart($dataCount, $pageShow, $page);
// 具体参数说明请直接参考代码注释。
```