|
|
@@ -0,0 +1,413 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace App\Module\File\Services;
|
|
|
+
|
|
|
+use App\Module\File\Models\FileStorageConfig;
|
|
|
+use App\Module\File\Models\FileStorageConfigHistory;
|
|
|
+use Illuminate\Support\Facades\Cache;
|
|
|
+use Illuminate\Support\Facades\Log;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 存储配置服务类
|
|
|
+ *
|
|
|
+ * 提供存储配置的业务逻辑处理,包括配置的读取、更新和缓存管理
|
|
|
+ */
|
|
|
+class StorageConfigService
|
|
|
+{
|
|
|
+ /**
|
|
|
+ * 缓存前缀
|
|
|
+ */
|
|
|
+ const CACHE_PREFIX = 'file_storage_config:';
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 缓存过期时间(秒)
|
|
|
+ */
|
|
|
+ const CACHE_TTL = 3600; // 1小时
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取默认存储磁盘配置
|
|
|
+ *
|
|
|
+ * @return FileStorageConfig|null 存储配置模型
|
|
|
+ */
|
|
|
+ public function getDefaultDisk()
|
|
|
+ {
|
|
|
+ return Cache::remember(self::CACHE_PREFIX . 'default:' . app()->environment(), self::CACHE_TTL, function () {
|
|
|
+ return FileStorageConfig::where('is_default', true)
|
|
|
+ ->where('status', true)
|
|
|
+ ->where('env', app()->environment())
|
|
|
+ ->first();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取临时存储磁盘配置
|
|
|
+ *
|
|
|
+ * @return FileStorageConfig|null 存储配置模型
|
|
|
+ */
|
|
|
+ public function getTempDisk()
|
|
|
+ {
|
|
|
+ return Cache::remember(self::CACHE_PREFIX . 'temp:' . app()->environment(), self::CACHE_TTL, function () {
|
|
|
+ return FileStorageConfig::where('is_temp', true)
|
|
|
+ ->where('status', true)
|
|
|
+ ->where('env', app()->environment())
|
|
|
+ ->first();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取指定名称的存储磁盘配置
|
|
|
+ *
|
|
|
+ * @param string $name 存储磁盘名称
|
|
|
+ * @return FileStorageConfig|null 存储配置模型
|
|
|
+ */
|
|
|
+ public function getDisk(string $name)
|
|
|
+ {
|
|
|
+ return Cache::remember(self::CACHE_PREFIX . 'name:' . $name . ':' . app()->environment(), self::CACHE_TTL, function () use ($name) {
|
|
|
+ return FileStorageConfig::where('name', $name)
|
|
|
+ ->where('status', true)
|
|
|
+ ->where('env', app()->environment())
|
|
|
+ ->first();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取所有启用的存储磁盘配置
|
|
|
+ *
|
|
|
+ * @param string|null $env 环境名称,为null时获取当前环境
|
|
|
+ * @return \Illuminate\Database\Eloquent\Collection 存储配置集合
|
|
|
+ */
|
|
|
+ public function getAllDisks(string $env = null)
|
|
|
+ {
|
|
|
+ $env = $env ?: app()->environment();
|
|
|
+
|
|
|
+ return Cache::remember(self::CACHE_PREFIX . 'all:' . $env, self::CACHE_TTL, function () use ($env) {
|
|
|
+ return FileStorageConfig::where('status', true)
|
|
|
+ ->where('env', $env)
|
|
|
+ ->get();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建存储磁盘配置
|
|
|
+ *
|
|
|
+ * @param string $name 存储磁盘名称
|
|
|
+ * @param string $driver 存储驱动
|
|
|
+ * @param array $config 配置值
|
|
|
+ * @param string $description 配置描述
|
|
|
+ * @param bool $isDefault 是否默认存储
|
|
|
+ * @param bool $isTemp 是否用于临时存储
|
|
|
+ * @param string $env 环境名称
|
|
|
+ * @param int $createdBy 创建人ID
|
|
|
+ * @return FileStorageConfig 存储配置模型
|
|
|
+ */
|
|
|
+ public function createDisk(string $name, string $driver, array $config, string $description = '', bool $isDefault = false, bool $isTemp = false, string $env = 'production', int $createdBy = 0)
|
|
|
+ {
|
|
|
+ // 如果设置为默认存储,则将其他配置的默认标志设为false
|
|
|
+ if ($isDefault) {
|
|
|
+ $this->resetDefaultFlag($env);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果设置为临时存储,则将其他配置的临时标志设为false
|
|
|
+ if ($isTemp) {
|
|
|
+ $this->resetTempFlag($env);
|
|
|
+ }
|
|
|
+
|
|
|
+ $storageConfig = new FileStorageConfig();
|
|
|
+ $storageConfig->name = $name;
|
|
|
+ $storageConfig->driver = $driver;
|
|
|
+ $storageConfig->config = $config;
|
|
|
+ $storageConfig->description = $description;
|
|
|
+ $storageConfig->is_default = $isDefault;
|
|
|
+ $storageConfig->is_temp = $isTemp;
|
|
|
+ $storageConfig->env = $env;
|
|
|
+ $storageConfig->status = true;
|
|
|
+ $storageConfig->created_by = $createdBy;
|
|
|
+ $storageConfig->updated_by = $createdBy;
|
|
|
+ $storageConfig->save();
|
|
|
+
|
|
|
+ // 清除缓存
|
|
|
+ $this->clearCache();
|
|
|
+
|
|
|
+ return $storageConfig;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新存储磁盘配置
|
|
|
+ *
|
|
|
+ * @param int $id 存储配置ID
|
|
|
+ * @param string $driver 存储驱动
|
|
|
+ * @param array $config 配置值
|
|
|
+ * @param string $description 配置描述
|
|
|
+ * @param bool $isDefault 是否默认存储
|
|
|
+ * @param bool $isTemp 是否用于临时存储
|
|
|
+ * @param int $status 状态
|
|
|
+ * @param int $updatedBy 更新人ID
|
|
|
+ * @param string $reason 变更原因
|
|
|
+ * @return FileStorageConfig 存储配置模型
|
|
|
+ */
|
|
|
+ public function updateDisk(int $id, string $driver, array $config, string $description = '', bool $isDefault = false, bool $isTemp = false, int $status = 1, int $updatedBy = 0, string $reason = '')
|
|
|
+ {
|
|
|
+ $storageConfig = FileStorageConfig::findOrFail($id);
|
|
|
+ $oldData = $storageConfig->toArray();
|
|
|
+
|
|
|
+ // 如果设置为默认存储,则将其他配置的默认标志设为false
|
|
|
+ if ($isDefault && !$storageConfig->is_default) {
|
|
|
+ $this->resetDefaultFlag($storageConfig->env);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果设置为临时存储,则将其他配置的临时标志设为false
|
|
|
+ if ($isTemp && !$storageConfig->is_temp) {
|
|
|
+ $this->resetTempFlag($storageConfig->env);
|
|
|
+ }
|
|
|
+
|
|
|
+ $storageConfig->driver = $driver;
|
|
|
+ $storageConfig->config = $config;
|
|
|
+ $storageConfig->description = $description;
|
|
|
+ $storageConfig->is_default = $isDefault;
|
|
|
+ $storageConfig->is_temp = $isTemp;
|
|
|
+ $storageConfig->status = (bool)$status;
|
|
|
+ $storageConfig->updated_by = $updatedBy;
|
|
|
+ $storageConfig->save();
|
|
|
+
|
|
|
+ // 记录变更历史
|
|
|
+ $this->recordHistory($id, $oldData, $storageConfig->toArray(), $updatedBy, $reason);
|
|
|
+
|
|
|
+ // 清除缓存
|
|
|
+ $this->clearCache();
|
|
|
+
|
|
|
+ return $storageConfig;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 删除存储磁盘配置
|
|
|
+ *
|
|
|
+ * @param int $id 存储配置ID
|
|
|
+ * @param int $deletedBy 删除人ID
|
|
|
+ * @param string $reason 删除原因
|
|
|
+ * @return bool 是否成功
|
|
|
+ */
|
|
|
+ public function deleteDisk(int $id, int $deletedBy = 0, string $reason = '')
|
|
|
+ {
|
|
|
+ $storageConfig = FileStorageConfig::findOrFail($id);
|
|
|
+ $oldData = $storageConfig->toArray();
|
|
|
+
|
|
|
+ // 记录删除历史
|
|
|
+ $this->recordHistory($id, $oldData, [], $deletedBy, $reason ?: '删除配置');
|
|
|
+
|
|
|
+ $result = $storageConfig->delete();
|
|
|
+
|
|
|
+ // 清除缓存
|
|
|
+ $this->clearCache();
|
|
|
+
|
|
|
+ return $result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置默认存储磁盘
|
|
|
+ *
|
|
|
+ * @param int $id 存储配置ID
|
|
|
+ * @param int $updatedBy 更新人ID
|
|
|
+ * @return bool 是否成功
|
|
|
+ */
|
|
|
+ public function setDefaultDisk(int $id, int $updatedBy = 0)
|
|
|
+ {
|
|
|
+ $storageConfig = FileStorageConfig::findOrFail($id);
|
|
|
+ $oldData = $storageConfig->toArray();
|
|
|
+
|
|
|
+ // 重置当前环境中的所有默认标志
|
|
|
+ $this->resetDefaultFlag($storageConfig->env);
|
|
|
+
|
|
|
+ // 设置当前配置为默认
|
|
|
+ $storageConfig->is_default = true;
|
|
|
+ $storageConfig->updated_by = $updatedBy;
|
|
|
+ $result = $storageConfig->save();
|
|
|
+
|
|
|
+ // 记录变更历史
|
|
|
+ $this->recordHistory($id, $oldData, $storageConfig->toArray(), $updatedBy, '设置为默认存储磁盘');
|
|
|
+
|
|
|
+ // 清除缓存
|
|
|
+ $this->clearCache();
|
|
|
+
|
|
|
+ return $result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置临时存储磁盘
|
|
|
+ *
|
|
|
+ * @param int $id 存储配置ID
|
|
|
+ * @param int $updatedBy 更新人ID
|
|
|
+ * @return bool 是否成功
|
|
|
+ */
|
|
|
+ public function setTempDisk(int $id, int $updatedBy = 0)
|
|
|
+ {
|
|
|
+ $storageConfig = FileStorageConfig::findOrFail($id);
|
|
|
+ $oldData = $storageConfig->toArray();
|
|
|
+
|
|
|
+ // 重置当前环境中的所有临时标志
|
|
|
+ $this->resetTempFlag($storageConfig->env);
|
|
|
+
|
|
|
+ // 设置当前配置为临时存储
|
|
|
+ $storageConfig->is_temp = true;
|
|
|
+ $storageConfig->updated_by = $updatedBy;
|
|
|
+ $result = $storageConfig->save();
|
|
|
+
|
|
|
+ // 记录变更历史
|
|
|
+ $this->recordHistory($id, $oldData, $storageConfig->toArray(), $updatedBy, '设置为临时存储磁盘');
|
|
|
+
|
|
|
+ // 清除缓存
|
|
|
+ $this->clearCache();
|
|
|
+
|
|
|
+ return $result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取存储磁盘配置变更历史
|
|
|
+ *
|
|
|
+ * @param int $configId 存储配置ID
|
|
|
+ * @return \Illuminate\Database\Eloquent\Collection 配置历史集合
|
|
|
+ */
|
|
|
+ public function getHistory(int $configId)
|
|
|
+ {
|
|
|
+ return FileStorageConfigHistory::where('config_id', $configId)
|
|
|
+ ->orderBy('id', 'desc')
|
|
|
+ ->get();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 清除存储配置缓存
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function clearCache()
|
|
|
+ {
|
|
|
+ $cacheKeys = [
|
|
|
+ self::CACHE_PREFIX . 'default:' . app()->environment(),
|
|
|
+ self::CACHE_PREFIX . 'temp:' . app()->environment(),
|
|
|
+ self::CACHE_PREFIX . 'all:' . app()->environment()
|
|
|
+ ];
|
|
|
+
|
|
|
+ foreach ($cacheKeys as $key) {
|
|
|
+ Cache::forget($key);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 清除所有名称缓存
|
|
|
+ $disks = FileStorageConfig::where('env', app()->environment())->get();
|
|
|
+ foreach ($disks as $disk) {
|
|
|
+ Cache::forget(self::CACHE_PREFIX . 'name:' . $disk->name . ':' . app()->environment());
|
|
|
+ }
|
|
|
+
|
|
|
+ Log::info('存储配置缓存已清除');
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 重置默认存储标志
|
|
|
+ *
|
|
|
+ * @param string $env 环境名称
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ protected function resetDefaultFlag(string $env)
|
|
|
+ {
|
|
|
+ FileStorageConfig::where('env', $env)
|
|
|
+ ->where('is_default', true)
|
|
|
+ ->update(['is_default' => false]);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 重置临时存储标志
|
|
|
+ *
|
|
|
+ * @param string $env 环境名称
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ protected function resetTempFlag(string $env)
|
|
|
+ {
|
|
|
+ FileStorageConfig::where('env', $env)
|
|
|
+ ->where('is_temp', true)
|
|
|
+ ->update(['is_temp' => false]);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 记录存储配置变更历史
|
|
|
+ *
|
|
|
+ * @param int $configId 存储配置ID
|
|
|
+ * @param array $oldData 旧数据
|
|
|
+ * @param array $newData 新数据
|
|
|
+ * @param int $changedBy 变更人ID
|
|
|
+ * @param string $reason 变更原因
|
|
|
+ * @return FileStorageConfigHistory 配置历史模型
|
|
|
+ */
|
|
|
+ protected function recordHistory(int $configId, array $oldData, array $newData, int $changedBy, string $reason = '')
|
|
|
+ {
|
|
|
+ return FileStorageConfigHistory::create([
|
|
|
+ 'config_id' => $configId,
|
|
|
+ 'old_driver' => $oldData['driver'] ?? null,
|
|
|
+ 'new_driver' => $newData['driver'] ?? null,
|
|
|
+ 'old_config' => isset($oldData['config']) ? $oldData['config'] : null,
|
|
|
+ 'new_config' => isset($newData['config']) ? $newData['config'] : null,
|
|
|
+ 'old_status' => $oldData['status'] ?? null,
|
|
|
+ 'new_status' => $newData['status'] ?? null,
|
|
|
+ 'changed_by' => $changedBy,
|
|
|
+ 'change_reason' => $reason,
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 测试存储配置连接
|
|
|
+ *
|
|
|
+ * @param string $driver 存储驱动
|
|
|
+ * @param array $config 配置值
|
|
|
+ * @return array 测试结果,包含success和message字段
|
|
|
+ */
|
|
|
+ public function testConnection(string $driver, array $config)
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ // 创建临时磁盘配置
|
|
|
+ $diskName = 'temp_test_' . time();
|
|
|
+ $fullConfig = array_merge(['driver' => $driver], $config);
|
|
|
+ config(["filesystems.disks.{$diskName}" => $fullConfig]);
|
|
|
+
|
|
|
+ // 测试连接
|
|
|
+ $disk = \Storage::disk($diskName);
|
|
|
+ $testFile = 'test_' . time() . '.txt';
|
|
|
+ $disk->put($testFile, 'Testing connection at ' . now());
|
|
|
+ $content = $disk->get($testFile);
|
|
|
+ $disk->delete($testFile);
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'success' => true,
|
|
|
+ 'message' => '连接成功!测试文件已成功创建和删除。',
|
|
|
+ ];
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::error('存储配置连接测试失败', [
|
|
|
+ 'driver' => $driver,
|
|
|
+ 'config' => $config,
|
|
|
+ 'error' => $e->getMessage(),
|
|
|
+ ]);
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'success' => false,
|
|
|
+ 'message' => '连接失败:' . $e->getMessage(),
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 注册存储配置到Laravel文件系统
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function registerStorageConfigs()
|
|
|
+ {
|
|
|
+ $disks = $this->getAllDisks();
|
|
|
+
|
|
|
+ foreach ($disks as $disk) {
|
|
|
+ $config = array_merge(['driver' => $disk->driver], $disk->config);
|
|
|
+ config(["filesystems.disks.{$disk->name}" => $config]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置默认磁盘
|
|
|
+ $defaultDisk = $this->getDefaultDisk();
|
|
|
+ if ($defaultDisk) {
|
|
|
+ config(['filesystems.default' => $defaultDisk->name]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|