├── .gitignore
├── src
├── Qiniu.php
├── QiniuServiceProvider.php
├── Http
│ └── Controllers
│ │ └── QiniuController.php
└── QiniuImages.php
├── routes
└── routes.php
├── resources
└── views
│ └── qiniuimage.blade.php
├── composer.json
├── LICENSE
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | composer.phar
2 | /vendor/
3 | /.idea
4 | composer.lock
5 |
6 |
7 | # Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control
8 | # You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
9 | # composer.lock
10 |
--------------------------------------------------------------------------------
/src/Qiniu.php:
--------------------------------------------------------------------------------
1 | config('admin.route.prefix'),
7 | 'namespace' => 'Hanson\\LaravelAdminQiniu\\Http\\Controllers',
8 | 'middleware' => config('admin.route.middleware'),
9 | ], function () {
10 |
11 | Route::post('qiniu/upload', 'QiniuController@upload');
12 | Route::match(['put', 'post'], 'qiniu/delete', 'QiniuController@delete');
13 |
14 | });
15 |
--------------------------------------------------------------------------------
/resources/views/qiniuimage.blade.php:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hanson/laravel-admin-qiniu",
3 | "authors": [
4 | {
5 | "name": "Hanson",
6 | "email": "h@hanc.cc"
7 | }
8 | ],
9 | "require": {
10 | "overtrue/laravel-filesystem-qiniu": "^1.0"
11 | },
12 | "autoload": {
13 | "psr-4": {
14 | "Hanson\\LaravelAdminQiniu\\": "src/"
15 | }
16 | },
17 | "extra": {
18 | "laravel": {
19 | "providers": [
20 | "Hanson\\LaravelAdminQiniu\\QiniuServiceProvider"
21 | ]
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/QiniuServiceProvider.php:
--------------------------------------------------------------------------------
1 | views()) {
16 | $this->loadViewsFrom($views, 'qiniu');
17 | }
18 |
19 | $this->loadRoutesFrom(__DIR__.'/../routes/routes.php');
20 |
21 | Admin::booting(function () {
22 | Form::extend('qiniuImages', QiniuImages::class);
23 | });
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Hanson
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/Http/Controllers/QiniuController.php:
--------------------------------------------------------------------------------
1 | file();
16 |
17 | if (!$file) {
18 | return ['error' => '没有需要上传的图片'];
19 | }
20 |
21 | $file = array_values($file)[0][0];
22 |
23 | $disk = request('disk', 'qiniu');
24 |
25 | $domain = config('filesystems.disks.'.$disk.'.domain');
26 |
27 | $domain = Str::endsWith($domain, '/') ? $domain : $domain . '/';
28 |
29 | try {
30 | $path = Storage::disk($disk)->put(request('path', ''), $file);
31 | } catch (\Exception $exception) {
32 | return ['error' => '网络错误,错误信息:'.$exception->getMessage()];
33 | }
34 |
35 | return [
36 | 'initialPreview' => [
37 | "$domain$path"
38 | ],
39 | 'initialPreviewConfig' => [
40 | ['caption' => $file->getClientOriginalName(), 'size' => $file->getSize(), 'width' => '120px', 'url' => "/admin/qiniu/delete", 'key' => $path],
41 | ],
42 | 'append' => true // 是否把这些配置加入`initialPreview`。
43 | ];
44 | }
45 |
46 | public function delete()
47 | {
48 | return ['has_delete' => Storage::disk(request('disk'))->delete(request('key'))];
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # laravel-admin-qiniu
2 |
3 | Laravel admin 框架的七牛 qiniu 多图上传扩展,可拖拽,异步上传图片,支持删除
4 |
5 | 
6 |
7 | 
8 |
9 | ## 安装
10 |
11 | `composer require hanson/laravel-admin-qiniu:dev-master -vvv`
12 |
13 | ## 配置
14 |
15 | 在 `config/filesystems.php` 增加一个 disk
16 |
17 | ```php
18 | [
22 | //...
23 | 'qiniu' => [
24 | 'driver' => 'qiniu',
25 | 'access_key' => env('QINIU_ACCESS_KEY', 'xxxxxxxxxxxxxxxx'),
26 | 'secret_key' => env('QINIU_SECRET_KEY', 'xxxxxxxxxxxxxxxx'),
27 | 'bucket' => env('QINIU_BUCKET', 'xxx'),
28 | 'domain' => env('QINIU_DOMAIN', 'xxx.clouddn.com'), // or host: https://xxxx.clouddn.com
29 | ],
30 | //...
31 | ]
32 | ];
33 | ```
34 |
35 | ## 使用
36 |
37 | ```php
38 | qiniuImages('column', '商品图')->sortable(); // 普通用法
43 |
44 | $form->qiniuImages('column', '商品图')
45 | ->sortable() // 让图片可以拖拽排序
46 | ->extraData(['disk' => 'qiniu2', 'path' => 'avatar']) // 假如你有多个七牛配置,可以通过指定此处的 disk 进行上传, path 为文件路径的前缀
47 | ->value(['http://url.com/a.jpg', 'http://url.com/b.jpg']); // 默认显示的图片数组,必须为 url
48 |
49 | $form->saving(function (\Encore\Admin\Form $form) {
50 | $paths = \Hanson\LaravelAdminQiniu\Qiniu::getPaths(request('qiniu_column')); // 需要 qiniu_ 作为前缀的字段
51 | });
52 | ```
53 |
--------------------------------------------------------------------------------
/src/QiniuImages.php:
--------------------------------------------------------------------------------
1 | options['uploadLabel'] = '上传';
23 | $this->options['uploadAsync'] = true; // 异步上传
24 | $this->options['showUpload'] = true; // 显示上传按钮
25 | $this->options['dropZoneEnabled'] = true; // 允许拖拽上传
26 | $this->options['fileActionSettings']['showRemove'] = true; // 允许单个图片删除
27 | $this->options['uploadExtraData']['_token'] = csrf_token();
28 | $this->options['deleteExtraData']['_token'] = csrf_token();
29 | $this->options['deleteUrl'] = '/admin/qiniu/delete';
30 | $this->options['uploadUrl'] = '/admin/qiniu/upload';
31 | }
32 |
33 | /**
34 | * js 层面逻辑修改为 hidden 传值为字符串,通过逗号分隔图片的 key
35 | *
36 | * @param string $options
37 | */
38 | protected function setupScripts($options)
39 | {
40 | $this->script = <<getElementClassSelector()}").fileinput({$options});
42 | EOT;
43 |
44 | if ($this->fileActionSettings['showRemove']) {
45 | $text = [
46 | 'title' => trans('admin.delete_confirm'),
47 | 'confirm' => trans('admin.confirm'),
48 | 'cancel' => trans('admin.cancel'),
49 | ];
50 |
51 | $this->script .= <<getElementClassSelector()}").on('filebeforedelete', function() {
53 |
54 | return new Promise(function(resolve, reject) {
55 |
56 | var remove = resolve;
57 |
58 | swal({
59 | title: "{$text['title']}",
60 | type: "warning",
61 | showCancelButton: true,
62 | confirmButtonColor: "#DD6B55",
63 | confirmButtonText: "{$text['confirm']}",
64 | showLoaderOnConfirm: true,
65 | cancelButtonText: "{$text['cancel']}",
66 | preConfirm: function() {
67 | return new Promise(function(resolve) {
68 | resolve(remove());
69 | });
70 | }
71 | });
72 | });
73 | });
74 | EOT;
75 | }
76 |
77 | if ($this->fileActionSettings['showDrag']) {
78 | $this->addVariables([
79 | 'sortable' => true,
80 | 'sort_flag' => static::FILE_SORT_FLAG,
81 | ]);
82 |
83 | $this->script .= <<getElementClassSelector()}").on('filesorted', function(event, params) {
85 |
86 | var order = "";
87 |
88 | params.stack.forEach(function (item) {
89 | order += item.key + ","
90 | });
91 |
92 | $("input.qiniu_{$this->formatName($this->column)}").val(order)
93 | });
94 | EOT;
95 | }
96 |
97 | $keys = collect($this->options['initialPreviewConfig'] ?? [])->map(function ($item) {
98 | return $item['key'];
99 | })->implode(',');
100 |
101 | $this->script .= <<getElementClassSelector()}").on('fileuploaded', function(event, data, previewId, index) {
103 | var key = data.response.initialPreviewConfig[0].key;
104 | var value = $("input.qiniu_{$this->formatName($this->column)}").val()
105 |
106 | $("input.qiniu_{$this->formatName($this->column)}").val(value+","+key);
107 | });
108 | $("input.qiniu_{$this->formatName($this->column)}").val("{$keys}");
109 | EOT;
110 | }
111 |
112 | /**
113 | * 由于修改了下面方法的 value ,这里需要重新取出 URL,去掉 key
114 | *
115 | * @return array
116 | */
117 | protected function preview()
118 | {
119 | return array_values($this->value ?? []);
120 | }
121 |
122 | /**
123 | * 可以设置参数定义上传与删除时的传参,控制器会获取其中的 disk 与 path 值
124 | *
125 | * @param array $data
126 | * @return $this
127 | */
128 | public function extraData(array $data)
129 | {
130 | $this->options['uploadExtraData'] = $data;
131 | $this->options['deleteExtraData'] = $data;
132 |
133 | return $this;
134 | }
135 |
136 | /**
137 | * 为了让 value 传值纯为 URL,这里需要修改 key 值 为 path
138 | *
139 | * @param null $value
140 | * @return $this|mixed
141 | */
142 | public function value($value = null)
143 | {
144 | if ($value === null) {
145 | return $this->value ?? $this->getDefault();
146 | }
147 |
148 | if (is_array($value)) {
149 | foreach ($value as $url) {
150 | $key = substr(parse_url($url)['path'], 1);
151 | $this->value[$key] = $url;
152 | }
153 | }
154 |
155 | return $this;
156 | }
157 | }
158 |
--------------------------------------------------------------------------------