Yii2控制台程序最佳实践
模板工程标准的控制台程序要素:
(1)完整明确文字提示用户(并且使用红,绿,黄三种颜色标识提示文字;红色为错误相关,绿色为成功相关,黄色为进行中提示)
(2)告知用户运行进度(完成任务的一部分即显示进度条)
(3)如果需要用户做出选择,应该出现文本选择组件(通常为让用户选择yes还是no,或者使用1,2,3让用户做出选择)
(4)支持空执行(即使用事务回滚的方法,做出模拟执行,以避免在真正执行时出现错误,真正执行前会发现错误)
(5)支持无限次运行(使用缓存记录ID号的方法,若已经执行过则不再执行)
(6)命令行可以支持加参数
(7)核心业务逻辑应该被封装
例如:
/**
* 山西永济基地的成品均改为标准件
* 运行命令为./yii wms-handle/handle-piece-type-for-shanxi
*/
public function actionHandlePieceTypeForShanxi(){
//提示用户选择模拟更新还是真实更新
if(Console::confirm("请选择真实更新还是模拟更新;模拟更新不会真正更新数据;[yes]为真实更新[no]为模拟更新")){
$tip = Console::ansiFormat(PHP_EOL."正在轮询真实更新中",[Console::FG_GREEN]);
Console::output("{$tip}");
unset($tip);
$is_update=true;
}else{
$tip = Console::ansiFormat(PHP_EOL."正在模拟更新中,不会真正更新",[Console::FG_RED]);
Console::output("{$tip}");
unset($tip);
$is_update=false;
}
$wmsProductInSheetModels = \core\models\WmsProductInSheet::find()->where(['common_producer_info_id'=>14, 'piece_type'=>2])->orderBy(['id'=>SORT_ASC])->all();
//设置进度条
Console::startProgress(0, count($wmsProductInSheetModels));
foreach ($wmsProductInSheetModels as $key => $wmsProductInSheetModel){
$transtion = \Yii::$app->db->beginTransaction();
try {
//提示文字
$tip = Console::ansiFormat(PHP_EOL . "正在处理成品入库单{$wmsProductInSheetModel->wms_product_in_sheet_number}", [Console::FG_YELLOW]);
Console::output("{$tip}");
unset($tip);
//已经处理过则无需再次处理
if (\Yii::$app->redis->sismember("in_sheet_number_updated_piece_type_for_shanxi", $wmsProductInSheetModel->wms_product_in_sheet_number)) {
throw new \yii\db\Exception(PHP_EOL . "成品入库单{$wmsProductInSheetModel->wms_product_in_sheet_number}已经更新过,无需再次更新");
}
//核心处理逻辑
$updateHandler = $wmsProductInSheetModel->updatePieceTypeFrom2To1();
if (!$updateHandler['status']){
throw new \yii\db\Exception($updateHandler['errmsg']);
}else{
//提示文字
$tip = Console::ansiFormat(PHP_EOL . "正在处理成品入库单{$wmsProductInSheetModel->wms_product_in_sheet_number}成功", [Console::FG_GREEN]);
Console::output("{$tip}");
unset($tip);
}
//更新进度条
Console::updateProgress($key + 1, count($wmsProductInSheetModels));
//如果是模拟更新则回滚
if (!$is_update) {
throw new \yii\db\Exception(PHP_EOL . "此次是模拟更新,不会真正更新,正在回滚到初始状态!");
}
$transtion->commit();
//将已更新的入库单号添加到已更新队列中
\Yii::$app->redis->sadd("in_sheet_number_updated_piece_type_for_shanxi", $wmsProductInSheetModel->wms_product_in_sheet_number);
} catch (\yii\base\Exception $e) {
$transtion->rollBack();
$tip = Console::ansiFormat(PHP_EOL . $e->getMessage(), [Console::FG_RED]);
Console::output("{$tip}");
unset($tip);
} catch (\yii\base\ErrorException $e) {
$transtion->rollBack();
$tip = Console::ansiFormat(PHP_EOL . $e->getMessage(), [Console::FG_RED]);
Console::output("{$tip}");
unset($tip);
}
unset($wmsProductInSheetModel);
}
unset($wmsProductInSheetModels);
//设置进度条
Console::endProgress();
//成品出库单
$wmsProductOutSheetModels = \core\models\WmsProductOutSheet::find()->where(['common_producer_info_id'=>14, 'piece_type'=>2])->orderBy(['id'=>SORT_ASC])->all();
//设置进度条
Console::startProgress(0, count($wmsProductOutSheetModels));
foreach ($wmsProductOutSheetModels as $key => $wmsProductOutSheetModel){
$transtion = \Yii::$app->db->beginTransaction();
try {
//提示文字
$tip = Console::ansiFormat(PHP_EOL . "正在处理成品出库单{$wmsProductOutSheetModel->wms_product_out_sheet_number}", [Console::FG_YELLOW]);
Console::output("{$tip}");
unset($tip);
//已经处理过则无需再次处理
if (\Yii::$app->redis->sismember("in_sheet_number_updated_piece_type_for_shanxi", $wmsProductOutSheetModel->wms_product_out_sheet_number)) {
throw new \yii\db\Exception(PHP_EOL . "成品出库单{$wmsProductOutSheetModel->wms_product_out_sheet_number}已经更新过,无需再次更新");
}
//核心处理逻辑
$updateHandler = $wmsProductOutSheetModel->updatePieceTypeFrom2To1();
if (!$updateHandler['status']){
throw new \yii\db\Exception($updateHandler['errmsg']);
}else{
//提示文字
$tip = Console::ansiFormat(PHP_EOL . "正在处理成品出库单{$wmsProductOutSheetModel->wms_product_out_sheet_number}成功", [Console::FG_GREEN]);
Console::output("{$tip}");
unset($tip);
}
//更新进度条
Console::updateProgress($key + 1, count($wmsProductOutSheetModels));
//如果是模拟更新则回滚
if (!$is_update) {
throw new \yii\db\Exception(PHP_EOL . "此次是模拟更新,不会真正更新,正在回滚到初始状态!");
}
$transtion->commit();
//将已更新的入库单号添加到已更新队列中
\Yii::$app->redis->sadd("in_sheet_number_updated_piece_type_for_shanxi", $wmsProductOutSheetModel->wms_product_out_sheet_number);
} catch (\yii\base\Exception $e) {
$transtion->rollBack();
$tip = Console::ansiFormat(PHP_EOL . $e->getMessage(), [Console::FG_RED]);
Console::output("{$tip}");
unset($tip);
} catch (\yii\base\ErrorException $e) {
$transtion->rollBack();
$tip = Console::ansiFormat(PHP_EOL . $e->getMessage(), [Console::FG_RED]);
Console::output("{$tip}");
unset($tip);
}
unset($wmsProductOutSheetModel);
}
unset($wmsProductOutSheetModels);
//设置进度条
Console::endProgress();
}
模拟执行的过程如下所示:

真实更新的过程如下:

Yii2控制台程序最佳实践的更多相关文章
- YII2 随笔 视图最佳实践
yii\base\Controller::render(): 渲染一个 视图名 并使用一个 布局 返回到渲染结果. yii\base\Controller::renderPartial(): 渲染一个 ...
- 【转】优化Web程序的最佳实践
自动排版有点乱,看着蛋疼,建议下载中文PDF版阅读或阅读英文原文. Yahoo!的Exceptional Performance团队为改善Web性能带来最佳实践.他们为此进行了 一系列的实验.开发了各 ...
- paip.java win程序迁移linux的最佳实践
paip.java win程序迁移linux的最佳实践 1.class load路径的问题... windows哈第一的从calsses目录加载,,而linux优先从jar加载.. 特别的是修理了ja ...
- Windows Azure 安全最佳实践 - 第 6 部分:Azure 服务如何扩展应用程序安全性
多种Windows Azure服务可以帮助您将应用程序安全性扩展到云. 有三种服务可提供多个提供程序之间的身份标识映射.内部部署数据中心间的连接和相互发送消息的应用程序功能(无论应用程序位于何处). ...
- Asp.NetCore程序发布到CentOs(含安装部署netcore)--最佳实践(二)
Asp.NetCore程序发布到CentOs(含安装部署netcore)--最佳实践(一) 接上一篇 3. Nginx配置反向代理 3.1 cnetos 安装nginx 首先,我们需要在服务器上安装N ...
- Asp.NetCore程序发布到CentOs(含安装部署netcore)--最佳实践(一)
环境 本地 win7 服务器:Virtual Box 上的Centos ssh工具: Xshell 文件传输: xftp 1.在本地创建asp.net core应用发布 1.1 使用Vs2017 新建 ...
- mpvue最佳实践 , 美团出的一个小程序框架
看手机微信,看到说美团出了1个小程序框架, mpvue 搜下来试试,看了网上的一个对比 ----------------- 以下为引用 我们对微信小程序.mpvue.WePY 这三个开发框架的主要能 ...
- Atitit. Gui控件and面板----程序快速启动区--最佳实践Launchy ObjectDock-o0g
Atitit. Gui控件and面板----程序快速启动区--最佳实践Launchy ObjectDock-o0g 两个方式::: 键盘式::先用热键呼叫出QS,然后开始输入程序中的部分字母,按En ...
- Javascript模块化编程(一)模块的写法最佳实践六、输入全局变量 独立性是模块的重要特点,模块内部最好不与程序的其他部分直接交互。 为了在模块内部调用全局变量,必须显式地将其他变量输入模块。
Javascript模块化编程,已经成为一个迫切的需求.理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块但是,Javascript不是一种模块化编程语言,它不支持类clas ...
随机推荐
- 微信小程序PHP 微信支付接口调用
小程序端 /** * 微信支付接口 */ wxPaymoney:function (out_trade_no, true_money){ //out_trade_no 后台统一下单接口需要用 var ...
- MySQL笔记--注意
replace into 和 insert into..... on duplicate key update的异同 同:1. 当key不存在时,两者相同,都是插入一条数据2. key存在时,执行两者 ...
- Feature Extractor[content]
0. AlexNet 1. VGG VGG网络相对来说,结构简单,通俗易懂,作者通过分析2013年imagenet的比赛的最好模型,并发现感受野还是小的好,然后再加上<network in ne ...
- machine learning[GMM-EM]
介绍下EM算法和GMM模型,先简单介绍GMM的物理意义,然后给出最直接的迭代过程:然后再介绍EM. 1 高斯混合模型 高斯分布,是统计学中的模型,其输出值表示当前输入数据样本(一维标量,多维向量)的概 ...
- 唯一正确的修改Jupyter Notebook默认路径的方法
唯一正确修改Jupyter Notebook的默认路径 1.按照网上的方法,先修改了快捷方式的起始位置,发现并不能修改默认路径. 2.后来发现“目标”中后面有个参数%USERPROFILE%,它代表的 ...
- CF833D Red-Black Cobweb 点分治、树状数组
传送门 统计所有路径的边权乘积的乘积,不难想到点分治求解. 边权颜色比例在\([\frac{1}{2},2]\)之间,等价于\(2B \geq R , 2R \geq B\)(\(R,B\)表示红色和 ...
- BZOJ4061/Gym100624F CERC2012 Farm and Factory 最短路、切比雪夫距离
传送门--BZOJCH 传送门--Vjudge 设\(f_i\)表示\(i\)到\(1\)号点的最短距离,\(g_i\)表示\(i\)到\(2\)号点的最短距离,\(s_i\)表示\(n+1\)号点到 ...
- Mysql字段名与保留字冲突导致的异常解决
一:引言 用hibernate建表时经常遇到的一个异常:Error executing DDL via JDBC Statement 方法: 查看报错sql语句.问题就在这里. 我是表名(字段名)与保 ...
- WPF仿网易云音乐系列(三、播放进度条+控制按钮)
一.简介 上一篇,咱们基本把左侧导航栏给搞定,这一篇文章,开始来做一下播放进度条和控制按钮:老规矩,咱们先来看一下原版的效果: 首先,它这个专辑图片,有一个按钮效果,鼠标移入会显示出伸缩箭头:移出后消 ...
- Java字符串操作及与C#字符串操作的不同
每种语言都会有字符串的操作,因为字符串是我们平常开发使用频率最高的一种类型.今天我们来聊一下Java的字符串操作及在某些具体方法中与C#的不同,对于需要熟悉多种语言的人来说,作为一种参考.进行诫勉 首 ...