largezhou / admin

laravel + ant design vue 权限后台
http://admin-demo.largezhou.com/admin
MIT License
450 stars 139 forks source link

创建resource的时候如果是二级控制器会出错 #17

Closed ghost closed 3 years ago

ghost commented 3 years ago

执行命令 php artisan admin:make-resource phone\Group 创建出来的控制器和model filter request 的父级都是有错误,目前我这边的解决方案是 在每个stub文件内手动定义父级 创建出来的vue文件也未能支持二级 目前我这边做了对应的解决方案 您这边可以看下 ,目前我是这样临时做解决的 项目很棒哦 大佬 里面我的todo 都有写 大佬看看吧

<?php

namespace App\Admin\Console\Commands;

use Illuminate\Console\GeneratorCommand;
use Illuminate\Support\Str;

class ResourceMakeCommand extends GeneratorCommand
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = '
        admin:make-resource
        {name : 短横式命名的资源名称}
        {--force : 覆盖已存在文件}
        {--model= : 指定模型}
        {--test : 生成控制器测试类}
    ';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '添加一个资源,包含各种相关文件';

    protected $types = [
        'model', 'filter', 'request', 'resource', 'controller', 'test',
    ];

    /**
     * 当前正在生成的类型
     *
     * @var string
     */
    protected $nowType;

    /**
     * 各类型对应的完整的类名
     *
     * @var array
     */
    protected $classes = [];

    protected $frontendTypePathMap = [
        'api' => 'api/dummy-resources.js',
        'index' => 'views/dummy-resources/Index.vue',
        'form' => 'views/dummy-resources/Form.vue',
    ];

    /**
     * Execute the console command.
     */
    public function handle()
    {
        if (!$res = $this->makeBackend()) {
            return $res;
        }

        return $this->makeFrontend();
    }

    protected function makeBackend()
    {
        foreach ($this->types as $type) {
            $this->nowType = $type;
            $this->type = Str::ucfirst($type);

            if (($type == 'model') && ($model = $this->option('model'))) {
                if (!class_exists($model)) {
                    $this->error("模型 [ {$model} ] 不存在");
                    return 0;
                } elseif (class_exists($model)) {
                    $this->classes[$type] = trim($model, '\\');
                    continue;
                }
            }

            if (($type == 'test') && (!$this->option('test'))) {
                continue;
            }

            if (parent::handle() === false) {
                return 0;
            }
            $this->classes[$type] = $this->qualifyClass($this->getNameInput());
        }

        return 1;
    }

    protected function getStub()
    {
        return __DIR__ . "/stubs/{$this->nowType}.stub";
    }

    protected function getNameInput()
    {
        $name = Str::studly(trim($this->argument('name')));
        if ($this->nowType == 'test') {
            $name = 'Feature\\' . $name . 'ControllerTest';
        } elseif ($this->nowType != 'model') {
            $name .= $this->type;
        }

        return $name;
    }

    protected function rootNamespace()
    {
        return 'App\\Admin\\' . Str::ucfirst(Str::plural($this->nowType));
    }

    protected function getPath($name)
    {
        $name = Str::replaceFirst($this->rootNamespace(), '', $name);
        return $this->laravel['path'] .
            '/Admin/' .
            Str::ucfirst(Str::plural($this->type)) .
            str_replace('\\', '/', $name) . '.php';
    }

    protected function replaceClass($stub, $name)
    {
        $stub = parent::replaceClass($stub, $name);

        if ($this->nowType == 'test') {
            $stub = str_replace('NamespacedDummyModel', $this->classes['model'], $stub);
            $stub = str_replace('dummy-resource-name', Str::plural($this->argument('name')), $stub);
        } elseif ($this->nowType == 'controller') {
            foreach (['filter', 'request', 'resource', 'model'] as $type) {
                $stub = $this->replaceDummyResource($type, $stub);
            }
        }

        return $stub;
    }

    protected function replaceDummyResource(string $type, string $stub): string
    {
        $namespaced = $this->classes[$type];
        $class = class_basename($namespaced);
        $type = Str::ucfirst($type);
        $stub = str_replace("NamespacedDummy{$type}", $namespaced, $stub);
        $stub = str_replace("Dummy{$type}", $class, $stub);

        if ($type == 'Model') {
            $model = '$' . Str::camel($class);
            $models = Str::plural($model);

            $stub = str_replace('$dummyModel', $model, $stub);
            $stub = str_replace('$dummyModels', $models, $stub);
        }

        return $stub;
    }

    protected function makeFrontend()
    {
        //todo 修正做出来临时名称 begin
        $name = str_replace('\\', '/', trim($this->argument('name')));
        $tmp = explode('/', $name);
        //todo 制作临时变量 end
        $dummyResource = Str::camel($name);
        $ucDummyResource = Str::ucfirst($dummyResource);
        $pluralDummyResource = Str::plural($dummyResource);
        $ucPluralDummyResource = Str::ucfirst($pluralDummyResource);
        reset($tmp);
        //todo 兼容vue内文件
        $pluralKebabDummyResource = Str::plural(current($tmp) . '/' . strtolower(end($tmp)));
        //todo 修正文件
        $replaces = [
            'PluralDummyResource' => ucfirst(end($tmp)),
            'dummy-resources' => $pluralKebabDummyResource,
            'DummyResource' => ucfirst(end($tmp)),
            'dummyResources' => ucfirst(end($tmp)),
        ];

        foreach (['api', 'index', 'form', 'routes'] as $type) {
            $content = $this->files->get(__DIR__ . "/stubs/frontend/{$type}.stub");
            foreach ($replaces as $search => $replace) {
                $content = str_replace($search, $replace, $content);
            }

            if ($type == 'routes') {
                $this->info('路由配置:');
                $this->line($content);
            } else {
                $relativePath = str_replace('dummy-resources', $pluralKebabDummyResource, $this->frontendTypePathMap[$type]);
                $path = $this->laravel['path.resources'] . '/admin/src/' . $relativePath;

                if (
                    !$this->option('force') &&
                    $this->files->exists($path)
                ) {
                    $this->error($relativePath . ' 已存在');
                    return 0;
                }
                $this->makeDirectory($path);
                $this->files->put($path, $content);
                $this->info($relativePath . ' 创建成功');
            }
        }

        return 1;
    }
}
largezhou commented 3 years ago

这个我有空得看看,,,

largezhou commented 3 years ago

已经处理了,,,不过感觉加二级、三级,,,不怎么合适,,,还是尽量别加,,,如果只是想调整模型,可以先不加,生成后,再手动调整模型的目录,,,

https://github.com/largezhou/admin/commit/355698cba09882f8b8ae3b170964c35143291430