laravel 图片流_laravel-admin恶心的图片上传功能改为异步传图的完整方案

缪修德
2023-12-01

laravel-admin恶心的图片上传功能,让广大开发者很是苦恼,今天分享一个 手动改为异步传图的完整方案给大家,如果有大神在,也可以考虑将其封装为扩展~

同时也分享一下列表使用tab的解决方案~以及如何使用json方式存储动态性字段比较强的类型的数据~

话不多,看代码

grid()控制器

protected function grid()

{

$grid = new Grid(new Ad());

$grid->column('id', __('广告编号'))->sortable();;

//$grid->column('group', __('广告位置'));

$grid->column('value', __('广告信息'));

$grid->column('status', __('广告状态'))->radio(Ad::STATUS);

//$grid->column('created_at', __('创建时间'));

//$grid->column('updated_at', __('最后更新'));

//return $grid;

$tab = new Tab();

$tabs = Ad::GROUP;

$tab_type = request('tab_type', 1);

$grid->disableCreateButton();//禁用默认的推荐按钮

foreach ($tabs as $key => $value) {

if ($tab_type == $key) {

$grid->model()->where('group', $key);

$grid->tools(function ($tools)use($key,$value) {

$url = "ads/create?group={$key}";

$icon = "fa fa-plus";

$text = "新建{$value}";

$tools->append(new ShowArtwork($url,$icon,$text));

});

$tab->add($value, $grid->render(), true);

}else {

$tab->addLink($value,'?tab_type='.$key);

}

}

return $tab;

}

form()控制器代码

/**

* Make a form builder.

*

* @return Form

*/

protected function form()

{

$form = new Form(new Ad());

$form->saving(function (Form $form) {//保存数据前,合并一下value

$original = $form->model()->value ?? [];// 原数据

$now = $form->value;// 表单数据

$merge = array_merge($original,$now);// 合并数据

//echo "requset:";dump(request()->all());

// 根据model->value配置的字段处理数据

$groupInfo = Ad::GROUPINFO[$form->model()->group??request('group',1)];

$groupInfo = array_merge(Ad::GROUPALL,$groupInfo);

//dump($groupInfo);

foreach ($groupInfo as $mk => $mv){

try{

$key = strstr($mk, '_tmp',true);

if(!$key){//_tmp结尾的字段为图片上传字段不需要保存

$file_key = $mk . '_upload_file';

$file = Session::get($file_key);

if($file){// 判断session中有没有图片

// 删除原图

$disk = QiniuStorage::disk('qiniu');

if(isset($merge[$mk]) && $file['key'] != $merge[$mk])//避免传的新图和老图是同一张

$disk->delete($merge[$mk]);

// 存储新图

$merge[$mk] = $file['key'];

Session::forget($file_key);

}

$endValue[$mk] = $merge[$mk]??'';

}

} catch (\Exception $exception ){

dd($exception);

}

}

//dd($endValue);

$form->value = $endValue;

});

//$form->radio('group', __('广告位置'))->options(Ad::GROUP)->default(1);

$form->hidden('group')->default(request('group',1));

$form->display('group', __('广告位置'))->with(function ($group) {

return '' . Ad::GROUP[$group?:request('group',1)] . '';

});

//$form->text('value', __('广告信息'));

$form->embeds('value', '广告信息', function ($em_form) use($form) {

$groupInfo = Ad::GROUPINFO[$form->model()->group??request('group',1)];

$groupInfo = array_merge(Ad::GROUPALL,$groupInfo);

foreach ($groupInfo as $gik => $giv){

$type = $giv[0];

switch ($type){

case 'image' :

case 'file' :

$em_form->$type($gik,$giv[1]??$gik)->rules($giv[2]??'')->removable()

->options(

[

'showPreview' => true,

//'allowedFileExtensions'=>['apk'],

'showUpload' => false,

'uploadAsync' => true,

'uploadUrl' => '/admin/upload_file',

'uploadExtraData' => [

'_token' => csrf_token(),

'_method' => 'POST',

'dir' => 'ads',//保存路径

'file_field' => "value.{$gik}",//文件存放字段

],

]

);

break;

case 'multipleImage' :

case 'multipleFile' :

$em_form->$type($gik,$giv[1]??$gik)->rules($giv[2]??'')->sortable()->removable();

break;

case 'display' :

$config = config("filesystems.disks.qiniu");

$em_form->$type($gik,$giv[1]??$gik)->rules($giv[2]??'')->with(function ($value) use($config) {

if($value)

return "";

});

break;

case 'radio' :

$em_form->$type($gik,$giv[1]??$gik)->rules($giv[2]??'')

->options($giv[4])->default(1);

break;

default:

$em_form->$type($gik,$giv[1]??$gik)->rules($giv[2]??'')->attribute($giv[3]??[]);;

}

}

});

$form->switch('status', __('广告状态'))->default(1)->rules();

return $form;

}

Ad的Model类

'开屏广告',

2   => '首页幻灯',

3   => '首页滚动',

4   => '首页推荐',

5   => '首页大图',

];

const GROUPALL = [

'title'=>[

'text', '标题', 'required',['required' => '1']

],

'type'=>[

'radio', '类型', 'required',['required' => '1'],['1' => '外链', '2'=> '信息详情']

],

'url'=>[

'text', '链接', 'required',['required' => '1']

]

];

const GROUPINFO = [// 广告位字段配置

1   => [

//            'title'=>[

//                'text', '标题', 'required',['required' => '1']

//            ],

'image'=>[// _tmp为固定必加后缀,实际上字段为image

'display', '图片预览', ''

],

'image_tmp'=>[// _tmp为固定必加后缀,实际上字段为image

'image', '替换图片', ''

],

//            'url'=>[

//                'text', '链接', 'required',['required' => '1']

//            ]

],

2   => [

//            'title'=>[

//                'text', '标题', 'required',['required' => '1']

//            ],

'image'=>[// _tmp为固定必加后缀,实际上字段为image

'display', '图片预览', ''

],

'image_tmp'=>[// _tmp为固定必加后缀,实际上字段为image

'image', '替换图片', ''

],

//            'url'=>[

//                'text', '链接', 'required',['required' => '1']

//            ]

],

3   => [

],

4   => [

//            'title'=>[

//                'text', '标题', 'required',['required' => '1']

//            ],

'image'=>[// _tmp为固定必加后缀,实际上字段为image

'display', '图片预览', ''

],

'image_tmp'=>[// _tmp为固定必加后缀,实际上字段为image

'image', '替换图片', ''

],

//            'url'=>[

//                'text', '链接', 'required',['required' => '1']

//            ]

],

5   => [

//            'title'=>[

//                'text', '标题', 'required',['required' => '1']

//            ],

'image'=>[// _tmp为固定必加后缀,实际上字段为image

'display', '图片预览', ''

],

'image_tmp'=>[// _tmp为固定必加后缀,实际上字段为image

'image', '替换图片', ''

],

//            'url'=>[

//                'text', '链接', 'required',['required' => '1']

//            ]

],

];

const STATUS = [

'0' => '隐藏',

'1' => '显示',

];

/**

* The attributes that are mass assignable.

*

* @var array

*/

protected $fillable = [

'group', 'value', 'status',

];

/**

* The attributes that should be hidden for arrays.

*

* @var array

*/

protected $hidden = [

];

protected $casts = [

'value' => 'json',

];

}

上传文件的控制器/admin/upload_file

/**

* 上传文件到七牛

* @param  Request $request [description]

* @return [type][description]

*/

public function uploadFile(Request $request)

{

$dir = $request->input('dir','images');

$file_field = $request->input('file_field');

// 判断是否有文件上传

if ($request->hasFile($file_field)) {

// 获取文件,file对应的是前端表单上传input的name

$file = $request->file($file_field);

$extension = $file->getClientOriginalExtension();

// 初始化

$disk = QiniuStorage::disk('qiniu');

// 重命名文件

//$fileName = md5($file->getClientOriginalName().time().rand()).'.'.$extension;

//$fileName = $file->getClientOriginalName();//使用原文件名

$fileName = md5_file($file->getRealPath()).'.'.$extension;//用md5值

// 上传到七牛

$bool = $disk->put($dir.'/'.$fileName,file_get_contents($file->getRealPath()));

// 判断是否上传成功

if ($bool) {

$data['key'] = $dir.'/'.$fileName;

$data['url'] = $disk->downloadUrl($data['key']);

$data['type'] = $extension;

//$data['md5'] = $disk->avInfo($data['key']);

$file_key = strstr(substr(strrchr($file_field,'.'),1), '_tmp',true) . '_upload_file';

Session::put($file_key, $data);

return Response::json(['success' => "true", 'message' => "上传成功", "data" => $data]);

}

return Response::json(['success' => "false", 'message' => "上传失败"],401);

}

return Response::json(['success' => "false", 'message' => "没有文件"],401);

}

简单说一下异步传图实现方案,也是同事传授的方法,使用seesion缓存传上来的图

这里我根据字段名称进行了缓存,看代码

$file_key = strstr(substr(strrchr($file_field,'.'),1), '_tmp',true) . '_upload_file';

然后在控制器层再将它读出来使用。。。

由于json方式传图字段每次提交都会报错,索性只要是图文的字段就必须两个一个真实字段,一个是上传图片的临时字段例如:image_tmp,数据库中并不保存该值

总之方案也不是很完美,如果你也要解决这恶心的事情,可以优化一下,或者分享更好的方案~

也可以使用js解决方案

$this->script = script);

 类似资料: