mirror of
https://github.com/sergeyyarkov/asu_tools_service.git
synced 2026-10-11 18:39:15 +03:00
refactor
This commit is contained in:
parent
9cff9624a8
commit
53a8cab4fb
@ -1,5 +1,4 @@
|
|||||||
import { equipmentRepository } from "#root/repositories/equipment.repository.js";
|
import { dbExporterService, XlsExporterAdapter } from "#root/services/dbExporter.service.js";
|
||||||
import ExcelJS from "exceljs";
|
|
||||||
|
|
||||||
/** @import { HttpRouteHandler } from "#root/http-server/types/http-server.js" */
|
/** @import { HttpRouteHandler } from "#root/http-server/types/http-server.js" */
|
||||||
|
|
||||||
@ -12,193 +11,14 @@ import ExcelJS from "exceljs";
|
|||||||
*/
|
*/
|
||||||
export default async (ctx) => {
|
export default async (ctx) => {
|
||||||
const { res, searchParams } = ctx;
|
const { res, searchParams } = ctx;
|
||||||
|
|
||||||
const systemIdsParam = searchParams.get("systemIds")?.split(",");
|
const systemIdsParam = searchParams.get("systemIds")?.split(",");
|
||||||
|
|
||||||
const wb = new ExcelJS.Workbook();
|
|
||||||
const ws = wb.addWorksheet("Перечень систем", {
|
|
||||||
views: [{ state: "frozen", ySplit: 1, zoomScale: 70 }]
|
|
||||||
});
|
|
||||||
|
|
||||||
const filename = encodeURIComponent("АСУ промплощадка.xlsx");
|
const filename = encodeURIComponent("АСУ промплощадка.xlsx");
|
||||||
const equipmentData = await equipmentRepository.getAll({ filter: { systemIds: systemIdsParam } });
|
const exportResult = await dbExporterService.export(XlsExporterAdapter, { filter: { systemIds: systemIdsParam } });
|
||||||
|
|
||||||
const excelData = [];
|
|
||||||
|
|
||||||
/** @type {Map<string, { row: number }} */
|
|
||||||
const addedBaseLocationNames = new Map();
|
|
||||||
|
|
||||||
/** @type {{ colStart: string, colEnd: string, from: number; to: number }[]} */
|
|
||||||
const mergeRanges = [];
|
|
||||||
|
|
||||||
let currentRow = 2;
|
|
||||||
|
|
||||||
for (const system of equipmentData) {
|
|
||||||
const subsystems = system.subsystems || [];
|
|
||||||
|
|
||||||
if (subsystems.length === 0) {
|
|
||||||
excelData.push([system.name, ...new Array(8).fill("", 0, 8)]);
|
|
||||||
currentRow++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Заголовок для расположения систем
|
|
||||||
if (!addedBaseLocationNames.has(system.baseLocationName)) {
|
|
||||||
addedBaseLocationNames.set(system.baseLocationName, { row: currentRow });
|
|
||||||
excelData.push([system.baseLocationName]);
|
|
||||||
mergeRanges.push({ colStart: "A", colEnd: "I", from: currentRow, to: currentRow });
|
|
||||||
currentRow++;
|
|
||||||
}
|
|
||||||
|
|
||||||
const startRow = currentRow;
|
|
||||||
|
|
||||||
// Добавление систем подсистем в таблицу excel
|
|
||||||
subsystems.forEach((subsystem) => {
|
|
||||||
const hasDocLink = Boolean(subsystem?.docLink);
|
|
||||||
const hasElectroPlan = Boolean(subsystem?.electrDiagLink);
|
|
||||||
const plcs = subsystem?.plcs || [];
|
|
||||||
const hmis = subsystem?.hmis || [];
|
|
||||||
const fgs = subsystem?.fgs || [];
|
|
||||||
const pcs = subsystem?.pcs || [];
|
|
||||||
|
|
||||||
excelData.push([
|
|
||||||
system.name,
|
|
||||||
subsystem.name,
|
|
||||||
`${system.baseLocationName} ${subsystem.locationName}`,
|
|
||||||
hasDocLink ? { text: "Документация", hyperlink: subsystem?.docLink } : "",
|
|
||||||
hasElectroPlan ? { text: "Электроплан", hyperlink: subsystem?.electrDiagLink } : "",
|
|
||||||
plcs.map((plc) => `${plc.nameModel || ""}`).join("\n"),
|
|
||||||
hmis.map((hmi) => `${hmi.nameModel || ""}`).join("\n"),
|
|
||||||
fgs.map((fg) => `${fg.nameModel || ""}`).join("\n"),
|
|
||||||
pcs.map((pc) => `${pc.name || ""}`).join("\n")
|
|
||||||
]);
|
|
||||||
|
|
||||||
currentRow++;
|
|
||||||
});
|
|
||||||
|
|
||||||
mergeRanges.push({ colStart: "A", colEnd: "A", from: startRow, to: currentRow - 1 });
|
|
||||||
}
|
|
||||||
|
|
||||||
ws.getRow(1).values = [
|
|
||||||
"Наименование системы",
|
|
||||||
"Наименование внутренних подсистем.",
|
|
||||||
"Расположение",
|
|
||||||
"Документация",
|
|
||||||
"Электроплан",
|
|
||||||
"PLC",
|
|
||||||
"HMI",
|
|
||||||
"ПЧ",
|
|
||||||
"Промышленные ПК"
|
|
||||||
];
|
|
||||||
|
|
||||||
ws.autoFilter = `A1:I${excelData.length + 1}`;
|
|
||||||
|
|
||||||
ws.addRows(excelData);
|
|
||||||
|
|
||||||
mergeRanges.forEach((r) => ws.mergeCells(`${r.colStart}${r.from}:${r.colEnd}${r.to}`));
|
|
||||||
|
|
||||||
ws.getColumn(1).width = 50;
|
|
||||||
ws.getColumn(2).width = 50;
|
|
||||||
ws.getColumn(3).width = 35;
|
|
||||||
ws.getColumn(4).width = 17;
|
|
||||||
ws.getColumn(5).width = 17;
|
|
||||||
ws.getColumn(6).width = 45;
|
|
||||||
ws.getColumn(7).width = 45;
|
|
||||||
ws.getColumn(8).width = 45;
|
|
||||||
ws.getColumn(9).width = 30;
|
|
||||||
ws.getRow(1).height = 45;
|
|
||||||
|
|
||||||
ws.eachRow((row, rowNumber) => {
|
|
||||||
row.eachCell({ includeEmpty: true }, (cell) => {
|
|
||||||
cell.alignment = {
|
|
||||||
wrapText: true,
|
|
||||||
vertical: "middle",
|
|
||||||
horizontal: "center"
|
|
||||||
};
|
|
||||||
|
|
||||||
if (rowNumber > 1) {
|
|
||||||
cell.font = {
|
|
||||||
name: "Calibri",
|
|
||||||
size: 12
|
|
||||||
};
|
|
||||||
cell.border = {
|
|
||||||
top: { style: "thin", color: { argb: "FF000000" } },
|
|
||||||
left: { style: "thin", color: { argb: "FF000000" } },
|
|
||||||
right: { style: "thin", color: { argb: "FF000000" } },
|
|
||||||
bottom: { style: "thin", color: { argb: "FF000000" } }
|
|
||||||
};
|
|
||||||
cell.fill = {
|
|
||||||
type: "pattern",
|
|
||||||
pattern: "solid",
|
|
||||||
fgColor: { argb: "FFF4F4F4" }
|
|
||||||
};
|
|
||||||
|
|
||||||
if (cell.value === null || cell.value === undefined || cell.value === "") {
|
|
||||||
cell.fill = {
|
|
||||||
type: "pattern",
|
|
||||||
pattern: "solid",
|
|
||||||
fgColor: { argb: "FFFCE4D6" }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ссылки
|
|
||||||
if (cell.value && typeof cell.value === "object" && "hyperlink" in cell.value) {
|
|
||||||
cell.font = {
|
|
||||||
name: "Calibri",
|
|
||||||
size: 11,
|
|
||||||
color: { argb: "FF0563C1" },
|
|
||||||
underline: "single"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cell.font = {
|
|
||||||
name: "Calibri",
|
|
||||||
size: 11,
|
|
||||||
color: { argb: "FFFFFFFF" }
|
|
||||||
};
|
|
||||||
|
|
||||||
cell.border = {
|
|
||||||
top: { style: "thin", color: { argb: "FF000000" } },
|
|
||||||
right: { style: "thin", color: { argb: "FF000000" } },
|
|
||||||
bottom: { style: "thin", color: { argb: "FF000000" } }
|
|
||||||
};
|
|
||||||
|
|
||||||
cell.fill = {
|
|
||||||
type: "pattern",
|
|
||||||
pattern: "solid",
|
|
||||||
fgColor: { argb: "FFF27A2B" }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
addedBaseLocationNames.forEach((baseLocationHeaderRow) => {
|
|
||||||
const row = ws.getRow(baseLocationHeaderRow.row);
|
|
||||||
row.height = 30;
|
|
||||||
row.eachCell((cell) => {
|
|
||||||
cell.font = {
|
|
||||||
name: "Tahoma",
|
|
||||||
bold: true,
|
|
||||||
size: 11
|
|
||||||
};
|
|
||||||
cell.border = {
|
|
||||||
top: { style: "medium", color: { argb: "FF000000" } },
|
|
||||||
bottom: { style: "medium", color: { argb: "FF000000" } }
|
|
||||||
};
|
|
||||||
cell.fill = {
|
|
||||||
type: "pattern",
|
|
||||||
pattern: "solid",
|
|
||||||
fgColor: { argb: "FF92D050" }
|
|
||||||
};
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const excelBuffer = await wb.xlsx.writeBuffer();
|
|
||||||
|
|
||||||
res.res.setHeader("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
res.res.setHeader("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
res.res.setHeader("Content-Disposition", `attachment; filename=${filename}; filename*=UTF-8''${filename}`);
|
res.res.setHeader("Content-Disposition", `attachment; filename=${filename}; filename*=UTF-8''${filename}`);
|
||||||
res.res.setHeader("Content-Length", excelBuffer.byteLength);
|
res.res.setHeader("Content-Length", exportResult.byteLength);
|
||||||
res.res.end(excelBuffer);
|
res.res.end(exportResult);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1 +1,2 @@
|
|||||||
export * from "./report.model.js";
|
export * from "./report.model.js";
|
||||||
|
export * from "./system.model.js";
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { BaseModel } from "./base.model.js";
|
import { BaseModel } from "./base.model.js";
|
||||||
|
|
||||||
/** @import { ReportColumns } from "#tables/report.table.js" */
|
/** @import { ReportColumns } from "./types.js" */
|
||||||
|
|
||||||
export class ReportModel extends BaseModel {
|
export class ReportModel extends BaseModel {
|
||||||
/**
|
/**
|
||||||
|
|||||||
20
models/system.model.js
Normal file
20
models/system.model.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { BaseModel } from "./base.model.js";
|
||||||
|
|
||||||
|
/** @import { SystemModelTableCols } from "./types.js" */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @implements { SystemModelTableCols }
|
||||||
|
*/
|
||||||
|
export class SystemModel extends BaseModel {
|
||||||
|
id;
|
||||||
|
location_id;
|
||||||
|
name;
|
||||||
|
|
||||||
|
/** @param {SystemModelTableCols} columns */
|
||||||
|
constructor(columns) {
|
||||||
|
super();
|
||||||
|
this.id = columns.id;
|
||||||
|
this.location_id = columns.location_id;
|
||||||
|
this.name = columns.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
17
models/types.d.ts
vendored
Normal file
17
models/types.d.ts
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
export type ReportColumns = {
|
||||||
|
id?: number | string;
|
||||||
|
date: Date;
|
||||||
|
reason_call: string;
|
||||||
|
job_description: string;
|
||||||
|
root_cause: string | null;
|
||||||
|
applicant_id: number | string | null;
|
||||||
|
equipment_id: number | string | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ReportExecutorTableCols = { id: string | number; report_id: string | number; user_id: string | number };
|
||||||
|
|
||||||
|
export type SystemModelTableCols = {
|
||||||
|
id: string | number;
|
||||||
|
name: string | null;
|
||||||
|
location_id: string | number | null;
|
||||||
|
};
|
||||||
@ -1,9 +1,23 @@
|
|||||||
import { UOW } from "./index.js";
|
import { UOW } from "./index.js";
|
||||||
import sql from "mssql";
|
import sql from "mssql";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {{ name: string, nameModel?: string | null; }} EquipmentDbRecord;
|
||||||
|
*
|
||||||
|
* @typedef {{ id: string, name?: string,
|
||||||
|
* docLink?: string | null, electrDiagLink?: string | null,
|
||||||
|
* locationName?: string | null, plcs?: Array<EquipmentDbRecord>,
|
||||||
|
* fgs?: Array<EquipmentDbRecord>, hmis: Array<EquipmentDbRecord>,
|
||||||
|
* pcs?: Array<EquipmentDbRecord>
|
||||||
|
* }} SubSystemDbRecord;
|
||||||
|
*
|
||||||
|
* @typedef {{ id: string, name: string, baseLocationName: string, subsystems: Array<SubSystemDbRecord> }} SystemDbRecord;
|
||||||
|
*/
|
||||||
|
|
||||||
export const equipmentRepository = {
|
export const equipmentRepository = {
|
||||||
/**
|
/**
|
||||||
* @param {{ filter?: { systemIds?: string[] | number[] } }} [options]
|
* @param {{ filter?: { systemIds?: string[] | number[] } }} [options]
|
||||||
|
* @returns {Promise<Array<SystemDbRecord>>}
|
||||||
*/
|
*/
|
||||||
async getAll(options) {
|
async getAll(options) {
|
||||||
const request = UOW.request;
|
const request = UOW.request;
|
||||||
|
|||||||
20
services/dbExporter.service.js
Normal file
20
services/dbExporter.service.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { equipmentRepository } from "#root/repositories/equipment.repository.js";
|
||||||
|
|
||||||
|
/** @import { ExporterAdapterInterface } from './types.js' */
|
||||||
|
|
||||||
|
export const dbExporterService = {
|
||||||
|
/**
|
||||||
|
* @param { new () => ExporterAdapterInterface } Adapter
|
||||||
|
* @param {{ filter?: { systemIds?: number[] | string[] } }} options
|
||||||
|
* */
|
||||||
|
async export(Adapter, options) {
|
||||||
|
const db = await equipmentRepository.getAll({ filter: options.filter });
|
||||||
|
const AdapterInstance = new Adapter();
|
||||||
|
|
||||||
|
/** @type {Buffer} */
|
||||||
|
const data = await AdapterInstance.export(db);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export * from "./exporters/index.js";
|
||||||
199
services/exporters/excel.exporter.js
Normal file
199
services/exporters/excel.exporter.js
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
import ExcelJS from "exceljs";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @import { ExporterAdapterInterface } from '../types.js'
|
||||||
|
* @import { SystemDbRecord } from '#repositories/equipment.repository.js'
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @implements {ExporterAdapterInterface} */
|
||||||
|
export class XlsExporterAdapter {
|
||||||
|
/** @type {Partial<ExcelJS.AddWorksheetOptions>} */
|
||||||
|
static mainWsOptions = { views: [{ state: "frozen", ySplit: 1, zoomScale: 70 }] };
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.wb = new ExcelJS.Workbook();
|
||||||
|
this.ws = this.wb.addWorksheet("Перечень систем", XlsExporterAdapter.mainWsOptions);
|
||||||
|
|
||||||
|
/** @type {Array<any[]>} */
|
||||||
|
this.data = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {SystemDbRecord[]} db */
|
||||||
|
async export(db) {
|
||||||
|
/** @type {Map<string, { row: number }>} */
|
||||||
|
const addedBaseLocationNames = new Map();
|
||||||
|
|
||||||
|
/** @type {{ colStart: string, colEnd: string, from: number; to: number }[]} */
|
||||||
|
const mergeRanges = [];
|
||||||
|
|
||||||
|
let currentRow = 2;
|
||||||
|
|
||||||
|
for (const system of db) {
|
||||||
|
const subsystems = system.subsystems || [];
|
||||||
|
|
||||||
|
// Подсистема не найдены, добавляет название системы с пустыми ячейками
|
||||||
|
if (subsystems.length === 0) {
|
||||||
|
this.data.push([system.name, ...new Array(8).fill("", 0, 8)]);
|
||||||
|
currentRow++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Заголовок для расположения систем
|
||||||
|
if (!addedBaseLocationNames.has(system.baseLocationName)) {
|
||||||
|
addedBaseLocationNames.set(system.baseLocationName, { row: currentRow });
|
||||||
|
this.data.push([system.baseLocationName]);
|
||||||
|
mergeRanges.push({ colStart: "A", colEnd: "I", from: currentRow, to: currentRow });
|
||||||
|
currentRow++;
|
||||||
|
}
|
||||||
|
|
||||||
|
const startRow = currentRow;
|
||||||
|
|
||||||
|
// Добавление систем и подсистем в таблицу Excel
|
||||||
|
subsystems.forEach((subsystem) => {
|
||||||
|
const hasDocLink = Boolean(subsystem?.docLink);
|
||||||
|
const hasElectroPlan = Boolean(subsystem?.electrDiagLink);
|
||||||
|
const plcs = subsystem?.plcs || [];
|
||||||
|
const hmis = subsystem?.hmis || [];
|
||||||
|
const fgs = subsystem?.fgs || [];
|
||||||
|
const pcs = subsystem?.pcs || [];
|
||||||
|
|
||||||
|
this.data.push([
|
||||||
|
system.name,
|
||||||
|
subsystem.name,
|
||||||
|
`${system.baseLocationName} ${subsystem.locationName}`,
|
||||||
|
hasDocLink ? { text: "Документация", hyperlink: subsystem?.docLink } : "",
|
||||||
|
hasElectroPlan ? { text: "Электроплан", hyperlink: subsystem?.electrDiagLink } : "",
|
||||||
|
plcs.map((plc) => `${plc.nameModel || ""}`).join("\n"),
|
||||||
|
hmis.map((hmi) => `${hmi.nameModel || ""}`).join("\n"),
|
||||||
|
fgs.map((fg) => `${fg.nameModel || ""}`).join("\n"),
|
||||||
|
pcs.map((pc) => `${pc.name || ""}`).join("\n")
|
||||||
|
]);
|
||||||
|
|
||||||
|
currentRow++;
|
||||||
|
});
|
||||||
|
|
||||||
|
mergeRanges.push({ colStart: "A", colEnd: "A", from: startRow, to: currentRow - 1 });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ws.getRow(1).values = [
|
||||||
|
"Наименование системы",
|
||||||
|
"Наименование внутренних подсистем.",
|
||||||
|
"Расположение",
|
||||||
|
"Документация",
|
||||||
|
"Электроплан",
|
||||||
|
"PLC",
|
||||||
|
"HMI",
|
||||||
|
"ПЧ",
|
||||||
|
"Промышленные ПК"
|
||||||
|
];
|
||||||
|
|
||||||
|
this.ws.autoFilter = `A1:I${this.data.length + 1}`;
|
||||||
|
|
||||||
|
this.ws.addRows(this.data);
|
||||||
|
|
||||||
|
mergeRanges.forEach((r) => this.ws.mergeCells(`${r.colStart}${r.from}:${r.colEnd}${r.to}`));
|
||||||
|
|
||||||
|
this.ws.getColumn(1).width = 50;
|
||||||
|
this.ws.getColumn(2).width = 50;
|
||||||
|
this.ws.getColumn(3).width = 35;
|
||||||
|
this.ws.getColumn(4).width = 17;
|
||||||
|
this.ws.getColumn(5).width = 17;
|
||||||
|
this.ws.getColumn(6).width = 45;
|
||||||
|
this.ws.getColumn(7).width = 45;
|
||||||
|
this.ws.getColumn(8).width = 45;
|
||||||
|
this.ws.getColumn(9).width = 30;
|
||||||
|
this.ws.getRow(1).height = 45;
|
||||||
|
|
||||||
|
this.ws.eachRow((row, rowNumber) => {
|
||||||
|
row.eachCell({ includeEmpty: true }, (cell) => {
|
||||||
|
cell.alignment = {
|
||||||
|
wrapText: true,
|
||||||
|
vertical: "middle",
|
||||||
|
horizontal: "center"
|
||||||
|
};
|
||||||
|
|
||||||
|
if (rowNumber > 1) {
|
||||||
|
cell.font = {
|
||||||
|
name: "Calibri",
|
||||||
|
size: 12
|
||||||
|
};
|
||||||
|
cell.border = {
|
||||||
|
top: { style: "thin", color: { argb: "FF000000" } },
|
||||||
|
left: { style: "thin", color: { argb: "FF000000" } },
|
||||||
|
right: { style: "thin", color: { argb: "FF000000" } },
|
||||||
|
bottom: { style: "thin", color: { argb: "FF000000" } }
|
||||||
|
};
|
||||||
|
cell.fill = {
|
||||||
|
type: "pattern",
|
||||||
|
pattern: "solid",
|
||||||
|
fgColor: { argb: "FFF4F4F4" }
|
||||||
|
};
|
||||||
|
|
||||||
|
if (cell.value === null || cell.value === undefined || cell.value === "") {
|
||||||
|
cell.fill = {
|
||||||
|
type: "pattern",
|
||||||
|
pattern: "solid",
|
||||||
|
fgColor: { argb: "FFFCE4D6" }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ссылки
|
||||||
|
if (cell.value && typeof cell.value === "object" && "hyperlink" in cell.value) {
|
||||||
|
cell.font = {
|
||||||
|
name: "Calibri",
|
||||||
|
size: 11,
|
||||||
|
color: { argb: "FF0563C1" },
|
||||||
|
underline: "single"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cell.font = {
|
||||||
|
name: "Calibri",
|
||||||
|
size: 11,
|
||||||
|
color: { argb: "FFFFFFFF" }
|
||||||
|
};
|
||||||
|
|
||||||
|
cell.border = {
|
||||||
|
top: { style: "thin", color: { argb: "FF000000" } },
|
||||||
|
right: { style: "thin", color: { argb: "FF000000" } },
|
||||||
|
bottom: { style: "thin", color: { argb: "FF000000" } }
|
||||||
|
};
|
||||||
|
|
||||||
|
cell.fill = {
|
||||||
|
type: "pattern",
|
||||||
|
pattern: "solid",
|
||||||
|
fgColor: { argb: "FFF27A2B" }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
addedBaseLocationNames.forEach((baseLocationHeaderRow) => {
|
||||||
|
const row = this.ws.getRow(baseLocationHeaderRow.row);
|
||||||
|
row.height = 30;
|
||||||
|
row.eachCell((cell) => {
|
||||||
|
cell.font = {
|
||||||
|
name: "Tahoma",
|
||||||
|
bold: true,
|
||||||
|
size: 11
|
||||||
|
};
|
||||||
|
cell.border = {
|
||||||
|
top: { style: "medium", color: { argb: "FF000000" } },
|
||||||
|
bottom: { style: "medium", color: { argb: "FF000000" } }
|
||||||
|
};
|
||||||
|
cell.fill = {
|
||||||
|
type: "pattern",
|
||||||
|
pattern: "solid",
|
||||||
|
fgColor: { argb: "FF92D050" }
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const excelBuffer = await this.wb.xlsx.writeBuffer();
|
||||||
|
|
||||||
|
/** @type {Buffer} */
|
||||||
|
return excelBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
setupStyles() {}
|
||||||
|
}
|
||||||
1
services/exporters/index.js
Normal file
1
services/exporters/index.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from "./excel.exporter.js";
|
||||||
@ -1 +1,2 @@
|
|||||||
export * from "./reports.service.js";
|
export * from "./reports.service.js";
|
||||||
|
export * from "./dbExporter.service.js";
|
||||||
|
|||||||
5
services/types.d.ts
vendored
Normal file
5
services/types.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { SystemDbRecord } from "#root/repositories/equipment.repository.js";
|
||||||
|
|
||||||
|
export interface ExporterAdapterInterface {
|
||||||
|
export: (database: Array<SystemDbRecord>) => Promise<any>;
|
||||||
|
}
|
||||||
@ -1,10 +1,6 @@
|
|||||||
import sql from "mssql";
|
import sql from "mssql";
|
||||||
import { BaseTable } from "./base.table.js";
|
import { BaseTable } from "./base.table.js";
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {{ id?: number | string; date: Date; reason_call: string; job_description: string; root_cause: string | null; applicant_id: number | string | null; equipment_id: number | string | null; }} ReportColumns
|
|
||||||
*/
|
|
||||||
|
|
||||||
export class ReportTable extends BaseTable {
|
export class ReportTable extends BaseTable {
|
||||||
static tableName = "gpp_report_api_report";
|
static tableName = "gpp_report_api_report";
|
||||||
static table = new sql.Table(this.tableName);
|
static table = new sql.Table(this.tableName);
|
||||||
|
|||||||
@ -1,10 +1,6 @@
|
|||||||
import sql from "mssql";
|
import sql from "mssql";
|
||||||
import { BaseTable } from "./base.table.js";
|
import { BaseTable } from "./base.table.js";
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {{ id: string | number; report_id: string | number; user_id: string | number; }} ReportExecutorTableCols
|
|
||||||
*/
|
|
||||||
|
|
||||||
export class ReportExecutorTable extends BaseTable {
|
export class ReportExecutorTable extends BaseTable {
|
||||||
static tableName = "gpp_report_api_report_executor";
|
static tableName = "gpp_report_api_report_executor";
|
||||||
static table = new sql.Table(this.tableName);
|
static table = new sql.Table(this.tableName);
|
||||||
|
|||||||
16
tables/system.table.js
Normal file
16
tables/system.table.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import sql from "mssql";
|
||||||
|
import { BaseTable } from "./base.table.js";
|
||||||
|
|
||||||
|
export class SystemTable extends BaseTable {
|
||||||
|
static tableName = "asu_system_api_systemlist";
|
||||||
|
static table = new sql.Table(this.tableName);
|
||||||
|
|
||||||
|
static columns = {
|
||||||
|
id: { type: sql.BigInt, nullable: false },
|
||||||
|
location_id: { type: sql.BigInt, nullable: true },
|
||||||
|
name: { type: sql.VarChar, nullable: true }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemTable.table.create = false;
|
||||||
|
SystemTable.init();
|
||||||
Loading…
x
Reference in New Issue
Block a user