se agregó endpoint de ejemplo

This commit is contained in:
2025-11-05 10:43:08 -06:00
parent 5861064c8d
commit 7e7ee75511
7 changed files with 975 additions and 88 deletions
Binary file not shown.
Binary file not shown.
+801 -20
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -8,7 +8,7 @@
"scripts": {
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
@@ -31,6 +31,7 @@
"bcryptjs": "^3.0.2",
"class-transformer": "0.5.1",
"class-validator": "0.14.2",
"exceljs": "^4.4.0",
"mysql2": "^3.15.2",
"passport": "^0.7.0",
"passport-jwt": "^4.0.1",
+3 -3
View File
@@ -10,8 +10,8 @@ import { Equipo } from './equipo.entity';
@Entity()
export class Uso {
@PrimaryGeneratedColumn()
id_tipo_uso: number;
@PrimaryGeneratedColumn({ name: 'id_uso' })
id_uso: number;
@Column({ type: 'varchar', length: 100 })
tipo_uso: string;
@@ -108,7 +108,7 @@ export class Periferico {
@Entity('procesador_tipoequipo')
export class ProcesadorTipoEquipo {
@PrimaryGeneratedColumn({ name: 'id_Procesador_tipoeEquipo' })
@PrimaryGeneratedColumn({ name: 'id_Procesador_tipoEquipo' })
id: number;
@ManyToOne(() => Procesador, (procesador) => procesador.procesadorTipoEquipos)
+17
View File
@@ -8,12 +8,14 @@ import {
Get,
Query,
Post,
Res,
} from '@nestjs/common';
import { EquipoService } from './equipo.service';
import { UpdateEquipoDto } from './dto/update-equipo.dto';
import { AuthGuard } from '@nestjs/passport';
import { Equipo } from './entities/equipo.entity';
import { CreateEquipoDto } from './dto/create-equipo.dto';
import type { Response } from 'express';
@Controller('equipos')
export class EquipoController {
@@ -107,4 +109,19 @@ export class EquipoController {
) {
return this.equipoService.findAllProcesadorforTipoEquipos(idEquipo);
}
@Get('reporte')
async generarReporte(@Res() res: Response) {
try {
await this.equipoService.createEcxel(res);
} catch (error) {
console.error('Error al generar el Excel:', error);
res.status(500).send('Error al generar el archivo Excel');
}
}
@Post('example')
async generate() {
this.equipoService.example();
}
}
+152 -64
View File
@@ -4,10 +4,13 @@ import { Repository } from 'typeorm';
import { Equipo } from './entities/equipo.entity';
import { UpdateEquipoDto } from './dto/update-equipo.dto';
import axios from 'axios';
import { Response } from 'express';
import * as ExcelJS from 'exceljs';
import {
Adscripcion,
Estado,
Marca,
Periferico,
Procesador,
ProcesadorTipoEquipo,
SistemaOperativo,
@@ -43,8 +46,8 @@ export class EquipoService {
@InjectRepository(Procesador)
private readonly procesadorRepo: Repository<Procesador>,
@InjectRepository(Equipo)
private readonly perifericoRepo: Repository<Equipo>,
@InjectRepository(Periferico)
private readonly perifericoRepo: Repository<Periferico>,
@InjectRepository(ProcesadorTipoEquipo)
private readonly procesadorTipoEquipoRepo: Repository<ProcesadorTipoEquipo>,
@@ -139,9 +142,7 @@ export class EquipoService {
procesador: equipoNuevo.id_procesador
? { id_procesador: equipoNuevo.id_procesador }
: undefined,
tipoUso: equipoNuevo.id_tipo_uso
? { id_tipo_uso: equipoNuevo.id_tipo_uso }
: undefined,
tipoUso: equipoNuevo.id_uso ? { id_uso: equipoNuevo.id_uso } : undefined,
marca: equipoNuevo.id_marca
? { id_marca: equipoNuevo.id_marca }
: undefined,
@@ -216,7 +217,7 @@ export class EquipoService {
modelo: equipo.modelo,
estado: { id_estado: equipo.id_estado },
adscripcion: { id_adscripcion: equipo.id_adscripcion },
tipoUso: { id_tipo_uso: equipo.id_uso },
tipoUso: { id_uso: equipo.id_uso },
marca: { id_marca: equipo.id_marca },
periferico: { id_periferico: equipo.id_periferico },
});
@@ -243,7 +244,7 @@ export class EquipoService {
estado: { id_estado: equipo.id_estado },
adscripcion: { id_adscripcion: equipo.id_adscripcion },
sistemaOperativo: { id_sistema_operativo: equipo.id_sistema_operativo },
tipoUso: { id_tipo_uso: equipo.id_uso },
tipoUso: { id_uso: equipo.id_uso },
marca: { id_marca: equipo.id_marca },
});
}
@@ -294,6 +295,14 @@ export class EquipoService {
});
}
async createEcxel(res: Response) {
let obj = await this.generar_reporte();
const objectParse = Array.isArray(obj)
? obj.map((item) => this.flattenObject(item))
: [this.flattenObject(obj)];
return this.exportToClient(objectParse, res);
}
async contar_tipoEquipos_tipoUso(): Promise<any> {
try {
const count = await this.equipoRepository
@@ -303,7 +312,7 @@ export class EquipoService {
.select(['u.tipo_uso AS uso', 't.tipo_equipo AS categoria'])
.addSelect('COUNT(*) AS total')
.groupBy('t.id_tipo_de_equipo')
.addGroupBy('u.id_tipo_uso')
.addGroupBy('u.id_uso')
.getRawMany();
return count;
@@ -362,7 +371,7 @@ export class EquipoService {
.where('t.tipo_equipo IN (:...tipo_equipo)', { tipo_equipo })
.select(['t.tipo_equipo AS tipo_equipo'])
.addSelect('COUNT(*) AS total')
.groupBy('t.tipoEquipo')
.groupBy('t.tipo_equipo')
.getRawMany();
return count;
@@ -526,7 +535,7 @@ export class EquipoService {
const count = await this.equipoRepository
.createQueryBuilder('e')
.innerJoin('e.tipoUso', 't')
.innerJoin('e.periferico', 'te')
.innerJoin('e.periferico', 'p')
.where('p.periferico IN (:...perifericos)', { perifericos })
.select(['t.tipo_uso AS uso'])
.addSelect('COUNT(*) AS total')
@@ -608,65 +617,144 @@ export class EquipoService {
}
async generar_reporte() {
let contar_te_tu = await this.contar_tipoEquipos_tipoUso();
let so_pc = await this.contar_tipoEquipos_sistemasOperativos(equpos_pc);
let so_mac = await this.contar_tipoEquipos_sistemasOperativos([
estritorio_mac,
const [
contar_equipos_de_tipo_uso,
sisitema_operativo_pc,
sisitema_operativo_mac,
sisitema_operativo_portatiles_pc,
sisitema_operativo_portatiles_mac,
sisitema_operativo_servidores,
contar_pc_procesador,
contar_mac_procesador,
contar_portatil_procesador,
contar_portatil_mac_procesador,
contar_servidor_procesador,
porcentaje_antiguedad,
garantia_escritorio,
garantia_portatiles,
garantia_servidor,
contar_impresoras,
contar_impresoras_tipo_uso,
contar_digitalizacion,
contar_contar_digitalizacion_u,
] = await Promise.all([
this.contar_tipoEquipos_tipoUso(),
this.contar_tipoEquipos_sistemasOperativos(equpos_pc),
this.contar_tipoEquipos_sistemasOperativos([estritorio_mac]),
this.contar_tipoEquipos_sistemasOperativos(portatiles),
this.contar_tipoEquipos_sistemasOperativos([portatiles_mac]),
this.contar_tipoEquipos_sistemasOperativos([servidor]),
this.contar_tipoEquipos_procesador(equpos_pc),
this.contar_tipoEquipos_procesador([estritorio_mac]),
this.contar_tipoEquipos_procesador(portatiles),
this.contar_tipoEquipos_procesador([portatiles_mac]),
this.contar_tipoEquipos_procesador([servidor]),
this.contar_tipoEquipos_antiguedad(),
this.garantia(escritorio),
this.garantia(portatil),
this.garantia([servidor]),
this.equipos_impesion_group(impresoras),
this.contar_periferico_tipoUso(impresoras),
this.equipos_impesion_group(dijitales),
this.contar_periferico_tipoUso(dijitales),
]);
let so_ppc = await this.contar_tipoEquipos_sistemasOperativos(portatiles);
let so_pmac = await this.contar_tipoEquipos_sistemasOperativos([
portatiles_mac,
]);
let so_serv = await this.contar_tipoEquipos_sistemasOperativos([servidor]);
let contar_pc_p = await this.contar_tipoEquipos_procesador(equpos_pc);
let contar_macpc_p = await this.contar_tipoEquipos_procesador([
estritorio_mac,
]);
let contar_p_p = await this.contar_tipoEquipos_procesador(portatiles);
let contar_pmac_p = await this.contar_tipoEquipos_procesador([
portatiles_mac,
]);
let contar_serv = await this.contar_tipoEquipos_procesador([servidor]);
let porcentaje = await this.contar_tipoEquipos_antiguedad();
let garantia_e = await this.garantia(escritorio);
let garantia_p = await this.garantia(portatil);
let garantia_s = await this.garantia([servidor]);
let contar_impresoras = await this.equipos_impesion_group(impresoras);
let contar_i_u = await this.contar_periferico_tipoUso(impresoras);
let contar_digitalizacion = await this.equipos_impesion_group(dijitales);
let contar_d_u = await this.contar_periferico_tipoUso(dijitales);
let garantia_periferico = await this.generar_reporte();
return {
...contar_te_tu,
...so_pc,
...so_mac,
...so_ppc,
...so_pmac,
...so_serv,
...contar_pc_p,
...contar_macpc_p,
...contar_p_p,
...contar_pmac_p,
...contar_serv,
...porcentaje,
...garantia_e,
...garantia_p,
...garantia_s,
...contar_impresoras,
...contar_i_u,
...contar_digitalizacion,
...contar_d_u,
...garantia_periferico,
contar_equipos_de_tipo_uso,
sisitema_operativo_pc,
sisitema_operativo_mac,
sisitema_operativo_portatiles_pc,
sisitema_operativo_portatiles_mac,
sisitema_operativo_servidores,
contar_pc_procesador,
contar_mac_procesador,
contar_portatil_procesador,
contar_portatil_mac_procesador,
contar_servidor_procesador,
porcentaje_antiguedad,
garantia_escritorio,
garantia_portatiles,
garantia_servidor,
contar_impresoras,
contar_impresoras_tipo_uso,
contar_digitalizacion,
contar_contar_digitalizacion_u,
};
}
async exportToClient(data: any, res: Response) {
// Aseguramos que los datos sean un arreglo de objetos planos
const rows = Array.isArray(data)
? data.map((item) => this.flattenObject(item))
: [this.flattenObject(data)];
// Crear workbook y hoja
const workbook = new ExcelJS.Workbook();
const worksheet = workbook.addWorksheet('Datos');
// Definir encabezados dinámicamente
const headers = Object.keys(rows[0] || {});
worksheet.columns = headers.map((h) => ({
header: h,
key: h,
width: 25,
}));
// Agregar filas
worksheet.addRows(rows);
// Estilizar encabezados
const headerRow = worksheet.getRow(1);
headerRow.font = { bold: true };
headerRow.alignment = { vertical: 'middle', horizontal: 'center' };
headerRow.eachCell((cell) => {
cell.border = {
top: { style: 'thin' },
left: { style: 'thin' },
bottom: { style: 'thin' },
right: { style: 'thin' },
};
});
// Configurar cabeceras HTTP
res.setHeader(
'Content-Type',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
);
res.setHeader('Content-Disposition', 'attachment; filename="reporte.xlsx"');
// Enviar directamente al cliente
await workbook.xlsx.write(res);
res.end();
}
private flattenObject(obj: any, parentKey = '', res: any = {}): any {
for (const key of Object.keys(obj || {})) {
const propName = parentKey ? `${parentKey}.${key}` : key;
const value = obj[key];
if (value && typeof value === 'object' && !Array.isArray(value)) {
this.flattenObject(value, propName, res);
} else if (Array.isArray(value)) {
res[propName] = JSON.stringify(value);
} else {
res[propName] = value;
}
}
return res;
}
async example() {
await this.usoRepo.save({ tipo_uso: 'ej' });
await this.marcaRepo.save({ marca: 'ej' });
await this.estadoRepo.save({ estado: 'ej' });
await this.adscripcionRepo.save({ adscripcion: 'ej' });
let tipo = await this.tipoEquipoRepo.save({ tipo_equipo: 'ej' });
await this.sistemaOperativoRepo.save({ sistema_operativo: 'ej' });
let procesador = await this.procesadorRepo.save({ procesador: 'ej' });
await this.perifericoRepo.save({ periferico: 'el' });
await this.procesadorTipoEquipoRepo.save({ procesador, tipoEquipo: tipo });
}
}
let escritorio = [