In Yii 2.0, edit and update the task type and step setting of the tenant (multiple records, tree structure) to realize the split realization (3)
1. Edit and update the UI of the task type and step settings of the tenant to complete the design after the interface is implemented. Implementation of the previous version:https://www.shuijingwanwq.com/2019/11/14/3605/, in the previous version, the task type can be implemented at the same time: the task type can be (add, delete, rename its name, sort), and the task steps can be selected from the 18 task steps list (add, delete, check, uncheck, sort).
2. After the UI comes out, the front-end developers hope to be able to split the update interface, which is divided into: new task type, delete task type, edit a certain task type and the task steps under it, because this implementation is more consistent with the UI interface, and reduces the difficulty of front-end development. as shown in Figure 1
3. The original design scheme is to refer to the update request of Zentao and Rap, as shown in Figure 2
4. Since you want to continue to retain the previous route implementation, the routing configuration is as follows
// 基础设置 - 任务配置
[
'class' => 'yii\rest\UrlRule',
'controller' => ['v1/config-task'],
'only' => ['create', 'update', 'delete'],
],
5. Edit the model file of the task configuration, \api\models\configtask.php
<?php
namespace api\models;
use Yii;
use yii\helpers\ArrayHelper;
class ConfigTask extends \common\logics\ConfigTask
{
const SCENARIO_CREATE = 'create';
const SCENARIO_UPDATE = 'update';
const SCENARIO_DELETE = 'delete';
public function scenarios()
{
$scenarios = parent::scenarios();
$scenarios[self::SCENARIO_CREATE] = ['group_id', 'code', 'name', 'sort_order', 'is_default', 'status', 'is_deleted', 'deleted_at'];
$scenarios[self::SCENARIO_UPDATE] = ['name', 'sort_order', 'is_default', 'status'];
return $scenarios;
}
/**
* @inheritdoc
*/
public function rules()
{
$rules = [
/* 创建 */
[['code'], 'match', 'pattern' => '/^[a-z0-9]+$/', 'message' => Yii::t('application', '{attribute} should contain lowercase letters and numbers.'), 'on' => self::SCENARIO_CREATE],
[['is_default'], 'in', 'range' => [static::IS_DEFAULT_NO, static::IS_DEFAULT_YES], 'on' => self::SCENARIO_CREATE],
[['status'], 'in', 'range' => [self::STATUS_DISABLED, self::STATUS_ENABLED], 'on' => self::SCENARIO_CREATE],
/* 更新 */
[['is_default'], 'in', 'range' => [static::IS_DEFAULT_NO, static::IS_DEFAULT_YES], 'on' => self::SCENARIO_UPDATE],
[['status'], 'in', 'range' => [self::STATUS_DISABLED, self::STATUS_ENABLED], 'on' => self::SCENARIO_UPDATE],
/* 删除 */
[['id'], 'validateDeletePermission', 'on' => self::SCENARIO_DELETE],
];
$parentRules = parent::rules();
return ArrayHelper::merge($rules, $parentRules);
}
/**
* Validates the delete permission.
* This method serves as the inline validation for delete permission.
*
* @param string $attribute the attribute currently being validated
* @param array $params the additional name-value pairs given in the rule
*/
public function validateDeletePermission($attribute, $params)
{
if (!$this->hasErrors()) {
// 基于 租户ID、任务配置ID 查找资源(选题任务)的任务配置ID列
$planTaskConfigTaskIds = PlanTask::find()
->select('config_task_id')
->where([
'and',
['group_id' => $this->group_id],
['config_task_id' => $this->id]]
)
->isDeletedNo()
->distinct()
->column();
// 待删除的任务配置的代码,但是其下存在选题任务
if (!empty($planTaskConfigTaskIds)) {
$codes = implode(";", [$this->code]);
$this->addError($attribute, Yii::t('error', Yii::t('error', Yii::t('error', '226088'), ['codes' => $codes])));
}
}
}
/**
* {@inheritdoc}
* @return ConfigTaskQuery the active query used by this AR class.
*/
public static function find()
{
return new ConfigTaskQuery(get_called_class());
}
/**
* 基于 租户ID、ID 批量设置资源为是否默认:否(场景:当某资源设置为是否默认:是时,需要设置其他资源为是否默认:否)
*
* @param array $groupId 租户ID
* @param int $id ID
*
* @return int 设置资源为是否默认:否(更新)的行数
*/
public static function updateAllIsDefaultNoByGroupIdAndId($groupId, $id)
{
return self::updateAll(
[
'is_default' => self::IS_DEFAULT_NO,
],
[
'and',
['group_id' => $groupId],
['is_deleted' => self::IS_DELETED_NO],
['!=', 'id', $id],
]
);
}
}
6. Edit the model file configured by the task step, \api\models\configtaskstep.php
<?php
namespace api\models;
use yii\helpers\ArrayHelper;
class ConfigTaskStep extends \common\logics\ConfigTaskStep
{
const SCENARIO_CREATE = 'create';
const SCENARIO_UPDATE = 'update';
public function scenarios()
{
$scenarios = parent::scenarios();
$scenarios[self::SCENARIO_CREATE] = ['group_id', 'config_task_code', 'step_code', 'sort_order', 'is_default', 'is_deleted', 'deleted_at'];
$scenarios[self::SCENARIO_UPDATE] = ['sort_order', 'is_default'];
return $scenarios;
}
/**
* @inheritdoc
*/
public function rules()
{
$rules = [
/* 创建 */
['step_code', 'exist', 'targetClass' => '\api\models\ConfigStep', 'targetAttribute' => 'code', 'filter' => ['is_deleted' => ConfigStep::IS_DELETED_NO], 'on' => self::SCENARIO_CREATE],
[['is_default'], 'in', 'range' => [static::IS_DEFAULT_NO, static::IS_DEFAULT_YES], 'on' => self::SCENARIO_CREATE],
/* 添加、更新任务步骤配置 */
[['is_default'], 'in', 'range' => [static::IS_DEFAULT_NO, static::IS_DEFAULT_YES], 'on' => self::SCENARIO_UPDATE],
];
$parentRules = parent::rules();
return ArrayHelper::merge($rules, $parentRules);
}
/**
* {@inheritdoc}
* @return ConfigTaskStepQuery the active query used by this AR class.
*/
public static function find()
{
return new ConfigTaskStepQuery(get_called_class());
}
}
7. Edit the service file configured by the task step, \API\Services\ConfigTaskStepService.php
<?php
/**
* Created by PhpStorm.
* User: terryhong
* Date: 2018/12/20
* Time: 3:09 PM
*/
namespace api\services;
use Yii;
use api\models\ConfigTask;
use api\models\ConfigStep;
use api\models\ConfigTaskStep;
use yii\web\ServerErrorHttpException;
class ConfigTaskStepService extends \common\services\ConfigTaskStepService
{
/**
* 创建任务步骤配置
*
* @param object $configTask 任务配置
* 格式如下:
* [
* 'group_id' => '015ce30b116ce86058fa6ab4fea4ac63', // 租户ID
* 'code' => 'zidingyisi', // 代码
* 'name' => '自定义四', // 名称
* 'sort_order' => 8, // 顺序
* 'is_default' => 0, // 是否默认,0:否;1:是
* 'status' => 1, // 状态,0:禁用;1:启用
* 'is_deleted' => 0, // 是否被删除,0:否;1:是
* 'deleted_at' => 0, // 删除时间
* ]
*
* @param array $configTaskSteps 任务步骤配置
* 格式如下:
* [
* [ // object
* 'group_id' => '015ce30b116ce86058fa6ab4fea4ac63', // 租户ID
* 'config_task_code' => 'zidingyisi', // 任务配置代码
* 'step_code' => 'begin_shot', // 步骤代码
* 'sort_order' => 1, // 顺序
* 'is_default' => 1, // 是否默认步骤,1:是;0:否
* 'is_deleted' => 0, // 是否被删除,0:否;1:是
* 'deleted_at' => 0, // 删除时间
* ],
* [ // object
* 'group_id' => '015ce30b116ce86058fa6ab4fea4ac63', // 租户ID
* 'config_task_code' => 'zidingyisi', // 任务配置代码
* 'step_code' => 'writing', // 步骤代码
* 'sort_order' => 2, // 顺序
* 'is_default' => 1, // 是否默认步骤,1:是;0:否
* 'is_deleted' => 0, // 是否被删除,0:否;1:是
* 'deleted_at' => 0, // 删除时间
* ],
* ...
* ]
*
* @param object $identity 当前用户的身份实例
*
* @return array
* 格式如下:
*
* [
* 'status' => true, // 成功
* ]
*
* @throws \Throwable
*/
public function create($configTask, $configTaskSteps, $identity)
{
/* 操作数据(事务) */
$transaction = Yii::$app->db->beginTransaction();
try {
$configTaskService = new ConfigTaskService();
/* 创建 MySQL 模型(任务配置) */
$configTask->category = $configTask::CATEGORY_CUSTOMIZE;
$configTask->parameter = serialize('');
$configTaskServiceCreateResult = $configTaskService->create($configTask, false);
if ($configTaskServiceCreateResult['status'] === false) {
throw new ServerErrorHttpException($configTaskServiceCreateResult['message'], $configTaskServiceCreateResult['code']);
}
// 基于 租户ID、ID 批量设置资源为是否默认:否(场景:当某资源设置为是否默认:是时,需要设置其他资源为是否默认:否)
if ($configTask->is_default == ConfigTask::IS_DEFAULT_YES) {
ConfigTask::updateAllIsDefaultNoByGroupIdAndId($identity->group_id, $configTask->id);
}
$configTaskItems = ConfigTask::find()->where(['group_id' => $identity->group_id])->indexBy(['code'])->all();
$configStepItems = ConfigStep::find()->isDeletedNo()->indexBy(['code'])->all();
/* 循环创建 MySQL 模型(任务步骤配置) */
foreach ($configTaskSteps as $configTaskStep) {
/* @var $configTaskStep ConfigTaskStep */
$configTaskStep->config_task_id = $configTaskItems[$configTaskStep->config_task_code]->id;
$configTaskStep->config_step_id = $configStepItems[$configTaskStep->step_code]->id;
$configTaskStep->step_name = $configStepItems[$configTaskStep->step_code]->name;
$configTaskStep->up_status_type = $configTaskStep::UP_STATUS_TYPE_ARTIFICIAL;
$configTaskStep->status = $configTaskStep::STATUS_ENABLED;
if ($configTaskStep->save(false)) {
// return ['status' => true, 'data' => $configTaskStep];
} elseif ($configTaskStep->hasErrors()) {
$firstError = '';
foreach ($configTaskStep->getFirstErrors() as $message) {
$firstError = $message;
break;
}
return ['status' => false, 'code' => 226084, 'message' => Yii::t('error', Yii::t('error', Yii::t('error', '226084'), ['first_error' => $firstError]))];
} elseif (!$configTaskStep->hasErrors()) {
throw new ServerErrorHttpException('Failed to create the object (task step configuration) for unknown reason.');
}
}
$transaction->commit();
} catch(\Throwable $e) {
$transaction->rollBack();
throw $e;
}
return ['status' => true];
}
/**
* 更新任务配置、添加|还原|更新|删除任务步骤配置
*
* @param object $configTask 任务配置
* 格式如下:
* [ // object
* 'id' => 24, // ID
* 'group_id' => '015ce30b116ce86058fa6ab4fea4ac63', // 租户ID
* 'code' => 'zidingyisi', // 代码
* 'name' => '自定义四十', // 名称
* 'sort_order' => 9, // 顺序
* 'category' => 2, // 任务类型,1:系统内置;2:用户定义
* 'is_default' => 1, // 是否默认,0:否;1:是
* 'parameter' => 's:0:"";', // 自定义参数,序列化存储
* 'status' => 0, // 状态,0:禁用;1:启用
* 'is_deleted' => 0, // 是否被删除,0:否;1:是
* 'created_at' => 1574670316, // 创建时间
* 'updated_at' => 1574670316, // 更新时间
* 'deleted_at' => 0, // 删除时间
* ]
*
* @param array $deletedConfigTaskSteps 需要删除的任务步骤配置
* 格式如下:
* [
* [ // object
* 'id' => 127, // ID
* 'group_id' => '015ce30b116ce86058fa6ab4fea4ac63', // 租户ID
* 'config_task_id' => 24, // 任务配置ID
* 'config_task_code' => 'zidingyisi', // 任务配置代码
* 'config_step_id' => 2, // 步骤配置ID
* 'step_code' => 'begin_shot', // 步骤配置代码
* 'step_name' => '上传素材', // 步骤配置名称
* 'sort_order' => 1, // 步骤顺序,顺序排列
* 'is_default' => 1, // 是否默认步骤,1:是;0:否
* 'up_status_type' => 2, // 状态更新方式,1:接口;2:人工
* 'status' => 1, // 状态,0:禁用;1:启用
* 'is_deleted' => 0, // 是否被删除,0:否;1:是
* 'created_at' => 1574670316, // 创建时间
* 'updated_at' => 1574670316, // 更新时间
* 'deleted_at' => 0, // 删除时间
* ],
* ...
* ]
*
*
* @param array $configTaskSteps 任务步骤配置
* 格式如下:
* [
* [ // object
* 'group_id' => '015ce30b116ce86058fa6ab4fea4ac63', // 租户ID
* 'config_task_code' => 'zidingyisi', // 任务配置代码
* 'step_code' => 'begin_shot', // 步骤代码
* 'sort_order' => 6, // 顺序
* 'is_default' => 1, // 是否默认步骤,1:是;0:否
* 'is_deleted' => 0, // 是否被删除,0:否;1:是
* 'deleted_at' => 0, // 删除时间
* ],
* [ // object
* 'id' => 128, // ID
* 'group_id' => '015ce30b116ce86058fa6ab4fea4ac63', // 租户ID
* 'config_task_id' => 24, // 任务配置ID
* 'config_task_code' => 'zidingyisi', // 任务配置代码
* 'config_step_id' => 4, // 步骤配置ID
* 'step_code' => 'writing', // 步骤配置代码
* 'step_name' => '撰写稿件', // 步骤配置名称
* 'sort_order' => 3, // 步骤顺序,顺序排列
* 'is_default' => 0, // 是否默认步骤,1:是;0:否
* 'up_status_type' => 2, // 状态更新方式,1:接口;2:人工
* 'status' => 1, // 状态,0:禁用;1:启用
* 'is_deleted' => 0, // 是否被删除,0:否;1:是
* 'created_at' => 1574670316, // 创建时间
* 'updated_at' => 1574670316, // 更新时间
* 'deleted_at' => 0, // 删除时间
* ],
* ...
* ]
*
* @param object $identity 当前用户的身份实例
*
* @return array
* 格式如下:
*
* [
* 'status' => true, // 成功
* ]
*
* @throws \Throwable
*/
public function update($configTask, $deletedConfigTaskSteps, $configTaskSteps, $identity)
{
/* 操作数据(事务) */
$transaction = Yii::$app->db->beginTransaction();
try {
$configTaskService = new ConfigTaskService();
/* 更新 MySQL 模型(任务配置) */
$configTaskServiceUpdateResult = $configTaskService->update($configTask, false);
if ($configTaskServiceUpdateResult['status'] === false) {
throw new ServerErrorHttpException($configTaskServiceUpdateResult['message'], $configTaskServiceUpdateResult['code']);
}
// 基于 租户ID、ID 批量设置资源为是否默认:否(场景:当某资源设置为是否默认:是时,需要设置其他资源为是否默认:否)
if ($configTask->is_default == ConfigTask::IS_DEFAULT_YES) {
ConfigTask::updateAllIsDefaultNoByGroupIdAndId($identity->group_id, $configTask->id);
}
// 使用键名比较计算数组的差集,如果不为空,则删除 (软删除) 出现在 任务步骤配置模型(MySQL) 中但是未出现在 任务步骤配置列表 中的记录
$this->deleteMultiple($deletedConfigTaskSteps);
$configTaskItems = ConfigTask::find()->where(['group_id' => $identity->group_id])->indexBy(['code'])->all();
$configStepItems = ConfigStep::find()->isDeletedNo()->indexBy(['code'])->all();
// 遍历模型数组,判断在 任务步骤配置 中是否存在,如果不存在则插入,如果存在则更新(已删除则先还原)
foreach ($configTaskSteps as $configTaskStep) {
$configTaskStepItem = ConfigTaskStep::find()->where(['group_id' => $identity->group_id, 'config_task_code' => $configTaskStep->config_task_code, 'step_code' => $configTaskStep->step_code])->one();
/* @var $configTaskStep ConfigTaskStep */
if (!isset($configTaskStepItem)) {
$configTaskStep->config_task_id = $configTaskItems[$configTaskStep->config_task_code]->id;
$configTaskStep->config_step_id = $configStepItems[$configTaskStep->step_code]->id;
$configTaskStep->step_name = $configStepItems[$configTaskStep->step_code]->name;
$configTaskStep->up_status_type = $configTaskStep::UP_STATUS_TYPE_ARTIFICIAL;
$configTaskStep->status = $configTaskStep::STATUS_ENABLED;
if ($configTaskStep->save(false)) {
// return ['status' => true, 'data' => $configTaskStep];
} elseif ($configTaskStep->hasErrors()) {
$firstError = '';
foreach ($configTaskStep->getFirstErrors() as $message) {
$firstError = $message;
break;
}
return ['status' => false, 'code' => 226084, 'message' => Yii::t('error', Yii::t('error', Yii::t('error', '226084'), ['first_error' => $firstError]))];
} elseif (!$configTaskStep->hasErrors()) {
throw new ServerErrorHttpException('Failed to create the object (task step configuration) for unknown reason.');
}
} else if (isset($configTaskStepItem)) {
if ($configTaskStepItem->is_deleted == ConfigTaskStep::IS_DELETED_YES && $configTaskStepItem->restore() === false) {
throw new ServerErrorHttpException('Failed to restore the object (task step configuration) for unknown reason.');
}
$configTaskStepItem->sort_order = $configTaskStep->sort_order;
$configTaskStepItem->is_default = $configTaskStep->is_default;
if ($configTaskStepItem->save(false)) {
// return ['status' => true, 'data' => $configTaskStepItem];
} elseif ($configTaskStepItem->hasErrors()) {
$firstError = '';
foreach ($configTaskStepItem->getFirstErrors() as $message) {
$firstError = $message;
break;
}
throw new ServerErrorHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '226085'), ['first_error' => $firstError])), 226085);
} elseif (!$configTaskStepItem->hasErrors()) {
throw new ServerErrorHttpException('Failed to update the object (task step configuration) for unknown reason.');
}
}
}
$transaction->commit();
} catch(\Throwable $e) {
$transaction->rollBack();
throw $e;
}
return ['status' => true];
}
/**
* 添加|还原|更新|删除任务配置、添加|还原|更新|删除任务步骤配置
*
* @param array $deletedConfigTasks 需要删除的任务配置
* 格式如下:
* [
* [ // object
* 'id' => 32, // ID
* 'group_id' => '015ce30b116ce86058fa6ab4fea4ac63', // 租户ID
* 'code' => 'other', // 代码
* 'name' => '手动任务', // 名称
* 'sort_order' => 1, // 顺序
* 'category' => 2, // 任务类型,1:系统内置;2:用户定义
* 'is_default' => 0, // 是否默认,0:否;1:是
* 'parameter' => 's:0:"";', // 自定义参数,序列化存储
* 'status' => 1, // 状态,0:禁用;1:启用
* 'is_deleted' => 0, // 是否被删除,0:否;1:是
* 'created_at' => 1573632826, // 创建时间
* 'updated_at' => 1573632826, // 更新时间
* 'deleted_at' => 0, // 删除时间
* ],
* ...
* ]
*
* @param array $configTasks 任务配置
* 格式如下:
* [
* [ // object
* 'group_id' => '015ce30b116ce86058fa6ab4fea4ac63', // 租户ID
* 'code' => 'tv_broadcast', // 代码
* 'name' => '电视播出', // 名称
* 'sort_order' => 1, // 顺序
* 'is_default' => 0, // 是否默认,0:否;1:是
* 'is_deleted' => 0, // 是否被删除,0:否;1:是
* 'deleted_at' => 0, // 删除时间
* ],
* [ // object
* 'id' => 29, // ID
* 'group_id' => '015ce30b116ce86058fa6ab4fea4ac63', // 租户ID
* 'code' => 'tv_broadcast', // 代码
* 'name' => '电视播出', // 名称
* 'sort_order' => 1, // 顺序
* 'category' => 2, // 任务类型,1:系统内置;2:用户定义
* 'is_default' => 0, // 是否默认,0:否;1:是
* 'parameter' => 's:0:"";', // 自定义参数,序列化存储
* 'status' => 1, // 状态,0:禁用;1:启用
* 'is_deleted' => 0, // 是否被删除,0:否;1:是
* 'created_at' => 1573632826, // 创建时间
* 'updated_at' => 1573632826, // 更新时间
* 'deleted_at' => 0, // 删除时间
* ],
* ...
* ]
*
* @param array $deletedConfigTaskSteps 需要删除的任务步骤配置
* 格式如下:
* [
* [ // object
* 'id' => 145, // ID
* 'group_id' => '015ce30b116ce86058fa6ab4fea4ac63', // 租户ID
* 'config_task_id' => 32, // 任务配置ID
* 'config_task_code' => 'other', // 任务配置代码
* 'config_step_id' => 2, // 步骤配置ID
* 'step_code' => 'begin_shot', // 步骤配置代码
* 'step_name' => '上传素材', // 步骤配置名称
* 'sort_order' => 1, // 步骤顺序,顺序排列
* 'is_default' => 1, // 是否默认步骤,1:是;0:否
* 'up_status_type' => 2, // 状态更新方式,1:接口;2:人工
* 'status' => 1, // 状态,0:禁用;1:启用
* 'is_deleted' => 0, // 是否被删除,0:否;1:是
* 'created_at' => 1573632826, // 创建时间
* 'updated_at' => 1573632826, // 更新时间
* 'deleted_at' => 0, // 删除时间
* ],
* ...
* ]
*
*
* @param array $configTaskSteps 任务步骤配置
* 格式如下:
* [
* [ // object
* 'group_id' => '015ce30b116ce86058fa6ab4fea4ac63', // 租户ID
* 'config_task_code' => 'tv_broadcast', // 任务配置代码
* 'step_code' => 'begin_shot', // 步骤代码
* 'sort_order' => 1, // 顺序
* 'is_default' => 1, // 是否默认步骤,1:是;0:否
* 'is_deleted' => 0, // 是否被删除,0:否;1:是
* 'deleted_at' => 0, // 删除时间
* ],
* [ // object
* 'id' => 122, // ID
* 'group_id' => '015ce30b116ce86058fa6ab4fea4ac63', // 租户ID
* 'config_task_id' => 29, // 任务配置ID
* 'config_task_code' => 'tv_broadcast', // 任务配置代码
* 'config_step_id' => 2, // 步骤配置ID
* 'step_code' => 'begin_shot', // 步骤配置代码
* 'step_name' => '上传素材', // 步骤配置名称
* 'sort_order' => 1, // 步骤顺序,顺序排列
* 'is_default' => 1, // 是否默认步骤,1:是;0:否
* 'up_status_type' => 2, // 状态更新方式,1:接口;2:人工
* 'status' => 1, // 状态,0:禁用;1:启用
* 'is_deleted' => 0, // 是否被删除,0:否;1:是
* 'created_at' => 1573632826, // 创建时间
* 'updated_at' => 1573632826, // 更新时间
* 'deleted_at' => 0, // 删除时间
* ],
* ...
* ]
*
* @param object $identity 当前用户的身份实例
*
* @return array
* 格式如下:
*
* [
* 'status' => true, // 成功
* ]
*
* @throws \Throwable
*/
public function updateMultiple($deletedConfigTasks, $configTasks, $deletedConfigTaskSteps, $configTaskSteps, $identity)
{
/* 操作数据(事务) */
$transaction = Yii::$app->db->beginTransaction();
try {
$configTaskService = new ConfigTaskService();
// 使用键名比较计算数组的差集,如果不为空,则删除 (软删除) 出现在 任务配置模型(MySQL) 中但是未出现在 任务配置列表 中的记录
$configTaskService->deleteMultiple($deletedConfigTasks);
// 遍历模型数组,判断在 任务配置 中是否存在,如果不存在则插入,如果存在则更新(已删除则先还原)
foreach ($configTasks as $configTask) {
$configTaskItem = ConfigTask::find()->where(['group_id' => $identity->group_id, 'code' => $configTask->code])->one();
/* @var $configTask ConfigTask */
if (!isset($configTaskItem)) {
$configTask->category = $configTask::CATEGORY_CUSTOMIZE;
$configTask->parameter = serialize('');
$configTask->status = $configTask::STATUS_ENABLED;
$configTask->is_deleted = $configTask::IS_DELETED_NO;
$configTask->deleted_at = $configTask::DELETED_AT_DEFAULT;
$configTaskServiceCreateResult = $configTaskService->create($configTask, false);
if ($configTaskServiceCreateResult['status'] === false) {
throw new ServerErrorHttpException($configTaskServiceCreateResult['message'], $configTaskServiceCreateResult['code']);
}
} else if (isset($configTaskItem)) {
if ($configTaskItem->is_deleted == ConfigTask::IS_DELETED_YES && $configTaskItem->restore() === false) {
throw new ServerErrorHttpException('Failed to restore the object (task configuration) for unknown reason.');
}
$configTaskItem->name = $configTask->name;
$configTaskItem->sort_order = $configTask->sort_order;
$configTaskItem->is_default = $configTask->is_default;
$configTaskItemServiceUpdateResult = $configTaskService->update($configTaskItem, false);
if ($configTaskItemServiceUpdateResult['status'] === false) {
throw new ServerErrorHttpException($configTaskItemServiceUpdateResult['message'], $configTaskItemServiceUpdateResult['code']);
}
}
}
// 使用键名比较计算数组的差集,如果不为空,则删除 (软删除) 出现在 任务步骤配置模型(MySQL) 中但是未出现在 任务步骤配置列表 中的记录
$this->deleteMultiple($deletedConfigTaskSteps);
$configTaskItems = ConfigTask::find()->where(['group_id' => $identity->group_id])->indexBy(['code'])->all();
$configStepItems = ConfigStep::find()->isDeletedNo()->indexBy(['code'])->all();
// 遍历模型数组,判断在 任务步骤配置 中是否存在,如果不存在则插入,如果存在则更新(已删除则先还原)
foreach ($configTaskSteps as $configTaskStep) {
$configTaskStepItem = ConfigTaskStep::find()->where(['group_id' => $identity->group_id, 'config_task_code' => $configTaskStep->config_task_code, 'step_code' => $configTaskStep->step_code])->one();
/* @var $configTaskStep ConfigTaskStep */
if (!isset($configTaskStepItem)) {
$configTaskStep->config_task_id = $configTaskItems[$configTaskStep->config_task_code]->id;
$configTaskStep->config_step_id = $configStepItems[$configTaskStep->step_code]->id;
$configTaskStep->step_name = $configStepItems[$configTaskStep->step_code]->name;
$configTaskStep->up_status_type = $configTaskStep::UP_STATUS_TYPE_ARTIFICIAL;
$configTaskStep->status = $configTaskStep::STATUS_ENABLED;
if ($configTaskStep->save(false)) {
// return ['status' => true, 'data' => $configTaskStep];
} elseif ($configTaskStep->hasErrors()) {
$firstError = '';
foreach ($configTaskStep->getFirstErrors() as $message) {
$firstError = $message;
break;
}
return ['status' => false, 'code' => 226084, 'message' => Yii::t('error', Yii::t('error', Yii::t('error', '226084'), ['first_error' => $firstError]))];
} elseif (!$configTaskStep->hasErrors()) {
throw new ServerErrorHttpException('Failed to create the object (task step configuration) for unknown reason.');
}
} else if (isset($configTaskStepItem)) {
if ($configTaskStepItem->is_deleted == ConfigTaskStep::IS_DELETED_YES && $configTaskStepItem->restore() === false) {
throw new ServerErrorHttpException('Failed to restore the object (task step configuration) for unknown reason.');
}
$configTaskStepItem->sort_order = $configTaskStep->sort_order;
$configTaskStepItem->is_default = $configTaskStep->is_default;
if ($configTaskStepItem->save(false)) {
// return ['status' => true, 'data' => $configTaskStepItem];
} elseif ($configTaskStepItem->hasErrors()) {
$firstError = '';
foreach ($configTaskStepItem->getFirstErrors() as $message) {
$firstError = $message;
break;
}
throw new ServerErrorHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '226085'), ['first_error' => $firstError])), 226085);
} elseif (!$configTaskStepItem->hasErrors()) {
throw new ServerErrorHttpException('Failed to update the object (task step configuration) for unknown reason.');
}
}
}
$transaction->commit();
} catch(\Throwable $e) {
$transaction->rollBack();
throw $e;
}
return ['status' => true];
}
/**
* 批量删除(删除任务步骤配置)
*
* @param $models
*
* @return bool the saved model or false if saving fails
* @throws \Throwable
*/
public function deleteMultiple($models)
{
$transaction = Yii::$app->db->beginTransaction();
try {
foreach ($models as $model) {
if($model->softDelete() === false) {
throw new ServerErrorHttpException(Yii::t('error', '226086'), 226086);
}
}
$transaction->commit();
return true;
} catch (\Throwable $e) {
$transaction->rollBack();
throw $e;
}
}
}
8. Edit the operation method file of the tenant’s task type and step settings to retain support for batch updates, \api\rests\config_task_step\updateaction.php
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace api\rests\config_task_step;
use Yii;
use api\models\ConfigTask;
use api\models\ConfigTaskStep;
use api\models\PlanTask;
use api\models\redis\cmc_console\User as RedisCmcConsoleUser;
use api\services\ConfigTaskStepService;
use yii\base\Model;
use yii\base\InvalidConfigException;
use yii\helpers\ArrayHelper;
use yii\web\UnprocessableEntityHttpException;
use yii\web\ServerErrorHttpException;
/**
* 更新租户的任务类型与步骤设置:/config-task-steps/{group_id}(config-task-step/update)
*
* For more details and usage information on CreateAction, see the [guide article on rest controllers](guide:rest-controllers).
*
* @author Qiang Wang <shuijingwanwq@163.com>
* @since 1.0
*/
class UpdateAction extends Action
{
/**
* @var string the scenario to be assigned to the model before it is validated and updated.
* $id {config_column_id}
*/
public $scenario = Model::SCENARIO_DEFAULT;
/**
* Updates an existing model.
* @param string $id the primary key of the model.
* @return array the model being updated
* @throws InvalidConfigException if a registered parser does not implement the [[RequestParserInterface]].
* @throws ServerErrorHttpException if there is any error when updating the model
* @throws \Throwable
*/
public function run($id)
{
// 当前用户的身份实例,未认证用户则为 Null
/* @var $identity RedisCmcConsoleUser */
$identity = Yii::$app->user->identity;
// 比对:group_id,检查其值是否等于:my-group-id
if ($id != 'my-group-id') {
throw new UnprocessableEntityHttpException(Yii::t('error', '226053'), 226053);
}
/* @var $modelClass ConfigTaskStep */
$modelClass = $this->modelClass;
$requestParams = Yii::$app->getRequest()->getBodyParams();
/* @var $configGroupTaskItem ConfigTask */
// 基于租户ID查找资源(任务配置、是否被删除:否)列表
$configTaskIsDeletedNoItems = ConfigTask::find()->where(['group_id' => $identity->group_id])->isDeletedNo()->indexBy(['code'])->all();
// 基于租户ID查找资源(任务配置)列表
$configTaskItems = ConfigTask::find()->where(['group_id' => $identity->group_id])->indexBy(['code'])->all();
/* @var $configGroupTaskStepItem ConfigTaskStep */
// 基于租户ID查找资源(任务步骤配置、是否被删除:否)列表
$configTaskStepIsDeletedNoItems = $modelClass::find()->where(['group_id' => $identity->group_id])->isDeletedNo()->indexBy(function ($row) { return $row['config_task_code'] . ':' . $row['step_code']; })->all();
// 基于租户ID查找资源(任务步骤配置)列表
$configTaskStepItems = $modelClass::find()->where(['group_id' => $identity->group_id])->indexBy(function ($row) { return $row['config_task_code'] . ':' . $row['step_code']; })->all();
if (!is_array($requestParams)) {
return ['code' => 226010, 'message' => Yii::t('error', '226010')];
}
$configTasks = [];
$configTaskSteps = [];
foreach ($requestParams as $configTask) {
// 检查 任务配置的(代码、名称、顺序) 是否存在
if (!ArrayHelper::keyExists('code', $configTask) || !ArrayHelper::keyExists('name', $configTask) || !ArrayHelper::keyExists('sort_order', $configTask)) {
throw new UnprocessableEntityHttpException(Yii::t('error', '226080'), 226080);
}
$isDefault = isset($configTask['is_default']) ? $configTask['is_default'] : 0;
$configTasks[$configTask['code']] = [
'group_id' => $identity->group_id,
'code' => $configTask['code'],
'name' => $configTask['name'],
'sort_order' => $configTask['sort_order'],
'is_default' => isset($configTask['is_default']) ? $configTask['is_default'] : ConfigTask::IS_DEFAULT_NO,
];
// 检查 步骤配置列表 是否存在
if (ArrayHelper::keyExists('steps', $configTask)) {
foreach ($configTask['steps'] as $configTaskStep) {
// 检查 步骤代码、顺序、是否默认步骤 是否存在
if (!ArrayHelper::keyExists('code', $configTaskStep) || !ArrayHelper::keyExists('sort_order', $configTaskStep) || !ArrayHelper::keyExists('is_default', $configTaskStep)) {
throw new UnprocessableEntityHttpException(Yii::t('error', '226080'), 226080);
}
$configTaskSteps[$configTask['code'] . ':' . $configTaskStep['code']] = [
'group_id' => $identity->group_id,
'config_task_code' => $configTask['code'],
'step_code' => $configTaskStep['code'],
'sort_order' => $configTaskStep['sort_order'],
'is_default' => $configTaskStep['is_default'],
];
}
}
}
/* 任务配置 */
// 使用键名比较计算数组的差集,如果不为空,则删除 (软删除) 出现在 任务配置模型(MySQL) 中但是未出现在 任务配置 中的记录
$configTaskDiffItems = array_diff_key($configTaskIsDeletedNoItems, $configTasks);
// 获取 id 值列表
$configTaskDiffIds = ArrayHelper::getColumn($configTaskDiffItems, 'id');
// 基于 租户ID、任务配置ID 查找资源(选题任务)的任务配置ID列
$planTaskConfigTaskIds = PlanTask::find()
->select('config_task_id')
->where([
'and',
['group_id' => $identity->group_id],
['in', 'config_task_id', $configTaskDiffIds]]
)
->isDeletedNo()
->distinct()
->column();
// 待删除的任务配置的代码,但是其下存在选题任务
$configTaskDiffCodes = [];
foreach ($configTaskDiffIds as $configTaskDiffIdKey => $configTaskDiffId) {
if (in_array($configTaskDiffId, $planTaskConfigTaskIds)) {
$configTaskDiffCodes[] = $configTaskDiffIdKey;
}
}
if (!empty($configTaskDiffCodes)) {
$codes = implode(";", $configTaskDiffCodes);
throw new UnprocessableEntityHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '226088'), ['codes' => $codes])), 226088);
}
$configTasks = array_values($configTasks);
$configTaskModels = [];
foreach ($configTasks as $configTask) {
if (isset($configTaskItems[$configTask['code']])) {
$configTaskItems[$configTask['code']]->scenario = ConfigTask::SCENARIO_UPDATE;
$configTaskModels[] = $configTaskItems[$configTask['code']];
} else {
$configTaskModels[] = new ConfigTask([
'scenario' => ConfigTask::SCENARIO_CREATE,
]);
}
}
// 批量填充模型属性
if (!empty($configTaskModels) && !Model::loadMultiple($configTaskModels, $configTasks, '')) {
return ['code' => 226010, 'message' => Yii::t('error', '226010')];
}
// 批量验证模型
if (!empty($configTaskModels) && !Model::validateMultiple($configTaskModels)) {
$configTaskModelsResult = self::handleValidateMultipleError($configTaskModels);
if ($configTaskModelsResult['status'] === false) {
return ['code' => $configTaskModelsResult['code'], 'message' => $configTaskModelsResult['message']];
}
}
/* 任务步骤配置 */
// 使用键名比较计算数组的差集,如果不为空,则删除 (软删除) 出现在 任务步骤配置模型(MySQL) 中但是未出现在 任务步骤配置 中的记录
$configTaskStepDiffItems = array_diff_key($configTaskStepIsDeletedNoItems, $configTaskSteps);
$configTaskSteps = array_values($configTaskSteps);
$configTaskStepModels = [];
foreach ($configTaskSteps as $configTaskStep) {
$index = $configTaskStep['config_task_code'] . ':' . $configTaskStep['step_code'];
if (isset($configTaskStepItems[$index])) {
$configTaskStepItems[$index]->scenario = $modelClass::SCENARIO_UPDATE;
$configTaskStepModels[] = $configTaskStepItems[$index];
} else {
$configTaskStepModels[] = new $modelClass([
'scenario' => $modelClass::SCENARIO_CREATE,
]);
}
}
// 批量填充模型属性
if (!empty($configTaskStepModels) && !Model::loadMultiple($configTaskStepModels, $configTaskSteps, '')) {
return ['code' => 226010, 'message' => Yii::t('error', '226010')];
}
// 批量验证模型
if (!empty($configTaskStepModels) && !Model::validateMultiple($configTaskStepModels)) {
$configTaskStepModelsResult = self::handleValidateMultipleError($configTaskStepModels);
if ($configTaskStepModelsResult['status'] === false) {
return ['code' => $configTaskStepModelsResult['code'], 'message' => $configTaskStepModelsResult['message']];
}
}
/* 操作数据(事务) */
$configTaskStepService = new ConfigTaskStepService();
$result = $configTaskStepService->updateMultiple($configTaskDiffItems, $configTaskModels, $configTaskStepDiffItems, $configTaskStepModels, $identity);
if ($result['status'] === false) {
throw new ServerErrorHttpException($result['message'], $result['code']);
}
return ['code' => 10000, 'message' => Yii::t('success', '126039')];
}
}
9. Get in Postman:http://api.pcs-api.localhost/v1/config-task-steps/edit/my-group-id, the response data is as follows
{
"code": 10000,
"message": "编辑租户的任务类型与步骤设置成功",
"data": {
"items": [
{
"id": 5,
"code": "tv_broadcast",
"name": "电视播出",
"sort_order": 1,
"is_default": 0,
"status": 1,
"steps": [
{
"id": 2,
"code": "begin_shot",
"name": "上传素材",
"sort_order": 1,
"is_default": 1,
"status": 1
},
{
"id": 4,
"code": "writing",
"name": "撰写稿件",
"sort_order": 2,
"is_default": 1,
"status": 1
},
{
"id": 7,
"code": "manuscript_review",
"name": "稿件审核",
"sort_order": 3,
"is_default": 1,
"status": 1
},
{
"id": 10,
"code": "video_editing",
"name": "视频编辑",
"sort_order": 4,
"is_default": 1,
"status": 1
},
{
"id": 11,
"code": "tandem_list",
"name": "串联单",
"sort_order": 5,
"is_default": 1,
"status": 1
},
{
"id": 14,
"code": "program_render",
"name": "节目上传",
"sort_order": 6,
"is_default": 1,
"status": 1
},
{
"id": 16,
"code": "program_authen",
"name": "节目审查",
"sort_order": 7,
"is_default": 1,
"status": 1
}
]
},
{
"id": 6,
"code": "inter_view",
"name": "采访任务",
"sort_order": 2,
"is_default": 0,
"status": 1,
"steps": [
{
"id": 2,
"code": "begin_shot",
"name": "上传素材",
"sort_order": 1,
"is_default": 1,
"status": 1
},
{
"id": 3,
"code": "material_review",
"name": "素材审核",
"sort_order": 2,
"is_default": 1,
"status": 1
},
{
"id": 4,
"code": "writing",
"name": "撰写稿件",
"sort_order": 3,
"is_default": 1,
"status": 1
},
{
"id": 8,
"code": "writing_draft",
"name": "撰写通稿",
"sort_order": 4,
"is_default": 1,
"status": 1
},
{
"id": 7,
"code": "manuscript_review",
"name": "稿件审核",
"sort_order": 5,
"is_default": 1,
"status": 1
},
{
"id": 13,
"code": "finish_interview",
"name": "结束采访",
"sort_order": 6,
"is_default": 1,
"status": 1
}
]
},
{
"id": 7,
"code": "rich_doc",
"name": "互联网发布",
"sort_order": 3,
"is_default": 0,
"status": 1,
"steps": [
{
"id": 1,
"code": "retrieval",
"name": "取稿",
"sort_order": 1,
"is_default": 1,
"status": 1
},
{
"id": 4,
"code": "writing",
"name": "撰写稿件",
"sort_order": 2,
"is_default": 1,
"status": 1
},
{
"id": 7,
"code": "manuscript_review",
"name": "稿件审核",
"sort_order": 3,
"is_default": 1,
"status": 1
},
{
"id": 9,
"code": "newspaper_issued",
"name": "报纸签发",
"sort_order": 4,
"is_default": 1,
"status": 1
},
{
"id": 12,
"code": "wechat_group_reference",
"name": "微信组稿引用",
"sort_order": 5,
"is_default": 1,
"status": 1
},
{
"id": 15,
"code": "website_release",
"name": "网站发布",
"sort_order": 6,
"is_default": 1,
"status": 1
},
{
"id": 17,
"code": "app_release",
"name": "APP发布",
"sort_order": 7,
"is_default": 1,
"status": 1
},
{
"id": 18,
"code": "wechat_release",
"name": "微信发布",
"sort_order": 8,
"is_default": 1,
"status": 1
},
{
"id": 19,
"code": "blog_release",
"name": "微博发布",
"sort_order": 9,
"is_default": 1,
"status": 1
},
{
"id": 20,
"code": "qq_release",
"name": "企鹅号发布",
"sort_order": 10,
"is_default": 1,
"status": 1
}
]
},
{
"id": 8,
"code": "other",
"name": "手动任务",
"sort_order": 4,
"is_default": 0,
"status": 1,
"steps": [
{
"id": 2,
"code": "begin_shot",
"name": "上传素材",
"sort_order": 1,
"is_default": 1,
"status": 1
}
]
},
{
"id": 17,
"code": "zidingyiyi",
"name": "自定义一",
"sort_order": 5,
"is_default": 0,
"status": 1,
"steps": [
{
"id": 2,
"code": "begin_shot",
"name": "上传素材",
"sort_order": 1,
"is_default": 1,
"status": 1
}
]
},
{
"id": 22,
"code": "zidingyier",
"name": "自定义二",
"sort_order": 6,
"is_default": 0,
"status": 1,
"steps": [
{
"id": 2,
"code": "begin_shot",
"name": "上传素材",
"sort_order": 1,
"is_default": 1,
"status": 1
}
]
},
{
"id": 23,
"code": "zidingyisan",
"name": "自定义三",
"sort_order": 7,
"is_default": 0,
"status": 1,
"steps": [
{
"id": 2,
"code": "begin_shot",
"name": "上传素材",
"sort_order": 1,
"is_default": 1,
"status": 1
}
]
},
{
"id": 24,
"code": "zidingyisi",
"name": "自定义四十",
"sort_order": 9,
"is_default": 1,
"status": 0,
"steps": [
{
"id": 4,
"code": "writing",
"name": "撰写稿件",
"sort_order": 3,
"is_default": 0,
"status": 1
},
{
"id": 15,
"code": "website_release",
"name": "网站发布",
"sort_order": 6,
"is_default": 1,
"status": 1
}
]
}
]
}
}
10. Put in Postman:http://api.pcs-api.localhost/v1/config-task-steps/my-group-id, request data (delete 1 task configuration (custom 3) and 1 step configuration in it; update 1 task configuration (custom 40) and 1 of the steps in it); add 1 task configuration (custom six) at the end and add 1 in it Item step configuration and execution SQL (task configuration table: 1 insert statement, 2 update statements; task step configuration table: 1 insert statement, 2 update statement) as follows
[
{
"code": "tv_broadcast",
"name": "电视播出",
"sort_order": 1,
"is_default": 0,
"steps": [
{
"code": "begin_shot",
"sort_order": 1,
"is_default": 1
},
{
"code": "writing",
"sort_order": 2,
"is_default": 1
},
{
"code": "manuscript_review",
"sort_order": 3,
"is_default": 1
},
{
"code": "video_editing",
"sort_order": 4,
"is_default": 1
},
{
"code": "tandem_list",
"sort_order": 5,
"is_default": 1
},
{
"code": "program_render",
"sort_order": 6,
"is_default": 1
},
{
"code": "program_authen",
"sort_order": 7,
"is_default": 1
}
]
},
{
"code": "inter_view",
"name": "采访任务",
"sort_order": 2,
"is_default": 0,
"steps": [
{
"code": "begin_shot",
"sort_order": 1,
"is_default": 1
},
{
"code": "material_review",
"sort_order": 2,
"is_default": 1
},
{
"code": "writing",
"sort_order": 3,
"is_default": 1
},
{
"code": "writing_draft",
"sort_order": 4,
"is_default": 1
},
{
"code": "manuscript_review",
"sort_order": 5,
"is_default": 1
},
{
"code": "finish_interview",
"sort_order": 6,
"is_default": 1
}
]
},
{
"code": "rich_doc",
"name": "互联网发布",
"sort_order": 3,
"is_default": 0,
"steps": [
{
"code": "retrieval",
"sort_order": 1,
"is_default": 1
},
{
"code": "writing",
"sort_order": 2,
"is_default": 1
},
{
"code": "manuscript_review",
"sort_order": 3,
"is_default": 1
},
{
"code": "newspaper_issued",
"sort_order": 4,
"is_default": 1
},
{
"code": "wechat_group_reference",
"sort_order": 5,
"is_default": 1
},
{
"code": "website_release",
"sort_order": 6,
"is_default": 1
},
{
"code": "app_release",
"sort_order": 7,
"is_default": 1
},
{
"code": "wechat_release",
"sort_order": 8,
"is_default": 1
},
{
"code": "blog_release",
"sort_order": 9,
"is_default": 1
},
{
"code": "qq_release",
"sort_order": 10,
"is_default": 1
}
]
},
{
"code": "other",
"name": "手动任务",
"sort_order": 4,
"is_default": 0,
"steps": [
{
"code": "begin_shot",
"sort_order": 1,
"is_default": 1
}
]
},
{
"code": "zidingyiyi",
"name": "自定义一",
"sort_order": 5,
"is_default": 0,
"steps": [
{
"code": "begin_shot",
"sort_order": 1,
"is_default": 1
}
]
},
{
"code": "zidingyier",
"name": "自定义二",
"sort_order": 6,
"is_default": 0,
"steps": [
{
"code": "begin_shot",
"sort_order": 1,
"is_default": 1
}
]
},
{
"code": "zidingyisi",
"name": "自定义四十",
"sort_order": 9,
"is_default": 0,
"steps": [
{
"code": "writing",
"sort_order": 1,
"is_default": 0
},
{
"code": "website_release",
"sort_order": 6,
"is_default": 1
}
]
},
{
"code": "zidingyiliu",
"name": "自定义六",
"sort_order": 10,
"is_default": 0,
"steps": [
{
"code": "website_release",
"sort_order": 1,
"is_default": 1
}
]
}
]
SELECT * FROM `pa_config_task` WHERE (`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`is_deleted`=0)
SELECT * FROM `pa_config_task` WHERE `group_id`='015ce30b116ce86058fa6ab4fea4ac63'
SELECT * FROM `pa_config_task_step` WHERE (`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`is_deleted`=0)
SELECT * FROM `pa_config_task_step` WHERE `group_id`='015ce30b116ce86058fa6ab4fea4ac63'
SELECT DISTINCT `config_task_id` FROM `pa_plan_task` WHERE (`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`config_task_id`=23) AND (`is_deleted`=0)
SELECT EXISTS(SELECT * FROM `pa_config_task` WHERE (`pa_config_task`.`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`pa_config_task`.`code`='zidingyiliu') AND (`pa_config_task`.`is_deleted`=0) AND (`pa_config_task`.`deleted_at`=0)) // 总计 4 次执行
SELECT EXISTS(SELECT * FROM `pa_config_step` WHERE (`pa_config_step`.`code`='website_release') AND (`is_deleted`=0))
SELECT EXISTS(SELECT * FROM `pa_config_task_step` WHERE (`pa_config_task_step`.`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`pa_config_task_step`.`config_task_code`='zidingyiliu') AND (`pa_config_task_step`.`step_code`='website_release') AND (`pa_config_task_step`.`is_deleted`=0) AND (`pa_config_task_step`.`deleted_at`=0)) // 总计 5 次执行
Begin transaction
UPDATE `pa_config_task` SET `is_deleted`=1, `deleted_at`=1574755354 WHERE `id`=23
SELECT * FROM `pa_config_task` WHERE (`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`code`='tv_broadcast') // 总计 8 次执行【SELECT * FROM `pa_config_task` WHERE (`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`code`=】
UPDATE `pa_config_task` SET `is_default`=0, `updated_at`=1574755354 WHERE `id`=24
INSERT INTO `pa_config_task` (`group_id`, `code`, `name`, `sort_order`, `is_default`, `is_deleted`, `deleted_at`, `category`, `parameter`, `status`, `created_at`, `updated_at`) VALUES ('015ce30b116ce86058fa6ab4fea4ac63', 'zidingyiliu', '自定义六', 10, 0, 0, 0, 2, 's:0:\"\";', 1, 1574755354, 1574755354)
UPDATE `pa_config_task_step` SET `is_deleted`=1, `deleted_at`=1574755354 WHERE `id`=126
SELECT * FROM `pa_config_task` WHERE `group_id`='015ce30b116ce86058fa6ab4fea4ac63'
SELECT * FROM `pa_config_step` WHERE `is_deleted`=0
SELECT * FROM `pa_config_task_step` WHERE (`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`config_task_code`='tv_broadcast') AND (`step_code`='begin_shot') // 总计 29 次执行【SELECT * FROM `pa_config_task_step` WHERE (`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`config_task_code`=】
UPDATE `pa_config_task_step` SET `sort_order`=1, `updated_at`=1574755354 WHERE `id`=128
INSERT INTO `pa_config_task_step` (`group_id`, `config_task_code`, `step_code`, `sort_order`, `is_default`, `is_deleted`, `deleted_at`, `config_task_id`, `config_step_id`, `step_name`, `up_status_type`, `status`, `created_at`, `updated_at`) VALUES ('015ce30b116ce86058fa6ab4fea4ac63', 'zidingyiliu', 'website_release', 1, 1, 0, 0, 26, 15, '网站发布', 2, 1, 1574755354, 1574755354)
Commit transaction
11. Create a new method file configuration file, \api\rests\config_task\createaction.php
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace api\rests\config_task;
use Yii;
use api\models\ConfigTask;
use api\models\ConfigTaskStep;
use api\models\redis\cmc_console\User as RedisCmcConsoleUser;
use api\services\ConfigTaskStepService;
use yii\base\Model;
use yii\base\InvalidConfigException;
use yii\helpers\ArrayHelper;
use yii\web\UnprocessableEntityHttpException;
use yii\web\ServerErrorHttpException;
/**
* 新建任务配置:/config-tasks(config-task/create)
*
* For more details and usage information on CreateAction, see the [guide article on rest controllers](guide:rest-controllers).
*
* @author Qiang Wang <shuijingwanwq@163.com>
* @since 1.0
*/
class CreateAction extends Action
{
/**
* @var string the scenario to be assigned to the new model before it is validated and saved.
*/
public $scenario = Model::SCENARIO_DEFAULT;
/**
* @var string the name of the view action. This property is need to create the URL when the model is successfully created.
*/
public $viewAction = 'view';
/**
* Creates a new model.
* @return array the model newly created
* @throws InvalidConfigException if a registered parser does not implement the [[RequestParserInterface]].
* @throws ServerErrorHttpException if there is any error when creating the model
* @throws UnprocessableEntityHttpException
* @throws \Throwable
*/
public function run()
{
if ($this->checkAccess) {
call_user_func($this->checkAccess, $this->id);
}
// 当前用户的身份实例,未认证用户则为 Null
/* @var $identity RedisCmcConsoleUser */
$identity = Yii::$app->user->identity;
/* @var $modelClass ConfigTask */
$modelClass = $this->modelClass;
$requestParams = Yii::$app->getRequest()->getBodyParams();
// 检查 任务配置的(代码、名称、顺序) 是否存在
if (!ArrayHelper::keyExists('code', $requestParams) || !ArrayHelper::keyExists('name', $requestParams) || !ArrayHelper::keyExists('sort_order', $requestParams)) {
throw new UnprocessableEntityHttpException(Yii::t('error', '226080'), 226080);
}
$isDefault = isset($requestParams['is_default']) ? $requestParams['is_default'] : $modelClass::IS_DEFAULT_NO;
$status = isset($requestParams['status']) ? $requestParams['status'] : $modelClass::STATUS_ENABLED;
$configTask = [
'group_id' => $identity->group_id,
'code' => $requestParams['code'],
'name' => $requestParams['name'],
'sort_order' => $requestParams['sort_order'],
'is_default' => $isDefault,
'status' => $status,
];
$configTaskSteps = [];
// 检查 步骤配置列表 是否存在
if (ArrayHelper::keyExists('steps', $requestParams)) {
foreach ($requestParams['steps'] as $configTaskStep) {
// 检查 步骤代码、顺序、是否默认步骤 是否存在
if (!ArrayHelper::keyExists('code', $configTaskStep) || !ArrayHelper::keyExists('sort_order', $configTaskStep) || !ArrayHelper::keyExists('is_default', $configTaskStep)) {
throw new UnprocessableEntityHttpException(Yii::t('error', '226080'), 226080);
}
$configTaskSteps[$requestParams['code'] . ':' . $configTaskStep['code']] = [
'group_id' => $identity->group_id,
'config_task_code' => $requestParams['code'],
'step_code' => $configTaskStep['code'],
'sort_order' => $configTaskStep['sort_order'],
'is_default' => $configTaskStep['is_default'],
];
}
}
/* 任务配置 */
/* @var $model ConfigTask */
$model = new $modelClass([
'scenario' => $modelClass::SCENARIO_CREATE,
]);
// 把请求数据填充到模型中
if (!$model->load($configTask, '')) {
return ['code' => 226010, 'message' => Yii::t('error', '226010')];
}
// 验证模型
if (!$model->validate()) {
$modelResult = self::handleValidateError($model);
if ($modelResult['status'] === false) {
return ['code' => $modelResult['code'], 'message' => $modelResult['message']];
}
}
/* 任务步骤配置 */
$configTaskSteps = array_values($configTaskSteps);
$configTaskStepModels = [];
$count = count($configTaskSteps);
if ($count > 0) {
// 创建一个初始的 $configTaskStepModels 数组包含一个默认的模型
$configTaskStepModels = [
new ConfigTaskStep([
'scenario' => ConfigTaskStep::SCENARIO_CREATE,
])
];
for ($i = 1; $i < $count; $i++) {
$configTaskStepModels[] = new ConfigTaskStep([
'scenario' => ConfigTaskStep::SCENARIO_CREATE,
]);
}
// 批量填充模型属性
if (!Model::loadMultiple($configTaskStepModels, $configTaskSteps, '')) {
return ['code' => 226010, 'message' => Yii::t('error', '226010')];
}
// 批量验证模型
if (!Model::validateMultiple($configTaskStepModels)) {
$configTaskStepModelsResult = self::handleValidateMultipleError($configTaskStepModels);
if ($configTaskStepModelsResult['status'] === false) {
return ['code' => $configTaskStepModelsResult['code'], 'message' => $configTaskStepModelsResult['message']];
}
}
}
/* 操作数据(事务) */
$configTaskStepService = new ConfigTaskStepService();
$result = $configTaskStepService->create($model, $configTaskStepModels, $identity);
if ($result['status'] === false) {
throw new ServerErrorHttpException($result['message'], $result['code']);
}
return ['code' => 10000, 'message' => Yii::t('success', '126043')];
}
}
12. Create a new method file for updating task configuration, \api\rests\config_task\updateaction.php
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace api\rests\config_task;
use Yii;
use api\models\ConfigTask;
use api\models\ConfigTaskStep;
use api\models\redis\cmc_console\User as RedisCmcConsoleUser;
use api\services\ConfigTaskStepService;
use yii\base\Model;
use yii\base\InvalidConfigException;
use yii\helpers\ArrayHelper;
use yii\web\UnprocessableEntityHttpException;
use yii\web\ServerErrorHttpException;
/**
* 更新任务配置:/config-tasks/{id}(config-task/update)
*
* For more details and usage information on CreateAction, see the [guide article on rest controllers](guide:rest-controllers).
*
* @author Qiang Wang <shuijingwanwq@163.com>
* @since 1.0
*/
class UpdateAction extends Action
{
/**
* @var string the scenario to be assigned to the model before it is validated and updated.
* $id {config_column_id}
*/
public $scenario = Model::SCENARIO_DEFAULT;
/**
* Updates an existing model.
* @param string $id the primary key of the model.
* @return array the model being updated
* @throws InvalidConfigException if a registered parser does not implement the [[RequestParserInterface]].
* @throws ServerErrorHttpException if there is any error when updating the model
* @throws \Throwable
*/
public function run($id)
{
/* @var $model ConfigTask */
$model = $this->findModel($id);
if ($this->checkAccess) {
call_user_func($this->checkAccess, $this->id, $model);
}
// 当前用户的身份实例,未认证用户则为 Null
/* @var $identity RedisCmcConsoleUser */
$identity = Yii::$app->user->identity;
/* @var $modelClass ConfigTask */
$modelClass = $this->modelClass;
$requestParams = Yii::$app->getRequest()->getBodyParams();
$model->scenario = $model::SCENARIO_UPDATE;
// 把请求数据填充到模型中
if (!$model->load(Yii::$app->getRequest()->getBodyParams(), '')) {
return ['code' => 226010, 'message' => Yii::t('error', '226010')];
}
// 验证模型
if (!$model->validate()) {
$modelResult = self::handleValidateError($model);
if ($modelResult['status'] === false) {
return ['code' => $modelResult['code'], 'message' => $modelResult['message']];
}
}
$configTaskSteps = [];
// 检查 步骤配置列表 是否存在
if (ArrayHelper::keyExists('steps', $requestParams)) {
foreach ($requestParams['steps'] as $configTaskStep) {
// 检查 步骤代码、顺序、是否默认步骤 是否存在
if (!ArrayHelper::keyExists('code', $configTaskStep) || !ArrayHelper::keyExists('sort_order', $configTaskStep) || !ArrayHelper::keyExists('is_default', $configTaskStep)) {
throw new UnprocessableEntityHttpException(Yii::t('error', '226080'), 226080);
}
$configTaskSteps[$configTaskStep['code']] = [
'group_id' => $identity->group_id,
'config_task_code' => $model->code,
'step_code' => $configTaskStep['code'],
'sort_order' => $configTaskStep['sort_order'],
'is_default' => $configTaskStep['is_default'],
];
}
}
/* @var $configGroupTaskStepItem ConfigTaskStep */
// 基于 租户ID、任务配置ID 查找资源(任务步骤配置、是否被删除:否)列表
$configTaskStepIsDeletedNoItems = ConfigTaskStep::find()->where(['group_id' => $identity->group_id, 'config_task_id' => $model->id])->isDeletedNo()->indexBy(['step_code'])->all();
// 基于 租户ID、任务配置ID 查找资源(任务步骤配置)列表
$configTaskStepItems = ConfigTaskStep::find()->where(['group_id' => $identity->group_id, 'config_task_id' => $model->id])->indexBy(['step_code'])->all();
/* 任务步骤配置 */
// 使用键名比较计算数组的差集,如果不为空,则删除 (软删除) 出现在 任务步骤配置模型(MySQL) 中但是未出现在 任务步骤配置 中的记录
$configTaskStepDiffItems = array_diff_key($configTaskStepIsDeletedNoItems, $configTaskSteps);
$configTaskSteps = array_values($configTaskSteps);
$configTaskStepModels = [];
foreach ($configTaskSteps as $configTaskStep) {
$index = $configTaskStep['step_code'];
if (isset($configTaskStepItems[$index])) {
$configTaskStepItems[$index]->scenario = ConfigTaskStep::SCENARIO_UPDATE;
$configTaskStepModels[] = $configTaskStepItems[$index];
} else {
$configTaskStepModels[] = new ConfigTaskStep([
'scenario' => ConfigTaskStep::SCENARIO_CREATE,
]);
}
}
// 批量填充模型属性
if (!empty($configTaskStepModels) && !Model::loadMultiple($configTaskStepModels, $configTaskSteps, '')) {
return ['code' => 226010, 'message' => Yii::t('error', '226010')];
}
// 批量验证模型
if (!empty($configTaskStepModels) && !Model::validateMultiple($configTaskStepModels)) {
$configTaskStepModelsResult = self::handleValidateMultipleError($configTaskStepModels);
if ($configTaskStepModelsResult['status'] === false) {
return ['code' => $configTaskStepModelsResult['code'], 'message' => $configTaskStepModelsResult['message']];
}
}
/* 操作数据(事务) */
$configTaskStepService = new ConfigTaskStepService();
$result = $configTaskStepService->update($model, $configTaskStepDiffItems, $configTaskStepModels, $identity);
if ($result['status'] === false) {
throw new ServerErrorHttpException($result['message'], $result['code']);
}
return ['code' => 10000, 'message' => Yii::t('success', '126039')];
}
}
13. Create a new method file to delete the task configuration, \api\rests\config_task\deleteaction.php
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace api\rests\config_task;
use Yii;
use api\models\ConfigTask;
use api\models\ConfigTaskStep;
use api\services\ConfigTaskStepService;
use yii\base\Model;
use yii\web\NotFoundHttpException;
use yii\web\ServerErrorHttpException;
/**
* 删除任务配置:/config-tasks/{id}(config-task/delete)
*
* For more details and usage information on CreateAction, see the [guide article on rest controllers](guide:rest-controllers).
*
* @author Qiang Wang <shuijingwanwq@163.com>
* @since 1.0
*/
class DeleteAction extends Action
{
/**
* @var string the scenario to be assigned to the model before it is validated and updated.
*/
public $scenario = Model::SCENARIO_DEFAULT;
/**
* Updates an existing model.
* @param string $id the primary key of the model.
* @return array the model being updated
* @throws NotFoundHttpException if the model cannot be found
* @throws ServerErrorHttpException if there is any error when updating the model
* @throws \Throwable
*/
public function run($id)
{
/* @var $model ConfigTask */
$model = $this->findModel($id);
if ($this->checkAccess) {
call_user_func($this->checkAccess, $this->id, $model);
}
$model->scenario = $model::SCENARIO_DELETE;
if ($model->validate()) {
// 基于 租户ID、任务配置ID 查找资源(任务步骤配置、是否被删除:否)列表
$configTaskStepIsDeletedNoItems = ConfigTaskStep::find()->where(['group_id' => $model->group_id, 'config_task_id' => $model->id])->isDeletedNo()->all();
/* 操作数据(事务) */
$transaction = Yii::$app->db->beginTransaction();
try {
if ($model->softDelete() === false) {
throw new ServerErrorHttpException('Failed to delete the object for unknown reason.');
}
// 删除 (软删除) 出现在 任务步骤配置模型(MySQL) 中的记录
$configTaskStepService = new ConfigTaskStepService();
$configTaskStepService->deleteMultiple($configTaskStepIsDeletedNoItems);
$transaction->commit();
} catch(\Throwable $e) {
$transaction->rollBack();
throw $e;
}
} elseif ($model->hasErrors()) {
$response = Yii::$app->getResponse();
$response->setStatusCode(422, 'Data Validation Failed.');
$firstError = '';
foreach ($model->getFirstErrors() as $message) {
$firstError = $message;
break;
}
return ['code' => 226004, 'message' => Yii::t('error', Yii::t('error', Yii::t('error', '226004'), ['first_error' => $firstError]))];
} elseif (!$model->hasErrors()) {
throw new ServerErrorHttpException('Failed to create the object for unknown reason.');
}
return ['code' => 10000, 'message' => Yii::t('success', '126045')];
}
}
14. In Postman POST:http://api.pcs-api.localhost/v1/config-tasks, request data and execution SQL (task configuration table: 1 insert statement, 1 update statement; task step configuration table: 2 insert statement) as follows
{
"code": "zidingyiqi",
"name": "自定义七",
"sort_order": 11,
"is_default": 1,
"status": 1,
"steps": [
{
"code": "begin_shot",
"sort_order": 1,
"is_default": 1
},
{
"code": "writing",
"sort_order": 2,
"is_default": 1
}
]
}
SELECT EXISTS(SELECT * FROM `pa_config_task` WHERE (`pa_config_task`.`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`pa_config_task`.`code`='zidingyiqi') AND (`pa_config_task`.`is_deleted`=0) AND (`pa_config_task`.`deleted_at`=0)) // 总计 4 次执行
SELECT EXISTS(SELECT * FROM `pa_config_step` WHERE (`pa_config_step`.`code`='begin_shot') AND (`is_deleted`=0)) // 总计 2 次执行【SELECT EXISTS(SELECT * FROM `pa_config_step` WHERE (`pa_config_step`.`code`=】
SELECT EXISTS(SELECT * FROM `pa_config_task_step` WHERE (`pa_config_task_step`.`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`pa_config_task_step`.`config_task_code`='zidingyiqi') AND (`pa_config_task_step`.`step_code`='begin_shot') AND (`pa_config_task_step`.`is_deleted`=0) AND (`pa_config_task_step`.`deleted_at`=0)) // 总计 10 次执行【SELECT EXISTS(SELECT * FROM `pa_config_task_step` WHERE (`pa_config_task_step`.`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`pa_config_task_step`.`config_task_code`='zidingyiqi') AND (`pa_config_task_step`.`step_code`=】
Begin transaction
INSERT INTO `pa_config_task` (`group_id`, `code`, `name`, `sort_order`, `is_default`, `status`, `is_deleted`, `deleted_at`, `category`, `parameter`, `created_at`, `updated_at`) VALUES ('015ce30b116ce86058fa6ab4fea4ac63', 'zidingyiqi', '自定义七', 11, 1, 1, 0, 0, 2, 's:0:\"\";', 1574756713, 1574756713)
UPDATE `pa_config_task` SET `is_default`=0 WHERE (`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`is_deleted`=0) AND (`id` != 27)
SELECT * FROM `pa_config_task` WHERE `group_id`='015ce30b116ce86058fa6ab4fea4ac63'
SELECT * FROM `pa_config_step` WHERE `is_deleted`=0
INSERT INTO `pa_config_task_step` (`group_id`, `config_task_code`, `step_code`, `sort_order`, `is_default`, `is_deleted`, `deleted_at`, `config_task_id`, `config_step_id`, `step_name`, `up_status_type`, `status`, `created_at`, `updated_at`) VALUES ('015ce30b116ce86058fa6ab4fea4ac63', 'zidingyiqi', 'begin_shot', 1, 1, 0, 0, 27, 2, '上传素材', 2, 1, 1574756713, 1574756713)
INSERT INTO `pa_config_task_step` (`group_id`, `config_task_code`, `step_code`, `sort_order`, `is_default`, `is_deleted`, `deleted_at`, `config_task_id`, `config_step_id`, `step_name`, `up_status_type`, `status`, `created_at`, `updated_at`) VALUES ('015ce30b116ce86058fa6ab4fea4ac63', 'zidingyiqi', 'writing', 2, 1, 0, 0, 27, 4, '撰写稿件', 2, 1, 1574756713, 1574756713)
Commit transaction
15. Put in Postman:http://api.pcs-api.localhost/v1/config-tasks/27, request data and execution SQL (task configuration table: 2 update statements; task step configuration table: 2 insert statements, 2 update statements) as follows
{
"name": "自定义七",
"sort_order": 11,
"is_default": 1,
"status": 0,
"steps": [
{
"code": "writing",
"sort_order": 1,
"is_default": 0
},
{
"code": "website_release",
"sort_order": 2,
"is_default": 1
},
{
"code": "wechat_release",
"sort_order": 3,
"is_default": 1
}
]
}
SELECT * FROM `pa_config_task` WHERE (`id`='27') AND (`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`is_deleted`=0)
SELECT * FROM `pa_config_task_step` WHERE ((`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`config_task_id`=27)) AND (`is_deleted`=0)
SELECT * FROM `pa_config_task_step` WHERE (`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`config_task_id`=27)
SELECT EXISTS(SELECT * FROM `pa_config_step` WHERE (`pa_config_step`.`code`='website_release') AND (`is_deleted`=0)) // 总计 2 次执行【SELECT EXISTS(SELECT * FROM `pa_config_step` WHERE (`pa_config_step`.`code`=】
SELECT EXISTS(SELECT * FROM `pa_config_task_step` WHERE (`pa_config_task_step`.`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`pa_config_task_step`.`config_task_code`='zidingyiqi') AND (`pa_config_task_step`.`step_code`='website_release') AND (`pa_config_task_step`.`is_deleted`=0) AND (`pa_config_task_step`.`deleted_at`=0)) // 总计 10 次执行【SELECT EXISTS(SELECT * FROM `pa_config_task_step` WHERE (`pa_config_task_step`.`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`pa_config_task_step`.`config_task_code`=】
Begin transaction
UPDATE `pa_config_task` SET `status`=0, `updated_at`=1574757171 WHERE `id`=27
UPDATE `pa_config_task` SET `is_default`=0 WHERE (`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`is_deleted`=0) AND (`id` != 27)
UPDATE `pa_config_task_step` SET `is_deleted`=1, `deleted_at`=1574757171 WHERE `id`=131
SELECT * FROM `pa_config_task` WHERE `group_id`='015ce30b116ce86058fa6ab4fea4ac63'
SELECT * FROM `pa_config_step` WHERE `is_deleted`=0
SELECT * FROM `pa_config_task_step` WHERE (`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`config_task_code`='zidingyiqi') AND (`step_code`='writing') // 总计 3 次执行【SELECT * FROM `pa_config_task_step` WHERE (`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`config_task_code`=】
UPDATE `pa_config_task_step` SET `sort_order`=1, `is_default`=0, `updated_at`=1574757171 WHERE `id`=132
INSERT INTO `pa_config_task_step` (`group_id`, `config_task_code`, `step_code`, `sort_order`, `is_default`, `is_deleted`, `deleted_at`, `config_task_id`, `config_step_id`, `step_name`, `up_status_type`, `status`, `created_at`, `updated_at`) VALUES ('015ce30b116ce86058fa6ab4fea4ac63', 'zidingyiqi', 'website_release', 2, 1, 0, 0, 27, 15, '网站发布', 2, 1, 1574757171, 1574757171)
INSERT INTO `pa_config_task_step` (`group_id`, `config_task_code`, `step_code`, `sort_order`, `is_default`, `is_deleted`, `deleted_at`, `config_task_id`, `config_step_id`, `step_name`, `up_status_type`, `status`, `created_at`, `updated_at`) VALUES ('015ce30b116ce86058fa6ab4fea4ac63', 'zidingyiqi', 'wechat_release', 3, 1, 0, 0, 27, 18, '微信发布', 2, 1, 1574757171, 1574757171)
Commit transaction
16. Delete in Postman:http://api.pcs-api.localhost/v1/config-tasks/27, the execution SQL (task configuration table: 1 update statement; task step configuration table: 3 update statements) as follows
SELECT * FROM `pa_config_task` WHERE (`id`='27') AND (`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`is_deleted`=0)
SELECT DISTINCT `config_task_id` FROM `pa_plan_task` WHERE (`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`config_task_id`=27) AND (`is_deleted`=0)
SELECT `pa_config_task`.`id` FROM `pa_config_task` WHERE (`pa_config_task`.`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`pa_config_task`.`code`='zidingyiqi') AND (`pa_config_task`.`is_deleted`=0) AND (`pa_config_task`.`deleted_at`=0) LIMIT 2 // 总计 4 次执行【SELECT `pa_config_task`.`id` FROM `pa_config_task` WHERE (`pa_config_task`.`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`pa_config_task`.`code`=】
SELECT * FROM `pa_config_task_step` WHERE ((`group_id`='015ce30b116ce86058fa6ab4fea4ac63') AND (`config_task_id`=27)) AND (`is_deleted`=0)
Begin transaction
UPDATE `pa_config_task` SET `is_deleted`=1, `deleted_at`=1574757947 WHERE `id`=27
UPDATE `pa_config_task_step` SET `is_deleted`=1, `deleted_at`=1574757947 WHERE `id`=133
UPDATE `pa_config_task_step` SET `is_deleted`=1, `deleted_at`=1574757947 WHERE `id`=134
UPDATE `pa_config_task_step` SET `is_deleted`=1, `deleted_at`=1574757947 WHERE `id`=132
Commit transaction

