历届毕业生信息收集系统(含多图和视频)开发要点
2019-10-10 admin laravel 1837
刚接到了个项目,大概用途就是收集历届毕业生的毕业年份、姓名、专业、现在的工作照片多张、祝福母校的短视频等信息。前台要简洁有背景图,后台要求能查看或删除毕业生填写的数据,并对每个毕业生的图片视频单独打包下载,所有操作要求手机电脑都能完成。
项目开始,在前面的php查询填报系统的基础上,导入一个excel填报模板,并将其命令为shipin,然后,设置为中文字段名,上传图片字段设置为text,因为多图容易超过字数。bgsx那里开放全部字段填报,这时,前台能显示查询页面,但步骤多界面复杂,不符合要求。因此,对前台模板进行重构了。
前台的难点在于,h5多图上传在安卓手机上很难实现。目前暂时没有设计手机多图上传,代码要点在控制器,需要用json_encode将数组转成字符串存在数据库:
public function tbxg(Request $request) { $data = $request->all(); //dd($data); $bm = $request['bm'];//表名 $id = $request['id'];//要修改的id //视频上传 if ($request->hasFile('上传祝福视频')) { $path = $request['上传祝福视频']->store('files', 'admin'); } //多图上传 if ($request->hasFile('img')) { $file = $request->file('img'); $filePath =[]; // 定义空数组用来存放图片路径 foreach ($file as $key => $value) { // 判断图片上传中是否出错 if (!$value->isValid()) { exit("上传图片出错,请重试!"); } if(!empty($value)){//此处防止没有多文件上传的情况 $destinationPath = '/uploads/files/'; //存放目录 $extension = $value->getClientOriginalExtension(); // 上传文件后缀 $fileName = date('YmdHis').mt_rand(100,999).'.'.$extension; // 重命名 $value->move(public_path().$destinationPath, $fileName); // 保存图片 $filePath[] = url($destinationPath.'/'.$fileName); } } //dd($filePath); } unset($data['_token'],$data['bm'],$data['id']); //dd($data); if($id == 'new'){ $createone = new TableModelcx($bm);//调用模型插入一条新数据 foreach($data as $key=>$value){ if($key=='img'){ $createone->上传照片 = json_encode($filePath,JSON_UNESCAPED_UNICODE); }elseif($key=='上传祝福视频'){ $createone->$key = url('uploads/'.$path); }else{ $createone->$key = $value; } } //dd($createone); $createone->save(); session()->flash('success', '提交成功,请再次查询核对是否填报正确!'); $data = bgsxModel::orderBy('created_at','desc')->where('sfkf', '开放')->paginate(10);//以创建时间为倒序排列,取10条,分页 return redirect()->route('cxsy'); }else{ unset($data['上传祝福视频']); unset($data['img']); if ($request->hasFile('上传祝福视频')) { $path = $request['上传祝福视频']->store('files', 'admin'); $data['上传祝福视频']=url('uploads/'.$path); }elseif ($request->hasFile('img')) { $data['上传照片']=json_encode($filePath,JSON_UNESCAPED_UNICODE); } //dd($data); $xgjgs = ShipinModel::where('id', $id)->update($data);//更新现在数据 if ($xgjgs == 1){ session()->flash('success', '修改成功!'); $data = bgsxModel::orderBy('created_at','desc')->where('sfkf', '开放')->paginate(10);//以创建时间为倒序排列,取10条,分页 return redirect()->route('cxsy'); } else { echo ""; } } }
前端的要点是,视频上传要过滤用户上传类型,如果要直接打开手机相机拍摄视频,加上capture="camcorder":
多图上传和显示的要点:
@foreach(json_decode($val) as $img) @endforeach
上传时,要加上图片过滤和多图可选参数
前台效果:
后台的难点比较多,一个是需要自定义laravel-admin的功能:
$grid->actions(function ($actions) { // 去掉编辑 $actions->disableEdit(); // 去掉查看 $actions->disableView(); //添加打包压缩图片视频按钮 $actions->add(new xztableController); }); $grid->disableCreation();//禁用新增按钮
zip压缩不使用任何插件,打包下载的控制器xztableController.php:
namespace App\Admin\Controllers; use Encore\Admin\Actions\RowAction; use Illuminate\Database\Eloquent\Model; use App\Models\ShipinModel; class xztableController extends RowAction { public $name = '打包下载图片和视频'; /** * @return string */ public function handle(Model $model) { $array = $model->toArray();//模型数据转数组 $pictures = json_decode($array['上传照片']);//用户上传的照片数组 foreach($pictures as $val){ //去除https://by.dzbfsj.com/ $img[]=str_replace("https://by.dzbfsj.com/","",$val); } $video = str_replace("https://by.dzbfsj.com/","",$array['上传祝福视频']); $name = $array['姓名']; //var_dump($img); //开始打包压缩成zip下载 $zip_file = $name.'.zip'; // 要下载的压缩包的名称 // 初始化 PHP 类 $zip = new \ZipArchive(); $zip->open($zip_file, \ZipArchive::CREATE | \ZipArchive::OVERWRITE); // 添加文件:第二个参数是待压缩文件在压缩包中的路径/+文件名。 $zip->addFile($video, 'video/'.$name.'.mp4'); foreach ($img as $key=>$val){ $zip->addFile($val, 'picture/'.$key.'.jpg'); } $zip->close(); // 下载文件 return $this->response()->download(url($zip_file))->success('打包下载成功'); //unlink($zip_file);//下载后删除 //return $this->response()->success('图片和视频打包成功')->refresh(); } public function dialog() { $this->confirm('确定打包下载?'); } }
对于后台多图和视频展示,需要将数据库中字符串转数组,并自定义显示:
$grid->上传照片('上传照片')->display(function ($pictures) { return json_decode($pictures, true); })->image(); $grid->上传祝福视频('上传祝福视频')->video(['videoWidth' => '100%', 'videoHeight' => 480]);
后台展示效果: