cambios
This commit is contained in:
+1
-1
@@ -55,4 +55,4 @@ pids
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
imagenes
|
||||
fotografias
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { AdscripcionController } from './adscripcion.controller'; // Asumiendo que el controlador se llama EdificioController
|
||||
|
||||
describe('AdscripcionController', () => {
|
||||
let controller: AdscripcionController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [AdscripcionController],
|
||||
}).compile();
|
||||
|
||||
controller = module.get<AdscripcionController>(AdscripcionController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -7,7 +7,6 @@ export class AdscripcionController {
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
Logger.debug('find all adscripcion');
|
||||
return this.adscripcionService.findAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { AdscripcionService } from './adscripcion.service';
|
||||
|
||||
describe('AdscripcionService', () => {
|
||||
let service: AdscripcionService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [AdscripcionService],
|
||||
}).compile();
|
||||
|
||||
service = module.get<AdscripcionService>(AdscripcionService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -1,22 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { AppController } from './app.controller';
|
||||
import { AppService } from './app.service';
|
||||
|
||||
describe('AppController', () => {
|
||||
let appController: AppController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const app: TestingModule = await Test.createTestingModule({
|
||||
controllers: [AppController],
|
||||
providers: [AppService],
|
||||
}).compile();
|
||||
|
||||
appController = app.get<AppController>(AppController);
|
||||
});
|
||||
|
||||
describe('root', () => {
|
||||
it('should return "Hello World!"', () => {
|
||||
expect(appController.getHello()).toBe('Hello World!');
|
||||
});
|
||||
});
|
||||
});
|
||||
+6
-6
@@ -20,10 +20,10 @@ import { Profesor } from './profesor/entities/profesor.entity';
|
||||
import { AdscripcionModule } from './adscripcion/adscripcion.module';
|
||||
import { EdificioModule } from './edificio/edificio.module';
|
||||
import { CategoriaModule } from './categoria/categoria.module';
|
||||
import { ImagenModule } from './images/images.module';
|
||||
import { DatabaseModule } from './database/database.module';
|
||||
import { LineasInvestigacionModule } from './lineas-investigacion/lineas-investigacion.module';
|
||||
import { ProyectosAcademicosModule } from './proyectos-academicos/proyectos-academicos.module';
|
||||
import { FotografiaModule } from './fotografia/fotografia.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -43,7 +43,6 @@ import { ProyectosAcademicosModule } from './proyectos-academicos/proyectos-acad
|
||||
username: configService.get('DB_USER'),
|
||||
password: configService.get('DB_PASSWORD'),
|
||||
database: configService.get('DB_DATABASE'),
|
||||
//dropSchema: true,
|
||||
entities: [
|
||||
Profesor,
|
||||
Usuario,
|
||||
@@ -55,14 +54,15 @@ import { ProyectosAcademicosModule } from './proyectos-academicos/proyectos-acad
|
||||
ProyectosAcademicos,
|
||||
TipoUsuario,
|
||||
],
|
||||
synchronize: true,
|
||||
//dropSchema: true,
|
||||
//synchronize: true, JAMA USAR ESTO EN PRODUCCION BORRA DATOS DE LA DB
|
||||
}),
|
||||
}),
|
||||
ServeStaticModule.forRoot({
|
||||
rootPath: join(__dirname, '..', 'imagenes'),
|
||||
serveRoot: '/imagenes',
|
||||
rootPath: join(__dirname, '..', 'fotografias'),
|
||||
serveRoot: '/fotografias',
|
||||
}),
|
||||
ImagenModule,
|
||||
FotografiaModule,
|
||||
ProfesorModule,
|
||||
AdscripcionModule,
|
||||
EdificioModule,
|
||||
|
||||
@@ -24,10 +24,8 @@ import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||
import { SignUpDto } from './dto/sign-up.dto';
|
||||
import { JwtAuthGuard } from 'src/permissions/jwt.guard';
|
||||
|
||||
@ApiBearerAuth()
|
||||
@ApiTags('Auth')
|
||||
@Controller('auth')
|
||||
@UseGuards(RolesGuard)
|
||||
export class AuthController {
|
||||
constructor(private authService: AuthService) {}
|
||||
|
||||
@@ -45,7 +43,9 @@ export class AuthController {
|
||||
summary: 'Registro de usuario',
|
||||
description: 'Registro ded administradores o responsables',
|
||||
})
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@UseGuards(RolesGuard)
|
||||
@Roles(Role.Admin)
|
||||
async register(@Body() data: SignUpDto) {
|
||||
Logger.debug('register user');
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { CategoriaController } from './categoria.controller';
|
||||
|
||||
describe('CategoriaController', () => {
|
||||
let controller: CategoriaController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [CategoriaController],
|
||||
}).compile();
|
||||
|
||||
controller = module.get<CategoriaController>(CategoriaController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -7,7 +7,6 @@ export class CategoriaController {
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
Logger.debug('find all categoria');
|
||||
return this.categoriaService.findAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { CategoriaService } from './categoria.service';
|
||||
|
||||
describe('CategoriaService', () => {
|
||||
let service: CategoriaService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [CategoriaService],
|
||||
}).compile();
|
||||
|
||||
service = module.get<CategoriaService>(CategoriaService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -1,18 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { DatabaseController } from './database.controller';
|
||||
|
||||
describe('DatabaseController', () => {
|
||||
let controller: DatabaseController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [DatabaseController],
|
||||
}).compile();
|
||||
|
||||
controller = module.get<DatabaseController>(DatabaseController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Controller, Post } from '@nestjs/common';
|
||||
import { DatabaseService } from './database.service';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||
|
||||
@ApiTags('Carga de Datos')
|
||||
@Controller('database')
|
||||
@@ -12,4 +12,15 @@ export class DatabaseController {
|
||||
await this.databaseService.cargarDatosDesdeExcel();
|
||||
return { message: 'Datos cargados exitosamente' };
|
||||
}
|
||||
|
||||
@Post('migrar-datos')
|
||||
@ApiOperation({
|
||||
summary: 'Migrar datos a la nueva base de datos',
|
||||
description:
|
||||
'Este endpoint ejecuta la migración desde la base de datos antigua a la nueva.',
|
||||
})
|
||||
async migrateDatabase() {
|
||||
await this.databaseService.migrateDB();
|
||||
return { message: 'Migración completada exitosamente' };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { DatabaseService } from './database.service';
|
||||
|
||||
describe('DatabaseService', () => {
|
||||
let service: DatabaseService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [DatabaseService],
|
||||
}).compile();
|
||||
|
||||
service = module.get<DatabaseService>(DatabaseService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -60,4 +60,8 @@ export class DatabaseService {
|
||||
await Promise.all(data.map((row) => repo.save(row)));
|
||||
}
|
||||
}
|
||||
|
||||
async migrateDB(): Promise<any> {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,15 +11,16 @@ import { DatosAcademicosService } from './datos-academicos.service';
|
||||
import { ApiBearerAuth, ApiBody, ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||
import { JwtAuthGuard } from 'src/permissions/jwt.guard';
|
||||
import { RolesGuard } from 'src/permissions/roles.guard';
|
||||
import { Roles } from 'src/permissions/roles.decorator';
|
||||
import { Role } from 'src/permissions/role.enum';
|
||||
|
||||
@ApiBearerAuth()
|
||||
@ApiTags('datos-academicos')
|
||||
@Controller('datos-academicos')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class DatosAcademicosController {
|
||||
constructor(private datosAcademicosService: DatosAcademicosService) {}
|
||||
|
||||
@Patch(':id_datos')
|
||||
@Patch(':id_profesor')
|
||||
@ApiOperation({
|
||||
summary: 'Actualizar datos academicos de un profesor',
|
||||
description:
|
||||
@@ -29,13 +30,12 @@ export class DatosAcademicosController {
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id_profesor: {
|
||||
id_datos: {
|
||||
type: 'number',
|
||||
description:
|
||||
'ID del profesor al que se debe actualizar sus lineas de investigacion',
|
||||
description: 'ID de los datos que se van a actualizar',
|
||||
example: 1,
|
||||
},
|
||||
lineas_inv_html: {
|
||||
grados_obtenidos: {
|
||||
type: 'string',
|
||||
description:
|
||||
'Nuevo contenido de líneas de investigación en formato Markdown o HTML',
|
||||
@@ -45,14 +45,21 @@ export class DatosAcademicosController {
|
||||
},
|
||||
})
|
||||
async updateDatosAcademicos(
|
||||
@Param('id_datos') id_datos: number,
|
||||
@Param('id_profesor') id_profesor: number,
|
||||
@Body('id_datos') id_datos: number,
|
||||
@Body('grados_obtenidos') grados_obtenidos: string,
|
||||
@Body('id_profesor') id_profesor: number,
|
||||
@Body('grado_maximo') grado_maximo: number,
|
||||
) {
|
||||
console.log(grados_obtenidos);
|
||||
console.log(grado_maximo);
|
||||
console.log(id_profesor);
|
||||
console.log(id_datos);
|
||||
if (!grados_obtenidos || grados_obtenidos.trim() === '') {
|
||||
throw new HttpException(
|
||||
'El contenido no puede estar vacío.',
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
}
|
||||
|
||||
return this.datosAcademicosService.updateDatosAcademicos(
|
||||
id_datos,
|
||||
id_profesor,
|
||||
grados_obtenidos,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { forwardRef, Inject, Injectable, Logger } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { DatosAcademicos } from './entities/datos_academicos.entity';
|
||||
import { Profesor } from 'src/profesor/entities/profesor.entity';
|
||||
import { ProfesorService } from 'src/profesor/profesor.service';
|
||||
|
||||
@Injectable()
|
||||
export class DatosAcademicosService {
|
||||
constructor(
|
||||
@InjectRepository(DatosAcademicos)
|
||||
private readonly datosAcademicosRepository: Repository<DatosAcademicos>,
|
||||
|
||||
@Inject(forwardRef(() => ProfesorService))
|
||||
private readonly profesorService: ProfesorService,
|
||||
) {}
|
||||
|
||||
async create(profesor: Profesor, grado_maximo: string) {
|
||||
@@ -21,6 +25,59 @@ export class DatosAcademicosService {
|
||||
return await this.datosAcademicosRepository.save(datosAcademicos);
|
||||
}
|
||||
|
||||
async updateDatosAcademicos(
|
||||
id_datos: number,
|
||||
id_profesor: number,
|
||||
nuevoContenido: string,
|
||||
) {
|
||||
const profesor = await this.profesorService.findOne(id_profesor);
|
||||
|
||||
let datosAcademicos = await this.datosAcademicosRepository.findOne({
|
||||
where: { profesor: profesor, id_datos },
|
||||
});
|
||||
|
||||
if (!datosAcademicos) {
|
||||
Logger.error(
|
||||
`No se encontraron datos académicos del profesor con ID ${id_profesor} al intentar actualizar. Se procederá a crear una nueva.`,
|
||||
);
|
||||
|
||||
// Crear nuevos datos académicos con el contenido
|
||||
datosAcademicos = this.datosAcademicosRepository.create({
|
||||
profesor: profesor,
|
||||
grados_obtenidos: nuevoContenido, // Se asigna el nuevo contenido directamente
|
||||
grado_maximo: 'Sin Grado Maximo', // Valor predeterminado
|
||||
});
|
||||
|
||||
// Guardar los nuevos datos académicos
|
||||
await this.datosAcademicosRepository.save(datosAcademicos);
|
||||
} else {
|
||||
// Si ya existen, actualizar su contenido
|
||||
datosAcademicos.grados_obtenidos = nuevoContenido;
|
||||
await this.datosAcademicosRepository.save(datosAcademicos);
|
||||
}
|
||||
|
||||
return datosAcademicos; // Devolver los datos académicos actualizados o recién creados
|
||||
}
|
||||
|
||||
async updateGradoMaximo(id_profesor: number, nuevoGradoMaximo: string) {
|
||||
const profesor = await this.profesorService.findOne(id_profesor);
|
||||
|
||||
const datosAcademicos = await this.datosAcademicosRepository.findOne({
|
||||
where: { profesor: profesor },
|
||||
});
|
||||
|
||||
if (!datosAcademicos) {
|
||||
Logger.error(
|
||||
`No se encontraron datos académicos del profesor con ID ${id_profesor} al intentar actualizar el grado máximo \n Se procede a crear una nueva`,
|
||||
);
|
||||
return await this.create(profesor, nuevoGradoMaximo);
|
||||
}
|
||||
|
||||
datosAcademicos.grado_maximo = nuevoGradoMaximo;
|
||||
|
||||
return await this.datosAcademicosRepository.save(datosAcademicos);
|
||||
}
|
||||
|
||||
async removeByProfesorId(id_profesor: number): Promise<void> {
|
||||
await this.datosAcademicosRepository.delete({ profesor: { id_profesor } });
|
||||
}
|
||||
|
||||
@@ -21,9 +21,7 @@ export class DatosAcademicos {
|
||||
@Column({ type: 'varchar', length: 600, nullable: true })
|
||||
grados_obtenidos: string;
|
||||
|
||||
@ManyToOne(() => Profesor, (profesor) => profesor.lineasInvestigacion, {
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@ManyToOne(() => Profesor, (profesor) => profesor.lineasInvestigacion)
|
||||
@JoinColumn({ name: 'id_profesor' })
|
||||
profesor: Profesor;
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { EdificioController } from './edificio.controller';
|
||||
|
||||
describe('EdificioController', () => {
|
||||
let controller: EdificioController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [EdificioController],
|
||||
}).compile();
|
||||
|
||||
controller = module.get<EdificioController>(EdificioController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -7,7 +7,6 @@ export class EdificioController {
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
Logger.debug('find all edificio');
|
||||
return this.edificioService.findAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { EdificioService } from './edificio.service'; // Asegúrate de importar el servicio correcto
|
||||
|
||||
describe('EdificioService', () => {
|
||||
let service: EdificioService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [EdificioService], // Asegúrate de incluir el servicio correcto aquí
|
||||
}).compile();
|
||||
|
||||
service = module.get<EdificioService>(EdificioService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,85 @@
|
||||
import {
|
||||
Controller,
|
||||
Post,
|
||||
Patch,
|
||||
UseInterceptors,
|
||||
UploadedFile,
|
||||
Body,
|
||||
} from '@nestjs/common';
|
||||
import { FileInterceptor } from '@nestjs/platform-express';
|
||||
import { FotografiaService } from './fotografia.service';
|
||||
import {
|
||||
ApiBody,
|
||||
ApiConsumes,
|
||||
ApiOperation,
|
||||
ApiResponse,
|
||||
ApiTags,
|
||||
} from '@nestjs/swagger';
|
||||
import { Express } from 'express';
|
||||
|
||||
@ApiTags('fotografia')
|
||||
@Controller('fotografia')
|
||||
export class FotografiaController {
|
||||
constructor(private readonly fotografiaService: FotografiaService) {}
|
||||
|
||||
@Post('upload')
|
||||
@UseInterceptors(FileInterceptor('file'))
|
||||
@ApiOperation({ summary: 'Subir una imagen con un nombre personalizado' })
|
||||
@ApiConsumes('multipart/form-data')
|
||||
@ApiBody({
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
customName: {
|
||||
type: 'string',
|
||||
description: 'Nombre personalizado de la imagen',
|
||||
},
|
||||
file: {
|
||||
type: 'string',
|
||||
format: 'binary',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
@ApiResponse({ status: 201, description: 'Imagen subida exitosamente' })
|
||||
uploadFile(
|
||||
@UploadedFile() file: Express.Multer.File,
|
||||
@Body('customName') customName: string,
|
||||
) {
|
||||
return { message: 'Imagen subida exitosamente', fileName: file.filename };
|
||||
}
|
||||
|
||||
@Post('update')
|
||||
@UseInterceptors(FileInterceptor('file'))
|
||||
@ApiOperation({
|
||||
summary: 'Actualizar una imagen existente con un nombre personalizado',
|
||||
})
|
||||
@ApiConsumes('multipart/form-data')
|
||||
@ApiBody({
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
oldFileName: {
|
||||
type: 'string',
|
||||
description: 'Nombre de la imagen antigua',
|
||||
},
|
||||
customName: {
|
||||
type: 'string',
|
||||
description: 'Nuevo nombre personalizado de la imagen',
|
||||
},
|
||||
file: {
|
||||
type: 'string',
|
||||
format: 'binary',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
@ApiResponse({ status: 200, description: 'Imagen actualizada correctamente' })
|
||||
updateFile(
|
||||
@UploadedFile() file: Express.Multer.File,
|
||||
@Body('oldFileName') oldFileName: string,
|
||||
@Body('customName') customName: string,
|
||||
) {
|
||||
return this.fotografiaService.updateFile(oldFileName, file, customName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { MulterModule } from '@nestjs/platform-express';
|
||||
import { FotografiaController } from './fotografia.controller';
|
||||
import { FotografiaService } from './fotografia.service';
|
||||
import { diskStorage } from 'multer';
|
||||
import { join } from 'path';
|
||||
import { existsSync, mkdirSync } from 'fs';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
MulterModule.register({
|
||||
storage: diskStorage({
|
||||
destination: (req, file, cb) => {
|
||||
const uploadPath = join(__dirname, '..', '..', 'fotografias');
|
||||
if (!existsSync(uploadPath)) {
|
||||
mkdirSync(uploadPath, { recursive: true });
|
||||
}
|
||||
cb(null, uploadPath);
|
||||
},
|
||||
filename: (req, file, cb) => {
|
||||
const uniqueSuffix =
|
||||
Date.now() + '-' + Math.round(Math.random() * 1e9);
|
||||
const customName = req.body.customName
|
||||
? req.body.customName.toLowerCase().replace(/\s+/g, '-')
|
||||
: 'image';
|
||||
cb(
|
||||
null,
|
||||
`${customName}-${uniqueSuffix}${file.originalname.substring(file.originalname.lastIndexOf('.'))}`,
|
||||
);
|
||||
},
|
||||
}),
|
||||
}),
|
||||
],
|
||||
controllers: [FotografiaController],
|
||||
providers: [FotografiaService],
|
||||
})
|
||||
export class FotografiaModule {}
|
||||
@@ -0,0 +1,58 @@
|
||||
import { Injectable, BadRequestException } from '@nestjs/common';
|
||||
import { renameSync, existsSync, unlinkSync, mkdirSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
@Injectable()
|
||||
export class FotografiaService {
|
||||
updateFile(
|
||||
oldFileName: string,
|
||||
newFile: Express.Multer.File,
|
||||
customName?: string,
|
||||
) {
|
||||
try {
|
||||
const uploadPath = join(__dirname, '..', '..', 'fotografias');
|
||||
const oldFilePath = join(uploadPath, oldFileName);
|
||||
const tempFilePath = newFile.path; // Ruta temporal del archivo subido
|
||||
|
||||
// 🛠️ 1. Asegurar que la carpeta 'fotografias/' exista
|
||||
if (!existsSync(uploadPath)) {
|
||||
mkdirSync(uploadPath, { recursive: true });
|
||||
}
|
||||
|
||||
// 🛠️ 2. Verificar si el archivo temporal realmente existe antes de renombrar
|
||||
if (!existsSync(tempFilePath)) {
|
||||
throw new BadRequestException('El archivo temporal no fue encontrado.');
|
||||
}
|
||||
|
||||
// 🛠️ 3. Eliminar la imagen anterior si existe
|
||||
if (oldFileName && existsSync(oldFilePath)) {
|
||||
try {
|
||||
unlinkSync(oldFilePath);
|
||||
console.log(`✅ Imagen anterior eliminada: ${oldFileName}`);
|
||||
} catch (error) {
|
||||
console.error(`❌ Error al eliminar la imagen anterior: ${error.message}`);
|
||||
}
|
||||
} else {
|
||||
console.log('No se encontró imagen anterior para eliminar.', oldFileName);
|
||||
}
|
||||
|
||||
// 🛠️ 4. Generar nuevo nombre de archivo con customName y timestamp
|
||||
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
|
||||
const fileExtension = newFile.originalname.substring(newFile.originalname.lastIndexOf('.'));
|
||||
const newFileName = `${customName ? customName.toLowerCase().replace(/\s+/g, '-') : 'image'}-${uniqueSuffix}${fileExtension}`;
|
||||
const newFilePath = join(uploadPath, newFileName);
|
||||
|
||||
// 🛠️ 5. Mover el archivo de la carpeta temporal a 'fotografias/' con su nuevo nombre
|
||||
renameSync(tempFilePath, newFilePath);
|
||||
console.log(`Imagen subida con éxito: ${newFileName}`);
|
||||
|
||||
console.log('-------------------')
|
||||
return {
|
||||
message: 'Imagen actualizada correctamente',
|
||||
fileName: newFileName,
|
||||
};
|
||||
} catch (error) {
|
||||
throw new BadRequestException(`Error en la actualización de la imagen: ${error.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
import { Controller, Post, Body, Put, Logger } from '@nestjs/common';
|
||||
import { ImagenService } from './images.service';
|
||||
|
||||
@Controller('imagen')
|
||||
export class ImagenController {
|
||||
constructor(private readonly imagenService: ImagenService) {}
|
||||
|
||||
@Post()
|
||||
async upload(@Body() body) {
|
||||
Logger.debug('upload image');
|
||||
const { fotografia, nombre } = body;
|
||||
|
||||
const imageUrl = await this.imagenService.saveImage(fotografia, nombre);
|
||||
|
||||
return { message: 'Image uploaded successfully', imageUrl };
|
||||
}
|
||||
|
||||
@Put()
|
||||
async modify(@Body() body) {
|
||||
Logger.debug('modify image');
|
||||
const { fotografia, nombre } = body;
|
||||
|
||||
const imageUrl = await this.imagenService.modify(fotografia, nombre);
|
||||
|
||||
return { message: 'Image uploaded successfully', imageUrl };
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ImagenController } from './images.controller';
|
||||
import { ImagenService } from './images.service';
|
||||
|
||||
@Module({
|
||||
controllers: [ImagenController],
|
||||
providers: [ImagenService],
|
||||
})
|
||||
export class ImagenModule {}
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
import { Injectable, BadRequestException, Logger } from '@nestjs/common';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
@Injectable()
|
||||
export class ImagenService {
|
||||
async saveImage(fotografia: string, id: string): Promise<string> {
|
||||
if (!fotografia) {
|
||||
throw new BadRequestException('No image provided');
|
||||
}
|
||||
|
||||
// Extract the image extension
|
||||
const matches = fotografia.match(/^data:image\/([a-zA-Z]+);base64,/);
|
||||
if (!matches) {
|
||||
throw new BadRequestException('Invalid image format');
|
||||
}
|
||||
const ext = matches[1];
|
||||
|
||||
// Decode base64 string and save the image
|
||||
const buffer = Buffer.from(fotografia.split(',')[1], 'base64');
|
||||
const imageName = `${id}.${ext}`;
|
||||
|
||||
// Save image to the 'imagenes' directory in the root of the project
|
||||
const imagePath = path.join(process.cwd(), 'imagenes', imageName);
|
||||
|
||||
// Ensure the directory exists
|
||||
const dirPath = path.join(process.cwd(), 'imagenes');
|
||||
if (!fs.existsSync(dirPath)) {
|
||||
fs.mkdirSync(dirPath, { recursive: true });
|
||||
}
|
||||
|
||||
fs.writeFileSync(imagePath, buffer);
|
||||
|
||||
return imageName;
|
||||
}
|
||||
|
||||
async deleteImage(id: string): Promise<void> {
|
||||
Logger.debug('delete image');
|
||||
const imageDir = path.join(process.cwd(), 'imagenes');
|
||||
const imagePath = path.join(imageDir, id);
|
||||
|
||||
const extensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'avif'];
|
||||
|
||||
let fileFound = false;
|
||||
for (const ext of extensions) {
|
||||
const fullImagePath = `${imagePath}.${ext}`;
|
||||
if (fs.existsSync(fullImagePath)) {
|
||||
fs.unlinkSync(fullImagePath);
|
||||
fileFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fileFound) {
|
||||
console.log('Image not found, but continuing to save the new image.');
|
||||
}
|
||||
}
|
||||
|
||||
async modify(fotografia: string, id: string): Promise<string> {
|
||||
if (!fotografia) {
|
||||
throw new BadRequestException('No image provided');
|
||||
}
|
||||
|
||||
await this.deleteImage(id);
|
||||
|
||||
// Extract the image extension
|
||||
const matches = fotografia.match(/^data:image\/([a-zA-Z]+);base64,/);
|
||||
if (!matches) {
|
||||
throw new BadRequestException('Invalid image format');
|
||||
}
|
||||
const ext = matches[1];
|
||||
|
||||
// Decode base64 string and save the image
|
||||
const buffer = Buffer.from(fotografia.split(',')[1], 'base64');
|
||||
const imageName = `${id}.${ext}`;
|
||||
|
||||
// Save image to the 'imagenes' directory in the root of the project
|
||||
const imagePath = path.join(process.cwd(), 'imagenes', imageName);
|
||||
|
||||
// Ensure the directory exists
|
||||
const dirPath = path.join(process.cwd(), 'imagenes');
|
||||
if (!fs.existsSync(dirPath)) {
|
||||
fs.mkdirSync(dirPath, { recursive: true });
|
||||
}
|
||||
|
||||
fs.writeFileSync(imagePath, buffer);
|
||||
|
||||
return imageName;
|
||||
}
|
||||
}
|
||||
@@ -12,15 +12,10 @@ export class LineasInvestigacion {
|
||||
@PrimaryGeneratedColumn()
|
||||
id_linea_inv: number;
|
||||
|
||||
@Column({ type: 'int', nullable: false, unique: true })
|
||||
id_profesor: number;
|
||||
|
||||
@Column({ type: 'longtext', nullable: true })
|
||||
@Column({ type: 'varchar', length: 600, nullable: true })
|
||||
lineas_inv_html: string;
|
||||
|
||||
@ManyToOne(() => Profesor, (profesor) => profesor.lineasInvestigacion, {
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@ManyToOne(() => Profesor, (profesor) => profesor.lineasInvestigacion)
|
||||
@JoinColumn({ name: 'id_profesor' })
|
||||
profesor: Profesor;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import { RolesGuard } from 'src/permissions/roles.guard';
|
||||
export class LineasInvestigacionController {
|
||||
constructor(private lineasInvestigacionService: LineasInvestigacionService) {}
|
||||
|
||||
@Patch(':id_linea_inv')
|
||||
@Patch(':id_profesor')
|
||||
@ApiOperation({
|
||||
summary: 'Actualizar líneas de investigación de un profesor',
|
||||
description:
|
||||
@@ -29,10 +29,10 @@ export class LineasInvestigacionController {
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id_profesor: {
|
||||
id_linea_inv: {
|
||||
type: 'number',
|
||||
description:
|
||||
'ID del profesor al que se debe actualizar sus lineas de investigacion',
|
||||
'ID de las lineas de investigacion que se deben actualizar',
|
||||
example: 1,
|
||||
},
|
||||
lineas_inv_html: {
|
||||
@@ -45,9 +45,9 @@ export class LineasInvestigacionController {
|
||||
},
|
||||
})
|
||||
async updateLineasInvestigacion(
|
||||
@Param('id_linea_inv') id_linea_inv: number,
|
||||
@Param('id_profesor') id_profesor: number,
|
||||
@Body('id_linea_inv') id_linea_inv: number,
|
||||
@Body('lineas_inv_html') lineasInvHtml: string,
|
||||
@Body('id_profesor') id_profesor: number,
|
||||
) {
|
||||
if (!lineasInvHtml || lineasInvHtml.trim() === '') {
|
||||
throw new HttpException(
|
||||
|
||||
@@ -31,24 +31,30 @@ export class LineasInvestigacionService {
|
||||
) {
|
||||
const profesor = await this.profesorService.findOne(id_profesor);
|
||||
|
||||
console.log(profesor);
|
||||
console.log(nuevoContenido);
|
||||
|
||||
const lineasInvestigacion =
|
||||
await this.lineasInvestigacionRepository.findOne({
|
||||
where: { profesor: profesor, id_linea_inv },
|
||||
});
|
||||
let lineasInvestigacion = await this.lineasInvestigacionRepository.findOne({
|
||||
where: { profesor: profesor, id_linea_inv },
|
||||
});
|
||||
|
||||
if (!lineasInvestigacion) {
|
||||
Logger.error(
|
||||
`No se encontró la línea de investigación del profesor con ID ${id_profesor} al intentar actualizarla \n Se procede a crear una nueva`,
|
||||
`No se encontró la línea de investigación del profesor con ID ${id_profesor} al intentar actualizarla. Se procederá a crear una nueva.`,
|
||||
);
|
||||
return await this.create(profesor);
|
||||
|
||||
// Crear una nueva línea de investigación con el contenido
|
||||
lineasInvestigacion = this.lineasInvestigacionRepository.create({
|
||||
profesor: profesor,
|
||||
lineas_inv_html: nuevoContenido, // Se asigna el nuevo contenido directamente
|
||||
});
|
||||
|
||||
// Guardar la nueva línea de investigación
|
||||
await this.lineasInvestigacionRepository.save(lineasInvestigacion);
|
||||
} else {
|
||||
// Si ya existe, actualizar su contenido
|
||||
lineasInvestigacion.lineas_inv_html = nuevoContenido;
|
||||
await this.lineasInvestigacionRepository.save(lineasInvestigacion);
|
||||
}
|
||||
|
||||
lineasInvestigacion.lineas_inv_html = nuevoContenido;
|
||||
|
||||
return await this.lineasInvestigacionRepository.save(lineasInvestigacion);
|
||||
return lineasInvestigacion; // Devolver la línea de investigación actualizada o recién creada
|
||||
}
|
||||
|
||||
async removeByProfesorId(id_profesor: number): Promise<void> {
|
||||
|
||||
+3
-2
@@ -29,6 +29,7 @@ async function bootstrap() {
|
||||
.addTag('Usuario')
|
||||
.addTag('lineas-investigacion')
|
||||
.addTag('proyectos-academicos')
|
||||
.addTag('datos-academicos')
|
||||
.addBearerAuth()
|
||||
.build();
|
||||
const documentFactory = () => SwaggerModule.createDocument(app, config);
|
||||
@@ -40,8 +41,8 @@ async function bootstrap() {
|
||||
app.use(bodyParser.json({ limit: '1mb' }));
|
||||
app.use(bodyParser.urlencoded({ limit: '1mb', extended: true }));
|
||||
|
||||
app.useStaticAssets(path.join(__dirname, '..', 'imagenes'), {
|
||||
prefix: '/imagenes/',
|
||||
app.useStaticAssets(path.join(__dirname, '..', 'fotografias'), {
|
||||
prefix: '/fotografias/',
|
||||
});
|
||||
|
||||
await app.listen(3000);
|
||||
|
||||
@@ -67,14 +67,6 @@ export class Profesor {
|
||||
})
|
||||
fecha_actualizacion: Date;
|
||||
|
||||
/* Datos Personales Eliminados */
|
||||
|
||||
/* @Column({ type: 'varchar', length: 13, nullable: true })
|
||||
tel_personal: string; */
|
||||
|
||||
/* @Column({ type: 'varchar', length: 65, nullable: true })
|
||||
correo_per: string; */
|
||||
|
||||
/* RELACIONES */
|
||||
|
||||
@Column({ type: 'int', nullable: true })
|
||||
@@ -92,49 +84,44 @@ export class Profesor {
|
||||
@ManyToOne(() => Edificio, (edificio) => edificio.profesores)
|
||||
@JoinColumn({
|
||||
name: 'id_edificio',
|
||||
referencedColumnName: 'id_edificio',
|
||||
foreignKeyConstraintName: 'FK_edificio_fk',
|
||||
})
|
||||
edificio: Edificio;
|
||||
|
||||
@ManyToOne(() => Adscripcion, (adscripcion) => adscripcion.profesores)
|
||||
@JoinColumn({
|
||||
name: 'id_adscripcion',
|
||||
referencedColumnName: 'id_adscripcion',
|
||||
foreignKeyConstraintName: 'FK_adscripcion_fk',
|
||||
})
|
||||
adscripcion: Adscripcion;
|
||||
|
||||
@ManyToOne(() => Categoria, (categoria) => categoria.profesores)
|
||||
@JoinColumn({
|
||||
name: 'id_categoria',
|
||||
referencedColumnName: 'id_categoria',
|
||||
foreignKeyConstraintName: 'FK_categoria_fk',
|
||||
})
|
||||
categoria: Categoria;
|
||||
|
||||
@ManyToOne(() => Usuario, (usuario) => usuario.profesores)
|
||||
@JoinColumn({
|
||||
name: 'id_usuario',
|
||||
referencedColumnName: 'id_usuario',
|
||||
foreignKeyConstraintName: 'FK_usuario_fk',
|
||||
})
|
||||
usuario: Usuario;
|
||||
|
||||
@OneToMany(
|
||||
() => DatosAcademicos,
|
||||
(datosAcademicos) => datosAcademicos.profesor,
|
||||
{ cascade: true },
|
||||
)
|
||||
datosAcademicos: DatosAcademicos[];
|
||||
|
||||
@OneToMany(() => LineasInvestigacion, (linea) => linea.profesor, {
|
||||
cascade: true,
|
||||
})
|
||||
@OneToMany(() => LineasInvestigacion, (linea) => linea.profesor)
|
||||
lineasInvestigacion: LineasInvestigacion[];
|
||||
|
||||
@OneToMany(() => ProyectosAcademicos, (proyecto) => proyecto.profesor, {
|
||||
cascade: true,
|
||||
})
|
||||
@OneToMany(() => ProyectosAcademicos, (proyecto) => proyecto.profesor)
|
||||
proyectosAcademicos: ProyectosAcademicos[];
|
||||
}
|
||||
|
||||
/* Datos Personales Eliminados */
|
||||
|
||||
/* @Column({ type: 'varchar', length: 13, nullable: true })
|
||||
tel_personal: string; */
|
||||
|
||||
/* @Column({ type: 'varchar', length: 65, nullable: true })
|
||||
correo_per: string; */
|
||||
|
||||
@@ -40,12 +40,12 @@ interface RequestWithUser extends Request {
|
||||
@ApiBearerAuth()
|
||||
@ApiTags('Profesor')
|
||||
@Controller('profesor')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class ProfesorController {
|
||||
constructor(private profesorService: ProfesorService) {}
|
||||
|
||||
@Post()
|
||||
@ApiOperation({ summary: 'Crear un profesor' })
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
@Roles(Role.Responsable, Role.Admin)
|
||||
async register(@Body() data: CreateProfesorDto, @Req() req: RequestWithUser) {
|
||||
return this.profesorService.register(data, req.user);
|
||||
@@ -97,19 +97,19 @@ export class ProfesorController {
|
||||
description: 'Filtrar por nombre del profesor',
|
||||
})
|
||||
@ApiQuery({
|
||||
name: 'id_adscripcion',
|
||||
name: 'adscripcion',
|
||||
required: false,
|
||||
example: 2,
|
||||
description: 'Filtrar por ID de adscripción',
|
||||
})
|
||||
@ApiQuery({
|
||||
name: 'id_edificio',
|
||||
name: 'edificio',
|
||||
required: false,
|
||||
example: 3,
|
||||
description: 'Filtrar por ID de edificio',
|
||||
})
|
||||
@ApiQuery({
|
||||
name: 'id_categoria',
|
||||
name: 'categoria',
|
||||
required: false,
|
||||
example: 1,
|
||||
description: 'Filtrar por ID de categoría',
|
||||
@@ -118,9 +118,9 @@ export class ProfesorController {
|
||||
@Query('page') page: number = 1,
|
||||
@Query('limit') limit: number = 12,
|
||||
@Query('nombre') nombre?: string,
|
||||
@Query('id_adscripcion') id_adscripcion?: number,
|
||||
@Query('id_edificio') id_edificio?: number,
|
||||
@Query('id_categoria') id_categoria?: number,
|
||||
@Query('adscripcion') adscripcion?: number,
|
||||
@Query('edificio') edificio?: number,
|
||||
@Query('categoria') categoria?: number,
|
||||
) {
|
||||
// Validaciones básicas
|
||||
page = page < 1 ? 1 : page;
|
||||
@@ -129,9 +129,9 @@ export class ProfesorController {
|
||||
// Filtros dinámicos
|
||||
const filters: any = {};
|
||||
if (nombre) filters.nombre = nombre;
|
||||
if (id_adscripcion) filters.id_adscripcion = Number(id_adscripcion);
|
||||
if (id_edificio) filters.id_edificio = Number(id_edificio);
|
||||
if (id_categoria) filters.id_categoria = Number(id_categoria);
|
||||
if (adscripcion) filters.adscripcion = Number(adscripcion);
|
||||
if (edificio) filters.edificio = Number(edificio);
|
||||
if (categoria) filters.categoria = Number(categoria);
|
||||
|
||||
return await this.profesorService.findAllPaginated(page, limit, filters);
|
||||
}
|
||||
@@ -161,6 +161,7 @@ export class ProfesorController {
|
||||
summary:
|
||||
'Elimina un profesor con sus proyectos y lineas de investigacion por su id_profesor',
|
||||
})
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
@Roles(Role.Responsable, Role.Admin)
|
||||
async remove(@Param('id_profesor', ParseIntPipe) id_profesor: number) {
|
||||
return this.profesorService.remove(id_profesor);
|
||||
|
||||
@@ -50,25 +50,18 @@ export class ProfesorService {
|
||||
id_profesor: number,
|
||||
data: UpdateProfesorDto,
|
||||
): Promise<Profesor> {
|
||||
const { grado_maximo } = data;
|
||||
const profesor = await this.findOne(id_profesor);
|
||||
Object.assign(profesor, data);
|
||||
return await this.profesorRepository.save(profesor);
|
||||
}
|
||||
|
||||
private async findAvailableId(): Promise<number> {
|
||||
let id = 1;
|
||||
let exists = true;
|
||||
|
||||
while (exists) {
|
||||
if (
|
||||
!(await this.profesorRepository.findOne({ where: { id_profesor: id } }))
|
||||
) {
|
||||
Logger.debug(`id_profesor = ${id}`);
|
||||
exists = false;
|
||||
return id;
|
||||
}
|
||||
id++;
|
||||
if (grado_maximo) {
|
||||
await this.datosAcademicosService.updateGradoMaximo(
|
||||
profesor.id_profesor,
|
||||
grado_maximo,
|
||||
);
|
||||
}
|
||||
|
||||
return await this.profesorRepository.save(profesor);
|
||||
}
|
||||
|
||||
//register teacher
|
||||
@@ -175,6 +168,18 @@ export class ProfesorService {
|
||||
],
|
||||
});
|
||||
|
||||
if (profesor.lineasInvestigacion.length === 0) {
|
||||
await this.lineasInvestigacionService.create(profesor);
|
||||
}
|
||||
|
||||
if (profesor.proyectosAcademicos.length === 0) {
|
||||
await this.proyectosAcademicosService.create(profesor);
|
||||
}
|
||||
|
||||
if (profesor.datosAcademicos.length === 0) {
|
||||
await this.datosAcademicosService.create(profesor, '');
|
||||
}
|
||||
|
||||
if (!profesor) {
|
||||
throw new HttpException('Profesor not found', 404);
|
||||
}
|
||||
@@ -189,7 +194,8 @@ export class ProfesorService {
|
||||
): Promise<{ profesores: Profesor[]; total: number; totalPages: number }> {
|
||||
const query = this.profesorRepository.createQueryBuilder('profesor');
|
||||
|
||||
// 🔹 Filtro por Nombre (LIKE %nombre%)
|
||||
console.log(filters);
|
||||
|
||||
if (filters.nombre) {
|
||||
Logger.debug('Filter by name');
|
||||
query.andWhere('LOWER(profesor.nombre) LIKE LOWER(:nombre)', {
|
||||
@@ -197,15 +203,13 @@ export class ProfesorService {
|
||||
});
|
||||
}
|
||||
|
||||
// 🔹 Filtro por Adscripción
|
||||
if (filters.adscripcion && !isNaN(filters.adscripcion)) {
|
||||
Logger.debug('Filter by adscription');
|
||||
query.andWhere('profesor.adscripcion = :adscripcion', {
|
||||
query.andWhere('profesor.id_adscripcion = :adscripcion', {
|
||||
adscripcion: Number(filters.adscripcion),
|
||||
});
|
||||
}
|
||||
|
||||
// 🔹 Filtro por Categoría
|
||||
if (filters.categoria && !isNaN(filters.categoria)) {
|
||||
Logger.debug('Filter by category');
|
||||
query.andWhere('profesor.categoria = :categoria', {
|
||||
@@ -213,26 +217,15 @@ export class ProfesorService {
|
||||
});
|
||||
}
|
||||
|
||||
// 🔹 Filtro por Edificio
|
||||
if (filters.edificio && !isNaN(filters.edificio)) {
|
||||
Logger.debug('Filter by building');
|
||||
query.andWhere('profesor.edificio = :edificio', {
|
||||
query.andWhere('profesor.id_edificio = :edificio', {
|
||||
edificio: Number(filters.edificio),
|
||||
});
|
||||
}
|
||||
|
||||
// 🔹 Filtro por Activo
|
||||
if (typeof filters.activo !== 'undefined') {
|
||||
const isActive = filters.activo === 'true' || filters.activo === true;
|
||||
Logger.debug('Filter by active status');
|
||||
query.andWhere('profesor.activo = :activo', { activo: isActive });
|
||||
} else {
|
||||
query.orderBy('profesor.activo', 'DESC'); // Si no se especifica, prioriza activos
|
||||
}
|
||||
|
||||
query.addOrderBy('profesor.nombre', 'ASC');
|
||||
|
||||
// 🔹 Ejecutar consulta con paginación
|
||||
const [profesores, total] = await query
|
||||
.skip((page - 1) * limit)
|
||||
.take(limit)
|
||||
|
||||
@@ -18,9 +18,7 @@ export class ProyectosAcademicos {
|
||||
@Column({ type: 'varchar', length: 700, nullable: true })
|
||||
proyectos_html: string;
|
||||
|
||||
@ManyToOne(() => Profesor, (profesor) => profesor.proyectosAcademicos, {
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@ManyToOne(() => Profesor, (profesor) => profesor.proyectosAcademicos)
|
||||
@JoinColumn({
|
||||
name: 'id_profesor',
|
||||
})
|
||||
|
||||
@@ -17,11 +17,10 @@ import { JwtAuthGuard } from 'src/permissions/jwt.guard';
|
||||
@ApiBearerAuth()
|
||||
@ApiTags('proyectos-academicos')
|
||||
@Controller('proyectos-academicos')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class ProyectosAcademicosController {
|
||||
constructor(private proyectosAcademicosService: ProyectosAcademicosService) {}
|
||||
|
||||
@Patch(':id_proyecto')
|
||||
@Patch(':id_profesor')
|
||||
@ApiOperation({
|
||||
summary: 'Actualizar los proyectos academicos de un profesor',
|
||||
description:
|
||||
@@ -47,9 +46,9 @@ export class ProyectosAcademicosController {
|
||||
},
|
||||
})
|
||||
async updateProyectosAcademicos(
|
||||
@Param('id_proyecto') id_proyecto: number,
|
||||
@Param('id_profesor') id_profesor: number,
|
||||
@Body('proyectos_html') proyectos_html: string,
|
||||
@Body('id_profesor') id_profesor: number,
|
||||
@Body('id_proyecto') id_proyecto: number,
|
||||
) {
|
||||
if (!proyectos_html || proyectos_html.trim() === '') {
|
||||
throw new HttpException(
|
||||
|
||||
@@ -31,20 +31,30 @@ export class ProyectosAcademicosService {
|
||||
) {
|
||||
const profesor = await this.profesorService.findOne(id_profesor);
|
||||
|
||||
const proyectos = await this.proyectosAcademicosRepository.findOne({
|
||||
let proyecto = await this.proyectosAcademicosRepository.findOne({
|
||||
where: { profesor: profesor, id_proyecto },
|
||||
});
|
||||
|
||||
if (!proyectos) {
|
||||
if (!proyecto) {
|
||||
Logger.error(
|
||||
`No se encontrarón proyectos academicos del profesor con ID ${id_profesor} al intentar actualizarla \n Se procede a crear uno nuevo`,
|
||||
`No se encontraron proyectos académicos del profesor con ID ${id_profesor} al intentar actualizar. Se procederá a crear uno nuevo.`,
|
||||
);
|
||||
return await this.create(profesor);
|
||||
|
||||
// Crear nuevo proyecto con el contenido
|
||||
proyecto = this.proyectosAcademicosRepository.create({
|
||||
profesor: profesor,
|
||||
proyectos_html: nuevoContenido, // Se asigna el nuevo contenido directamente
|
||||
});
|
||||
|
||||
// Guardar el nuevo proyecto
|
||||
await this.proyectosAcademicosRepository.save(proyecto);
|
||||
} else {
|
||||
// Si ya existe, actualizar su contenido
|
||||
proyecto.proyectos_html = nuevoContenido;
|
||||
await this.proyectosAcademicosRepository.save(proyecto);
|
||||
}
|
||||
|
||||
proyectos.proyectos_html = nuevoContenido;
|
||||
|
||||
return await this.proyectosAcademicosRepository.save(proyectos);
|
||||
return proyecto; // Devolver el proyecto actualizado o recién creado
|
||||
}
|
||||
|
||||
async removeByProfesorId(id_profesor: number): Promise<void> {
|
||||
|
||||
@@ -26,7 +26,7 @@ export class Usuario {
|
||||
@Column({ type: 'varchar', length: 60, nullable: false })
|
||||
usuario: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 60, nullable: false })
|
||||
@Column({ type: 'varchar', length: 60, nullable: false }) // ALTER TABLE usuario CHANGE COLUMN contraseña password VARCHAR(60);
|
||||
password: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 255, nullable: true })
|
||||
@@ -41,8 +41,6 @@ export class Usuario {
|
||||
@ManyToOne(() => TipoUsuario, (tipoUsuario) => tipoUsuario.usuarios)
|
||||
@JoinColumn({
|
||||
name: 'id_tipo_usuario',
|
||||
referencedColumnName: 'id_tipo_usuario',
|
||||
foreignKeyConstraintName: 'FK_tipo_usuario',
|
||||
})
|
||||
tipoUsuario: TipoUsuario;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user