buildLabelPrintPayload.ts 4.05 KB
/**
 * 按平台 label-template-*.json 结构组装「打印任务」数据(合并后的模板快照 + printInputJson)。
 * 物理 BLE 打印仍走位图 TSC(与 Test Print 相同);本对象为业务/插件侧与 JSON 模板对齐的权威快照。
 */
import type { SystemLabelTemplate, SystemTemplateElementBase } from '../print/types/printer'

/** 与仓库内 label-template-template-*.json 根结构一致 */
export interface LabelTemplateDocumentJson {
  id: string
  name: string
  labelType?: string
  unit: string
  width: number
  height: number
  appliedLocation?: string
  showRuler?: boolean
  showGrid?: boolean
  elements: Record<string, unknown>[]
}

export interface LabelPrintJobMeta {
  labelCode?: string
  productId?: string
  printQuantity?: number
  locationId?: string
}

export interface LabelPrintJobPayload {
  template: LabelTemplateDocumentJson
  /** 与接口 printInputJson 一致(inputKey / elementName 等键) */
  printInputJson: Record<string, unknown>
  meta?: LabelPrintJobMeta
}

function cloneJsonSafeConfig(cfg: Record<string, unknown>): Record<string, unknown> {
  try {
    return JSON.parse(JSON.stringify(cfg ?? {})) as Record<string, unknown>
  } catch {
    return { ...(cfg || {}) } as Record<string, unknown>
  }
}

/** 落库 config:完整深拷贝,避免白名单遗漏字段导致重打缺价签/过敏原/数字等 */
function mergePersistConfigSnapshot(src: Record<string, unknown>): Record<string, unknown> {
  return cloneJsonSafeConfig(src)
}

/** 单元素序列化:与 JSON 模板 elements[] 项字段对齐,并保留 PRINT_INPUT 相关根字段 */
export function serializeElementForLabelTemplateJson(el: SystemTemplateElementBase): Record<string, unknown> {
  const cfg = (el.config || {}) as Record<string, unknown>
  const o: Record<string, unknown> = {
    id: el.id,
    type: el.type,
    x: el.x,
    y: el.y,
    width: el.width,
    height: el.height,
    rotation: el.rotation ?? 'horizontal',
    border: el.border ?? 'none',
    config: mergePersistConfigSnapshot(cfg),
  }
  if (el.valueSourceType) o.valueSourceType = el.valueSourceType
  if (el.inputKey != null && String(el.inputKey).trim()) o.inputKey = el.inputKey
  if (el.elementName != null && String(el.elementName).trim()) o.elementName = el.elementName
  const zx = el as SystemTemplateElementBase & { zIndex?: number; orderNum?: number }
  if (zx.zIndex !== undefined) o.zIndex = zx.zIndex
  if (zx.orderNum !== undefined) o.orderNum = zx.orderNum
  return o
}

/**
 * 从当前合并模板 + 已组好的 printInputJson 生成与 label-template JSON 同构的打印载荷。
 */
export function buildLabelPrintJobPayload(
  merged: SystemLabelTemplate,
  printInputJson: Record<string, unknown>,
  meta?: LabelPrintJobMeta
): LabelPrintJobPayload {
  const template: LabelTemplateDocumentJson = {
    id: String(merged.id || ''),
    name: String(merged.name || '未命名模板'),
    labelType: merged.labelType,
    unit: String(merged.unit || 'inch'),
    width: Number(merged.width) || 0,
    height: Number(merged.height) || 0,
    appliedLocation: merged.appliedLocation || 'ALL',
    showRuler: merged.showRuler !== false,
    showGrid: merged.showGrid !== false,
    elements: (merged.elements || []).map(serializeElementForLabelTemplateJson),
  }
  return {
    template,
    printInputJson: { ...printInputJson },
    meta: meta ? { ...meta } : undefined,
  }
}

let lastLabelPrintJobPayload: LabelPrintJobPayload | null = null

/** 供调试或后续原生插件读取最近一次组装的任务(template + printInputJson) */
export function setLastLabelPrintJobPayload(p: LabelPrintJobPayload): void {
  lastLabelPrintJobPayload = p
}

export function getLastLabelPrintJobPayload(): LabelPrintJobPayload | null {
  return lastLabelPrintJobPayload
}

/** 与原生 printTemplate 入参一致:插件侧可对齐平台导出 JSON */
export function stringifyLabelPrintJobForNative(p: LabelPrintJobPayload): {
  templateJson: string
  dataJson: string
} {
  return {
    templateJson: JSON.stringify(p.template),
    dataJson: JSON.stringify(p.printInputJson ?? {}),
  }
}