美文网首页Laravel备忘录
使用summerblue/administrator或者Froz

使用summerblue/administrator或者Froz

作者: 提莫小小队长 | 来源:发表于2018-11-05 15:34 被阅读2次
  1. 将config/administrator/users.php里的avatar对应的目录注释掉,换成如下这样

        'avatar' => [
        'title' => '用户头像',
         // 设置表单条目的类型,默认的 type 是 input
         'type' => 'image',
    
         // 图片上传必须设置图片存放路径
         //'location' => public_path() . '/uploads/images/avatars/',
         'location' => 'https://xxx.xxx.aliyuncs.com/uploads/images/avatars/'. date('Ymd') . DIRECTORY_SEPARATOR
     ],
    
  2. 在vendor下找到summer大神的这个包(建议fork一份在修改)
    大部分修改都在/vendor/summerblue/administrator/src/controllers/AdminController.php这个文件里,首先先把判断location是不是目录的方法改掉,文件位置(如图)下的validateDirectory()方法

~/Code/larabbs/vendor/summerblue/administrator/src/Frozennode/Administrator/Validator.php
    /**
     * Validates that an item is a directory.
     */
    public function validateDirectory($attribute, $value, $parameters)
    {
        //return is_dir($value); //于11月2号修改
        $statusDir = is_dir($value);
        $statusOss = strpos($value,"aliyuncs.com");
        if($statusDir || $statusOss){
            return true;
        }else{
            return false;
        }
    }

加了一个简单的判断,如果目录是aliyuncs的话,也返回true, 这样这里就不报错了

  1. 修改头像上传逻辑,增加了oss判断逻辑fileUpload()是上传方法, displayFile()是上传之后用于显示图片的方法,同时调用了之前写的ImageUploadHandler.php辅助类
 /**
     * The POST method that runs when a user uploads a file on a file field.
     *
     * @param string $modelName
     * @param string $fieldName
     * Request $request是lpf新加的
     * @return JSON
     */
    public function fileUpload($modelName, $fieldName, Request $request, ImageUploadHandler $uploader)
    {
        //lpf 2018/11/02 Edit
        //判断一下目录是真实目录还是OSS地址,如果是真实目录则保持源代码不变
        $path = config('administrator.users.edit_fields.avatar.location');

        if(is_dir($path)){
            //dd($modelName); //users
            //dd($fieldName); //avatar
            $fieldFactory = app('admin_field_factory');

            //get the model and the field object
            $field = $fieldFactory->findField($fieldName);

            return response()->JSON($field->doUpload());
        }else{
            /*
                 array:5 [
                    "errors" => []
                    "path" => "/home/lpf/Code/larabbs/public/uploads/images/avatars/kpAodaQyzmjevze0wwUJTgp1rMzXEHWr.jpeg"
                    "filename" => "kpAodaQyzmjevze0wwUJTgp1rMzXEHWr.jpeg"
                    "original_name" => "timg (2).jpeg"
                    "resizes" => []
                    ]
             */
            //存一份到storage/tmp下用于后面获取二进制数据流
            $result = $uploader->saveAdmin($request->file('file'),'avatars',$modelName, 362);

            return response()->JSON($result);
        }
    }
 /**
     * The GET method that displays a file field's file.
     *
     * @edit By lpf
     * @return Image / File
     */
    public function displayFile()
    {
        //判断一下目录是真实目录还是OSS地址,如果是真实目录则保持源代码不变
        $pathConfig = config('administrator.users.edit_fields.avatar.location');

        //get the stored path of the original
        $path = $this->request->input('path');

        if(!is_dir($pathConfig)){
            $tmpFileName = basename($path);

            $pathTmp = storage_path("app/tmp/{$tmpFileName}");
            $data = File::get($pathTmp);
            $file = new SFile($pathTmp);
            
            //使用完tmp下的图之后,可以考虑删掉,这里我没有做处理,保留了下来
            
        }else{
            $data = File::get($path);
            $file = new SFile($path);

        }

        $mimeType   = $file->getMimeType();
        $size       = $file->getSize();
        $fileName   = $file->getFilename();

        $headers = array(
            'Content-Type'        => $mimeType,
            'Content-Length'      => $size,
            'Content-Disposition' => 'attachment; filename="'.$fileName.'"',
        );


        return response()->make($data, 200, $headers);
    }
    public function saveAdmin($file,$folder,$file_prefix = null, $max_width = false)
    {
        //存储文件规则 uploads/images/avatars/20180808/
        $folderName = "uploads/images/$folder/".date('Ymd');

        //获取文件的后缀名
        $extension  = strtolower($file->getClientOriginalExtension()) ?? 'jpg';

        //判断图片是否正确
        if(!getimagesize($file) || !in_array($extension,$this->allowed_ext)){
            return false;
        }

        $fileName = $file_prefix . '_' . time() . '_' .str_random(10) . '.' . $extension;

        //裁剪图片
        if($max_width && $extension != 'gif'){
            //封装函数,裁剪图片
            $this->reduceSize($file->getRealPath(),$max_width);
        }
        //保存一份到/tmp目录下,为了后面获取图片信息数据
        Storage::disk('local')->putFileAs('tmp',new File($file->getRealPath()),$fileName);

        //上传图片  $file->getRealPath()获取真实文件地址,$file是个对象,虽然也能上传,但是在OSS上会建立目录
        Storage::disk('oss-public')->putFileAs($folderName,new File($file->getRealPath()),$fileName);



        return [
            'errors' => [],
            'filename' => $fileName,
            'original_name' => $file->getClientOriginalName(),
            'resizes' => [],
            'path' =>  config('app.ali_endpoint') . DIRECTORY_SEPARATOR . "$folderName/$fileName"
        ];

    }

然后再将Model下的User.php中的setAvatarAttribute()加一层验证:

    public function setAvatarAttribute($path)
    {
        $dir_path = config('administrator.users.edit_fields.avatar.location');


        //修改这块逻辑
        if(!is_dir($dir_path)){
            //oss上传
            $this->attributes['avatar'] = $dir_path.$path;
        }else{
            // 如果不是 `http` 子串开头,那就是从后台上传的,需要补全 URL
            if ( ! starts_with($path, 'http')) {

                // 拼接完整的 URL
                $path = config('app.url') . "/uploads/images/avatars/$path";
            }

            $this->attributes['avatar'] = $path;
        }
    }

这样就可以了,修改的思路就是确保原代码不动,加入oss路径判断,以及响应结果格式和原代码保持一致,这样改完,如果不想用阿里OSS,直接注释掉users.php里的location配置,继续用服务器目录也可以。
这几段代码是周五晚上临时修改的,很多地方不简洁也不严谨,也没有经过仔细测试,总觉得更好的方法应该是不修改作者源码才对,水平有限,目前还没想到好办法,有点蛋疼。

附录ImageUploadHandler.php代码

<?php
/**
 * Created by PhpStorm.
 * User: root
 * Date: 18-8-21
 * Time: 下午2:10
 */
namespace App\Handlers;

use Illuminate\Http\File;
use Illuminate\Support\Facades\Storage;
use Image;

class ImageUploadHandler
{
    /**
     *
     * File move(string $directory, string $name = null)
        Moves the file to a new location.

        Parameters
        string  $directory  The destination folder
        string  $name   The new file name
        Return Value
        File    A File object representing the new file
        Exceptions
        FileException   if, for any reason, the file could not have been moved
     */
    //只允许以下后缀名的图片文件上传
    protected $allowed_ext = ['png','jpg','gif','jpeg'];


    public function save($file,$folder,$file_prefix = null, $max_width = false)
    {
        //存储文件规则 uploads/images/avatars/20180808/
        $folderName = "uploads/images/$folder/".date('Ymd');

        //获取文件的后缀名
        $extension  = strtolower($file->getClientOriginalExtension()) ?? 'jpg';

        //判断图片是否正确
        if(!getimagesize($file) || !in_array($extension,$this->allowed_ext)){
            return false;
        }

        $fileName = $file_prefix . '_' . time() . '_' .str_random(10) . '.' . $extension;

        //裁剪图片
        if($max_width && $extension != 'gif'){
            //封装函数,裁剪图片
            $this->reduceSize($file->getRealPath(),$max_width);
        }
        //上传图片  $file->getRealPath()获取真实文件地址,$file是个对象,虽然也能上传,但是在OSS上会建立目录
        Storage::disk('oss-public')->putFileAs($folderName,new File($file->getRealPath()),$fileName);



        return [
            'path' =>  config('app.ali_endpoint') . DIRECTORY_SEPARATOR . "$folderName/$fileName"
        ];

    }

    public function saveAdmin($file,$folder,$file_prefix = null, $max_width = false)
    {
        //存储文件规则 uploads/images/avatars/20180808/
        $folderName = "uploads/images/$folder/".date('Ymd');

        //获取文件的后缀名
        $extension  = strtolower($file->getClientOriginalExtension()) ?? 'jpg';

        //判断图片是否正确
        if(!getimagesize($file) || !in_array($extension,$this->allowed_ext)){
            return false;
        }

        $fileName = $file_prefix . '_' . time() . '_' .str_random(10) . '.' . $extension;

        //裁剪图片
        if($max_width && $extension != 'gif'){
            //封装函数,裁剪图片
            $this->reduceSize($file->getRealPath(),$max_width);
        }
        //保存一份到/tmp目录下,为了后面获取图片信息数据
        Storage::disk('local')->putFileAs('tmp',new File($file->getRealPath()),$fileName);

        //上传图片  $file->getRealPath()获取真实文件地址,$file是个对象,虽然也能上传,但是在OSS上会建立目录
        Storage::disk('oss-public')->putFileAs($folderName,new File($file->getRealPath()),$fileName);



        return [
            'errors' => [],
            'filename' => $fileName,
            'original_name' => $file->getClientOriginalName(),
            'resizes' => [],
            'path' =>  config('app.ali_endpoint') . DIRECTORY_SEPARATOR . "$folderName/$fileName"
        ];

    }

    public function reduceSize($file_path, $max_width)
    {
        //实例化, 参数是文件的磁盘物理路径
        $image = Image::make($file_path);

        //调整大小
        $image->resize($max_width, null, function($constraint){
            // 设定宽度是 $max_width,高度等比例双方缩放
            $constraint->aspectRatio();

            // 防止裁图时图片尺寸变大
            $constraint->upsize();
        });

        // 对图片修改后进行保存
        $image->save();
    }
}

相关文章

网友评论

    本文标题:使用summerblue/administrator或者Froz

    本文链接:https://www.haomeiwen.com/subject/srusxqtx.html