- Crear modelo Printer con campos: id, name, host, deviceId, timeout, isDefault - Almacenamiento persistente en data/printers.json - APIs CRUD: GET/POST /api/printers, GET/PUT/DELETE /api/printers/:id - API para seleccionar impresora activa: POST /api/printers/select - Endpoint de impresión ahora usa la impresora seleccionada o la especificada por printerId - Composable usePrinters() para el cliente - UI: Selector de impresora en sidebar, tab Impresoras en mobile - Componentes: PrintersList, PrintersCard, PrintersForm, PrintersSelector
179 lines
4.6 KiB
TypeScript
179 lines
4.6 KiB
TypeScript
// Gestión de impresoras persistentes
|
|
import { readFile, writeFile, mkdir } from 'fs/promises'
|
|
import { existsSync } from 'fs'
|
|
import { join } from 'path'
|
|
|
|
export interface Printer {
|
|
id: string
|
|
name: string
|
|
host: string
|
|
deviceId: string
|
|
timeout: number
|
|
isDefault: boolean
|
|
createdAt: string
|
|
updatedAt: string
|
|
}
|
|
|
|
export interface PrintersStore {
|
|
printers: Printer[]
|
|
selectedPrinterId: string | null
|
|
}
|
|
|
|
// Directorio de datos persistentes
|
|
const DATA_DIR = join(process.cwd(), 'data')
|
|
const PRINTERS_FILE = join(DATA_DIR, 'printers.json')
|
|
|
|
// Asegurar que el directorio existe
|
|
async function ensureDataDir(): Promise<void> {
|
|
if (!existsSync(DATA_DIR)) {
|
|
await mkdir(DATA_DIR, { recursive: true })
|
|
}
|
|
}
|
|
|
|
// Leer store de impresoras
|
|
export async function readPrintersStore(): Promise<PrintersStore> {
|
|
await ensureDataDir()
|
|
|
|
try {
|
|
const data = await readFile(PRINTERS_FILE, 'utf-8')
|
|
return JSON.parse(data)
|
|
} catch {
|
|
// Si no existe el archivo, retornar store vacío
|
|
return {
|
|
printers: [],
|
|
selectedPrinterId: null
|
|
}
|
|
}
|
|
}
|
|
|
|
// Guardar store de impresoras
|
|
export async function writePrintersStore(store: PrintersStore): Promise<void> {
|
|
await ensureDataDir()
|
|
await writeFile(PRINTERS_FILE, JSON.stringify(store, null, 2), 'utf-8')
|
|
}
|
|
|
|
// Generar ID único
|
|
function generateId(): string {
|
|
return `printer_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`
|
|
}
|
|
|
|
// CRUD Operations
|
|
|
|
export async function getAllPrinters(): Promise<Printer[]> {
|
|
const store = await readPrintersStore()
|
|
return store.printers
|
|
}
|
|
|
|
export async function getPrinterById(id: string): Promise<Printer | null> {
|
|
const store = await readPrintersStore()
|
|
return store.printers.find(p => p.id === id) || null
|
|
}
|
|
|
|
export async function getDefaultPrinter(): Promise<Printer | null> {
|
|
const store = await readPrintersStore()
|
|
return store.printers.find(p => p.isDefault) || store.printers[0] || null
|
|
}
|
|
|
|
export async function getSelectedPrinter(): Promise<Printer | null> {
|
|
const store = await readPrintersStore()
|
|
if (store.selectedPrinterId) {
|
|
const printer = store.printers.find(p => p.id === store.selectedPrinterId)
|
|
if (printer) return printer
|
|
}
|
|
// Fallback a la impresora por defecto
|
|
return getDefaultPrinter()
|
|
}
|
|
|
|
export async function setSelectedPrinter(printerId: string | null): Promise<void> {
|
|
const store = await readPrintersStore()
|
|
store.selectedPrinterId = printerId
|
|
await writePrintersStore(store)
|
|
}
|
|
|
|
export async function createPrinter(data: {
|
|
name: string
|
|
host: string
|
|
deviceId: string
|
|
timeout?: number
|
|
isDefault?: boolean
|
|
}): Promise<Printer> {
|
|
const store = await readPrintersStore()
|
|
|
|
const now = new Date().toISOString()
|
|
const printer: Printer = {
|
|
id: generateId(),
|
|
name: data.name,
|
|
host: data.host,
|
|
deviceId: data.deviceId,
|
|
timeout: data.timeout || 60000,
|
|
isDefault: data.isDefault || store.printers.length === 0, // Primera impresora es default
|
|
createdAt: now,
|
|
updatedAt: now
|
|
}
|
|
|
|
// Si esta es default, quitar default de las demás
|
|
if (printer.isDefault) {
|
|
store.printers.forEach(p => p.isDefault = false)
|
|
}
|
|
|
|
store.printers.push(printer)
|
|
|
|
// Si es la primera impresora, seleccionarla
|
|
if (store.printers.length === 1) {
|
|
store.selectedPrinterId = printer.id
|
|
}
|
|
|
|
await writePrintersStore(store)
|
|
return printer
|
|
}
|
|
|
|
export async function updatePrinter(id: string, data: Partial<{
|
|
name: string
|
|
host: string
|
|
deviceId: string
|
|
timeout: number
|
|
isDefault: boolean
|
|
}>): Promise<Printer | null> {
|
|
const store = await readPrintersStore()
|
|
const index = store.printers.findIndex(p => p.id === id)
|
|
|
|
if (index === -1) return null
|
|
|
|
// Si se está estableciendo como default, quitar default de las demás
|
|
if (data.isDefault) {
|
|
store.printers.forEach(p => p.isDefault = false)
|
|
}
|
|
|
|
store.printers[index] = {
|
|
...store.printers[index],
|
|
...data,
|
|
updatedAt: new Date().toISOString()
|
|
}
|
|
|
|
await writePrintersStore(store)
|
|
return store.printers[index]
|
|
}
|
|
|
|
export async function deletePrinter(id: string): Promise<boolean> {
|
|
const store = await readPrintersStore()
|
|
const index = store.printers.findIndex(p => p.id === id)
|
|
|
|
if (index === -1) return false
|
|
|
|
const wasDefault = store.printers[index].isDefault
|
|
store.printers.splice(index, 1)
|
|
|
|
// Si era la impresora seleccionada, limpiar selección
|
|
if (store.selectedPrinterId === id) {
|
|
store.selectedPrinterId = store.printers[0]?.id || null
|
|
}
|
|
|
|
// Si era default y hay otras impresoras, hacer la primera default
|
|
if (wasDefault && store.printers.length > 0) {
|
|
store.printers[0].isDefault = true
|
|
}
|
|
|
|
await writePrintersStore(store)
|
|
return true
|
|
}
|