]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
Мягкое удаление
authorVladimir Fomichev <vladimir.fomichev@erp-flowers.ru>
Mon, 8 Sep 2025 10:35:43 +0000 (13:35 +0300)
committerVladimir Fomichev <vladimir.fomichev@erp-flowers.ru>
Mon, 8 Sep 2025 10:35:43 +0000 (13:35 +0300)
erp24/controllers/MatrixTypeController.php
erp24/migrations/m250905_090045_add_parentid_active_fields_to_matrix_type_table.php
erp24/records/MatrixType.php
erp24/records/MatrixTypeSearch.php
erp24/views/matrix-type/index.php
erp24/web/css/matrix-type/index.css [new file with mode: 0644]
erp24/web/js/matrix-type/index.js

index 9d346ce64d1a52f2bb5d678cbad0f0f71e5eedce..ed4e5d16ef4ab1daf7e512a366ca71ddefd894ae 100644 (file)
@@ -116,6 +116,7 @@ class MatrixTypeController extends Controller
         $child->parent_id = (int)$parent_id;
 
         if ($child->save()) {
+            Yii::$app->session->setFlash('success', 'Запись создана', false);
             return ['success'=>true,'data'=>['id'=>$child->id, 'name'=>$child->name]];
         }
         return ['success'=>false,'message'=>current($child->getFirstErrors()) ?: 'Ошибка создания'];
@@ -129,6 +130,7 @@ class MatrixTypeController extends Controller
 
         $model = $this->findModel($id);
         if (!$model) {
+            Yii::$app->session->setFlash('error', 'Ошибка изменения активности');
             return ['success' => false, 'message' => 'Не найдено'];
         }
 
@@ -138,6 +140,7 @@ class MatrixTypeController extends Controller
         try {
             $model->active = $active;
             if (!$model->save(false)) {
+                Yii::$app->session->setFlash('error', 'Ошибка изменения активности');
                 throw new \RuntimeException('Не удалось сохранить узел');
             }
 
@@ -146,10 +149,12 @@ class MatrixTypeController extends Controller
             }
 
             $transaction->commit();
-            return ['success' => true];
+            Yii::$app->session->setFlash('success', 'Активность записей изменена', false);
+            return ['success' => true, 'message' => 'Активность записей изменена'];
 
         } catch (Throwable $e) {
             $transaction->rollBack();
+            Yii::$app->session->setFlash('error', 'Ошибка изменения активности');
             Yii::error($e->getMessage(), 'matrix-type.toggle-active');
             return ['success' => false, 'message' => 'Ошибка при сохранении'];
         }
@@ -202,6 +207,7 @@ class MatrixTypeController extends Controller
     {
         $model = $this->findModel($id);
         if (!$model) {
+            Yii::$app->session->setFlash('error', 'Запись не найдена');
             return $this->redirect(['index']);
         }
 
@@ -219,9 +225,11 @@ class MatrixTypeController extends Controller
             }
 
             $transaction->commit();
+            Yii::$app->session->setFlash('success', 'Записи удалены');
             return $this->redirect(['index']);
         } catch (\Throwable $e) {
             $transaction->rollBack();
+            Yii::$app->session->setFlash('error', 'Ошибка удаления записей');
             Yii::error($e->getMessage(), 'matrix-type.soft-delete');
             return $this->redirect(['index']);
         }
@@ -235,6 +243,7 @@ class MatrixTypeController extends Controller
             'deleted_by' => $uid,
             'deleted_at' => $now,
             'active'     => 0,
+            'deleted'     => 1,
         ]);
         if ($result === false) {
             Yii::error("Ошибка сохранения " . json_encode($matrixType->getErrors(), JSON_UNESCAPED_UNICODE));
@@ -263,7 +272,7 @@ class MatrixTypeController extends Controller
      */
     protected function findModel($id)
     {
-        if (($model = MatrixType::find()->where(['id' => $id])->andWhere(['deleted_at' => null])->one()) !== null) {
+        if (($model = MatrixType::find()->where(['id' => $id])->andWhere(['deleted' => 0])->one()) !== null) {
             return $model;
         }
 
index 08db8437e39e01422a13005d4d452c389a89818d..16236ffd36a72cc21fd212a8ac7b9400c96058e8 100644 (file)
@@ -43,6 +43,13 @@ class m250905_090045_add_parentid_active_fields_to_matrix_type_table extends Mig
                 $this->timestamp()->defaultValue(null)->comment('дата удаления')
             );
         }
+        if (!$this->db->schema->getTableSchema(self::TABLE_NAME, true)->getColumn('deleted')) {
+            $this->addColumn(
+                self::TABLE_NAME,
+                'deleted',
+                $this->tinyInteger()->notNull()->defaultValue(0)->comment('признак удаленного элемента')
+            );
+        }
     }
 
     /**
@@ -61,6 +68,8 @@ class m250905_090045_add_parentid_active_fields_to_matrix_type_table extends Mig
         }
         if ($this->db->schema->getTableSchema(self::TABLE_NAME, true)->getColumn('deleted_at')) {
             $this->dropColumn(self::TABLE_NAME, 'deleted_at');
+        }if ($this->db->schema->getTableSchema(self::TABLE_NAME, true)->getColumn('deleted')) {
+            $this->dropColumn(self::TABLE_NAME, 'deleted');
         }
     }
 
index 4fdeebeb3fea5893a568bff96f059b0cd9f69342..2af17a876900a3a50ad3675576763103471128ac 100644 (file)
@@ -1,7 +1,6 @@
 <?php
 namespace yii_app\records;
 
-use Yii;
 use yii\behaviors\BlameableBehavior;
 use yii\behaviors\TimestampBehavior;
 use yii\db\Expression;
@@ -16,6 +15,9 @@ use yii\db\Expression;
  * @property int $created_by
  * @property string $created_at
  * @property int|null $updated_by
+ * @property int $deleted Признак (флаг) удаления
+ * @property int|null $deleted_by ИД пользователя осуществившего удаление
+ * @property string|null $deleted_at Дата удаления
  * @property string|null $updated_at
  */
 class MatrixType extends \yii\db\ActiveRecord
@@ -53,8 +55,8 @@ class MatrixType extends \yii\db\ActiveRecord
         return [
             [['name'], 'filter', 'filter' => 'trim'],
             [['name'], 'required'],
-            [['created_by', 'updated_by', 'active', 'parent_id'], 'integer'],
-            [['created_at', 'updated_at'], 'safe'],
+            [['created_by', 'updated_by', 'deleted_by', 'active', 'parent_id', 'deleted'], 'integer'],
+            [['created_at', 'updated_at', 'deleted_at'], 'safe'],
             [['name'], 'string', 'max' => 255],
             // Уникальность имени в рамках одной группы
             [
@@ -78,10 +80,13 @@ class MatrixType extends \yii\db\ActiveRecord
             'name' => 'Название типа матрицы',
             'parent_id' => 'Родительская категория',
             'active' => 'Активность',
+            'deleted' => 'Удалено',
             'created_by' => 'ИД создателя',
             'created_at' => 'Дата создания',
             'updated_by' => 'ИД редактировавшего',
             'updated_at' => 'Дата обновления',
+            'deleted_by' => 'ИД удалившего',
+            'deleted_at' => 'Дата обновления',
         ];
     }
 
index a4fe7421d5b3d5a62a3af7bf3c522c4818501876..51f581d6b337b1130b6f0fe197038029dbb9d782 100644 (file)
@@ -21,7 +21,7 @@ class MatrixTypeSearch extends MatrixType
         $this->load($params, '');
 
         $allTypes = MatrixType::find()
-            ->andWhere(['deleted_at' => null])
+            ->andWhere(['deleted' => 0])
             ->orderBy(['parent_id' => SORT_ASC, 'id' => SORT_ASC])
             ->all();
 
index 49bfa268bdeb650f929e44e64f2505c763c17939..09656b18e3fc54a2400104ba04e9075851e0dd60 100644 (file)
@@ -11,10 +11,26 @@ use yii\widgets\ActiveForm;
 
 $this->title = 'Управление категориями букетов';
 $this->params['breadcrumbs'][] = $this->title;
+
+$this->registerCssFile(Yii::getAlias('@web') . '/css/matrix-type/index.css');
 $this->registerJsFile('/js/matrix-type/index.js', ['position' => \yii\web\View::POS_END]);
+
 ?>
 <div class="matrix-type-index p-3">
+    <?php if (Yii::$app->session->hasFlash('success')): ?>
+        <div class="alert alert-success alert-dismissible fade show" role="alert">
+            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">×</button>
+            <?= Yii::$app->session->getFlash('success') ?>
+        </div>
+    <?php endif; ?>
 
+
+    <?php if (Yii::$app->session->hasFlash('error')): ?>
+        <div class="alert alert-success alert-dismissible fade show" role="alert">
+            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">×</button>
+            <?= Yii::$app->session->getFlash('error') ?>
+        </div>
+    <?php endif; ?>
     <h1><?= Html::encode($this->title) ?></h1>
 
     <div class="d-flex justify-content-between mb-4">
diff --git a/erp24/web/css/matrix-type/index.css b/erp24/web/css/matrix-type/index.css
new file mode 100644 (file)
index 0000000..0341ac8
--- /dev/null
@@ -0,0 +1,14 @@
+.loading-spinner {
+    display: inline-block;
+    width: 16px;
+    height: 16px;
+    border: 2px solid #ccc;
+    border-top: 2px solid #333;
+    border-radius: 50%;
+    animation: spin 0.6s linear infinite;
+    margin-left: 6px;
+}
+
+@keyframes spin {
+    100% { transform: rotate(360deg); }
+}
index ec2408e0a8d26ccb730c1ebf82c2d5fad1c8d112..23c4451779e9efa52c75e9780877f43fe102cf13 100644 (file)
@@ -80,6 +80,9 @@
         var id = checkbox.data('id');
         var active = checkbox.is(':checked') ? 1 : 0;
 
+        var spinner = $('<span class="loading-spinner"></span>');
+        checkbox.after(spinner);
+
         $.ajax({
             url: '/matrix-type/toggle-active',
             type: 'POST',
                     checkbox.prop('checked', !active);
                     return;
                 }
+                var row = checkbox.closest('tr');
+                if (active === 0) {
+                    row.css('background', '#ffecec');
+                } else {
+                    row.css('background', '');
+                }
+                var alertBox = $('<div class="alert alert-success alert-dismissible fade show" role="alert">'
+                    + res.message +
+                    '<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">×</button>' +
+                    '</div>');
+                $('.matrix-type-index').prepend(alertBox);
 
                 if (active === 0 && checkbox.closest('tr').find('td:first').text().trim() !== '') {
                     var nodeId = id;
             error: function () {
                 alert('Ошибка сервера');
                 checkbox.prop('checked', !active);
+            },
+            complete: function () {
+                spinner.remove();
             }
         });
     });