模板工程标准的控制台程序要素

(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控制台程序最佳实践-LMLPHP

真实更新的过程如下:

Yii2控制台程序最佳实践-LMLPHP

05-11 15:24