aogg
4/24/2019 - 11:49 AM

laravel-admin的给key加描述

laravel-admin的给key加描述

给前端动态写入的key,添加中文描述

<?php

namespace App\Models;


use App\Helper\Common\Tinyint;
use App\Helper\Traits\TinyintTrait;

class SysJsonDescMapModel extends Model
{
    use TinyintTrait;

    // type用于表区分,不同表可以放不同字段做关联
    const TYPE_JSON = 1;
    const TYPE_TIMESTAMP = 2;
    const TYPE_INTEGER_DATETIME_STATISTICS = 3;

    protected $table = 'gz_sys_json_desc_map';

    protected $guarded = [
        'id'
    ];

    protected $casts = [
        'json' => 'json',
    ];

    protected $tinyintConfig = [

    ];

    /**
     * 支持匿名函数
     */
    protected function tinyintConfigTableAttr()
    {
        $this->tinyintConfig['table'] = [
            self::TYPE_JSON => [
                Tinyint::TITLE => '游戏属性描述',
                'model' => UserGameJsonAttributeModel::class,
                'table_fields' => [
                    'app_id' => '微信app_id', 'key' => '属性key',
                ],
                'table_form_fields' => [
                    'app_id' => function ($form, $field, $editValue = ''){
                        /** @var \Encore\Admin\Form $form */
                        return $form->select($field, '微信app_id')->options(UserWechatModel::instance()->getAppIdAndNameArr())->default($editValue)->required();
                    },
                    'key' => '属性key',
                ],
            ],
            self::TYPE_TIMESTAMP => [
                Tinyint::TITLE => '游戏时间描述',
                'model' => UserGameTimestampAttributeModel::class,
                'table_fields' => [
                    'app_id' => '微信app_id', 'cid' => '分类(整数)', 'key' => '属性key',
                ],
                'table_form_fields' => [
                    'app_id' => function ($form, $field, $editValue = ''){
                        /** @var \Encore\Admin\Form $form */
                        return $form->select($field, '微信app_id')->options(UserWechatModel::instance()->getAppIdAndNameArr())->default($editValue)->required();
                    },
                    'cid' => function ($form, $field, $editValue = 0){
                        /** @var \Encore\Admin\Form $form */
                        return $form->number($field, '分类(整数)')->default($editValue)->required()->rules('gt:0');
                    },
                    'key' => '属性key',
                ],
            ],
            self::TYPE_INTEGER_DATETIME_STATISTICS => [
                Tinyint::TITLE => '次数统计分类描述',
                'model' => UserGameIntegerStatisticsModel::class,
                'table_fields' => [
                    'app_id' => '微信app_id', 'cate_id_0' => '1级分类id', 'cate_id_1' => '2级分类id', 'cate_id_2' => '3级分类id',
                ],
                'table_form_fields' => [
                    'app_id' => function ($form, $field, $editValue = ''){
                        /** @var \Encore\Admin\Form $form */
                        return $form->select($field, '微信app_id')->options(UserWechatModel::instance()->getAppIdAndNameArr())->default($editValue)->required();
                    },
                    'cate_id_0' => function ($form, $field, $editValue = 0){
                        /** @var \Encore\Admin\Form $form */
                        return $form->number($field, '1级分类id')->default($editValue)->help('逐级填写分类id')->rules('min:1|required')->required();
                    },
                    'cate_id_1' => function ($form, $field, $editValue = 0){
                        /** @var \Encore\Admin\Form $form */
                        return $form->number($field, '2级分类id')->default($editValue)->help('需要填写1级分类id');
                    },
                    'cate_id_2' => function ($form, $field, $editValue = 0){
                        /** @var \Encore\Admin\Form $form */
                        return $form->number($field, '3级分类id')->default($editValue)->help('需要填写1级分类id');
                    },
                ],
            ],
        ];
    }

    public function newInstance($attributes = [], $exists = false)
    {
        $result = parent::newInstance();

        $this->tinyintConfigTableAttr();

        return $result;
    }

    public function __construct(array $attributes = [])
    {
        parent::__construct($attributes);

        $this->tinyintConfigTableAttr();
    }

    /**
     * 获取json里的type
     *
     * @return int
     */
    public function getTypeAttribute()
    {
        $json = $this->getAttribute('json');

        return $json['type'] ?? 0;
    }

    /**
     * 获取json的初始化
     *
     * @param $type
     * @return array
     */
    public function getInitJson($type)
    {
        return [
            'type' => (int)$type, // 留意字符串和整数
        ];
    }

    /**
     * md5一个json数据
     *
     * @param $json
     * @return string
     */
    public function md5Json($json)
    {
        return md5(json_encode($this->sortJson($json)));
    }

    public function sortJson($json)
    {
        if (is_array($json)) {
            krsort($json);
        }

        return $json;
    }

    /**
     * 根据json获取数据
     *
     * @param $json
     * @return SysJsonDescMapModel|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|\Illuminate\Database\Query\Builder|object|null
     */
    public function getDataByJson($json)
    {
        return $this->where('md5', $this->md5Json($json))->first();
    }

    /**
     * 根据json获取描述
     *
     * @param $json
     * @return string
     */
    public function getDescByJson($json)
    {
        return (string)$this->where('md5', $this->md5Json($json))->value('value');
    }
}
<?php
/**
 * Created by PhpStorm.
 * User: code
 * Date: 2019/4/24
 * Time: 19:57
 */

namespace App\Helper\Traits\Business;

/**
 * 给其他model添加描述字段
 *
 * @property $sysDescType = 0 定义type的类型
 */
trait SysJsonDescMapModelTrait
{

    /**
     * 添加访问器,方便获取描述
     */
    public function getSysDescAttribute()
    {
        $descModel = \App\Models\SysJsonDescMapModel::instance();
        $fields = (array)$descModel->getTinyint('table')->get($this->getSysDescType(), [], 'table_fields');

        $json = $descModel->getInitJson($this->getSysDescType());
        foreach ($fields as $field => $title) {
            $json[$field] = $this->getAttribute($field); // 要处理好访问器
        }

        return $descModel->getDescByJson($json);
    }

    /**
     * @param int $sysDescType
     * @return $this
     */
    public function setSysDescType(int $sysDescType)
    {
        $this->sysDescType = $sysDescType;

        return $this;
    }

    /**
     * @return int
     */
    public function getSysDescType(): int
    {
        return $this->sysDescType;
    }
}
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateGzSysJsonDescMapTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('gz_sys_json_desc_map', function (Blueprint $table) {
            $table->increments('id');
            $table->json('json')->comment('son');
            $table->string('md5')->index()->default('')->comment('json的md5');
            $table->string('value')->default('')->comment('描述');
            $table->timestamps();
        });

        \Illuminate\Support\Facades\DB::statement("ALTER TABLE `gz_sys_json_desc_map` comment '系统描述表'");// 表注释
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('gz_sys_json_desc_map');
    }
}
<?php

namespace App\Admin\Controllers;

use App\Models\SysJsonDescMapModel as Model;
use Encore\Admin\Form;
use Encore\Admin\Grid;

class SysJsonDescMapAdminController extends AdminTemplateController
{
        
    /**
     *
     * 页名
     *
     * @var string
     */
    protected $headerText = '系统描述';

    protected function grid()
    {
        $model = new Model;
        $grid = new Grid($model);

        $tableTitleList = $model->getTinyint('table')->getList();

        $grid->disableCreateButton();
        $grid->tools(function (Grid\Tools $tools)use($grid, $tableTitleList){
            foreach ($tableTitleList as $value => $item) {
                $tools->append((new \App\Helper\Vendor\LaravelAdmin\CreateButton(
                    $grid, 'type=' . $value, '新增' . $item . '数据', true
                ))->render());
            }
        });

        $grid->filter(function (Grid\Filter $filter) use($tableTitleList) {
            $filter->disableIdFilter(); // 已有
            $filter->column(12, function (Grid\Filter $filter){
                $filter->equal('id', '主键ID')->integer();
                $filter->equal('value', '描述');
            });
            $filter->column(1/2, function (Grid\Filter $filter){
                $filter->equal(Model::CREATED_AT, trans('admin.created_at'))->datetime();
            });
            $filter->column(1/2, function (Grid\Filter $filter){
                $filter->equal(Model::UPDATED_AT, trans('admin.updated_at'))->datetime();
            });
        });

        $grid->column('id', '主键ID')->sortable();
        $grid->column('cate', '分类')->display(function (){
            return $this->type;
        })->using($tableTitleList);
        $grid->title('详细配置')->expand(function (){
            $model = $this;
            if (empty($model['json'])) {
                return;
            }

            /** @var Model $model */
            $type = $model['type'];
            $fields = (array)$model->getTinyint('table')->get($type, [], 'table_fields');

            $row = [];
            foreach ($fields as $field => $title) {
                if (isset($model['json'][$field])) {
                    $row[] = [
                        $title,
                        $model['json'][$field],
                    ];
                }
            }

            return new \Encore\Admin\Widgets\Table(['配置', '值'], $row);
        });
        $grid->column('value', '描述');
        $grid->column(Model::CREATED_AT, trans('admin.created_at'))->sortable();
        $grid->column(Model::UPDATED_AT, trans('admin.updated_at'))->sortable();

        return $grid;
    }

    protected function form()
    {
        $model = new Model;
        $form = new Form($model);

        $tinyint = $model->getTinyint('table');

        $form->display('id', '主键ID');
        $form->text('value', '描述')->help('中文')->required();


        $form->asyncRender('async-json', function (Form $form)use($tinyint){
            $output = '';
            if ($form->builder()->isEditing()) { // 编辑
                $data = $form->model();
                $tempJson = $data['json'];

                $output .= $form->hidden('type', '分类')->default($data['type'])->render()->render();

                // 扩展字段
                $fields = (array)$tinyint->get($data['type'], [], $tinyint->existsSetAction('table_form_fields') ? 'table_form_fields' : 'table_fields');

                foreach ($fields as $field => $title){
                    if (is_callable($title)) {
                        $output .= call_user_func($title, $form, $this->handleJsonField($field), $tempJson[$field] ?? '')->render()->render();
                    }else{
                        $output .= $form->text($this->handleJsonField($field), $title)->default($tempJson[$field] ?? '')->render()->render();
                    }
                }
            }else{ // 创建
                $type = request()->input('type', 0);
                $output .= $form->hidden('type', '分类')->default($type)->render()->render();

                // 扩展字段
                $fields = (array)$tinyint->get($type, [], $tinyint->existsSetAction('table_form_fields') ? 'table_form_fields' : 'table_fields');

                foreach ($fields as $field => $title){
                    if (is_callable($title)) {
                        $output .= call_user_func($title, $form, $this->handleJsonField($field))->render()->render();
                    }else{
                        $output .= $form->text($this->handleJsonField($field), $title)->render()->render();
                    }
                }
            }

            return $output;
        }, $form);


        $form->display(Model::CREATED_AT, trans('admin.created_at'));
        $form->display(Model::UPDATED_AT, trans('admin.updated_at'));

        $form->saving(function (Form $form)use($tinyint){
            /** @var Model $model */
            $model = $form->model();
            $fields = (array)$tinyint->get($form->type, [], 'table_fields');

            $json = $model->getInitJson($form->type);
            foreach ($fields as $field => $title) {
                $tempField = $this->handleJsonField($field);
                if (!is_null($form->$tempField)) {
                    $json[$field] = $form->$tempField;
                }

                unset($form->$field);
            }

            $model->json = $model->sortJson($json);
            $model->md5 = $model->md5Json($json);
        });

        return $form;
    }

    protected function handleJsonField($field)
    {
        return 'json_' . $field;
    }
}