feat: separate review images into /uploads/reviews/ subdir
This commit is contained in:
@@ -14,13 +14,14 @@ export function uploadError(message, statusCode = 400) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function persistMultipartImages(request, { maxFiles = 10, maxFileBytes }) {
|
export async function persistMultipartImages(request, { maxFiles = 10, maxFileBytes, subdir = '' }) {
|
||||||
if (!request.isMultipart()) {
|
if (!request.isMultipart()) {
|
||||||
throw uploadError('Ожидается multipart/form-data')
|
throw uploadError('Ожидается multipart/form-data')
|
||||||
}
|
}
|
||||||
|
|
||||||
const uploadsDir = path.join(process.cwd(), 'uploads')
|
const uploadsDir = path.join(process.cwd(), 'uploads')
|
||||||
await fs.promises.mkdir(uploadsDir, { recursive: true })
|
const targetDir = subdir ? path.join(uploadsDir, subdir) : uploadsDir
|
||||||
|
await fs.promises.mkdir(targetDir, { recursive: true })
|
||||||
|
|
||||||
const urls = []
|
const urls = []
|
||||||
const parts = request.parts({
|
const parts = request.parts({
|
||||||
@@ -40,9 +41,9 @@ export async function persistMultipartImages(request, { maxFiles = 10, maxFileBy
|
|||||||
}
|
}
|
||||||
|
|
||||||
const fileName = `${crypto.randomUUID()}${ext}`
|
const fileName = `${crypto.randomUUID()}${ext}`
|
||||||
const fullPath = path.join(uploadsDir, fileName)
|
const fullPath = path.join(targetDir, fileName)
|
||||||
await fs.promises.writeFile(fullPath, await part.toBuffer())
|
await fs.promises.writeFile(fullPath, await part.toBuffer())
|
||||||
urls.push(`/uploads/${fileName}`)
|
urls.push(subdir ? `/uploads/${subdir}/${fileName}` : `/uploads/${fileName}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (urls.length === 0) {
|
if (urls.length === 0) {
|
||||||
@@ -55,17 +56,18 @@ export async function persistMultipartImages(request, { maxFiles = 10, maxFileBy
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Сохранить один буфер изображения в uploads/, вернуть путь `/uploads/...`. */
|
/** Сохранить один буфер изображения в uploads/, вернуть путь `/uploads/...`. */
|
||||||
export async function saveImageBufferToUploads(originalFilename, buffer) {
|
export async function saveImageBufferToUploads(originalFilename, buffer, subdir = '') {
|
||||||
const ext = safeImageExt(originalFilename)
|
const ext = safeImageExt(originalFilename)
|
||||||
if (!ext) {
|
if (!ext) {
|
||||||
throw uploadError('Разрешены только файлы: png, jpg, jpeg, webp')
|
throw uploadError('Разрешены только файлы: png, jpg, jpeg, webp')
|
||||||
}
|
}
|
||||||
|
|
||||||
const uploadsDir = path.join(process.cwd(), 'uploads')
|
const uploadsDir = path.join(process.cwd(), 'uploads')
|
||||||
await fs.promises.mkdir(uploadsDir, { recursive: true })
|
const targetDir = subdir ? path.join(uploadsDir, subdir) : uploadsDir
|
||||||
|
await fs.promises.mkdir(targetDir, { recursive: true })
|
||||||
|
|
||||||
const fileName = `${crypto.randomUUID()}${ext}`
|
const fileName = `${crypto.randomUUID()}${ext}`
|
||||||
const fullPath = path.join(uploadsDir, fileName)
|
const fullPath = path.join(targetDir, fileName)
|
||||||
await fs.promises.writeFile(fullPath, buffer)
|
await fs.promises.writeFile(fullPath, buffer)
|
||||||
return `/uploads/${fileName}`
|
return subdir ? `/uploads/${subdir}/${fileName}` : `/uploads/${fileName}`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ export async function registerPublicReviewRoutes(fastify) {
|
|||||||
const urls = await persistMultipartImages(request, {
|
const urls = await persistMultipartImages(request, {
|
||||||
maxFiles: 1,
|
maxFiles: 1,
|
||||||
maxFileBytes: getOtherUploadMaxFileBytes(),
|
maxFileBytes: getOtherUploadMaxFileBytes(),
|
||||||
|
subdir: 'reviews',
|
||||||
})
|
})
|
||||||
if (urls.length !== 1) return reply.code(400).send({ error: 'Нужно прикрепить 1 изображение' })
|
if (urls.length !== 1) return reply.code(400).send({ error: 'Нужно прикрепить 1 изображение' })
|
||||||
return { url: urls[0] }
|
return { url: urls[0] }
|
||||||
|
|||||||
Reference in New Issue
Block a user