From 90ddb52370f086110d878dab495d4dca7f8e4090 Mon Sep 17 00:00:00 2001 From: IO Date: Sun, 30 Jun 2024 15:58:08 -0600 Subject: [PATCH] images --- package-lock.json | 11 +++++ package.json | 1 + src/Profesor/entities/profesor.entity.ts | 6 +-- src/Profesor/profesor.service.ts | 56 +++++++++++++++++++----- src/images/dto/imagesDto.dto.ts | 0 src/images/helpers/images.helper.ts | 15 +++++++ src/images/images.controller.ts | 53 ++++++++++++++++++++++ src/images/images.module.ts | 0 src/images/images.service.ts | 0 9 files changed, 129 insertions(+), 13 deletions(-) create mode 100644 src/images/dto/imagesDto.dto.ts create mode 100644 src/images/helpers/images.helper.ts create mode 100644 src/images/images.controller.ts create mode 100644 src/images/images.module.ts create mode 100644 src/images/images.service.ts diff --git a/package-lock.json b/package-lock.json index 4b92ece..f6a3a71 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,6 +36,7 @@ "@types/bcryptjs": "^2.4.6", "@types/express": "^4.17.17", "@types/jest": "^29.5.2", + "@types/multer": "^1.4.11", "@types/node": "^20.14.2", "@types/passport-jwt": "^4.0.1", "@types/supertest": "^6.0.0", @@ -2392,6 +2393,16 @@ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "dev": true }, + "node_modules/@types/multer": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.11.tgz", + "integrity": "sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, "node_modules/@types/node": { "version": "20.14.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", diff --git a/package.json b/package.json index 91ce9fa..8f7b7f0 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "@types/bcryptjs": "^2.4.6", "@types/express": "^4.17.17", "@types/jest": "^29.5.2", + "@types/multer": "^1.4.11", "@types/node": "^20.14.2", "@types/passport-jwt": "^4.0.1", "@types/supertest": "^6.0.0", diff --git a/src/Profesor/entities/profesor.entity.ts b/src/Profesor/entities/profesor.entity.ts index 07cc908..a18cb49 100644 --- a/src/Profesor/entities/profesor.entity.ts +++ b/src/Profesor/entities/profesor.entity.ts @@ -101,13 +101,13 @@ export class Profesor { @JoinColumn({ name: 'id_usuario' }) user: User; - @OneToMany(() => DatosAcademicos, datosAcademicos => datosAcademicos.profesor) + @OneToMany(() => DatosAcademicos, datosAcademicos => datosAcademicos.profesor,{ cascade: true }) datosAcademicos: DatosAcademicos[]; - @OneToMany(() => LineasInvestigacion, linea => linea.profesor) + @OneToMany(() => LineasInvestigacion, linea => linea.profesor,{ cascade: true }) lineasInvestigacion: LineasInvestigacion[]; - @OneToMany(() => ProyectosAcademicos, proyecto => proyecto.profesor) + @OneToMany(() => ProyectosAcademicos, proyecto => proyecto.profesor,{ cascade: true }) proyectosAcademicos: ProyectosAcademicos[]; } diff --git a/src/Profesor/profesor.service.ts b/src/Profesor/profesor.service.ts index b39778a..d5e395f 100644 --- a/src/Profesor/profesor.service.ts +++ b/src/Profesor/profesor.service.ts @@ -9,6 +9,8 @@ import { profesorDto } from './dto/profesorDto.dto'; import { ProyectosAcademicos } from '../proyectos_academicos/entities/proyectos_academicos.entity'; import { DatosAcademicos } from '../datos_academicos/entities/datos_academicos.entity' import { LineasInvestigacion } from '../lineas_investigacion/entities/lineas_investigacion.entity' +import * as fs from 'fs'; +import * as path from 'path'; @Injectable() export class ProfesorService { @@ -18,29 +20,44 @@ export class ProfesorService { private readonly datosAcademicosService: DatosAcademicosService, private readonly lineasInvestigacionService: LineasInvestigacionService, private readonly proyectosAcademicosService: ProyectosAcademicosService, - @InjectRepository(ProyectosAcademicos) - private readonly proyectosAcademicosRepository: Repository, @InjectRepository(DatosAcademicos) private readonly datosAcademicosRepository: Repository, @InjectRepository(LineasInvestigacion) private readonly lineasInvestigacionRepository: Repository, + @InjectRepository(ProyectosAcademicos) + private readonly proyectosAcademicosRepository: Repository, ) {} //register teacher - async register(data: profesorDto) { - const {num_trabajador,rfc,proyectosAcademicos, datosAcademicos, lineasInvestigacion } = data; + async register(data: profesorDto, file: Express.Multer.File) { + const { num_trabajador, rfc, proyectosAcademicos, datosAcademicos, lineasInvestigacion, nombre } = data; - const existrfc = await this.profesorRepository.findOne({where:{rfc}}); - if(existrfc){ + const existrfc = await this.profesorRepository.findOne({ where: { rfc } }); + if (existrfc) { throw new HttpException('rfc already exist', 403); } - const existnumber = await this.profesorRepository.findOne({where:{num_trabajador}}); - if(existnumber){ + const existnumber = await this.profesorRepository.findOne({ where: { num_trabajador } }); + if (existnumber) { throw new HttpException('number of worker already exist', 403); } - const newProfesor = this.profesorRepository.create(data); + let imageUrl = ''; + if (file) { + const profesorName = nombre.toLowerCase().replace(/ /g, '_'); + const fileExtName = path.extname(file.originalname); + const fileName = `${profesorName}${fileExtName}`; + const filePath = path.join(__dirname, '..', 'imagenes', fileName); + + // Save the image + fs.writeFileSync(filePath, file.buffer); + imageUrl = `/imagenes/${fileName}`; + } + + const newProfesor = this.profesorRepository.create({ + ...data, + fotografia: imageUrl, + }); const savedProfesor = await this.profesorRepository.save(newProfesor); if (proyectosAcademicos && proyectosAcademicos.length > 0) { @@ -92,7 +109,7 @@ export class ProfesorService { } //modify teacher - async modify(id_profesor: number, data: profesorDto) { + async modify(id_profesor: number, data: profesorDto, file?: Express.Multer.File) { const profesor = await this.profesorRepository.findOne({ where: { id_profesor } }); if (!profesor) { throw new HttpException('Profesor not found', 404); @@ -100,6 +117,17 @@ export class ProfesorService { const { proyectosAcademicos, datosAcademicos, lineasInvestigacion, ...profesorData } = data; Object.assign(profesor, profesorData); + + if (file) { + const profesorName = profesor.nombre.toLowerCase().replace(/ /g, '_'); + const fileExtName = path.extname(file.originalname); + const fileName = `${profesorName}${fileExtName}`; + const filePath = path.join(__dirname, '..', 'imagenes', fileName); + + fs.writeFileSync(filePath, file.buffer); + profesor.fotografia = `/imagenes/${fileName}`; + } + const savedProfesor = await this.profesorRepository.save(profesor); if (proyectosAcademicos) { @@ -238,4 +266,12 @@ export class ProfesorService { return { profesores, total, totalPages }; } + async updateImageURL(id_profesor: number, imageUrl: string): Promise { + const profesor = await this.profesorRepository.findOne({where:{id_profesor}}); + if (!profesor) { + throw new Error('Profesor not found'); + } + profesor.fotografia = imageUrl; + await this.profesorRepository.save(profesor); + } } diff --git a/src/images/dto/imagesDto.dto.ts b/src/images/dto/imagesDto.dto.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/images/helpers/images.helper.ts b/src/images/helpers/images.helper.ts new file mode 100644 index 0000000..fe1c560 --- /dev/null +++ b/src/images/helpers/images.helper.ts @@ -0,0 +1,15 @@ +import { extname } from 'path'; + +export const renameImage = (req, file, callback) => { + const profesorName = req.body.nombre.toLowerCase().replace(/ /g, '_'); + const fileExtName = extname(file.originalname); + const fileName = `${profesorName}${fileExtName}`; + callback(null, fileName); +}; + +export const fileFilter = (req, file, callback) => { + if (!file.originalname.match(/\.(jpg|jpeg|png)$/)) { + return callback(new Error('Invalid format type'), false); + } + callback(null, true); +}; diff --git a/src/images/images.controller.ts b/src/images/images.controller.ts new file mode 100644 index 0000000..a16d84b --- /dev/null +++ b/src/images/images.controller.ts @@ -0,0 +1,53 @@ +import { Controller, Post, UploadedFile, UseInterceptors, Body, BadRequestException, Put, Param } from '@nestjs/common'; +import { FileInterceptor } from '@nestjs/platform-express'; +import { diskStorage } from 'multer'; +import { renameImage, fileFilter } from './helpers/images.helper'; +import { ProfesorService } from '../Profesor/profesor.service'; + +@Controller('images') +export class ImagesController { + constructor(private readonly profesorService: ProfesorService) {} + + @Post() + @UseInterceptors(FileInterceptor('file', { + storage: diskStorage({ + destination: './imagenes', + filename: renameImage, + }), + fileFilter: fileFilter, + })) + async upload(@UploadedFile() file: Express.Multer.File, @Body() body) { + if (!file) { + throw new BadRequestException('No file uploaded'); + } + + const { id_profesor } = body; + const imageUrl = `/imagenes/${file.filename}`; + + // Update the professor's image URL in the database + await this.profesorService.updateImageURL(id_profesor, imageUrl); + + return { message: 'File uploaded successfully', imageUrl }; + } + + @Put(':id_profesor') + @UseInterceptors(FileInterceptor('file', { + storage: diskStorage({ + destination: './imagenes', + filename: renameImage, + }), + fileFilter: fileFilter, + })) + async modify(@Param('id_profesor') id_profesor: number, @UploadedFile() file: Express.Multer.File, @Body() body) { + if (!file) { + throw new BadRequestException('No file uploaded'); + } + + const imageUrl = `/imagenes/${file.filename}`; + + // Update the professor's image URL in the database + await this.profesorService.updateImageURL(id_profesor, imageUrl); + + return { message: 'File uploaded successfully', imageUrl }; + } +} diff --git a/src/images/images.module.ts b/src/images/images.module.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/images/images.service.ts b/src/images/images.service.ts new file mode 100644 index 0000000..e69de29