在 Yii 2.0 中,一键多渠道发布(即在一个接口请求中,批量调用多个接口请求) 的实现
1、在之前的发布界面上,一次发布仅支持一个渠道,因此,3 个渠道的发布需要分别调用 3 次接口(APP、网易号、微博),如图1
2、在现在的发布界面上,准备一次发布可发布至多个渠道上,原型,如图2
3、在渠道发布接口中,每一个渠道的任务(文章)的发布是隔离开的,不支持在一次发布中,发布至多个渠道,如图3
4、现阶段需要支持在一次发布中,发布至多个渠道。渠道发布提供一个一键多渠道发布的接口。有 2 种方案,第 1 种方案:在接口内部通过 HTTP 调用其他渠道的发布接口。第 2 种方案:在接口内部的控制器动作中调用其他控制器动作。因为,一个接口的入口本质是控制器动作。最终决定采纳第 2 种方案。
5、编辑 /api/controllers/TaskGroupController.php,覆盖 afterAction() 方法。在其中运行其他操作ID。
<?php
/**
* Created by PhpStorm.
* User: Qiang Wang
* Date: 2020/03/16
* Time: 14:47
*/
namespace api\controllers;
use Yii;
use yii\base\InvalidConfigException;
use yii\db\Exception;
use yii\rest\ActiveController;
/**
* Class TaskGroupController
* @package api\controllers
*
* @author Qiang Wang <shuijingwanwq@163.com>
* @since 1.0
*/
class TaskGroupController extends ActiveController
{
public $serializer = [
'class' => 'api\rests\task_group\Serializer',
'collectionEnvelope' => 'items',
];
/**
* @inheritdoc
*/
public function actions()
{
$actions = parent::actions();
// 禁用"view"、"update"、"delete"、"options"动作
unset($actions['view'], $actions['update'], $actions['delete'], $actions['options']);
$actions['index']['class'] = 'api\rests\task_group\IndexAction';
$actions['create']['class'] = 'api\rests\task_group\CreateAction';
return $actions;
}
/**
* {@inheritdoc}
* @throws InvalidConfigException if a registered parser does not implement the [[RequestParserInterface]].
* @throws Exception execution failed
*/
public function afterAction($action, $result)
{
if ($action->id == 'create' && $result['code'] === 10000) {
// 返回所有请求参数
$request = Yii::$app->request;
$requestParams = $request->getBodyParams();
// 添加请求参数
$requestParams['task_group']['id'] = $result['data']['id'];
$requestParams['task_group']['uuid'] = $result['data']['uuid'];
$request->setBodyParams($requestParams);
$requestParams = $request->getBodyParams();
// 运行操作ID:index
$this->runAction('index');
}
return parent::afterAction($action, $result);
}
}
6、请求:IndexAction,报错:Method Not Allowed,Method Not Allowed. This URL can only handle the following request methods: GET, HEAD.由此看来,在接口内部的控制器动作中调用其他控制器动作。是会受到请求类型的限制的。而基于安全考虑,暂时不允许放开相应的限制。如图4
{
"name": "Method Not Allowed",
"message": "Method Not Allowed. This URL can only handle the following request methods: GET, HEAD.",
"code": 0,
"status": 405,
"type": "yii\\web\\MethodNotAllowedHttpException"
}
7、而且每一个渠道的发布接口是分布于 qq、wx 等独立的一个个应用中,在 api 应用中是无法运行 qq、wx 等应用下的操作ID的。因此,决定采纳第 1 种方案:在接口内部通过 HTTP 调用其他渠道的发布接口。如图5
8、编辑 /api/controllers/TaskGroupController.php,在 behaviors() 方法中添加过滤器:taskGroupFilter
<?php
/**
* Created by PhpStorm.
* User: Qiang Wang
* Date: 2020/03/16
* Time: 14:47
*/
namespace api\controllers;
use api\filters\TaskGroupFilter;
use yii\rest\ActiveController;
/**
* Class TaskGroupController
* @package api\controllers
*
* @author Qiang Wang <shuijingwanwq@163.com>
* @since 1.0
*/
class TaskGroupController extends ActiveController
{
public $serializer = [
'class' => 'api\rests\task_group\Serializer',
'collectionEnvelope' => 'items',
];
/**
* {@inheritdoc}
*/
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['taskGroupFilter'] = [
'class' => TaskGroupFilter::className(),
'only' => ['create'],
];
return $behaviors;
}
/**
* @inheritdoc
*/
public function actions()
{
$actions = parent::actions();
// 禁用"view"、"update"、"delete"、"options"动作
unset($actions['view'], $actions['update'], $actions['delete'], $actions['options']);
$actions['index']['class'] = 'api\rests\task_group\IndexAction';
$actions['create']['class'] = 'api\rests\task_group\CreateAction';
return $actions;
}
}
9、任务组(即一键多渠道发布)过滤器,新建 /api/filters/TaskGroupFilter.php
<?php
/**
* Created by PhpStorm.
* User: Qiang Wang
* Date: 2020/03/18
* Time: 16:27
*/
namespace api\filters;
use Yii;
use api\services\TaskGroupService;
use yii\base\ActionFilter;
use yii\base\InvalidConfigException;
use yii\httpclient\Exception;
/**
* 任务组(即一键多渠道发布)过滤器
* @package api\filters
*
* @author Qiang Wang <shuijingwanwq@163.com>
* @since 1.0
*/
class TaskGroupFilter extends ActionFilter
{
/**
* {@inheritdoc}
*
* @throws Exception
* @throws InvalidConfigException
*/
public function afterAction($action, $result)
{
if ($result['code'] === 10000) {
// 返回所有请求参数
$request = Yii::$app->request;
$requestParams = $request->getBodyParams();
// 添加请求参数
$requestParams['task_group']['id'] = $result['data']['id'];
$requestParams['task_group']['uuid'] = $result['data']['uuid'];
/* 操作数据(一键发布至多渠道)(同步) */
TaskGroupService::createMultipleSync($requestParams);
}
return parent::afterAction($action, $result);
}
}
10、实现任务组服务类的一键发布至多渠道(同步)方法。暂时仅实现了企鹅号、微信。createMultipleSync($requestParams),编辑 /common/services/TaskGroupService.php
<?php
/**
* Created by PhpStorm.
* User: Qiang Wang
* Date: 2020/03/18
* Time: 10:23
*/
namespace common\services;
use common\logics\ArticleType;
use common\logics\Task;
use common\logics\WxArticle;
use common\logics\WxArticleNews;
use Yii;
use common\logics\Channel;
use common\logics\QqArticleNormal;
use common\logics\http\channel_pub_api\Article as HttpChannelPubApiArticle;
use yii\base\InvalidConfigException;
use yii\httpclient\Exception;
use yii\web\ServerErrorHttpException;
/**
* Class TaskGroupService
* @package common\services
*
* @author Qiang Wang <shuijingwanwq@163.com>
* @since 1.0
*/
class TaskGroupService extends Service
{
/**
* 创建任务组
* @param object $model 对象
*
* @param bool $runValidation 保存记录之前是否执行验证 (调用 [[validate()]]),默认为 true
*
* @return array
* 格式如下:
*
* [
* 'status' => true, // 成功
* 'data' => [ // object
* ]
* ]
*
* [
* 'status' => false, // 失败
* 'code' => 202184, // 返回码
* 'message' => '', // 说明
* ]
*
* @throws ServerErrorHttpException
*/
public function create($model, $runValidation = true)
{
if ($model->save($runValidation)) {
return ['status' => true, 'data' => $model];
} elseif ($model->hasErrors()) {
$firstError = '';
foreach ($model->getFirstErrors() as $message) {
$firstError = $message;
break;
}
return ['status' => false, 'code' => 202184, 'message' => Yii::t('error', Yii::t('error', Yii::t('error', '202184'), ['first_error' => $firstError]))];
} elseif (!$model->hasErrors()) {
throw new ServerErrorHttpException('Failed to create the object (task group) for unknown reason.');
}
}
/**
* 一键发布至多渠道(同步)
*
* @param array $requestParams 请求参数
*
* @throws Exception
* @throws InvalidConfigException
*/
public static function createMultipleSync($requestParams)
{
// 请求数据
$requestDatas = [];
// 判断渠道:企鹅号是否存在,准备对应渠道的数据
if (isset($requestParams[Channel::CODE_QQ])) {
foreach ($requestParams[Channel::CODE_QQ] as $key => $value) {
$value['source'] = $requestParams['task_group']['source'];
$value['source_uuid'] = $requestParams['task_group']['source_uuid'];
$value['source_pub_user_id'] = $requestParams['task_group']['source_pub_user_id'];
$value['source_callback_url'] = $requestParams['task_group']['source_callback_url'];
$value['task_group_id'] = $requestParams['task_group']['id'];
$value['task_group_uuid'] = $requestParams['task_group']['uuid'];
$value['cover_pics'] = $value['covers'] ?? [];
$value['apply'] = $value['original'] ?? QqArticleNormal::APPLY_DEFAULT;
unset($value['covers'], $value['original']);
$requestDatas[] = [
'url' => 'qq/v1/articles/standard',
'data' => $value,
];
}
}
// 判断渠道:微信公众帐号是否存在,准备对应渠道的数据
if (isset($requestParams[Channel::CODE_WX])) {
foreach ($requestParams[Channel::CODE_WX] as $key => $value) {
$value['app_ids'] = $value['channel_app_source_uuids'] ?? [];
$value['source'] = $requestParams['task_group']['source'];
$value['source_uuid'] = $requestParams['task_group']['source_uuid'];
$value['source_pub_user_id'] = $requestParams['task_group']['source_pub_user_id'];
$value['source_callback_url'] = $requestParams['task_group']['source_callback_url'];
$value['task_group_id'] = $requestParams['task_group']['id'];
$value['task_group_uuid'] = $requestParams['task_group']['uuid'];
$value['thumb'] = $value['covers'][0] ?? '';
$value['show_cover_pic'] = $value['cover_show'] ?? WxArticleNews::SHOW_COVER_PIC_DEFAULT;
$value['url'] = $value['source_url'] ?? '';
unset($value['covers'], $value['cover_show'], $value['source_url']);
$value['code'] = ArticleType::CODE_STANDARD;
$value['type'] = Task::TYPE_PUB;
$value['wx_send_type'] = WxArticle::WX_SEND_TYPE_MASS;
$requestDatas[] = [
'url' => 'wx/v1/wx-articles/article',
'data' => $value,
];
}
}
// 批量发布文章类型:标准(普通、图文)的文章
$httpChannelPubApiArticle = new HttpChannelPubApiArticle();
$httpChannelPubApiArticle->batchPostArticlesStandard(Yii::$app->params['groupId'], $requestDatas);
}
}
11、实现 HTTP 模型类,渠道发布接口的基础类。新建 /common/logics/http/channel_pub_api/Model.php
<?php
/**
* Created by PhpStorm.
* User: Qiang Wang
* Date: 2020/03/20
* Time: 13:56
*/
namespace common\logics\http\channel_pub_api;
use Yii;
use yii\httpclient\Client;
use yii\httpclient\CurlTransport;
use yii\web\ServerErrorHttpException;
/**
* 渠道发布接口的基础类
*
* @author Qiang Wang <shuijingwanwq@163.com>
* @since 1.0
*/
class Model extends \yii\base\Model
{
private $_httpClient;
/*
* 创建 HTTP 客户端对象
*
* @return object the created object
* @throws InvalidConfigException if a registered parser does not implement the [[RequestParserInterface]].
*/
public function getHttpClient()
{
if (!is_object($this->_httpClient)) {
$this->_httpClient = Yii::createObject([
'class' => Client::className(),
'baseUrl' => Yii::$app->params['channelPubApi']['hostInfo'] . Yii::$app->params['channelPubApi']['baseUrl'],
'requestConfig' => [
'format' => Client::FORMAT_JSON
],
'transport' => CurlTransport::className(),
]);
}
return $this->_httpClient;
}
/*
* 响应对象的处理
*
* @param object $response 响应对象
*
* @return array|bool
*
* 格式如下:
*
* 渠道发布接口的响应信息
* [
* 'message' => '', //说明
* 'data' => [], //数据
* ]
*
* 失败(将错误保存在 [[yii\base\Model::errors]] 属性中)
* false
*
* @throws ServerErrorHttpException 如果响应状态码不等于20x
*/
public function responseHandler($response)
{
// 检查响应状态码是否等于20x
$responseCode = $response->data['code'] ?? 0; // 返回码
if ($response->isOk) {
// 检查业务逻辑是否成功
if ($responseCode === 10000) {
return ['message' => $response->data['message'], 'data' => $response->data['data']];
} else {
$this->addError('id', Yii::t('error', Yii::t('error', Yii::t('error', '202186'), ['code' => $responseCode, 'message' => $response->data['message']])));
return !$this->hasErrors();
}
} else {
$responseMessage = $response->data['message'] ?? ''; // 说明
throw new ServerErrorHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '202185'), ['status_code' => $response->statusCode, 'code' => $responseCode, 'message' => $responseMessage])), 202185);
}
}
}
12、实现 HTTP 模型类,渠道发布接口的文章。批量发布文章类型:标准(普通、图文)的文章。新建 /common/logics/http/channel_pub_api/Article.php
<?php
/**
* Created by PhpStorm.
* User: Qiang Wang
* Date: 2020/03/20
* Time: 14:19
*/
namespace common\logics\http\channel_pub_api;
use Yii;
use yii\base\InvalidConfigException;
use yii\httpclient\Client;
use yii\httpclient\Exception;
/**
* 渠道发布接口的文章
*
* @author Qiang Wang <shuijingwanwq@163.com>
* @since 1.0
*/
class Article extends Model
{
/**
* 批量发布文章类型:标准(普通、图文)的文章
*
* @param string $groupId 租户ID
* @param array $requestDatas 请求数据
*
* @throws Exception
* @throws InvalidConfigException
*/
public function batchPostArticlesStandard($groupId, $requestDatas)
{
$client = new Client();
$requests = [];
foreach ($requestDatas as $requestData) {
$requests[] = $this->httpClient->createRequest()
->setMethod('post')
->setUrl($requestData['url'] . '?group_id=' . $groupId)
->setData($requestData['data']);
}
$client->batchSend($requests);
}
}
13、POST 请求:http://api.channel-pub-api.localhost/v1/task-groups?group_id=015ce30b116ce86058fa6ab4fea4ac63 。创建任务组(即一键多渠道发布)。成功响应。如图6
{
"source": {
"channel_app_source_uuids": [
"55f62c8c67fc11ea809554ee75d2ebc1",
"36cf694a67fc11eaa79d54ee75d2ebc1",
"29473624681311eaab8e54ee75d2ebc1"
],
"title": "北京小汤山医院启用,设千张床位",
"content": "3月16日晚拍摄的北京小汤山医院局部(无人机照片)。记者从北京市疫情防控领导小组获悉,为做好境外输入人员疫情防控工作,3月16日起,启用北京小汤山医院。医院设床位1000余张,将主要用于境外来(返)京人员中需筛查人员、疑似病例及轻型、普通型确诊患者的筛查和治疗。",
"source": "spider",
"source_uuid": "825e6d5e36468cc4bf536799ce3565cf",
"source_pub_user_id": 1,
"source_callback_url": "http://scms.wjdev.chinamcloud.cn/api/thirdPush/callBack",
"task_group_source_article_id": 1,
"baijia_source_article_id": 2,
"baijia_author": "鞠焕宗",
"baijia_covers": [
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRG00AN0001NOS.jpg",
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRH00AN0001NOS.jpg",
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRI00AN0001NOS.jpg"
],
"baijia_original": 0,
"baijia_original_url": "http://news.163.com/photoview/00AN0001/2307424.html",
"netease_source_article_id": 3,
"netease_author": "鞠焕宗",
"netease_article_category_id": 417,
"netease_covers": [
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRG00AN0001NOS.jpg",
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRH00AN0001NOS.jpg",
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRI00AN0001NOS.jpg"
],
"netease_cover_type": "threeImg",
"netease_original": 0,
"qq_source_article_id": 4,
"qq_author": "鞠焕宗",
"qq_article_category_id": 24,
"qq_tag": "北京,疫情,防控,境外,输入,小汤山,医院",
"qq_covers": [
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRG00AN0001NOS.jpg",
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRH00AN0001NOS.jpg",
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRI00AN0001NOS.jpg"
],
"qq_cover_type": 3,
"qq_original": 0,
"qq_original_platform": 0,
"qq_original_url": "",
"qq_original_author": "",
"weibo_source_article_id": 5,
"weibo_summary": "记者从北京市疫情防控领导小组获悉,为做好境外输入人员疫情防控工作,3月16日起,启用北京小汤山医院。医院设床位1000余张,将主要用于境外来(返)京人员中需筛查人员、疑似病例及轻型、普通型确诊患者的筛查和治疗。",
"weibo_link_content": "记者从北京市疫情防控领导小组获悉,为做好境外输入人员疫情防控工作,3月16日起,启用北京小汤山医院。医院设床位1000余张,将主要用于境外来(返)京人员中需筛查人员、疑似病例及轻型、普通型确诊患者的筛查和治疗。",
"weibo_covers": [
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRG00AN0001NOS.jpg"
],
"wx_source_article_id": 6,
"wx_author": "鞠焕宗",
"wx_covers": [
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRG00AN0001NOS.jpg"
],
"wx_cover_show": 1,
"wx_description": "记者从北京市疫情防控领导小组获悉,为做好境外输入人员疫情防控工作,3月16日起,启用北京小汤山医院。医院设床位1000余张,将主要用于境外来(返)京人员中需筛查人员、疑似病例及轻型、普通型确诊患者的筛查和治疗。",
"wx_source_url": "http://news.163.com/photoview/00AN0001/2307424.html",
"toutiao_source_article_id": 7,
"toutiao_source_url": "http://news.163.com/photoview/00AN0001/2307424.html"
},
"task_group": {
"source": "spider",
"source_uuid": "825e6d5e36468cc4bf536799ce3565cf",
"source_pub_user_id": 1,
"source_callback_url": "http://scms.wjdev.chinamcloud.cn/api/thirdPush/callBack",
"source_article_id": 1
},
"baijia": [
{
"channel_app_source_uuids": [
"29473624681311eaab8e54ee75d2ebc1"
],
"title": "北京小汤山医院启用,设千张床位",
"content": "3月16日晚拍摄的北京小汤山医院局部(无人机照片)。记者从北京市疫情防控领导小组获悉,为做好境外输入人员疫情防控工作,3月16日起,启用北京小汤山医院。医院设床位1000余张,将主要用于境外来(返)京人员中需筛查人员、疑似病例及轻型、普通型确诊患者的筛查和治疗。",
"source_article_id": 2,
"author": "鞠焕宗",
"covers": [
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRG00AN0001NOS.jpg",
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRH00AN0001NOS.jpg",
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRI00AN0001NOS.jpg"
],
"original": 0,
"original_url": "http://news.163.com/photoview/00AN0001/2307424.html"
}
],
"netease": [
{
"channel_app_source_uuids": [
"29473624681311eaab8e54ee75d2ebc1"
],
"title": "北京小汤山医院启用,设千张床位",
"content": "3月16日晚拍摄的北京小汤山医院局部(无人机照片)。记者从北京市疫情防控领导小组获悉,为做好境外输入人员疫情防控工作,3月16日起,启用北京小汤山医院。医院设床位1000余张,将主要用于境外来(返)京人员中需筛查人员、疑似病例及轻型、普通型确诊患者的筛查和治疗。",
"source_article_id": 3,
"author": "鞠焕宗",
"article_category_id": 417,
"covers": [
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRG00AN0001NOS.jpg",
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRH00AN0001NOS.jpg",
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRI00AN0001NOS.jpg"
],
"cover_type": "threeImg",
"original": 0
}
],
"qq": [
{
"channel_app_source_uuids": [
"55f62c8c67fc11ea809554ee75d2ebc1"
],
"title": "北京小汤山医院启用,设千张床位",
"content": "3月16日晚拍摄的北京小汤山医院局部(无人机照片)。记者从北京市疫情防控领导小组获悉,为做好境外输入人员疫情防控工作,3月16日起,启用北京小汤山医院。医院设床位1000余张,将主要用于境外来(返)京人员中需筛查人员、疑似病例及轻型、普通型确诊患者的筛查和治疗。",
"source_article_id": 4,
"author": "鞠焕宗",
"article_category_id": 24,
"tag": "北京,疫情,防控,境外,输入,小汤山,医院",
"covers": [
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRG00AN0001NOS.jpg",
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRH00AN0001NOS.jpg",
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRI00AN0001NOS.jpg"
],
"cover_type": 3,
"original": 0,
"original_platform": 0,
"original_url": "",
"original_author": ""
},
{
"channel_app_source_uuids": [
"36cf694a67fc11eaa79d54ee75d2ebc1"
],
"title": "北京小汤山医院启用,设千张床位",
"content": "3月16日晚拍摄的北京小汤山医院局部(无人机照片)。记者从北京市疫情防控领导小组获悉,为做好境外输入人员疫情防控工作,3月16日起,启用北京小汤山医院。医院设床位1000余张,将主要用于境外来(返)京人员中需筛查人员、疑似病例及轻型、普通型确诊患者的筛查和治疗。",
"source_article_id": 4,
"author": "鞠焕宗",
"article_category_id": 24,
"tag": "北京,疫情,防控,境外,输入,小汤山,医院",
"covers": [
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRJ00AN0001NOS.jpg",
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRH00AN0001NOS.jpg",
"http://pic-bucket.ws.126.net/photo/0001/2020-03-17/F7TNMMRI00AN0001NOS.jpg"
],
"cover_type": 3,
"original": 0,
"original_platform": 0,
"original_url": "",
"original_author": ""
}
],
"weibo": [
{
"channel_app_source_uuids": [
"渠道的应用的来源ID(UUID)"
],
"title": "北京小汤山医院启用,设千张床位",
"content": "内容",
"source_article_id": "来源文章ID",
"summary": "导语",
"link_content": "链接内容",
"covers": [
"封面图"
]
}
],
"wx": [
{
"channel_app_source_uuids": [
"渠道的应用的来源ID(UUID)"
],
"title": "北京小汤山医院启用,设千张床位",
"content": "内容",
"source_article_id": "来源文章ID",
"author": "作者",
"covers": [
"封面图"
],
"cover_show": "封面图是否显示",
"description": "描述",
"source_url": "来源链接"
}
],
"toutiao": [
{
"channel_app_source_uuids": [
"渠道的应用的来源ID(UUID)"
],
"title": "北京小汤山医院启用,设千张床位",
"content": "内容",
"source_article_id": "来源文章ID",
"source_url": "来源链接"
}
]
}
{
"code": 10000,
"message": "已发布文章至渠道发布,待发布至多渠道,请稍候",
"data": {
"source_article_id": 1,
"is_deleted": 0,
"deleted_at": 0,
"status": 1,
"created_at": 1584758252,
"updated_at": 1584758252,
"uuid": "eba334aa6b1c11ea8d7154ee75d2ebc1",
"id": 63
}
}
14、查看 api 应用的 Log Messages,分别请求了 2 次 企鹅号与 1 次 微信。如图7
15、查看 qq 应用的 Log Messages,分别请求了 2 次 企鹅号。如图8
16、查看 wx 应用的 Log Messages,分别请求了 1 次 微信。图9
17、查看 MySQl 表中的数据,分别写入了 2 次 企鹅号与 1 次 微信。符合预期。其他渠道按照相类似的规则皆可以如此处理。如图10










近期评论