From: Vladimir Fomichev Date: Fri, 5 Sep 2025 13:45:14 +0000 (+0300) Subject: Создаем дерево X-Git-Url: https://gitweb.erp-flowers.ru/?a=commitdiff_plain;h=50933fd52d63748f9f166a24f1715e08f3c59723;p=erp24_rep%2Fyii-erp24%2F.git Создаем дерево --- diff --git a/erp24/controllers/MatrixTypeController.php b/erp24/controllers/MatrixTypeController.php index 0c317592..389ee1d2 100644 --- a/erp24/controllers/MatrixTypeController.php +++ b/erp24/controllers/MatrixTypeController.php @@ -92,6 +92,50 @@ class MatrixTypeController extends Controller ]); } + public function actionUpdateName($id) + { + Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; + $model = $this->findModel($id); + if (!$model) { + return ['success'=>false,'message'=>'Не найдено']; + } + $model->load(Yii::$app->request->post(), ''); + if ($model->save()) { + return ['success'=>true,'data'=>['name'=>$model->name]]; + } + return ['success'=>false,'message'=>current($model->getFirstErrors()) ?: 'Ошибка сохранения']; + } + + public function actionCreateChild($parent_id) + { + Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; + $child = new MatrixType(); + $child->load(Yii::$app->request->post(), ''); + $child->parent_id = (int)$parent_id; + + if ($child->save()) { + return ['success'=>true,'data'=>['id'=>$child->id, 'name'=>$child->name]]; + } + return ['success'=>false,'message'=>current($child->getFirstErrors()) ?: 'Ошибка создания']; + } + + public function actionToggleActive() + { + Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; + $id = Yii::$app->request->post('id'); + $active = Yii::$app->request->post('active'); + + $model = $this->findModel($id); + if (!$model) { + return ['success' => false, 'message' => 'Не найдено']; + } + + $model->active = (int)$active; + if ($model->save(false)) { + return ['success' => true]; + } + return ['success' => false, 'message' => 'Не удалось сохранить']; + } /** * Deletes an existing MatrixType model. * If deletion is successful, the browser will be redirected to the 'index' page. diff --git a/erp24/migrations/m250905_090045_add_parentid_active_fields_to_matrix_type_table.php b/erp24/migrations/m250905_090045_add_parentid_active_fields_to_matrix_type_table.php new file mode 100644 index 00000000..e2b70c18 --- /dev/null +++ b/erp24/migrations/m250905_090045_add_parentid_active_fields_to_matrix_type_table.php @@ -0,0 +1,61 @@ +db->schema->getTableSchema(self::TABLE_NAME); + if ($table === null) { + return; + } + + if (!$this->db->schema->getTableSchema(self::TABLE_NAME, true)->getColumn('parent_id')) { + $this->addColumn( + self::TABLE_NAME, + 'parent_id', + $this->integer()->null()->comment('id записи родителя') + ); + } + if (!$this->db->schema->getTableSchema(self::TABLE_NAME, true)->getColumn('active')) { + $this->addColumn( + self::TABLE_NAME, + 'active', + $this->tinyInteger()->notNull()->defaultValue(1)->comment('активность') + ); + } + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + if ($this->db->schema->getTableSchema(self::TABLE_NAME, true)->getColumn('parent_id')) { + $this->dropColumn(self::TABLE_NAME, 'parent_id'); + } + if ($this->db->schema->getTableSchema(self::TABLE_NAME, true)->getColumn('active')) { + $this->dropColumn(self::TABLE_NAME, 'active'); + } + } + + /* + // Use up()/down() to run migration code without a transaction. + public function up() + { + + } + + public function down() + { + echo "m250905_090045_add_parentid_active_fields_to_matrix_type_table cannot be reverted.\n"; + + return false; + } + */ +} diff --git a/erp24/records/MatrixType.php b/erp24/records/MatrixType.php index a61304bc..0709aa18 100644 --- a/erp24/records/MatrixType.php +++ b/erp24/records/MatrixType.php @@ -10,6 +10,8 @@ use yii\db\Expression; * This is the model class for table "erp24.matrix_type". * * @property int $id + * @property int|null $parent_id id родительской категории - null - корневая + * @property int $active активность (0,1) по умолчанию - 1 - активная запись * @property string $name * @property int $created_by * @property string $created_at @@ -50,11 +52,26 @@ class MatrixType extends \yii\db\ActiveRecord { return [ [['name'], 'filter', 'filter' => 'trim'], - [['name'], 'unique', 'targetAttribute' => ['name'], 'message' => 'Имя матрицы уже используется'], [['name'], 'required'], - [['created_by', 'updated_by'], 'integer'], + [['created_by', 'updated_by', 'active', 'parent_id'], 'integer'], [['created_at', 'updated_at'], 'safe'], [['name'], 'string', 'max' => 255], + // Уникальность имени в рамках одной группы + [ + ['name', 'parent_id'], + 'unique', + 'targetAttribute' => ['name', 'parent_id'], + 'message' => 'Подгруппа с таким названием уже существует в этой группе.', + ], + + // Уникальность имени для групп (без parent_id) + [ + 'name', + 'unique', + 'targetAttribute' => 'name', + 'filter' => ['parent_id' => null], + 'message' => 'Группа с таким названием уже существует.', + ], ]; } @@ -66,6 +83,8 @@ class MatrixType extends \yii\db\ActiveRecord return [ 'id' => 'ID', 'name' => 'Название типа матрицы', + 'parent_id' => 'Родительская категория', + 'active' => 'Активность', 'created_by' => 'ИД создателя', 'created_at' => 'Дата создания', 'updated_by' => 'ИД редактировавшего', diff --git a/erp24/views/matrix-type/index.php b/erp24/views/matrix-type/index.php index 1ca95c95..31527777 100644 --- a/erp24/views/matrix-type/index.php +++ b/erp24/views/matrix-type/index.php @@ -1,13 +1,16 @@ title = 'Типы матриц'; $this->params['breadcrumbs'][] = $this->title; +$this->registerJsFile('/js/matrix-type/index.js', ['position' => \yii\web\View::POS_END]); ?>
@@ -17,18 +20,159 @@ $this->params['breadcrumbs'][] = $this->title; 'btn btn-success']) ?>

- $dataProvider, +// 'filterModel' => null, +// 'columns' => [ +// 'id', +// 'name', +// 'created_at', +// 'updated_at', +// [ +// 'class' => 'yii\grid\ActionColumn', +// 'template' => '{update} {delete}', +// ], +// ], +// ]); ?> + + $dataProvider, - 'filterModel' => null, + 'keyColumnName' => 'id', + 'showOnEmpty' => FALSE, + 'parentColumnName' => 'parent_id', 'columns' => [ - 'id', - 'name', - 'created_at', - 'updated_at', + + //'name', + [ + 'attribute' => 'name', + 'format' => 'raw', + 'value' => function ($model) { + $id = (int)$model->id; + $editModalId = "editModal-$id"; + $createModalId = "createModal-$id"; + + $editUrl = Url::to(['matrix-type/update-name', 'id' => $id]); + $createUrl = Url::to(['matrix-type/create-child', 'parent_id' => $id]); + + ob_start(); ?> + +
+
+ + + + +
+
+ + + + + + + + + 'yii\grid\ActionColumn', - 'template' => '{update} {delete}', + 'attribute' => 'active', + 'format' => 'raw', + 'value' => function ($model) { + return \yii\helpers\Html::checkbox( + 'active[' . $model->id . ']', + $model->active == 1, + [ + 'class' => 'js-toggle-active', + 'data-id' => $model->id, + ] + ); + }, + 'contentOptions' => ['class' => 'text-center', 'style' => 'width:80px; min-width:50px; '], ], - ], - ]); ?> + + ['class' => 'yii\grid\ActionColumn', + 'template' => '{delete}', + 'contentOptions' => ['class' => 'text-center', 'style' => 'width:80px; min-width:50px; '], + 'buttons' => [ + 'delete' => function ($url, $model, $key) + { + return Html::a('', + $url, + [ + 'title' => "Удалить", + 'data' => [ + 'method' => 'post', + 'confirm' => 'Вы уверены, что хотите удалить этот элемент?', + ] + ]); + }, + ] + ] + ] + ]); + ?>
diff --git a/erp24/web/js/matrix-type/index.js b/erp24/web/js/matrix-type/index.js new file mode 100644 index 00000000..62036bd8 --- /dev/null +++ b/erp24/web/js/matrix-type/index.js @@ -0,0 +1,103 @@ +(function(){ + function setError(form, msg){ + var $box = $(form).find('.js-form-error'); + if(!$box.length) return; + if(!msg){ $box.addClass('d-none').text(''); return; } + $box.removeClass('d-none').text(msg); + } + + $(document).on('submit', '.ajax-form', function(e){ + e.preventDefault(); + var $form = $(this); + setError($form[0], null); + + var action = $form.data('action'); + var mode = $form.data('success'); + var id = $form.data('id'); + var parentId = $form.data('parent-id'); + + var dataArr = $form.serializeArray(); + + + dataArr.push({ + name: yii.getCsrfParam(), + value: yii.getCsrfToken() + }); + + if (id && !$form.find('[name="id"]').length) { + dataArr.push({name: 'id', value: id}); + } + if (parentId && !$form.find('[name="parent_id"]').length) { + dataArr.push({name: 'parent_id', value: parentId}); + } + + var $submitBtn = $form.find('button[type="submit"]').prop('disabled', true); + + $.ajax({ + url: action, + type: 'POST', + data: $.param(dataArr), + dataType: 'json', + headers: { 'X-Requested-With':'XMLHttpRequest' }, + success: function(json){ + if (!json || json.success !== true) { + setError($form[0], (json && json.message) ? json.message : 'Ошибка сохранения'); + return; + } + + if (mode === 'rename') { + var label = document.getElementById('nameLabel-' + id); + var newName = (json.data && json.data.name) ? json.data.name : $form.find('[name="name"]').val(); + if (label && newName) { label.textContent = newName; } + } else if (mode === 'created') { + if ($.pjax) { + $.pjax.reload({container:'#pjaxtable', async:false}); + } else { + location.reload(); + } + } + + // закрыть модалку + var modalEl = $form.closest('.modal')[0]; + if (modalEl) { + var modal = bootstrap.Modal.getInstance(modalEl) || new bootstrap.Modal(modalEl); + modal.hide(); + $form[0].reset(); + setError($form[0], null); + } + }, + error: function(){ + setError($form[0], 'Сеть/сервер недоступен'); + }, + complete: function(){ + $submitBtn.prop('disabled', false); + } + }); + }); + + $(document).on('change', '.js-toggle-active', function () { + var checkbox = $(this); + var id = checkbox.data('id'); + var active = checkbox.is(':checked') ? 1 : 0; + + $.ajax({ + url: '/matrix-type/toggle-active', + type: 'POST', + data: { + id: id, + active: active, + _csrf: yii.getCsrfToken() + }, + success: function (res) { + if (!res.success) { + alert('Ошибка: ' + res.message); + checkbox.prop('checked', !active); + } + }, + error: function () { + alert('Ошибка сервера'); + checkbox.prop('checked', !active); + } + }); + }); +})();