u
This commit is contained in:
171
src/services/companyPrinterService.js
Normal file
171
src/services/companyPrinterService.js
Normal file
@@ -0,0 +1,171 @@
|
||||
import { emit } from '../api/sse.js';
|
||||
import { createLogger } from '../util/logger.js';
|
||||
|
||||
const log = createLogger('printer');
|
||||
|
||||
/**
|
||||
* Global in-memory registry of live printer states per company.
|
||||
* Structure: Map<companyId, Map<agentId, Array<LivePrinter>>>
|
||||
*
|
||||
* @typedef {object} LivePrinter
|
||||
* @property {number} agentId
|
||||
* @property {string|null} agentName
|
||||
* @property {string} updatedAt
|
||||
* @property {string} [model]
|
||||
* @property {string} [serial]
|
||||
* @property {string} [name]
|
||||
* @property {string} [ip]
|
||||
* @property {string} [address]
|
||||
* @property {number} [labelLength]
|
||||
* @property {object} [errors]
|
||||
* @property {boolean} [ready]
|
||||
* @property {string} [status]
|
||||
*/
|
||||
|
||||
/** @type {Map<number, Map<number, LivePrinter[]>>} */
|
||||
const companyAgents = new Map();
|
||||
|
||||
/**
|
||||
* Normalizes an array of printer objects reported by an agent and registers them for the given company.
|
||||
* Broadcasts the updated whole company printer state via SSE.
|
||||
*
|
||||
* @param {number} companyId
|
||||
* @param {number} agentId
|
||||
* @param {string|null} agentName
|
||||
* @param {Array<object>} rawPrinters
|
||||
* @returns {LivePrinter[]} The complete list of live printers for this company across all agents.
|
||||
*/
|
||||
export function updateAgentPrinters(companyId, agentId, agentName, rawPrinters) {
|
||||
const cId = Number(companyId);
|
||||
const aId = Number(agentId);
|
||||
if (!Number.isInteger(cId) || cId <= 0 || !Number.isInteger(aId) || aId <= 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!companyAgents.has(cId)) {
|
||||
companyAgents.set(cId, new Map());
|
||||
}
|
||||
|
||||
const now = new Date().toISOString();
|
||||
const printerList = Array.isArray(rawPrinters) ? rawPrinters : [];
|
||||
const normalized = printerList.map((p) => ({
|
||||
...p,
|
||||
agentId: aId,
|
||||
agentName: agentName || null,
|
||||
updatedAt: now,
|
||||
}));
|
||||
|
||||
companyAgents.get(cId).set(aId, normalized);
|
||||
|
||||
const allCompanyPrinters = getCompanyPrinters(cId);
|
||||
log.info(`Updated ${normalized.length} live printer(s) for company ${cId} (agent ${aId}, total ${allCompanyPrinters.length})`);
|
||||
|
||||
broadcastCompanyPrinters(cId, allCompanyPrinters);
|
||||
return allCompanyPrinters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all printers associated with a disconnected agent and broadcasts the updated company printer state.
|
||||
*
|
||||
* @param {number} companyId
|
||||
* @param {number} agentId
|
||||
* @returns {LivePrinter[]} The remaining live printers for this company.
|
||||
*/
|
||||
export function removeAgentPrinters(companyId, agentId) {
|
||||
const cId = Number(companyId);
|
||||
const aId = Number(agentId);
|
||||
if (!Number.isInteger(cId) || cId <= 0 || !Number.isInteger(aId) || aId <= 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const agentsMap = companyAgents.get(cId);
|
||||
if (!agentsMap || !agentsMap.has(aId)) {
|
||||
return getCompanyPrinters(cId);
|
||||
}
|
||||
|
||||
const removedCount = agentsMap.get(aId)?.length || 0;
|
||||
agentsMap.delete(aId);
|
||||
|
||||
if (agentsMap.size === 0) {
|
||||
companyAgents.delete(cId);
|
||||
}
|
||||
|
||||
const remainingPrinters = getCompanyPrinters(cId);
|
||||
log.info(`Removed ${removedCount} live printer(s) for disconnected agent ${aId} from company ${cId} (${remainingPrinters.length} remaining)`);
|
||||
|
||||
broadcastCompanyPrinters(cId, remainingPrinters);
|
||||
return remainingPrinters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all active discovered printers for a company across all reporting agents.
|
||||
*
|
||||
* @param {number} companyId
|
||||
* @returns {LivePrinter[]}
|
||||
*/
|
||||
export function getCompanyPrinters(companyId) {
|
||||
const cId = Number(companyId);
|
||||
const agentsMap = companyAgents.get(cId);
|
||||
if (!agentsMap) return [];
|
||||
|
||||
const result = [];
|
||||
for (const printers of agentsMap.values()) {
|
||||
result.push(...printers);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a single live printer by ID, serial, IP/address, or name.
|
||||
*
|
||||
* @param {number} companyId
|
||||
* @param {string|number} identifier
|
||||
* @returns {LivePrinter|null}
|
||||
*/
|
||||
export function getCompanyPrinter(companyId, identifier) {
|
||||
if (identifier == null) return null;
|
||||
const key = String(identifier).trim().toLowerCase();
|
||||
if (!key) return null;
|
||||
|
||||
const printers = getCompanyPrinters(companyId);
|
||||
return printers.find((p) => {
|
||||
if (p.id != null && String(p.id).toLowerCase() === key) return true;
|
||||
if (p.serial && String(p.serial).toLowerCase() === key) return true;
|
||||
if (p.ip && String(p.ip).toLowerCase() === key) return true;
|
||||
if (p.address && String(p.address).toLowerCase() === key) return true;
|
||||
if (p.name && String(p.name).toLowerCase() === key) return true;
|
||||
return false;
|
||||
}) || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts the current live printer list for a company to all connected subscribers via SSE.
|
||||
* Emits both `printer` (with data `{ printers }`) and `printerstate`.
|
||||
*
|
||||
* @param {number} companyId
|
||||
* @param {LivePrinter[]} [printers]
|
||||
*/
|
||||
export function broadcastCompanyPrinters(companyId, printers) {
|
||||
const cId = Number(companyId);
|
||||
if (!Number.isInteger(cId) || cId <= 0) return;
|
||||
|
||||
const list = printers ?? getCompanyPrinters(cId);
|
||||
const payload = { printers: list };
|
||||
|
||||
emit('printer', { companyId: cId, data: payload });
|
||||
emit('printerstate', { companyId: cId, data: payload });
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all live printers for a company (e.g. on company deletion).
|
||||
*
|
||||
* @param {number} companyId
|
||||
*/
|
||||
export function clearCompanyPrinters(companyId) {
|
||||
const cId = Number(companyId);
|
||||
if (companyAgents.has(cId)) {
|
||||
companyAgents.delete(cId);
|
||||
broadcastCompanyPrinters(cId, []);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user