ImageController.php 8.6 KB
<?php

namespace App\Http\Controllers\File;

use App\Enums\Common\Code;
use App\Http\Controllers\type;
use App\Models\File\Image as ImageModel;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Facades\Image;

class ImageController
{
    public $upload_img = [
            //设置静态缓存参数(304)
            'header' => [
                'Cache-Control' => 'max-age=2592000',
                'Pragma' => 'cache',
                'Expires' => "%Expires%", // cache 1 month
                'etag' => "%etag%",
                'Last-Modified' => "%Last-Modified%",
                'Content-Description' => 'File Transfer',
            ],
    ];
    const TYPE = 1;

    public $path = '';

    public $config = '';

    public $thr_path = '';

    public $request = '';

    public function __construct()
    {
        $this->request = request();
        $this->config = config('filesystems.disks.upload');
        $this->uploads = config('upload.default_image');
        $this->path = $this->config['root'].$this->uploads['path'].'/';
    }

    /**
     * @param $hash
     * @param $w
     * @param $h
     * @name   :index
     * @author :lyh
     * @method :post
     * @time   :2023/5/11 17:19
     */
    public function index($hash = '', $w = 0 ,$h = 0 ){
        if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) || isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
            header("HTTP/1.1 304 Not Modified");
            exit;
        }
        $imageModel = new ImageModel();
        $info = $imageModel->read(['hash'=>$hash]);
        if ($info === false) {
            $this->response('指定图片不存在!', Code::USER_ERROR);
        }
        //查看缩略图是否存在
        $filename = $this->path . $info['hash'] . $w . '_' . $h;
        if(is_file($filename)){
            $last_modified_time = gmdate(time() + ((30 * 60 * 60 * 24))) . " GMT";
            $header = str_replace(['%Expires%', "%etag%", '%Last-Modified%'],
                [$last_modified_time, $hash . ':' . $w . '_' . $h . '_' . 1, $last_modified_time], $this->upload_img['header']);
            $content = file_get_contents($filename);
            $header['Content-Length'] = strlen($content);
        }else{
            $path = $info['path'];
            if (!is_file($path)) {
                $this->response('指定图片已被系统删除!', Code::USER_ERROR);
            }
            $content = '';
            $last_modified_time = gmdate(time() + ((30 * 60 * 60 * 24))) . " GMT";
            $header = str_replace(['%Expires%', "%etag%", '%Last-Modified%'],
                [$last_modified_time, $hash . ':' . $w . '_' . $h . '_' . 1, $last_modified_time], $this->upload_img['header']);
            if ($w > 0 && $h > 0) {
                $path = $this->cacheImage($info, $w, $h);
                $content = file_get_contents($path);
                $header['Content-Length'] = strlen($content);
            } else {
                $content = file_get_contents($path);
                $header['Content-Length'] = strlen($content);
            }
        }
        $header['Content-Type'] = 'image/'.$info['type'];
        return response($content,200,$header);
    }

    /**
     * @name   :(图片上传)upload
     * @author :lyh
     * @method :post
     * @time   :2023/6/17 16:28
     */
    public function upload() {
        $this->request->validate([
            'image'=>['required'],
        ],[
            'image.required'=>'图片必须填写',
        ]);
        $files = $this->request->file('image');
        if (empty($files)) {
            $this->response('没有上传的文件!', 400);
        }
        $type = $this->request->post('type', 'single');
        if ($type == 'multi') {
            return $this->multi($files);
        } else {
            return $this->single($files);
        }
    }

    /**
     * @param $files
     * @remark :单图片上传
     * @name   :single
     * @author :lyh
     * @method :post
     * @time   :2023/6/17 16:30
     */
    public function single($files){
        $hash = hash_file('md5', $files->getPathname());
        //查看文件是否存在
        $imageModel = new ImageModel();
        $image_hash = $imageModel->read(['hash'=>$hash]);
        if($image_hash !== false){
            return $this->response('图片资源',Code::SUCCESS,['image'=>$hash]);
        }
        $url = $this->path;
        $fileName = uniqid().rand(10000,99999).'.'.$files->getClientOriginalExtension();
        $res =  $files->move($url,$fileName);
        if ($res === false) {
            return $this->response($files->getError(), Code::USER_ERROR);
        }
        $data = [
            'path' => $url.$fileName,
            'created_at' => date('Y-m-d H:i:s',time()),
            'size' => $res->getSize(),
            'hash' => $hash,
            'type'=>$files->getClientOriginalExtension(),
        ];
        $rs = $imageModel->add($data);
        if ($rs === false) {
            return $this->response('添加失败', Code::USER_ERROR);
        }
        return $this->response('图片资源',Code::SUCCESS,['image'=>$hash]);
    }

    /**
     * @param $info
     * @param $w
     * @param $h
     * @remark :生成缩略图
     * @name   :cacheImage
     * @author :lyh
     * @method :post
     * @time   :2023/6/17 16:31
     */
    private function cacheImage($info, $w, $h) {
        $path = $info['path'];
        $filename = $this->path . $info['hash'] . $w . '_' . $h;
        Image::make($path)->resize($w, $h)->save($filename);
        return $filename;
    }

    /**
     * @param $files
     * @remark :多图片上传
     * @name   :multi
     * @author :lyh
     * @method :post
     * @time   :2023/6/17 16:31
     */
    private function multi($files) {

        if (!is_array($files)) {
            $files = [$files];
        }
        $save_data = [];
        $data = [];
        foreach ($files as $file) {
            $imageModel = new ImageModel();
            $hash = hash_file('md5', $file->getPathname());
            $image_hash = $imageModel->read(['hash'=>$hash]);
            if($image_hash !== false){
                $data[] = ['image'=>$hash];
                continue;
            }
            $url = $this->path;
            $fileName = uniqid().rand(10000,99999).'.'.$file->getClientOriginalExtension();
            $res = $file->move($url,$fileName);
            if ($res === false) {
                return $this->response($file->getError(), Code::USER_ERROR);
            }
            $save_data[] = [
                'path' => $url.$fileName,
                'created_at' => date('Y-m-d H:i:s',time()),
                'updated_at'=>date('Y-m-d H:i:s',time()),
                'size' => $res->getSize(),
                'hash' => $hash,
                'type'=>$file->getClientOriginalExtension(),
            ];
            $data[] = ['image'=>$hash];
        }
        $imageModel->insert($save_data);
        return $this->response('图片资源',Code::SUCCESS,$data);
    }

    //下载
    public function download($filename){
        $path = Storage::path($filename);
        return response()->download($path,time().rand(1,100000));
    }
    /**
     * @name 统一返回参数
     * @return JsonResponse
     * @author :liyuhang
     * @method
     */
    public function response($msg = null,string $code = Code::SUCCESS,$data = [],$result_code = 200,$type = 'application/json'): JsonResponse
    {
        $code = Code::fromValue($code);
        $result = [
            'msg' => $msg == ' ' ? $code->description : $msg,
            'code' => $code->value,
            'data' => $this->_extents($data),
        ];
        $this->header['Content-Type'] = $type;
        $response =  response($result,$result_code,$this->header);
        throw new HttpResponseException($response);
    }

    /**
     * @param $data
     * @name :返回参数处理
     * @return array|string
     * @author :liyuhang
     * @method
     */
    protected function _extents($data) {

        if (empty($data) || !is_array($data)) {
            return empty($data) ? is_array($data) ? [] : '' : $data;
        }
        foreach ($data as $k => $v) {
            if (is_array($v)) {
                $data[$k] = $this->_extents($v);
            } else {
                if (is_null($v)) {
                    $data[$k] = '';
                    continue;
                }
                //获取操作人
                switch ((string) $k) {
                    case 'image':
                        $data['image_link'] = url('/b/image/' . $v);
                        break;
                }
            }
        }
        return $data;
    }
}