feat(note): add image upload functionality for notes

- Implemented a new endpoint in the Note controller to handle image uploads associated with notes.
- Added the `uploadImage` method in NoteService to manage image storage and return public URLs.
- Updated API routes to include the new image upload endpoint, enhancing note management capabilities.
This commit is contained in:
nepiedg
2026-04-20 10:27:54 +00:00
parent 9cc82df980
commit 69eb3e5019
4 changed files with 84 additions and 0 deletions
+59
View File
@@ -268,6 +268,33 @@ class NoteService
return $this->formatAudio($audio);
}
/**
* 上传笔记图片。
*
* 这里不额外建表,直接返回公开图片地址,由前端把图片标记写回 note.content
* 以便在跨设备打开同一笔记时仍能恢复图片内容。
*
* @param int $noteUserId
* @param int $id
* @param File $file
* @return array
* @throws \Exception
*/
public function uploadImage(int $noteUserId, int $id, File $file): array
{
$this->getOwnedNote($noteUserId, $id);
$savedPath = str_replace('\\', '/', Filesystem::disk('public')->putFile('note/image', $file));
return [
'disk' => 'public',
'file_path' => $savedPath,
'image_url' => $this->buildPublicFileUrl($savedPath),
'file_size' => (int) $file->getSize(),
'mime_type' => $this->detectImageMimeType($savedPath, $file),
'updated_at' => time(),
];
}
/**
* 创建分享
*
@@ -444,6 +471,38 @@ class NoteService
return $mimeMap[$extension] ?? 'application/octet-stream';
}
/**
* 推断图片 MIME。
*
* 与音频上传一样,这里优先按扩展名兜底,避免依赖 fileinfo 扩展。
*
* @param string $savedPath
* @param File $file
* @return string
*/
private function detectImageMimeType(string $savedPath, File $file): string
{
$extension = strtolower((string) pathinfo($savedPath, PATHINFO_EXTENSION));
if ($extension === '') {
$extension = strtolower((string) pathinfo((string) $file->getOriginalName(), PATHINFO_EXTENSION));
}
$mimeMap = [
'avif' => 'image/avif',
'bmp' => 'image/bmp',
'gif' => 'image/gif',
'heic' => 'image/heic',
'heif' => 'image/heif',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'png' => 'image/png',
'svg' => 'image/svg+xml',
'webp' => 'image/webp',
];
return $mimeMap[$extension] ?? 'application/octet-stream';
}
/**
* 规范化标题
*