柔晶美网络工作室

柔晶美网络工作室,倾心于web技术的博客站点

关注我 微信公众号

您现在的位置是: 首页 > 博客日记

laravel-admin的文件管理插件media-manager,迁移到dcat admin中使用

2021-05-13 admin laravel  2960

因Dcat admin中暂无文件管理插件,项目需要在后台管理文件,以前在使用laravel-admin时,比较喜欢media-manager这个插件。这个插件有两种模式,一是表格模式,二是列表模式,如下图:


而且,容易拓展相应的功能,因此,准备将此插件搬到dcat中使用。在迁移过程中,遇到的问题是,需要兼容dcat的前端组件,样式模板需要修改,控制器调用的方法和命名空间也要相应修改。

一、添加路由

/app/Admin/routes.php中添加以下路由:

    $router->get('media', 'MediaController@index')->name('media-index');
    $router->get('media/download', 'MediaController@download')->name('media-download');
    $router->delete('media/delete', 'MediaController@delete')->name('media-delete');
    $router->put('media/move', 'MediaController@move')->name('media-move');
    $router->post('media/upload', 'MediaController@upload')->name('media-upload');
    $router->post('media/folder', 'MediaController@newFolder')->name('media-new-folder');


二、创建文件管理控制器

app/Admin/Controllers中创建MediaController.php文件,代码如下:

namespace App\Admin\Controllers;

use App\Admin\Metrics\Examples;
use App\Http\Controllers\Controller;
use Dcat\Admin\Http\Controllers\Dashboard;
use Dcat\Admin\Layout\Column;
use Dcat\Admin\Layout\Content;
use Dcat\Admin\Layout\Row;
use Illuminate\Support\Facades\Storage;
use Dcat\Admin\Exception\Handler;
use Illuminate\Http\UploadedFile;
use Illuminate\Http\Request;
use Admin;

class MediaController extends Controller
{
    
    public function index(Request $request,Content $content)
    {
        $path = $request->get('path', '/');
        $view = $request->get('view', 'table');
        $manager = new MediaManager($path);
        return $content->header('文件管理')->description('点击路径名可快速跳转相应文件夹')->body(view($view,[
            'list'   => $manager->ls(),
            'nav'    => $manager->navigation(),
            'url'    => $manager->urls(),
        ]));
    }

    public function download(Request $request)
    {
        $file = $request->get('file');

        $manager = new MediaManager($file);

        return $manager->download();
    }

    public function upload(Request $request)
    {
        $files = $request->file('files');
        $dir = $request->get('dir', '/');

        $manager = new MediaManager($dir);

        try {
            if ($manager->upload($files)) {
                admin_toastr(trans('admin.upload_succeeded'));
            }
        } catch (\Exception $e) {
            admin_toastr($e->getMessage(), 'error');
        }

        return back();
    }

    public function delete(Request $request)
    {
        $files = $request->get('files');

        $manager = new MediaManager();

        try {
            if ($manager->delete($files)) {
                return response()->json([
                    'status'  => true,
                    'message' => trans('admin.delete_succeeded'),
                ]);
            }
        } catch (\Exception $e) {
            return response()->json([
                'status'  => true,
                'message' => $e->getMessage(),
            ]);
        }
    }

    public function move(Request $request)
    {
        $path = $request->get('path');
        $new = $request->get('new');

        $manager = new MediaManager($path);

        try {
            if ($manager->move($new)) {
                return response()->json([
                    'status'  => true,
                    'message' => trans('admin.move_succeeded'),
                ]);
            }
        } catch (\Exception $e) {
            return response()->json([
                'status'  => true,
                'message' => $e->getMessage(),
            ]);
        }
    }

    public function newFolder(Request $request)
    {
        $dir = $request->get('dir');
        $name = $request->get('name');

        $manager = new MediaManager($dir);

        try {
            if ($manager->newFolder($name)) {
                return response()->json([
                    'status'  => true,
                    'message' => trans('admin.move_succeeded'),
                ]);
            }
        } catch (\Exception $e) {
            return response()->json([
                'status'  => true,
                'message' => $e->getMessage(),
            ]);
        }
    }
}


创建文件管理控制器MediaManager.php,代码如下:

namespace App\Admin\Controllers;

use App\Admin\Metrics\Examples;
use App\Http\Controllers\Controller;
use Dcat\Admin\Http\Controllers\Dashboard;
use Dcat\Admin\Layout\Column;
use Dcat\Admin\Layout\Content;
use Dcat\Admin\Layout\Row;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\File;
//use Dcat\Admin\Exception\Handler;
use Illuminate\Http\UploadedFile;
use Illuminate\Http\Request;
use Dcat\Admin\Http\JsonResponse;
use Admin;

class MediaManager extends Controller
{

    protected $path = '/';

    protected $storage;

    protected $fileTypes = [
        'image' => 'png|jpg|jpeg|tmp|gif',
        'word'  => 'doc|docx',
        'ppt'   => 'ppt|pptx',
        'pdf'   => 'pdf',
        'code'  => 'php|js|java|python|ruby|go|c|cpp|sql|m|h|json|html|aspx',
        'zip'   => 'zip|tar\.gz|rar|rpm',
        'txt'   => 'txt|pac|log|md',
        'audio' => 'mp3|wav|flac|3pg|aa|aac|ape|au|m4a|mpc|ogg',
        'video' => 'mkv|rmvb|flv|mp4|avi|wmv|rm|asf|mpeg',
    ];


    public function __construct($path = '/')
    {
        $this->path = $path;

        $this->initStorage();
    }

    private function initStorage()
    {
        $disk = config('admin.upload.disk');

        $this->storage = Storage::disk($disk);

        if (!$this->storage->getDriver()->getAdapter() instanceof Local) {
            return JsonResponse::make()->error('只能管理本地文件');
        }
    }

    public function ls()
    {
        if (!$this->exists()) {
            return [];
        }

        $files = $this->storage->files($this->path);

        $directories = $this->storage->directories($this->path);

        return $this->formatDirectories($directories)
            ->merge($this->formatFiles($files))
            ->sort(function ($item) {
                return $item['name'];
            })->all();
    }

    protected function getFullPath($path)
    {
        return $this->storage->getDriver()->getAdapter()->applyPathPrefix($path);
    }

    public function download()
    {
        $fullPath = $this->getFullPath($this->path);

        if (File::isFile($fullPath)) {
            return response()->download($fullPath);
        }

        return response('', 404);
    }

    public function delete($path)
    {
        $paths = is_array($path) ? $path : func_get_args();

        foreach ($paths as $path) {
            $fullPath = $this->getFullPath($path);

            if (is_file($fullPath)) {
                $this->storage->delete($path);
            } else {
                $this->storage->deleteDirectory($path);
            }
        }

        return true;
    }

    public function move($new)
    {
        return $this->storage->move($this->path, $new);
    }

    /**
     * @param UploadedFile[] $files
     * @param string         $dir
     *
     * @return mixed
     */
    public function upload($files = [])
    {
        foreach ($files as $file) {
            $this->storage->putFileAs($this->path, $file, $file->getClientOriginalName());
        }

        return true;
    }

    public function newFolder($name)
    {
        $path = rtrim($this->path, '/').'/'.trim($name, '/');

        return $this->storage->makeDirectory($path);
    }

    public function exists()
    {
        $path = $this->getFullPath($this->path);

        return file_exists($path);
    }

    /**
     * @return array
     */
    public function urls()
    {
        return [
            'path'       => $this->path,
            'index'      => admin_route('media-index'),
            'move'       => admin_route('media-move'),
            'delete'     => admin_route('media-delete'),
            'upload'     => admin_route('media-upload'),
            'new-folder' => admin_route('media-new-folder'),
        ];
    }

    public function formatFiles($files = [])
    {
        $files = array_map(function ($file) {
            return [
                'download'  => admin_route('media-download', compact('file')),
                'icon'      => '',
                'name'      => $file,
                'preview'   => $this->getFilePreview($file),
                'isDir'     => false,
                'size'      => $this->getFilesize($file),
                'link'      => admin_route('media-download', compact('file')),
                'url'       => $this->storage->url($file),
                'time'      => $this->getFileChangeTime($file),
            ];
        }, $files);

        return collect($files);
    }

    public function formatDirectories($dirs = [])
    {
        $url = admin_route('media-index', ['path' => '__path__', 'view' => request('view')]);

        $preview = "<a href=\"$url\"><span class=\"file-icon text-aqua\"><i class=\"fa fa-folder\"></i></span></a>";

        $dirs = array_map(function ($dir) use ($preview) {
            return [
                'download'  => '',
                'icon'      => '',
                'name'      => $dir,
                'preview'   => str_replace('__path__', $dir, $preview),
                'isDir'     => true,
                'size'      => '',
                'link'      => admin_route('media-index', ['path' => '/'.trim($dir, '/'), 'view' => request('view')]),
                'url'       => $this->storage->url($dir),
                'time'      => $this->getFileChangeTime($dir),
            ];
        }, $dirs);

        return collect($dirs);
    }

    public function navigation()
    {
        $folders = explode('/', $this->path);

        $folders = array_filter($folders);

        $path = '';

        $navigation = [];

        foreach ($folders as $folder) {
            $path = rtrim($path, '/').'/'.$folder;

            $navigation[] = [
                'name'  => $folder,
                'url'   => admin_route('media-index', ['path' => $path]),
            ];
        }

        return $navigation;
    }

    public function getFilePreview($file)
    {
        switch ($this->detectFileType($file)) {
            case 'image':

                if ($this->storage->getDriver()->getConfig()->has('url')) {
                    $url = $this->storage->url($file);
                    $preview = "<span class=\"file-icon has-img\"><img src=\"$url\" alt=\"Attachment\"></span>";
                } else {
                    $preview = '<span class="file-icon"><i class="fa fa-file-image-o"></i></span>';
                }
                break;

            case 'pdf':
                $preview = '<span class="file-icon"><i class="fa fa-file-pdf-o"></i></span>';
                break;

            case 'zip':
                $preview = '<span class="file-icon"><i class="fa fa-file-zip-o"></i></span>';
                break;

            case 'word':
                $preview = '<span class="file-icon"><i class="fa fa-file-word-o"></i></span>';
                break;

            case 'ppt':
                $preview = '<span class="file-icon"><i class="fa fa-file-powerpoint-o"></i></span>';
                break;

            case 'xls':
                $preview = '<span class="file-icon"><i class="fa fa-file-excel-o"></i></span>';
                break;

            case 'txt':
                $preview = '<span class="file-icon"><i class="fa fa-file-text-o"></i></span>';
                break;

            case 'code':
                $preview = '<span class="file-icon"><i class="fa fa-code"></i></span>';
                break;

            default:
                $preview = '<span class="file-icon"><i class="fa fa-file"></i></span>';
        }

        return $preview;
    }

    protected function detectFileType($file)
    {
        $extension = File::extension($file);

        foreach ($this->fileTypes as $type => $regex) {
            if (preg_match("/^($regex)$/i", $extension) !== 0) {
                return $type;
            }
        }

        return false;
    }

    public function getFilesize($file)
    {
        $bytes = filesize($this->getFullPath($file));

        $units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];

        for ($i = 0; $bytes > 1024; $i++) {
            $bytes /= 1024;
        }

        return round($bytes, 2).' '.$units[$i];
    }

    public function getFileChangeTime($file)
    {
        $time = filectime($this->getFullPath($file));

        return date('Y-m-d H:i:s', $time);
    }
}


三、创建模板

在public目录下创建前端js和css资源目录icheck,将下面的附件中的文件包解压到其中。

resources/views目录中创建两个模板,一个为表格,一个为列表:table.blade.php和list.blade.php,因文件代码较多,就不放在这些。

直接下载链接:http://roujingmei.com:20080/wangpan/JV6,提取码:9379

这样就完成了文件管理功能。

文章评论


需要 登录 才能发表评论
热门评论
0条评论

暂时没有评论!