diff --git a/app/Enums/Strategy/SftpOption.php b/app/Enums/Strategy/SftpOption.php new file mode 100644 index 00000000..3d3c94a5 --- /dev/null +++ b/app/Enums/Strategy/SftpOption.php @@ -0,0 +1,33 @@ + 'required', 'configs.bucket' => 'required', ], + StrategyKey::Sftp => [ + 'configs.root' => 'required', + 'configs.host' => 'required', + 'configs.port' => 'integer', + 'configs.username' => 'required', + 'configs.password' => 'required_if:configs.private_key,null', + 'configs.private_key' => 'required_if:configs.password,null', + 'configs.passphrase' => '', + 'configs.use_agent' => 'boolean', + ], }); } @@ -110,6 +120,16 @@ class StrategyRequest extends FormRequest 'configs.secret_key' => 'SecretKey', 'configs.bucket' => 'Bucket', ], + StrategyKey::Sftp => [ + 'configs.root' => '储存路径', + 'configs.host' => '主机地址', + 'configs.port' => '连接端口', + 'configs.username' => '用户名', + 'configs.password' => '密码', + 'configs.private_key' => '密钥', + 'configs.passphrase' => '密钥口令', + 'configs.use_agent' => '使用代理', + ], }); } } diff --git a/app/Services/ImageService.php b/app/Services/ImageService.php index dadc1725..fa0aa88e 100644 --- a/app/Services/ImageService.php +++ b/app/Services/ImageService.php @@ -10,6 +10,7 @@ use App\Enums\ImagePermission; use App\Enums\Scan\AliyunOption; use App\Enums\Strategy\CosOption; use App\Enums\Strategy\KodoOption; +use App\Enums\Strategy\SftpOption; use App\Enums\StrategyKey; use App\Enums\UserConfigKey; use App\Enums\UserStatus; @@ -28,6 +29,7 @@ use Illuminate\Http\UploadedFile; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Log; use Illuminate\Support\Str; use Intervention\Image\Facades\Image as InterventionImage; use Intervention\Image\Imagick\Font; @@ -36,6 +38,9 @@ use League\Flysystem\Filesystem; use League\Flysystem\FilesystemAdapter; use League\Flysystem\FilesystemException; use League\Flysystem\Local\LocalFilesystemAdapter; +use League\Flysystem\PhpseclibV2\SftpAdapter; +use League\Flysystem\PhpseclibV2\SftpConnectionProvider; +use League\Flysystem\UnixVisibility\PortableVisibilityConverter; use Overtrue\Flysystem\Cos\CosAdapter; use Overtrue\Flysystem\Qiniu\QiniuAdapter; @@ -151,7 +156,8 @@ class ImageService try { $filesystem->writeStream($pathname, $handle); } catch (FilesystemException $e) { - throw new UploadException('图片上传失败'); + Log::error('保存图片时出现异常', ['message' => $e->getMessage(), 'trace' => $e->getTraceAsString()]); + throw new UploadException(config('app.debug', false) ? $e->getMessage() : '图片上传失败'); } @fclose($handle); } else { @@ -211,6 +217,27 @@ class ImageService bucket: $configs->get(KodoOption::Bucket), domain: $configs->get(KodoOption::Url), ), + StrategyKey::Sftp => new SftpAdapter(new SftpConnectionProvider( + host: $configs->get(SftpOption::Host), + username: $configs->get(SftpOption::Username), + password: $configs->get(SftpOption::Password), + privateKey: $configs->get(SftpOption::PrivateKey), + passphrase: (string)$configs->get(SftpOption::Passphrase), + port: $configs->get(SftpOption::Port), + useAgent: (bool)$configs->get(SftpOption::UseAgent) + ), + root: $configs->get(SftpOption::Root), + visibilityConverter: PortableVisibilityConverter::fromArray([ + 'file' => [ + 'public' => 0640, + 'private' => 0604, + ], + 'dir' => [ + 'public' => 0740, + 'private' => 7604, + ], + ]) + ) }; } diff --git a/resources/views/admin/setting/index.blade.php b/resources/views/admin/setting/index.blade.php index 46253a85..b8b1b910 100644 --- a/resources/views/admin/setting/index.blade.php +++ b/resources/views/admin/setting/index.blade.php @@ -40,26 +40,20 @@