FastAdmin 管理システムでの審査機能付きカスタムアクションボタンの実装

実装概要

FastAdmin の管理画面において、既存のリストデータに対して独自の業務フローを組み込む場合があります。今回は、「編集」ボタンの前に「審査(承認)」機能を追加し、選択したレコードをステータス更新する処理を実装します。

1. 言語キーの定義

まず、フロントエンドに表示されるラベル用に、必要な文字列を言語定義ファイルに追加します。この例では、動画(video)モジュールに関する設定を行います。

以下のパスにあるファイルを開き、新しい翻訳キーを追加してください。

application/admin/lang/zh-cn/video.php

'Status' => 'ステータス',
'Audit Reason' => '審査理由',
'Review' => '審査',
// ... existing lines

2. コントローラー側の処理追加

バックエンドでデータの保存を行う処理を作成します。基本的には既存の「編集」アクションと同様の構造を持ちますが、受け付けるパラメータを絞り込むため、一部フィールドの制限を加えます。ここでは元の関数名から独自の名前に変更しています。

コントローラーファイル:application/admin/controller/Video.php

public function review($id = null)
{
    // レコードの取得
    $row = $this->model->find($id);
    if (!$row) {
        $this->error(__('No Data Found'));
    }

    // データ権限の制限チェック
    $allowedAdminIds = $this->getDataLimitAdminIds();
    if (is_array($allowedAdminIds)) {
        if (!in_array($row[$this->dataLimitField], $allowedAdminIds)) {
            $this->error(__('Access Denied'));
        }
    }

    if ($this->request->isPost()) {
        $updateData = $this->request->post("row/a");
        
        if ($updateData) {
            $updateData = $this->preExcludeFields($updateData);
            $saveResult = false;
            Db::startTrans();
            try {
                // バリデーションモデルの適用
                if ($this->modelValidate) {
                    $modelName = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                    $validateRule = is_bool($this->modelValidate) 
                        ? ($this->modelSceneValidate ? $modelName . '.edit' : $modelName) 
                        : $this->modelValidate;
                    
                    $row->validateFailException(true)->validate($validateRule);
                }

                // フィールドを指定して保存(許可されたフィールドのみ)
                $saveResult = $row->allowField(['reason', 'status'])->save($updateData);
                
                Db::commit();
            } catch (\think\exception\ValidateException $e) {
                Db::rollback();
                $this->error($e->getMessage());
            } catch (\PDOException $e) {
                Db::rollback();
                $this->error($e->getMessage());
            } catch (\Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }

            if ($saveResult !== false) {
                $this->success();
            } else {
                $this->error(__('Update Failed'));
            }
        }
        $this->error(__('Parameter Invalid'));
    }

    $this->view->assign("dataRow", $row);
    return $this->view->fetch();
}

3. ビューテンプレートの作成

入力フォームの画面を新規作成します。ここでの注意点は、タイトルなどの参照すべき情報を読み取り専用(readonly)にし、変更が必要なフィールド(理由やステータス)だけを入力可能にすることです。

ファイルパス:application/admin/view/video/review.html

<form id="review-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
    <div class="form-group">
        <label class="control-label col-xs-12 col-sm-2">{:__('Subject')}:</label>
        <div class="col-xs-12 col-sm-8">
             {$dataRow.title|htmlentities} 
        </div>
    </div>
    <div class="form-group">
        <label class="control-label col-xs-12 col-sm-2">{:__('Audit Reason')}:</label>
        <div class="col-xs-12 col-sm-8">
           <input id="input-reason" class="form-control" name="row[reason]" type="text" value="{$dataRow.reason|htmlentities}">
        </div>
    </div>
    <div class="form-group">
        <label class="control-label col-xs-12 col-sm-2">{:__('Approval Status')}:</label>
        <div class="col-xs-12 col-sm-8">
            <select id="select-status" class="form-control" name="row[status]">
                 <option value="0" {$dataRow.status == 0 ? 'selected' : ''}>Rejected</option>
                 <option value="1" {$dataRow.status == 1 ? 'selected' : ''}>Approved</option>
            </select>
        </div>
    </div>
    
    <div class="form-group layer-footer">
        <label class="control-label col-xs-12 col-sm-2"></label>
        <div class="col-xs-12 col-sm-8">
            <button type="submit" class="btn btn-success btn-embossed ">{:__('Submit')}</button>
            <button type="reset" class="btn btn-default btn-embossed">{:__('Clear')}</button>
        </div>
    </div>
</form>

4. フロントエンドテーブルの設定

最後に、管理一覧表のJavaScript設定を変更し、新たな操作ボタンを表示します。これにより、各データ行に対して「審査」ポップアップがトリガーされます。

対象ファイル:public/assets/js/backend/video.js

define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {

    var MainController = {
        init: function () {
            // テーブル API の拡張設定
            Table.api.init({
                extend: {
                    index_url: 'video/index' + location.search,
                    add_url: 'video/add',
                    edit_url: 'video/edit',
                    review_url: 'video/review', // カスタム URL を追加
                    del_url: 'video/del',
                    multi_url: 'video/multi',
                    table: 'video',
                }
            });

            var dataTable = $("#list-table");

            // テーブルの初期化
            dataTable.bootstrapTable({
                url: $.fn.bootstrapTable.defaults.extend.index_url,
                pk: 'id',
                sortName: 'id',
                columns: [
                    [
                        {checkbox: true},
                        {field: 'id', title: __('Id')},
                        {field: 'title', title: __('Subject')},
                        {field: 'create_time', title: __('Create Time')},
                        {field: 'status', title: __('Current Status')},
                        {field: 'operate', title: __('Actions'), table: dataTable, 
                             buttons: [
                                       // 新しいボタン定義
                                       {name: 'verify', text: __('Review'), icon: 'fa fa-check', classname: 'btn btn-xs btn-warning btn-dialog', url: 'video/review'}
                                     ], 
                        events: Table.api.events.operate, formatter: Table.api.formatter.operate}
                    ]
                ]
            });

            Table.api.bindevent(dataTable);
        },
        verify: function () {
            // ページ遷移時のイベントバインド確保
            MainController.api.bindevent();
        },
        api: {
            bindevent: function () {
                Form.api.bindevent($("form[role=form]"));
            }
        }
    };
    return MainController;
});

タグ: fastadmin PHP mvc-pattern bootstrap-table ajax-crud

6月21日 17:01 投稿