accessKeyId = getenv('OSS_ACCESSID'); $this->accessKeySecret = getenv('OSS_ACCESSSECRET'); $this->bucket = getenv('OSS_BUCKET'); $this->endpoint = getenv('OSS_ENDPOINT'); $this->ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint); } /** * 上传图片到 OSS * @param string $filePath 本地文件路径 * @param string $objectKey OSS上存储的对象名称 * @return string 图片的 URL */ public function uploadImage($filePath, $objectKey) { try { // 上传文件到 OSS $this->ossClient->uploadFile($this->bucket, $objectKey, $filePath); // 构造图片的私有 URL $url = $this->generatePrivateUrl($objectKey); return $url; } catch (OssException $e) { // 错误处理 throw new \RuntimeException('OSS Error: ' . $e->getMessage()); } catch (\Throwable $th) { // 错误处理 throw new BusinessException('Error: ' . $th->getMessage()); } } /** * 生成图片的私有访问 URL * @param string $objectKey * @return string */ public function generatePrivateUrl($objectKey, $expireTime = 3600) { // 生成 OSS 私有 URL(有效期为 3600 秒) return $this->ossClient->signUrl($this->bucket, $objectKey, $expireTime); } /** * 附件数组的 url 重签为新的私有访问地址(响应期调用,防止历史签名过期)。 * 兼容三种存量格式:完整签名URL / 完整未签名URL / 纯对象键。 * @param array $attachments [{url, original_name}, ...] * @param int $expireTime * @return array */ public static function resignAttachmentUrls(array $attachments, int $expireTime = 604800): array { foreach ($attachments as &$a) { if (empty($a['url']) || !is_string($a['url'])) { continue; } try { $url = $a['url']; if (strpos($url, 'http') === 0) { $path = (string)parse_url($url, PHP_URL_PATH); if ($path === '') { continue; } $key = ltrim(urldecode($path), '/'); } else { $key = ltrim($url, '/'); // 已是对象键 } if ($key === '') { continue; } $a['url'] = (new self())->generatePrivateUrl($key, $expireTime); } catch (\Throwable $e) { // 重签失败保留原样 } } unset($a); return $attachments; } /** * 删除 OSS 上的文件 * @param string $objectKey OSS上存储的对象名称 * @return bool 删除是否成功 */ public function deleteFile($objectKey) { try { // 删除 OSS 上的文件 $this->ossClient->deleteObject($this->bucket, $objectKey); return true; } catch (OssException $e) { // 错误处理 throw new \RuntimeException('OSS Delete Error: ' . $e->getMessage()); } catch (\Throwable $th) { // 错误处理 throw new BusinessException('Delete Error: ' . $th->getMessage()); } } /** * 获取对应的 MIME 类型 */ public function getMimeTypes($extensions) { $mimeMap = [ 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'png' => 'image/png', 'gif' => 'image/gif', 'bmp' => 'image/bmp', 'webp' => 'image/webp', 'pdf' => 'application/pdf', 'doc' => 'application/msword', 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'xls' => 'application/vnd.ms-excel', 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'ppt' => 'application/vnd.ms-powerpoint', 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'txt' => 'text/plain', 'zip' => 'application/zip', 'rar' => 'application/x-rar-compressed' ]; $mimes = []; foreach ($extensions as $ext) { if (isset($mimeMap[$ext])) { $mimes[] = $mimeMap[$ext]; } } return array_unique($mimes); } }