1、在 api.pcs-stat.localhost 下,一个标准的 RESTful API。方法文件中的代码如下(一位同事所编写)。如图1
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace api/rests/data_plan_control_task;
use common/logics/StatTask;
use Yii;
use api/models/Plan;
use yii/data/ActiveDataProvider;
use yii/data/ArrayDataProvider;
use yii/base/InvalidConfigException;
/**
* 获取数据大屏的选题管控的任务统计列表:/data-plan-control-tasks ( data-plan-control-task/index )
*
* For more details and usage information on IndexAction, see the [guide article on rest controllers](guide:rest-controllers).
*
*/
class IndexAction extends /yii/rest/IndexAction
{
public $dataFilter = [
'class' => 'yii/data/ActiveDataFilter',
'searchModel' => 'api/models/StatTaskSearch',
'attributeMap' => [
'group_id' => '{{%stat_task}}.[[group_id]]',
'created_at' => '{{%stat_task}}.[[created_at]]',
],
];
/**
* Prepares the data provider that should return the requested collection of the models.
* @return array|object|ActiveDataProvider
* @throws InvalidConfigException
*/
protected function prepareDataProvider()
{
$requestParams = Yii::$app->getRequest()->getQueryParams();
$filter = null;
if ($this->dataFilter !== null) {
$this->dataFilter = Yii::createObject($this->dataFilter);
if ($this->dataFilter->load($requestParams)) {
$filter = $this->dataFilter->build();
if ($filter === false) {
$firstError = '';
foreach ($this->dataFilter->getFirstErrors() as $message) {
$firstError = $message;
break;
}
return ['code' => 224003, 'message' => Yii::t('error', Yii::t('error', Yii::t('error', '224003'), ['first_error' => $firstError]))];
}
}
}
if ($this->prepareDataProvider !== null) {
return call_user_func($this->prepareDataProvider, $this, $filter);
}
/* @var $modelClass Plan */
$modelClass = $this->modelClass;
// 任务数量
$statTask = StatTask::find()->select('sum(plan_task_sum) as plan_task_sum');
if (!empty($filter)) {
$statTask->andFilterWhere($filter);
}
$statTask = $statTask->one();
$planTaskCount = $statTask->plan_task_sum;
if(empty($planTaskCount)){
$planTaskInfo = [];
}else{
// 任务信息
$planTaskInfo = StatTask::find()
->select([
StatTask::tableName() . '.name',
'sum('.StatTask::tableName().'.plan_task_sum)'.' as planTaskSum',
])
->groupBy(StatTask::tableName() . '.name')
->orderBy(['planTaskSum' => SORT_DESC]);
if (!empty($filter)) {
$planTaskInfo->andFilterWhere($filter);
}
$planTaskInfo = $planTaskInfo->asArray()->all();
$num = 0;
foreach($planTaskInfo as $key=>$value){
$planTaskInfo[$key]['planTaskSum'] = (int)$value['planTaskSum'];
$proportion = (float)sprintf("%.4f", $planTaskInfo[$key]['planTaskSum']/$planTaskCount);
$planTaskInfo[$key]['proportion'] = $proportion;
if($value == end($planTaskInfo)) {
$planTaskInfo[$key]['proportion'] = 1 - $num;
}else{
$num = $num + $planTaskInfo[$key]['proportion'];
}
}
}
// 设置每页资源数量总数
// $count = 20;
// $requestParams['per-page'] = $count;
return Yii::createObject([
'class' => ArrayDataProvider::className(),
'allModels' => $planTaskInfo,
'pagination' => [
'params' => $requestParams,
],
'sort' => [
'params' => $requestParams,
],
]);
}
}
Opening DB connection: mysql:host=62.234.135.47;dbname=pcs_stat SELECT sum(plan_task_sum) AS `plan_task_sum` FROM `ps_stat_task` WHERE ((`ps_stat_task`.`created_at` >= '1588756760') AND (`ps_stat_task`.`created_at` <= '1589880664')) AND (`ps_stat_task`.`group_id`='015ce30b116ce86058fa6ab4fea4ac63'); SELECT `ps_stat_task`.`name`, sum(`ps_stat_task`.plan_task_sum) AS `planTaskSum` FROM `ps_stat_task` WHERE ((`ps_stat_task`.`created_at` >= '1588756760') AND (`ps_stat_task`.`created_at` <= '1589880664')) AND (`ps_stat_task`.`group_id`='015ce30b116ce86058fa6ab4fea4ac63') GROUP BY `ps_stat_task`.`name` ORDER BY `planTaskSum` DESC;
2、现在计划将此接口迁移至 api.pcs-api.localhost 下,此时,api.pcs-api.localhost 为 RPC 客户端,api.pcs-stat.localhost 为 RPC 服务端。参考:https://www.shuijingwanwq.com/2020/06/23/4273/ 。
3、新建 RPC 服务端文件,rpc/controllers/DataPlanControlTaskController.php
<?php
/**
* Created by PhpStorm.
* User: Qiang Wang
* Date: 2020/09/01
* Time: 10:50
*/
namespace rpc/controllers;
use Yii;
use rpc/models/StatTask;
use yii/base/InvalidConfigException;
/**
* DataPlanControlTask Controller
*
* @author Qiang Wang <shuijingwanwq@163.com>
* @since 1.0
*/
class DataPlanControlTaskController extends ServerController
{
public $dataFilter = [
'class' => 'yii/data/ActiveDataFilter',
'searchModel' => 'rpc/models/StatTaskSearch',
];
/**
* 获取数据大屏的选题管控的任务统计列表
*
* @param array $data 数据
*
* @param string $version 版本号(次版本号与修订号)
* 格式如下:
* 2.3
*
* @param string $language 区域和语言
* 格式如下:
* en-US
*
* @return array
* @throws InvalidConfigException
*/
public function actionIndex(array $data = [], string $version = '', string $language = '')
{
if (!empty($language)) {
Yii::$app->language = $language;
}
$filter = null;
if ($this->dataFilter !== null) {
$this->dataFilter = Yii::createObject($this->dataFilter);
if ($this->dataFilter->load($data)) {
$filter = $this->dataFilter->build();
if ($filter === false) {
$firstError = '';
foreach ($this->dataFilter->getFirstErrors() as $message) {
$firstError = $message;
break;
}
return ['code' => 230003, 'message' => Yii::t('error', Yii::t('error', Yii::t('error', '230003'), ['first_error' => $firstError]))];
}
}
}
/* @var $modelClass StatTask */
$modelClass = $this->modelClass;
// 任务数量
$statTask = $modelClass::find()->select('sum(plan_task_sum) as plan_task_sum');
if (!empty($filter)) {
$statTask->andFilterWhere($filter);
}
$statTask = $statTask->one();
$planTaskCount = $statTask->plan_task_sum;
if (empty($planTaskCount)) {
$planTaskInfo = [];
} else {
// 任务信息
$planTaskInfo = StatTask::find()
->select([
StatTask::tableName() . '.name',
'sum('.StatTask::tableName().'.plan_task_sum)'.' as planTaskSum',
])
->groupBy(StatTask::tableName() . '.name')
->orderBy(['planTaskSum' => SORT_DESC]);
if (!empty($filter)) {
$planTaskInfo->andFilterWhere($filter);
}
$planTaskInfo = $planTaskInfo->asArray()->all();
$num = 0;
foreach ($planTaskInfo as $key => $value) {
$planTaskInfo[$key]['planTaskSum'] = (int) $value['planTaskSum'];
$proportion = (float) sprintf("%.4f", $planTaskInfo[$key]['planTaskSum'] / $planTaskCount);
$planTaskInfo[$key]['proportion'] = $proportion;
if ($value == end($planTaskInfo)) {
$planTaskInfo[$key]['proportion'] = 1 - $num;
} else {
$num = $num + $planTaskInfo[$key]['proportion'];
}
}
}
return ['code' => 10000, 'message' => Yii::t('success', '10000'), 'data' => $planTaskInfo];
}
}
4、新建 RPC 客户端的模型文件,common/logics/rpc/stat/StatTask.php
<?php
namespace common/logics/rpc/stat;
use Yii;
use common/logics/rpc/Model;
/**
* 任务统计
*/
class StatTask extends Model
{
const CONTROLLER_ID = 'data-plan-control-task'; // 控制器ID
/**
* 获取数据大屏的选题管控的任务统计列表
*
* @param array $data 数据
*
* @param string $version 版本号(次版本号与修订号)
* 格式如下:
* 2.3
*
* @param string $language 区域和语言
* 格式如下:
* en-US
*
* @return mixed
* @throws /Exception
*/
public function index(array $data, string $version, string $language)
{
$actionId = 'index';
return self::client(self::CONTROLLER_ID, $actionId)->$actionId($data, $version, $language);
}
}
5、新建 RPC 客户端的方法文件,api/rests/data_plan_control_task/IndexAction.php
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace api/rests/data_plan_control_task;
use Yii;
use api/models/rpc/stat/StatTask;
use yii/data/ActiveDataProvider;
use yii/data/ArrayDataProvider;
use yii/base/InvalidConfigException;
use yii/web/ServerErrorHttpException;
/**
* 获取数据大屏的选题管控的任务统计列表:/data-plan-control-tasks(data-plan-control-task/index)
*
* For more details and usage information on IndexAction, see the [guide article on rest controllers](guide:rest-controllers).
*
*/
class IndexAction extends /yii/rest/IndexAction
{
public $dataFilter = [
'class' => 'yii/data/ActiveDataFilter',
'searchModel' => 'api/models/StatTaskSearch',
];
/**
* Prepares the data provider that should return the requested collection of the models.
* @return array|mixed|object|ActiveDataProvider
* @throws InvalidConfigException
* @throws ServerErrorHttpException
*/
protected function prepareDataProvider()
{
$requestParams = Yii::$app->getRequest()->getQueryParams();
$filter = null;
if ($this->dataFilter !== null) {
$this->dataFilter = Yii::createObject($this->dataFilter);
if ($this->dataFilter->load($requestParams)) {
$filter = $this->dataFilter->build();
if ($filter === false) {
$firstError = '';
foreach ($this->dataFilter->getFirstErrors() as $message) {
$firstError = $message;
break;
}
return ['code' => 224003, 'message' => Yii::t('error', Yii::t('error', Yii::t('error', '224003'), ['first_error' => $firstError]))];
}
}
}
if ($this->prepareDataProvider !== null) {
return call_user_func($this->prepareDataProvider, $this, $filter);
}
/* @var $modelClass StatTask */
$modelClass = $this->modelClass;
// 内容协商
$response = Yii::$app->response;
$acceptParams = $response->acceptParams;
if (isset($acceptParams['version'])) {
$version = $acceptParams['version'];
} else {
$version = '';
}
// 获取数据大屏的选题管控的任务统计列表
$rpcStatStatTask = new $modelClass();
$data = $rpcStatStatTask->index($requestParams, $version, Yii::$app->language);
if ($data['code'] !== 10000) {
throw new ServerErrorHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '202087'), ['code' => $data['code'], 'message' => $data['message']])), 202087);
}
// 设置每页资源数量默认为资源总数
$count = count($data['data']);
if ($count !== 0) {
$requestParams['per-page'] = $count;
}
return Yii::createObject([
'class' => ArrayDataProvider::className(),
'allModels' => $data['data'],
'pagination' => [
'params' => $requestParams,
],
'sort' => [
'params' => $requestParams,
],
]);
}
}
6、分页参数的支持,有待于后续实现。此接口无需要支持分页参数的自定义。GET 请求:http://api.pcs-api.localhost/v1/data-plan-control-tasks?login_id=2e368664c41b8bf511bcc9c65d86dbc3&login_tid=d31652b0f940b810da05d9755d20c7a1&filter[created_at][gte]=1588756760&filter[created_at][lte]=1589880664&filter[group_id]=015ce30b116ce86058fa6ab4fea4ac63 。符合预期。如图2
{
"code": 10000,
"message": "获取数据大屏的选题管控的任务统计列表成功",
"data": {
"items": [
{
"name": "采访任务",
"plan_task_sum": 17,
"proportion": 0.2537
},
{
"name": "互联网发布",
"plan_task_sum": 14,
"proportion": 0.209
},
{
"name": "自定义一",
"plan_task_sum": 13,
"proportion": 0.194
},
{
"name": "手动任务",
"plan_task_sum": 9,
"proportion": 0.1343
},
{
"name": "电视播出",
"plan_task_sum": 8,
"proportion": 0.1194
},
{
"name": "自定义二",
"plan_task_sum": 3,
"proportion": 0.0448
},
{
"name": "自定义八",
"plan_task_sum": 2,
"proportion": 0.0299
},
{
"name": "自定义六",
"plan_task_sum": 1,
"proportion": 0.0149
}
],
"_links": {
"self": {
"href": "http://api.pcs-api.localhost/v1/data-plan-control-tasks?login_id=2e368664c41b8bf511bcc9c65d86dbc3&login_tid=d31652b0f940b810da05d9755d20c7a1&filter%5Bcreated_at%5D%5Bgte%5D=1588756760&filter%5Bcreated_at%5D%5Blte%5D=1589880664&filter%5Bgroup_id%5D=015ce30b116ce86058fa6ab4fea4ac63&page=1&per-page=8"
}
},
"_meta": {
"totalCount": 8,
"pageCount": 1,
"currentPage": 1,
"perPage": 8
}
}
}
7、查看请求日志,本质上是先请求:api.pcs-api.localhost,再请求:rpc.pcs-stat.localhost。如图3
原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/tech/webdev/181568.html
