Магазин на Yii2, часть 25. Админка: главная страница и работа с заказами
30.08.2019
Теги: Web-разработка • Yii2 • Заказ • ИнтернетМагазин • КаталогТоваров • ПанельУправления • Практика • Фреймворк
Главная страница
На главной странице панели управления будем показывать две таблицы — новые заказы и заказы в работе. Чтобы администратор магазина сразу видел, какие заказы надо обработать, у каких — отслеживать оплату и доставку, а какие — можно завершать. Итак, вносим изменения в контроллер DefaultController
и view-шаболон default/index.php
.
<?php namespace app\modules\admin\controllers; use yii\data\ActiveDataProvider; use app\modules\admin\models\Order; class DefaultController extends AdminController { public function actionIndex() { $queueOrders = new ActiveDataProvider([ 'query' => Order::find() ->where(['status' => 0]) ->orderBy(['created' => SORT_ASC]), 'sort' => false, 'pagination' => [ // три заказа на страницу 'pageSize' => 3, // уникальный параметр пагинации 'pageParam' => 'queue', ] ]); $processOrders = new ActiveDataProvider([ 'query' => Order::find() ->where(['IN', 'status', [1,2,3]]) ->orderBy(['updated' => SORT_ASC]), 'sort' => false, 'pagination' => [ // три заказа на страницу 'pageSize' => 3, // уникальный параметр пагинации 'pageParam' => 'process', ] ]); return $this->render('index', [ 'queueOrders' => $queueOrders, 'processOrders' => $processOrders, ]); } }
Поскольку на главной странице у нас две таблицы GridView
, при переходе на вторую страницу списка новых заказов или списка заказов в работе, будет происходить переход на вторую страницу сразу для двух списков. Поэтому надо задать для каждого списка уникальный параметр пагинации pageParam
. Тогда ссылки на вторую страницу для первого и второго списков будут иметь вид:
http://www.server.com/admin/default/index?queue=2&per-page=3 http://www.server.com/admin/default/index?process=2&per-page=3
<?php /* * Файл view-шаблона modules/admin/views/default/index.php */ use yii\helpers\Html; use yii\grid\GridView; /* @var $this yii\web\View */ /* @var $queueOrders yii\data\ActiveDataProvider */ /* @var $processOrders yii\data\ActiveDataProvider */ $this->title = 'Текущее состояние'; ?> <h1><?= Html::encode($this->title) ?></h1> <h2>Новые заказы</h2> <?= GridView::widget([ 'dataProvider' => $queueOrders, 'columns' => [ ['class' => 'yii\grid\SerialColumn'], 'id', 'name', 'email:email', 'phone', 'amount', [ 'attribute' => 'status', 'value' => function ($data) { switch ($data->status) { case 0: return '<span class="text-danger">Новый</span>'; case 1: return '<span class="text-warning">Обработан</span>'; case 2: return '<span class="text-warning">Оплачен</span>'; case 3: return '<span class="text-warning">Доставлен</span>'; case 4: return '<span class="text-success">Завершен</span>'; default: return 'Ошибка'; } }, 'format' => 'html' ], 'created', 'updated' ], ]); ?> <h2>Заказы в работе</h2> <?= GridView::widget([ 'dataProvider' => $processOrders, 'columns' => [ ['class' => 'yii\grid\SerialColumn'], 'id', 'name', 'email:email', 'phone', 'amount', [ 'attribute' => 'status', 'value' => function ($data) { switch ($data->status) { case 0: return '<span class="text-danger">Новый</span>'; case 1: return '<span class="text-warning">Обработан</span>'; case 2: return '<span class="text-warning">Оплачен</span>'; case 3: return '<span class="text-warning">Доставлен</span>'; case 4: return '<span class="text-success">Завершен</span>'; default: return 'Ошибка'; } }, 'format' => 'html' ], 'created', 'updated' ], ]); ?>
Работа с заказами
Сейчас при просмотре заказа мы видим только данные покупателя, дату создания и обновления заказа. Но на странице просмотра нет данных о составе заказа. Давайте это исправим: создадим модель OrderItem
и добавим в класс модели Order
метод getItems()
:
<?php namespace app\modules\admin\models; use yii\db\ActiveRecord; class OrderItem extends ActiveRecord { /** * Возвращает имя таблицы БД */ public static function tableName() { return 'order_item'; } /** * Позволяет получить заказ, в который входит этот элемент */ public function getOrder() { // связь таблицы БД `order_item` с таблицей `order` return $this->hasOne(Order::class, ['id' => 'order_id']); } }
<?php namespace app\modules\admin\models; use yii\db\ActiveRecord; class Order extends ActiveRecord { /*...*/ /** * Позволяет получить все товары заказа */ public function getItems() { // связь таблицы БД `order` с таблицей `order_item` return $this->hasMany(OrderItem::class, ['order_id' => 'id']); } }
В представлении получим список товаров заказа и покажем таблицу:
<?php /* * Файл view-шаблона modules/admin/views/order/view.php */ use yii\helpers\Html; use yii\widgets\DetailView; /* @var $this yii\web\View */ /* @var $model app\modules\admin\models\Order */ $this->title = 'Просмотр заказа № ' . $model->id; ?> <h1><?= Html::encode($this->title); ?></h1> <p> <?= Html::a( 'Изменить', ['update', 'id' => $model->id], ['class' => 'btn btn-primary'] ); ?> <?= Html::a( 'Удалить', ['delete', 'id' => $model->id], [ 'class' => 'btn btn-danger', 'data' => [ 'confirm' => 'Вы уверены, что хотите удалить заказ?', 'method' => 'post', ], ] ); ?> </p> <?= DetailView::widget([ 'model' => $model, 'attributes' => [ [ 'attribute' => 'status', 'value' => function ($data) { switch ($data->status) { case 0: return '<span class="text-danger">Новый</span>'; case 1: return '<span class="text-warning">Обработан</span>'; case 2: return '<span class="text-warning">Оплачен</span>'; case 3: return '<span class="text-warning">Доставлен</span>'; case 4: return '<span class="text-success">Завершен</span>'; default: return 'Ошибка'; } }, 'format' => 'html' ], 'name', 'email:email', 'phone', 'address', 'comment', 'created', 'updated' ], ]); ?> <?php $products = $model->items; ?> <table class="table table-bordered table-striped"> <tr> <th>Наименование</th> <th>Количество</th> <th>Цена</th> <th>Сумма</th> </tr> <?php foreach ($products as $product): ?> <tr> <td><?= $product->name; ?></td> <td class="text-right"><?= $product->quantity; ?></td> <td class="text-right"><?= $product->price; ?></td> <td class="text-right"><?= $product->cost; ?></td> </tr> <?php endforeach; ?> <tr> <th colspan="3" class="text-right">Итого</th> <th class="text-right"><?= $model->amount; ?></th> </tr> </table>
Хорошо, с просмотром заказа разобрались, осталось еще подправить view-шаблон для редактирования заказа. Давайте посмотрим на код шаблона:
<?php /* * Файл view-шаблона modules/admin/views/order/update.php */ use yii\helpers\Html; /* @var $this yii\web\View */ /* @var $model app\modules\admin\models\Order */ $this->title = 'Редактирование заказа № ' . $model->id; ?> <h1><?= Html::encode($this->title) ?></h1> <?= $this->render('_form', [ 'model' => $model, ]); ?>
Вопреки ожиданиям, формы там нет, она расположена в файле _form.php
:
<?php use yii\helpers\Html; use yii\widgets\ActiveForm; /* @var $this yii\web\View */ /* @var $model app\modules\admin\models\Order */ /* @var $form yii\widgets\ActiveForm */ ?> <?php $form = ActiveForm::begin(); ?> <?= $form->field($model, 'user_id')->textInput() ?> <?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?> <?= $form->field($model, 'email')->textInput(['maxlength' => true]) ?> <?= $form->field($model, 'phone')->textInput(['maxlength' => true]) ?> <?= $form->field($model, 'address')->textInput(['maxlength' => true]) ?> <?= $form->field($model, 'comment')->textInput(['maxlength' => true]) ?> <?= $form->field($model, 'amount')->textInput(['maxlength' => true]) ?> <?= $form->field($model, 'status')->textInput() ?> <?= $form->field($model, 'created')->textInput() ?> <?= $form->field($model, 'updated')->textInput() ?> <div class="form-group"> <?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?> </div> <?php ActiveForm::end(); ?>
Давайте ее немного изменим — запретим редактировать сумму заказа, дату создания и обновления + заменим текстовое поле статуса заказа на выпадающий список.
<?php use yii\helpers\Html; use yii\widgets\ActiveForm; /* @var $this yii\web\View */ /* @var $model app\modules\admin\models\Order */ /* @var $form yii\widgets\ActiveForm */ ?> <?php $form = ActiveForm::begin(); ?> <?php $items = [ 0 => 'Новый', 1 => 'Обработан', 2 => 'Оплачен', 3 => 'Доставлен', 4 => 'Завершен', ]; echo $form->field($model, 'status')->dropDownList($items); echo $form->field($model, 'name')->textInput(['maxlength' => true]); echo $form->field($model, 'email')->textInput(['maxlength' => true]); echo $form->field($model, 'phone')->textInput(['maxlength' => true]); echo $form->field($model, 'address')->textarea(['rows' => 2, 'maxlength' => true]); echo $form->field($model, 'comment')->textarea(['rows' => 2, 'maxlength' => true]); echo $form->field($model, 'amount')->textInput(['readonly' => true]); echo $form->field($model, 'created')->textInput(['readonly' => true]); echo $form->field($model, 'updated')->textInput(['readonly' => true]); ?> <div class="form-group"> <?= Html::submitButton('Сохранить', ['class' => 'btn btn-success']) ?> </div> <?php ActiveForm::end(); ?>
Нам еще нужно изменять дату и время обновления заказа при редактировании. Чтобы правильно их сортировать на главной странице панели управления. Для этого добавим метод behaviors()
классу модели Order
:
<?php namespace app\modules\admin\models; use yii\behaviors\TimestampBehavior; use yii\db\ActiveRecord; use yii\db\Expression; class Order extends ActiveRecord { /*...*/ public function behaviors() { return [ [ 'class' => TimestampBehavior::class, 'attributes' => [ // при обновлении существующей записи присвоить атрибуту // updated значение метки времени UNIX ActiveRecord::EVENT_BEFORE_UPDATE => ['updated'], ], // если вместо метки времени UNIX используется DATETIME 'value' => new Expression('NOW()'), ], ]; } /*...*/ }
И последнее, что осталось сделать — удалять записи из таблицы БД order_item
при удалении заказа:
<?php namespace app\modules\admin\models; use yii\behaviors\TimestampBehavior; use yii\db\ActiveRecord; use yii\db\Expression; class Order extends ActiveRecord { /*...*/ /** * Удаляет товары заказа при удалении заказа */ public function afterDelete() { parent::afterDelete(); OrderItem::deleteAll(['order_id' => $this->id]); } /*...*/ }
- Магазин на Yii2, часть 24. Админка: модель, контроллер и представления для заказов
- Магазин на Laravel 7, часть 17. Панель управления, работа с заказами, изменение статуса
- Магазин на Yii2, часть 35. Админка: загрузка картинок для страниц и страница 404
- Магазин на Yii2, часть 33. Админка: приводим в порядок CRUD-код для страниц
- Магазин на Yii2, часть 32. Админка: удаление категорий и CRUD для страниц
- Магазин на Yii2, часть 31. Админка: загрузка изображений для категорий и брендов
- Магазин на Yii2, часть 30. Админка: WYSIWYG-редактор и изображение для товара
Поиск: Web-разработка • Yii2 • Заказ • Интернет магазин • Каталог товаров • Панель управления • Фреймворк • GridView • DataProvider