diff --git a/src/controllers/imageController.ts b/src/controllers/imageController.ts index e15d2fa..9fd5ee5 100644 --- a/src/controllers/imageController.ts +++ b/src/controllers/imageController.ts @@ -2,6 +2,7 @@ import { FastifyRequest, FastifyReply } from 'fastify'; import { removeImagesAll, viewImage, + viewImageByName, updateImage, searchImage, removeImage, @@ -14,6 +15,8 @@ interface BodyType { username: { value: string }; password: { value: string }; } +type RequestImageByName = FastifyRequest<{ Querystring: { bookID: number, imageName:string } }> + async function search( req: FastifyRequest<{ Body: BodyType }>, reply: FastifyReply @@ -35,6 +38,15 @@ async function view(req: RequestQueryID, reply: FastifyReply) { reply.code(404).send(error); } } +async function viewByName(req: RequestImageByName, reply: FastifyReply) { + try { + const { bookID, imageName } = req.query; + const image = await viewImageByName(Number(bookID), imageName); + reply.send(image); + } catch (error) { + reply.code(404).send(error); + } +} async function upload(req: FastifyRequest, reply: FastifyReply) { try { const files = await req.files(); @@ -80,4 +92,4 @@ async function total(req: FastifyRequest, reply: FastifyReply) { } } -export { search, view, upload, update, remove, removAll, total }; +export { search, view, viewByName, upload, update, remove, removAll, total }; diff --git a/src/routes/image/index.ts b/src/routes/image/index.ts index aba858b..4aa5c5f 100644 --- a/src/routes/image/index.ts +++ b/src/routes/image/index.ts @@ -1,9 +1,10 @@ import { FastifyPluginAsync } from "fastify" -import { search, view, update, remove, removAll, total } from '../../controllers/imageController.js' +import { search, view, viewByName, update, remove, removAll, total } from '../../controllers/imageController.js' const author: FastifyPluginAsync = async (fastify, opts): Promise => { fastify.get('/', search); fastify.get('/view', view); + fastify.get('/view-by-name', viewByName); fastify.post('/update', update); fastify.delete('/delete', remove); fastify.delete('/delete-all', removAll); diff --git a/src/services/imageService.ts b/src/services/imageService.ts index f0cd91b..32fca17 100644 --- a/src/services/imageService.ts +++ b/src/services/imageService.ts @@ -1,8 +1,14 @@ import { PrismaClient } from '@prisma/client'; -import { Image, ImageFromDB, QueryImages } from '../types/images.js'; +import { + Image, + ImageFromDB, + QueryImages, + StorageImages, +} from '../types/images.js'; import { pipeline } from 'stream'; -import util from 'node:util'; +import util, { promisify } from 'node:util'; import fs from 'fs'; +import path from 'path'; import fastifyMultipart from '@fastify/multipart'; import multipart from '@fastify/multipart'; import { RequestFormField } from '../types/meta.js'; @@ -70,6 +76,14 @@ async function viewImage(id: number) { throw new Error('image not found'); } +async function viewImageByName(bookID: number, imageName: string) { + const image = await prisma.image.findFirst({ where: { book_id: bookID, file_name: imageName } }); + if (image) { + return image; + } + throw new Error('image not found'); +} + async function updateImage(data: Image) { const image = await prisma.image.update({ where: { id: data.id }, @@ -137,16 +151,17 @@ async function searchImage(params: QueryImages) { } async function totalImageBooks() { - const result = await prisma.image.groupBy({ - by: ['book_id'], - _count: { - book_id: true, - }, - }); - return result.map((item) => ({ - book_id: item.book_id, - images_count: item._count.book_id, - })); + // const result = await prisma.image.groupBy({ + // by: ['book_id'], + // _count: { + // book_id: true, + // }, + // }); + // return result.map((item) => ({ + // book_id: item.book_id, + // images_count: item._count.book_id, + // })); + return await getAllStorageImages() } async function removeImage(id: number) { @@ -173,7 +188,7 @@ async function removeImagesAll(bookID: number) { console.error(err); throw err; } - console.log('removeImagesAll', dirPath) + console.log('removeImagesAll', dirPath); return true; }); } @@ -189,10 +204,35 @@ function prepageImages(images: Array) { }); } +async function getAllStorageImages() { + const readdir = promisify(fs.readdir); + const stat = promisify(fs.stat); + const storagePath = 'storage/media'; + const folders = await readdir(storagePath); + const bookImages: StorageImages[] = []; + + for (const folder of folders) { + const folderPath = path.join(storagePath, folder); + const folderStat = await stat(folderPath); + + if (folderStat.isDirectory()) { + const match = folder.match(/^book_(\d+)$/); + if (match) { + const bookID = parseInt(match[1]); + const images = await readdir(folderPath); + bookImages.push({ bookID, images }); + } + } + } + + return bookImages; +} + export { uploadImage, uploadImages, viewImage, + viewImageByName, updateImage, searchImage, removeImage, diff --git a/src/types/images.ts b/src/types/images.ts index 9c8f6cf..5d72ca8 100644 --- a/src/types/images.ts +++ b/src/types/images.ts @@ -37,4 +37,9 @@ interface ImageFromDB { }; } -export type { Image, ImageFromDB, QueryImages, ImagesResponse }; +interface StorageImages { + bookID: number; + images: string[]; +} + +export type { Image, ImageFromDB, QueryImages, ImagesResponse, StorageImages };