Przeglądaj źródła

Merge pull request #12 from jqhph/master

拉取最新的代码
yxx 5 lat temu
rodzic
commit
c0bf6deee8

+ 4 - 2
README.md

@@ -42,13 +42,15 @@
 ![](https://cdn.learnku.com/uploads/images/202004/24/38389/bP75OeDbWH.png!large)
 
 
-## 功能
+## 功能特性
 
+- [x] 简洁优雅、灵活可扩展的API
 - [x] 用户管理
 - [x] RBAC权限管理,支持无限极权限节点
 - [x] 菜单管理
 - [x] 使用pjax构建无刷新页面,支持**按需加载**静态资源,可以无限扩展组件而不影响整体性能
 - [x] 松耦合的页面构建与数据操作设计,可轻松切换数据源
+- [x] 自定义页面
 - [x] 自定义主题配色
 - [x] 多主题切换功能,内置多种主题色
 - [x] 可轻松构建无菜单栏的独立页面(如可用于构建弹窗选择器等功能)
@@ -64,7 +66,7 @@
 - [x] 内置丰富的常用页面组件(如图表、数据统计卡片、下拉菜单、Tab卡片、提示工具等)
 - [x] `Section`功能(类似`Wordpress`的`Filter`和`blade`模板的`section`标签)
 - [x] 异步文件上传表单,支持分块多线程上传
-- [ ] 多应用(多后台)
+- [x] 多应用
 - [ ] 插件市场,只需在管理页面轻轻点击鼠标即可完成插件的安装、更新和卸载等操作
 
 

+ 1 - 1
src/Actions/HasActionHandler.php

@@ -66,7 +66,7 @@ trait HasActionHandler
      */
     public function handlerRoute()
     {
-        return route('dcat.api.action');
+        return route(admin_api_route('action'));
     }
 
     /**

+ 14 - 4
src/Admin.php

@@ -35,7 +35,7 @@ class Admin
      *
      * @var string
      */
-    const VERSION = '1.3.5';
+    const VERSION = '1.4.0';
 
     /**
      * @var array
@@ -230,14 +230,16 @@ class Admin
     /**
      * 注册api路由.
      *
+     * @param string $as
+     *
      * @return void
      */
-    public static function registerApiRoutes()
+    public static function registerApiRoutes(string $as = null)
     {
         $attributes = [
-            'prefix' => admin_base_path('dcat-api'),
+            'prefix'     => admin_base_path('dcat-api'),
             'middleware' => config('admin.route.middleware'),
-            'as' => 'dcat.api.',
+            'as'         => $as ?: static::app()->getApiRoutePrefix(Application::DEFAULT),
         ];
 
         app('router')->group($attributes, function ($router) {
@@ -311,6 +313,14 @@ class Admin
         return new Proxy($repository);
     }
 
+    /**
+     * @return Application
+     */
+    public static function app()
+    {
+        return app('admin.app');
+    }
+
     /**
      * 获取所有已注册的扩展.
      *

+ 6 - 7
src/AdminServiceProvider.php

@@ -33,6 +33,7 @@ class AdminServiceProvider extends ServiceProvider
         Console\ActionCommand::class,
         Console\MenuCacheCommand::class,
         Console\MinifyCommand::class,
+        Console\AppCommand::class,
     ];
 
     /**
@@ -55,6 +56,7 @@ class AdminServiceProvider extends ServiceProvider
         'admin.bootstrap'  => Middleware\Bootstrap::class,
         'admin.session'    => Middleware\Session::class,
         'admin.upload'     => Middleware\WebUploader::class,
+        'admin.app'        => Middleware\Application::class,
     ];
 
     /**
@@ -77,7 +79,7 @@ class AdminServiceProvider extends ServiceProvider
         $this->registerDefaultSections();
         $this->registerViews();
         $this->ensureHttps();
-        $this->registerRoutes();
+        $this->bootApplication();
         $this->registerPublishing();
         $this->compatibleBlade();
     }
@@ -127,13 +129,9 @@ class AdminServiceProvider extends ServiceProvider
     /**
      * 路由注册.
      */
-    protected function registerRoutes()
+    protected function bootApplication()
     {
-        Admin::registerApiRoutes();
-
-        if (is_file($routes = admin_path('routes.php'))) {
-            $this->loadRoutesFrom($routes);
-        }
+        Admin::app()->boot();
     }
 
     /**
@@ -211,6 +209,7 @@ class AdminServiceProvider extends ServiceProvider
 
     protected function registerServices()
     {
+        $this->app->singleton('admin.app', Application::class);
         $this->app->singleton('admin.asset', Asset::class);
         $this->app->singleton('admin.color', Color::class);
         $this->app->singleton('admin.sections', SectionManager::class);

+ 148 - 0
src/Application.php

@@ -0,0 +1,148 @@
+<?php
+
+namespace Dcat\Admin;
+
+use Illuminate\Contracts\Container\Container;
+use Illuminate\Support\Facades\Route;
+
+class Application
+{
+    const DEFAULT = 'admin';
+
+    /**
+     * @var Container
+     */
+    protected $app;
+
+    /**
+     * 所有启用应用的配置.
+     *
+     * @var array
+     */
+    protected $configs = [];
+
+    /**
+     * 当前应用名称.
+     *
+     * @var string
+     */
+    protected $name;
+
+    public function __construct(Container $app)
+    {
+        $this->app = $app;
+    }
+
+    /**
+     * 设置当前应用配置.
+     *
+     * @param string $app
+     */
+    public function current(string $app = null)
+    {
+        $this->withName($app);
+
+        $this->withConfig($this->name);
+    }
+
+    /**
+     * 设置应用名称.
+     *
+     * @param string $app
+     */
+    public function withName(string $app)
+    {
+        $this->name = $app;
+    }
+
+    /**
+     * 获取当前应用名称.
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->name ?: static::DEFAULT;
+    }
+
+    /**
+     * 注册应用.
+     */
+    public function boot()
+    {
+        $this->registerRoute(static::DEFAULT);
+
+        if ($this->app->runningInConsole()) {
+            return;
+        }
+        foreach ((array) config('admin.multi_app') as $app => $enable) {
+            if ($enable) {
+                $this->registerRoute($app);
+            }
+        }
+    }
+
+    /**
+     * @return string
+     */
+    public function getCurrentApiRoutePrefix()
+    {
+        return $this->getApiRoutePrefix($this->getName());
+    }
+
+    /**
+     * @param string|null $app
+     *
+     * @return string
+     */
+    public function getApiRoutePrefix(?string $app)
+    {
+        return "dcat.api.{$app}.";
+    }
+
+    /**
+     * 注册应用路由.
+     *
+     * @param string|null $app
+     */
+    protected function registerRoute(?string $app)
+    {
+        $this->withConfig($app);
+
+        Admin::registerApiRoutes($this->getApiRoutePrefix($app));
+
+        if (is_file($routes = admin_path('routes.php'))) {
+            $this->loadRoutesFrom($routes, $app);
+        }
+    }
+
+    /**
+     * 设置应用配置.
+     *
+     * @param string $app
+     */
+    protected function withConfig(string $app)
+    {
+        if (! isset($this->configs[$app])) {
+            $this->configs[$app] = config($app);
+            $this->configs[$app]['current_app'] = $app;
+        }
+
+        config(['admin' => $this->configs[$app]]);
+    }
+
+    /**
+     * 加载路由文件.
+     *
+     * @param  string  $path
+     * @param  string  $app
+     *
+     * @return void
+     */
+    protected function loadRoutesFrom(string $path, ?string $app)
+    {
+        if (! $this->app->routesAreCached()) {
+            Route::middleware('admin.app:'.$app)->group($path);
+        }
+    }
+}

+ 65 - 0
src/Console/AppCommand.php

@@ -0,0 +1,65 @@
+<?php
+
+namespace Dcat\Admin\Console;
+
+use Dcat\Admin\Support\Helper;
+use Illuminate\Filesystem\Filesystem;
+
+class AppCommand extends InstallCommand
+{
+    /**
+     * The console command name.
+     *
+     * @var string
+     */
+    protected $signature = 'admin:app {name}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Create new application';
+
+    /**
+     * Execute the console command.
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        $this->addConfig();
+        $this->initAdminDirectory();
+
+        $this->info('Done.');
+    }
+
+    protected function addConfig()
+    {
+        /* @var Filesystem $files */
+        $files = $this->laravel['files'];
+
+        $app = Helper::slug($namespace = $this->argument('name'));
+
+        $files->put(
+            $config = config_path($app.'.php'),
+            str_replace(
+                ['DummyNamespace', 'DummyApp'],
+                [$namespace, $app],
+                $files->get(__DIR__.'/stubs/config.stub')
+            )
+        );
+
+        config(['admin' => include $config]);
+    }
+
+    /**
+     * Set admin directory.
+     *
+     * @return void
+     */
+    protected function setDirectory()
+    {
+        $this->directory = app_path($this->argument('name'));
+    }
+}

+ 12 - 2
src/Console/InstallCommand.php

@@ -59,13 +59,23 @@ class InstallCommand extends Command
     }
 
     /**
-     * Initialize the admAin directory.
+     * Set admin directory.
      *
      * @return void
      */
-    protected function initAdminDirectory()
+    protected function setDirectory()
     {
         $this->directory = config('admin.directory');
+    }
+
+    /**
+     * Initialize the admin directory.
+     *
+     * @return void
+     */
+    protected function initAdminDirectory()
+    {
+        $this->setDirectory();
 
         if (is_dir($this->directory)) {
             $this->warn("{$this->directory} directory already exists !");

+ 359 - 0
src/Console/stubs/config.stub

@@ -0,0 +1,359 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin name
+    |--------------------------------------------------------------------------
+    |
+    | This value is the name of dcat-admin, This setting is displayed on the
+    | login page.
+    |
+    */
+    'name' => 'Dcat Admin',
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin logo
+    |--------------------------------------------------------------------------
+    |
+    | The logo of all admin pages. You can also set it as an image by using a
+    | `img` tag, eg '<img src="http://logo-url" alt="Admin logo">'.
+    |
+    */
+    'logo' => '<img src="/vendors/dcat-admin/images/logo.png" width="35"> &nbsp;Dcat Admin',
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin mini logo
+    |--------------------------------------------------------------------------
+    |
+    | The logo of all admin pages when the sidebar menu is collapsed. You can
+    | also set it as an image by using a `img` tag, eg
+    | '<img src="http://logo-url" alt="Admin logo">'.
+    |
+    */
+    'logo-mini' => '<img src="/vendors/dcat-admin/images/logo.png">',
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin route settings
+    |--------------------------------------------------------------------------
+    |
+    | The routing configuration of the admin page, including the path prefix,
+    | the controller namespace, and the default middleware. If you want to
+    | access through the root path, just set the prefix to empty string.
+    |
+    */
+    'route' => [
+
+        'prefix' => 'DummyApp',
+
+        'namespace' => 'App\\DummyNamespace\\Controllers',
+
+        'middleware' => ['web', 'admin'],
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin install directory
+    |--------------------------------------------------------------------------
+    |
+    | The installation directory of the controller and routing configuration
+    | files of the administration page. The default is `app/Admin`, which must
+    | be set before running `artisan admin::install` to take effect.
+    |
+    */
+    'directory' => app_path('DummyNamespace'),
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin html title
+    |--------------------------------------------------------------------------
+    |
+    | Html title for all pages.
+    |
+    */
+    'title' => 'Admin',
+
+    /*
+    |--------------------------------------------------------------------------
+    | Assets hostname
+    |--------------------------------------------------------------------------
+    |
+   */
+    'assets_server' => env('ADMIN_ASSETS_SERVER'),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Access via `https`
+    |--------------------------------------------------------------------------
+    |
+    | If your page is going to be accessed via https, set it to `true`.
+    |
+    */
+    'https' => env('ADMIN_HTTPS', false),
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin auth setting
+    |--------------------------------------------------------------------------
+    |
+    | Authentication settings for all admin pages. Include an authentication
+    | guard and a user provider setting of authentication driver.
+    |
+    | You can specify a controller for `login` `logout` and other auth routes.
+    |
+    */
+    'auth' => [
+        'enable' => true,
+
+        'controller' => App\DummyNamespace\Controllers\AuthController::class,
+
+        'guard' => 'admin',
+
+        'guards' => [
+            'admin' => [
+                'driver'   => 'session',
+                'provider' => 'admin',
+            ],
+        ],
+
+        'providers' => [
+            'admin' => [
+                'driver' => 'eloquent',
+                'model'  => Dcat\Admin\Models\Administrator::class,
+            ],
+        ],
+
+        // Add "remember me" to login form
+        'remember' => true,
+
+        // All method to path like: auth/users/*/edit
+        // or specific method to path like: get:auth/users.
+        'except' => [
+            'auth/login',
+            'auth/logout',
+        ],
+
+    ],
+
+    'grid' => [
+
+        /*
+        |--------------------------------------------------------------------------
+        | The global Grid action display class.
+        |--------------------------------------------------------------------------
+        */
+        'grid_action_class' => Dcat\Admin\Grid\Displayers\DropdownActions::class,
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin helpers setting.
+    |--------------------------------------------------------------------------
+    */
+    'helpers' => [
+        'enable' => true,
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin permission setting
+    |--------------------------------------------------------------------------
+    |
+    | Permission settings for all admin pages.
+    |
+    */
+    'permission' => [
+        // Whether enable permission.
+        'enable' => true,
+
+        // All method to path like: auth/users/*/edit
+        // or specific method to path like: get:auth/users.
+        'except' => [
+            '/',
+            'auth/login',
+            'auth/logout',
+            'auth/setting',
+        ],
+
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin menu setting
+    |--------------------------------------------------------------------------
+    |
+    */
+    'menu' => [
+        'cache' => [
+            // enable cache or not
+            'enable' => false,
+            'store'  => 'file',
+        ],
+
+        // Whether enable menu bind to a permission.
+        'bind_permission' => true,
+
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin upload setting
+    |--------------------------------------------------------------------------
+    |
+    | File system configuration for form upload files and images, including
+    | disk and upload path.
+    |
+    */
+    'upload' => [
+
+        // Disk in `config/filesystem.php`.
+        'disk' => 'admin',
+
+        // Image and file upload path under the disk above.
+        'directory' => [
+            'image' => 'images',
+            'file'  => 'files',
+        ],
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin database settings
+    |--------------------------------------------------------------------------
+    |
+    | Here are database settings for dcat-admin builtin model & tables.
+    |
+    */
+    'database' => [
+
+        // Database connection for following tables.
+        'connection' => '',
+
+        // User tables and model.
+        'users_table' => 'admin_users',
+        'users_model' => Dcat\Admin\Models\Administrator::class,
+
+        // Role table and model.
+        'roles_table' => 'admin_roles',
+        'roles_model' => Dcat\Admin\Models\Role::class,
+
+        // Permission table and model.
+        'permissions_table' => 'admin_permissions',
+        'permissions_model' => Dcat\Admin\Models\Permission::class,
+
+        // Menu table and model.
+        'menu_table' => 'admin_menu',
+        'menu_model' => Dcat\Admin\Models\Menu::class,
+
+        // Pivot table for table above.
+        'operation_log_table'    => 'admin_operation_log',
+        'user_permissions_table' => 'admin_user_permissions',
+        'role_users_table'       => 'admin_role_users',
+        'role_permissions_table' => 'admin_role_permissions',
+        'role_menu_table'        => 'admin_role_menu',
+        'permission_menu_table'  => 'admin_permission_menu',
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | User operation log setting
+    |--------------------------------------------------------------------------
+    |
+    | By setting this option to open or close operation log in dcat-admin.
+    |
+    */
+    'operation_log' => [
+
+        'enable' => true,
+
+        // Only logging allowed methods in the list
+        'allowed_methods' => ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH'],
+
+        'secret_fields' => [
+            'password',
+            'password_confirmation',
+        ],
+
+        // Routes that will not log to database.
+        // All method to path like: auth/logs/*/edit
+        // or specific method to path like: get:auth/logs.
+        'except' => [
+            'auth/logs*',
+        ],
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | Admin map field provider
+    |--------------------------------------------------------------------------
+    |
+    | Supported: "tencent", "google", "yandex".
+    |
+    */
+    'map_provider' => 'google',
+
+    /*
+    |--------------------------------------------------------------------------
+    | Application layout
+    |--------------------------------------------------------------------------
+    |
+    | This value is the layout of admin pages.
+    */
+    'layout' => [
+        // indigo, blue, blue-light, blue-dark, green
+        'color' => 'indigo',
+
+        'body_class' => '',
+
+        'sidebar_collapsed' => false,
+
+        'sidebar_dark' => false,
+
+        // bg-primary, bg-info, bg-warning, bg-success, bg-danger, bg-dark
+        'navbar_color' => '',
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | Login page background image
+    |--------------------------------------------------------------------------
+    |
+    | This value is used to set the background image of login page.
+    |
+    */
+    'login_background_image' => '',
+
+    /*
+    |--------------------------------------------------------------------------
+    | The exception handler class
+    |--------------------------------------------------------------------------
+    |
+    */
+    'exception_handler' => \Dcat\Admin\Exception\Handler::class,
+
+    /*
+    |--------------------------------------------------------------------------
+    | Enable default breadcrumb
+    |--------------------------------------------------------------------------
+    |
+    | Whether enable default breadcrumb for every page content.
+    */
+    'enable_default_breadcrumb' => true,
+
+    /*
+    |--------------------------------------------------------------------------
+    | Settings for extensions.
+    |--------------------------------------------------------------------------
+    |
+    | You can find all available extensions here
+    | https://github.com/dcat-admin-extensions.
+    |
+    */
+    'extensions' => [
+
+    ],
+];

+ 1 - 1
src/Form/Field/Editor.php

@@ -135,7 +135,7 @@ class Editor extends Field
      */
     protected function defaultImageUploadUrl()
     {
-        return $this->formatUrl(route('dcat.api.tinymce.upload'));
+        return $this->formatUrl(route(admin_api_route('tinymce.upload')));
     }
 
     /**

+ 1 - 1
src/Form/Field/Markdown.php

@@ -166,7 +166,7 @@ JS
      */
     protected function defaultImageUploadUrl()
     {
-        return $this->formatUrl(route('dcat.api.editor-md.upload'));
+        return $this->formatUrl(route(admin_api_route('editor-md.upload')));
     }
 
     /**

+ 1 - 1
src/Grid/Column.php

@@ -18,7 +18,7 @@ use Illuminate\Support\Str;
 use Illuminate\Support\Traits\Macroable;
 
 /**
- * @method $this editable()
+ * @method $this editable(bool $refresh = false)
  * @method $this switch(string $color = '')
  * @method $this switchGroup($columns = [], string $color = '')
  * @method $this image($server = '', int $width = 200, int $height = 200)

+ 1 - 1
src/Grid/Displayers/DialogTree.php

@@ -172,7 +172,7 @@ EOF;
 
     protected function getSelectorPrefix()
     {
-        return $this->grid->getName().'_'.$this->column->getName();
+        return $this->grid->getName().'_'.$this->column->getName().'_'.$this->getKey();
     }
 
     protected function setupScript()

+ 64 - 54
src/Grid/Displayers/Editable.php

@@ -8,18 +8,27 @@ class Editable extends AbstractDisplayer
 {
     protected $selector = 'grid-editable';
 
-    public function display()
+    public function display($refresh = false)
     {
         $this->addScript();
         $this->addStyle();
 
+        $label = __('admin.save');
+
         return <<<HTML
-            <div>
-                <span class="{$this->selector}" >
-                    {$this->value}
-                </span>
-                 <i class="feather icon-check btn-outline-primary hidden" data-value="{$this->value}" data-name="{$this->column->getName()}" data-id="{$this->getKey()}" data-url="{$this->getUrl()}"></i>
-            </div>
+<div>
+    <span class="{$this->selector}" contenteditable="true">
+        {$this->value}
+    </span>
+    <span class="save hidden" 
+        data-value="{$this->value}" 
+        data-name="{$this->column->getName()}" 
+        data-id="{$this->getKey()}" 
+        data-refresh="{$refresh}"
+        data-url="{$this->getUrl()}">
+        {$label}
+    </span>
+</div>
 HTML;
     }
 
@@ -35,7 +44,7 @@ HTML;
         Admin::style(
             <<<CSS
 .grid-editable{border-bottom:dashed 1px $color;color: $color;display: inline-block}
-.grid-editable,.icon-check{margin-left: 0.4rem}
+.grid-editable+.save{margin-left: 0.55rem;color: $color}
 CSS
         );
     }
@@ -43,55 +52,56 @@ CSS
     protected function addScript()
     {
         $script = <<<JS
-            $(".{$this->selector}").on("click",function() {
-                $(this).attr('contenteditable', true);
-                $(this).next().removeClass("hidden");
-            })
-            $(".icon-check").on("click",function() {
-                var obj = $(this);
-                var url = obj.attr('data-url');
-                var name = obj.attr('data-name');
-                var old_value = obj.attr('data-value').trim();
-                var rebr = new RegExp("<br>","g");
-                var renbsp = new RegExp("&nbsp;","g");
-                var value = obj.prev().html().replace(rebr,'').replace(renbsp,'').trim();
-                if (value == old_value) {
-                    obj.addClass("hidden").prev().attr('contenteditable', false);
-                    return;
-                }
+$(".{$this->selector}").on("click", function() {
+    $(this).next().removeClass("hidden");
+}).on('blur', function () {
+    var icon = $(this).next();
+    setTimeout(function () {
+        icon.addClass("hidden")
+    }, 200)
+});
+$('.{$this->selector}+.save').on("click",function() {
+    var obj = $(this),
+        url = obj.data('url'),
+        name = obj.data('name'),
+        refresh = obj.data('refresh'),
+        old_value = obj.data('value').trim(),
+        value = obj.prev().html().replace(new RegExp("<br>","g"), '').replace(new RegExp("&nbsp;","g"), '').trim();
+    
+    var data = {
+        _token: Dcat.token,
+        _method: 'PUT'
+    };
+    data[name] = value;
+    Dcat.NP.start();
+    $.ajax({
+        url: url,
+        type: "POST",
+        data: data,
+        success: function (data) {
+            if (data.status) {
+                obj.attr('data-value',value).addClass("hidden").prev().html(value);
+                Dcat.success(data.message);
                 
-                var data = {
-                    _token: Dcat.token,
-                    _method: 'PUT'
-                };
-                data[name] = value;
-                Dcat.NP.start();
-                $.ajax({
-                    url: url,
-                    type: "POST",
-                    data: data,
-                    success: function (data) {
-                        if (data.status) {
-                            obj.attr('data-value',value).addClass("hidden").prev().html(value).attr('contenteditable', false);
-                            Dcat.success(data.message);
-                        } else {
-                            obj.prev().html(old_value);
-                            Dcat.error(data.message);
-                        }
-                    },
-                    error:function(a,b,c) {
-                        obj.prev().html(old_value);
-                        Dcat.handleAjaxError(a, b, c);
-                    },
-                    complete:function(a,b) {
-                        Dcat.NP.done();
-                    }
-                });
-            })
+                refresh && Dcat.reload()
+            } else {
+                obj.prev().html(old_value);
+                Dcat.error(data.message);
+            }
+        },
+        error:function(a,b,c) {
+            obj.prev().html(old_value);
+            Dcat.handleAjaxError(a, b, c);
+        },
+        complete:function(a,b) {
+            Dcat.NP.done();
+        }
+    });
+    
+    return false;
+})
 JS;
 
         Admin::script($script);
     }
-
-
 }

+ 17 - 0
src/Middleware/Application.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace Dcat\Admin\Middleware;
+
+use Dcat\Admin\Admin;
+
+class Application
+{
+    public function handle($request, \Closure $next, $app = null)
+    {
+        if ($app) {
+            Admin::app()->current($app);
+        }
+
+        return $next($request);
+    }
+}

+ 1 - 1
src/Middleware/LogOperation.php

@@ -98,7 +98,7 @@ class LogOperation
      */
     protected function inExceptArray($request)
     {
-        if ($request->routeIs('dcat.api.value')) {
+        if ($request->routeIs(admin_api_route('value'))) {
             return true;
         }
 

+ 14 - 0
src/Support/helpers.php

@@ -1,5 +1,6 @@
 <?php
 
+use Dcat\Admin\Admin;
 use Dcat\Admin\Support\Helper;
 use Illuminate\Contracts\Support\Htmlable;
 use Illuminate\Contracts\Support\Renderable;
@@ -381,3 +382,16 @@ if (! function_exists('admin_asset')) {
         return Dcat\Admin\Admin::asset()->url($path);
     }
 }
+
+if (! function_exists('admin_api_route')) {
+
+    /**
+     * @param string $path
+     *
+     * @return string
+     */
+    function admin_api_route(string $path = '')
+    {
+        return Dcat\Admin\Admin::app()->getCurrentApiRoutePrefix().$path;
+    }
+}

+ 1 - 1
src/Traits/InteractsWithApi.php

@@ -78,7 +78,7 @@ trait InteractsWithApi
      */
     public function getRequestUrl()
     {
-        return $this->url ?: route('dcat.api.value');
+        return $this->url ?: route(admin_api_route('value'));
     }
 
     /**

+ 1 - 1
src/Widgets/Form.php

@@ -651,7 +651,7 @@ JS
     {
         if (method_exists($this, 'handle')) {
             $this->method('POST');
-            $this->action(route('dcat.api.form'));
+            $this->action(route(admin_api_route('form')));
             $this->hidden('_form_')->default(get_called_class());
             $this->hidden('_current_')->default($this->getCurrentUrl());
         }