UploadOssService.php 7.25 KB
Newer Older
chentianyu's avatar
chentianyu committed
1 2
<?php

chentianyu's avatar
chentianyu committed
3
namespace Meibuyu\Common\UploadOss;
chentianyu's avatar
chentianyu committed
4 5

use Hyperf\Contract\ConfigInterface;
chentianyu's avatar
chentianyu committed
6
use League\Flysystem\Filesystem;
chentianyu's avatar
chentianyu committed
7 8 9
use Hyperf\Filesystem\FilesystemFactory;
use Hyperf\HttpMessage\Upload\UploadedFile;
use League\Flysystem\FileExistsException;
chentianyu's avatar
chentianyu committed
10
use Meibuyu\Common\Exceptions\HttpResponseException;
chentianyu's avatar
chentianyu committed
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
use Psr\Container\ContainerInterface;

class UploadOssService
{

    /**
     * @var FilesystemFactory
     */
    private $factory;

    /**
     * @var ConfigInterface
     */
    private $config;

    /**
     * @var string
     */
    private $urlPrefix;

    /**
     * @var string
     */
    private $appDev;

chentianyu's avatar
chentianyu committed
36 37 38 39 40
    /**
     * @var string
     */
    private $appName;

41 42 43 44 45 46
    /**
     * 是否自动保存数据库
     * @var bool
     */
    private $autoSaveDataBase = true;

chentianyu's avatar
chentianyu committed
47 48 49 50 51 52 53 54 55 56
    public static $options = [
        'maxSize' => 10 * 1024 * 1024, // 文件大小,10M
        'mime' => ['jpeg', 'png', 'gif', 'jpg', 'svg', 'txt', 'pdf', 'xlsx', 'xls', 'doc', 'docx', 'rar', 'zip', 'csv'], // 允许上传的文件类型
    ];

    public function __construct(ContainerInterface $container)
    {
        $this->config = $container->get(ConfigInterface::class);
        $this->factory = $container->get(FilesystemFactory::class);
        $ossConfig = $this->config->get('file.storage.oss');
chentianyu's avatar
chentianyu committed
57
        $this->urlPrefix = 'https://' . $ossConfig['bucket'] . '.' . $ossConfig['endpoint'] . '/';
chentianyu's avatar
chentianyu committed
58
        $this->appDev = $this->config->get('app_env');
chentianyu's avatar
chentianyu committed
59
        $this->appName = $this->config->get('app_name');
chentianyu's avatar
chentianyu committed
60 61
    }

62 63 64 65 66 67 68 69 70 71
    /**
     * 设置是否自动保存记录到数据库
     * @param bool $bool
     * @author chentianyu
     */
    public function setAutoSaveDataBase(bool $bool)
    {
        $this->autoSaveDataBase = $bool;
    }

chentianyu's avatar
chentianyu committed
72
    /**
chentianyu's avatar
chentianyu committed
73
     * 上传图片
chentianyu's avatar
chentianyu committed
74
     * @param \Hyperf\HttpMessage\Upload\UploadedFile $image
chentianyu's avatar
chentianyu committed
75
     * @param string $module
76
     * @return array|string
chentianyu's avatar
chentianyu committed
77
     * @throws \Meibuyu\Common\Exceptions\HttpResponseException
chentianyu's avatar
chentianyu committed
78
     * @author chentianyu
chentianyu's avatar
chentianyu committed
79
     */
chentianyu's avatar
chentianyu committed
80
    public function uploadImage(UploadedFile $image, string $module, $userId, $uniqueFileName = true)
chentianyu's avatar
chentianyu committed
81
    {
chentianyu's avatar
chentianyu committed
82 83 84
        $ext = $image->getExtension();
        $clientFilename = $image->getClientFilename();
        $fileName = $uniqueFileName ? ($this->genUniqueFileName() . '.' . $ext) : $clientFilename;
chentianyu's avatar
chentianyu committed
85
        $options = ['mime' => ['jpeg', 'png', 'gif', 'jpg', 'svg']];
86
        $filePath = 'oss2/' . $this->appDev . "/" . $this->appName . "/$module/images/" . today() . "/$userId/" . $fileName;
chentianyu's avatar
chentianyu committed
87
        $this->upload($image, $filePath, $options);
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
        if($this->autoSaveDataBase){
            $model = new FileModel();
            $model = $model->newInstance([
                'type'  => 'image',
                'module'  => $module,
                'user_id' => $userId,
                'source_name' => $clientFilename,
                'name' => $fileName,
                'path' => $this->urlPrefix . $filePath,
                'ext'  => $ext,
                'size' => num_2_file_size($image->getSize()),
            ]);
            $model->save();
            return $model->toArray();
        }else{
            return $this->urlPrefix . $filePath;
        }

chentianyu's avatar
chentianyu committed
106 107
    }

chentianyu's avatar
chentianyu committed
108 109 110
    /**
     * 上传文件
     * @param \Hyperf\HttpMessage\Upload\UploadedFile $image
chentianyu's avatar
chentianyu committed
111
     * @param string $module
112
     * @return array|string
chentianyu's avatar
chentianyu committed
113
     * @throws \Meibuyu\Common\Exceptions\HttpResponseException
chentianyu's avatar
chentianyu committed
114
     * @author chentianyu
chentianyu's avatar
chentianyu committed
115
     */
chentianyu's avatar
chentianyu committed
116
    public function uploadFile(UploadedFile $file, string $module, $userId, $uniqueFileName = true, array $options = [])
chentianyu's avatar
chentianyu committed
117
    {
chentianyu's avatar
chentianyu committed
118 119 120
        $ext = $file->getExtension();
        $clientFilename = $file->getClientFilename();
        $fileName = $uniqueFileName ? ($this->genUniqueFileName() . '.' . $ext) : $clientFilename;
121
        $filePath = 'oss2/' . $this->appDev . "/" . $this->appName . "/$module/files/" . today() . "/$userId/" . $fileName;
chentianyu's avatar
chentianyu committed
122
        $this->upload($file, $filePath, $options);
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
        if($this->autoSaveDataBase){
            $model = new FileModel();
            $model = $model->newInstance([
                'type'  => 'file',
                'module'  => $module,
                'user_id' => $userId,
                'source_name' => $clientFilename,
                'name' => $fileName,
                'path' => $this->urlPrefix . $filePath,
                'ext'  => $ext,
                'size' => num_2_file_size($file->getSize()),
            ]);
            $model->save();
            return $model->toArray();
        }else{
            return $this->urlPrefix . $filePath;
        }

chentianyu's avatar
chentianyu committed
141 142
    }

chentianyu's avatar
chentianyu committed
143 144
    /**
     * @param \Hyperf\HttpMessage\Upload\UploadedFile $file
chentianyu's avatar
chentianyu committed
145
     * @param $filePath
chentianyu's avatar
chentianyu committed
146 147
     * @param array $options
     * @return bool
chentianyu's avatar
chentianyu committed
148
     * @throws \Meibuyu\Common\Exceptions\HttpResponseException
chentianyu's avatar
chentianyu committed
149
     * @author chentianyu
chentianyu's avatar
chentianyu committed
150
     */
chentianyu's avatar
chentianyu committed
151
    public function upload(UploadedFile $file, string $filePath, array $options = [])
chentianyu's avatar
chentianyu committed
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
    {
        if ($file->isValid()) {
            $options = array_merge(self::$options, $options);
            $extension = strtolower($file->getExtension());
            // 通过扩展名判断类型
            if (!in_array($extension, $options['mime'])) {
                throw new HttpResponseException('文件类型不支持,目前只支持' . implode(',', $options['mime']));
            }
            // 判断文件大小
            if ($file->getSize() > $options['maxSize']) {
                throw new HttpResponseException('文件超出系统规定的大小,最大不能超过' . num_2_file_size($options['maxSize']));
            }
            try {
                $oss = $this->factory->get('oss');
                $stream = fopen($file->getRealPath(), 'r+');
chentianyu's avatar
chentianyu committed
167
                $res = $oss->writeStream($filePath, $stream);
chentianyu's avatar
chentianyu committed
168 169 170 171 172 173 174 175 176 177
                is_resource($stream) && fclose($stream);
                return $res;
            } catch (FileExistsException $e) {
                throw new HttpResponseException($e->getMessage());
            }
        } else {
            throw new HttpResponseException('文件无效');
        }
    }

Liu lu's avatar
Liu lu committed
178 179 180 181
    /**
     * 上传本地文件到oss
     * @param string $localFilePath
     * @param string $ossFilePath 枚举key
Liu lu's avatar
Liu lu committed
182
     * @param bool $fixedDir 使用oss固定目录
Liu lu's avatar
Liu lu committed
183 184 185 186 187
     * @return mixed
     * @throws HttpResponseException
     * @author Liu lu
     * date 2023-02-09
     */
Liu lu's avatar
Liu lu committed
188
    public function uploadLocalFile(string $localFilePath,  string $ossFilePath,$fixedDir=false)
Liu lu's avatar
Liu lu committed
189 190
    {
        $extension = pathinfo(parse_url($localFilePath,PHP_URL_PATH),PATHINFO_EXTENSION);
Liu lu's avatar
Liu lu committed
191 192 193 194 195 196
        if($fixedDir){
            $ossFilePath      = 'oss2/'.env('APP_ENV').'/'.env('APP_NAME') ."/{$ossFilePath}/". md5($localFilePath).'.'.$extension;
        }else{
            $fileName = $this->genUniqueFileName() . '.' . $extension;
            $ossFilePath      = 'oss2/'. $this->appDev .'/'. $this->appName ."/{$ossFilePath}/". today() .'/'. $fileName;
        }
Liu lu's avatar
Liu lu committed
197 198 199 200 201 202 203 204 205 206 207 208

        try {
            $oss = $this->factory->get('oss');
            $stream = fopen($localFilePath, 'r+');
            $oss->writeStream($ossFilePath, $stream);
            is_resource($stream) && fclose($stream);
            return $this->urlPrefix . $ossFilePath;
        } catch (FileExistsException $e) {
            throw new HttpResponseException($e->getMessage());
        }
    }

chentianyu's avatar
chentianyu committed
209 210 211 212 213 214 215 216 217 218
    /**
     * 生成唯一文件名
     * @return string
     * @author chentianyu
     */
    public function genUniqueFileName()
    {
        return date('YmdHis') . uniqid();
    }

chentianyu's avatar
chentianyu committed
219
}