mirror of
https://github.com/sergeyyarkov/asu_tools_service.git
synced 2026-10-11 02:19:09 +03:00
экспорт по подсистеме
This commit is contained in:
parent
8139a711f4
commit
29ebc98d0e
@ -12,8 +12,11 @@ import { dbExporterService, XlsExporterAdapter } from "#root/services/dbExporter
|
|||||||
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 subSystemIdsParam = searchParams.get("subSystemIds")?.split(",");
|
||||||
const filename = encodeURIComponent("АСУ промплощадка.xlsx");
|
const filename = encodeURIComponent("АСУ промплощадка.xlsx");
|
||||||
const exportResult = await dbExporterService.export(XlsExporterAdapter, { filter: { systemIds: systemIdsParam } });
|
const exportResult = await dbExporterService.export(XlsExporterAdapter, {
|
||||||
|
filter: { systemIds: systemIdsParam, subsystemIds: subSystemIdsParam }
|
||||||
|
});
|
||||||
|
|
||||||
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}`);
|
||||||
|
|||||||
@ -2,13 +2,108 @@ import { UOW } from "./index.js";
|
|||||||
import sql from "mssql";
|
import sql from "mssql";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {{ name: string, nameModel?: string | null; }} EquipmentDbRecord;
|
* @typedef {{
|
||||||
*
|
* invNumber?: string | null;
|
||||||
|
* location?: string | null;
|
||||||
|
* purpose?: string | null;
|
||||||
|
* name?: string | null;
|
||||||
|
* adminLoginPass?: string | null;
|
||||||
|
* workerLoginPass?: string | null;
|
||||||
|
* promConn?: string | null;
|
||||||
|
* compConn?: string | null;
|
||||||
|
* locAndRemark?: string | null;
|
||||||
|
* upsReq?: string | null;
|
||||||
|
* upsAvail?: string | null;
|
||||||
|
* lastServiceDate?: string | null;
|
||||||
|
* osVersion?: string | null;
|
||||||
|
* indSoftInst?: string | null;
|
||||||
|
* softAdminLoginPass?: string | null;
|
||||||
|
* projectSource?: string | null;
|
||||||
|
* projectSourceLink?: string | null;
|
||||||
|
* comments?: string | null;
|
||||||
|
* projectArchieveLink?: string | null;
|
||||||
|
* config?: PCConfigDbRecord[] | null;
|
||||||
|
* }} PcEquipmentDbRecord
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {{
|
||||||
|
* nameModel?: string | null;
|
||||||
|
* partNum?: string | null;
|
||||||
|
* cabinet?: string | null;
|
||||||
|
* cabinetLocation?: string | null;
|
||||||
|
* purpose?: string | null;
|
||||||
|
* adminLoginPass?: string | null;
|
||||||
|
* workerLoginPass?: string | null;
|
||||||
|
* interface?: string | null;
|
||||||
|
* cableLocation?: string | null;
|
||||||
|
* projectName?: string | null;
|
||||||
|
* projectLink?: string | null;
|
||||||
|
* diskImage?: string | null;
|
||||||
|
* imageLink?: string | null;
|
||||||
|
* connectionSettings?: string | null;
|
||||||
|
* }} HmiModelDbRecord
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {{
|
||||||
|
* modelName?: string | null;
|
||||||
|
* partNum?: string | null;
|
||||||
|
* motherboard?: string | null;
|
||||||
|
* socket?: string | null;
|
||||||
|
* cpu?: string | null;
|
||||||
|
* mem?: string | null;
|
||||||
|
* memVolume?: string | null;
|
||||||
|
* hdd?: string | null;
|
||||||
|
* hddVolume?: string | null;
|
||||||
|
* expansionCards?: string | null;
|
||||||
|
* externalDevices?: string | null;
|
||||||
|
* caseFan?: string | null;
|
||||||
|
* cpuFan?: string | null;
|
||||||
|
* powerUnit?: string | null;
|
||||||
|
* }} PCConfigDbRecord
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {{
|
||||||
|
* nameModel?: string | null;
|
||||||
|
* partNum?: string | null;
|
||||||
|
* cabinet?: string | null;
|
||||||
|
* cabinetLocation?: string | null;
|
||||||
|
* purpose?: string | null;
|
||||||
|
* interface?: string | null;
|
||||||
|
* cableLocation?: string | null;
|
||||||
|
* projectName?: string | null;
|
||||||
|
* plcPass?: string | null;
|
||||||
|
* safetyPass?: string | null;
|
||||||
|
* projectLink?: string | null;
|
||||||
|
* nameId?: string | null;
|
||||||
|
* connectionSettings?: string | null;
|
||||||
|
* }} PlcModelDbRecord
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {{
|
||||||
|
* nameModel?: string | null;
|
||||||
|
* partNum?: string | null;
|
||||||
|
* cabinet?: string | null;
|
||||||
|
* cabinetLocation?: string | null;
|
||||||
|
* purpose?: string | null;
|
||||||
|
* interface?: string | null;
|
||||||
|
* cableLocation?: string | null;
|
||||||
|
* configName?: string | null;
|
||||||
|
* projectLink?: string | null;
|
||||||
|
* nameId?: string | null;
|
||||||
|
* connectionSettings?: string | null;
|
||||||
|
* }} FgModelDbRecord
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
* @typedef {{ id: string, name?: string,
|
* @typedef {{ id: string, name?: string,
|
||||||
* docLink?: string | null, electrDiagLink?: string | null,
|
* docLink?: string | null, electrDiagLink?: string | null,
|
||||||
* locationName?: string | null, plcs?: Array<EquipmentDbRecord>,
|
* locationName?: string | null, plcs?: Array<PlcModelDbRecord>,
|
||||||
* fgs?: Array<EquipmentDbRecord>, hmis: Array<EquipmentDbRecord>,
|
* fgs?: Array<FgModelDbRecord>, hmis: Array<HmiModelDbRecord>,
|
||||||
* pcs?: Array<EquipmentDbRecord>
|
* pcs?: Array<PcEquipmentDbRecord>
|
||||||
* }} SubSystemDbRecord;
|
* }} SubSystemDbRecord;
|
||||||
*
|
*
|
||||||
* @typedef {{ id: string, name: string, baseLocationName: string, subsystems: Array<SubSystemDbRecord> }} SystemDbRecord;
|
* @typedef {{ id: string, name: string, baseLocationName: string, subsystems: Array<SubSystemDbRecord> }} SystemDbRecord;
|
||||||
@ -16,23 +111,39 @@ import sql from "mssql";
|
|||||||
|
|
||||||
export const equipmentRepository = {
|
export const equipmentRepository = {
|
||||||
/**
|
/**
|
||||||
* @param {{ filter?: { systemIds?: string[] | number[] } }} [options]
|
* @param {{ filter?: { systemIds?: string[] | number[], subsystemIds? : string[] | number[] } }} [options]
|
||||||
* @returns {Promise<Array<SystemDbRecord>>}
|
* @returns {Promise<Array<SystemDbRecord>>}
|
||||||
*/
|
*/
|
||||||
async getAll(options) {
|
async getAll(options) {
|
||||||
const request = UOW.request;
|
const request = UOW.request;
|
||||||
const systemIds = options?.filter?.systemIds;
|
const systemIds = options?.filter?.systemIds;
|
||||||
|
const subsystemIds = options?.filter?.subsystemIds;
|
||||||
const hasFilterBySystemIds = systemIds !== undefined && systemIds.length !== 0;
|
const hasFilterBySystemIds = systemIds !== undefined && systemIds.length !== 0;
|
||||||
|
const hasFilterBySubsystemIds = subsystemIds !== undefined && subsystemIds.length !== 0;
|
||||||
|
|
||||||
let whereClause = "";
|
const whereParts = [];
|
||||||
|
|
||||||
if (hasFilterBySystemIds) {
|
if (hasFilterBySystemIds) {
|
||||||
const idsString = systemIds.map(Number).filter(Boolean).join(",");
|
const idsString = systemIds.map(Number).filter(Boolean).join(",");
|
||||||
request.input("sysIdsString", sql.VarChar, idsString);
|
request.input("sysIdsString", sql.VarChar, idsString);
|
||||||
|
whereParts.push(`systemsTbl.id IN (SELECT value FROM STRING_SPLIT(@sysIdsString, ','))`);
|
||||||
whereClause = `WHERE systemsTbl.id IN (SELECT value FROM STRING_SPLIT(@sysIdsString, ','))`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasFilterBySubsystemIds) {
|
||||||
|
const subIdsString = subsystemIds.map(Number).filter(Boolean).join(",");
|
||||||
|
request.input("subSysIdsString", sql.VarChar, subIdsString);
|
||||||
|
|
||||||
|
whereParts.push(`systemsTbl.id IN (
|
||||||
|
SELECT systemlist_id
|
||||||
|
FROM asu_system_api_systemlist_subsystem_name
|
||||||
|
WHERE subsystemlist_id IN (SELECT value FROM STRING_SPLIT(@subSysIdsString, ','))
|
||||||
|
)`);
|
||||||
|
} else {
|
||||||
|
request.input("subSysIdsString", sql.VarChar, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
const whereClause = whereParts.length > 0 ? `WHERE ${whereParts.join(" AND ")}` : "";
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
SELECT systemsTbl.id as id,
|
SELECT systemsTbl.id as id,
|
||||||
systemsTbl.name as name,
|
systemsTbl.name as name,
|
||||||
@ -44,7 +155,20 @@ export const equipmentRepository = {
|
|||||||
locTbl.name as locationName,
|
locTbl.name as locationName,
|
||||||
(select
|
(select
|
||||||
plcTbl.plc_name as name,
|
plcTbl.plc_name as name,
|
||||||
plcModelTbl.name as nameModel
|
plcModelTbl.name as nameModel,
|
||||||
|
plcModelTbl.part_num as partNum,
|
||||||
|
plcTbl.cabinet as cabinet,
|
||||||
|
plcTbl.cabinet_location as cabinetLocation,
|
||||||
|
plcTbl.purpose as purpose,
|
||||||
|
plcModelTbl.interface as interface,
|
||||||
|
plcTbl.cable_location as cableLocation,
|
||||||
|
plcTbl.project_name as projectName,
|
||||||
|
plcTbl.plc_pass as plcPass,
|
||||||
|
plcTbl.safety_pass as safetyPass,
|
||||||
|
plcTbl.project_link as projectLink,
|
||||||
|
plcTbl.connection_settings as connectionSettings
|
||||||
|
|
||||||
|
|
||||||
FROM asu_system_api_plc as plcTbl
|
FROM asu_system_api_plc as plcTbl
|
||||||
left join asu_system_api_plc_model as plcModelTbl on plcModelTbl.id = plcTbl.name_id
|
left join asu_system_api_plc_model as plcModelTbl on plcModelTbl.id = plcTbl.name_id
|
||||||
left join asu_system_api_subsystemlist_plc as jtPLC on jtPLC.plc_id = plcTbl.id
|
left join asu_system_api_subsystemlist_plc as jtPLC on jtPLC.plc_id = plcTbl.id
|
||||||
@ -52,8 +176,22 @@ export const equipmentRepository = {
|
|||||||
FOR JSON PATH) as plcs,
|
FOR JSON PATH) as plcs,
|
||||||
|
|
||||||
(select
|
(select
|
||||||
hmiTbl.hmi_name as name,
|
hmiTbl.hmi_name as name,
|
||||||
hmiModelTbl.name as nameModel
|
hmiModelTbl.name as nameModel,
|
||||||
|
hmiModelTbl.part_num as partNum,
|
||||||
|
hmiTbl.cabinet as cabinet,
|
||||||
|
hmiTbl.cabinet_location as cabinetLocation,
|
||||||
|
hmiTbl.purpose as purpose,
|
||||||
|
hmiTbl.admin_login_pass as adminLoginPass,
|
||||||
|
hmiTbl.worker_login_pass as workerLoginPass,
|
||||||
|
hmiModelTbl.interface as interface,
|
||||||
|
hmiTbl.cable_location as cableLocation,
|
||||||
|
hmiTbl.project_name as projectName,
|
||||||
|
hmiTbl.project_link as projectLink,
|
||||||
|
hmiTbl.disk_image as diskImage,
|
||||||
|
hmiTbl.image_link as imageLink,
|
||||||
|
hmiTbl.connection_settings as connectionSettings
|
||||||
|
|
||||||
FROM asu_system_api_hmi as hmiTbl
|
FROM asu_system_api_hmi as hmiTbl
|
||||||
left join asu_system_api_hmi_model as hmiModelTbl on hmiModelTbl.id = hmiTbl.name_id
|
left join asu_system_api_hmi_model as hmiModelTbl on hmiModelTbl.id = hmiTbl.name_id
|
||||||
left join asu_system_api_subsystemlist_hmi as jtHMI on jtHMI.hmi_id = hmiTbl.id
|
left join asu_system_api_subsystemlist_hmi as jtHMI on jtHMI.hmi_id = hmiTbl.id
|
||||||
@ -61,15 +199,64 @@ export const equipmentRepository = {
|
|||||||
FOR JSON PATH) as hmis,
|
FOR JSON PATH) as hmis,
|
||||||
|
|
||||||
(select
|
(select
|
||||||
fgTbl.fg_name as name,
|
fgTbl.fg_name as name,
|
||||||
fgModelTbl.name as nameModel
|
fgModelTbl.name as nameModel,
|
||||||
|
fgModelTbl.part_num as partNum,
|
||||||
|
fgModelTbl.interface as interface,
|
||||||
|
fgTbl.cabinet as cabinet,
|
||||||
|
fgTbl.cabinet_location as cabinetLocation,
|
||||||
|
fgTbl.purpose as purpose,
|
||||||
|
fgTbl.cable_location as cableLocation,
|
||||||
|
fgTbl.config_name as configName,
|
||||||
|
fgTbl.project_link as projectLink,
|
||||||
|
fgTbl.name_id as nameId,
|
||||||
|
fgTbl.connection_settings as connectionSettings
|
||||||
|
|
||||||
FROM asu_system_api_fg as fgTbl
|
FROM asu_system_api_fg as fgTbl
|
||||||
left join asu_system_api_fg_model as fgModelTbl on fgModelTbl.id = fgTbl.name_id
|
left join asu_system_api_fg_model as fgModelTbl on fgModelTbl.id = fgTbl.name_id
|
||||||
left join asu_system_api_subsystemlist_fg as jtFG on jtFG.fg_id = fgTbl.id
|
left join asu_system_api_subsystemlist_fg as jtFG on jtFG.fg_id = fgTbl.id
|
||||||
where jtFG.subsystemlist_id = subSystemsTbl.id
|
where jtFG.subsystemlist_id = subSystemsTbl.id
|
||||||
FOR JSON PATH) as fgs,
|
FOR JSON PATH) as fgs,
|
||||||
|
|
||||||
(select pcTbl.pc_name as name
|
(select pcTbl.inv_number as invNumber,
|
||||||
|
pcTbl.location as location,
|
||||||
|
pcTbl.purpose as purpose,
|
||||||
|
pcTbl.pc_name as name,
|
||||||
|
pcTbl.admin_login_pass as adminLoginPass,
|
||||||
|
pcTbl.worker_login_pass as workerLoginPass,
|
||||||
|
pcTbl.prom_conn as promConn,
|
||||||
|
pcTbl.comp_conn as compConn,
|
||||||
|
pcTbl.loc_and_remark as locAndRemark,
|
||||||
|
pcTbl.ups_req as upsReq,
|
||||||
|
pcTbl.ups_avail as upsAvail,
|
||||||
|
pcTbl.last_service_date as lastServiceDate,
|
||||||
|
pcTbl.os_version as osVersion,
|
||||||
|
pcTbl.ind_soft_inst as indSoftInst,
|
||||||
|
pcTbl.soft_admin_login_pass as softAdminLoginPass,
|
||||||
|
pcTbl.project_source as projectSource,
|
||||||
|
pcTbl.project_source_link as projectSourceLink,
|
||||||
|
pcTbl.comments as comments,
|
||||||
|
pcTbl.project_archieve_link as projectArchieveLink,
|
||||||
|
(select
|
||||||
|
pcConfigTbl.model as modelName,
|
||||||
|
pcConfigTbl.part_num as partNum,
|
||||||
|
pcConfigTbl.motherboard as motherboard,
|
||||||
|
pcConfigTbl.socket as socket,
|
||||||
|
pcConfigTbl.cpu as cpu,
|
||||||
|
pcConfigTbl.mem as mem,
|
||||||
|
pcConfigTbl.mem_volume as memVolume,
|
||||||
|
pcConfigTbl.hdd as hdd,
|
||||||
|
pcConfigTbl.hdd_volume as hddVolume,
|
||||||
|
pcConfigTbl.expansion_cards as expansionCards,
|
||||||
|
pcConfigTbl.external_devices as externalDevices,
|
||||||
|
pcConfigTbl.case_fan as caseFan,
|
||||||
|
pcConfigTbl.cpu_fan as cpuFan,
|
||||||
|
pcConfigTbl.power_unit as powerUnit
|
||||||
|
from asu_system_api_pcconfig as pcConfigTbl
|
||||||
|
left join asu_system_api_pc_model as jtPCModel on jtPCModel.pc_id = pcTbl.id
|
||||||
|
where pcConfigTbl.id = jtPCModel.pcconfig_id
|
||||||
|
FOR JSON PATH) as config
|
||||||
|
|
||||||
FROM asu_system_api_pc as pcTbl
|
FROM asu_system_api_pc as pcTbl
|
||||||
left join asu_system_api_subsystemlist_pc as jtPC on jtPC.subsystemlist_id = subSystemsTbl.id
|
left join asu_system_api_subsystemlist_pc as jtPC on jtPC.subsystemlist_id = subSystemsTbl.id
|
||||||
where jtPC.pc_id = pcTbl.id
|
where jtPC.pc_id = pcTbl.id
|
||||||
@ -79,6 +266,7 @@ export const equipmentRepository = {
|
|||||||
inner join asu_system_api_systemlist_subsystem_name as jt on subSystemsTbl.id = jt.subsystemlist_id
|
inner join asu_system_api_systemlist_subsystem_name as jt on subSystemsTbl.id = jt.subsystemlist_id
|
||||||
left join asu_system_api_location as locTbl on locTbl.id = subSystemsTbl.location_id
|
left join asu_system_api_location as locTbl on locTbl.id = subSystemsTbl.location_id
|
||||||
where jt.systemlist_id = systemsTbl.id
|
where jt.systemlist_id = systemsTbl.id
|
||||||
|
and (@subSysIdsString IS NULL OR subSystemsTbl.id IN (SELECT value FROM STRING_SPLIT(@subSysIdsString, ',')))
|
||||||
FOR JSON PATH) as subsystems
|
FOR JSON PATH) as subsystems
|
||||||
from asu_system_api_systemlist as systemsTbl
|
from asu_system_api_systemlist as systemsTbl
|
||||||
inner join asu_system_api_baselocation as baseLocTbl on systemsTbl.location_id = baseLocTbl.id
|
inner join asu_system_api_baselocation as baseLocTbl on systemsTbl.location_id = baseLocTbl.id
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { equipmentRepository } from "#root/repositories/equipment.repository.js"
|
|||||||
export const dbExporterService = {
|
export const dbExporterService = {
|
||||||
/**
|
/**
|
||||||
* @param { new () => ExporterAdapterInterface } Adapter
|
* @param { new () => ExporterAdapterInterface } Adapter
|
||||||
* @param {{ filter?: { systemIds?: number[] | string[] } }} options
|
* @param {{ filter?: { systemIds?: number[] | string[], subsystemIds?: number[] | string[] } }} options
|
||||||
* */
|
* */
|
||||||
async export(Adapter, options) {
|
async export(Adapter, options) {
|
||||||
const db = await equipmentRepository.getAll({ filter: options.filter });
|
const db = await equipmentRepository.getAll({ filter: options.filter });
|
||||||
|
|||||||
100
services/exporters/constants.js
Normal file
100
services/exporters/constants.js
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
export const EXCEL_MAIN_WS_HEADERS = [
|
||||||
|
"Наименование системы",
|
||||||
|
"Наименование внутренних подсистем.",
|
||||||
|
"Расположение",
|
||||||
|
"Документация",
|
||||||
|
"Электроплан",
|
||||||
|
"PLC",
|
||||||
|
"HMI",
|
||||||
|
"ПЧ",
|
||||||
|
"Промышленные ПК"
|
||||||
|
];
|
||||||
|
|
||||||
|
export const EXCEL_PC_WS_HEADERS = [
|
||||||
|
"Наименование АСУ",
|
||||||
|
"Вендер, модель ",
|
||||||
|
"Инвентарный номер ОС ПК или комплекса",
|
||||||
|
"Местоположение (цех\\АБК, ось\\ряд или кабинет)",
|
||||||
|
"Назначение",
|
||||||
|
"Имя ПК",
|
||||||
|
"Администратор в ОС (логин/Пароль)",
|
||||||
|
"Рабочий пользователь в ОС (логин/Пароль)",
|
||||||
|
"Подключение к промышленной сети. (ДА\\НЕТ) IP адрес, MAC адрес",
|
||||||
|
"Подключение к сети предприятия (ДА\\НЕТ) IP адрес, MAC адрес",
|
||||||
|
"Место установки. Замечания.",
|
||||||
|
"ИБП Потребность",
|
||||||
|
"ИБП Наличие",
|
||||||
|
"Последняя дата Обслуживания",
|
||||||
|
"Версия ОС",
|
||||||
|
"Установленное промышленное ПО",
|
||||||
|
"Администратор в ПО (логин/Пароль)",
|
||||||
|
"Исходник проекта ПО",
|
||||||
|
"Ссылка на исходник проекта",
|
||||||
|
"Резервная копия HDD, расположение"
|
||||||
|
];
|
||||||
|
|
||||||
|
export const EXCEL_PC_CONFIG_WS_HEADERS = [
|
||||||
|
"Наименование оборудования",
|
||||||
|
"Вендер, модель",
|
||||||
|
"Артикул",
|
||||||
|
"Процессор",
|
||||||
|
"Материнская плата",
|
||||||
|
"Сокет",
|
||||||
|
"Тип ОЗУ",
|
||||||
|
"Объем ОЗУ",
|
||||||
|
"Тип HDD",
|
||||||
|
"Объем HDD",
|
||||||
|
"Блок питания(мощность, тип, особенности)",
|
||||||
|
"Установленные карты расширения",
|
||||||
|
"Внешние устройства (тип)",
|
||||||
|
"Вентилятор ЦП",
|
||||||
|
"Доп.вентилятор на корпусе"
|
||||||
|
];
|
||||||
|
|
||||||
|
export const EXCEL_HMI_WS_HEADERS = [
|
||||||
|
"Наименование подсистемы",
|
||||||
|
"HMI",
|
||||||
|
"Артикул",
|
||||||
|
"Шкаф (по электроплану)",
|
||||||
|
"Расположение шкафа (физически)",
|
||||||
|
"Назначение",
|
||||||
|
"Администратор (логин/Пароль)",
|
||||||
|
"Рабочий пользователь (логин/Пароль)",
|
||||||
|
"Интерфейс для подключения (Интерфейс, протокол, коммуникация)",
|
||||||
|
"Настройки подключения",
|
||||||
|
"Месторасположения кабеля",
|
||||||
|
"Имя проекта",
|
||||||
|
"Ссылка на проект",
|
||||||
|
"Образ носителя",
|
||||||
|
"Ссылка на папку с образом"
|
||||||
|
];
|
||||||
|
|
||||||
|
export const EXCEL_PLC_WS_HEADERS = [
|
||||||
|
"Наименование подсистемы",
|
||||||
|
"PLC",
|
||||||
|
"Артикул",
|
||||||
|
"Шкаф",
|
||||||
|
"Расположение шкафа (физически)",
|
||||||
|
"Назначение",
|
||||||
|
"Интерфейс для подключения (Интерфейс, протокол, коммуникация)",
|
||||||
|
"Настройки подключения",
|
||||||
|
"Месторасположение кабеля",
|
||||||
|
"Имя проекта",
|
||||||
|
"Пароль PLC",
|
||||||
|
"Пароль Safety",
|
||||||
|
"Ссылка на проект"
|
||||||
|
];
|
||||||
|
|
||||||
|
export const EXCEL_FG_WS_HEADERS = [
|
||||||
|
"Наименование подсистемы",
|
||||||
|
"Наименование ПЧ",
|
||||||
|
"Артикул",
|
||||||
|
"Шкаф",
|
||||||
|
"Месторасположение шкафа",
|
||||||
|
"Назначение",
|
||||||
|
"Интерфейс для подключения (Интерфейс, протокол, коммуникация)",
|
||||||
|
"Настройки подключения",
|
||||||
|
"Месторасположение кабеля",
|
||||||
|
"Имя проекта конфигурации ПЧ (архива параметров)",
|
||||||
|
"Ссылка"
|
||||||
|
];
|
||||||
@ -1,48 +1,405 @@
|
|||||||
import ExcelJS from "exceljs";
|
import ExcelJS from "exceljs";
|
||||||
|
import {
|
||||||
|
EXCEL_FG_WS_HEADERS,
|
||||||
|
EXCEL_HMI_WS_HEADERS,
|
||||||
|
EXCEL_MAIN_WS_HEADERS,
|
||||||
|
EXCEL_PC_CONFIG_WS_HEADERS,
|
||||||
|
EXCEL_PC_WS_HEADERS,
|
||||||
|
EXCEL_PLC_WS_HEADERS
|
||||||
|
} from "./constants.js";
|
||||||
|
import * as utilNum from "#utils/num.js";
|
||||||
|
import * as utilStr from "#utils/str.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @import { ExporterAdapterInterface } from '../types.js'
|
* @import { ExporterAdapterInterface } from '../types.js'
|
||||||
* @import { SystemDbRecord } from '#repositories/equipment.repository.js'
|
* @import { FgModelDbRecord, HmiModelDbRecord, PCConfigDbRecord, PcEquipmentDbRecord, PlcModelDbRecord, SubSystemDbRecord, SystemDbRecord } from '#repositories/equipment.repository.js'
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Map<string, { row: number }>} HeadingRowMap
|
||||||
|
* @typedef {Array<any[]>} WsData
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @implements {ExporterAdapterInterface} */
|
/** @implements {ExporterAdapterInterface} */
|
||||||
export class XlsExporterAdapter {
|
export class XlsExporterAdapter {
|
||||||
/** @type {Partial<ExcelJS.AddWorksheetOptions>} */
|
/** @type {Partial<ExcelJS.AddWorksheetOptions>} */
|
||||||
static mainWsOptions = { views: [{ state: "frozen", ySplit: 1, zoomScale: 70 }] };
|
static worksheetsOptions = { views: [{ state: "frozen", ySplit: 1, zoomScale: 70 }] };
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.wb = new ExcelJS.Workbook();
|
this.wb = new ExcelJS.Workbook();
|
||||||
this.ws = this.wb.addWorksheet("Перечень систем", XlsExporterAdapter.mainWsOptions);
|
this.ws = this.wb.addWorksheet("Перечень систем", XlsExporterAdapter.worksheetsOptions);
|
||||||
|
this.PcWs = this.wb.addWorksheet("Перечень ПК", XlsExporterAdapter.worksheetsOptions);
|
||||||
|
this.pcConfigWs = this.wb.addWorksheet("Компоненты ПК", XlsExporterAdapter.worksheetsOptions);
|
||||||
|
this.hmiWs = this.wb.addWorksheet("HMI", XlsExporterAdapter.worksheetsOptions);
|
||||||
|
this.plcWs = this.wb.addWorksheet("PLC", XlsExporterAdapter.worksheetsOptions);
|
||||||
|
this.fgWs = this.wb.addWorksheet("ПЧ", XlsExporterAdapter.worksheetsOptions);
|
||||||
|
|
||||||
/** @type {Array<any[]>} */
|
/** @type {WsData} */
|
||||||
this.data = [];
|
this.mainSheetData = [];
|
||||||
|
|
||||||
|
/** @type {WsData} */
|
||||||
|
this.pcSheetData = [];
|
||||||
|
|
||||||
|
/** @type {WsData} */
|
||||||
|
this.pcConfigSheetData = [];
|
||||||
|
|
||||||
|
/** @type {WsData} */
|
||||||
|
this.hmiSheetData = [];
|
||||||
|
|
||||||
|
/** @type {WsData} */
|
||||||
|
this.plcSheetData = [];
|
||||||
|
|
||||||
|
/** @type {WsData} */
|
||||||
|
this.fgSheetData = [];
|
||||||
|
|
||||||
|
/** @type {{ sheet: ExcelJS.Worksheet, colStart: string, colEnd: string, from: number; to: number }[]} */
|
||||||
|
this.mergeRanges = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param {SystemDbRecord[]} db */
|
/** @param {SystemDbRecord[]} db */
|
||||||
async export(db) {
|
async export(db) {
|
||||||
/** @type {Map<string, { row: number }>} */
|
db.sort((a, b) => a.baseLocationName.localeCompare(b.baseLocationName, "ru", { sensitivity: "base" }));
|
||||||
const addedBaseLocationNames = new Map();
|
|
||||||
|
|
||||||
/** @type {{ colStart: string, colEnd: string, from: number; to: number }[]} */
|
const mainWsHeadings = this.fillMainWorksheet(db);
|
||||||
const mergeRanges = [];
|
const pcWsHeadings = this.fillPcWorksheet(db);
|
||||||
|
const pcConfigWsHeadings = this.fillPcConfigWorksheet(db);
|
||||||
|
const hmiWsHeadings = this.fillHmisWorksheet(db);
|
||||||
|
const plcWsHeadings = this.fillPlcsWorksheet(db);
|
||||||
|
const fgWsHeadings = this.fillFgsWorksheet(db);
|
||||||
|
|
||||||
|
this.ws.getRow(1).values = EXCEL_MAIN_WS_HEADERS;
|
||||||
|
this.PcWs.getRow(1).values = EXCEL_PC_WS_HEADERS;
|
||||||
|
this.pcConfigWs.getRow(1).values = EXCEL_PC_CONFIG_WS_HEADERS;
|
||||||
|
this.hmiWs.getRow(1).values = EXCEL_HMI_WS_HEADERS;
|
||||||
|
this.plcWs.getRow(1).values = EXCEL_PLC_WS_HEADERS;
|
||||||
|
this.fgWs.getRow(1).values = EXCEL_FG_WS_HEADERS;
|
||||||
|
|
||||||
|
this.ws.autoFilter = `A1:I${this.mainSheetData.length + 1}`;
|
||||||
|
this.PcWs.autoFilter = `A1:T${this.pcSheetData.length + 1}`;
|
||||||
|
this.pcConfigWs.autoFilter = `A1:O${this.pcSheetData.length + 1}`;
|
||||||
|
this.hmiWs.autoFilter = `A1:O${this.pcSheetData.length + 1}`;
|
||||||
|
|
||||||
|
this.ws.addRows(this.mainSheetData);
|
||||||
|
this.PcWs.addRows(this.pcSheetData);
|
||||||
|
this.pcConfigWs.addRows(this.pcConfigSheetData);
|
||||||
|
this.hmiWs.addRows(this.hmiSheetData);
|
||||||
|
this.plcWs.addRows(this.plcSheetData);
|
||||||
|
this.fgWs.addRows(this.fgSheetData);
|
||||||
|
|
||||||
|
this.mergeRanges.forEach((r) => r.sheet.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.PcWs.getColumn(1).width = 30;
|
||||||
|
this.PcWs.getColumn(2).width = 40;
|
||||||
|
this.PcWs.getColumn(3).width = 20;
|
||||||
|
utilNum.range(4, 20).forEach((el) => (this.PcWs.getColumn(el).width = 18));
|
||||||
|
this.pcConfigWs.getColumn(1).width = 30;
|
||||||
|
this.pcConfigWs.getColumn(2).width = 35;
|
||||||
|
utilNum.range(3, 8).forEach((el) => (this.pcConfigWs.getColumn(el).width = 25));
|
||||||
|
this.pcConfigWs.getColumn(9).width = 40;
|
||||||
|
this.pcConfigWs.getColumn(10).width = 20;
|
||||||
|
utilNum.range(11, 15).forEach((el) => (this.pcConfigWs.getColumn(el).width = 30));
|
||||||
|
|
||||||
|
this.hmiWs.getColumn(1).width = 30;
|
||||||
|
this.hmiWs.getColumn(2).width = 45;
|
||||||
|
this.hmiWs.getColumn(3).width = 35;
|
||||||
|
utilNum.range(4, 15).forEach((el) => (this.hmiWs.getColumn(el).width = 16));
|
||||||
|
this.hmiWs.getColumn(9).width = 35;
|
||||||
|
|
||||||
|
this.plcWs.getColumn(1).width = 30;
|
||||||
|
this.plcWs.getColumn(2).width = 40;
|
||||||
|
this.plcWs.getColumn(3).width = 20;
|
||||||
|
utilNum.range(4, 13).forEach((el) => (this.plcWs.getColumn(el).width = 16));
|
||||||
|
this.fgWs.getColumn(6).width = 30;
|
||||||
|
this.fgWs.getColumn(7).width = 35;
|
||||||
|
|
||||||
|
this.fgWs.getColumn(1).width = 30;
|
||||||
|
this.fgWs.getColumn(2).width = 40;
|
||||||
|
this.fgWs.getColumn(3).width = 20;
|
||||||
|
utilNum.range(4, 11).forEach((el) => (this.fgWs.getColumn(el).width = 16));
|
||||||
|
this.fgWs.getColumn(6).width = 25;
|
||||||
|
this.fgWs.getColumn(7).width = 35;
|
||||||
|
|
||||||
|
this.setSheetCellStyles(this.ws);
|
||||||
|
this.setSheetCellStyles(this.PcWs);
|
||||||
|
this.setSheetCellStyles(this.pcConfigWs);
|
||||||
|
this.setSheetCellStyles(this.hmiWs);
|
||||||
|
this.setSheetCellStyles(this.plcWs);
|
||||||
|
this.setSheetCellStyles(this.fgWs);
|
||||||
|
this.setHeadingCellsStyles(this.ws, mainWsHeadings);
|
||||||
|
this.setHeadingCellsStyles(this.PcWs, pcWsHeadings);
|
||||||
|
this.setHeadingCellsStyles(this.pcConfigWs, pcConfigWsHeadings);
|
||||||
|
this.setHeadingCellsStyles(this.hmiWs, hmiWsHeadings);
|
||||||
|
this.setHeadingCellsStyles(this.plcWs, plcWsHeadings);
|
||||||
|
this.setHeadingCellsStyles(this.fgWs, fgWsHeadings);
|
||||||
|
|
||||||
|
const excelBuffer = await this.wb.xlsx.writeBuffer();
|
||||||
|
|
||||||
|
/** @type {Buffer} */
|
||||||
|
return excelBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {SystemDbRecord[]} db
|
||||||
|
*/
|
||||||
|
fillPcWorksheet(db) {
|
||||||
|
/** @type {HeadingRowMap} */
|
||||||
|
const headings = new Map();
|
||||||
|
|
||||||
|
let currRow = 2;
|
||||||
|
|
||||||
|
for (const system of db) {
|
||||||
|
const subsystems = system.subsystems || [];
|
||||||
|
const pcCount = subsystems.reduce((count, curr) => (curr?.pcs?.length || 0) + count, 0);
|
||||||
|
|
||||||
|
if (subsystems.length === 0) continue;
|
||||||
|
|
||||||
|
if (pcCount > 0) {
|
||||||
|
const isHeadingInserted = this.addBaseLocHeading({
|
||||||
|
ws: this.PcWs,
|
||||||
|
data: this.pcSheetData,
|
||||||
|
currRow,
|
||||||
|
headings,
|
||||||
|
name: system.baseLocationName,
|
||||||
|
colStart: "A",
|
||||||
|
colEnd: "T"
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isHeadingInserted) currRow++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const subsystem of subsystems) {
|
||||||
|
const pcItems = subsystem?.pcs || [];
|
||||||
|
|
||||||
|
if (pcItems.length === 0) continue;
|
||||||
|
|
||||||
|
pcItems.forEach((pc) => {
|
||||||
|
this.addPcRow(pc, system, subsystem);
|
||||||
|
currRow++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return headings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {SystemDbRecord[]} db
|
||||||
|
*/
|
||||||
|
fillPcConfigWorksheet(db) {
|
||||||
|
/** @type {HeadingRowMap} */
|
||||||
|
const headings = new Map();
|
||||||
|
|
||||||
|
let currRow = 2;
|
||||||
|
|
||||||
|
for (const system of db) {
|
||||||
|
const subsystems = system.subsystems || [];
|
||||||
|
const pcCount = subsystems.reduce((count, curr) => (curr?.pcs?.length || 0) + count, 0);
|
||||||
|
|
||||||
|
if (subsystems.length === 0) continue;
|
||||||
|
|
||||||
|
if (pcCount > 0) {
|
||||||
|
const isHeadingInserted = this.addBaseLocHeading({
|
||||||
|
ws: this.pcConfigWs,
|
||||||
|
data: this.pcConfigSheetData,
|
||||||
|
currRow,
|
||||||
|
headings,
|
||||||
|
name: system.baseLocationName,
|
||||||
|
colStart: "A",
|
||||||
|
colEnd: "O"
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isHeadingInserted) currRow++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const subsystem of subsystems) {
|
||||||
|
const pcItems = subsystem?.pcs || [];
|
||||||
|
|
||||||
|
if (pcItems.length === 0) continue;
|
||||||
|
|
||||||
|
pcItems.forEach((pc) => {
|
||||||
|
const configs = pc?.config || [];
|
||||||
|
if (configs.length > 0) {
|
||||||
|
configs.forEach((c) => {
|
||||||
|
this.addPcConfigRow(c, subsystem);
|
||||||
|
currRow++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return headings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {SystemDbRecord[]} db
|
||||||
|
*/
|
||||||
|
fillHmisWorksheet(db) {
|
||||||
|
/** @type {HeadingRowMap} */
|
||||||
|
const headings = new Map();
|
||||||
|
|
||||||
|
let currRow = 2;
|
||||||
|
|
||||||
|
for (const system of db) {
|
||||||
|
const subsystems = system.subsystems || [];
|
||||||
|
const pcCount = subsystems.reduce((count, curr) => (curr?.hmis?.length || 0) + count, 0);
|
||||||
|
|
||||||
|
if (subsystems.length === 0) continue;
|
||||||
|
|
||||||
|
if (pcCount > 0) {
|
||||||
|
const isHeadingInserted = this.addBaseLocHeading({
|
||||||
|
ws: this.hmiWs,
|
||||||
|
data: this.hmiSheetData,
|
||||||
|
currRow,
|
||||||
|
headings,
|
||||||
|
name: system.baseLocationName,
|
||||||
|
colStart: "A",
|
||||||
|
colEnd: "O"
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isHeadingInserted) currRow++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const subsystem of subsystems) {
|
||||||
|
const hmiItems = subsystem?.hmis || [];
|
||||||
|
|
||||||
|
if (hmiItems.length === 0) continue;
|
||||||
|
|
||||||
|
hmiItems.forEach((hmi) => {
|
||||||
|
// console.log(hmi);
|
||||||
|
this.addHmiRow(hmi, subsystem);
|
||||||
|
currRow++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return headings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {SystemDbRecord[]} db
|
||||||
|
*/
|
||||||
|
fillPlcsWorksheet(db) {
|
||||||
|
/** @type {HeadingRowMap} */
|
||||||
|
const headings = new Map();
|
||||||
|
|
||||||
|
let currRow = 2;
|
||||||
|
|
||||||
|
for (const system of db) {
|
||||||
|
const subsystems = system.subsystems || [];
|
||||||
|
const plcCount = subsystems.reduce((count, curr) => (curr?.plcs?.length || 0) + count, 0);
|
||||||
|
|
||||||
|
if (subsystems.length === 0) continue;
|
||||||
|
|
||||||
|
if (plcCount > 0) {
|
||||||
|
const isHeadingInserted = this.addBaseLocHeading({
|
||||||
|
ws: this.plcWs,
|
||||||
|
data: this.plcSheetData,
|
||||||
|
currRow,
|
||||||
|
headings,
|
||||||
|
name: system.baseLocationName,
|
||||||
|
colStart: "A",
|
||||||
|
colEnd: "M"
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isHeadingInserted) currRow++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const subsystem of subsystems) {
|
||||||
|
const plcItems = subsystem?.plcs || [];
|
||||||
|
|
||||||
|
if (plcItems.length === 0) continue;
|
||||||
|
|
||||||
|
plcItems.forEach((plc) => {
|
||||||
|
// console.log(hmi);
|
||||||
|
this.addPlcRow(plc, subsystem);
|
||||||
|
currRow++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return headings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {SystemDbRecord[]} db
|
||||||
|
*/
|
||||||
|
fillFgsWorksheet(db) {
|
||||||
|
/** @type {HeadingRowMap} */
|
||||||
|
const headings = new Map();
|
||||||
|
|
||||||
|
let currRow = 2;
|
||||||
|
|
||||||
|
for (const system of db) {
|
||||||
|
const subsystems = system.subsystems || [];
|
||||||
|
const fgCount = subsystems.reduce((count, curr) => (curr?.fgs?.length || 0) + count, 0);
|
||||||
|
|
||||||
|
if (subsystems.length === 0) continue;
|
||||||
|
|
||||||
|
if (fgCount > 0) {
|
||||||
|
const isHeadingInserted = this.addBaseLocHeading({
|
||||||
|
ws: this.fgWs,
|
||||||
|
data: this.fgSheetData,
|
||||||
|
currRow,
|
||||||
|
headings,
|
||||||
|
name: system.baseLocationName,
|
||||||
|
colStart: "A",
|
||||||
|
colEnd: "K"
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isHeadingInserted) currRow++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const subsystem of subsystems) {
|
||||||
|
const fgsItems = subsystem?.fgs || [];
|
||||||
|
|
||||||
|
if (fgsItems.length === 0) continue;
|
||||||
|
|
||||||
|
fgsItems.forEach((fg) => {
|
||||||
|
this.addFgRow(fg, subsystem);
|
||||||
|
currRow++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return headings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {SystemDbRecord[]} db
|
||||||
|
*/
|
||||||
|
fillMainWorksheet(db) {
|
||||||
|
/** @type {HeadingRowMap} */
|
||||||
|
const headings = new Map();
|
||||||
|
|
||||||
let currentRow = 2;
|
let currentRow = 2;
|
||||||
|
|
||||||
for (const system of db) {
|
for (const system of db) {
|
||||||
const subsystems = system.subsystems || [];
|
const subsystems = system.subsystems || [];
|
||||||
|
|
||||||
// Подсистема не найдены, добавляет название системы с пустыми ячейками
|
// Подсистемы не найдены, добавляет название системы с пустыми ячейками
|
||||||
if (subsystems.length === 0) {
|
if (subsystems.length === 0) {
|
||||||
this.data.push([system.name, ...new Array(8).fill("", 0, 8)]);
|
this.mainSheetData.push([system.name, ...new Array(8).fill("", 0, 8)]);
|
||||||
currentRow++;
|
currentRow++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Заголовок для расположения систем
|
// Заголовок для расположения систем
|
||||||
if (!addedBaseLocationNames.has(system.baseLocationName)) {
|
if (!headings.has(system.baseLocationName)) {
|
||||||
addedBaseLocationNames.set(system.baseLocationName, { row: currentRow });
|
headings.set(system.baseLocationName, { row: currentRow });
|
||||||
this.data.push([system.baseLocationName]);
|
this.mainSheetData.push([system.baseLocationName]);
|
||||||
mergeRanges.push({ colStart: "A", colEnd: "I", from: currentRow, to: currentRow });
|
this.mergeRanges.push({ sheet: this.ws, colStart: "A", colEnd: "I", from: currentRow, to: currentRow });
|
||||||
currentRow++;
|
currentRow++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +414,7 @@ export class XlsExporterAdapter {
|
|||||||
const fgs = subsystem?.fgs || [];
|
const fgs = subsystem?.fgs || [];
|
||||||
const pcs = subsystem?.pcs || [];
|
const pcs = subsystem?.pcs || [];
|
||||||
|
|
||||||
this.data.push([
|
this.mainSheetData.push([
|
||||||
system.name,
|
system.name,
|
||||||
subsystem.name,
|
subsystem.name,
|
||||||
`${system.baseLocationName} ${subsystem.locationName}`,
|
`${system.baseLocationName} ${subsystem.locationName}`,
|
||||||
@ -72,39 +429,191 @@ export class XlsExporterAdapter {
|
|||||||
currentRow++;
|
currentRow++;
|
||||||
});
|
});
|
||||||
|
|
||||||
mergeRanges.push({ colStart: "A", colEnd: "A", from: startRow, to: currentRow - 1 });
|
this.mergeRanges.push({ sheet: this.ws, colStart: "A", colEnd: "A", from: startRow, to: currentRow - 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ws.getRow(1).values = [
|
return headings;
|
||||||
"Наименование системы",
|
}
|
||||||
"Наименование внутренних подсистем.",
|
|
||||||
"Расположение",
|
|
||||||
"Документация",
|
|
||||||
"Электроплан",
|
|
||||||
"PLC",
|
|
||||||
"HMI",
|
|
||||||
"ПЧ",
|
|
||||||
"Промышленные ПК"
|
|
||||||
];
|
|
||||||
|
|
||||||
this.ws.autoFilter = `A1:I${this.data.length + 1}`;
|
/**
|
||||||
|
* @param {PCConfigDbRecord} config
|
||||||
|
* @param {SubSystemDbRecord} subsystem
|
||||||
|
*/
|
||||||
|
addPcConfigRow(config, subsystem) {
|
||||||
|
this.pcConfigSheetData.push([
|
||||||
|
subsystem.name || "",
|
||||||
|
config.modelName || "",
|
||||||
|
config.partNum || "",
|
||||||
|
config.cpu || "",
|
||||||
|
config.motherboard || "",
|
||||||
|
config.socket || "",
|
||||||
|
config.mem || "",
|
||||||
|
config.memVolume || "",
|
||||||
|
config.hdd || "",
|
||||||
|
config.hddVolume || "",
|
||||||
|
config.powerUnit || "",
|
||||||
|
config.expansionCards || "",
|
||||||
|
config.externalDevices || "",
|
||||||
|
config.cpuFan || "",
|
||||||
|
config.caseFan || ""
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
this.ws.addRows(this.data);
|
/**
|
||||||
|
*
|
||||||
|
* @param {PcEquipmentDbRecord} pc
|
||||||
|
* @param {SystemDbRecord} system
|
||||||
|
* @param {SubSystemDbRecord} subsystem
|
||||||
|
*/
|
||||||
|
addPcRow(pc, system, subsystem) {
|
||||||
|
const hasProjectSourceLink = Boolean(pc?.projectSourceLink) && utilStr.isStrLink(pc?.projectSourceLink || "");
|
||||||
|
const hasProjectArchieveLink = Boolean(pc?.projectArchieveLink) && utilStr.isStrLink(pc?.projectArchieveLink || "");
|
||||||
|
const modelNames = pc?.config?.map((c) => c.modelName).join("\n");
|
||||||
|
|
||||||
mergeRanges.forEach((r) => this.ws.mergeCells(`${r.colStart}${r.from}:${r.colEnd}${r.to}`));
|
this.pcSheetData.push([
|
||||||
|
subsystem.name,
|
||||||
|
modelNames || "",
|
||||||
|
pc.invNumber || "",
|
||||||
|
`${system.baseLocationName} ${subsystem.locationName}`,
|
||||||
|
pc.purpose || "",
|
||||||
|
pc.name || "",
|
||||||
|
pc.adminLoginPass || "",
|
||||||
|
pc.workerLoginPass || "",
|
||||||
|
pc.promConn || "",
|
||||||
|
pc.compConn || "",
|
||||||
|
pc.locAndRemark || "",
|
||||||
|
pc.upsReq || "",
|
||||||
|
pc.upsAvail || "",
|
||||||
|
pc.lastServiceDate || "",
|
||||||
|
pc.osVersion || "",
|
||||||
|
pc.indSoftInst || "",
|
||||||
|
pc.softAdminLoginPass || "",
|
||||||
|
pc.projectSource || "",
|
||||||
|
hasProjectSourceLink ? { text: "Ссылка", hyperlink: pc.projectSourceLink } : pc.projectSourceLink || "",
|
||||||
|
hasProjectArchieveLink ? { text: "Ссылка", hyperlink: pc.projectArchieveLink } : pc.projectArchieveLink || ""
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
this.ws.getColumn(1).width = 50;
|
/**
|
||||||
this.ws.getColumn(2).width = 50;
|
* @param {HmiModelDbRecord} hmi
|
||||||
this.ws.getColumn(3).width = 35;
|
* @param {SubSystemDbRecord} subsystem
|
||||||
this.ws.getColumn(4).width = 17;
|
*/
|
||||||
this.ws.getColumn(5).width = 17;
|
addHmiRow(hmi, subsystem) {
|
||||||
this.ws.getColumn(6).width = 45;
|
const hasProjectLink = Boolean(hmi?.projectLink) && utilStr.isStrLink(hmi?.projectLink || "");
|
||||||
this.ws.getColumn(7).width = 45;
|
const hasImageLink = Boolean(hmi?.imageLink) && utilStr.isStrLink(hmi?.imageLink || "");
|
||||||
this.ws.getColumn(8).width = 45;
|
|
||||||
this.ws.getColumn(9).width = 30;
|
|
||||||
this.ws.getRow(1).height = 45;
|
|
||||||
|
|
||||||
this.ws.eachRow((row, rowNumber) => {
|
this.hmiSheetData.push([
|
||||||
|
subsystem.name,
|
||||||
|
hmi.nameModel || "",
|
||||||
|
hmi.partNum || "",
|
||||||
|
hmi.cabinet || "",
|
||||||
|
hmi.cabinetLocation || "",
|
||||||
|
hmi.purpose || "",
|
||||||
|
hmi.adminLoginPass || "",
|
||||||
|
hmi.workerLoginPass || "",
|
||||||
|
hmi.interface || "",
|
||||||
|
hmi.connectionSettings || "",
|
||||||
|
hmi.cableLocation || "",
|
||||||
|
hmi.projectName || "",
|
||||||
|
hasProjectLink ? { text: "Ссылка", hyperlink: hmi.projectLink } : hmi.projectLink || "",
|
||||||
|
hmi.diskImage || "",
|
||||||
|
hasImageLink ? { text: "Ссылка", hyperlink: hmi.imageLink } : hmi.imageLink || ""
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {PlcModelDbRecord} plc
|
||||||
|
* @param {SubSystemDbRecord} subsystem
|
||||||
|
*/
|
||||||
|
addPlcRow(plc, subsystem) {
|
||||||
|
const hasProjectLink = Boolean(plc?.projectLink) && utilStr.isStrLink(plc?.projectLink || "");
|
||||||
|
|
||||||
|
this.plcSheetData.push([
|
||||||
|
subsystem.name,
|
||||||
|
plc.nameModel || "",
|
||||||
|
plc.partNum || "",
|
||||||
|
plc.cabinet || "",
|
||||||
|
plc.cabinetLocation || "",
|
||||||
|
plc.purpose || "",
|
||||||
|
plc.interface || "",
|
||||||
|
plc.connectionSettings || "",
|
||||||
|
plc.cableLocation || "",
|
||||||
|
plc.projectName || "",
|
||||||
|
plc.plcPass || "",
|
||||||
|
plc.safetyPass || "",
|
||||||
|
hasProjectLink ? { text: "Ссылка", hyperlink: plc.projectLink } : plc.projectLink || ""
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {FgModelDbRecord} fg
|
||||||
|
* @param {SubSystemDbRecord} subsystem
|
||||||
|
*/
|
||||||
|
addFgRow(fg, subsystem) {
|
||||||
|
const hasProjectLink = Boolean(fg?.projectLink) && utilStr.isStrLink(fg?.projectLink || "");
|
||||||
|
|
||||||
|
this.fgSheetData.push([
|
||||||
|
subsystem.name,
|
||||||
|
fg.nameModel || "",
|
||||||
|
fg.partNum || "",
|
||||||
|
fg.cabinet || "",
|
||||||
|
fg.cabinetLocation || "",
|
||||||
|
fg.purpose || "",
|
||||||
|
fg.interface || "",
|
||||||
|
fg.connectionSettings || "",
|
||||||
|
fg.cableLocation || "",
|
||||||
|
fg.configName || "",
|
||||||
|
hasProjectLink ? { text: "Ссылка", hyperlink: fg.projectLink } : fg.projectLink || ""
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {{ ws: ExcelJS.Worksheet, data: WsData, headings: HeadingRowMap, name: string, currRow: number, colStart: string, colEnd: string }} info
|
||||||
|
*/
|
||||||
|
addBaseLocHeading({ ws, data, headings, name, currRow, colStart, colEnd }) {
|
||||||
|
if (!headings.has(name)) {
|
||||||
|
headings.set(name, { row: currRow });
|
||||||
|
data.push([name]);
|
||||||
|
this.mergeRanges.push({ sheet: ws, colStart, colEnd, from: currRow, to: currRow });
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ExcelJS.Worksheet} ws
|
||||||
|
* @param {Map<string, { row: number }>} headings
|
||||||
|
*/
|
||||||
|
setHeadingCellsStyles(ws, headings) {
|
||||||
|
headings.forEach((h) => {
|
||||||
|
const row = ws.getRow(h.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" }
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ExcelJS.Worksheet} ws
|
||||||
|
*/
|
||||||
|
setSheetCellStyles(ws) {
|
||||||
|
ws.eachRow((row, rowNumber) => {
|
||||||
row.eachCell({ includeEmpty: true }, (cell) => {
|
row.eachCell({ includeEmpty: true }, (cell) => {
|
||||||
cell.alignment = {
|
cell.alignment = {
|
||||||
wrapText: true,
|
wrapText: true,
|
||||||
@ -167,33 +676,5 @@ export class XlsExporterAdapter {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
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 +1,3 @@
|
|||||||
export * from "./date.js";
|
export * from "./date.js";
|
||||||
|
export * from "./num.js";
|
||||||
|
export * from "./str.js";
|
||||||
|
|||||||
11
utils/num.js
Normal file
11
utils/num.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export function range(from = 0, to = 1) {
|
||||||
|
const ret = [];
|
||||||
|
|
||||||
|
to++;
|
||||||
|
|
||||||
|
for (const idx of Array(to - from).keys()) {
|
||||||
|
ret[idx] = from + idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
2
utils/str.js
Normal file
2
utils/str.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/** @param {string} str */
|
||||||
|
export const isStrLink = (str) => RegExp(/^(https?:\/\/|file:\/\/)/gm).test(str);
|
||||||
Loading…
x
Reference in New Issue
Block a user