diff --git a/.gitignore b/.gitignore index d005c20..0f1e652 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ .env config/install/lock/install.lock /public/upload +/public/storage /public/docs runtime/admin runtime/log diff --git a/app/admin/config/admin.php b/app/admin/config/admin.php index 180ae14..0df12ed 100644 --- a/app/admin/config/admin.php +++ b/app/admin/config/admin.php @@ -25,4 +25,11 @@ return [ 'login/index', 'login/out', ], + + //上传类型 + 'upload_types' => [ + 'local' => '本地存储', + 'oss' => '阿里云oss', + 'cos' => '腾讯云cos' + ], ]; \ No newline at end of file diff --git a/app/admin/controller/Ajax.php b/app/admin/controller/Ajax.php index 51d6eef..967265b 100644 --- a/app/admin/controller/Ajax.php +++ b/app/admin/controller/Ajax.php @@ -3,6 +3,7 @@ namespace app\admin\controller; use app\admin\model\SystemUploadfile; +use app\admin\service\UploadService; use app\common\controller\AdminController; use app\common\service\MenuService; use app\admin\service\upload\Uploadfile; @@ -59,75 +60,36 @@ class Ajax extends AdminController { $this->isDemo && $this->error('演示环境下不允许修改'); $this->checkPostRequest(); + $type = $this->request->param('type', ''); $data = [ 'upload_type' => $this->request->post('upload_type'), - 'file' => $this->request->file('file'), + 'file' => $this->request->file($type == 'editor' ? 'upload' : 'file'), ]; $uploadConfig = sysconfig('upload'); empty($data['upload_type']) && $data['upload_type'] = $uploadConfig['upload_type']; $rule = [ 'upload_type|指定上传类型有误' => "in:{$uploadConfig['upload_allow_type']}", - 'file|文件' => "require|file|fileExt:{$uploadConfig['upload_allow_ext']}|fileSize:{$uploadConfig['upload_allow_size']}", + 'file|文件' => "require|file|fileExt:{$uploadConfig['upload_allow_ext']}|fileSize:{$uploadConfig['upload_allow_size']}", ]; $this->validate($data, $rule); + $upload_type = $uploadConfig['upload_type']; try { - $upload = Uploadfile::instance() - ->setUploadType($data['upload_type']) - ->setUploadConfig($uploadConfig) - ->setFile($data['file']) - ->save(); + $upload = UploadService::instance()->setConfig($uploadConfig)->$upload_type($data['file'], $type); } catch (\Exception $e) { return $this->error($e->getMessage()); } - if ($upload['save'] == true) { - $this->success($upload['msg'], ['url' => $upload['url']]); + $code = $upload['code'] ?? 0; + if ($code == 0) { + return $this->error($upload['data'] ?? ''); } else { - $this->error($upload['msg']); - } - } - - /** - * 上传图片至编辑器 - * @return Json - */ - public function uploadEditor(): Json - { - $this->isDemo && $this->error('演示环境下不允许修改'); - $this->checkPostRequest(); - $data = [ - 'upload_type' => $this->request->post('upload_type'), - 'file' => $this->request->file('upload'), - ]; - $uploadConfig = sysconfig('upload'); - empty($data['upload_type']) && $data['upload_type'] = $uploadConfig['upload_type']; - $rule = [ - 'upload_type|指定上传类型有误' => "in:{$uploadConfig['upload_allow_type']}", - 'file|文件' => "require|file|fileExt:{$uploadConfig['upload_allow_ext']}|fileSize:{$uploadConfig['upload_allow_size']}", - ]; - $this->validate($data, $rule); - try { - $upload = Uploadfile::instance() - ->setUploadType($data['upload_type']) - ->setUploadConfig($uploadConfig) - ->setFile($data['file']) - ->save(); - } catch (\Exception $e) { - return $this->error($e->getMessage()); - } - if ($upload['save'] == true) { - return json([ - 'error' => ['message' => '上传成功', 'number' => 201,], - 'fileName' => '', - 'uploaded' => 1, - 'url' => $upload['url'], - ]); - } else { - return json([ - 'error' => ['message' => $upload['msg'], 'number' => -1,], - 'fileName' => '', - 'uploaded' => 0, - 'url' => '', - ]); + return $type == 'editor' ? json( + [ + 'error' => ['message' => '上传成功', 'number' => 201,], + 'fileName' => '', + 'uploaded' => 1, + 'url' => $upload['data']['url'] ?? '', + ] + ) : $this->success('上传成功', $upload['data'] ?? ''); } } diff --git a/app/admin/controller/system/Config.php b/app/admin/controller/system/Config.php index bff45cc..396bbd0 100644 --- a/app/admin/controller/system/Config.php +++ b/app/admin/controller/system/Config.php @@ -21,6 +21,7 @@ class Config extends AdminController { parent::__construct($app); $this->model = new SystemConfig(); + $this->assign('upload_types', config('admin.upload_types')); } /** @@ -39,12 +40,24 @@ class Config extends AdminController $this->checkPostRequest(); $post = $this->request->post(); try { + $group = $post['group'] ?? ''; + if (empty($group)) $this->error('保存失败'); + if ($group == 'upload') { + $upload_types = config('admin.upload_types'); + // 兼容旧版本 + $this->model->where('name', 'upload_allow_type')->update(['value' => implode(',', array_keys($upload_types))]); + } foreach ($post as $key => $val) { - $this->model - ->where('name', $key) - ->update([ - 'value' => $val, - ]); + if ($this->model->where('name', $key)->count()) { + $this->model->where('name', $key)->update(['value' => $val,]); + } else { + $this->model->save( + [ + 'name' => $key, + 'value' => $val, + 'group' => $group, + ]); + } } TriggerService::updateMenu(); TriggerService::updateSysconfig(); diff --git a/app/admin/service/UploadService.php b/app/admin/service/UploadService.php new file mode 100644 index 0000000..9d6fc6b --- /dev/null +++ b/app/admin/service/UploadService.php @@ -0,0 +1,182 @@ +options = $options; + return $this; + } + + /** + * @return array + */ + public function getConfig(): array + { + return $this->options; + } + + /** + * @param UploadedFile $file + * @param string $base_path + * @return string + */ + protected function setFilePath(UploadedFile $file, string $base_path = ''): string + { + $path = date('Ymd') . '/' . Str::random(3) . time() . Str::random() . '.' . $file->extension(); + return $base_path . $path; + } + + /** + * @param UploadedFile $file + * @return UploadService + */ + protected function setSaveData(UploadedFile $file): static + { + $options = $this->options; + $data = [ + 'upload_type' => $options['upload_type'], + 'original_name' => $file->getOriginalName(), + 'mime_type' => $file->getMime(), + 'file_size' => $file->getSize(), + 'file_ext' => strtolower($file->extension()), + 'create_time' => time(), + ]; + $this->saveData = $data; + return $this; + } + + /** + * 本地存储 + * + * @param UploadedFile $file + * @param string $type + * @return array + */ + public function local(UploadedFile $file, string $type = ''): array + { + if ($file->isValid()) { + $base_path = '/storage/' . date('Ymd') . '/'; + // 上传文件的目标文件夹 + $destinationPath = public_path() . $base_path; + $this->setSaveData($file); + // 将文件移动到目标文件夹中 + $move = $file->move($destinationPath, Str::random(3) . time() . Str::random() . session('admin.id') . '.' . $file->extension()); + $url = $base_path . $move->getFilename(); + $data = ['url' => $url]; + $this->save($url); + return ['code' => 1, 'data' => $data]; + } + $data = '上传失败'; + return ['code' => 0, 'data' => $data]; + } + + /** + * 阿里云OSS + * + * @param UploadedFile $file + * @param string $type + * @return array + */ + public function oss(UploadedFile $file, string $type = ''): array + { + $config = $this->getConfig(); + $accessKeyId = $config['oss_access_key_id']; + $accessKeySecret = $config['oss_access_key_secret']; + $endpoint = $config['oss_endpoint']; + $bucket = $config['oss_bucket']; + if ($file->isValid()) { + $object = $this->setFilePath($file, Env::get('EASYADMIN.OSS_STATIC_PREFIX', 'easyadmin8') . '/'); + try { + $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint); + $_rs = $ossClient->putObject($bucket, $object, file_get_contents($file->getRealPath())); + $oss_request_url = $_rs['oss-request-url'] ?? ''; + if (empty($oss_request_url)) return ['code' => 0, 'data' => '上传至OSS失败']; + $oss_request_url = str_replace('http://', 'https://', $oss_request_url); + $this->setSaveData($file); + } catch (OssException $e) { + return ['code' => 0, 'data' => $e->getMessage()]; + } + $data = ['url' => $oss_request_url]; + $this->save($oss_request_url); + return ['code' => 1, 'data' => $data]; + } + $data = '上传失败'; + return ['code' => 0, 'data' => $data]; + } + + /** + * 腾讯云cos + * + * @param UploadedFile $file + * @param string $type + * @return array + */ + public function cos(UploadedFile $file, string $type = ''): array + { + $config = $this->getConfig(); + $secretId = $config['cos_secret_id']; //替换为用户的 secretId,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi + $secretKey = $config['cos_secret_key']; //替换为用户的 secretKey,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi + $region = $config['cos_region']; //替换为用户的 region,已创建桶归属的region可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket + if ($file->isValid()) { + $cosClient = new Client( + [ + 'region' => $region, + 'schema' => 'http', + 'credentials' => ['secretId' => $secretId, 'secretKey' => $secretKey, + ], + ]); + try { + $object = $this->setFilePath($file, Env::get('EASYADMIN.OSS_STATIC_PREFIX', 'easyadmin8') . '/'); + $result = $cosClient->upload( + $config['cos_bucket'], //存储桶名称,由BucketName-Appid 组成,可以在COS控制台查看 https://console.cloud.tencent.com/cos5/bucket + $object, //此处的 key 为对象键 + file_get_contents($file->getRealPath()) + ); + $location = $result['Location'] ?? ''; + if (empty($location)) return ['code' => 0, 'data' => '上传至COS失败']; + $location = 'https://' . $location; + $this->setSaveData($file); + } catch (\Exception $e) { + return ['code' => 0, 'data' => $e->getMessage()]; + } + $data = ['url' => $location]; + $this->save($location); + return ['code' => 1, 'data' => $data]; + } + $data = '上传失败'; + return ['code' => 0, 'data' => $data]; + } + + protected function save(string $url = ''): bool + { + $data = $this->saveData; + $data['url'] = $url; + $data['upload_time'] = time(); + return (new SystemUploadfile())->save($data); + } +} diff --git a/app/admin/service/upload/Uploadfile.php b/app/admin/service/upload/Uploadfile.php index 09e9d91..db680c2 100644 --- a/app/admin/service/upload/Uploadfile.php +++ b/app/admin/service/upload/Uploadfile.php @@ -1,7 +1,6 @@ uploadType == 'local') { $obj = new Local(); - } elseif ($this->uploadType == 'alioss') { + } elseif ($this->uploadType == 'oss') { $obj = new Alioss(); - } elseif ($this->uploadType == 'qnoss') { - $obj = new Qnoss(); - } elseif ($this->uploadType == 'txcos') { + } elseif ($this->uploadType == 'cos') { $obj = new Txcos(); } $save = $obj->setUploadConfig($this->uploadConfig) - ->setUploadType($this->uploadType) - ->setTableName($this->tableName) - ->setFile($this->file) - ->save(); + ->setUploadType($this->uploadType) + ->setTableName($this->tableName) + ->setFile($this->file) + ->save(); return $save; } } \ No newline at end of file diff --git a/app/admin/view/system/config/index.html b/app/admin/view/system/config/index.html index bf9e694..289b448 100644 --- a/app/admin/view/system/config/index.html +++ b/app/admin/view/system/config/index.html @@ -3,9 +3,9 @@