任务的入库成功、入库失败,皆需要能够查询到发布记录的设计与实现(在 Yii 2.0 中具体实现) (一)
1、获取企鹅号的应用的任务列表,列表为空,如图1
2、发布文章类型:标准(普通、图文)的文章,发布成功(即入库成功),查看发布任务的 SQL 语句,如图2
1 2 3 4 5 6 7 8 9 10 11 12 13 | Begin transaction INSERT INTO `cpa_task` (`group_id`, `source`, `source_uuid`, `source_pub_user_id`, `source_callback_url`, `channel_id`, `channel_code`, `channel_type_id`, `channel_type_code`, `status`, `created_at`, `updated_at`) VALUES ( '015ce30b116ce86058fa6ab4fea4ac63' , 'spider' , '825e6d5e36468cc4bf536799ce3565cf' , '3' , 'http://scms.wjdev.chinamcloud.cn/api/thirdPush/callBack' , 1, 'qq' , 1, 'qq_cw' , 1, 1577686722, 1577686722) INSERT INTO `cpa_channel_app_task` (`channel_id`, `channel_code`, `channel_type_id`, `channel_type_code`, `channel_app_source_id`, `channel_app_source_uuid`, `task_id`, `have_pub_number`, `status`, `created_at`, `updated_at`, `uuid`) VALUES (1, 'qq' , 1, 'qq_cw' , 14, '8d72b7cc2ac911eab85a54ee75d2ebc1' , 1, 3, 1, 1577686722, 1577686722, '3a1d31262acc11ea9f5754ee75d2ebc1' ) INSERT INTO `cpa_qq_cw_app_task` (`channel_app_task_id`, `channel_app_task_uuid`, `qq_cw_app_id`, `task_id`, `platform_status`, `status`, `created_at`, `updated_at`) VALUES (1, '3a1d31262acc11ea9f5754ee75d2ebc1' , 2, 1, 0, 1, 1577686722, 1577686722) INSERT INTO `cpa_qq_article` (`group_id`, `article_category_id`, `title`, `author`, `source_article_id`, `qq_app_type`, `article_type_id`, `qq_article_type_id`, `qq_article_category_id`, `task_id`, `status`, `created_at`, `updated_at`) VALUES ( '015ce30b116ce86058fa6ab4fea4ac63' , 15, '2019 年 22 款最佳软件开发工具' , 'Guru99' , 1, 'cw' , 1, 1, 18, 1, 1, 1577686722, 1577686722) INSERT INTO `cpa_qq_article_normal` (`content`, `cover_pic`, `cover_type`, `tag`, `apply`, `original_platform`, `original_url`, `original_author`, `qq_article_id`, `category`, `status`, `created_at`, `updated_at`) VALUES ( '市面上有海量的软件开发工具,因此,选择最佳软件开发工具可能是一项挑战。本文是 22 款顶级软件开发工具的精选列表。' , 'https://static001.infoq.cn/resource/image/90/6a/9054bf66f3ce4d0a4822a1b7398c566a.png' , 1, '2019,22,最佳,软件,开发工具' , 0, 0, '' , '' , 1, 18, 1, 1577686722, 1577686722) Commit transaction |
3、获取企鹅号的应用的任务列表,列表中存在 1 条记录,查看获取企鹅号的应用的任务列表的 SQL 语句,如图3
1 | SELECT `cpa_channel_app_task`.*, `cpa_task`.`group_id`, `cpa_task`.`source`, `cpa_task`.`source_uuid`, `cpa_task`.`source_pub_user_id`, `cpa_qq_cw_app`.`penguin_name`, `cpa_channel_app_task`.`status`, `cpa_article_type`.`code` AS `article_type_code`, `cpa_article_type`.` name ` AS `article_type_name`, `cpa_qq_article`.`article_category_id`, `cpa_qq_article`.`title` AS `article_title`, `cpa_qq_article`.`author` AS `article_author`, `cpa_qq_article`.`source_article_id`, `cpa_qq_transaction`.`article_url`, `cpa_pub_log`.`code` AS `pub_log_code`, `cpa_pub_log`.`message` AS `pub_log_message` FROM `cpa_channel_app_task` LEFT JOIN `cpa_task` ON `cpa_channel_app_task`.`task_id` = `cpa_task`.`id` LEFT JOIN `cpa_qq_article` ON `cpa_task`.`id` = `cpa_qq_article`.`task_id` LEFT JOIN `cpa_article_type` ON `cpa_qq_article`.`article_type_id` = `cpa_article_type`.`id` LEFT JOIN `cpa_qq_cw_app_task` ON `cpa_channel_app_task`.`id` = `cpa_qq_cw_app_task`.`channel_app_task_id` LEFT JOIN `cpa_qq_cw_app` ON `cpa_qq_cw_app_task`.`qq_cw_app_id` = `cpa_qq_cw_app`.`id` LEFT JOIN `cpa_pub_log` ON `cpa_channel_app_task`.`id` = `cpa_pub_log`.`channel_app_task_id` LEFT JOIN `cpa_qq_transaction` ON `cpa_qq_cw_app_task`.`id` = `cpa_qq_transaction`.`qq_app_task_id` AND `cpa_qq_transaction`.`type` = '1' WHERE ((`cpa_channel_app_task`.`is_deleted`=0) AND (`cpa_task`.`is_deleted`=0) AND (`cpa_qq_article`.`is_deleted`=0) AND (`cpa_article_type`.`is_deleted`=0) AND (`cpa_qq_cw_app_task`.`is_deleted`=0) AND (`cpa_qq_cw_app`.`is_deleted`=0)) AND (`cpa_task`.`group_id`= '015ce30b116ce86058fa6ab4fea4ac63' ) ORDER BY `cpa_task`.`id` DESC LIMIT 20 |
4、发布文章类型:标准(普通、图文)的文章,发布失败(即未入库,因为数据验证失败),由步骤 2 可知,即使数据验证成功(),5 条插入 SQL 语句在 1 个事务中,只要其中任意 1 条 SQL 执行失败,便会回滚,入库失败。如图4
5、获取企鹅号的应用的任务列表,列表中存在 1 条记录。但是,客户端希望能够获取到 2 条记录,因为,从客户端的用户方面来看待此问题,实际上是已经发布过 2 次任务,而不是 1 次。现阶段的实现方案有 2 种,第 1 种是渠道发布本身维持现有的业务逻辑不变化,发布任务的记录在客户端数据库中冗余再存储;第 2 种方案是渠道发布任务的入库成功、入库失败,皆需要能够查询到发布记录,客户端不做处理,仅直接获取渠道发布的任务列表。最终决定采用第 2 种方案,原因在于任务记录仅存在一个数据源,有利于保证唯一性与简单性,避免多个数据源导致的冗余度与复杂性。如图5
6、如何来实现即使入库失败,也能够查询到发布记录呢?前提是必须要保证请求的数据入库成功,但是理论上是无法实现的。比如说:请求数据中的标题长度超出表:cpa_qq_article 的字段:title 的长度,即使在执行插入 SQL 之前不做数据验证,SQL 语句也会执行失败,进而回滚。如图6
1 2 3 4 5 6 7 8 9 | /** * {@inheritdoc} */ public function rules() { return [ [[ 'title' ], 'string' , 'max' => 255], // 删除掉,不做数据验证 ]; } |
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 | { "name": "Database Exception", "message": "SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'title' at row 1\nThe SQL being executed was: INSERT INTO `cpa_qq_article` (`group_id`, `article_category_id`, `title`, `author`, `source_article_id`, `qq_app_type`, `article_type_id`, `qq_article_type_id`, `qq_article_category_id`, `task_id`, `status`, `created_at`, `updated_at`) VALUES ('015ce30b116ce86058fa6ab4fea4ac63', 15, '未来 10 年,“星光中国芯工程”计划投资 100 亿元用于芯片研发及大规模产业化。北京时间 2019 年 12 月 28 日,1999-2019“星光中国芯工程”创新成果与展望报告会在人民大会堂举行。会议回顾和总结了“星光中国芯工程”20 年来在核心技术自主创新、在研发成果大规模产业化、以及在满足国家重大工程技术需求方面取得的重要进展和成功经验,并对“星光中国芯工程”未来发展进行了规划和展望。中国工程院院士、“星光中国芯工程”总指挥、中星微电子集团创建人兼首席科学家邓中翰作了“星光中国芯工程”20 年成果与展望工作报告,报告中,邓中翰表示,在物理层面智能芯片的发展已经受到了物理规律的限制,看似已经接近了极限的时候,在信息层面的技术创新还远远没有碰到天花板。1999 年,邓中翰等一批海外爱国博士企业家回国承担并启动实施“星光中国芯工程”,在北京中关村设立中星微电子公司,致力于超大规模集成电路芯片的研发、设计及产业化工作。2001 年,中国第一颗百万门级超大规模数字多媒体芯片“星光一号”诞生。其后数年间,“星光多媒体”系列芯片被苹果、三星、飞利浦、惠普、LG、索尼、戴尔等国外知名品牌规模采用,占领了全球计算机图像输入芯片 60% 以上的市场份额,彻底结束了中国无“芯”的历史。', '刘燕', 1, 'cw', 1, 1, 18, 4, 1, 1577692119, 1577692119)", "code": 22001, "type": "yii\\db\\Exception", "file": "E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\db\\Schema.php", "line": 674, "stack-trace": [ "#0 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\db\\Command.php(1295): yii\\db\\Schema->convertException(Object(PDOException), 'INSERT INTO `cp...')", "#1 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\db\\Command.php(1091): yii\\db\\Command->internalExecute('INSERT INTO `cp...')", "#2 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\db\\Schema.php(432): yii\\db\\Command->execute()", "#3 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\db\\ActiveRecord.php(600): yii\\db\\Schema->insert('{{%qq_article}}', Array)", "#4 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\db\\ActiveRecord.php(566): yii\\db\\ActiveRecord->insertInternal(NULL)", "#5 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\db\\BaseActiveRecord.php(678): yii\\db\\ActiveRecord->insert(false, NULL)", "#6 E:\\wwwroot\\channel-pub-api\\common\\services\\QqArticleService.php(88): yii\\db\\BaseActiveRecord->save(false)", "#7 E:\\wwwroot\\channel-pub-api\\qq\\services\\QqArticleService.php(182): common\\services\\QqArticleService->create(Object(qq\\modules\\v1\\models\\QqArticle), false)", "#8 E:\\wwwroot\\channel-pub-api\\qq\\rests\\article\\StandardCreateAction.php(342): qq\\services\\QqArticleService->standardCreate(Object(common\\logics\\Channel), Object(common\\logics\\ChannelType), Array, Array, Object(common\\logics\\ArticleType), Object(common\\logics\\QqArticleType), Object(common\\logics\\QqArticleCategoryNormal), Object(qq\\models\\Task), Object(qq\\modules\\v1\\models\\QqArticle), Object(qq\\models\\QqArticleNormal))", "#9 [internal function]: qq\\rests\\article\\StandardCreateAction->run()", "#10 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\base\\Action.php(94): call_user_func_array(Array, Array)", "#11 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\base\\Controller.php(157): yii\\base\\Action->runWithParams(Array)", "#12 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\base\\Module.php(528): yii\\base\\Controller->runAction('standard-create', Array)", "#13 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\web\\Application.php(103): yii\\base\\Module->runAction('v1/article/stan...', Array)", "#14 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\base\\Application.php(386): yii\\web\\Application->handleRequest(Object(yii\\web\\Request))", "#15 E:\\wwwroot\\channel-pub-api\\qq\\web\\index.php(17): yii\\base\\Application->run()", "#16 {main}" ], "error-info": [ "22001", 1406, "Data too long for column 'title' at row 1" ], "previous": { "name": "Exception", "message": "SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'title' at row 1", "code": "22001", "type": "PDOException", "file": "E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\db\\Command.php", "line": 1290, "stack-trace": [ "#0 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\db\\Command.php(1290): PDOStatement->execute()", "#1 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\db\\Command.php(1091): yii\\db\\Command->internalExecute('INSERT INTO `cp...')", "#2 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\db\\Schema.php(432): yii\\db\\Command->execute()", "#3 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\db\\ActiveRecord.php(600): yii\\db\\Schema->insert('{{%qq_article}}', Array)", "#4 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\db\\ActiveRecord.php(566): yii\\db\\ActiveRecord->insertInternal(NULL)", "#5 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\db\\BaseActiveRecord.php(678): yii\\db\\ActiveRecord->insert(false, NULL)", "#6 E:\\wwwroot\\channel-pub-api\\common\\services\\QqArticleService.php(88): yii\\db\\BaseActiveRecord->save(false)", "#7 E:\\wwwroot\\channel-pub-api\\qq\\services\\QqArticleService.php(182): common\\services\\QqArticleService->create(Object(qq\\modules\\v1\\models\\QqArticle), false)", "#8 E:\\wwwroot\\channel-pub-api\\qq\\rests\\article\\StandardCreateAction.php(342): qq\\services\\QqArticleService->standardCreate(Object(common\\logics\\Channel), Object(common\\logics\\ChannelType), Array, Array, Object(common\\logics\\ArticleType), Object(common\\logics\\QqArticleType), Object(common\\logics\\QqArticleCategoryNormal), Object(qq\\models\\Task), Object(qq\\modules\\v1\\models\\QqArticle), Object(qq\\models\\QqArticleNormal))", "#9 [internal function]: qq\\rests\\article\\StandardCreateAction->run()", "#10 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\base\\Action.php(94): call_user_func_array(Array, Array)", "#11 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\base\\Controller.php(157): yii\\base\\Action->runWithParams(Array)", "#12 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\base\\Module.php(528): yii\\base\\Controller->runAction('standard-create', Array)", "#13 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\web\\Application.php(103): yii\\base\\Module->runAction('v1/article/stan...', Array)", "#14 E:\\wwwroot\\channel-pub-api\\vendor\\yiisoft\\yii2\\base\\Application.php(386): yii\\web\\Application->handleRequest(Object(yii\\web\\Request))", "#15 E:\\wwwroot\\channel-pub-api\\qq\\web\\index.php(17): yii\\base\\Application->run()", "#16 {main}" ] } } |
1 2 3 4 5 6 7 8 9 10 11 | Begin transaction INSERT INTO `cpa_task` (`group_id`, `source`, `source_uuid`, `source_pub_user_id`, `source_callback_url`, `channel_id`, `channel_code`, `channel_type_id`, `channel_type_code`, `status`, `created_at`, `updated_at`) VALUES ( '015ce30b116ce86058fa6ab4fea4ac63' , 'spider' , '825e6d5e36468cc4bf536799ce3565cf' , '3' , 'http://scms.wjdev.chinamcloud.cn/api/thirdPush/callBack' , 1, 'qq' , 1, 'qq_cw' , 1, 1577692119, 1577692119) INSERT INTO `cpa_channel_app_task` (`channel_id`, `channel_code`, `channel_type_id`, `channel_type_code`, `channel_app_source_id`, `channel_app_source_uuid`, `task_id`, `have_pub_number`, `status`, `created_at`, `updated_at`, `uuid`) VALUES (1, 'qq' , 1, 'qq_cw' , 14, '8d72b7cc2ac911eab85a54ee75d2ebc1' , 4, 3, 1, 1577692119, 1577692119, 'caf880d62ad811ea88f654ee75d2ebc1' ) INSERT INTO `cpa_qq_cw_app_task` (`channel_app_task_id`, `channel_app_task_uuid`, `qq_cw_app_id`, `task_id`, `platform_status`, `status`, `created_at`, `updated_at`) VALUES (4, 'caf880d62ad811ea88f654ee75d2ebc1' , 2, 4, 0, 1, 1577692119, 1577692119) INSERT INTO `cpa_qq_article` (`group_id`, `article_category_id`, `title`, `author`, `source_article_id`, `qq_app_type`, `article_type_id`, `qq_article_type_id`, `qq_article_category_id`, `task_id`, `status`, `created_at`, `updated_at`) VALUES ( '015ce30b116ce86058fa6ab4fea4ac63' , 15, '未来 10 年,“星光中国芯工程”计划投资 100 亿元用于芯片研发及大规模产业化。北京时间 2019 年 12 月 28 日,1999-2019“星光中国芯工程”创新成果与展望报告会在人民大会堂举行。会议回顾和总结了“星光中国芯工程”20 年来在核心技术自主创新、在研发成果大规模产业化、以及在满足国家重大工程技术需求方面取得的重要进展和成功经验,并对“星光中国芯工程”未来发展进行了规划和展望。中国工程院院士、“星光中国芯工程”总指挥、中星微电子集团创建人兼首席科学家邓中翰作了“星光中国芯工程”20 年成果与展望工作报告,报告中,邓中翰表示,在物理层面智能芯片的发展已经受到了物理规律的限制,看似已经接近了极限的时候,在信息层面的技术创新还远远没有碰到天花板。1999 年,邓中翰等一批海外爱国博士企业家回国承担并启动实施“星光中国芯工程”,在北京中关村设立中星微电子公司,致力于超大规模集成电路芯片的研发、设计及产业化工作。2001 年,中国第一颗百万门级超大规模数字多媒体芯片“星光一号”诞生。其后数年间,“星光多媒体”系列芯片被苹果、三星、飞利浦、惠普、LG、索尼、戴尔等国外知名品牌规模采用,占领了全球计算机图像输入芯片 60% 以上的市场份额,彻底结束了中国无“芯”的历史。' , '刘燕' , 1, 'cw' , 1, 1, 18, 4, 1, 1577692119, 1577692119) Roll back transaction |
7、实施新的数据库迁移,新建表:预发布日志(pre_pub_log),最终的表结构,表中的字段类型与任务表中的字段类型保持一致,但是字符串类型的字段,加大其长度,尽可能提升其入库成功率,基于接口动作方法的返回码,当返回码不等于 10000 时,插入记录,如图7
8、实现预发布日志服务,创建预发布日志,尽最大可能避免抛出异常,一旦抛出异常,则无法插入记录至预发布日志。common/services/PrePubLogService.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 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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | <?php /** * Created by PhpStorm. * User: Qiang Wang * Date: 2020/01/03 * Time: 17:51 */ namespace common\services; use Yii; use common\logics\ArticleType; use common\logics\Channel; use common\logics\ChannelAppSource; use common\logics\PrePubLog; use common\behaviors\UUIDBehavior; use yii\db\Exception; use yii\helpers\ArrayHelper; class PrePubLogService extends Service { /** * 批量创建预发布日志 * @param string $groupId 租户ID * 格式如下:015ce30b116ce86058fa6ab4fea4ac63 * * @param int $code 返回码 * 格式如下:226004 * * @param string $message 说明 * 格式如下:数据验证失败:文章封面图不能为空。 * * @param string $channelCode 渠道代码 * 格式如下:qq * * @param string $type 任务类型,preview:预览;pub:发布;revoke:撤回 * 格式如下:pub * * @param string $articleTypeCode 文章类型代码 * 格式如下:standard * * @param array $requestParams 请求参数 * 格式如下: * [ * 'channel_app_source_uuids' => [ * '18cf06d22ac911eaa31854ee75d2ebc0', * '8d72b7cc2ac911eab85a54ee75d2ebc1', * ], * 'source' => 'spider', * 'source_uuid' => '825e6d5e36468cc4bf536799ce3565cf', * 'source_pub_user_id' => 3, * 'source_callback_url' => 'http://scms.wjdev.chinamcloud.cn/api/thirdPush/callBack', * 'article_category_id' => 15, * 'title' => '未来 10 年,“星光中国芯工程”计划投资 100 亿元用于芯片研发及大规模产业化', * 'author' => '刘燕', * 'source_article_id' => 1, * ... * ] * * @return int number of rows affected by the execution. * @throws Exception execution failed */ public function createMultiple( $groupId , $code , $message , $channelCode , $type , $articleTypeCode , $requestParams ) { // 基于代码查找单个资源(渠道) $channelItem = Channel::findOneByCode( $channelCode ); if (isset( $channelItem )) { $channelId = $channelItem ->id; } else { $channelId = 0; } // 基于代码查找单个资源(文章类型) $articleTypeItem = ArticleType::findOneByCode( $articleTypeCode ); if (isset( $articleTypeItem )) { $articleTypeId = $articleTypeItem ->id; $articleTypeName = $articleTypeItem ->name; } else { $articleTypeId = 0; $articleTypeName = '' ; } // 渠道的应用的来源ID(UUID) $channelAppSourceUuids = $requestParams [ 'channel_app_source_uuids' ] ?? []; // 渠道的应用的来源ID(UUID) if (! is_array ( $channelAppSourceUuids )) { $channelAppSourceUuids = [ $channelAppSourceUuids ]; } $time = time(); // 公共字段列表 $prePubLogCommonFields = [ 'group_id' => $groupId , 'channel_id' => $channelId , 'channel_code' => $channelCode , 'type' => $type , 'article_type_id' => $articleTypeId , 'article_type_code' => $articleTypeCode , 'article_type_name' => $articleTypeName , 'article_category_id' => $requestParams [ 'article_category_id' ] ?? 0, 'article_title' => $requestParams [ 'title' ] ?? '' , 'article_author' => $requestParams [ 'author' ] ?? '' , 'source' => $requestParams [ 'source' ] ?? '' , 'source_uuid' => $requestParams [ 'source_uuid' ] ?? '' , 'source_pub_user_id' => $requestParams [ 'source_pub_user_id' ] ?? 0, 'source_callback_url' => $requestParams [ 'source_callback_url' ] ?? '' , 'source_article_id' => $requestParams [ 'source_article_id' ] ?? '' , 'pub_log_code' => $code , 'pub_log_message' => $message , 'pub_log_body' => serialize( $requestParams ), 'status' => PrePubLog::STATUS_PUBLISH_ERROR, 'is_deleted' => PrePubLog::IS_DELETED_NO, 'created_at' => $time , 'updated_at' => $time , 'deleted_at' => PrePubLog::DELETED_AT_DEFAULT, ]; foreach ( $channelAppSourceUuids as $channelAppSourceUuid ) { $uuidBehavior = new UUIDBehavior(); $uuid = $uuidBehavior ->createUUID(); // 预发布日志ID(UUID) // 基于UUID查找单个资源 $channelAppSourceItem = ChannelAppSource::findOneByUuid( $channelAppSourceUuid ); if (isset( $channelAppSourceItem )) { $prePubLogRows [] = ArrayHelper::merge( $prePubLogCommonFields , [ 'uuid' => $uuid , 'channel_type_id' => $channelAppSourceItem ->channel_type_id, 'channel_type_code' => $channelAppSourceItem ->channel_type_code, 'channel_app_source_id' => $channelAppSourceItem ->id, 'channel_app_source_uuid' => $channelAppSourceItem ->uuid, ]); } else { $prePubLogRows [] = ArrayHelper::merge( $prePubLogCommonFields , [ 'uuid' => $uuid , 'channel_type_id' => 0, 'channel_type_code' => '' , 'channel_app_source_id' => 0, 'channel_app_source_uuid' => $channelAppSourceUuid , ]); } } /* 创建MySQL模型(预发布日志) */ $prePubLogTable = PrePubLog::tableName(); if (isset( $prePubLogRows )) { $prePubLogColumns = array_keys ( $prePubLogRows [0]); return Yii:: $app ->db->createCommand()->batchInsert( $prePubLogTable , $prePubLogColumns , $prePubLogRows )->execute(); } return 0; } } |
9、创建预发布日志过滤器:qq/filters/PrePubLogFilter.php,继承 yii\base\ActionFilter 类并覆盖 afterAction() 方法来创建动作的过滤器,在动作执行之后执行。判断返回码,如果不等于 10000,则操作数据(批量创建预发布日志)。
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 | <?php /** * Created by PhpStorm. * User: Qiang Wang * Date: 2019/12/31 * Time: 17:25 */ namespace qq\filters; use Yii; use qq\models\ArticleType; use qq\models\Channel; use qq\models\Task; use qq\services\PrePubLogService; use yii\base\ActionFilter; use yii\base\InvalidConfigException; use yii\db\Exception; /** * 预发布日志过滤器 * @package qq\filters * * @author Qiang Wang <shuijingwanwq@163.com> * @since 1.0 */ class PrePubLogFilter extends ActionFilter { /** * {@inheritdoc} * @throws InvalidConfigException if a registered parser does not implement the [[RequestParserInterface]]. * @throws Exception execution failed */ public function afterAction( $action , $result ) { if ( $result [ 'code' ] !== 10000) { $groupId = Yii:: $app ->params[ 'groupId' ]; // 租户ID $channelCode = Channel::CODE_QQ; // 渠道代码 $type = Task::TYPE_PUB; // 任务类型,preview:预览;pub:发布;revoke:撤回 $articleTypeCode = ArticleType::CODE_STANDARD; // 文章类型代码 if ( $action ->id == 'video-create' ) { $articleTypeCode = ArticleType::CODE_VIDEO; } elseif ( $action ->id == 'images-create' ) { $articleTypeCode = ArticleType::CODE_IMAGES; } // 返回所有请求参数 $requestParams = Yii:: $app ->getRequest()->getBodyParams(); /* 操作数据(批量创建预发布日志) */ $prePubLogService = new PrePubLogService(); $prePubLogService ->createMultiple( $groupId , $result [ 'code' ], $result [ 'message' ], $channelCode , $type , $articleTypeCode , $requestParams ); } return parent::afterAction( $action , $result ); } } |
10、使用过滤器,过滤器本质上是一类特殊的行为, 所以使用过滤器和使用行为一样。 可以在控制器类中覆盖它的 behaviors() 方法来声明过滤器,编辑控制器:qq/controllers/ArticleController.php,配置 only 属性明确指定控制器应用到哪些动作。
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 | <?php /** * Created by PhpStorm. * User: Qiang Wang * Date: 2018/08/31 * Time: 10:43 */ namespace qq\controllers; use qq\filters\PrePubLogFilter; use yii\rest\ActiveController; /** * Class ArticleController * @package qq\controllers * * @author Qiang Wang <shuijingwanwq@163.com> * @since 1.0 */ class ArticleController extends ActiveController { public $serializer = [ 'class' => 'qq\rests\article\Serializer' , 'collectionEnvelope' => 'items' , ]; /** * {@inheritdoc} */ public function behaviors() { $behaviors = parent::behaviors(); $behaviors [ 'prePubLogFilter' ] = [ 'class' => PrePubLogFilter::className(), 'only' => [ 'standard-create' , 'video-create' , 'images-create' ], ]; return $behaviors ; } /** * @inheritdoc */ public function actions() { $actions = parent::actions(); // 禁用"create"、"update"、"delete"、"options"动作 unset( $actions [ 'create' ], $actions [ 'update' ], $actions [ 'delete' ], $actions [ 'options' ]); $actions [ 'index' ][ 'class' ] = 'qq\rests\article\IndexAction' ; $actions [ 'view' ][ 'class' ] = 'qq\rests\article\ViewAction' ; $actions [ 'standard-create' ] = [ 'class' => 'qq\rests\article\StandardCreateAction' , 'modelClass' => $this ->modelClass, 'checkAccess' => [ $this , 'checkAccess' ], ]; $actions [ 'video-create' ] = [ 'class' => 'qq\rests\article\VideoCreateAction' , 'modelClass' => $this ->modelClass, 'checkAccess' => [ $this , 'checkAccess' ], ]; $actions [ 'images-create' ] = [ 'class' => 'qq\rests\article\ImagesCreateAction' , 'modelClass' => $this ->modelClass, 'checkAccess' => [ $this , 'checkAccess' ], ]; return $actions ; } } |
11、发布文章类型:标准(普通、图文)的文章,发布失败(即未入库,因为数据验证失败),此时,当返回码不等于 10000 时,插入 2 条记录(预发布日志),因为有 2 个帐号,查看 SQL
1 2 3 4 | { "code": 226004, "message": "数据验证失败:标题只能包含至多255个字符。" } |
1 | INSERT INTO `cpa_pre_pub_log` (`group_id`, `channel_id`, `channel_code`, `type`, `article_type_id`, `article_type_code`, `article_type_name`, `article_category_id`, `article_title`, `article_author`, `source`, `source_uuid`, `source_pub_user_id`, `source_callback_url`, `source_article_id`, `pub_log_code`, `pub_log_message`, `pub_log_body`, `status`, `is_deleted`, `created_at`, `updated_at`, `deleted_at`, `uuid`, `channel_type_id`, `channel_type_code`, `channel_app_source_id`, `channel_app_source_uuid`) VALUES ('015ce30b116ce86058fa6ab4fea4ac63', 1, 'qq', 'pub', 1, 'standard', '标准(普通)', 15, '未来 10 年,“星光中国芯工程”计划投资 100 亿元用于芯片研发及大规模产业化。北京时间 2019 年 12 月 28 日,1999-2019“星光中国芯工程”创新成果与展望报告会在人民大会堂举行。会议回顾和总结了“星光中国芯工程”20 年来在核心技术自主创新、在研发成果大规模产业化、以及在满足国家重大工程技术需求方面取得的重要进展和成功经验,并对“星光中国芯工程”未来发展进行了规划和展望。中国工程院院士、“星光中国芯工程”总指挥、中星微电子集团创建人兼首席科学家邓中翰作了“星光中国芯工程”20 年成果与展望工作报告,报告中,邓中翰表示,在物理层面智能芯片的发展已经受到了物理规律的限制,看似已经接近了极限的时候,在信息层面的技术创新还远远没有碰到天花板。1999 年,邓中翰等一批海外爱国博士企业家回国承担并启动实施“星光中国芯工程”,在北京中关村设立中星微电子公司,致力于超大规模集成电路芯片的研发、设计及产业化工作。2001 年,中国第一颗百万门级超大规模数字多媒体芯片“星光一号”诞生。其后数年间,“星光多媒体”系列芯片被苹果、三星、飞利浦、惠普、LG、索尼、戴尔等国外知名品牌规模采用,占领了全球计算机图像输入芯片 60% 以上的市场份额,彻底结束了中国无“芯”的历史。', '高琳', 'spider', '825e6d5e36468cc4bf536799ce3565cf', 3, 'http://scms.wjdev.chinamcloud.cn/api/thirdPush/callBack', 1, 226004, '数据验证失败:标题只能包含至多255个字符。', 'a:17:{s:24:\"channel_app_source_uuids\";a:2:{i:0;s:32:\"8d72b7cc2ac911eab85a54ee75d2ebc1\";i:1;s:32:\"18cf06d22ac911eaa31854ee75d2ebc1\";}s:6:\"source\";s:6:\"spider\";s:11:\"source_uuid\";s:32:\"825e6d5e36468cc4bf536799ce3565cf\";s:18:\"source_pub_user_id\";i:3;s:19:\"source_callback_url\";s:55:\"http://scms.wjdev.chinamcloud.cn/api/thirdPush/callBack\";s:19:\"article_category_id\";i:15;s:5:\"title\";s:1525:\"未来 10 年,“星光中国芯工程”计划投资 100 亿元用于芯片研发及大规模产业化。北京时间 2019 年 12 月 28 日,1999-2019“星光中国芯工程”创新成果与展望报告会在人民大会堂举行。会议回顾和总结了“星光中国芯工程”20 年来在核心技术自主创新、在研发成果大规模产业化、以及在满足国家重大工程技术需求方面取得的重要进展和成功经验,并对“星光中国芯工程”未来发展进行了规划和展望。中国工程院院士、“星光中国芯工程”总指挥、中星微电子集团创建人兼首席科学家邓中翰作了“星光中国芯工程”20 年成果与展望工作报告,报告中,邓中翰表示,在物理层面智能芯片的发展已经受到了物理规律的限制,看似已经接近了极限的时候,在信息层面的技术创新还远远没有碰到天花板。1999 年,邓中翰等一批海外爱国博士企业家回国承担并启动实施“星光中国芯工程”,在北京中关村设立中星微电子公司,致力于超大规模集成电路芯片的研发、设计及产业化工作。2001 年,中国第一颗百万门级超大规模数字多媒体芯片“星光一号”诞生。其后数年间,“星光多媒体”系列芯片被苹果、三星、飞利浦、惠普、LG、索尼、戴尔等国外知名品牌规模采用,占领了全球计算机图像输入芯片 60% 以上的市场份额,彻底结束了中国无“芯”的历史。\";s:6:\"author\";s:6:\"高琳\";s:17:\"source_article_id\";i:1;s:7:\"content\";s:1525:\"未来 10 年,“星光中国芯工程”计划投资 100 亿元用于芯片研发及大规模产业化。北京时间 2019 年 12 月 28 日,1999-2019“星光中国芯工程”创新成果与展望报告会在人民大会堂举行。会议回顾和总结了“星光中国芯工程”20 年来在核心技术自主创新、在研发成果大规模产业化、以及在满足国家重大工程技术需求方面取得的重要进展和成功经验,并对“星光中国芯工程”未来发展进行了规划和展望。中国工程院院士、“星光中国芯工程”总指挥、中星微电子集团创建人兼首席科学家邓中翰作了“星光中国芯工程”20 年成果与展望工作报告,报告中,邓中翰表示,在物理层面智能芯片的发展已经受到了物理规律的限制,看似已经接近了极限的时候,在信息层面的技术创新还远远没有碰到天花板。1999 年,邓中翰等一批海外爱国博士企业家回国承担并启动实施“星光中国芯工程”,在北京中关村设立中星微电子公司,致力于超大规模集成电路芯片的研发、设计及产业化工作。2001 年,中国第一颗百万门级超大规模数字多媒体芯片“星光一号”诞生。其后数年间,“星光多媒体”系列芯片被苹果、三星、飞利浦、惠普、LG、索尼、戴尔等国外知名品牌规模采用,占领了全球计算机图像输入芯片 60% 以上的市场份额,彻底结束了中国无“芯”的历史。\";s:10:\"cover_pics\";a:1:{i:0;s:84:\"https://static001.infoq.cn/resource/image/7c/18/7c55c468adf1d616f48681c23e9b9518.png\";}s:10:\"cover_type\";i:1;s:3:\"tag\";s:62:\"百度,发布,推理引擎,Paddle Lite,华为,NPU,在线编译\";s:5:\"apply\";i:0;s:17:\"original_platform\";i:0;s:12:\"original_url\";s:0:\"\";s:15:\"original_author\";s:0:\"\";}', 3, 0, 1578361765, 1578361765, 0, 'effddba230ef11ea991a54ee75d2ebc1', 1, 'qq_cw', 14, '8d72b7cc2ac911eab85a54ee75d2ebc1'), ('015ce30b116ce86058fa6ab4fea4ac63', 1, 'qq', 'pub', 1, 'standard', '标准(普通)', 15, '未来 10 年,“星光中国芯工程”计划投资 100 亿元用于芯片研发及大规模产业化。北京时间 2019 年 12 月 28 日,1999-2019“星光中国芯工程”创新成果与展望报告会在人民大会堂举行。会议回顾和总结了“星光中国芯工程”20 年来在核心技术自主创新、在研发成果大规模产业化、以及在满足国家重大工程技术需求方面取得的重要进展和成功经验,并对“星光中国芯工程”未来发展进行了规划和展望。中国工程院院士、“星光中国芯工程”总指挥、中星微电子集团创建人兼首席科学家邓中翰作了“星光中国芯工程”20 年成果与展望工作报告,报告中,邓中翰表示,在物理层面智能芯片的发展已经受到了物理规律的限制,看似已经接近了极限的时候,在信息层面的技术创新还远远没有碰到天花板。1999 年,邓中翰等一批海外爱国博士企业家回国承担并启动实施“星光中国芯工程”,在北京中关村设立中星微电子公司,致力于超大规模集成电路芯片的研发、设计及产业化工作。2001 年,中国第一颗百万门级超大规模数字多媒体芯片“星光一号”诞生。其后数年间,“星光多媒体”系列芯片被苹果、三星、飞利浦、惠普、LG、索尼、戴尔等国外知名品牌规模采用,占领了全球计算机图像输入芯片 60% 以上的市场份额,彻底结束了中国无“芯”的历史。', '高琳', 'spider', '825e6d5e36468cc4bf536799ce3565cf', 3, 'http://scms.wjdev.chinamcloud.cn/api/thirdPush/callBack', 1, 226004, '数据验证失败:标题只能包含至多255个字符。', 'a:17:{s:24:\"channel_app_source_uuids\";a:2:{i:0;s:32:\"8d72b7cc2ac911eab85a54ee75d2ebc1\";i:1;s:32:\"18cf06d22ac911eaa31854ee75d2ebc1\";}s:6:\"source\";s:6:\"spider\";s:11:\"source_uuid\";s:32:\"825e6d5e36468cc4bf536799ce3565cf\";s:18:\"source_pub_user_id\";i:3;s:19:\"source_callback_url\";s:55:\"http://scms.wjdev.chinamcloud.cn/api/thirdPush/callBack\";s:19:\"article_category_id\";i:15;s:5:\"title\";s:1525:\"未来 10 年,“星光中国芯工程”计划投资 100 亿元用于芯片研发及大规模产业化。北京时间 2019 年 12 月 28 日,1999-2019“星光中国芯工程”创新成果与展望报告会在人民大会堂举行。会议回顾和总结了“星光中国芯工程”20 年来在核心技术自主创新、在研发成果大规模产业化、以及在满足国家重大工程技术需求方面取得的重要进展和成功经验,并对“星光中国芯工程”未来发展进行了规划和展望。中国工程院院士、“星光中国芯工程”总指挥、中星微电子集团创建人兼首席科学家邓中翰作了“星光中国芯工程”20 年成果与展望工作报告,报告中,邓中翰表示,在物理层面智能芯片的发展已经受到了物理规律的限制,看似已经接近了极限的时候,在信息层面的技术创新还远远没有碰到天花板。1999 年,邓中翰等一批海外爱国博士企业家回国承担并启动实施“星光中国芯工程”,在北京中关村设立中星微电子公司,致力于超大规模集成电路芯片的研发、设计及产业化工作。2001 年,中国第一颗百万门级超大规模数字多媒体芯片“星光一号”诞生。其后数年间,“星光多媒体”系列芯片被苹果、三星、飞利浦、惠普、LG、索尼、戴尔等国外知名品牌规模采用,占领了全球计算机图像输入芯片 60% 以上的市场份额,彻底结束了中国无“芯”的历史。\";s:6:\"author\";s:6:\"高琳\";s:17:\"source_article_id\";i:1;s:7:\"content\";s:1525:\"未来 10 年,“星光中国芯工程”计划投资 100 亿元用于芯片研发及大规模产业化。北京时间 2019 年 12 月 28 日,1999-2019“星光中国芯工程”创新成果与展望报告会在人民大会堂举行。会议回顾和总结了“星光中国芯工程”20 年来在核心技术自主创新、在研发成果大规模产业化、以及在满足国家重大工程技术需求方面取得的重要进展和成功经验,并对“星光中国芯工程”未来发展进行了规划和展望。中国工程院院士、“星光中国芯工程”总指挥、中星微电子集团创建人兼首席科学家邓中翰作了“星光中国芯工程”20 年成果与展望工作报告,报告中,邓中翰表示,在物理层面智能芯片的发展已经受到了物理规律的限制,看似已经接近了极限的时候,在信息层面的技术创新还远远没有碰到天花板。1999 年,邓中翰等一批海外爱国博士企业家回国承担并启动实施“星光中国芯工程”,在北京中关村设立中星微电子公司,致力于超大规模集成电路芯片的研发、设计及产业化工作。2001 年,中国第一颗百万门级超大规模数字多媒体芯片“星光一号”诞生。其后数年间,“星光多媒体”系列芯片被苹果、三星、飞利浦、惠普、LG、索尼、戴尔等国外知名品牌规模采用,占领了全球计算机图像输入芯片 60% 以上的市场份额,彻底结束了中国无“芯”的历史。\";s:10:\"cover_pics\";a:1:{i:0;s:84:\"https://static001.infoq.cn/resource/image/7c/18/7c55c468adf1d616f48681c23e9b9518.png\";}s:10:\"cover_type\";i:1;s:3:\"tag\";s:62:\"百度,发布,推理引擎,Paddle Lite,华为,NPU,在线编译\";s:5:\"apply\";i:0;s:17:\"original_platform\";i:0;s:12:\"original_url\";s:0:\"\";s:15:\"original_author\";s:0:\"\";}', 3, 0, 1578361765, 1578361765, 0, 'effe253a30ef11eaa2e454ee75d2ebc1', 1, 'qq_cw', 13, '18cf06d22ac911eaa31854ee75d2ebc1') |
12、查看 预发布日志 表,存在 2 条记录,符合预期,如图8
13、获取企鹅号的应用的任务列表,调整查询规则,基于 UNION ALL 语法,合并 预发布日志 的结果到一个结果集中。编辑 qq/rests/qq_app_task/IndexAction.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 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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | <?php /** * @link http://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC * @license http://www.yiiframework.com/license/ */ namespace qq\rests\qq_app_task; use Yii; use qq\models\ArticleType; use qq\models\ChannelAppTask; use qq\models\PrePubLog; use qq\models\PubLog; use qq\models\QqArticle; use qq\models\QqCwApp; use qq\models\QqCwAppTask; use qq\models\QqTransaction; use qq\models\Task; use yii\data\ActiveDataProvider; use yii\db\Expression; use yii\db\Query; use yii\base\InvalidConfigException; use yii\web\UnprocessableEntityHttpException; /** * 获取企鹅号的应用的任务列表:/qq-app-tasks(qq-app-task/index) * * For more details and usage information on IndexAction, see the [guide article on rest controllers](guide:rest-controllers). * * @author Qiang Wang <shuijingwanwq@163.com> * @since 1.0 */ class IndexAction extends \yii\rest\IndexAction { public $dataFilter = [ 'class' => 'yii\data\ActiveDataFilter' , 'searchModel' => 'qq\models\QqAppTaskSearch' , 'attributeMap' => [ 'group_id' => '{{%task}}.[[group_id]]' , 'channel_type_code' => '{{%channel_app_task}}.[[channel_type_code]]' , 'source' => '{{%task}}.[[source]]' , 'source_uuid' => '{{%task}}.[[source_uuid]]' , 'source_pub_user_id' => '{{%task}}.[[source_pub_user_id]]' , 'channel_app_source_uuid' => '{{%channel_app_task}}.[[channel_app_source_uuid]]' , 'penguin_name' => '{{%qq_cw_app}}.[[penguin_name]]' , 'status' => '{{%channel_app_task}}.[[status]]' , 'article_type_code' => '{{%article_type}}.[[code]]' , 'article_category_id' => '{{%qq_article}}.[[article_category_id]]' , 'article_title' => '{{%qq_article}}.[[title]]' , 'article_author' => '{{%qq_article}}.[[author]]' , 'source_article_id' => '{{%qq_article}}.[[source_article_id]]' , 'created_at' => '{{%channel_app_task}}.[[created_at]]' , ], ]; public $prePubLogDataFilter = [ 'class' => 'yii\data\ActiveDataFilter' , 'searchModel' => 'qq\models\QqAppTaskSearch' , 'attributeMap' => [ 'group_id' => '{{%pre_pub_log}}.[[group_id]]' , 'channel_type_code' => '{{%pre_pub_log}}.[[channel_type_code]]' , 'source' => '{{%pre_pub_log}}.[[source]]' , 'source_uuid' => '{{%pre_pub_log}}.[[source_uuid]]' , 'source_pub_user_id' => '{{%pre_pub_log}}.[[source_pub_user_id]]' , 'channel_app_source_uuid' => '{{%pre_pub_log}}.[[channel_app_source_uuid]]' , 'penguin_name' => '{{%qq_cw_app}}.[[penguin_name]]' , 'status' => '{{%pre_pub_log}}.[[status]]' , 'article_type_code' => '{{%pre_pub_log}}.[[article_type_code]]' , 'article_category_id' => '{{%pre_pub_log}}.[[article_category_id]]' , 'article_title' => '{{%pre_pub_log}}.[[article_title]]' , 'article_author' => '{{%pre_pub_log}}.[[article_author]]' , 'source_article_id' => '{{%pre_pub_log}}.[[source_article_id]]' , 'created_at' => '{{%pre_pub_log}}.[[created_at]]' , ], ]; /** * Prepares the data provider that should return the requested collection of the models. * @return ActiveDataProvider * @throws InvalidConfigException if the configuration is invalid. * @throws UnprocessableEntityHttpException */ protected function prepareDataProvider() { $requestParams = Yii:: $app ->getRequest()->getBodyParams(); if ( empty ( $requestParams )) { $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 ; } throw new UnprocessableEntityHttpException(Yii::t( 'error' , Yii::t( 'error' , Yii::t( 'error' , '224003' ), [ 'first_error' => $firstError ])), 224003); } } } $prePubLogFilter = null; if ( $this ->prePubLogDataFilter !== null) { $this ->prePubLogDataFilter = Yii::createObject( $this ->prePubLogDataFilter); if ( $this ->prePubLogDataFilter->load( $requestParams )) { $prePubLogFilter = $this ->prePubLogDataFilter->build(); if ( $prePubLogFilter === false) { $firstError = '' ; foreach ( $this ->prePubLogDataFilter->getFirstErrors() as $message ) { $firstError = $message ; break ; } throw new UnprocessableEntityHttpException(Yii::t( 'error' , Yii::t( 'error' , Yii::t( 'error' , '224003' ), [ 'first_error' => $firstError ])), 224003); } } } if ( $this ->prepareDataProvider !== null) { return call_user_func( $this ->prepareDataProvider, $this , $filter ); } /* @var $modelClass ChannelAppTask */ $modelClass = $this ->modelClass; $channelAppTaskQuery = $modelClass ::find() ->select([ new Expression( "'channel_app_task'" . " AS 'model'" ), ChannelAppTask::tableName() . '.id' , Task::tableName() . '.group_id' , ChannelAppTask::tableName() . '.uuid' , ChannelAppTask::tableName() . '.channel_id' , ChannelAppTask::tableName() . '.channel_code' , ChannelAppTask::tableName() . '.channel_type_id' , ChannelAppTask::tableName() . '.channel_type_code' , ChannelAppTask::tableName() . '.channel_app_source_id' , ChannelAppTask::tableName() . '.channel_app_source_uuid' , Task::tableName() . '.type' , 'article_type_id' => ArticleType::tableName() . '.id' , 'article_type_code' => ArticleType::tableName() . '.code' , 'article_type_name' => ArticleType::tableName() . '.name' , QqArticle::tableName() . '.article_category_id' , 'article_title' => QqArticle::tableName() . '.title' , 'article_author' => QqArticle::tableName() . '.author' , Task::tableName() . '.source' , Task::tableName() . '.source_uuid' , Task::tableName() . '.source_pub_user_id' , Task::tableName() . '.source_callback_url' , QqArticle::tableName() . '.source_article_id' , 'pub_log_code' => PubLog::tableName() . '.code' , 'pub_log_message' => PubLog::tableName() . '.message' , ChannelAppTask::tableName() . '.status' , ChannelAppTask::tableName() . '.is_deleted' , ChannelAppTask::tableName() . '.created_at' , ChannelAppTask::tableName() . '.updated_at' , ChannelAppTask::tableName() . '.deleted_at' , ChannelAppTask::tableName() . '.task_id' , ChannelAppTask::tableName() . '.have_pub_number' , QqCwApp::tableName() . '.penguin_name' , QqTransaction::tableName() . '.article_url' , ]) ->joinWith([ 'task.qqArticle.articleType' ], false) ->joinWith([ 'qqCwAppTask.qqCwApp' ], false) ->joinWith([ 'qqCwAppTask' ], false) ->leftJoin(QqTransaction::tableName(), QqCwAppTask::tableName() . '.[[id]] = ' . QqTransaction::tableName() . '.[[qq_app_task_id]] AND ' . QqTransaction::tableName() . '.[[type]] = \'' . QqTransaction::TYPE_ARTICLE . '\'' ) ->joinWith([ 'pubLog' ], false) ->where([ ChannelAppTask::tableName() . '.is_deleted' => ChannelAppTask::IS_DELETED_NO, Task::tableName() . '.is_deleted' => Task::IS_DELETED_NO, QqArticle::tableName() . '.is_deleted' => QqArticle::IS_DELETED_NO, ArticleType::tableName() . '.is_deleted' => ArticleType::IS_DELETED_NO, QqCwAppTask::tableName() . '.is_deleted' => QqCwAppTask::IS_DELETED_NO, QqCwApp::tableName() . '.is_deleted' => QqCwApp::IS_DELETED_NO, ]); if (! empty ( $filter )) { $channelAppTaskQuery ->andFilterWhere( $filter ); } $prePubLogQuery = PrePubLog::find() ->select([ new Expression( "'pre_pub_log'" . " AS 'model'" ), PrePubLog::tableName() . '.id' , PrePubLog::tableName() . '.group_id' , PrePubLog::tableName() . '.uuid' , PrePubLog::tableName() . '.channel_id' , PrePubLog::tableName() . '.channel_code' , PrePubLog::tableName() . '.channel_type_id' , PrePubLog::tableName() . '.channel_type_code' , PrePubLog::tableName() . '.channel_app_source_id' , PrePubLog::tableName() . '.channel_app_source_uuid' , PrePubLog::tableName() . '.type' , PrePubLog::tableName() . '.article_type_id' , PrePubLog::tableName() . '.article_type_code' , PrePubLog::tableName() . '.article_type_name' , PrePubLog::tableName() . '.article_category_id' , PrePubLog::tableName() . '.article_title' , PrePubLog::tableName() . '.article_author' , PrePubLog::tableName() . '.source' , PrePubLog::tableName() . '.source_uuid' , PrePubLog::tableName() . '.source_pub_user_id' , PrePubLog::tableName() . '.source_callback_url' , PrePubLog::tableName() . '.source_article_id' , PrePubLog::tableName() . '.pub_log_code' , PrePubLog::tableName() . '.pub_log_message' , PrePubLog::tableName() . '.status' , PrePubLog::tableName() . '.is_deleted' , PrePubLog::tableName() . '.created_at' , PrePubLog::tableName() . '.updated_at' , PrePubLog::tableName() . '.deleted_at' , new Expression(0 . " AS 'task_id'" ), new Expression(ChannelAppTask::HAVE_PUB_NUMBER_DEFAULT . " AS 'have_pub_number'" ), QqCwApp::tableName() . '.penguin_name' , new Expression( "''" . " AS 'article_url'" ), ]) ->joinWith([ 'qqCwApp' ], false) ->where([ PrePubLog::tableName() . '.is_deleted' => ChannelAppTask::IS_DELETED_NO, QqCwApp::tableName() . '.is_deleted' => QqCwApp::IS_DELETED_NO, ]); if (! empty ( $prePubLogFilter )) { $prePubLogQuery ->andFilterWhere( $prePubLogFilter ); } $query = ( new Query()) ->from([ 'model' => $channelAppTaskQuery ->union( $prePubLogQuery , true)]) ->orderBy([ 'created_at' => SORT_DESC, 'id' => SORT_DESC]); return Yii::createObject([ 'class' => ActiveDataProvider::className(), 'query' => $query , 'pagination' => [ 'params' => $requestParams , ], 'sort' => [ 'params' => $requestParams , ], ]); } } |
14、获取企鹅号的应用的任务列表,列表中存在 2 条记录,查看获取企鹅号的应用的任务列表的请求参数、响应参数、 SQL 语句,符合预期,如图9
1 2 3 4 | group_id:015ce30b116ce86058fa6ab4fea4ac63 filter[group_id]:015ce30b116ce86058fa6ab4fea4ac63 filter[channel_type_code]:qq_cw filter[penguin_name][like]:华栖云秀 |
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 77 78 79 80 81 82 83 84 85 86 87 88 89 | { "code": 10000, "message": "获取企鹅号的应用的任务列表成功", "data": { "items": [ { "model": "pre_pub_log", "id": 4, "group_id": "015ce30b116ce86058fa6ab4fea4ac63", "uuid": "effddba230ef11ea991a54ee75d2ebc1", "channel_id": 1, "channel_code": "qq", "channel_type_id": 1, "channel_type_code": "qq_cw", "channel_app_source_id": 14, "channel_app_source_uuid": "8d72b7cc2ac911eab85a54ee75d2ebc1", "type": "pub", "article_type_id": "1", "article_type_code": "standard", "article_type_name": "标准(普通)", "article_category_id": 15, "article_title": "未来 10 年,“星光中国芯工程”计划投资 100 亿元用于芯片研发及大规模产业化。北京时间 2019 年 12 月 28 日,1999-2019“星光中国芯工程”创新成果与展望报告会在人民大会堂举行。会议回顾和总结了“星光中国芯工程”20 年来在核心技术自主创新、在研发成果大规模产业化、以及在满足国家重大工程技术需求方面取得的重要进展和成功经验,并对“星光中国芯工程”未来发展进行了规划和展望。中国工程院院士、“星光中国芯工程”总指挥、中星微电子集团创建人兼首席科学家邓中翰作了“星光中国芯工程”20 年成果与展望工作报告,报告中,邓中翰表示,在物理层面智能芯片的发展已经受到了物理规律的限制,看似已经接近了极限的时候,在信息层面的技术创新还远远没有碰到天花板。1999 年,邓中翰等一批海外爱国博士企业家回国承担并启动实施“星光中国芯工程”,在北京中关村设立中星微电子公司,致力于超大规模集成电路芯片的研发、设计及产业化工作。2001 年,中国第一颗百万门级超大规模数字多媒体芯片“星光一号”诞生。其后数年间,“星光多媒体”系列芯片被苹果、三星、飞利浦、惠普、LG、索尼、戴尔等国外知名品牌规模采用,占领了全球计算机图像输入芯片 60% 以上的市场份额,彻底结束了中国无“芯”的历史。", "article_author": "高琳", "source": "spider", "source_uuid": "825e6d5e36468cc4bf536799ce3565cf", "source_pub_user_id": 3, "source_callback_url": "http://scms.wjdev.chinamcloud.cn/api/thirdPush/callBack", "source_article_id": 1, "pub_log_code": "226004", "pub_log_message": "数据验证失败:标题只能包含至多255个字符。", "status": 3, "is_deleted": 0, "created_at": 1578361765, "updated_at": 1578361765, "deleted_at": 0, "task_id": 0, "have_pub_number": "3", "penguin_name": "华栖云秀", "article_url": "" }, { "model": "channel_app_task", "id": 1, "group_id": "015ce30b116ce86058fa6ab4fea4ac63", "uuid": "3a1d31262acc11ea9f5754ee75d2ebc1", "channel_id": 1, "channel_code": "qq", "channel_type_id": 1, "channel_type_code": "qq_cw", "channel_app_source_id": 14, "channel_app_source_uuid": "8d72b7cc2ac911eab85a54ee75d2ebc1", "type": "pub", "article_type_id": "1", "article_type_code": "standard", "article_type_name": "标准(普通)", "article_category_id": 15, "article_title": "2019 年 22 款最佳软件开发工具", "article_author": "Guru99", "source": "spider", "source_uuid": "825e6d5e36468cc4bf536799ce3565cf", "source_pub_user_id": 3, "source_callback_url": "http://scms.wjdev.chinamcloud.cn/api/thirdPush/callBack", "source_article_id": 1, "pub_log_code": "", "pub_log_message": "", "status": 4, "is_deleted": 0, "created_at": 1577686722, "updated_at": 1577690249, "deleted_at": 0, "task_id": 1, "have_pub_number": "3", "penguin_name": "华栖云秀", "article_url": "" } ], "_links": { "self": { } }, "_meta": { "totalCount": 2, "pageCount": 1, "currentPage": 1, "perPage": 20 } } } |
1 | SELECT * FROM ((SELECT 'channel_app_task' AS 'model', `cpa_channel_app_task`.`id`, `cpa_task`.`group_id`, `cpa_channel_app_task`.`uuid`, `cpa_channel_app_task`.`channel_id`, `cpa_channel_app_task`.`channel_code`, `cpa_channel_app_task`.`channel_type_id`, `cpa_channel_app_task`.`channel_type_code`, `cpa_channel_app_task`.`channel_app_source_id`, `cpa_channel_app_task`.`channel_app_source_uuid`, `cpa_task`.`type`, `cpa_article_type`.`id` AS `article_type_id`, `cpa_article_type`.`code` AS `article_type_code`, `cpa_article_type`.`name` AS `article_type_name`, `cpa_qq_article`.`article_category_id`, `cpa_qq_article`.`title` AS `article_title`, `cpa_qq_article`.`author` AS `article_author`, `cpa_task`.`source`, `cpa_task`.`source_uuid`, `cpa_task`.`source_pub_user_id`, `cpa_task`.`source_callback_url`, `cpa_qq_article`.`source_article_id`, `cpa_pub_log`.`code` AS `pub_log_code`, `cpa_pub_log`.`message` AS `pub_log_message`, `cpa_channel_app_task`.`status`, `cpa_channel_app_task`.`is_deleted`, `cpa_channel_app_task`.`created_at`, `cpa_channel_app_task`.`updated_at`, `cpa_channel_app_task`.`deleted_at`, `cpa_channel_app_task`.`task_id`, `cpa_channel_app_task`.`have_pub_number`, `cpa_qq_cw_app`.`penguin_name`, `cpa_qq_transaction`.`article_url` FROM `cpa_channel_app_task` LEFT JOIN `cpa_task` ON `cpa_channel_app_task`.`task_id` = `cpa_task`.`id` LEFT JOIN `cpa_qq_article` ON `cpa_task`.`id` = `cpa_qq_article`.`task_id` LEFT JOIN `cpa_article_type` ON `cpa_qq_article`.`article_type_id` = `cpa_article_type`.`id` LEFT JOIN `cpa_qq_cw_app_task` ON `cpa_channel_app_task`.`id` = `cpa_qq_cw_app_task`.`channel_app_task_id` LEFT JOIN `cpa_qq_cw_app` ON `cpa_qq_cw_app_task`.`qq_cw_app_id` = `cpa_qq_cw_app`.`id` LEFT JOIN `cpa_pub_log` ON `cpa_channel_app_task`.`id` = `cpa_pub_log`.`channel_app_task_id` LEFT JOIN `cpa_qq_transaction` ON `cpa_qq_cw_app_task`.`id` = `cpa_qq_transaction`.`qq_app_task_id` AND `cpa_qq_transaction`.`type` = '1' WHERE ((`cpa_channel_app_task`.`is_deleted`=0) AND (`cpa_task`.`is_deleted`=0) AND (`cpa_qq_article`.`is_deleted`=0) AND (`cpa_article_type`.`is_deleted`=0) AND (`cpa_qq_cw_app_task`.`is_deleted`=0) AND (`cpa_qq_cw_app`.`is_deleted`=0)) AND ((`cpa_task`.`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`cpa_channel_app_task`.`channel_type_code`='qq_cw') AND (`cpa_qq_cw_app`.`penguin_name` LIKE '%华栖云秀%'))) UNION ALL ( SELECT 'pre_pub_log' AS 'model', `cpa_pre_pub_log`.`id`, `cpa_pre_pub_log`.`group_id`, `cpa_pre_pub_log`.`uuid`, `cpa_pre_pub_log`.`channel_id`, `cpa_pre_pub_log`.`channel_code`, `cpa_pre_pub_log`.`channel_type_id`, `cpa_pre_pub_log`.`channel_type_code`, `cpa_pre_pub_log`.`channel_app_source_id`, `cpa_pre_pub_log`.`channel_app_source_uuid`, `cpa_pre_pub_log`.`type`, `cpa_pre_pub_log`.`article_type_id`, `cpa_pre_pub_log`.`article_type_code`, `cpa_pre_pub_log`.`article_type_name`, `cpa_pre_pub_log`.`article_category_id`, `cpa_pre_pub_log`.`article_title`, `cpa_pre_pub_log`.`article_author`, `cpa_pre_pub_log`.`source`, `cpa_pre_pub_log`.`source_uuid`, `cpa_pre_pub_log`.`source_pub_user_id`, `cpa_pre_pub_log`.`source_callback_url`, `cpa_pre_pub_log`.`source_article_id`, `cpa_pre_pub_log`.`pub_log_code`, `cpa_pre_pub_log`.`pub_log_message`, `cpa_pre_pub_log`.`status`, `cpa_pre_pub_log`.`is_deleted`, `cpa_pre_pub_log`.`created_at`, `cpa_pre_pub_log`.`updated_at`, `cpa_pre_pub_log`.`deleted_at`, 0 AS 'task_id', 3 AS 'have_pub_number', `cpa_qq_cw_app`.`penguin_name`, '' AS 'article_url' FROM `cpa_pre_pub_log` LEFT JOIN `cpa_qq_cw_app` ON `cpa_pre_pub_log`.`channel_app_source_id` = `cpa_qq_cw_app`.`channel_app_source_id` WHERE ((`cpa_pre_pub_log`.`is_deleted`=0) AND (`cpa_qq_cw_app`.`is_deleted`=0)) AND ((`cpa_pre_pub_log`.`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`cpa_pre_pub_log`.`channel_type_code`='qq_cw') AND (`cpa_qq_cw_app`.`penguin_name` LIKE '%华栖云秀%')) )) `model` ORDER BY `created_at` DESC, `id` DESC LIMIT 20 |
15、仍然存在问题,当响应状态码为 404、302 时,未执行到过滤器方法:afterAction($action, $result),预发布日志表中未插入记录,有待于后续进一步分析处理,如图10
1 2 3 4 5 6 7 | { "name": "Not Found", "message": "渠道的应用的来源UUID:8d72b7cc2ac911eab85a54ee75d2ebc0,不存在", "code": 202001, "status": 404, "type": "yii\\web\\NotFoundHttpException" } |
1 2 3 4 5 6 7 | { "name": "Found", "message": "微博的微连接的网页应用的用户的访问令牌的渠道的应用的来源ID(UUID):bad753742ad511ea9d2054ee75d2ebc1,的访问令牌已失效", "code": 202136, "status": 302, "type": "yii\\web\\HttpException" } |
近期评论