@worm-vue3-print/canvas 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +54 -0
  2. package/dist/canvas.css +1 -0
  3. package/dist/components/CanvasArea.vue.d.ts +102 -0
  4. package/dist/components/CanvasPaper.vue.d.ts +50 -0
  5. package/dist/components/DesignerToolbar.vue.d.ts +59 -0
  6. package/dist/components/ExpressionEditor.vue.d.ts +16 -0
  7. package/dist/components/FieldTreePanel.vue.d.ts +11 -0
  8. package/dist/components/LayerPanel.vue.d.ts +14 -0
  9. package/dist/components/LeftPanel.vue.d.ts +24 -0
  10. package/dist/components/PresetColorPicker.vue.d.ts +10 -0
  11. package/dist/components/PrintDesigner.vue.d.ts +27 -0
  12. package/dist/components/PrintHtmlPreview.vue.d.ts +23 -0
  13. package/dist/components/PropertyPanel.vue.d.ts +23 -0
  14. package/dist/components/Ruler.vue.d.ts +12 -0
  15. package/dist/components/StatusBar.vue.d.ts +14 -0
  16. package/dist/components/WatermarkConfig.vue.d.ts +12 -0
  17. package/dist/components/elements/BarcodeElement.vue.d.ts +9 -0
  18. package/dist/components/elements/BaseElement.vue.d.ts +45 -0
  19. package/dist/components/elements/CellBarcode.vue.d.ts +10 -0
  20. package/dist/components/elements/HtmlElement.vue.d.ts +9 -0
  21. package/dist/components/elements/ImageElement.vue.d.ts +9 -0
  22. package/dist/components/elements/LineElement.vue.d.ts +7 -0
  23. package/dist/components/elements/LongTextElement.vue.d.ts +9 -0
  24. package/dist/components/elements/PageNumberElement.vue.d.ts +9 -0
  25. package/dist/components/elements/QrcodeElement.vue.d.ts +9 -0
  26. package/dist/components/elements/ShapeElement.vue.d.ts +7 -0
  27. package/dist/components/elements/TableContextMenu.vue.d.ts +19 -0
  28. package/dist/components/elements/TableElement.vue.d.ts +17 -0
  29. package/dist/components/elements/TextElement.vue.d.ts +9 -0
  30. package/dist/components/property/AdvancedGroup.vue.d.ts +13 -0
  31. package/dist/components/property/AppearanceGroup.vue.d.ts +10 -0
  32. package/dist/components/property/BindingControl.vue.d.ts +13 -0
  33. package/dist/components/property/BorderBgGroup.vue.d.ts +9 -0
  34. package/dist/components/property/CodeGroup.vue.d.ts +13 -0
  35. package/dist/components/property/ImageContentUpload.vue.d.ts +10 -0
  36. package/dist/components/property/PaginationGroup.vue.d.ts +9 -0
  37. package/dist/components/property/PositionSizeGroup.vue.d.ts +9 -0
  38. package/dist/components/property/PropertyGroup.vue.d.ts +19 -0
  39. package/dist/components/property/PropertySearch.vue.d.ts +7 -0
  40. package/dist/components/property/TableCellGroup.vue.d.ts +12 -0
  41. package/dist/components/property/TableRowGroup.vue.d.ts +8 -0
  42. package/dist/components/property/TableSettingsGroup.vue.d.ts +8 -0
  43. package/dist/composables/useAdsorb.d.ts +26 -0
  44. package/dist/composables/useAdsorbManager.d.ts +31 -0
  45. package/dist/composables/useAlign.d.ts +5 -0
  46. package/dist/composables/useBindingDisplay.d.ts +11 -0
  47. package/dist/composables/useClipboard.d.ts +251 -0
  48. package/dist/composables/useDesignerState.d.ts +1149 -0
  49. package/dist/composables/useDrag.d.ts +51 -0
  50. package/dist/composables/useGroup.d.ts +7 -0
  51. package/dist/composables/useGuides.d.ts +12 -0
  52. package/dist/composables/useHistory.d.ts +31 -0
  53. package/dist/composables/useHostAdapter.d.ts +4 -0
  54. package/dist/composables/useKeyboard.d.ts +22 -0
  55. package/dist/composables/useResize.d.ts +26 -0
  56. package/dist/composables/useSelection.d.ts +26 -0
  57. package/dist/composables/useStudioChrome.d.ts +8 -0
  58. package/dist/composables/useTableSelection.d.ts +10 -0
  59. package/dist/index.cjs +4 -0
  60. package/dist/index.cjs.map +1 -0
  61. package/dist/index.d.ts +9 -0
  62. package/dist/index.js +6444 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/render/browser-code-renderer.d.ts +3 -0
  65. package/dist/render/browser-pagination.d.ts +17 -0
  66. package/dist/types.d.ts +282 -0
  67. package/dist/utils/binding-registry.d.ts +8 -0
  68. package/dist/utils/binding.d.ts +16 -0
  69. package/dist/utils/default-config.d.ts +13 -0
  70. package/dist/utils/demo-data.d.ts +2 -0
  71. package/dist/utils/element-factory.d.ts +4 -0
  72. package/dist/utils/engine.d.ts +2 -0
  73. package/dist/utils/expression-eval.d.ts +30 -0
  74. package/dist/utils/field-groups.d.ts +21 -0
  75. package/dist/utils/migrate.d.ts +2 -0
  76. package/dist/utils/preset-colors.d.ts +2 -0
  77. package/dist/utils/property-search.d.ts +18 -0
  78. package/dist/utils/ruler.d.ts +7 -0
  79. package/dist/utils/scale.d.ts +2 -0
  80. package/dist/utils/table-matrix.d.ts +61 -0
  81. package/dist/utils/units.d.ts +4 -0
  82. package/dist/utils/zone-layout.d.ts +27 -0
  83. package/package.json +55 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/utils/table-matrix.ts","../src/utils/element-factory.ts","../src/utils/engine.ts","../src/utils/demo-data.ts","../src/utils/expression-eval.ts","../src/utils/binding.ts","../src/utils/units.ts","../src/utils/migrate.ts","../src/utils/default-config.ts","../src/utils/scale.ts","../src/utils/zone-layout.ts","../src/composables/useSelection.ts","../src/composables/useClipboard.ts","../src/composables/useAlign.ts","../src/composables/useGroup.ts","../src/composables/useHistory.ts","../src/composables/useKeyboard.ts","../src/composables/useDesignerState.ts","../src/composables/useGuides.ts","../src/composables/useTableSelection.ts","../src/composables/useHostAdapter.ts","../src/components/DesignerToolbar.vue","../src/components/LayerPanel.vue","../src/utils/field-groups.ts","../src/components/FieldTreePanel.vue","../src/components/LeftPanel.vue","../src/composables/useDrag.ts","../src/composables/useResize.ts","../src/composables/useBindingDisplay.ts","../src/components/elements/TextElement.vue","../src/components/elements/ImageElement.vue","../src/components/elements/LongTextElement.vue","../src/components/elements/TableContextMenu.vue","../src/components/elements/CellBarcode.vue","../src/components/elements/TableElement.vue","../src/components/elements/LineElement.vue","../src/components/elements/ShapeElement.vue","../src/components/elements/BarcodeElement.vue","../src/components/elements/QrcodeElement.vue","../src/components/elements/HtmlElement.vue","../src/components/elements/PageNumberElement.vue","../src/components/elements/BaseElement.vue","../src/utils/ruler.ts","../src/components/Ruler.vue","../src/composables/useAdsorb.ts","../src/composables/useAdsorbManager.ts","../src/components/CanvasPaper.vue","../src/components/CanvasArea.vue","../src/utils/property-search.ts","../src/components/property/PropertySearch.vue","../src/components/property/PropertyGroup.vue","../src/components/property/PositionSizeGroup.vue","../src/utils/preset-colors.ts","../src/components/PresetColorPicker.vue","../src/components/property/AppearanceGroup.vue","../src/components/ExpressionEditor.vue","../src/components/property/BindingControl.vue","../src/components/property/TableSettingsGroup.vue","../src/components/property/BorderBgGroup.vue","../src/components/property/AdvancedGroup.vue","../src/components/property/PaginationGroup.vue","../src/components/property/ImageContentUpload.vue","../src/components/property/TableRowGroup.vue","../src/components/property/TableCellGroup.vue","../src/utils/binding-registry.ts","../src/components/PropertyPanel.vue","../src/components/StatusBar.vue","../src/composables/useStudioChrome.ts","../src/components/PrintDesigner.vue","../src/render/browser-pagination.ts","../src/render/browser-code-renderer.ts","../src/components/PrintHtmlPreview.vue"],"sourcesContent":["// web/src/components/print/utils/table-matrix.ts\n// Excel 风格表格矩阵结构操作纯函数库。\n// 约定:函数原地修改传入的 rows/colWidths;返回 string 的函数以非空字符串为拒绝原因。\nimport type { TableRow, TableRowType, TableCell, TableCellBorder, ElementOptions } from '../types'\n\nexport interface CellRect { r1: number; c1: number; r2: number; c2: number }\n\n/** 单元格 ID 生成器:使用闭包隔离的计数器,避免全局变量冲突 */\nfunction createCellIdGenerator() {\n let seq = 0\n return function genCellId(): string {\n seq += 1\n return `cell-${Date.now().toString(36)}-${seq}`\n }\n}\n\n/** 行 ID 生成器:使用闭包隔离的计数器 */\nfunction createRowIdGenerator() {\n let seq = 0\n return function genRowId(): string {\n seq += 1\n return `row-${Date.now().toString(36)}-${seq}`\n }\n}\n\n// 模块级单例:同一模块内共享计数器\nconst genCellId = createCellIdGenerator()\nconst genRowId = createRowIdGenerator()\n\nconst DEFAULT_BORDER: TableCellBorder = { width: 0.75, style: 'solid', color: '#333333' }\n\n/** JSON 深拷贝:兼容 Vue reactive Proxy(structuredClone 对 Proxy 抛 DataCloneError) */\nfunction deepClone<T>(v: T): T {\n return JSON.parse(JSON.stringify(v)) as T\n}\n\nexport function createCell(partial?: Partial<TableCell>): TableCell {\n return {\n id: genCellId(),\n borders: {\n top: { ...DEFAULT_BORDER }, right: { ...DEFAULT_BORDER },\n bottom: { ...DEFAULT_BORDER }, left: { ...DEFAULT_BORDER },\n },\n ...partial,\n }\n}\n\n/** 默认新建表格:3 列 × 4 行(标题/数据/小计/汇总),列宽均分 50mm,表格组件默认显示当前页小计行 */\nexport function createDefaultTable(): { rows: TableRow[]; colWidths: number[] } {\n const colWidths = [50, 50, 50]\n const mk = (type: TableRowType, repeat?: boolean): TableRow => ({\n id: genRowId(),\n type,\n height: 8,\n ...(repeat !== undefined ? { repeatOnPage: repeat } : {}),\n cells: colWidths.map(() => createCell()),\n })\n const header = mk('header', true)\n header.cells.forEach((c, i) => { c.formatter = `列${i + 1}`; c.align = 'center'; c.fontWeight = 'bold' })\n return { rows: [header, mk('data'), mk('subtotal'), mk('summary')], colWidths }\n}\n\n/** 定位覆盖 (r,c) 的主格坐标(自身非 merged 即为主格) */\nexport function findMainCell(rows: TableRow[], r: number, c: number): { r: number; c: number } {\n if (!rows[r]!.cells[c]!.merged) { return { r, c } }\n for (let ri = r; ri >= 0; ri--) {\n for (let ci = c; ci >= 0; ci--) {\n const cell = rows[ri]!.cells[ci]!\n if (cell.merged) { continue }\n const rs = cell.rowspan ?? 1\n const cs = cell.colspan ?? 1\n if (ri + rs - 1 >= r && ci + cs - 1 >= c) { return { r: ri, c: ci } }\n }\n }\n return { r, c }\n}\n\n/** 主格覆盖矩形 */\nexport function getSpanRect(rows: TableRow[], r: number, c: number): CellRect {\n const main = findMainCell(rows, r, c)\n const cell = rows[main.r]!.cells[main.c]!\n return {\n r1: main.r, c1: main.c,\n r2: main.r + (cell.rowspan ?? 1) - 1,\n c2: main.c + (cell.colspan ?? 1) - 1,\n }\n}\n\n/** 由锚点/焦点推导矩形选区,并迭代扩展至完整包含所有跨越的合并格 */\nexport function normalizeSelection(\n rows: TableRow[], a: { r: number; c: number }, b: { r: number; c: number },\n): CellRect {\n let rect: CellRect = {\n r1: Math.min(a.r, b.r), c1: Math.min(a.c, b.c),\n r2: Math.max(a.r, b.r), c2: Math.max(a.c, b.c),\n }\n for (;;) {\n let changed = false\n for (let r = rect.r1; r <= rect.r2; r++) {\n for (let c = rect.c1; c <= rect.c2; c++) {\n const span = getSpanRect(rows, r, c)\n const merged: CellRect = {\n r1: Math.min(rect.r1, span.r1), c1: Math.min(rect.c1, span.c1),\n r2: Math.max(rect.r2, span.r2), c2: Math.max(rect.c2, span.c2),\n }\n if (merged.r1 !== rect.r1 || merged.c1 !== rect.c1 || merged.r2 !== rect.r2 || merged.c2 !== rect.c2) {\n rect = merged\n changed = true\n }\n }\n }\n if (!changed) { return rect }\n }\n}\n\n/** 合并合法性校验,返回拒绝原因或 null */\nexport function canMergeReason(rows: TableRow[], rect: CellRect): string | null {\n const cellCount = (rect.r2 - rect.r1 + 1) * (rect.c2 - rect.c1 + 1)\n if (cellCount < 2) { return '至少选择 2 个单元格' }\n const types = new Set<TableRowType>()\n for (let r = rect.r1; r <= rect.r2; r++) { types.add(rows[r]!.type) }\n if (types.size > 1) { return '合并区域不能跨越不同类型的行' }\n // 与已有合并区部分重叠:normalize 后矩形应与选区一致\n const norm = normalizeSelection(rows, { r: rect.r1, c: rect.c1 }, { r: rect.r2, c: rect.c2 })\n if (norm.r1 !== rect.r1 || norm.c1 !== rect.c1 || norm.r2 !== rect.r2 || norm.c2 !== rect.c2) {\n return '选区与已有合并区域部分重叠'\n }\n return null\n}\n\n/** 合并:左上为主格,非空内容空格拼接并入主格 */\nexport function mergeCells(rows: TableRow[], rect: CellRect): void {\n const main = rows[rect.r1]!.cells[rect.c1]!\n const contents: string[] = []\n for (let r = rect.r1; r <= rect.r2; r++) {\n for (let c = rect.c1; c <= rect.c2; c++) {\n const cell = rows[r]!.cells[c]!\n if (cell.formatter) { contents.push(cell.formatter) }\n if (r === rect.r1 && c === rect.c1) { continue }\n cell.merged = true\n cell.rowspan = 1\n cell.colspan = 1\n cell.formatter = ''\n }\n }\n main.rowspan = rect.r2 - rect.r1 + 1\n main.colspan = rect.c2 - rect.c1 + 1\n main.formatter = contents.join(' ')\n}\n\n/** 拆分选区内所有合并格:占位格恢复并复制主格样式 */\nexport function splitCells(rows: TableRow[], rect: CellRect): void {\n for (let r = rect.r1; r <= rect.r2; r++) {\n for (let c = rect.c1; c <= rect.c2; c++) {\n const cell = rows[r]!.cells[c]!\n if (!cell.merged && ((cell.rowspan ?? 1) > 1 || (cell.colspan ?? 1) > 1)) {\n const span = getSpanRect(rows, r, c)\n const styleSrc = cell\n for (let sr = span.r1; sr <= span.r2; sr++) {\n for (let sc = span.c1; sc <= span.c2; sc++) {\n const t = rows[sr]!.cells[sc]!\n t.merged = false\n t.rowspan = 1\n t.colspan = 1\n copyCellStyle(styleSrc, t)\n }\n }\n cell.rowspan = 1\n cell.colspan = 1\n }\n }\n }\n}\n\nfunction copyCellStyle(src: TableCell, dst: TableCell): void {\n if (src === dst) { return }\n dst.align = src.align\n dst.valign = src.valign\n dst.fontSize = src.fontSize\n dst.fontWeight = src.fontWeight\n dst.color = src.color\n dst.backgroundColor = src.backgroundColor\n dst.borders = src.borders ? deepClone(src.borders) : undefined\n dst.padding = src.padding\n dst.wordWrap = src.wordWrap\n}\n\n/** 插入行。index 为参照行,position 决定插在其上方或下方 */\nexport function insertRow(rows: TableRow[], index: number, position: 'above' | 'below'): void {\n const insertAt = position === 'above' ? index : index + 1\n const ref = rows[index]!\n const colCount = ref.cells.length\n // 参照行为 data 时新行降级为 header(data 全表唯一)\n const type: TableRowType = ref.type === 'data' ? 'header' : ref.type\n const newRow: TableRow = {\n id: `row-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`,\n type,\n height: ref.height,\n cells: Array.from({ length: colCount }, () => createCell()),\n }\n // 处理跨越插入边界的纵向合并:主格 rowspan+1,新行对应格置 merged\n for (let c = 0; c < colCount; c++) {\n if (insertAt > 0 && insertAt < rows.length) {\n const span = getSpanRect(rows, insertAt - 1, c)\n if (span.r1 < insertAt && span.r2 >= insertAt) {\n const main = rows[span.r1]!.cells[span.c1]!\n main.rowspan = (main.rowspan ?? 1) + 1\n newRow.cells[c]!.merged = true\n }\n }\n }\n rows.splice(insertAt, 0, newRow)\n}\n\n/** 删除行;主格在被删行时移交下一行 */\nexport function deleteRow(rows: TableRow[], index: number): string | null {\n if (rows.length <= 1) { return '不能删除最后一行' }\n const row = rows[index]!\n const colCount = row.cells.length\n for (let c = 0; c < colCount; c++) {\n const cell = row.cells[c]!\n if (!cell.merged && (cell.rowspan ?? 1) > 1) {\n // 主格在被删行:移交到下一行\n const next = rows[index + 1]!.cells[c]!\n Object.assign(next, deepClone(cell), { id: next.id })\n next.rowspan = (cell.rowspan ?? 1) - 1\n next.merged = false\n } else if (cell.merged) {\n // 被删行处于某纵向合并中间:主格 rowspan-1\n const span = getSpanRect(rows, index, c)\n if (span.r1 < index && span.c1 === c) {\n const main = rows[span.r1]!.cells[span.c1]!\n main.rowspan = (main.rowspan ?? 1) - 1\n }\n }\n }\n rows.splice(index, 1)\n return null\n}\n\n/** 插入列 */\nexport function insertCol(\n rows: TableRow[], colWidths: number[], index: number, position: 'left' | 'right',\n): void {\n const insertAt = position === 'left' ? index : index + 1\n colWidths.splice(insertAt, 0, colWidths[index]!)\n for (const row of rows) {\n const newCell = createCell()\n if (insertAt > 0 && insertAt < row.cells.length) {\n const r = rows.indexOf(row)\n const span = getSpanRect(rows, r, insertAt - 1)\n if (span.c1 < insertAt && span.c2 >= insertAt) {\n const main = rows[span.r1]!.cells[span.c1]!\n // 每个横跨行都会命中一次,只在主格所在行加 colspan\n if (r === span.r1) { main.colspan = (main.colspan ?? 1) + 1 }\n newCell.merged = true\n }\n }\n row.cells.splice(insertAt, 0, newCell)\n }\n}\n\n/** 删除列;主格在被删列时移交右侧列 */\nexport function deleteCol(rows: TableRow[], colWidths: number[], index: number): string | null {\n if (colWidths.length <= 1) { return '不能删除最后一列' }\n for (let r = 0; r < rows.length; r++) {\n const cell = rows[r]!.cells[index]!\n if (!cell.merged && (cell.colspan ?? 1) > 1) {\n const next = rows[r]!.cells[index + 1]!\n Object.assign(next, deepClone(cell), { id: next.id })\n next.colspan = (cell.colspan ?? 1) - 1\n next.merged = false\n } else if (cell.merged) {\n const span = getSpanRect(rows, r, index)\n if (span.c1 < index && span.r1 === r) {\n const main = rows[span.r1]!.cells[span.c1]!\n main.colspan = (main.colspan ?? 1) - 1\n }\n }\n }\n for (const row of rows) { row.cells.splice(index, 1) }\n colWidths.splice(index, 1)\n return null\n}\n\n/** 行类型变更校验 + 写入。约束:header 顶部连续;data 唯一;subtotal/summary 在 data 之后;subtotal 在 summary 之前 */\nexport function setRowType(\n rows: TableRow[], index: number, type: TableRowType,\n): string | null {\n if (type === 'data') {\n const existing = rows.findIndex((r, i) => r.type === 'data' && i !== index)\n if (existing >= 0) { return `数据行已存在(第 ${existing + 1} 行),全表最多一行` }\n }\n if (type === 'header') {\n // 设置后 header 行必须从第 0 行起连续\n for (let i = 0; i < index; i++) {\n if (rows[i]!.type !== 'header') { return '标题行必须从表格顶部连续设置' }\n }\n }\n if (type === 'subtotal' || type === 'summary') {\n const dataIdx = rows.findIndex(r => r.type === 'data')\n if (dataIdx < 0) { return '请先设置数据行,小计/汇总行必须位于数据行之后' }\n if (index < dataIdx) { return '小计/汇总行必须位于数据行之后' }\n }\n if (type === 'subtotal') {\n // 目标状态:本行设为小计后,其上方(index 之前)不得存在汇总行(小计必须位于汇总行之前)\n if (rows.slice(0, index).some(r => r.type === 'summary')) {\n return '小计行必须位于汇总行之前'\n }\n }\n if (type === 'summary') {\n if (rows.slice(index + 1).some(r => r.type === 'subtotal')) {\n return '汇总行必须位于小计行之后'\n }\n }\n // 取消 header 时校验剩余 header 仍连续(中间行取消会断开)\n if (rows[index]!.type === 'header' && type !== 'header') {\n for (let i = index + 1; i < rows.length; i++) {\n if (rows[i]!.type === 'header') { return '取消该标题行会导致标题行不连续,请先调整后续标题行' }\n }\n }\n rows[index]!.type = type\n if (type !== 'header') { delete rows[index]!.repeatOnPage }\n return null\n}\n\nexport type BorderPreset = 'all' | 'outer' | 'inner' | 'none'\n\n/** 按预设批量写边框;none 时清空选区内所有格的 borders */\nexport function applyBorderPreset(\n rows: TableRow[], rect: CellRect, preset: BorderPreset, border: TableCellBorder,\n): void {\n for (let r = rect.r1; r <= rect.r2; r++) {\n for (let c = rect.c1; c <= rect.c2; c++) {\n const cell = rows[r]!.cells[c]!\n if (cell.merged) { continue }\n if (preset === 'none') {\n delete cell.borders\n continue\n }\n const span = getSpanRect(rows, r, c)\n const atTop = span.r1 === rect.r1\n const atBottom = span.r2 === rect.r2\n const atLeft = span.c1 === rect.c1\n const atRight = span.c2 === rect.c2\n const b = { ...(cell.borders ?? {}) }\n if (preset === 'all') {\n b.top = { ...border }; b.bottom = { ...border }; b.left = { ...border }; b.right = { ...border }\n } else if (preset === 'outer') {\n if (atTop) { b.top = { ...border } }\n if (atBottom) { b.bottom = { ...border } }\n if (atLeft) { b.left = { ...border } }\n if (atRight) { b.right = { ...border } }\n } else if (preset === 'inner') {\n if (!atTop) { b.top = { ...border } }\n if (!atBottom) { b.bottom = { ...border } }\n if (!atLeft) { b.left = { ...border } }\n if (!atRight) { b.right = { ...border } }\n }\n cell.borders = b\n }\n }\n}\n\n/** 设计态下无边框单元格的辅助虚线:与背景网格线同风格(浅灰虚线),略深保证可读 */\nexport const GHOST_BORDER_CSS = '1px dashed rgba(0,0,0,0.18)'\n\n/**\n * 解析单元格某条边的最终 CSS border 值。\n * - 有真实边框(style 非 none)→ 返回 `${width}pt ${style} ${color}`\n * - 设计态且开关开启、且该边无边框 → 返回虚拟虚线(仅设计稿展示,不影响预览/打印)\n * - 其余情况(预览态 / 开关关闭)→ 'none'\n */\nexport function resolveCellBorderCss(\n b: TableCellBorder | undefined,\n opts: { designMode?: boolean; showGhostBorder?: boolean } = {},\n): string {\n if (b && b.style !== 'none') return `${b.width}pt ${b.style} ${b.color}`\n if (opts.designMode && opts.showGhostBorder !== false) return GHOST_BORDER_CSS\n return 'none'\n}\n\n/** 表格元素尺寸派生:options.width/height 恒等于列宽和/行高和(mm),与渲染端一致 */\nexport function syncTableElementSize(options: ElementOptions): void {\n const wMm = (options.tableColWidths ?? []).reduce((s, w) => s + w, 0)\n const hMm = (options.tableRows ?? []).reduce((s, r) => s + r.height, 0)\n options.width = Math.round(wMm * 100) / 100\n options.height = Math.round(hMm * 100) / 100\n}\n","// web/src/components/print/utils/element-factory.ts\nimport type { RuntimeElement, ElementType, ElementOptions } from '../types'\nimport { createDefaultTable } from './table-matrix'\n\nexport function generateId(): string {\n return `el-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`\n}\n\nexport function createDefaultOptions(type: ElementType): ElementOptions {\n // pt → mm:20/50/120/20 → 7/17.6/42.3/7.1\n const base: ElementOptions = { left: 7, top: 17.6, width: 42.3, height: 7.1 }\n\n switch (type) {\n case 'text':\n return { ...base, formatter: '文本', fontSize: 12, textAlign: 'left', height: 5.3 }\n case 'image':\n return { ...base, width: 28.2, height: 28.2, fit: 'contain' }\n case 'longText':\n return { ...base, width: 141.1, height: 28.2, fontSize: 12, lineHeight: 18 }\n case 'table': {\n const { rows, colWidths } = createDefaultTable()\n const totalW = colWidths.reduce((s, w) => s + w, 0)\n const totalH = rows.reduce((s, r) => s + r.height, 0)\n return {\n ...base, width: totalW, height: totalH, // 表格尺寸由列宽/行高(mm)派生,与渲染端一致\n tableMode: 'dynamic',\n tableRows: rows,\n tableColWidths: colWidths,\n tableDefaultFontSize: 10,\n tableDefaultColor: '#333333',\n tableDefaultPadding: 1,\n fields: [],\n tablePagination: { enabled: true },\n }\n }\n case 'hline':\n return { ...base, width: 70.6, height: 1.8, borderWidth: 0.75 }\n case 'vline':\n return { ...base, width: 1.8, height: 35.3, borderWidth: 0.75 }\n case 'rect':\n return { ...base, width: 28.2, height: 28.2, borderWidth: 1, borderColor: '#333' }\n case 'oval':\n return { ...base, width: 28.2, height: 28.2, borderWidth: 1, borderColor: '#333' }\n case 'barcode':\n return { ...base, width: 56.4, height: 14.1, title: '条形码', barcodeType: 'code128', testData: '12345678' }\n case 'qrcode':\n return { ...base, width: 28.2, height: 28.2, title: '二维码', testData: 'qrcode' }\n case 'html':\n return { ...base, width: 28.2, height: 28.2 }\n default:\n return base\n }\n}\n\nexport function createRuntimeElement(type: ElementType, options?: Partial<ElementOptions>): RuntimeElement {\n const typeMetaMap: Record<ElementType, { title: string }> = {\n text: { title: '文本' },\n image: { title: '图片' },\n longText: { title: '长文' },\n table: { title: '表格' },\n hline: { title: '横线' },\n vline: { title: '竖线' },\n rect: { title: '矩形' },\n oval: { title: '椭圆' },\n barcode: { title: '条形码' },\n qrcode: { title: '二维码' },\n html: { title: 'HTML' },\n pageNumber: { title: '页码' },\n }\n\n return {\n id: generateId(),\n options: { ...createDefaultOptions(type), ...options },\n printElementType: { type, title: typeMetaMap[type]?.title || type },\n }\n}\n","// 打印设计器核心自持的表达式引擎单例。\n// 独立于宿主(不依赖 @/utils),便于整体抽离为开源包;扩展函数由 ./expression-eval 注册。\nimport { TemplateEngine } from '@worm-vue3-print/core'\n\nexport const engine = new TemplateEngine()\n","// web/src/components/print/utils/demo-data.ts\n// 采购收货单默认预览 demo 数据: 嵌套结构, 与字段树定义一致\n\nexport function getDemoData(): Record<string, any> {\n return DEFAULT_DEMO_DATA\n}\n\nexport const DEFAULT_DEMO_DATA: Record<string, any> = {\n supplier: {\n name: '鑫达五金有限公司',\n phone: '0571-88776655',\n address: '杭州市萧山区经济开发区88号',\n },\n receiver: {\n name: '李四',\n phone: '13912345678',\n address: '杭州市余杭区文一西路998号',\n },\n order: {\n no: 'PO20260801001',\n date: '2026-08-01',\n total: 69543.75,\n },\n // 50 条商品明细, 用于验证多页分页效果\n goods: [\n { name: '碳钢螺丝 M8', spec: 'M14×10', unit: '个', qty: 100, price: 0.50, amount: 50, remark: 'A级' },\n { name: '不锈钢螺母 M10', spec: 'M16×11', unit: '套', qty: 117, price: 0.75, amount: 87.75, remark: '' },\n { name: '弹簧垫圈 M12', spec: 'M6×12', unit: '盒', qty: 134, price: 1, amount: 134, remark: '' },\n { name: '六角螺栓 M14', spec: 'M5×13', unit: '支', qty: 151, price: 1.25, amount: 188.75, remark: '' },\n { name: '内六角螺钉 M16', spec: 'M20×14', unit: '袋', qty: 168, price: 1.50, amount: 252, remark: '' },\n { name: '平垫圈 M6', spec: 'M4×15', unit: '件', qty: 185, price: 1.75, amount: 323.75, remark: '' },\n { name: '自攻螺钉 M5', spec: 'M3×16', unit: '根', qty: 202, price: 2, amount: 404, remark: '' },\n { name: '双头螺柱 M20', spec: 'M8×17', unit: '包', qty: 219, price: 2.25, amount: 492.75, remark: 'A级' },\n { name: '紧定螺钉 M4', spec: 'M10×18', unit: '只', qty: 236, price: 2.50, amount: 590, remark: '' },\n { name: '十字盘头钉 M3', spec: 'M12×19', unit: '组', qty: 253, price: 2.75, amount: 695.75, remark: '' },\n { name: '碳钢螺丝 M8', spec: 'M14×20', unit: '个', qty: 270, price: 3, amount: 810, remark: '' },\n { name: '不锈钢螺母 M10', spec: 'M16×21', unit: '套', qty: 287, price: 3.25, amount: 932.75, remark: '' },\n { name: '弹簧垫圈 M12', spec: 'M6×22', unit: '盒', qty: 304, price: 3.50, amount: 1064, remark: '' },\n { name: '六角螺栓 M14', spec: 'M5×23', unit: '支', qty: 321, price: 3.75, amount: 1203.75, remark: '' },\n { name: '内六角螺钉 M16', spec: 'M20×24', unit: '袋', qty: 338, price: 4, amount: 1352, remark: 'A级' },\n { name: '平垫圈 M6', spec: 'M4×25', unit: '件', qty: 355, price: 4.25, amount: 1508.75, remark: '' },\n { name: '自攻螺钉 M5', spec: 'M3×26', unit: '根', qty: 372, price: 4.50, amount: 1674, remark: '' },\n { name: '双头螺柱 M20', spec: 'M8×27', unit: '包', qty: 389, price: 4.75, amount: 1847.75, remark: '' },\n { name: '紧定螺钉 M4', spec: 'M10×28', unit: '只', qty: 406, price: 5, amount: 2030, remark: '' },\n { name: '十字盘头钉 M3', spec: 'M12×29', unit: '组', qty: 423, price: 5.25, amount: 2220.75, remark: '' },\n { name: '碳钢螺丝 M8', spec: 'M14×30', unit: '个', qty: 440, price: 0.50, amount: 220, remark: '' },\n { name: '不锈钢螺母 M10', spec: 'M16×31', unit: '套', qty: 457, price: 0.75, amount: 342.75, remark: 'A级' },\n { name: '弹簧垫圈 M12', spec: 'M6×32', unit: '盒', qty: 474, price: 1, amount: 474, remark: '' },\n { name: '六角螺栓 M14', spec: 'M5×33', unit: '支', qty: 491, price: 1.25, amount: 613.75, remark: '' },\n { name: '内六角螺钉 M16', spec: 'M20×34', unit: '袋', qty: 508, price: 1.50, amount: 762, remark: '' },\n { name: '平垫圈 M6', spec: 'M4×35', unit: '件', qty: 525, price: 1.75, amount: 918.75, remark: '' },\n { name: '自攻螺钉 M5', spec: 'M3×36', unit: '根', qty: 542, price: 2, amount: 1084, remark: '' },\n { name: '双头螺柱 M20', spec: 'M8×37', unit: '包', qty: 559, price: 2.25, amount: 1257.75, remark: '' },\n { name: '紧定螺钉 M4', spec: 'M10×38', unit: '只', qty: 576, price: 2.50, amount: 1440, remark: 'A级' },\n { name: '十字盘头钉 M3', spec: 'M12×39', unit: '组', qty: 593, price: 2.75, amount: 1630.75, remark: '' },\n { name: '碳钢螺丝 M8', spec: 'M14×40', unit: '个', qty: 610, price: 3, amount: 1830, remark: '' },\n { name: '不锈钢螺母 M10', spec: 'M16×41', unit: '套', qty: 627, price: 3.25, amount: 2037.75, remark: '' },\n { name: '弹簧垫圈 M12', spec: 'M6×42', unit: '盒', qty: 644, price: 3.50, amount: 2254, remark: '' },\n { name: '六角螺栓 M14', spec: 'M5×43', unit: '支', qty: 661, price: 3.75, amount: 2478.75, remark: '' },\n { name: '内六角螺钉 M16', spec: 'M20×44', unit: '袋', qty: 678, price: 4, amount: 2712, remark: '' },\n { name: '平垫圈 M6', spec: 'M4×45', unit: '件', qty: 695, price: 4.25, amount: 2953.75, remark: 'A级' },\n { name: '自攻螺钉 M5', spec: 'M3×46', unit: '根', qty: 712, price: 4.50, amount: 3204, remark: '' },\n { name: '双头螺柱 M20', spec: 'M8×47', unit: '包', qty: 729, price: 4.75, amount: 3462.75, remark: '' },\n { name: '紧定螺钉 M4', spec: 'M10×48', unit: '只', qty: 746, price: 5, amount: 3730, remark: '' },\n { name: '十字盘头钉 M3', spec: 'M12×49', unit: '组', qty: 763, price: 5.25, amount: 4005.75, remark: '' },\n { name: '碳钢螺丝 M8', spec: 'M14×10', unit: '个', qty: 780, price: 0.50, amount: 390, remark: '' },\n { name: '不锈钢螺母 M10', spec: 'M16×11', unit: '套', qty: 797, price: 0.75, amount: 597.75, remark: '' },\n { name: '弹簧垫圈 M12', spec: 'M6×12', unit: '盒', qty: 814, price: 1, amount: 814, remark: 'A级' },\n { name: '六角螺栓 M14', spec: 'M5×13', unit: '支', qty: 831, price: 1.25, amount: 1038.75, remark: '' },\n { name: '内六角螺钉 M16', spec: 'M20×14', unit: '袋', qty: 848, price: 1.50, amount: 1272, remark: '' },\n { name: '平垫圈 M6', spec: 'M4×15', unit: '件', qty: 865, price: 1.75, amount: 1513.75, remark: '' },\n { name: '自攻螺钉 M5', spec: 'M3×16', unit: '根', qty: 882, price: 2, amount: 1764, remark: '' },\n { name: '双头螺柱 M20', spec: 'M8×17', unit: '包', qty: 899, price: 2.25, amount: 2022.75, remark: '' },\n { name: '紧定螺钉 M4', spec: 'M10×18', unit: '只', qty: 916, price: 2.50, amount: 2290, remark: '' },\n { name: '十字盘头钉 M3', spec: 'M12×19', unit: '组', qty: 933, price: 2.75, amount: 2565.75, remark: 'A级' },\n ],\n}\n","// web/src/components/print/utils/expression-eval.ts\n// 包装共享引擎,保持原有 API 兼容\n\nimport { engine } from './engine'\nimport {\n formatMoney,\n formatDate,\n toUpperCaseAmount,\n ifFn,\n sum,\n avg,\n count,\n min,\n max,\n} from '@worm-vue3-print/core'\n\n// 扩展函数库(保持原有导出)\nexport const EXTENDED_FUNCTIONS = {\n MONEY: formatMoney,\n CONCAT: (...args: any[]) => args.filter(v => v != null).join(''),\n IF: ifFn,\n FORMAT: (value: any) => {\n if (typeof value !== 'number') return String(value)\n return value.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })\n },\n SUBSTR: (str: string, start: number, len?: number) => String(str).slice(start, len ? start + len : undefined),\n LEN: (str: string) => String(str).length,\n ROUND: (num: number, decimals: number) => Number(Number(num).toFixed(decimals)),\n NOW: () => new Date().toISOString().split('T')[0],\n IFEMPTY: (value: any, defaultVal: string) => (value != null && value !== '' ? String(value) : defaultVal),\n PAD: (value: any, len: number, char: string) => String(value).padStart(len, char),\n REPLACE: (str: string, from: string, to: string) => String(str).replace(new RegExp(from, 'g'), to),\n JSON: (value: any) => JSON.stringify(value, null, 2),\n DATE: formatDate,\n UPPER: toUpperCaseAmount,\n} satisfies Record<string, (...args: any[]) => any>\n\n// 注册所有扩展函数到共享引擎\nfor (const [name, fn] of Object.entries(EXTENDED_FUNCTIONS)) {\n engine.registerFunction(name, fn)\n}\n\n// ─── 聚合函数 ───\n\nfunction aggregate(fn: string, field: string, rows: Record<string, any>[]): number {\n switch (fn.toUpperCase()) {\n case 'SUM': return sum(rows, field)\n case 'AVG': return avg(rows, field)\n case 'COUNT': return count(rows, field)\n case 'MIN': return min(rows, field)\n case 'MAX': return max(rows, field)\n default: return 0\n }\n}\n\n/**\n * 在受限沙箱内求值表达式\n * @param expr 表达式字符串\n * @param context 上下文变量\n * @param _callableNames 保留参数,实际使用共享引擎\n */\nexport function safeEval(expr: string, context: Record<string, any>, _callableNames?: string[]): any {\n return engine.evaluate(expr, context)\n}\n\n/**\n * 模板字符串求值:{表达式} 内 safeEval 求值,外为字面文本。\n * 聚合函数 SUM/AVG/COUNT/MIN/MAX(field) 预处理(需 ctx.rows)。\n * 单个 {expr} 求值失败时保留原 {expr} 文本。\n */\nexport function evaluateTemplate(text: string, ctx: Record<string, any>): string {\n if (!text) return ''\n if (!text.includes('{')) return text\n const rows: Record<string, any>[] = Array.isArray(ctx.rows) ? ctx.rows : []\n \n // 预处理聚合函数\n let processedText = text.replace(/\\{([^}]+)\\}/g, (_match, inner) => {\n let expr = inner.trim()\n // 聚合函数预处理:SUM(field) -> 数值字面量\n expr = expr.replace(/\\b(SUM|AVG|COUNT|MIN|MAX)\\(([^)]+)\\)/g, (_m: string, fn: string, arg: string) => {\n const field = arg.trim().replace(/^['\"]|['\"]$/g, '')\n return String(aggregate(fn, field, rows))\n })\n return `{${expr}}`\n })\n \n // 使用共享引擎渲染\n try {\n const result = engine.render(processedText, ctx)\n return result\n } catch {\n // 降级:保留原表达式\n return text\n }\n}\n","// web/src/components/print/utils/binding.ts\nimport type { RuntimeElement } from '../types'\nimport { createRuntimeElement } from './element-factory'\nimport { engine } from './engine'\nimport { DEFAULT_DEMO_DATA } from './demo-data'\nimport './expression-eval'\n\n/** 从业务字段创建带 formatter 绑定的文本元素 */\nexport function createFieldElement(field: { fieldKey: string; fieldLabel: string }): RuntimeElement {\n return createRuntimeElement('text', {\n formatter: `{${field.fieldKey}}`,\n title: field.fieldLabel,\n })\n}\n\n/** 非设计态文本内容解析:用共享引擎渲染 formatter */\nexport function resolveTextBinding(\n options: { formatter?: string },\n data?: Record<string, any>[],\n): string {\n if (options.formatter) {\n if (!data || data.length === 0) return ''\n const row = data[0]\n try {\n return engine.render(options.formatter, row ?? {})\n } catch {\n return options.formatter\n }\n }\n return ''\n}\n\n/** 按路径取 demo 数据值,数组节点取首项 */\nfunction lookupDemoPath(path: string): any {\n let cur: any = DEFAULT_DEMO_DATA\n for (const seg of path.split('.')) {\n if (cur == null) return undefined\n cur = Array.isArray(cur) ? cur[0]?.[seg] : cur[seg]\n }\n return cur\n}\n\n/**\n * 设计态条码/二维码单元格取值:{field} 占位符替换为 demo 数据\n * (列表字段取数据源首项,全局字段按路径取),无匹配回退通用示例码值\n */\nexport function resolveBarcodeDesignValue(\n formatter: string | undefined,\n listSource?: Record<string, any>[],\n): string {\n const first = listSource?.[0]\n const resolved = (formatter ?? '')\n .replace(/\\{([^{}]+)\\}/g, (_, expr: string) => {\n const key = expr.trim()\n const v = key.includes('.')\n ? lookupDemoPath(key)\n : (first?.[key] ?? lookupDemoPath(key))\n return v == null ? '' : String(v)\n })\n .trim()\n return resolved || '1234567890128'\n}\n","// web/src/components/print/utils/units.ts\n\n/** pt 转 mm */\nexport function ptToMm(pt: number): number {\n return pt / 2.83464566929\n}\n\n/** px 转 mm(基于 96dpi 屏幕) */\nexport function pxToMm(px: number): number {\n return px * (25.4 / 96)\n}\n","// web/src/components/print/utils/migrate.ts\n// 存量模板元素坐标 pt → mm 迁移(旧数据无 unit 标记,默认按 pt 处理)\nimport type { TemplateData, PrintElementData } from '../types'\nimport { ptToMm } from './units'\n\nconst PT_KEYS = ['left', 'top', 'width', 'height'] as const\n\nfunction convertElement(el: PrintElementData): PrintElementData {\n const options = { ...el.options }\n for (const key of PT_KEYS) {\n const v = options[key]\n if (typeof v === 'number' && Number.isFinite(v)) {\n ;(options as Record<string, unknown>)[key] = round2(ptToMm(v))\n }\n }\n return { ...el, options }\n}\n\nfunction round2(n: number): number {\n return Math.round(n * 100) / 100\n}\n\nexport function normalizeTemplateUnits(data: TemplateData): TemplateData {\n if (data.unit === 'mm') return data\n const convert = (els?: PrintElementData[]): PrintElementData[] => els?.map(convertElement) ?? []\n return {\n ...data,\n unit: 'mm',\n elements: convert(data.elements),\n header: data.header ? { ...data.header, elements: convert(data.header.elements) } : data.header,\n footer: data.footer ? { ...data.footer, elements: convert(data.footer.elements) } : data.footer,\n firstPageOverlay: data.firstPageOverlay\n ? { ...data.firstPageOverlay, elements: convert(data.firstPageOverlay.elements) }\n : data.firstPageOverlay,\n }\n}\n","// web/src/components/print/utils/default-config.ts\nimport type { TemplateData } from '../types'\n\nexport const PAPER_PRESETS: Record<string, { width: number; height: number }> = {\n A4: { width: 210, height: 297 },\n A3: { width: 297, height: 420 },\n A5: { width: 148, height: 210 },\n Letter: { width: 216, height: 279 },\n Legal: { width: 216, height: 356 },\n}\n\n/**\n * 获取纸张原始宽高(mm,未应用方向)\n * CUSTOM 时读取 customWidth/customHeight,缺省回退 A4\n */\nexport function getPaperDimensions(t: Pick<TemplateData, 'paperSize' | 'orientation' | 'customWidth' | 'customHeight'>): { width: number; height: number } {\n let base: { width: number; height: number }\n if (t.paperSize === 'CUSTOM') {\n base = {\n width: t.customWidth ?? 210,\n height: t.customHeight ?? 297,\n }\n } else {\n base = PAPER_PRESETS[t.paperSize] || PAPER_PRESETS['A4']!\n }\n return t.orientation === 'landscape'\n ? { width: base.height, height: base.width }\n : base\n}\n","// web/src/components/print/utils/scale.ts\n// 缩放计算纯函数\n\n/** 计算适应窗口的缩放百分比,clamp 到 [50,200] */\nexport function computeFitScale(\n containerW: number,\n containerH: number,\n paperW: number,\n paperH: number,\n ratio = 0.9,\n): number {\n if (paperW <= 0 || paperH <= 0) return 100\n const fit = Math.min(containerW / paperW, containerH / paperH) * ratio\n const pct = Math.round(fit * 100)\n return Math.min(200, Math.max(50, pct))\n}\n","// web/src/components/print/utils/zone-layout.ts\n// 页眉/页脚/内容三区几何计算与归区逻辑(区域元素坐标相对区域左上角,mm)\nimport type { RuntimeElement, TemplateData, ElementZone } from '../types'\nimport { getPaperDimensions } from './default-config'\n\n/** 允许放入页眉/页脚的元素类型 */\nexport const ZONE_ALLOWED_TYPES = ['text', 'image', 'hline', 'vline', 'rect', 'oval', 'barcode', 'qrcode']\n\nexport interface ZoneRectPt {\n left: number\n top: number\n width: number\n height: number\n}\n\n/** 纸张宽高(mm,含方向;CUSTOM 读取 customWidth/customHeight,缺省回退 A4) */\nexport function getPaperSizeMM(t: TemplateData): { width: number; height: number } {\n return getPaperDimensions(t)\n}\n\n/** 三区在纸面坐标系中的矩形(mm),布局:上边距→页眉→内容→页脚→下边距 */\nexport function getZoneRects(t: TemplateData): Record<ElementZone, ZoneRectPt> {\n const paper = getPaperSizeMM(t)\n const m = t.margins\n const headerH = t.header.height\n const footerH = t.footer.height\n const contentW = paper.width - m.left - m.right\n const contentH = paper.height - m.top - m.bottom - headerH - footerH\n const rect = (l: number, tp: number, w: number, h: number): ZoneRectPt => ({\n left: l, top: tp, width: w, height: h,\n })\n return {\n header: rect(m.left, m.top, contentW, headerH),\n content: rect(m.left, m.top + headerH, contentW, contentH),\n footer: rect(m.left, paper.height - m.bottom - footerH, contentW, footerH),\n }\n}\n\n/** 纸面 mm 坐标 → 命中区域(高度为 0 的区域不参与命中) */\nexport function zoneFromPaperPoint(t: TemplateData, _x: number, y: number): ElementZone {\n const r = getZoneRects(t)\n if (r.footer.height > 0 && y >= r.footer.top) return 'footer'\n if (r.header.height > 0 && y < r.header.top + r.header.height) return 'header'\n return 'content'\n}\n\n/** 将元素局部坐标 clamp 到区域矩形内(原地修改) */\nexport function clampToZone(el: RuntimeElement, zone: ZoneRectPt): void {\n const o = el.options\n o.width = Math.min(o.width, zone.width)\n o.height = Math.min(o.height, zone.height)\n o.left = Math.min(Math.max(0, o.left), zone.width - o.width)\n o.top = Math.min(Math.max(0, o.top), zone.height - o.height)\n}\n\n/**\n * 拖拽/缩放结束后按元素中心点归区:\n * 跨区时换算坐标并改写 zone;页眉/页脚内 clamp;类型不允许时拒绝跨入并 clamp 回内容区。\n */\nexport function finalizeElementZone(\n el: RuntimeElement,\n t: TemplateData,\n): { rejected: boolean } {\n const rects = getZoneRects(t)\n const fromZone: ElementZone = el.zone || 'content'\n const from = rects[fromZone]\n const cx = from.left + el.options.left + el.options.width / 2\n const cy = from.top + el.options.top + el.options.height / 2\n let target = zoneFromPaperPoint(t, cx, cy)\n let rejected = false\n if (target !== 'content' && !ZONE_ALLOWED_TYPES.includes(el.printElementType.type)) {\n target = 'content'\n rejected = true\n }\n if (target !== fromZone) {\n const to = rects[target]\n el.options.left = from.left + el.options.left - to.left\n el.options.top = from.top + el.options.top - to.top\n el.zone = target\n }\n if (target !== 'content') {\n clampToZone(el, rects[target])\n } else if (rejected) {\n clampToZone(el, rects.content)\n }\n return { rejected }\n}\n","// web/src/components/print/composables/useSelection.ts\nimport { ref, computed, type InjectionKey, type Ref } from 'vue'\nimport type { RuntimeElement } from '../types'\n\n/** 通过 provide/inject 共享选中状态,每个 BaseElement 精确追踪自身是否被选中 */\nexport const SELECTED_IDS_KEY: InjectionKey<Ref<Set<string>>> = Symbol('selected-ids')\n/** 框选实时预选状态:拖拽过程中高亮即将选中的元素,提交后转为正式选中 */\nexport const PREVIEW_IDS_KEY: InjectionKey<Ref<Set<string>>> = Symbol('preview-ids')\n\nexport function useSelection(elements: { value: RuntimeElement[] }) {\n const selectedIds = ref<Set<string>>(new Set())\n // 框选预选:拖拽中实时计算,提交时拷贝进 selectedIds\n const previewIds = ref<Set<string>>(new Set())\n\n const selectedElements = computed(() =>\n elements.value.filter(e => selectedIds.value.has(e.id))\n )\n\n const hasSelection = computed(() => selectedIds.value.size > 0)\n\n function select(id: string, multiple = false) {\n if (multiple) {\n const s = new Set(selectedIds.value)\n if (s.has(id)) { s.delete(id) } else { s.add(id) }\n selectedIds.value = s\n } else {\n selectedIds.value = new Set([id])\n }\n }\n\n function clearSelection() {\n selectedIds.value = new Set()\n }\n\n function selectAll(allIds: string[]) {\n selectedIds.value = new Set(allIds)\n }\n\n /** 设置框选预选集合(拖拽中实时调用) */\n function setPreview(ids: string[]) {\n previewIds.value = new Set(ids)\n }\n /** 清除预选 */\n function clearPreview() {\n previewIds.value = new Set()\n }\n /** 提交预选:将预选集合转为正式选中,并清空预选 */\n function commitPreview() {\n selectedIds.value = new Set(previewIds.value)\n previewIds.value = new Set()\n }\n\n function getSelectionBounds(): { left: number; top: number; width: number; height: number } | null {\n const els = selectedElements.value\n if (els.length === 0) return null\n let minL = Infinity, minT = Infinity, maxR = -Infinity, maxB = -Infinity\n els.forEach(e => {\n minL = Math.min(minL, e.options.left)\n minT = Math.min(minT, e.options.top)\n maxR = Math.max(maxR, e.options.left + e.options.width)\n maxB = Math.max(maxB, e.options.top + e.options.height)\n })\n return { left: minL, top: minT, width: maxR - minL, height: maxB - minT }\n }\n\n return { selectedIds, selectedElements, hasSelection, select, clearSelection, selectAll, getSelectionBounds, previewIds, setPreview, clearPreview, commitPreview }\n}\n","// web/src/components/print/composables/useClipboard.ts\nimport { ref } from 'vue'\nimport type { RuntimeElement, PrintElementData } from '../types'\nimport { generateId } from '../utils/element-factory'\n\nexport function useClipboard() {\n const clipboard = ref<PrintElementData[] | null>(null)\n\n function copy(elements: RuntimeElement[]) {\n clipboard.value = elements.map(e => ({\n options: { ...e.options },\n printElementType: { ...e.printElementType },\n }))\n }\n\n function paste(offset = 10): RuntimeElement[] | null {\n if (!clipboard.value) return null\n return clipboard.value.map(item => ({\n id: generateId(),\n options: {\n ...item.options,\n left: item.options.left + offset,\n top: item.options.top + offset,\n },\n printElementType: { ...item.printElementType },\n }))\n }\n\n function hasData() { return clipboard.value !== null && clipboard.value.length > 0 }\n\n return { clipboard, copy, paste, hasData }\n}\n","// web/src/components/print/composables/useAlign.ts\nimport type { RuntimeElement } from '../types'\n\nexport type AlignMode = 'left' | 'right' | 'top' | 'bottom' | 'vertical' | 'horizontal' | 'distributeHor' | 'distributeVer'\n\nexport function useAlign() {\n function align(elements: RuntimeElement[], mode: AlignMode) {\n if (elements.length < 2) return\n\n const bounds = {\n minLeft: Math.min(...elements.map(e => e.options.left)),\n maxRight: Math.max(...elements.map(e => e.options.left + e.options.width)),\n minTop: Math.min(...elements.map(e => e.options.top)),\n maxBottom: Math.max(...elements.map(e => e.options.top + e.options.height)),\n }\n\n switch (mode) {\n case 'left':\n elements.forEach(e => { e.options.left = bounds.minLeft })\n break\n case 'right':\n elements.forEach(e => { e.options.left = bounds.maxRight - e.options.width })\n break\n case 'top':\n elements.forEach(e => { e.options.top = bounds.minTop })\n break\n case 'bottom':\n elements.forEach(e => { e.options.top = bounds.maxBottom - e.options.height })\n break\n case 'vertical': {\n const centerX = bounds.minLeft + (bounds.maxRight - bounds.minLeft) / 2\n elements.forEach(e => { e.options.left = centerX - e.options.width / 2 })\n break\n }\n case 'horizontal': {\n const centerY = bounds.minTop + (bounds.maxBottom - bounds.minTop) / 2\n elements.forEach(e => { e.options.top = centerY - e.options.height / 2 })\n break\n }\n case 'distributeHor': {\n const sorted = [...elements].sort((a, b) => a.options.left - b.options.left)\n const totalW = sorted.reduce((s, e) => s + e.options.width, 0)\n const gap = (bounds.maxRight - bounds.minLeft - totalW) / (sorted.length - 1)\n let x = bounds.minLeft\n sorted.forEach(e => { e.options.left = x; x += e.options.width + gap })\n break\n }\n case 'distributeVer': {\n const sorted = [...elements].sort((a, b) => a.options.top - b.options.top)\n const totalH = sorted.reduce((s, e) => s + e.options.height, 0)\n const gap = (bounds.maxBottom - bounds.minTop - totalH) / (sorted.length - 1)\n let y = bounds.minTop\n sorted.forEach(e => { e.options.top = y; y += e.options.height + gap })\n break\n }\n }\n }\n\n return { align }\n}\n","// web/src/components/print/composables/useGroup.ts\n// 元素编组/组合逻辑\nimport type { RuntimeElement } from '../types'\n\nexport function generateGroupId(): string {\n return `grp-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`\n}\n\nexport function useGroup() {\n function group(elements: RuntimeElement[], selectedIds: Set<string>): RuntimeElement[] {\n const selected = elements.filter(e => selectedIds.has(e.id))\n if (selected.length < 2) return elements\n\n const groupId = generateGroupId()\n return elements.map(e =>\n selectedIds.has(e.id) ? { ...e, options: { ...e.options, groupId } } : e\n )\n }\n\n function ungroup(elements: RuntimeElement[], selectedIds: Set<string>): RuntimeElement[] {\n const selected = elements.filter(e => selectedIds.has(e.id))\n // 收集选中元素中涉及的 groupId\n const groupIds = new Set(selected.map(e => e.options.groupId).filter(Boolean))\n\n return elements.map(e =>\n e.options.groupId && groupIds.has(e.options.groupId)\n ? { ...e, options: { ...e.options, groupId: undefined } }\n : e\n )\n }\n\n /** 获取与选中元素同组的所有元素 ID */\n function getGroupedIds(elements: RuntimeElement[], selectedId: string): Set<string> {\n const el = elements.find(e => e.id === selectedId)\n if (!el?.options.groupId) return new Set([selectedId])\n\n const ids = new Set<string>()\n for (const e of elements) {\n if (e.options.groupId === el.options.groupId) {\n ids.add(e.id)\n }\n }\n return ids\n }\n\n return { group, ungroup, getGroupedIds }\n}\n","// web/src/components/print/composables/useHistory.ts\nimport { ref } from 'vue'\nimport type { TemplateData } from '../types'\n\nexport interface HistoryState {\n elements: any[]\n templateData?: TemplateData\n}\n\nexport interface UseHistoryOptions {\n /** 历史记录上限,默认 50 步 */\n maxSteps?: number\n /** 是否启用增量快照(减少内存占用),默认 false */\n useIncremental?: boolean\n}\n\n/**\n * 撤销/重做历史管理(操作级快照粒度)。\n *\n * 语义说明:\n * - `push(state)` 记录一次操作后的快照(检查点),并清空 redo 栈。\n * - `undo(currentState?)` 弹出栈顶检查点(当前状态)压入 redo 栈,\n * 返回新的栈顶(即上一个待恢复状态);栈空时返回 null。\n * - `redo(currentState?)` 弹出 redo 栈顶(待重做状态)压回 undo 栈并返回。\n * - 所有快照均做 JSON 深拷贝,避免外部对象突变污染历史。\n *\n * 调用约定:若希望\"撤销到初始状态\",应在首次操作前先 `push(initialState)`。\n */\nexport function useHistory(options?: UseHistoryOptions) {\n const maxSteps = options?.maxSteps ?? 50\n const useIncremental = options?.useIncremental ?? false\n const undoStack = ref<HistoryState[]>([])\n const redoStack = ref<HistoryState[]>([])\n\n const canUndo = ref(false)\n const canRedo = ref(false)\n\n function updateFlags() {\n canUndo.value = undoStack.value.length > 0\n canRedo.value = redoStack.value.length > 0\n }\n\n /** 深拷贝快照,避免外部对象突变污染历史 */\n function clone(state: HistoryState | undefined): HistoryState {\n return {\n elements: JSON.parse(JSON.stringify(state?.elements ?? [])),\n templateData: JSON.parse(JSON.stringify(state?.templateData ?? {})),\n }\n }\n\n /** 增量快照:只记录元素变更,templateData 只记录非 elements 部分 */\n function cloneIncremental(state: HistoryState): HistoryState {\n const clonedElements = JSON.parse(JSON.stringify(state.elements))\n const td = state.templateData\n if (!td) return { elements: clonedElements }\n return {\n elements: clonedElements,\n templateData: {\n paperSize: td.paperSize,\n orientation: td.orientation,\n margins: { ...td.margins },\n header: { height: td.header.height, elements: [] },\n footer: { height: td.footer.height, elements: [] },\n firstPageOverlay: { height: td.firstPageOverlay.height, elements: [] },\n elements: [], // 元素已在顶层存储\n customWidth: td.customWidth,\n customHeight: td.customHeight,\n watermark: td.watermark ? { ...td.watermark } : undefined,\n guides: td.guides ? [...td.guides] : undefined,\n },\n }\n }\n\n function cloneState(state: HistoryState): HistoryState {\n return useIncremental ? cloneIncremental(state) : clone(state)\n }\n\n /** 记录操作后快照(深拷贝),并清空 redo 栈 */\n function push(state: HistoryState) {\n undoStack.value.push(cloneState(state))\n // 新操作清空 redo 栈\n redoStack.value = []\n // 超出上限丢弃最早\n if (undoStack.value.length > maxSteps) {\n undoStack.value.shift()\n }\n updateFlags()\n }\n\n /**\n * 撤销:弹出当前栈顶检查点(压入 redo 栈),返回上一个待恢复状态。\n * @param currentState 可选,若提供则用其替代弹出的检查点压入 redo 栈\n * (显式传入当前实时状态时使用)\n */\n function undo(currentState?: HistoryState): HistoryState | null {\n if (undoStack.value.length === 0) return null\n const popped = undoStack.value.pop()!\n redoStack.value.push(currentState ? cloneState(currentState) : clone(popped))\n updateFlags()\n // 返回新的栈顶(上一个待恢复状态);栈空表示无更早历史\n return undoStack.value.length > 0\n ? clone(undoStack.value[undoStack.value.length - 1])\n : null\n }\n\n /**\n * 重做:弹出 redo 栈顶(待重做状态)压回 undo 栈并返回。\n * @param currentState 可选,若提供则用其替代弹出的状态压回 undo 栈\n */\n function redo(currentState?: HistoryState): HistoryState | null {\n if (redoStack.value.length === 0) return null\n const popped = redoStack.value.pop()!\n undoStack.value.push(currentState ? cloneState(currentState) : clone(popped))\n updateFlags()\n return clone(popped)\n }\n\n /** 清空全部历史 */\n function clear() {\n undoStack.value = []\n redoStack.value = []\n updateFlags()\n }\n\n return { push, undo, redo, canUndo, canRedo, clear }\n}\n","// web/src/components/print/composables/useKeyboard.ts\n\nexport interface KeyboardHandlers {\n onMove?: (dx: number, dy: number) => void\n onDelete?: () => void\n onCopy?: () => void\n onPaste?: () => void\n onSelectAll?: () => void\n onUndo?: () => void\n onRedo?: () => void\n onDuplicate?: () => void\n onResetZoom?: () => void\n onAlignLeft?: () => void\n onAlignRight?: () => void\n onAlignCenterH?: () => void\n onAlignTop?: () => void\n onAlignBottom?: () => void\n onGroup?: () => void\n onUngroup?: () => void\n}\n\nconst STEP = 1 // mm\nconst STEP_LARGE = 10\nconst STEP_SMALL = 0.5\n\nexport function useKeyboard(handlers: KeyboardHandlers) {\n function onKeyDown(e: KeyboardEvent) {\n const tag = (e.target as HTMLElement).tagName\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return\n\n const ctrl = e.ctrlKey || e.metaKey\n\n // 方向键:Shift=大步,Ctrl=微步,默认标准步\n if (e.key.startsWith('Arrow')) {\n e.preventDefault()\n const step = e.shiftKey ? STEP_LARGE : e.ctrlKey ? STEP_SMALL : STEP\n const dx = e.key === 'ArrowLeft' ? -step : e.key === 'ArrowRight' ? step : 0\n const dy = e.key === 'ArrowUp' ? -step : e.key === 'ArrowDown' ? step : 0\n handlers.onMove?.(dx, dy)\n return\n }\n\n if (e.key === 'Delete' || e.key === 'Backspace') {\n e.preventDefault()\n handlers.onDelete?.()\n return\n }\n\n // Ctrl+0 适应窗口需容器尺寸,由 PrintDesigner 单独监听,此处不处理\n if (ctrl) {\n const k = e.key.toLowerCase()\n if (k === 'c') { e.preventDefault(); handlers.onCopy?.() }\n else if (k === 'v') { e.preventDefault(); handlers.onPaste?.() }\n else if (k === 'a') { e.preventDefault(); handlers.onSelectAll?.() }\n else if (k === 'd') { e.preventDefault(); handlers.onDuplicate?.() }\n else if (k === 'z') { e.preventDefault(); e.shiftKey ? handlers.onRedo?.() : handlers.onUndo?.() }\n else if (k === 'y') { e.preventDefault(); handlers.onRedo?.() }\n else if (k === '1') { e.preventDefault(); handlers.onResetZoom?.() }\n else if (k === 'l') { e.preventDefault(); handlers.onAlignLeft?.() }\n else if (k === 'r') { e.preventDefault(); handlers.onAlignRight?.() }\n else if (k === 'e') { e.preventDefault(); handlers.onAlignCenterH?.() }\n else if (k === 't') { e.preventDefault(); handlers.onAlignTop?.() }\n else if (k === 'b') { e.preventDefault(); handlers.onAlignBottom?.() }\n else if (k === 'g') { e.preventDefault(); e.shiftKey ? handlers.onUngroup?.() : handlers.onGroup?.() }\n }\n }\n\n function setup() { document.addEventListener('keydown', onKeyDown) }\n function cleanup() { document.removeEventListener('keydown', onKeyDown) }\n\n return { setup, cleanup }\n}\n","// web/src/components/print/composables/useDesignerState.ts\n// 设计器核心状态管理:模板数据/选择/历史/剪贴板/编组/键盘/序列化\nimport { ref, computed, onMounted, onUnmounted } from 'vue'\nimport type {\n RuntimeElement, ElementType, ElementZone, PrintBusinessField, TemplateData,\n TableSelection, PrintElementData,\n} from '../types'\nimport { createRuntimeElement, generateId } from '../utils/element-factory'\nimport { createFieldElement } from '../utils/binding'\nimport { normalizeTemplateUnits } from '../utils/migrate'\nimport { syncTableElementSize } from '../utils/table-matrix'\nimport { getPaperDimensions } from '../utils/default-config'\nimport { computeFitScale } from '../utils/scale'\nimport {\n getZoneRects, zoneFromPaperPoint, clampToZone, finalizeElementZone, ZONE_ALLOWED_TYPES,\n} from '../utils/zone-layout'\nimport { useSelection } from './useSelection'\nimport { useClipboard } from './useClipboard'\nimport { useAlign, type AlignMode } from './useAlign'\nimport { useGroup } from './useGroup'\nimport { useHistory, type HistoryState } from './useHistory'\nimport { useKeyboard } from './useKeyboard'\n\nexport interface DesignerStateOptions {\n initialTemplate?: TemplateData\n initialElements?: RuntimeElement[]\n initialFields?: PrintBusinessField[]\n}\n\n/** 创建默认模板数据 */\nexport function createDefaultTemplate(): TemplateData {\n return {\n paperSize: 'A4',\n orientation: 'portrait',\n unit: 'mm',\n margins: { top: 10, right: 10, bottom: 10, left: 10 },\n header: { height: 10, elements: [] },\n footer: { height: 10, elements: [] },\n firstPageOverlay: { height: 0, elements: [] },\n elements: [],\n watermark: {},\n }\n}\n\n/** 三区元素合并为统一运行时元素池(补建 id、打 zone 标) */\nexport function toRuntimePool(data: TemplateData): TemplateData {\n const mk = (els: PrintElementData[], zone: ElementZone): RuntimeElement[] =>\n (els ?? []).map(e => {\n const options = { ...e.options }\n // 表格尺寸恒由列宽/行高派生(mm),加载时重算以自愈历史污染数据\n if ((e.printElementType?.type ?? e.type) === 'table') {\n syncTableElementSize(options)\n }\n return {\n id: e.id || generateId(),\n zone,\n options,\n printElementType: { ...e.printElementType },\n }\n })\n return {\n ...data,\n margins: { ...data.margins },\n header: { height: data.header?.height ?? 10, elements: [] },\n footer: { height: data.footer?.height ?? 10, elements: [] },\n firstPageOverlay: {\n height: data.firstPageOverlay?.height ?? 0,\n elements: [...(data.firstPageOverlay?.elements ?? [])],\n },\n guides: [...(data.guides ?? [])],\n elements: [\n ...mk(data.elements ?? [], 'content'),\n ...mk(data.header?.elements ?? [], 'header'),\n ...mk(data.footer?.elements ?? [], 'footer'),\n ],\n }\n}\n\nexport function useDesignerState(options: DesignerStateOptions = {}) {\n const scale = ref(100)\n const showGrid = ref(true)\n const snapToGrid = ref(false)\n // 设计态下无边框表格单元格的虚拟虚线边框开关(默认开启)\n const showTableGhostBorder = ref(true)\n\n // 单一模板状态(三区元素归一化进运行时元素池)\n const templateData = ref<TemplateData>(\n toRuntimePool(options.initialTemplate || createDefaultTemplate())\n )\n\n // 内容区主体元素(快捷访问)\n // 优化:setter 直接修改 elements 属性,避免展开替换整个 templateData 触发全量通知\n const elements = computed({\n get: () => templateData.value.elements as RuntimeElement[],\n set: (els: RuntimeElement[]) => {\n templateData.value.elements = els\n },\n })\n\n const fields = ref<PrintBusinessField[]>(options.initialFields || [])\n\n const { selectedIds, selectedElements, select, clearSelection, selectAll: selectAllIds, previewIds, setPreview, clearPreview, commitPreview } = useSelection(elements)\n\n // 编组\n const { group: groupElements, ungroup: ungroupElements } = useGroup()\n\n // 复制粘贴 / 对齐 / 撤销重做\n const { copy: copyElements, paste: pasteElements, hasData: hasClipboardData } = useClipboard()\n const { align } = useAlign()\n const { push: pushHistory, undo: undoHistory, redo: redoHistory, canUndo, canRedo } = useHistory()\n\n const selectedElement = computed(() => {\n if (selectedIds.value.size === 0) return null\n const id = selectedIds.value.values().next().value\n return elements.value.find(e => e.id === id) || null\n })\n\n // 表格单元格选区(Excel 风格表格编辑)\n const tableSelection = ref<TableSelection | null>(null)\n function setTableSelection(s: TableSelection | null) {\n tableSelection.value = s\n }\n\n /** 当前设计器状态的深拷贝快照(用于历史记录) */\n function getHistoryState(): HistoryState {\n return {\n elements: elements.value.map(e => ({\n id: e.id,\n zone: e.zone,\n // JSON 深拷贝:tableRows 等嵌套结构若浅拷会在撤销时共享引用\n options: JSON.parse(JSON.stringify(e.options)),\n printElementType: { ...e.printElementType },\n })),\n templateData: {\n paperSize: templateData.value.paperSize,\n orientation: templateData.value.orientation,\n margins: { ...templateData.value.margins },\n header: { height: templateData.value.header.height, elements: [] },\n footer: { height: templateData.value.footer.height, elements: [] },\n firstPageOverlay: { height: templateData.value.firstPageOverlay.height, elements: [] },\n elements: [], // 元素已在顶层存储,避免重复\n customWidth: templateData.value.customWidth,\n customHeight: templateData.value.customHeight,\n watermark: templateData.value.watermark ? { ...templateData.value.watermark } : undefined,\n guides: [...(templateData.value.guides ?? [])],\n },\n }\n }\n\n function recordHistory() {\n pushHistory(getHistoryState())\n }\n\n function undo() {\n const state = undoHistory(getHistoryState())\n if (state?.templateData) {\n templateData.value = { ...state.templateData, elements: state.elements }\n }\n }\n\n function redo() {\n const state = redoHistory(getHistoryState())\n if (state?.templateData) {\n templateData.value = { ...state.templateData, elements: state.elements }\n }\n }\n\n function copy() {\n copyElements(selectedElements.value)\n }\n\n /** 剪切:复制到剪贴板后删除选中元素 */\n function cutSelected() {\n copyElements(selectedElements.value)\n deleteSelected()\n }\n\n function paste() {\n const pasted = pasteElements()\n if (pasted && pasted.length > 0) {\n elements.value.push(...pasted)\n recordHistory()\n }\n }\n\n /** Ctrl+D 原地复制:复用剪贴板克隆选中元素,叠加小幅偏移 */\n function duplicateSelected() {\n copyElements(selectedElements.value)\n const pasted = pasteElements()\n if (pasted && pasted.length > 0) {\n pasted.forEach(e => { e.options.left += 5; e.options.top += 5 })\n elements.value.push(...pasted)\n select(pasted[0]!.id, false)\n recordHistory()\n }\n }\n\n /** Ctrl+1 重置缩放至 100% */\n function resetZoom() {\n scale.value = 100\n }\n\n const hasClipboard = computed(() => hasClipboardData())\n\n let moveSessionActive = false\n let moveDebounceTimer: ReturnType<typeof setTimeout> | null = null\n const MOVE_SESSION_GAP_MS = 300\n\n function moveSelected(dx: number, dy: number) {\n const movable = selectedElements.value.filter(e => !e.options.locked)\n if (movable.length === 0) return\n movable.forEach(e => {\n e.options.left += dx\n e.options.top += dy\n })\n if (!moveSessionActive) {\n moveSessionActive = true\n recordHistory()\n }\n if (moveDebounceTimer) clearTimeout(moveDebounceTimer)\n moveDebounceTimer = setTimeout(() => {\n moveSessionActive = false\n moveDebounceTimer = null\n }, MOVE_SESSION_GAP_MS)\n }\n\n function selectAll() {\n selectAllIds(elements.value.map(e => e.id))\n }\n\n function alignSelected(mode: AlignMode) {\n align(selectedElements.value, mode)\n recordHistory()\n }\n\n function groupSelected() {\n elements.value = groupElements(elements.value, selectedIds.value)\n recordHistory()\n }\n\n function ungroupSelected() {\n elements.value = ungroupElements(elements.value, selectedIds.value)\n recordHistory()\n }\n\n function deleteSelected() {\n if (selectedIds.value.size === 0) return\n elements.value = elements.value.filter(e => !selectedIds.value.has(e.id))\n clearSelection()\n recordHistory()\n }\n\n // 键盘快捷键\n const { setup: setupKeyboard, cleanup: cleanupKeyboard } = useKeyboard({\n onMove: moveSelected,\n onDelete: deleteSelected,\n onCopy: copy,\n onPaste: paste,\n onSelectAll: selectAll,\n onUndo: undo,\n onRedo: redo,\n onDuplicate: duplicateSelected,\n onResetZoom: resetZoom,\n // 多选对齐快捷键:Ctrl+L 左对齐 / Ctrl+R 右对齐 / Ctrl+E 水平居中 / Ctrl+T 顶对齐 / Ctrl+B 底对齐\n onAlignLeft: () => alignSelected('left'),\n onAlignRight: () => alignSelected('right'),\n onAlignCenterH: () => alignSelected('vertical'),\n onAlignTop: () => alignSelected('top'),\n onAlignBottom: () => alignSelected('bottom'),\n // 编组快捷键:Ctrl+G 组合 / Ctrl+Shift+G 取消组合\n onGroup: groupSelected,\n onUngroup: ungroupSelected,\n })\n\n let draggingBeforeState: HistoryState | null = null\n\n function dragStart() {\n draggingBeforeState = getHistoryState()\n }\n\n function dragStop() {\n if (!draggingBeforeState) return\n // 拖拽/缩放结束:对位置或尺寸变化的元素做归区收尾(跨区换算 + 区域 clamp)\n const before = new Map(draggingBeforeState.elements.map(e => [e.id, e]))\n let rejected = false\n for (const el of elements.value) {\n const prev = before.get(el.id)\n if (!prev) continue\n const moved = prev.options.left !== el.options.left\n || prev.options.top !== el.options.top\n || prev.options.width !== el.options.width\n || prev.options.height !== el.options.height\n if (moved && finalizeElementZone(el, templateData.value).rejected) {\n rejected = true\n }\n }\n if (rejected) {\n alert('该元素类型不能放入页眉/页脚')\n }\n const sig = (e: RuntimeElement) =>\n `${e.id}:${e.zone || 'content'}:${e.options.left},${e.options.top},${e.options.width},${e.options.height}`\n const beforeIds = draggingBeforeState.elements.map(sig).join('|')\n const afterIds = getHistoryState().elements.map(sig).join('|')\n draggingBeforeState = null\n if (beforeIds !== afterIds) {\n recordHistory()\n }\n }\n\n /** 按落点将新元素放入对应区域;页眉/页脚不允许的类型拒绝并提示 */\n function placeAtDropPoint(el: RuntimeElement, dropPoint: { x: number; y: number }): boolean {\n // dropPoint 为 mm(由 CanvasArea.toPaperPoint 返回)\n const zone = zoneFromPaperPoint(templateData.value, dropPoint.x, dropPoint.y)\n if (zone !== 'content' && !ZONE_ALLOWED_TYPES.includes(el.printElementType.type)) {\n alert('该元素类型不能放入页眉/页脚')\n return false\n }\n const rect = getZoneRects(templateData.value)[zone] // mm\n el.zone = zone\n // 元素 options 以 mm 存储:落点相对区域左上角的偏移即 mm 坐标\n el.options.left = dropPoint.x - rect.left\n el.options.top = dropPoint.y - rect.top\n if (zone !== 'content') {\n clampToZone(el, rect)\n }\n return true\n }\n\n function addElement(type: string, dropPoint?: { x: number; y: number }) {\n const el = createRuntimeElement(type as ElementType)\n if (dropPoint && !placeAtDropPoint(el, dropPoint)) return\n elements.value.push(el)\n select(el.id, false)\n recordHistory()\n }\n\n function addFieldElement(field: { fieldKey: string; fieldLabel: string }, dropPoint?: { x: number; y: number }) {\n const el = createFieldElement(field)\n if (dropPoint && !placeAtDropPoint(el, dropPoint)) return\n elements.value.push(el)\n select(el.id, false)\n recordHistory()\n }\n\n function moveLayer(direction: string) {\n if (selectedIds.value.size === 0) return\n const id = selectedIds.value.values().next().value\n const el = elements.value.find(e => e.id === id)\n if (!el) return\n const currentZ = el.options.zIndex ?? 0\n const allZ = elements.value.map(e => e.options.zIndex ?? 0)\n const maxZ = Math.max(...allZ, 0)\n const minZ = Math.min(...allZ, 0)\n switch (direction) {\n case 'top': el.options.zIndex = maxZ + 1; break\n case 'bottom': el.options.zIndex = minZ - 1; break\n case 'up': el.options.zIndex = currentZ + 1; break\n case 'down': el.options.zIndex = currentZ - 1; break\n }\n recordHistory()\n }\n\n /** 适应窗口:根据容器尺寸(px)与纸张尺寸(mm->px)计算缩放 */\n function fitToWindow(containerW: number, containerH: number) {\n const { width, height } = getPaperDimensions(templateData.value)\n const MM_TO_PX = 96 / 25.4\n scale.value = computeFitScale(containerW, containerH, width * MM_TO_PX, height * MM_TO_PX)\n }\n\n function updateTemplateData(data: TemplateData) {\n templateData.value = { ...data }\n recordHistory()\n }\n\n /** 当前设计器状态序列化为模板 JSON(单一出口,按 zone 拆回三区,保留 id/type 供渲染服务使用) */\n function getTemplateJson(): TemplateData {\n const all = elements.value\n const ser = (zone: ElementZone) => all\n .filter(e => (e.zone || 'content') === zone)\n .map(e => ({\n id: e.id,\n type: e.printElementType.type,\n options: { ...e.options },\n printElementType: { ...e.printElementType },\n }))\n return {\n unit: 'mm' as const,\n ...templateData.value,\n header: { ...templateData.value.header, elements: ser('header') },\n footer: { ...templateData.value.footer, elements: ser('footer') },\n // 首页叠加层也需补 id/type\n firstPageOverlay: {\n ...templateData.value.firstPageOverlay,\n elements: templateData.value.firstPageOverlay.elements.map(e => ({\n id: e.id || generateId(),\n type: e.printElementType?.type || 'text',\n options: { ...e.options },\n printElementType: { ...e.printElementType },\n })),\n },\n elements: ser('content'),\n guides: [...(templateData.value.guides ?? [])],\n }\n }\n\n /** 加载模板数据(三区合并进运行时元素池;旧数据按 pt 迁移为 mm) */\n function loadTemplate(data: TemplateData, els?: RuntimeElement[]) {\n const migrated = normalizeTemplateUnits(data)\n templateData.value = toRuntimePool(migrated)\n if (els) {\n templateData.value = {\n ...templateData.value,\n elements: els.map(e => ({\n ...e,\n id: e.id || generateId(),\n zone: e.zone || 'content',\n options: { ...e.options },\n printElementType: { ...e.printElementType },\n })),\n }\n }\n pushHistory(getHistoryState())\n }\n\n // 记录设计器初始状态快照\n pushHistory(getHistoryState())\n\n onMounted(() => setupKeyboard())\n onUnmounted(() => {\n cleanupKeyboard()\n if (moveDebounceTimer) {\n clearTimeout(moveDebounceTimer)\n moveDebounceTimer = null\n }\n })\n\n return {\n scale, showGrid, snapToGrid, showTableGhostBorder,\n templateData, elements, fields,\n selectedIds, selectedElements, selectedElement, select, clearSelection, selectAll,\n previewIds, setPreview, clearPreview, commitPreview,\n hasClipboard, copy, paste, cutSelected,\n tableSelection, setTableSelection,\n canUndo, canRedo, undo, redo,\n recordHistory,\n alignSelected, groupSelected, ungroupSelected, deleteSelected,\n duplicateSelected, resetZoom,\n dragStart, dragStop,\n addElement, addFieldElement, moveLayer, fitToWindow, updateTemplateData,\n getTemplateJson, loadTemplate,\n }\n}\n","// web/src/components/print/composables/useGuides.ts\n// 手动参考线管理:增删改 + 吸附目标生成,增删改入历史栈\nimport { computed, type Ref } from 'vue'\nimport type { TemplateData, AlignLine } from '../types'\n\nlet guideSeq = 0\nfunction genId(): string {\n guideSeq += 1\n return `guide-${guideSeq}`\n}\n\nexport function useGuides(templateData: Ref<TemplateData>, recordHistory: () => void) {\n const guides = computed(() => templateData.value.guides ?? [])\n\n function mutate(fn: (list: AlignLine[]) => AlignLine[]) {\n templateData.value = {\n ...templateData.value,\n guides: fn([...(templateData.value.guides ?? [])]),\n }\n recordHistory()\n }\n\n function addGuide(type: 'vertical' | 'horizontal', position: number) {\n mutate(list => { list.push({ type, position, id: genId() }); return list })\n }\n function moveGuide(id: string, position: number) {\n mutate(list => list.map(g => g.id === id ? { ...g, position } : g))\n }\n function removeGuide(id: string) {\n mutate(list => list.filter(g => g.id !== id))\n }\n function getGuidePositions(): { vertical: number[]; horizontal: number[] } {\n const v: number[] = [], h: number[] = []\n for (const g of guides.value) {\n if (g.type === 'vertical') v.push(g.position)\n else h.push(g.position)\n }\n return { vertical: v, horizontal: h }\n }\n\n return { guides, addGuide, moveGuide, removeGuide, getGuidePositions }\n}\n","// 表格单元格选区跨组件共享契约:PrintDesigner provide,TableElement/PropertyPanel inject\nimport type { InjectionKey, Ref } from 'vue'\nimport type { TableSelection } from '../types'\n\nexport interface TableEditContext {\n tableSelection: Ref<TableSelection | null>\n setTableSelection: (s: TableSelection | null) => void\n recordHistory: () => void\n /** 页面打印范围宽度(mm)= 纸宽 - 左右边距,表格总列宽不得超过 */\n maxTableWidth: Ref<number>\n}\n\nexport const TABLE_EDIT_KEY: InjectionKey<TableEditContext> = Symbol('table-edit')\n","// 宿主能力注入键:开源核心不直接发请求、不内置业务字典,相关能力/数据由\n// PrintDesigner 经 props 接收后 provide,深层组件通过 inject 获取。\nimport type { ComputedRef, InjectionKey } from 'vue'\nimport type { UploadImageFn } from '../types'\n\n/** 图片上传适配器:PrintDesigner provide,ImageContentUpload inject */\nexport const UPLOAD_IMAGE_KEY: InjectionKey<ComputedRef<UploadImageFn | undefined>> =\n Symbol('print-upload-image')\n","<template>\n <div class=\"designer-toolbar\">\n <!-- 文件 -->\n <div class=\"tb-group\">\n <button class=\"tb-btn tb-icon\" title=\"返回\" @click=\"$emit('back')\">←</button>\n <span class=\"tb-mark\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"5\" y=\"3\" width=\"14\" height=\"18\" rx=\"2.5\" />\n <line x1=\"8.5\" y1=\"8.5\" x2=\"15.5\" y2=\"8.5\" />\n <line x1=\"8.5\" y1=\"12.5\" x2=\"15.5\" y2=\"12.5\" />\n <line x1=\"8.5\" y1=\"16.5\" x2=\"12.5\" y2=\"16.5\" />\n </svg>\n </span>\n <div class=\"tb-title\">\n <span class=\"tb-title-name\">{{ isEdit ? '编辑模板' : '新建模板' }}</span>\n <span class=\"tb-title-sub\">印刷工作台</span>\n </div>\n </div>\n <!-- 编辑 -->\n <div class=\"tb-group\">\n <button class=\"tb-btn tb-icon\" :disabled=\"!canUndo\" @click=\"$emit('undo')\" title=\"撤销\">↶</button>\n <button class=\"tb-btn tb-icon\" :disabled=\"!canRedo\" @click=\"$emit('redo')\" title=\"重做\">↷</button>\n </div>\n <!-- 对齐分布(多选) -->\n <div class=\"tb-group\" v-if=\"hasMultiSelection\">\n <button class=\"tb-btn tb-icon\" @click=\"$emit('align', 'left')\" title=\"左对齐\">⇤</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('align', 'right')\" title=\"右对齐\">⇥</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('align', 'top')\" title=\"顶对齐\">⇡</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('align', 'bottom')\" title=\"底对齐\">⇣</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('align', 'vertical')\" title=\"水平居中\">↔</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('align', 'horizontal')\" title=\"垂直居中\">↕</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('align', 'distributeHor')\" title=\"水平分布\">⇔</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('align', 'distributeVer')\" title=\"垂直分布\">⇕</button>\n </div>\n <!-- 组合 -->\n <div class=\"tb-group\" v-if=\"hasMultiSelection\">\n <button class=\"tb-btn\" @click=\"$emit('group')\" title=\"组合\">组合</button>\n </div>\n <div class=\"tb-group\" v-if=\"!hasMultiSelection && selectedElementHasGroup\">\n <button class=\"tb-btn\" @click=\"$emit('ungroup')\" title=\"取消组合\">取消组合</button>\n </div>\n <!-- 层级 -->\n <div class=\"tb-group\" v-if=\"hasSelection\">\n <button class=\"tb-btn tb-icon\" @click=\"$emit('move-layer', 'top')\" title=\"置顶\">⤒</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('move-layer', 'up')\" title=\"上移\">↑</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('move-layer', 'down')\" title=\"下移\">↓</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('move-layer', 'bottom')\" title=\"置底\">⤓</button>\n </div>\n <!-- 视图 -->\n <div class=\"tb-group\">\n <button class=\"tb-btn\" :class=\"{ on: showGrid }\" @click=\"$emit('toggle-grid')\">\n <span class=\"dot\" /> 网格\n </button>\n <button class=\"tb-btn\" :class=\"{ on: showTableGhostBorder }\" title=\"显示/隐藏无边框表格的虚拟虚线\" @click=\"$emit('toggle-table-ghost-border')\">\n <span class=\"dot\" /> 虚框\n </button>\n <button class=\"tb-btn\" :class=\"{ on: snapToGrid }\" @click=\"$emit('toggle-snap')\">\n <span class=\"dot\" /> 吸附\n </button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('fit-window')\" title=\"适应窗口\">⤢</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('zoom', -10)\" title=\"缩小\">−</button>\n <span class=\"tb-zoom\">{{ scale }}%</span>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('zoom', 10)\" title=\"放大\">+</button>\n </div>\n <!-- 操作 -->\n <div class=\"tb-spacer\" />\n <div class=\"tb-group\">\n <button class=\"tb-btn\" @click=\"$emit('add-overlay-element')\">首页专属</button>\n <button class=\"tb-btn\" :class=\"{ warn: overlayVisible }\" @click=\"$emit('toggle-overlay')\">叠层对比</button>\n </div>\n <div class=\"tb-group\">\n <button v-if=\"showLoadDefault\" class=\"btn-secondary\" @click=\"$emit('load-default')\">加载默认布局</button>\n <button class=\"btn-secondary\" @click=\"$emit('preview')\">预览</button>\n <button class=\"btn-primary\" @click=\"$emit('save')\">保存</button>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nconst scale = defineModel<number>('scale', { default: 100 })\n\ndefineProps<{\n isEdit?: boolean\n canUndo?: boolean\n canRedo?: boolean\n hasMultiSelection?: boolean\n hasSelection?: boolean\n showGrid?: boolean\n snapToGrid?: boolean\n showTableGhostBorder?: boolean\n selectedElementHasGroup?: boolean\n overlayVisible?: boolean\n /** 是否展示「加载默认布局」按钮(宿主注入 loadDefaultTemplate 时由 PrintDesigner 开启) */\n showLoadDefault?: boolean\n}>()\n\ndefineEmits<{\n back: []\n preview: []\n save: []\n 'load-default': []\n undo: []\n redo: []\n align: [mode: string]\n 'move-layer': [direction: string]\n 'toggle-grid': []\n 'toggle-snap': []\n 'toggle-table-ghost-border': []\n 'toggle-overlay': []\n group: []\n ungroup: []\n 'add-overlay-element': []\n 'fit-window': []\n zoom: [delta: number]\n}>()\n</script>\n\n<style scoped>\n.designer-toolbar {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 0 12px;\n height: 50px;\n background: var(--pd-surface, #ffffff);\n border-bottom: 1px solid var(--pd-border-soft, #e9ecf2);\n box-shadow: 0 1px 2px rgba(23, 32, 60, .04), 0 6px 16px -12px rgba(23, 32, 60, .25);\n flex-shrink: 0;\n position: relative;\n z-index: 20;\n}\n.tb-group {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 0 8px;\n}\n.tb-group + .tb-group {\n border-left: 1px solid var(--pd-border-soft, #e9ecf2);\n}\n.tb-btn {\n height: 30px;\n min-width: 30px;\n padding: 0 8px;\n border-radius: 6px;\n border: 1px solid transparent;\n background: transparent;\n color: var(--pd-text-muted, #8b909c);\n font-size: 12px;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 5px;\n transition: background .14s ease, color .14s ease, border-color .14s ease, box-shadow .14s ease;\n}\n.tb-btn:hover {\n color: var(--pd-text, #2a2e37);\n background: var(--pd-sidebar-hover, #f0f3f9);\n}\n.tb-btn:active {\n background: var(--pd-border-soft, #e9ecf2);\n}\n.tb-btn:disabled {\n opacity: .32;\n cursor: default;\n background: transparent;\n color: var(--pd-text-faint, #b4b9c4);\n}\n.tb-btn.on {\n color: var(--pd-accent, #165DFF);\n background: var(--pd-accent-soft, rgba(22, 93, 255, .09));\n font-weight: 600;\n}\n.tb-btn.warn {\n color: var(--pd-accent-secondary, #f56c6c);\n background: var(--pd-danger-soft, rgba(245, 108, 108, .10));\n font-weight: 600;\n}\n.tb-btn .dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--pd-text-faint, #b4b9c4);\n display: inline-block;\n transition: background .14s ease, box-shadow .14s ease;\n}\n.tb-btn.on .dot {\n background: var(--pd-accent, #165DFF);\n box-shadow: 0 0 0 3px rgba(22, 93, 255, .12);\n}\n.tb-icon {\n font-size: 15px;\n line-height: 1;\n}\n.tb-mark {\n width: 28px;\n height: 28px;\n margin-right: 2px;\n border-radius: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: #fff;\n background: linear-gradient(150deg, var(--pd-accent-2, #3D7BFF), var(--pd-accent, #165DFF));\n box-shadow: 0 3px 8px rgba(22, 93, 255, .28), inset 0 1px 0 rgba(255, 255, 255, .22);\n flex-shrink: 0;\n}\n.tb-mark svg {\n width: 16px;\n height: 16px;\n}\n.tb-title {\n display: flex;\n flex-direction: column;\n line-height: 1.2;\n padding-left: 6px;\n}\n.tb-title-name {\n font-size: 13px;\n font-weight: 600;\n color: var(--pd-text, #2a2e37);\n letter-spacing: .2px;\n}\n.tb-title-sub {\n font-size: 10px;\n color: var(--pd-text-muted, #8b909c);\n letter-spacing: .8px;\n}\n.tb-zoom {\n font-size: 12px;\n color: var(--pd-text, #2a2e37);\n font-variant-numeric: tabular-nums;\n min-width: 46px;\n text-align: center;\n}\n.tb-spacer {\n flex: 1;\n}\n.btn-primary,\n.btn-secondary {\n height: 32px;\n padding: 0 16px;\n border-radius: 7px;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: filter .14s ease, background .14s ease, border-color .14s ease, box-shadow .14s ease;\n}\n.btn-secondary {\n background: var(--pd-field-bg, #f4f6fa);\n color: var(--pd-text-muted, #606266);\n border: 1px solid var(--pd-border, #d9dde6);\n}\n.btn-secondary:hover {\n border-color: var(--pd-accent, #165DFF);\n color: var(--pd-accent, #165DFF);\n background: var(--pd-accent-soft, rgba(22, 93, 255, .06));\n}\n.btn-primary {\n background: linear-gradient(180deg, var(--pd-accent-2, #3D7BFF), var(--pd-accent, #165DFF));\n color: #fff;\n border: none;\n box-shadow: 0 3px 10px rgba(22, 93, 255, .28), inset 0 1px 0 rgba(255, 255, 255, .18);\n}\n.btn-primary:hover {\n filter: brightness(1.07);\n box-shadow: 0 5px 14px rgba(22, 93, 255, .34), inset 0 1px 0 rgba(255, 255, 255, .18);\n}\n.btn-primary:active {\n filter: brightness(.97);\n}\n</style>\n","<template>\n <div class=\"layer-panel\">\n <div class=\"panel-title\">图层</div>\n <div\n v-for=\"layer in sortedLayers\"\n :key=\"layer.id\"\n class=\"layer-item\"\n :class=\"{ active: selectedIds.has(layer.id) }\"\n @click=\"$emit('select', layer.id, false)\"\n >\n <span class=\"layer-icon\">{{ layerIcon(layer) }}</span>\n <span class=\"layer-name\">{{ layerName(layer) }}</span>\n <span v-if=\"zoneTag(layer)\" class=\"layer-zone\">{{ zoneTag(layer) }}</span>\n <span class=\"layer-zindex\">z:{{ layer.options.zIndex ?? 0 }}</span>\n </div>\n <div class=\"layer-actions\" v-if=\"sortedLayers.length > 0\">\n <button type=\"button\" class=\"pd-button small\" @click=\"$emit('move-layer', 'top')\" title=\"置顶\">\n ⤒\n </button>\n <button type=\"button\" class=\"pd-button small\" @click=\"$emit('move-layer', 'up')\" title=\"上移\">\n ↑\n </button>\n <button type=\"button\" class=\"pd-button small\" @click=\"$emit('move-layer', 'down')\" title=\"下移\">\n ↓\n </button>\n <button type=\"button\" class=\"pd-button small\" @click=\"$emit('move-layer', 'bottom')\" title=\"置底\">\n ⤓\n </button>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { RuntimeElement } from '../types'\n\nconst props = defineProps<{\n elements: RuntimeElement[]\n selectedIds: Set<string>\n}>()\n\ndefineEmits<{\n select: [id: string, multiple: boolean]\n 'move-layer': [direction: string]\n}>()\n\nconst sortedLayers = computed(() =>\n [...props.elements].sort((a, b) => (b.options.zIndex ?? 0) - (a.options.zIndex ?? 0))\n)\n\nconst elementIconMap: Record<string, string> = {\n text: 'T',\n longText: '¶',\n table: '⊞',\n image: '🖼',\n barcode: '≡',\n qrcode: '▣',\n hline: '—',\n vline: '|',\n rect: '□',\n oval: '○',\n html: '<>',\n}\n\nfunction layerIcon(el: RuntimeElement): string {\n return elementIconMap[el.printElementType.type] || '?'\n}\n\nfunction layerName(el: RuntimeElement): string {\n return el.options.title || el.printElementType.title || el.printElementType.type\n}\n\nfunction zoneTag(el: RuntimeElement): string {\n if (el.zone === 'header') return '页眉'\n if (el.zone === 'footer') return '页脚'\n return ''\n}\n</script>\n\n<style scoped>\n.layer-panel {\n border-top: 1px solid var(--pd-border);\n padding: 8px 12px;\n height: 100%;\n box-sizing: border-box;\n overflow-y: auto;\n}\n.panel-title {\n font-size: 11px;\n color: var(--pd-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n}\n.layer-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 6px;\n margin-bottom: 2px;\n border-radius: 4px;\n cursor: pointer;\n font-size: 12px;\n transition: background 0.1s;\n}\n.layer-item:hover {\n background: var(--pd-sidebar-hover, #f0f2f5);\n}\n.layer-item.active {\n background: rgba(22, 93, 255, 0.10);\n color: var(--pd-accent, #165DFF);\n box-shadow: inset 2px 0 0 var(--pd-accent, #165DFF);\n}\n.layer-icon {\n width: 18px;\n text-align: center;\n font-size: 12px;\n color: var(--pd-text-muted, #909399);\n}\n.layer-name {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--pd-text, #303133);\n}\n.layer-zone {\n flex-shrink: 0;\n padding: 0 4px;\n font-size: 10px;\n line-height: 14px;\n color: var(--pd-ink-green, #67c23a);\n background: rgba(103, 194, 58, 0.1);\n border-radius: 3px;\n}\n.layer-zindex {\n font-size: 10px;\n color: var(--pd-text-muted, #909399);\n font-variant-numeric: tabular-nums;\n}\n.layer-actions {\n display: flex;\n gap: 4px;\n margin-top: 8px;\n}\n</style>\n","import type { PrintBusinessField } from '../types'\n\nexport interface FieldGroup {\n /** 分组键(fieldKey 首段);空串表示无分组的顶层字段 */\n key: string\n /** 分组显示名:取容器字段的 fieldLabel,缺省回退为 key */\n label: string\n /** 是否明细列表分组(容器字段 fieldType === 'list') */\n isList: boolean\n /** 分组下的叶子字段 */\n fields: PrintBusinessField[]\n}\n\n/**\n * 将宿主扁平字段按 fieldKey 首段分组:\n * - 带点路径(supplier.name、goods.spec)归入首段分组;\n * - 无点且作为其它字段前缀的记录视为分组容器(如 supplier/goods),\n * 容器提供分组名称,fieldType='list' 标识明细列表(表格数据源);\n * - 无点且无子字段的记录作为独立顶层字段。\n */\nexport function groupFields(fields: PrintBusinessField[]): FieldGroup[] {\n const sorted = [...fields].sort((a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0))\n const groupMap = new Map<string, FieldGroup>()\n const groupOrder: string[] = []\n\n for (const f of sorted) {\n const dot = f.fieldKey.indexOf('.')\n if (dot === -1) continue\n const key = f.fieldKey.slice(0, dot)\n let g = groupMap.get(key)\n if (!g) {\n g = { key, label: key, isList: false, fields: [] }\n groupMap.set(key, g)\n groupOrder.push(key)\n }\n g.fields.push(f)\n }\n\n const groups: FieldGroup[] = []\n const standalone: PrintBusinessField[] = []\n for (const f of sorted) {\n if (f.fieldKey.includes('.')) continue\n const g = groupMap.get(f.fieldKey)\n if (g) {\n // 容器记录:提供分组名称,列表容器(fieldType='list')用于表格数据源选择\n g.label = f.fieldLabel\n g.isList = f.fieldType === 'list'\n } else {\n standalone.push(f)\n }\n }\n if (standalone.length) groups.push({ key: '', label: '', isList: false, fields: standalone })\n for (const key of groupOrder) groups.push(groupMap.get(key)!)\n return groups\n}\n\n/** 按关键字过滤分组(匹配字段名/字段 key),无叶子的分组剔除 */\nexport function filterGroups(groups: FieldGroup[], keyword: string): FieldGroup[] {\n const kw = keyword.trim().toLowerCase()\n if (!kw) return groups\n return groups\n .map(g => ({\n ...g,\n fields: g.fields.filter(\n f => f.fieldLabel.toLowerCase().includes(kw) || f.fieldKey.toLowerCase().includes(kw),\n ),\n }))\n .filter(g => g.fields.length > 0)\n}\n","<template>\n <div class=\"field-tree-panel\">\n <div class=\"panel-title\">业务字段</div>\n <input v-model=\"searchText\" class=\"pd-input search-input\" type=\"search\" placeholder=\"搜索字段...\" aria-label=\"搜索字段\" />\n <div class=\"tree-container\">\n <template v-for=\"group in filteredGroups\" :key=\"group.key || '_top'\">\n <div\n v-if=\"group.key\"\n class=\"field-group-header\"\n :class=\"{ 'is-list': group.isList }\"\n @click=\"toggleGroup(group.key)\"\n >\n <span class=\"expand-icon\">{{ collapsedGroups.has(group.key) && !searching ? '▶' : '▼' }}</span>\n <span class=\"node-icon\">{{ group.isList ? '📋' : '📁' }}</span>\n <span class=\"group-label\">{{ group.label }}</span>\n </div>\n <div v-show=\"!group.key || searching || !collapsedGroups.has(group.key)\">\n <div\n v-for=\"field in group.fields\"\n :key=\"field.fieldKey\"\n class=\"field-row\"\n draggable=\"true\"\n :style=\"{ paddingLeft: (group.key ? 22 : 8) + 'px' }\"\n @dragstart=\"onDragStart($event, field)\"\n >\n <span class=\"node-icon\">📄</span>\n <span class=\"node-label\">{{ field.fieldLabel }}</span>\n <span class=\"node-key\">({{ field.fieldKey }})</span>\n </div>\n </div>\n </template>\n </div>\n <p v-if=\"filteredGroups.length === 0\" class=\"pd-empty\">暂无字段</p>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed } from 'vue'\nimport type { PrintBusinessField } from '../types'\nimport { groupFields, filterGroups } from '../utils/field-groups'\n\nconst props = defineProps<{\n fields: PrintBusinessField[]\n}>()\n\nconst emit = defineEmits<{\n 'field-drag': [field: PrintBusinessField]\n}>()\n\nconst searchText = ref('')\nconst collapsedGroups = ref<Set<string>>(new Set())\n\nconst searching = computed(() => !!searchText.value.trim())\nconst filteredGroups = computed(() =>\n filterGroups(groupFields(props.fields), searchText.value),\n)\n\nfunction toggleGroup(key: string) {\n const next = new Set(collapsedGroups.value)\n if (next.has(key)) next.delete(key)\n else next.add(key)\n collapsedGroups.value = next\n}\n\nfunction onDragStart(event: DragEvent, field: PrintBusinessField) {\n // 拖拽载荷为完整字段路径(如 goods.spec),与打印数据结构一致\n event.dataTransfer?.setData('fieldData', JSON.stringify({ fieldKey: field.fieldKey, fieldLabel: field.fieldLabel }))\n if (event.dataTransfer) event.dataTransfer.effectAllowed = 'copy'\n emit('field-drag', field)\n}\n</script>\n\n<style scoped>\n.field-tree-panel {\n padding: 0;\n}\n.panel-title {\n font-size: 11px;\n color: var(--pd-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n padding: 4px 0 8px;\n margin-bottom: 8px;\n border-bottom: 1px solid var(--pd-border);\n}\n.search-input {\n margin-bottom: 8px;\n}\n.tree-container {\n overflow-y: auto;\n min-height: 0;\n}\n.field-group-header {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 5px 8px;\n border-radius: 4px;\n font-size: 13px;\n color: var(--pd-text, #303133);\n cursor: pointer;\n user-select: none;\n transition: background 0.1s;\n}\n.field-group-header:hover {\n background: var(--pd-sidebar-hover, #f0f2f5);\n}\n.field-group-header.is-list {\n color: var(--pd-accent, #165DFF);\n font-weight: 500;\n}\n.expand-icon {\n width: 12px;\n font-size: 8px;\n flex-shrink: 0;\n color: var(--pd-text-muted, #909399);\n}\n.field-row {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 5px 8px;\n border-radius: 4px;\n font-size: 13px;\n color: var(--pd-text, #303133);\n cursor: grab;\n user-select: none;\n transition: background 0.1s;\n}\n.field-row:hover {\n background: var(--pd-sidebar-hover, #f0f2f5);\n}\n.node-icon {\n font-size: 14px;\n flex-shrink: 0;\n filter: saturate(.6);\n opacity: .9;\n}\n.node-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.node-key {\n font-size: 11px;\n color: var(--pd-text-muted, #909399);\n flex-shrink: 0;\n}\n.group-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n</style>\n","<template>\n <div class=\"left-panel\" :class=\"{ collapsed }\">\n <!-- 折叠态:竖排图标,点击即展开对应页签 -->\n <div v-if=\"collapsed\" class=\"left-collapsed\">\n <button class=\"lc-btn\" title=\"展开素材台\" @click=\"expandTab(activeTab)\">»</button>\n <button class=\"lc-btn\" :class=\"{ on: activeTab === 'elements' }\" title=\"元素\" @click=\"expandTab('elements')\">▦</button>\n <button class=\"lc-btn\" :class=\"{ on: activeTab === 'fields' }\" title=\"字段\" @click=\"expandTab('fields')\">⊛</button>\n <button class=\"lc-btn\" :class=\"{ on: activeTab === 'layers' }\" title=\"图层\" @click=\"expandTab('layers')\">≡</button>\n </div>\n <template v-else>\n <div class=\"left-head\">\n <span class=\"left-title\">素材台</span>\n <button class=\"collapse-btn\" title=\"收起素材台\" @click=\"$emit('toggle-collapse')\">«</button>\n </div>\n <div class=\"pd-tabs left-tabs\">\n <div class=\"pd-tab-bar\" role=\"tablist\">\n <button type=\"button\" class=\"pd-tab\" :class=\"{ active: activeTab === 'elements' }\" @click=\"activeTab = 'elements'\">元素</button>\n <button type=\"button\" class=\"pd-tab\" :class=\"{ active: activeTab === 'fields' }\" @click=\"activeTab = 'fields'\">字段</button>\n <button type=\"button\" class=\"pd-tab\" :class=\"{ active: activeTab === 'layers' }\" @click=\"activeTab = 'layers'\">图层</button>\n </div>\n <div v-show=\"activeTab === 'elements'\" class=\"pd-tab-pane\" role=\"tabpanel\">\n <div class=\"panel-title\">拖拽元素到画布</div>\n <div\n v-for=\"item in elementTypes\"\n :key=\"item.type\"\n class=\"material-card\"\n draggable=\"true\"\n @dragstart=\"onDragStart($event, item.type)\"\n >\n <span class=\"material-icon\">{{ item.icon }}</span>\n <span class=\"material-label\">{{ item.label }}</span>\n </div>\n </div>\n <div v-show=\"activeTab === 'fields'\" class=\"pd-tab-pane\" role=\"tabpanel\">\n <FieldTreePanel\n :fields=\"fields\"\n @field-drag=\"onFieldDrag\"\n />\n </div>\n <div v-show=\"activeTab === 'layers'\" class=\"pd-tab-pane\" role=\"tabpanel\">\n <LayerPanel\n :elements=\"elements\"\n :selected-ids=\"selectedIds\"\n @select=\"(id: string, m: boolean) => $emit('select', id, m)\"\n @move-layer=\"(d: string) => $emit('move-layer', d)\"\n @toggle-visible=\"(id: string) => $emit('toggle-visible', id)\"\n @toggle-locked=\"(id: string) => $emit('toggle-locked', id)\"\n />\n </div>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport type { ElementType, PrintBusinessField, RuntimeElement } from '../types'\nimport LayerPanel from './LayerPanel.vue'\nimport FieldTreePanel from './FieldTreePanel.vue'\n\ndefineProps<{\n fields: PrintBusinessField[]\n elements: RuntimeElement[]\n selectedIds: Set<string>\n collapsed: boolean\n}>()\n\nconst emit = defineEmits<{\n select: [id: string, multiple: boolean]\n 'move-layer': [direction: string]\n 'toggle-visible': [id: string]\n 'toggle-locked': [id: string]\n 'field-drag': [field: PrintBusinessField]\n 'toggle-collapse': []\n}>()\n\nconst activeTab = ref('elements')\n\nconst elementTypes: { type: ElementType; label: string; icon: string }[] = [\n { type: 'text', label: '文本', icon: 'T' },\n { type: 'barcode', label: '条形码', icon: '▍▍' },\n { type: 'qrcode', label: '二维码', icon: '▦' },\n { type: 'image', label: '图片', icon: '▧' },\n { type: 'table', label: '表格', icon: '⊞' },\n { type: 'longText', label: '长文', icon: '¶' },\n { type: 'hline', label: '横线', icon: '―' },\n { type: 'vline', label: '竖线', icon: '│' },\n { type: 'rect', label: '矩形', icon: '▭' },\n { type: 'oval', label: '椭圆', icon: '◯' },\n { type: 'html', label: 'HTML', icon: '<>' },\n]\n\nfunction onDragStart(event: DragEvent, type: string) {\n event.dataTransfer?.setData('elementType', type)\n}\n\nfunction onFieldDrag(field: PrintBusinessField) {\n emit('field-drag', field)\n}\n\nfunction expandTab(tab: string) {\n activeTab.value = tab\n emit('toggle-collapse')\n}\n</script>\n\n<style scoped>\n.left-panel {\n width: 224px;\n min-width: 224px;\n background: var(--pd-sidebar, #ffffff);\n border-right: 1px solid var(--pd-border-soft, #e9ecf2);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n transition: width .18s ease;\n}\n.left-panel.collapsed {\n width: 36px;\n min-width: 36px;\n border-right: 1px solid var(--pd-border-soft, #e9ecf2);\n}\n.left-collapsed {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding-top: 12px;\n flex: 1;\n}\n.lc-btn {\n width: 26px;\n height: 26px;\n border-radius: 6px;\n border: 1px solid transparent;\n background: transparent;\n color: var(--pd-text-muted, #8b909c);\n font-size: 12px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all .14s ease;\n}\n.lc-btn:hover {\n color: var(--pd-text, #2a2e37);\n background: var(--pd-sidebar-hover, #f0f3f9);\n}\n.lc-btn.on {\n color: var(--pd-accent, #165DFF);\n background: var(--pd-accent-soft, rgba(22, 93, 255, .09));\n}\n.left-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n height: 42px;\n padding: 0 12px;\n flex-shrink: 0;\n border-bottom: 1px solid var(--pd-border-soft, #e9ecf2);\n}\n.left-title {\n font-size: 12px;\n font-weight: 600;\n color: var(--pd-text, #2a2e37);\n letter-spacing: 1.2px;\n display: inline-flex;\n align-items: center;\n gap: 7px;\n}\n.left-title::before {\n content: \"\";\n width: 3px;\n height: 12px;\n border-radius: 2px;\n background: linear-gradient(180deg, var(--pd-accent-2, #3D7BFF), var(--pd-accent, #165DFF));\n}\n.collapse-btn {\n border: none;\n background: transparent;\n color: var(--pd-text-muted, #8b909c);\n font-size: 14px;\n cursor: pointer;\n width: 24px;\n height: 24px;\n border-radius: 5px;\n transition: all .14s ease;\n}\n.collapse-btn:hover {\n color: var(--pd-text, #2a2e37);\n background: var(--pd-sidebar-hover, #f0f3f9);\n}\n.left-tabs {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.left-tabs .pd-tab-pane {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 12px;\n}\n.panel-title {\n font-size: 11px;\n color: var(--pd-text-muted, #8b909c);\n letter-spacing: .6px;\n padding: 2px 2px 8px;\n margin-bottom: 10px;\n border-bottom: 1px solid var(--pd-border-soft, #e9ecf2);\n}\n.material-card {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 10px;\n margin-bottom: 7px;\n border: 1px solid var(--pd-border-soft, #e9ecf2);\n border-radius: 8px;\n background: var(--pd-field-bg, #f4f6fa);\n cursor: grab;\n user-select: none;\n transition: border-color .14s ease, background .14s ease, transform .14s ease, box-shadow .14s ease;\n}\n.material-card:hover {\n border-color: rgba(22, 93, 255, .45);\n background: var(--pd-surface, #ffffff);\n transform: translateY(-1px);\n box-shadow: var(--pd-shadow-sm, 0 1px 2px rgba(23, 32, 60, .05));\n}\n.material-card:active {\n cursor: grabbing;\n transform: translateY(0);\n}\n.material-icon {\n width: 30px;\n height: 24px;\n border: 1px dashed var(--pd-border, #d9dde6);\n border-radius: 5px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n color: var(--pd-accent, #165DFF);\n background: var(--pd-surface, #ffffff);\n flex-shrink: 0;\n transition: border-color .14s ease, background .14s ease;\n}\n.material-card:hover .material-icon {\n border-style: solid;\n border-color: var(--pd-accent, #165DFF);\n background: var(--pd-accent-soft, rgba(22, 93, 255, .09));\n}\n.material-label {\n font-size: 12.5px;\n color: var(--pd-text, #2a2e37);\n}\n</style>\n","// web/src/components/print/composables/useDrag.ts\nimport { ref } from 'vue'\nimport type { AdsorbResult } from '../types'\n\nexport interface DragOptions {\n axis?: 'x' | 'y'\n disabled?: boolean\n getScale?: () => number\n /** 拖拽过程中每帧回调,提供修正后的绝对坐标(调用方用 transform 做视觉跟随) */\n onDrag: (pos: { left: number; top: number }) => void\n /** 拖拽结束回调,提供最终坐标与修饰符信息(调用方一次性写入响应式数据) */\n onDragEnd?: (pos: { left: number; top: number }, info: { altKey: boolean }) => void\n onStart?: (info: { altKey: boolean }) => void\n onStop?: () => void\n onAdsorb?: (pos: { left: number; top: number; width: number; height: number }) => AdsorbResult\n}\n\nexport function useDrag(target: { value: HTMLElement | null }, options: DragOptions) {\n const isDragging = ref(false)\n /** 拖拽预览状态:半透明副本的绝对坐标与尺寸(pt),供上层渲染预览层 */\n const dragPreview = ref<{ left: number; top: number; width: number; height: number } | null>(null)\n\n let startX = 0, startY = 0\n let startLeft = 0, startTop = 0\n // 记录 mousedown 时的 altKey,供 onDragEnd 判定是否复制\n let downAltKey = false\n\n function onMouseDown(e: MouseEvent) {\n if (options.disabled) return\n // 忽略 resize 手柄点击\n const targetEl = e.target\n if (!(targetEl instanceof HTMLElement) || targetEl.classList.contains('resize-handle')) return\n\n isDragging.value = true\n downAltKey = e.altKey\n startX = e.clientX\n startY = e.clientY\n\n const el = target.value\n if (!el) return\n startLeft = parseFloat(el.style.left) || 0\n startTop = parseFloat(el.style.top) || 0\n // 初始化拖拽预览副本(记录起始位置与尺寸)\n dragPreview.value = {\n left: startLeft,\n top: startTop,\n width: parseFloat(el.style.width) || 0,\n height: parseFloat(el.style.height) || 0,\n }\n\n options.onStart?.({ altKey: downAltKey })\n\n document.addEventListener('mousemove', onMouseMove)\n document.addEventListener('mouseup', onMouseUp)\n e.preventDefault()\n }\n\n /** 由鼠标坐标计算吸附修正后的绝对坐标 */\n function computePos(e: MouseEvent) {\n const scale = options.getScale?.() ?? 1\n let newLeft = startLeft + (e.clientX - startX) / scale\n let newTop = startTop + (e.clientY - startY) / scale\n\n if (options.axis === 'x') newTop = startTop\n if (options.axis === 'y') newLeft = startLeft\n\n if (options.onAdsorb) {\n const el = target.value\n if (el) {\n const w = parseFloat(el.style.width) || 0\n const h = parseFloat(el.style.height) || 0\n const result = options.onAdsorb({ left: newLeft, top: newTop, width: w, height: h })\n newLeft = result.left\n newTop = result.top\n }\n }\n return { left: newLeft, top: newTop }\n }\n\n function onMouseMove(e: MouseEvent) {\n const pos = computePos(e)\n // 更新预览副本位置(响应式,供渲染层实时跟随)\n if (dragPreview.value) {\n dragPreview.value.left = pos.left\n dragPreview.value.top = pos.top\n }\n options.onDrag(pos)\n }\n\n function onMouseUp(e: MouseEvent) {\n isDragging.value = false\n const pos = computePos(e)\n // 一次性通知调用方最终坐标与修饰符,写入响应式数据\n options.onDragEnd?.(pos, { altKey: downAltKey })\n options.onStop?.()\n // 清空预览副本\n dragPreview.value = null\n\n document.removeEventListener('mousemove', onMouseMove)\n document.removeEventListener('mouseup', onMouseUp)\n }\n\n function cleanup() {\n const el = target.value\n if (el) {\n el.removeEventListener('mousedown', onMouseDown)\n }\n document.removeEventListener('mousemove', onMouseMove)\n document.removeEventListener('mouseup', onMouseUp)\n }\n\n function setup() {\n cleanup()\n const el = target.value\n if (el) {\n el.addEventListener('mousedown', onMouseDown)\n }\n }\n\n return { isDragging, dragPreview, setup, cleanup }\n}\n","// web/src/components/print/composables/useResize.ts\nimport type { ResizePoint } from '../types'\n\nexport interface ResizeRect {\n left: number\n top: number\n width: number\n height: number\n}\n\nexport interface ResizeOptions {\n minWidth?: number\n minHeight?: number\n getScale?: () => number\n /** 缩放起始时读取元素当前矩形(mm) */\n getRect: () => ResizeRect\n onResize: (rect: ResizeRect) => void\n onStart?: () => void\n onStop?: () => void\n}\n\n/** 8 方位缩放手柄,供模板 v-for 渲染 */\nexport const RESIZE_POINTS: ResizePoint[] = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w']\n\n/** 根据方位与位移计算缩放后矩形(纯函数) */\nexport function calcResizeRect(\n point: ResizePoint,\n startRect: ResizeRect,\n dx: number,\n dy: number,\n minW: number,\n minH: number,\n): ResizeRect {\n let { left, top, width, height } = startRect\n\n switch (point) {\n case 'e': width = Math.max(minW, startRect.width + dx); break\n case 'w': width = Math.max(minW, startRect.width - dx); left = startRect.left + startRect.width - width; break\n case 's': height = Math.max(minH, startRect.height + dy); break\n case 'n': height = Math.max(minH, startRect.height - dy); top = startRect.top + startRect.height - height; break\n case 'se': width = Math.max(minW, startRect.width + dx); height = Math.max(minH, startRect.height + dy); break\n case 'sw': width = Math.max(minW, startRect.width - dx); left = startRect.left + startRect.width - width; height = Math.max(minH, startRect.height + dy); break\n case 'ne': width = Math.max(minW, startRect.width + dx); height = Math.max(minH, startRect.height - dy); top = startRect.top + startRect.height - height; break\n case 'nw': width = Math.max(minW, startRect.width - dx); left = startRect.left + startRect.width - width; height = Math.max(minH, startRect.height - dy); top = startRect.top + startRect.height - height; break\n }\n\n return { left, top, width, height }\n}\n\n/** 缩放交互逻辑:手柄由组件模板渲染,mousedown 时调用 startResize */\nexport function useResize(options: ResizeOptions) {\n let startX = 0, startY = 0\n let startRect: ResizeRect = { left: 0, top: 0, width: 0, height: 0 }\n let activePoint: ResizePoint | null = null\n\n function startResize(point: ResizePoint, e: MouseEvent) {\n activePoint = point\n startX = e.clientX\n startY = e.clientY\n startRect = { ...options.getRect() }\n options.onStart?.()\n document.addEventListener('mousemove', onResizeMove)\n document.addEventListener('mouseup', onResizeEnd)\n e.preventDefault()\n }\n\n function onResizeMove(e: MouseEvent) {\n if (!activePoint) {\n return\n }\n const scale = options.getScale?.() || 1\n const dx = (e.clientX - startX) / scale\n const dy = (e.clientY - startY) / scale\n const minW = options.minWidth || 20\n const minH = options.minHeight || 20\n options.onResize(calcResizeRect(activePoint, startRect, dx, dy, minW, minH))\n }\n\n function onResizeEnd() {\n activePoint = null\n options.onStop?.()\n document.removeEventListener('mousemove', onResizeMove)\n document.removeEventListener('mouseup', onResizeEnd)\n }\n\n function cleanup() {\n document.removeEventListener('mousemove', onResizeMove)\n document.removeEventListener('mouseup', onResizeEnd)\n }\n\n return { startResize, cleanup }\n}\n","import { getDemoData } from '../utils/demo-data'\n\ninterface BindingDisplayState {\n status: 'unbound' | 'bound' | 'warning' | 'error'\n badge: string\n badgeColor: string\n demoPreview: string\n warning?: string\n}\n\nfunction getNestedValue(obj: any, path: string): any {\n return path.split('.').reduce((current, key) => current?.[key], obj)\n}\n\nexport function useBindingDisplay() {\n function getBindingDisplayState(element: any): BindingDisplayState {\n const formatter = element.options.formatter\n const title = element.options.title\n\n if (!formatter) {\n return {\n status: 'unbound',\n badge: title || '文本',\n badgeColor: '#909399',\n demoPreview: title || '文本',\n }\n }\n\n const demoData = getDemoData()\n // 简单预览:从 formatter 中提取字段名并查找 demo 数据\n const fieldMatch = formatter.match(/\\{([^}]+)\\}/)\n if (fieldMatch) {\n const fieldPath = fieldMatch[1]\n const demoValue = getNestedValue(demoData, fieldPath)\n return {\n status: 'bound',\n badge: `fx ${formatter}`,\n badgeColor: '#409EFF',\n demoPreview: demoValue != null ? String(demoValue) : formatter,\n }\n }\n\n return {\n status: 'bound',\n badge: `fx ${formatter}`,\n badgeColor: '#409EFF',\n demoPreview: formatter,\n }\n }\n\n return { getBindingDisplayState }\n}\n","<template>\n <div class=\"print-text\" :style=\"textStyle\">\n {{ displayText }}\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { RuntimeElement } from '../../types'\nimport { resolveTextBinding } from '../../utils/binding'\n\nconst props = defineProps<{\n element: RuntimeElement\n data?: Record<string, any>[]\n designMode?: boolean\n}>()\n\nconst V_ALIGN_FLEX: Record<string, string> = { top: 'flex-start', middle: 'center', bottom: 'flex-end' }\nconst H_ALIGN_FLEX: Record<string, string> = { left: 'flex-start', center: 'center', right: 'flex-end' }\n\nconst textStyle = computed(() => {\n const o = props.element.options\n return {\n fontSize: (o.fontSize || 12) + 'pt',\n fontWeight: o.fontWeight || 'normal',\n fontFamily: o.fontFamily || 'inherit',\n color: o.color || '#333',\n backgroundColor: o.backgroundColor || 'transparent',\n textAlign: o.textAlign || 'left',\n lineHeight: o.lineHeight ? o.lineHeight + 'pt' : 'normal',\n letterSpacing: o.letterSpacing ? o.letterSpacing + 'pt' : 'normal',\n textDecoration: o.textDecoration || 'none',\n padding: `${o.contentPaddingTop || 0}pt ${o.contentPaddingRight || 0}pt ${o.contentPaddingBottom || 0}pt ${o.contentPaddingLeft || 0}pt`,\n width: '100%',\n height: '100%',\n boxSizing: 'border-box' as const,\n overflow: 'hidden',\n ...(o.verticalAlign\n ? {\n display: 'flex',\n alignItems: V_ALIGN_FLEX[o.verticalAlign] ?? 'flex-start',\n justifyContent: H_ALIGN_FLEX[o.textAlign || 'left'] ?? 'flex-start',\n }\n : {}),\n }\n})\n\nconst displayText = computed(() => {\n if (props.designMode) {\n if (props.element.options.testData) {\n return props.element.options.testData\n }\n return props.element.options.formatter || '文本'\n }\n return resolveTextBinding(props.element.options, props.data)\n})\n</script>\n","<template>\n <div class=\"print-image\">\n <img v-if=\"imageSrc && !hasError\" :src=\"imageSrc\" :style=\"imgStyle\" @error=\"onError\" />\n <div v-else class=\"image-placeholder\">图片</div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport type { RuntimeElement } from '../../types'\nimport { evaluateTemplate } from '../../utils/expression-eval'\nimport { DEFAULT_DEMO_DATA } from '../../utils/demo-data'\n\nconst props = defineProps<{\n element: RuntimeElement\n data?: Record<string, any>[]\n designMode?: boolean\n}>()\n\nconst imageSrc = computed(() => {\n const raw = props.element.options.src || ''\n if (!raw) return ''\n // {字段} 表达式:设计态用 demo 数据求值,运行态用打印数据求值\n if (raw.includes('{')) {\n if (props.designMode) {\n return evaluateTemplate(raw, DEFAULT_DEMO_DATA)\n }\n return evaluateTemplate(raw, props.data?.[0] || {})\n }\n // 相对路径(如 /docfiles/...)经站点同源 + dev/prod 代理可直接访问;绝对 URL 原样使用\n return raw\n})\n\n// 加载失败兜底:显示占位,避免破图阻塞 PDF 就绪判定\nconst hasError = ref(false)\nfunction onError() {\n hasError.value = true\n}\n// src 变化时重置错误态\nwatch(imageSrc, () => {\n hasError.value = false\n})\n\nconst imgStyle = computed(() => ({\n objectFit: (props.element.options.fit || 'contain') as any,\n}))\n</script>\n\n<style scoped>\n.print-image { width: 100%; height: 100%; overflow: hidden; }\n.print-image img { width: 100%; height: 100%; display: block; }\n.image-placeholder {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #bbb;\n font-size: 12px;\n border: 1px dashed #ddd;\n box-sizing: border-box;\n}\n</style>\n","<template>\n <div class=\"print-longtext\" :style=\"textStyle\">\n {{ displayText }}\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { RuntimeElement } from '../../types'\nimport { resolveTextBinding } from '../../utils/binding'\n\nconst props = defineProps<{\n element: RuntimeElement\n data?: Record<string, any>[]\n designMode?: boolean\n}>()\n\nconst V_ALIGN_FLEX: Record<string, string> = { top: 'flex-start', middle: 'center', bottom: 'flex-end' }\nconst H_ALIGN_FLEX: Record<string, string> = { left: 'flex-start', center: 'center', right: 'flex-end' }\n\nconst textStyle = computed(() => {\n const o = props.element.options\n return {\n fontSize: (o.fontSize || 12) + 'pt',\n fontWeight: o.fontWeight || 'normal',\n fontFamily: o.fontFamily || 'inherit',\n color: o.color || '#333',\n backgroundColor: o.backgroundColor || 'transparent',\n textAlign: o.textAlign || 'left',\n lineHeight: o.lineHeight ? o.lineHeight + 'pt' : '1.5',\n letterSpacing: o.letterSpacing ? o.letterSpacing + 'pt' : 'normal',\n textIndent: o.longTextIndent ? o.longTextIndent + 'pt' : '0',\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n wordBreak: 'break-all' as const,\n boxSizing: 'border-box' as const,\n ...(o.verticalAlign\n ? {\n display: 'flex',\n alignItems: V_ALIGN_FLEX[o.verticalAlign] ?? 'flex-start',\n justifyContent: H_ALIGN_FLEX[o.textAlign || 'left'] ?? 'flex-start',\n }\n : {}),\n }\n})\n\nconst displayText = computed(() => {\n if (props.designMode) {\n if (props.element.options.formatter) return props.element.options.formatter\n return '长文本内容'\n }\n return resolveTextBinding(props.element.options, props.data)\n})\n</script>\n","<!-- 表格右键菜单:行列增删/合并拆分/行类型切换 -->\n<template>\n <Teleport to=\"body\">\n <div\n v-if=\"visible\"\n class=\"table-ctx-menu\"\n :style=\"{ left: x + 'px', top: y + 'px' }\"\n @mousedown.stop\n >\n <div class=\"menu-item\" @click=\"emitAction('insert-row-above')\">在上方插入行</div>\n <div class=\"menu-item\" @click=\"emitAction('insert-row-below')\">在下方插入行</div>\n <div\n class=\"menu-item\"\n :class=\"{ disabled: !canDeleteRow }\"\n @click=\"canDeleteRow && emitAction('delete-row')\"\n >\n 删除行\n </div>\n <div class=\"menu-divider\" />\n <div class=\"menu-item\" @click=\"emitAction('insert-col-left')\">在左侧插入列</div>\n <div class=\"menu-item\" @click=\"emitAction('insert-col-right')\">在右侧插入列</div>\n <div\n class=\"menu-item\"\n :class=\"{ disabled: !canDeleteCol }\"\n @click=\"canDeleteCol && emitAction('delete-col')\"\n >\n 删除列\n </div>\n <div class=\"menu-divider\" />\n <div\n class=\"menu-item\"\n :class=\"{ disabled: !!mergeDisabledReason }\"\n :title=\"mergeDisabledReason || ''\"\n @click=\"!mergeDisabledReason && emitAction('merge')\"\n >\n 合并单元格\n </div>\n <div\n class=\"menu-item\"\n :class=\"{ disabled: !canSplit }\"\n @click=\"canSplit && emitAction('split')\"\n >\n 拆分单元格\n </div>\n <div class=\"menu-divider\" />\n <div class=\"menu-group-title\">行类型</div>\n <div\n v-for=\"t in ROW_TYPES\"\n :key=\"t.value\"\n class=\"menu-item\"\n :class=\"{ disabled: !!rowTypeDisabledReason(t.value), active: currentRowType === t.value }\"\n :title=\"rowTypeDisabledReason(t.value) || ''\"\n @click=\"!rowTypeDisabledReason(t.value) && emitAction('set-row-type', t.value)\"\n >\n {{ t.label }}\n </div>\n </div>\n </Teleport>\n</template>\n\n<script setup lang=\"ts\">\nimport type { TableRowType } from '../../types'\n\nconst ROW_TYPES: { value: TableRowType; label: string }[] = [\n { value: 'header', label: '标题行' },\n { value: 'data', label: '数据行' },\n { value: 'subtotal', label: '小计行' },\n { value: 'summary', label: '汇总行' },\n]\n\ndefineProps<{\n visible: boolean\n x: number\n y: number\n canDeleteRow: boolean\n canDeleteCol: boolean\n mergeDisabledReason: string | null\n canSplit: boolean\n currentRowType: TableRowType | null\n rowTypeDisabledReason: (t: TableRowType) => string | null\n}>()\n\nconst emit = defineEmits<{ action: [name: string, payload?: string] }>()\n\nfunction emitAction(name: string, payload?: string) {\n emit('action', name, payload)\n}\n</script>\n\n<style scoped>\n.table-ctx-menu {\n position: fixed;\n z-index: 3000;\n min-width: 140px;\n padding: 4px 0;\n background: #fff;\n border: 1px solid #dcdfe6;\n border-radius: 4px;\n box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);\n font-size: 13px;\n}\n.menu-item {\n padding: 5px 14px;\n cursor: pointer;\n color: #333;\n}\n.menu-item:hover {\n background: #f5f7fa;\n}\n.menu-item.disabled {\n color: #c0c4cc;\n cursor: not-allowed;\n}\n.menu-item.active {\n color: #165DFF;\n}\n.menu-divider {\n height: 1px;\n margin: 4px 0;\n background: #ebeef5;\n}\n.menu-group-title {\n padding: 4px 14px;\n font-size: 12px;\n color: #909399;\n}\n</style>\n","<!-- 表格单元格内条形码/二维码渲染:设计态与预览态共用,按值生成图形 -->\n<template>\n <div class=\"cell-barcode\">\n <svg v-show=\"cellType === 'barcode' && svgOk\" ref=\"barcodeSvg\" preserveAspectRatio=\"xMidYMid meet\"></svg>\n <img v-if=\"cellType === 'qrcode' && dataUrl\" :src=\"dataUrl\" alt=\"qrcode\" />\n <span v-if=\"!svgOk && cellType === 'barcode'\" class=\"cell-barcode-fallback\">{{ value || '条码' }}</span>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, watch } from 'vue'\nimport JsBarcode from 'jsbarcode'\nimport QRCode from 'qrcode'\n\nconst props = defineProps<{\n cellType: 'barcode' | 'qrcode'\n value: string\n barcodeType?: string\n qrCodeLevel?: string\n showText?: boolean\n}>()\n\nconst barcodeSvg = ref<SVGSVGElement | null>(null)\nconst svgOk = ref(false)\nconst dataUrl = ref('')\n\nfunction renderBarcode() {\n svgOk.value = false\n if (!barcodeSvg.value) return\n try {\n JsBarcode(barcodeSvg.value, props.value, {\n format: (props.barcodeType || 'CODE128') as any,\n width: 1,\n height: 28,\n displayValue: props.showText !== false,\n fontSize: 9,\n margin: 0,\n })\n svgOk.value = true\n } catch { /* 码值不符合码制时回退文本占位 */ }\n}\n\nasync function renderQrcode() {\n if (!props.value) {\n dataUrl.value = ''\n return\n }\n try {\n dataUrl.value = await QRCode.toDataURL(props.value, {\n width: 96,\n margin: 1,\n errorCorrectionLevel: ((props.qrCodeLevel || 'M') as 'L' | 'M' | 'Q' | 'H'),\n })\n } catch {\n dataUrl.value = ''\n }\n}\n\nfunction render() {\n if (props.cellType === 'barcode') renderBarcode()\n else renderQrcode()\n}\n\nonMounted(render)\nwatch(() => [props.cellType, props.value, props.barcodeType, props.qrCodeLevel, props.showText], render)\n</script>\n\n<style scoped>\n.cell-barcode { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; overflow: hidden; }\n/* JsBarcode svg 自带 viewBox,100% + preserveAspectRatio 使条码按单元格等比缩放填满 */\n.cell-barcode svg { width: 100%; height: 100%; }\n.cell-barcode img { max-width: 100%; max-height: 100%; }\n.cell-barcode-fallback { font-style: italic; opacity: 0.6; }\n</style>\n","<!-- Excel 风格表格元素:单元格矩阵编辑器(选区/右键菜单/双击编辑) -->\n<template>\n <div class=\"print-table\" :class=\"{ 'design-mode': designMode }\" @contextmenu.prevent>\n <table ref=\"tableRef\" :style=\"{ fontSize: defaultFontSize + 'pt', color: defaultColor }\">\n <colgroup>\n <col v-for=\"(w, i) in colWidths\" :key=\"i\" :style=\"{ width: w + 'mm' }\" />\n </colgroup>\n <tbody>\n <tr v-for=\"(row, ri) in rows\" :key=\"row.id\" :style=\"{ height: row.height + 'mm' }\">\n <template v-for=\"(cell, ci) in row.cells\" :key=\"cell.id\">\n <td\n v-if=\"!cell.merged\"\n :rowspan=\"cell.rowspan || 1\"\n :colspan=\"cell.colspan || 1\"\n :class=\"cellClass(ri, ci)\"\n :style=\"cellStyle(row, cell)\"\n @mousedown.left=\"onCellMouseDown(ri, ci, $event)\"\n @mouseenter=\"onCellMouseEnter(ri, ci)\"\n @dblclick.stop=\"onCellDblClick(ri, ci)\"\n @contextmenu.prevent.stop=\"onCellContextMenu(ri, ci, $event)\"\n >\n <CellBarcode\n v-if=\"isCodeCell(cell)\"\n :cell-type=\"cell.cellType as 'barcode' | 'qrcode'\"\n :value=\"cellDisplay(row, cell)\"\n :barcode-type=\"cell.barcodeType\"\n :qr-code-level=\"cell.qrCodeLevel\"\n :show-text=\"cell.showBarcodeText\"\n />\n <span v-else-if=\"row.type === 'data'\" class=\"data-placeholder\">\n {{ cellDisplay(row, cell) }}\n </span>\n <template v-else>{{ cellDisplay(row, cell) }}</template>\n </td>\n </template>\n </tr>\n </tbody>\n </table>\n <!-- 行类型徽标(仅设计态且元素被选中) -->\n <div v-if=\"designMode && isSelected\" class=\"row-badges\">\n <span\n v-for=\"(row, ri) in rows\"\n :key=\"row.id\"\n class=\"row-badge\"\n :style=\"{ top: badgeTopMm(ri) + 'mm', height: badgeHeightMm(ri) + 'mm' }\"\n >\n {{ ROW_TYPE_BADGE[row.type] }}\n </span>\n </div>\n <TableContextMenu\n :visible=\"menu.visible\"\n :x=\"menu.x\"\n :y=\"menu.y\"\n :can-delete-row=\"rows.length > 1\"\n :can-delete-col=\"colWidths.length > 1\"\n :merge-disabled-reason=\"mergeReason\"\n :can-split=\"canSplit\"\n :current-row-type=\"selection ? rows[selection.r1]?.type ?? null : null\"\n :row-type-disabled-reason=\"rowTypeReason\"\n @action=\"onMenuAction\"\n />\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, inject, onMounted, reactive, ref, watch } from 'vue'\nimport type { RuntimeElement, TableRow, TableCell, TableRowType } from '../../types'\nimport {\n normalizeSelection, canMergeReason, mergeCells, splitCells,\n insertRow, deleteRow, insertCol, deleteCol, setRowType, syncTableElementSize,\n resolveCellBorderCss,\n} from '../../utils/table-matrix'\nimport { TABLE_EDIT_KEY, type TableEditContext } from '../../composables/useTableSelection'\nimport TableContextMenu from './TableContextMenu.vue'\nimport CellBarcode from './CellBarcode.vue'\nimport { resolveBarcodeDesignValue } from '../../utils/binding'\nimport { DEFAULT_DEMO_DATA } from '../../utils/demo-data'\n\nconst ROW_TYPE_BADGE: Record<TableRowType, string> = {\n header: '题', data: '数', subtotal: '小', summary: '汇',\n}\n\nconst props = defineProps<{\n element: RuntimeElement\n designMode?: boolean\n isSelected?: boolean\n /** 设计态下无边框单元格是否显示虚拟虚线(默认 true) */\n showTableGhostBorder?: boolean\n}>()\n\nconst emit = defineEmits<{\n 'dblclick-element': [id: string]\n 'dblclick-cell': [elementId: string, r: number, c: number]\n}>()\n\n// PrintDesigner 注入:选区共享 + 历史提交(非设计态如 PDF 预览无注入,提供空实现)\nconst editCtx = inject<TableEditContext>(TABLE_EDIT_KEY, {\n tableSelection: ref(null),\n setTableSelection: () => {},\n recordHistory: () => {},\n maxTableWidth: ref(Infinity),\n})\n\nconst rows = computed<TableRow[]>(() => props.element.options.tableRows ?? [])\nconst colWidths = computed<number[]>(() => props.element.options.tableColWidths ?? [])\nconst defaultFontSize = computed(() => props.element.options.tableDefaultFontSize ?? 10)\nconst defaultColor = computed(() => props.element.options.tableDefaultColor ?? '#333333')\n\n/** 当前元素的选区(全局选区属于本元素时才生效) */\nconst selection = computed(() => {\n const s = editCtx.tableSelection.value\n return s && s.elementId === props.element.id ? s : null\n})\n\nfunction rowTopMm(ri: number): number {\n let t = 0\n for (let i = 0; i < ri; i++) t += rows.value[i]!.height\n return t\n}\n\n// ─── 设计态实测尺寸自愈 ───\n// HTML 表格行高只是「最小高度」:单元格内容换行、大字号/大 padding 都会把行撑高,\n// 实际渲染高度可能大于行高和(打印端 overflow:visible 并按实测高度分页,行为一致)。\n// 设计框体(虚线选框/选中框/位置标签/吸附对齐)需跟随 <table> 实测高度,\n// 否则选中时示意虚线框与表格真实占用高度不一致。\nconst tableRef = ref<HTMLTableElement | null>(null)\n\n/** 96dpi 下 1mm ≈ 3.78px(与 render/browser-pagination 测量遍同一常量) */\nconst PX_PER_MM = 3.7795275591\n/** 实测高度与模型高度差小于该值(mm)时不回写,避免无意义抖动 */\nconst HEIGHT_EPSILON_MM = 0.1\n\n/** 各行实测布局(mm):行被内容撑高时,行类型徽标按实测位置/高度对齐 */\nconst rowLayoutMm = ref<{ top: number; height: number }[]>([])\n\nfunction measureTable() {\n if (!props.designMode) return\n const table = tableRef.value\n if (!table) return\n const tableHpx = table.offsetHeight\n if (tableHpx <= 0) return // 画布未挂载/隐藏(无布局)时跳过\n const o = props.element.options\n const tableHmm = tableHpx / PX_PER_MM\n if (Math.abs(tableHmm - (o.height ?? 0)) > HEIGHT_EPSILON_MM) {\n o.height = Math.round(tableHmm * 100) / 100\n }\n // tr.offsetTop 与 table.offsetTop 同属一个 offsetParent(.print-table 为 relative)\n const baseTop = table.offsetTop\n rowLayoutMm.value = Array.from(table.rows).map(tr => ({\n top: (tr.offsetTop - baseTop) / PX_PER_MM,\n height: tr.offsetHeight / PX_PER_MM,\n }))\n}\n\n/** 行徽标顶距:优先实测位置,未测量时回退行高累加 */\nfunction badgeTopMm(ri: number): number {\n return rowLayoutMm.value[ri]?.top ?? rowTopMm(ri)\n}\n\n/** 行徽标高:优先实测高度,未测量时回退配置行高 */\nfunction badgeHeightMm(ri: number): number {\n return rowLayoutMm.value[ri]?.height ?? rows.value[ri]?.height ?? 0\n}\n\n// 表格结构/内容/样式任意变化后,在 DOM 更新完毕时实测(post 钩子保证读到新布局)\nwatch(\n () => [props.element.options, props.designMode],\n () => measureTable(),\n { deep: true, flush: 'post' },\n)\n\nonMounted(() => {\n measureTable()\n // Web 字体加载完成后字宽可能变化导致换行变化,补测一次\n document.fonts?.ready.then(() => measureTable())\n})\n\n// ─── 单元格显示与样式 ───\n\n/** demo 数据中 data 行迭代用的列表(与服务端 resolveListSource 优先级一致) */\nconst demoList = computed<Record<string, any>[] | undefined>(() => {\n const ds = props.element.options.dataSource\n if (ds && Array.isArray(DEFAULT_DEMO_DATA[ds])) return DEFAULT_DEMO_DATA[ds]\n for (const v of Object.values(DEFAULT_DEMO_DATA)) {\n if (Array.isArray(v)) return v as Record<string, any>[]\n }\n return undefined\n})\n\nfunction isCodeCell(cell: TableCell): boolean {\n return cell.cellType === 'barcode' || cell.cellType === 'qrcode'\n}\n\nfunction cellDisplay(_row: TableRow, cell: TableCell): string {\n if (isCodeCell(cell)) {\n return resolveBarcodeDesignValue(cell.formatter, demoList.value)\n }\n return cell.formatter || ''\n}\n\nfunction cellStyle(_row: TableRow, cell: TableCell): Record<string, string> {\n const o = props.element.options\n // 设计态下无边框边补虚拟虚线(仅设计稿展示,预览/打印输出不受影响)\n const borderOpts = { designMode: props.designMode, showGhostBorder: props.showTableGhostBorder }\n return {\n fontFamily: cell.fontFamily || 'inherit',\n textAlign: cell.align ?? 'left',\n verticalAlign: cell.valign ?? 'middle',\n fontSize: (cell.fontSize ?? defaultFontSize.value) + 'pt',\n fontWeight: cell.fontWeight ?? 'normal',\n color: cell.color ?? defaultColor.value,\n backgroundColor: cell.backgroundColor ?? 'transparent',\n borderTop: resolveCellBorderCss(cell.borders?.top, borderOpts),\n borderRight: resolveCellBorderCss(cell.borders?.right, borderOpts),\n borderBottom: resolveCellBorderCss(cell.borders?.bottom, borderOpts),\n borderLeft: resolveCellBorderCss(cell.borders?.left, borderOpts),\n padding: (cell.padding ?? o.tableDefaultPadding ?? 1) + 'mm',\n whiteSpace: (cell.wordWrap ?? true) ? 'normal' : 'nowrap',\n overflow: (cell.wordWrap ?? true) ? 'visible' : 'hidden',\n }\n}\n\nfunction cellClass(ri: number, ci: number): Record<string, boolean> {\n const s = selection.value\n const inSel = !!s && ri >= s.r1 && ri <= s.r2 && ci >= s.c1 && ci <= s.c2\n return { 'cell-selected': inSel, 'row-data-bg': rows.value[ri]!.type === 'data' }\n}\n\n// ─── 选区交互 ───\n\nconst dragAnchor = ref<{ r: number; c: number } | null>(null)\n\nfunction applySelection(a: { r: number; c: number }, b: { r: number; c: number }) {\n const rect = normalizeSelection(rows.value, a, b)\n editCtx.setTableSelection({ elementId: props.element.id, ...rect })\n}\n\nfunction onCellMouseDown(r: number, c: number, e: MouseEvent) {\n if (!props.designMode || !props.isSelected) return\n e.stopPropagation() // 阻止画布拖拽元素\n if (e.shiftKey && selection.value) {\n applySelection({ r: selection.value.r1, c: selection.value.c1 }, { r, c })\n } else {\n dragAnchor.value = { r, c }\n applySelection({ r, c }, { r, c })\n }\n window.addEventListener('mouseup', () => { dragAnchor.value = null }, { once: true })\n}\n\nfunction onCellMouseEnter(r: number, c: number) {\n if (dragAnchor.value) applySelection(dragAnchor.value, { r, c })\n}\n\n// ─── 双击编辑 ───\n\nfunction onCellDblClick(r: number, c: number) {\n if (!props.designMode) return\n // 单元格双击:上报单元格坐标,由 PrintDesigner 打开该单元格的表达式编辑器\n emit('dblclick-cell', props.element.id, r, c)\n}\n\n// ─── 右键菜单 ───\n\nconst menu = reactive({ visible: false, x: 0, y: 0 })\n\nfunction onCellContextMenu(r: number, c: number, e: MouseEvent) {\n if (!props.designMode || !props.isSelected) return\n const s = selection.value\n const inSel = s && r >= s.r1 && r <= s.r2 && c >= s.c1 && c <= s.c2\n if (!inSel) applySelection({ r, c }, { r, c })\n menu.x = e.clientX\n menu.y = e.clientY\n menu.visible = true\n window.addEventListener('mousedown', () => { menu.visible = false }, { once: true })\n}\n\nconst mergeReason = computed(() => {\n const s = selection.value\n if (!s) return '未选择单元格'\n return canMergeReason(rows.value, s)\n})\n\nconst canSplit = computed(() => {\n const s = selection.value\n if (!s) return false\n for (let r = s.r1; r <= s.r2; r++) {\n for (let c = s.c1; c <= s.c2; c++) {\n const cell = rows.value[r]!.cells[c]!\n if (!cell.merged && ((cell.rowspan ?? 1) > 1 || (cell.colspan ?? 1) > 1)) return true\n }\n }\n return false\n})\n\nfunction rowTypeReason(t: TableRowType): string | null {\n const s = selection.value\n if (!s) return '未选择单元格'\n if (s.r1 !== s.r2) return '行类型仅支持单行设置'\n // 试算校验:在 JSON 深拷贝上执行(兼容 reactive Proxy)\n const cloned = JSON.parse(JSON.stringify(rows.value)) as TableRow[]\n return setRowType(cloned, s.r1, t)\n}\n\nfunction syncElementSize() {\n // 尺寸派生统一走共享函数:width/height 恒为列宽和/行高和(mm)\n syncTableElementSize(props.element.options)\n}\n\n/** 插入列前检查:新列复制相邻列宽,总列宽不得超过页面打印范围宽度 */\nfunction checkColWidthLimit(cw: number[], index: number): string | null {\n const maxW = editCtx.maxTableWidth.value\n const totalW = cw.reduce((s, w) => s + w, 0) + cw[index]!\n if (totalW > maxW) {\n return `插入后表格总宽 ${Math.round(totalW * 10) / 10}mm 超过打印范围宽度 ${maxW}mm,请先缩小列宽`\n }\n return null\n}\n\nfunction onMenuAction(name: string, payload?: string) {\n const s = selection.value\n if (!s) return\n menu.visible = false\n const o = props.element.options\n const rs = o.tableRows!\n const cw = o.tableColWidths!\n let err: string | null = null\n switch (name) {\n case 'insert-row-above': insertRow(rs, s.r1, 'above'); break\n case 'insert-row-below': insertRow(rs, s.r2, 'below'); break\n case 'delete-row': err = deleteRow(rs, s.r1); break\n case 'insert-col-left': err = checkColWidthLimit(cw, s.c1); if (!err) insertCol(rs, cw, s.c1, 'left'); break\n case 'insert-col-right': err = checkColWidthLimit(cw, s.c2); if (!err) insertCol(rs, cw, s.c2, 'right'); break\n case 'delete-col': err = deleteCol(rs, cw, s.c1); break\n case 'merge': mergeCells(rs, s); break\n case 'split': splitCells(rs, s); break\n case 'set-row-type':\n err = setRowType(rs, s.r1, payload as TableRowType)\n break\n }\n if (err) {\n alert(err)\n return\n }\n editCtx.setTableSelection(null) // 结构变化后选区坐标失效,清空\n syncElementSize()\n editCtx.recordHistory()\n}\n</script>\n\n<style scoped>\n.print-table {\n position: relative;\n width: 100%;\n height: 100%;\n}\n.print-table table {\n border-collapse: collapse;\n table-layout: fixed;\n width: 100%;\n}\n.print-table td {\n box-sizing: border-box;\n word-break: break-all;\n}\n.cell-selected {\n outline: 2px solid #165DFF;\n outline-offset: -2px;\n background-color: rgba(22, 93, 255, 0.08);\n}\n.row-data-bg {\n background-image: repeating-linear-gradient(\n 45deg,\n rgba(22, 93, 255, 0.04) 0 6px,\n transparent 6px 12px\n );\n}\n.data-placeholder {\n color: #909399;\n font-style: italic;\n}\n.cell-editor {\n width: 100%;\n border: none;\n outline: none;\n background: #fffbe6;\n font: inherit;\n}\n.row-badges {\n position: absolute;\n left: -16px;\n top: 0;\n width: 14px;\n}\n.row-badge {\n position: absolute;\n width: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n color: #909399;\n background: #f5f7fa;\n border-radius: 2px;\n}\n</style>\n","<template>\n <div class=\"print-line\" :style=\"lineStyle\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { RuntimeElement } from '../../types'\n\nconst props = defineProps<{\n element: RuntimeElement\n}>()\n\nconst isHline = computed(() => props.element.printElementType.type === 'hline')\n\nconst lineStyle = computed(() => {\n const o = props.element.options\n const bw = (o.borderWidth || 0.75) + 'pt'\n const bs = o.borderStyle || 'solid'\n const bc = o.borderColor || '#333'\n if (isHline.value) {\n return { width: '100%', height: '0', borderTop: `${bw} ${bs} ${bc}`, boxSizing: 'border-box' as const }\n }\n return { width: '0', height: '100%', borderLeft: `${bw} ${bs} ${bc}`, boxSizing: 'border-box' as const }\n})\n</script>","<template>\n <div class=\"print-shape\" :style=\"shapeStyle\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { RuntimeElement } from '../../types'\n\nconst props = defineProps<{\n element: RuntimeElement\n}>()\n\nconst isOval = computed(() => props.element.printElementType.type === 'oval')\n\nconst shapeStyle = computed(() => {\n const o = props.element.options\n return {\n width: '100%',\n height: '100%',\n borderWidth: (o.borderWidth || 1) + 'pt',\n borderStyle: (o.borderStyle || 'solid') as string,\n borderColor: o.borderColor || '#333',\n backgroundColor: o.backgroundColor || 'transparent',\n borderRadius: isOval.value ? '50%' : '0',\n boxSizing: 'border-box' as const,\n }\n})\n</script>\n","<template>\n <div class=\"print-barcode\" ref=\"containerRef\">\n <svg ref=\"svgRef\" preserveAspectRatio=\"xMidYMid meet\"></svg>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, watch } from 'vue'\nimport JsBarcode from 'jsbarcode'\nimport { resolveTextBinding } from '../../utils/binding'\nimport type { RuntimeElement } from '../../types'\n\nconst props = defineProps<{\n element: RuntimeElement\n data?: Record<string, any>[]\n designMode?: boolean\n}>()\n\nconst svgRef = ref<SVGSVGElement | null>(null)\n\n// 画布元素尺寸单位为 mm,浏览器 96dpi 下 1mm = 96/25.4 px\nconst MM_TO_PX = 96 / 25.4\n\nfunction render() {\n if (!svgRef.value) return\n const o = props.element.options\n const value = (props.designMode ? (o.testData || o.formatter) : resolveTextBinding(o, props.data)) || '条码'\n const showText = !o.hideTitle\n const fontSizePx = (o.fontSize || 12) * (96 / 72) // pt → px\n const totalPx = (o.height || 40) * MM_TO_PX // 元素高度 mm → px\n const textH = showText ? fontSizePx + 4 : 0 // 文本区预留\n const barH = Math.max(8, totalPx - textH) // 条码图形高度\n try {\n JsBarcode(svgRef.value, value, {\n format: (o.barcodeType || 'CODE128') as any,\n width: o.barWidth ? o.barWidth / 2 : 1,\n height: barH,\n displayValue: showText,\n fontSize: fontSizePx,\n margin: 2,\n })\n } catch { /* ignore render errors */ }\n}\n\nonMounted(render)\nwatch(\n () => [\n props.element.options.formatter,\n props.element.options.testData,\n props.element.options.barcodeType,\n props.element.options.width,\n props.element.options.height,\n props.element.options.barWidth,\n props.element.options.hideTitle,\n props.element.options.fontSize,\n ],\n render,\n)\n</script>\n\n<style scoped>\n.print-barcode { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; overflow: hidden; }\n/* JsBarcode 生成的 svg 自带 viewBox,width/height 100% 时等比缩放填满容器,随元素宽高变化 */\n.print-barcode svg { width: 100%; height: 100%; }\n</style>\n","<template>\n <div class=\"print-qrcode\">\n <img v-if=\"dataUrl\" :src=\"dataUrl\" alt=\"qrcode\" />\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, watch } from 'vue'\nimport QRCode from 'qrcode'\nimport { resolveTextBinding } from '../../utils/binding'\nimport type { RuntimeElement } from '../../types'\n\nconst props = defineProps<{\n element: RuntimeElement\n data?: Record<string, any>[]\n designMode?: boolean\n}>()\n\n// 改用 toDataURL 渲染为 <img>:纳入统一图片加载屏障,规避 canvas 在 PDF 中偶发空白\nconst dataUrl = ref('')\n\nasync function render() {\n const o = props.element.options\n const value = (props.designMode ? (o.testData || o.formatter) : resolveTextBinding(o, props.data)) || '二维码'\n const size = Math.min(o.width || 80, o.height || 80)\n try {\n dataUrl.value = await QRCode.toDataURL(value, {\n width: size,\n margin: 1,\n errorCorrectionLevel: (String(o.qrCodeLevel ?? 'M') as 'L' | 'M' | 'Q' | 'H'),\n })\n } catch {\n dataUrl.value = ''\n }\n}\n\nonMounted(render)\nwatch(() => [props.element.options.formatter, props.element.options.testData], render)\n</script>\n\n<style scoped>\n.print-qrcode { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; overflow: hidden; }\n.print-qrcode img { max-width: 100%; max-height: 100%; }\n</style>\n","<template>\n <div class=\"print-html\" v-html=\"htmlContent\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport DOMPurify from 'dompurify'\nimport type { RuntimeElement } from '../../types'\nimport { evaluateTemplate } from '../../utils/expression-eval'\n\nconst props = defineProps<{\n element: RuntimeElement\n data?: Record<string, any>[]\n designMode?: boolean\n}>()\n\nconst htmlContent = computed(() => {\n if (props.element.options.formatter) {\n const row = props.data && props.data.length > 0 ? props.data[0] : {}\n const result = evaluateTemplate(props.element.options.formatter, row ?? {})\n return result ? DOMPurify.sanitize(result) : ''\n }\n return '<div style=\"background:#e0e0e0;width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:10pt;color:#999\">HTML</div>'\n})\n</script>\n\n<style scoped>\n.print-html { width: 100%; height: 100%; overflow: hidden; }\n</style>\n","<template>\n <div class=\"page-number-element\" :style=\"textStyle\">\n {{ displayText }}\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { RuntimeElement } from '../../types'\n\nconst props = defineProps<{\n element: RuntimeElement\n data?: Record<string, any>[]\n designMode?: boolean\n}>()\n\nconst textStyle = computed(() => {\n const o = props.element.options\n return {\n fontSize: (o.fontSize || 12) + 'pt',\n fontWeight: o.fontWeight || 'normal',\n fontFamily: o.fontFamily || 'inherit',\n color: o.color || '#333',\n textAlign: (o.textAlign || 'left') as 'left' | 'center' | 'right',\n lineHeight: o.lineHeight ? o.lineHeight + 'pt' : 'normal',\n letterSpacing: o.letterSpacing ? o.letterSpacing + 'pt' : 'normal',\n }\n})\n\nconst displayText = computed(() => {\n if (props.designMode) {\n return props.element.options.title || '{pageIndex}/{totalPages}'\n }\n // 运行时由 print-render 渲染端按分页填充 {pageIndex}/{totalPages}\n return props.element.options.title || ''\n})\n</script>\n\n<style scoped>\n.page-number-element {\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n</style>\n","<template>\n <div\n ref=\"elRef\"\n class=\"print-element\"\n :class=\"{\n selected: isSelected,\n previewed: isPreviewed,\n 'design-mode': designMode,\n locked: element.options.locked,\n hidden: element.options.visible === false,\n 'drag-ghost': isDragging,\n [`type-${element.printElementType.type}`]: true,\n [`zone-${zone || 'content'}`]: true,\n }\"\n :style=\"elementStyle\"\n @mousedown.stop=\"onMouseDown\"\n @dblclick.stop=\"onDblClick\"\n @contextmenu.prevent.stop=\"$emit('contextmenu', element.id, $event)\"\n >\n <component\n :is=\"contentComponent\"\n :element=\"element\"\n :data=\"printData\"\n :design-mode=\"designMode\"\n :is-selected=\"isSelected\"\n v-bind=\"contentAttrs\"\n @dblclick-cell=\"onDblClickCell\"\n />\n\n <!-- 拖拽半透明预览副本 -->\n <div v-if=\"isDragging\" class=\"drag-preview\" />\n\n <div v-if=\"resizeEnabled\" class=\"resize-handles\">\n <div\n v-for=\"p in RESIZE_POINTS\"\n :key=\"p\"\n :class=\"['resize-handle', `handle-${p}`]\"\n @mousedown.stop=\"startResize(p, $event)\"\n />\n </div>\n\n <div v-if=\"isSelected && designMode\" class=\"selected-indicator\">\n <div class=\"position-label\">{{ posLabel }}</div>\n </div>\n <div v-if=\"designMode && bindingState\" class=\"binding-badge\" :style=\"{ color: bindingState.badgeColor }\">\n {{ bindingState.badge }}\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, inject, markRaw, reactive, ref, watchEffect, onMounted, onUnmounted } from 'vue'\nimport type { RuntimeElement, ElementRect, AdsorbResult } from '../../types'\nimport { useDrag } from '../../composables/useDrag'\nimport type { DragOptions } from '../../composables/useDrag'\nimport { generateId } from '../../utils/element-factory'\nimport { useResize, RESIZE_POINTS } from '../../composables/useResize'\nimport { useBindingDisplay } from '../../composables/useBindingDisplay'\nimport { SELECTED_IDS_KEY, PREVIEW_IDS_KEY } from '../../composables/useSelection'\nimport TextElement from './TextElement.vue'\nimport ImageElement from './ImageElement.vue'\nimport LongTextElement from './LongTextElement.vue'\nimport TableElement from './TableElement.vue'\nimport LineElement from './LineElement.vue'\nimport ShapeElement from './ShapeElement.vue'\nimport BarcodeElement from './BarcodeElement.vue'\nimport QrcodeElement from './QrcodeElement.vue'\nimport HtmlElement from './HtmlElement.vue'\nimport PageNumberElement from './PageNumberElement.vue'\n\nconst props = defineProps<{\n element: RuntimeElement\n /** @deprecated 通过 inject 获取,保留用于向后兼容 */\n isSelected?: boolean\n designMode?: boolean\n printData?: Record<string, any>[]\n scale?: number\n allElements?: RuntimeElement[]\n snapToGrid?: boolean\n /** 设计态下无边框表格单元格的虚拟虚线开关(透传给 TableElement) */\n showTableGhostBorder?: boolean\n /** 元素所在区域(影响设计态边框颜色) */\n zone?: 'content' | 'header' | 'footer' | 'overlay'\n /** 由 CanvasPaper 层吸附管理器提供:同步返回吸附修正结果并渲染引导线 */\n adsorbHandler?: (rect: ElementRect) => AdsorbResult\n clearAdsorbGuides?: () => void\n}>()\n\nconst emit = defineEmits<{\n select: [id: string, multiple: boolean]\n 'update:element': [element: RuntimeElement]\n 'drag-start': []\n 'drag-stop': []\n 'dblclick-element': [id: string]\n 'dblclick-cell': [elementId: string, r: number, c: number]\n 'contextmenu': [id: string, e: MouseEvent]\n 'clone-element': [element: RuntimeElement, position: { left: number; top: number }]\n}>()\n\nconst elRef = ref<HTMLElement | null>(null)\n\n// 通过 inject 精确追踪自身选中状态,避免父组件因 selectedIds 变化全量重渲染\nconst injectedSelectedIds = inject(SELECTED_IDS_KEY, null)\nconst isSelected = computed(() => {\n if (injectedSelectedIds?.value) {\n return injectedSelectedIds.value.has(props.element.id)\n }\n return props.isSelected ?? false\n})\n\n// 框选实时预选高亮(未提交前)\nconst injectedPreviewIds = inject(PREVIEW_IDS_KEY, null)\nconst isPreviewed = computed(() => injectedPreviewIds?.value.has(props.element.id) ?? false)\n\nconst componentMap: Record<string, any> = {\n text: markRaw(TextElement),\n image: markRaw(ImageElement),\n longText: markRaw(LongTextElement),\n table: markRaw(TableElement),\n hline: markRaw(LineElement),\n vline: markRaw(LineElement),\n rect: markRaw(ShapeElement),\n oval: markRaw(ShapeElement),\n barcode: markRaw(BarcodeElement),\n qrcode: markRaw(QrcodeElement),\n html: markRaw(HtmlElement),\n pageNumber: markRaw(PageNumberElement),\n}\n\nconst { getBindingDisplayState } = useBindingDisplay()\n\nconst bindingState = computed(() => {\n if (!props.designMode) return null\n return getBindingDisplayState(props.element)\n})\n\nconst contentComponent = computed(() => componentMap[props.element.printElementType.type])\n\n/** 仅表格元素需要虚拟虚线开关,避免其它元素根节点出现无关 attribute */\nconst contentAttrs = computed(() =>\n props.element.printElementType.type === 'table'\n ? { showTableGhostBorder: props.showTableGhostBorder }\n : {},\n)\n\nconst elementStyle = computed(() => {\n const o = props.element.options\n return {\n position: 'absolute' as const,\n left: o.left + 'mm',\n top: o.top + 'mm',\n width: o.width + 'mm',\n height: o.height + 'mm',\n zIndex: o.zIndex || 'auto',\n }\n})\n\nconst posLabel = computed(() => {\n const o = props.element.options\n return `x:${Math.round(o.left)} y:${Math.round(o.top)} ${Math.round(o.width)}×${Math.round(o.height)}mm`\n})\n\n// 吸附检测与引导线由 CanvasPaper 层的 useAdsorbManager 统一管理\n\n// 拖拽:拖拽期间用 CSS transform 做视觉跟随,不触发响应式更新;\n// mouseup 时通过 onDragEnd 一次性写入最终坐标。\nlet dragStartLeft = 0\nlet dragStartTop = 0\nconst dragConfig = reactive<DragOptions>({\n disabled: !props.designMode || !!props.element.options.locked,\n getScale: () => props.scale || 1,\n // 拖拽中:仅设置 style.transform,不修改响应式数据\n onDrag: (pos) => {\n const dx = pos.left - dragStartLeft\n const dy = pos.top - dragStartTop\n if (elRef.value) {\n elRef.value.style.transform = `translate(${dx}mm, ${dy}mm)`\n }\n // 同组元素拖拽跟随:拖拽期间不处理,mouseup 时通过 onDragEnd 一次性更新响应式坐标\n },\n // 拖拽结束:一次性写入最终坐标,清除 transform\n onDragEnd: (pos, info) => {\n // Alt+拖拽:在落点生成副本,原元素留在原位不动\n if (info.altKey) {\n const clone = JSON.parse(JSON.stringify(props.element)) as RuntimeElement\n clone.id = generateId()\n clone.options.left = pos.left\n clone.options.top = pos.top\n // 通过 emit 事件通知父组件处理克隆,而非直接操作 props\n emit('clone-element', clone, { left: pos.left, top: pos.top })\n if (elRef.value) {\n elRef.value.style.transform = ''\n }\n return\n }\n const finalDx = pos.left - dragStartLeft\n const finalDy = pos.top - dragStartTop\n // 写入主元素响应式坐标\n props.element.options.left = pos.left\n props.element.options.top = pos.top\n if (elRef.value) {\n elRef.value.style.transform = ''\n }\n // 同组元素一次性更新坐标(响应式写入,Vue 自动刷新 DOM)\n if (props.element.options.groupId && props.allElements) {\n for (const sibling of props.allElements) {\n if (sibling.id !== props.element.id && sibling.options.groupId === props.element.options.groupId) {\n sibling.options.left += finalDx\n sibling.options.top += finalDy\n }\n }\n }\n },\n onStart: () => {\n // 记录拖拽起始坐标(用于计算 transform 偏移量)\n dragStartLeft = props.element.options.left\n dragStartTop = props.element.options.top\n emit('select', props.element.id, false)\n emit('drag-start')\n },\n onStop: () => {\n props.clearAdsorbGuides?.()\n emit('drag-stop')\n },\n onAdsorb: (pos) => {\n // 网格吸附\n let left = pos.left\n let top = pos.top\n if (props.snapToGrid) {\n const grid = 5 // 5mm\n left = Math.round(pos.left / grid) * grid\n top = Math.round(pos.top / grid) * grid\n }\n\n // 元素间吸附交给 CanvasPaper 层管理器(含引导线渲染)\n if (props.adsorbHandler) {\n return props.adsorbHandler({\n id: props.element.id,\n left,\n top,\n width: props.element.options.width,\n height: props.element.options.height,\n })\n }\n return { left, top, lines: [] }\n },\n})\nconst { setup: setupDrag, cleanup: cleanupDrag, isDragging } = useDrag(elRef, dragConfig)\n\n// 锁定/设计态变化时自动同步拖拽禁用标志(useDrag.onMouseDown 实时读取 dragConfig.disabled)\nwatchEffect(() => {\n dragConfig.disabled = !props.designMode || !!props.element.options.locked\n})\n\n// 缩放:手柄由模板渲染,resizeEnabled 控制显隐;table 尺寸由列宽/行高派生,禁用缩放\nconst resizeEnabled = computed(\n () =>\n isSelected.value &&\n !!props.designMode &&\n !props.element.options.locked &&\n props.element.printElementType.type !== 'table',\n)\n\nconst { startResize, cleanup: cleanupResize } = useResize({\n minWidth: 3.5,\n minHeight: 3.5,\n getScale: () => props.scale || 1,\n getRect: () => ({\n left: props.element.options.left,\n top: props.element.options.top,\n width: props.element.options.width,\n height: props.element.options.height,\n }),\n onResize: (rect) => {\n props.element.options.left = rect.left\n props.element.options.top = rect.top\n props.element.options.width = rect.width\n props.element.options.height = rect.height\n },\n // 复用 drag-start/drag-stop 事件链记录历史:onStart 记录缩放前快照,\n // onStop 触发 PrintDesigner.onDragStop 的前后对比(含 width/height)入栈。\n onStart: () => {\n emit('drag-start')\n },\n onStop: () => {\n emit('drag-stop')\n },\n})\n\nfunction onMouseDown(e: MouseEvent) {\n if (!props.designMode) return\n emit('select', props.element.id, e.ctrlKey || e.metaKey)\n}\n\nfunction onDblClick() {\n if (!props.designMode) return\n emit('dblclick-element', props.element.id)\n}\n\n/** 表格单元格双击转发(仅表格元素的 TableElement 会触发) */\nfunction onDblClickCell(elementId: string, r: number, c: number) {\n if (!props.designMode) return\n emit('dblclick-cell', elementId, r, c)\n}\n\nonMounted(() => {\n // 始终挂载拖拽监听:useDrag.onMouseDown 在事件触发时实时读取 dragConfig.disabled,\n // 即使元素加载时 locked:true 也能正确门控;解锁后 locked watcher 更新 disabled 即生效。\n if (props.designMode) {\n setupDrag()\n }\n})\n\nfunction cleanup() {\n cleanupDrag()\n cleanupResize()\n props.clearAdsorbGuides?.()\n}\n\nonUnmounted(() => {\n cleanup()\n})\n</script>\n\n<style scoped>\n.print-element {\n box-sizing: border-box;\n cursor: pointer;\n user-select: none;\n}\n/* 设计态下所有元素显示浅灰虚线边框,标示占位空间大小 */\n.print-element.design-mode {\n outline: 1px dashed #C3C9D6;\n}\n/* 页眉/页脚区域元素:油墨绿虚线 */\n.print-element.design-mode.zone-header,\n.print-element.design-mode.zone-footer {\n outline: 1px dashed var(--pd-ink-green, #67c23a);\n}\n/* 首页叠加区域元素:青色虚线 */\n.print-element.design-mode.zone-overlay {\n outline: 1px dashed #06B6D4;\n}\n.print-element.selected {\n outline: 1.5px solid var(--pd-accent, #165DFF);\n background: rgba(22, 93, 255, 0.04);\n}\n/* 框选实时预选:墨蓝高亮(未提交) */\n.print-element.previewed {\n outline: 1.5px solid rgba(22, 93, 255, 0.5);\n background: rgba(22, 93, 255, 0.1);\n}\n.print-element.design-mode:hover {\n outline: 1px dashed var(--pd-accent, #165DFF);\n}\n.print-element.locked {\n cursor: not-allowed;\n}\n.print-element.locked:not(.selected) {\n outline: 1.5px dashed #999;\n}\n.print-element.hidden {\n opacity: 0.3;\n pointer-events: none;\n}\n/* 拖拽半透明预览:拖拽中元素变淡,叠加虚线副本框 */\n.print-element.drag-ghost {\n opacity: 0.4;\n}\n.drag-preview {\n position: absolute;\n inset: 0;\n border: 2px dashed var(--pd-accent, #165DFF);\n pointer-events: none;\n z-index: 1000;\n box-sizing: border-box;\n}\n.selected-indicator {\n position: absolute;\n top: -18px;\n left: 0;\n font-size: 10px;\n white-space: nowrap;\n pointer-events: none;\n z-index: 20;\n}\n.position-label {\n background: var(--pd-accent, #165DFF);\n color: #fff;\n padding: 1px 6px;\n border-radius: 3px;\n font-family: ui-monospace, 'SF Mono', Menlo, monospace;\n font-size: 10px;\n font-variant-numeric: tabular-nums;\n letter-spacing: 0;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);\n}\n.binding-badge {\n position: absolute;\n top: -1px;\n left: -1px;\n font-size: 9px;\n font-family: monospace;\n padding: 1px 4px;\n background: rgba(255, 255, 255, 0.92);\n border: 1px solid currentColor;\n border-radius: 2px;\n line-height: 1.4;\n max-width: calc(100% - 4px);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n pointer-events: none;\n z-index: 1;\n}\n.resize-handles {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n.resize-handle {\n position: absolute;\n width: 7px;\n height: 7px;\n background: var(--pd-handle, #165DFF);\n border: 1.5px solid #fff;\n border-radius: 2px;\n box-sizing: border-box;\n transform: translate(-50%, -50%);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18);\n z-index: 10;\n pointer-events: auto;\n}\n.handle-nw { top: 0; left: 0; cursor: nw-resize; }\n.handle-n { top: 0; left: 50%; cursor: n-resize; }\n.handle-ne { top: 0; left: 100%; cursor: ne-resize; }\n.handle-e { top: 50%; left: 100%; cursor: e-resize; }\n.handle-se { top: 100%; left: 100%; cursor: se-resize; }\n.handle-s { top: 100%; left: 50%; cursor: s-resize; }\n.handle-sw { top: 100%; left: 0; cursor: sw-resize; }\n.handle-w { top: 50%; left: 0; cursor: w-resize; }\n</style>\n","export interface RulerTick {\n mm: number\n major: boolean\n label?: string\n}\n\n/** 生成标尺刻度:5mm 小刻度,10mm 大刻度 + 数字标签 */\nexport function buildRulerTicks(lengthMM: number): RulerTick[] {\n const ticks: RulerTick[] = []\n for (let mm = 0; mm <= lengthMM + 1e-9; mm += 5) {\n const rounded = Math.round(mm * 100) / 100\n const major = rounded % 10 === 0\n if (major) {\n ticks.push({ mm: rounded, major, label: String(rounded) })\n } else {\n ticks.push({ mm: rounded, major })\n }\n }\n return ticks\n}\n","<template>\n <canvas ref=\"canvasRef\" class=\"pd-ruler\" :style=\"cssSize\" @mousedown=\"onDown\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, onMounted } from 'vue'\nimport { buildRulerTicks } from '../utils/ruler'\n\nconst MM_TO_PX = 96 / 25.4\nconst THICKNESS = 16\n\nconst props = defineProps<{\n orientation: 'horizontal' | 'vertical'\n lengthMM: number\n scale?: number\n}>()\nconst emit = defineEmits<{ 'add-guide': [type: 'vertical' | 'horizontal', positionMm: number] }>()\n\nconst canvasRef = ref<HTMLCanvasElement | null>(null)\n\nconst cssSize = computed(() => {\n if (props.orientation === 'horizontal') {\n return { width: props.lengthMM + 'mm', height: THICKNESS + 'px' }\n }\n return { width: THICKNESS + 'px', height: props.lengthMM + 'mm' }\n})\n\nfunction draw() {\n const canvas = canvasRef.value\n if (!canvas) return\n const dpr = window.devicePixelRatio || 1\n const lengthPx = props.lengthMM * MM_TO_PX\n const horizontal = props.orientation === 'horizontal'\n canvas.width = (horizontal ? lengthPx : THICKNESS) * dpr\n canvas.height = (horizontal ? THICKNESS : lengthPx) * dpr\n const ctx = canvas.getContext('2d')\n if (!ctx) return\n ctx.scale(dpr, dpr)\n\n const style = getComputedStyle(canvas)\n const bg = style.getPropertyValue('--pd-ruler-bg').trim() || '#FFFFFF'\n const fg = style.getPropertyValue('--pd-ruler').trim() || '#9CA3AF'\n\n ctx.fillStyle = bg\n ctx.fillRect(0, 0, horizontal ? lengthPx : THICKNESS, horizontal ? THICKNESS : lengthPx)\n\n ctx.strokeStyle = fg\n ctx.fillStyle = fg\n ctx.lineWidth = 1\n ctx.font = '8px ui-monospace, Menlo, monospace'\n\n for (const tick of buildRulerTicks(props.lengthMM)) {\n const pos = Math.round(tick.mm * MM_TO_PX) + 0.5\n const len = tick.major ? 8 : 4\n ctx.beginPath()\n if (horizontal) {\n ctx.moveTo(pos, 0)\n ctx.lineTo(pos, len)\n } else {\n ctx.moveTo(0, pos)\n ctx.lineTo(len, pos)\n }\n ctx.stroke()\n if (tick.major && tick.label) {\n if (horizontal) {\n ctx.fillText(tick.label, pos + 2, 14)\n } else {\n ctx.save()\n ctx.translate(12, pos + 2)\n ctx.rotate(-Math.PI / 2)\n ctx.fillText(tick.label, -ctx.measureText(tick.label).width, 0)\n ctx.restore()\n }\n }\n }\n}\n\nwatch(() => [props.lengthMM, props.orientation], draw)\nonMounted(draw)\n\n// ─── 拖出生成参考线 ───\nlet dragging = false\nfunction onDown(e: MouseEvent) {\n dragging = true\n e.preventDefault()\n window.addEventListener('mousemove', onMove)\n window.addEventListener('mouseup', onUp)\n}\nfunction onMove() {\n // 拖动中不显示预览,mouseup 时生成\n}\nfunction onUp(e: MouseEvent) {\n if (!dragging) return\n dragging = false\n window.removeEventListener('mousemove', onMove)\n window.removeEventListener('mouseup', onUp)\n const canvas = canvasRef.value\n if (!canvas) return\n const rect = canvas.getBoundingClientRect()\n const s = props.scale ?? 1\n const offset = props.orientation === 'horizontal'\n ? (e.clientX - rect.left) / s\n : (e.clientY - rect.top) / s\n const posMM = offset / MM_TO_PX\n if (posMM > 0 && posMM < props.lengthMM) {\n emit('add-guide', props.orientation === 'horizontal' ? 'horizontal' : 'vertical', posMM)\n }\n}\n</script>\n\n<style scoped>\n.pd-ruler {\n position: absolute;\n top: 0;\n left: 0;\n pointer-events: auto;\n cursor: crosshair;\n z-index: 5;\n display: block;\n}\n/* 横尺压下沿、竖尺压右沿,构成 L 型制图尺框 */\n.pd-ruler:nth-of-type(1) {\n box-shadow: 0 1px 0 var(--pd-border-soft, #e9ecf2);\n}\n.pd-ruler:nth-of-type(2) {\n box-shadow: 1px 0 0 var(--pd-border-soft, #e9ecf2);\n}\n</style>\n","// web/src/components/print/composables/useAdsorb.ts\nimport { ref, type Ref } from 'vue'\nimport type { ElementRect, AlignLine, AdsorbResult } from '../types'\n\nexport interface AdsorbConfig {\n adsorbMin?: number\n adsorbLineMin?: number\n showAdsorbLine?: boolean\n}\n\nexport function useAdsorb(config: AdsorbConfig = {}) {\n const adsorbMin = config.adsorbMin ?? 1\n const adsorbLineMin = config.adsorbLineMin ?? 2\n const showAdsorbLine = config.showAdsorbLine ?? true\n\n /** 引导线响应式数据,由模板 v-for 渲染 */\n const guideLines: Ref<AlignLine[]> = ref([])\n\n /** 纸张尺寸(mm),用于引导线贯穿整页 */\n const paperSize = ref({ width: 0, height: 0 })\n\n /** 对齐类型颜色:左/顶端蓝,居中绿,右/底橘 */\n const SNAP_COLORS: Record<'left' | 'center' | 'right' | 'top' | 'middle' | 'bottom', string> = {\n left: '#3b82f6',\n center: '#10b981',\n right: '#f59e0b',\n top: '#3b82f6',\n middle: '#10b981',\n bottom: '#f59e0b',\n }\n\n /** 根据移动元素对齐点(mk)返回引导线颜色 */\n function snapColor(mk: string): string {\n if (mk === 'vCenter') return SNAP_COLORS.center\n if (mk === 'hCenter') return SNAP_COLORS.middle\n return SNAP_COLORS[mk as keyof typeof SNAP_COLORS] ?? SNAP_COLORS.left\n }\n\n function check(\n movingRect: ElementRect,\n others: ElementRect[],\n guideLines?: { vertical: number[]; horizontal: number[] },\n ): AdsorbResult {\n let left = movingRect.left\n let top = movingRect.top\n const lines: AlignLine[] = []\n\n const m = {\n left: movingRect.left,\n right: movingRect.left + movingRect.width,\n vCenter: movingRect.left + movingRect.width / 2,\n top: movingRect.top,\n bottom: movingRect.top + movingRect.height,\n hCenter: movingRect.top + movingRect.height / 2,\n }\n\n let minDist = Infinity\n\n for (const other of others) {\n if (other.id === movingRect.id) continue\n const o = {\n left: other.left,\n right: other.left + other.width,\n vCenter: other.left + other.width / 2,\n top: other.top,\n bottom: other.top + other.height,\n hCenter: other.top + other.height / 2,\n }\n\n const hPairs: [keyof typeof m, keyof typeof o][] = [\n ['left', 'left'], ['left', 'vCenter'], ['left', 'right'],\n ['vCenter', 'left'], ['vCenter', 'vCenter'], ['vCenter', 'right'],\n ['right', 'left'], ['right', 'vCenter'], ['right', 'right'],\n ]\n const vPairs: [keyof typeof m, keyof typeof o][] = [\n ['top', 'top'], ['top', 'hCenter'], ['top', 'bottom'],\n ['hCenter', 'top'], ['hCenter', 'hCenter'], ['hCenter', 'bottom'],\n ['bottom', 'top'], ['bottom', 'hCenter'], ['bottom', 'bottom'],\n ]\n\n for (const [mk, ok] of hPairs) {\n const dist = Math.abs(m[mk] - o[ok])\n if (dist <= adsorbMin && dist < minDist) {\n minDist = dist\n left = movingRect.left + (o[ok] - m[mk])\n }\n }\n for (const [mk, ok] of vPairs) {\n const dist = Math.abs(m[mk] - o[ok])\n if (dist <= adsorbMin && dist < minDist) {\n minDist = dist\n top = movingRect.top + (o[ok] - m[mk])\n }\n }\n }\n\n // 手动参考线吸附:垂直参考线(position=X)参与水平方向,水平参考线参与垂直方向\n if (guideLines) {\n const m2 = {\n left, right: left + movingRect.width, vCenter: left + movingRect.width / 2,\n top, bottom: top + movingRect.height, hCenter: top + movingRect.height / 2,\n }\n const hKeys: (keyof typeof m2)[] = ['left', 'vCenter', 'right']\n for (const pos of guideLines.vertical) {\n for (const k of hKeys) {\n const d = Math.abs(m2[k] - pos)\n if (d <= adsorbMin && d < minDist) { minDist = d; left = movingRect.left + (pos - m2[k]) }\n }\n }\n const vKeys: (keyof typeof m2)[] = ['top', 'hCenter', 'bottom']\n for (const pos of guideLines.horizontal) {\n for (const k of vKeys) {\n const d = Math.abs(m2[k] - pos)\n if (d <= adsorbMin && d < minDist) { minDist = d; top = movingRect.top + (pos - m2[k]) }\n }\n }\n }\n\n const adjustedM = {\n left, right: left + movingRect.width,\n vCenter: left + movingRect.width / 2,\n top, bottom: top + movingRect.height,\n hCenter: top + movingRect.height / 2,\n }\n\n if (showAdsorbLine) {\n const seen = new Set<string>()\n for (const other of others) {\n if (other.id === movingRect.id) continue\n const o = {\n left: other.left,\n right: other.left + other.width,\n vCenter: other.left + other.width / 2,\n top: other.top,\n bottom: other.top + other.height,\n hCenter: other.top + other.height / 2,\n }\n\n const hPairs: [keyof typeof adjustedM, keyof typeof o][] = [\n ['left', 'left'], ['left', 'vCenter'], ['left', 'right'],\n ['vCenter', 'left'], ['vCenter', 'vCenter'], ['vCenter', 'right'],\n ['right', 'left'], ['right', 'vCenter'], ['right', 'right'],\n ]\n const vPairs: [keyof typeof adjustedM, keyof typeof o][] = [\n ['top', 'top'], ['top', 'hCenter'], ['top', 'bottom'],\n ['hCenter', 'top'], ['hCenter', 'hCenter'], ['hCenter', 'bottom'],\n ['bottom', 'top'], ['bottom', 'hCenter'], ['bottom', 'bottom'],\n ]\n\n for (const [mk, ok] of hPairs) {\n const dist = Math.abs(adjustedM[mk] - o[ok])\n // 吸附(dist <= adsorbMin)或近距(adsorbMin < dist <= adsorbLineMin)均绘制竖直引导线\n if (dist <= adsorbLineMin) {\n const key = `v:${o[ok]}`\n if (!seen.has(key)) {\n seen.add(key)\n lines.push({ type: 'vertical', position: o[ok], id: other.id, color: snapColor(mk) })\n }\n }\n }\n for (const [mk, ok] of vPairs) {\n const dist = Math.abs(adjustedM[mk] - o[ok])\n if (dist <= adsorbLineMin) {\n const key = `h:${o[ok]}`\n if (!seen.has(key)) {\n seen.add(key)\n lines.push({ type: 'horizontal', position: o[ok], id: other.id, color: snapColor(mk) })\n }\n }\n }\n }\n }\n\n if (guideLines) {\n for (const pos of guideLines.vertical) {\n if (!lines.some(l => l.type === 'vertical' && l.position === pos)) {\n lines.push({ type: 'vertical', position: pos })\n }\n }\n for (const pos of guideLines.horizontal) {\n if (!lines.some(l => l.type === 'horizontal' && l.position === pos)) {\n lines.push({ type: 'horizontal', position: pos })\n }\n }\n }\n\n return { left, top, lines }\n }\n\n /** 更新引导线(Vue 响应式,不再直接操作 DOM) */\n function renderLines(lines: AlignLine[], paperW: number, paperH: number) {\n guideLines.value = lines\n paperSize.value = { width: paperW, height: paperH }\n }\n\n /** 清除引导线 */\n function clearLines() {\n guideLines.value = []\n }\n\n return { check, renderLines, clearLines, guideLines, paperSize }\n}\n","// web/src/components/print/composables/useAdsorbManager.ts\n// 吸附管理器:在 CanvasPaper 层创建单例,统一处理吸附检测与引导线渲染\n// BaseElement 拖拽时通过函数 props 调用 requestAdsorb / clearGuides\nimport type { RuntimeElement, ElementRect, AdsorbResult } from '../types'\nimport { useAdsorb, type AdsorbConfig } from './useAdsorb'\n\nexport interface AdsorbManagerOptions {\n getElements: () => RuntimeElement[]\n /** 纸张尺寸(mm),用于引导线贯穿整页 */\n getPaperSize: () => { width: number; height: number }\n /** 手动参考线位置(mm),参与吸附 */\n getGuides?: () => { vertical: number[]; horizontal: number[] }\n config?: AdsorbConfig\n}\n\nexport function useAdsorbManager(options: AdsorbManagerOptions) {\n const { check, renderLines, clearLines, guideLines, paperSize } = useAdsorb(\n options.config ?? { adsorbMin: 1, adsorbLineMin: 2, showAdsorbLine: true }\n )\n\n function requestAdsorb(movingRect: ElementRect): AdsorbResult {\n const others = options.getElements()\n .filter(e => e.id !== movingRect.id)\n .map(e => ({\n id: e.id,\n left: e.options.left,\n top: e.options.top,\n width: e.options.width,\n height: e.options.height,\n } as ElementRect))\n const result = check(movingRect, others, options.getGuides?.())\n const paper = options.getPaperSize()\n renderLines(result.lines, paper.width, paper.height)\n return result\n }\n\n function clearGuides() {\n clearLines()\n }\n\n return { requestAdsorb, clearGuides, guideLines, paperSize }\n}\n","<template>\n <div\n class=\"hiprint-printPaper\"\n :style=\"paperStyle\"\n >\n <div\n class=\"hiprint-printPaper-content\"\n ref=\"contentRef\"\n :style=\"contentStyle\"\n >\n <!-- 刻度标尺 -->\n <template v-if=\"showRulerComputed\">\n <Ruler orientation=\"horizontal\" :length-m-m=\"paperWidthMM\" :scale=\"scale\" @add-guide=\"(t: 'vertical' | 'horizontal', p: number) => emit('add-guide', t, p)\" />\n <Ruler orientation=\"vertical\" :length-m-m=\"paperHeightMM\" :scale=\"scale\" @add-guide=\"(t: 'vertical' | 'horizontal', p: number) => emit('add-guide', t, p)\" />\n </template>\n <!-- 网格背景 -->\n <div\n v-if=\"showGrid && designMode\"\n class=\"grid-bg\"\n :style=\"gridBgStyle\"\n />\n <!-- 吸附高亮指示点(吸附发生时闪烁) -->\n <div\n v-if=\"snapIndicator\"\n :key=\"snapIndicator.key\"\n class=\"snap-indicator\"\n :style=\"{\n left: snapIndicator.left + 'mm',\n top: snapIndicator.top + 'mm',\n }\"\n />\n\n <!-- 水印渲染层(在所有元素之下) -->\n <div\n v-if=\"watermarkVisible\"\n class=\"watermark-layer\"\n :style=\"watermarkStyle\"\n />\n\n <!-- ─── 三段式区域层:上边距→页眉→内容→页脚→下边距 ─── -->\n <!-- 页眉层 -->\n <div\n class=\"zone-layer zone-header\"\n :class=\"{ 'design-mode': designMode }\"\n :style=\"layerStyle(zoneRectsMM.header)\"\n >\n <span v-if=\"designMode\" class=\"zone-label\">页眉</span>\n <BaseElement\n v-for=\"el in headerElements\"\n :key=\"el.id\"\n :element=\"el\"\n :design-mode=\"designMode\"\n :print-data=\"printData\"\n :scale=\"scale\"\n :all-elements=\"headerElements\"\n :snap-to-grid=\"snapToGrid\"\n :show-table-ghost-border=\"showTableGhostBorder\"\n zone=\"header\"\n :adsorb-handler=\"requestAdsorb\"\n :clear-adsorb-guides=\"clearGuides\"\n @select=\"onSelectElement\"\n @drag-start=\"$emit('drag-start')\"\n @drag-stop=\"$emit('drag-stop')\"\n @dblclick-element=\"(id: string) => $emit('dblclick-element', id)\"\n @dblclick-cell=\"(id: string, r: number, c: number) => $emit('dblclick-cell', id, r, c)\"\n @contextmenu=\"(id: string, e: MouseEvent) => $emit('contextmenu', id, e)\"\n @clone-element=\"(el, pos) => $emit('clone-element', el, pos)\"\n />\n <div\n v-if=\"designMode\"\n class=\"zone-resize-handle handle-bottom\"\n @mousedown.prevent.stop=\"startZoneResize('header', $event)\"\n >\n <div v-if=\"zoneResizing?.zone === 'header'\" class=\"zone-height-tip\">\n {{ templateData.header.height.toFixed(1) }}mm\n </div>\n </div>\n </div>\n\n <!-- 内容层 -->\n <div\n class=\"zone-layer zone-content\"\n :class=\"{ 'design-mode': designMode }\"\n :style=\"layerStyle(zoneRectsMM.content)\"\n >\n <!-- 首页叠加占位(本次不可编辑) -->\n <div\n v-if=\"designMode && templateData.firstPageOverlay.height > 0\"\n class=\"zone-overlay\"\n :style=\"{ height: templateData.firstPageOverlay.height + 'mm' }\"\n >\n <span class=\"zone-label\">首页叠加</span>\n </div>\n <BaseElement\n v-for=\"el in contentElements\"\n :key=\"el.id\"\n :element=\"el\"\n :design-mode=\"designMode\"\n :print-data=\"printData\"\n :scale=\"scale\"\n :all-elements=\"contentElements\"\n :snap-to-grid=\"snapToGrid\"\n :show-table-ghost-border=\"showTableGhostBorder\"\n zone=\"content\"\n :adsorb-handler=\"requestAdsorb\"\n :clear-adsorb-guides=\"clearGuides\"\n @select=\"onSelectElement\"\n @drag-start=\"$emit('drag-start')\"\n @drag-stop=\"$emit('drag-stop')\"\n @dblclick-element=\"(id: string) => $emit('dblclick-element', id)\"\n @dblclick-cell=\"(id: string, r: number, c: number) => $emit('dblclick-cell', id, r, c)\"\n @contextmenu=\"(id: string, e: MouseEvent) => $emit('contextmenu', id, e)\"\n @clone-element=\"(el, pos) => $emit('clone-element', el, pos)\"\n />\n </div>\n\n <!-- 页脚层 -->\n <div\n class=\"zone-layer zone-footer\"\n :class=\"{ 'design-mode': designMode }\"\n :style=\"layerStyle(zoneRectsMM.footer)\"\n >\n <span v-if=\"designMode\" class=\"zone-label\">页脚</span>\n <BaseElement\n v-for=\"el in footerElements\"\n :key=\"el.id\"\n :element=\"el\"\n :design-mode=\"designMode\"\n :print-data=\"printData\"\n :scale=\"scale\"\n :all-elements=\"footerElements\"\n :snap-to-grid=\"snapToGrid\"\n :show-table-ghost-border=\"showTableGhostBorder\"\n zone=\"footer\"\n :adsorb-handler=\"requestAdsorb\"\n :clear-adsorb-guides=\"clearGuides\"\n @select=\"onSelectElement\"\n @drag-start=\"$emit('drag-start')\"\n @drag-stop=\"$emit('drag-stop')\"\n @dblclick-element=\"(id: string) => $emit('dblclick-element', id)\"\n @dblclick-cell=\"(id: string, r: number, c: number) => $emit('dblclick-cell', id, r, c)\"\n @contextmenu=\"(id: string, e: MouseEvent) => $emit('contextmenu', id, e)\"\n @clone-element=\"(el, pos) => $emit('clone-element', el, pos)\"\n />\n <div\n v-if=\"designMode\"\n class=\"zone-resize-handle handle-top\"\n @mousedown.prevent.stop=\"startZoneResize('footer', $event)\"\n >\n <div v-if=\"zoneResizing?.zone === 'footer'\" class=\"zone-height-tip\">\n {{ templateData.footer.height.toFixed(1) }}mm\n </div>\n </div>\n </div>\n\n <!-- 吸附引导线(v-for 渲染,拖拽结束后自动清除) -->\n <div\n v-for=\"(line, idx) in guideLines\"\n :key=\"idx\"\n class=\"adsorb-guide\"\n :class=\"[`guide-${line.type}`]\"\n :style=\"line.type === 'vertical'\n ? { left: line.position + 'mm', top: '0', height: guidePaperSize.height + 'mm', borderLeftColor: line.color || 'var(--pd-accent-secondary, #f56c6c)' }\n : { top: line.position + 'mm', left: '0', width: guidePaperSize.width + 'mm', borderTopColor: line.color || 'var(--pd-accent-secondary, #f56c6c)' }\"\n />\n <!-- 手动参考线(常驻,可拖动/双击删除) -->\n <div\n v-for=\"g in guides\"\n :key=\"'mg-' + g.id\"\n class=\"manual-guide\"\n :class=\"[`guide-${g.type}`]\"\n :style=\"g.type === 'vertical'\n ? { left: g.position + 'mm', top: '0', height: paperHeightMM + 'mm' }\n : { top: g.position + 'mm', left: '0', width: paperWidthMM + 'mm' }\"\n @mousedown.prevent.stop=\"onGuideDown($event, g)\"\n @dblclick.prevent.stop=\"g.id && emit('guide-remove', g.id)\"\n />\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, onUnmounted } from 'vue'\nimport type { RuntimeElement, TemplateData, ElementRect, ElementZone, AlignLine } from '../types'\nimport { getPaperDimensions } from '../utils/default-config'\nimport BaseElement from './elements/BaseElement.vue'\nimport Ruler from './Ruler.vue'\nimport { useAdsorbManager } from '../composables/useAdsorbManager'\n\nconst props = defineProps<{\n templateData: TemplateData\n runtimeElements: RuntimeElement[]\n designMode?: boolean\n printData?: Record<string, any>[]\n scale?: number\n showRuler?: boolean\n showGrid?: boolean\n snapToGrid?: boolean\n showTableGhostBorder?: boolean\n guides?: AlignLine[]\n}>()\n\nconst emit = defineEmits<{\n select: [id: string, multiple: boolean]\n 'drag-start': []\n 'drag-stop': []\n 'dblclick-element': [id: string]\n 'dblclick-cell': [elementId: string, r: number, c: number]\n 'contextmenu': [id: string, e: MouseEvent]\n 'zone-height-change': [zone: 'header' | 'footer', height: number]\n 'zone-height-commit': [zone: 'header' | 'footer']\n 'add-guide': [type: 'vertical' | 'horizontal', positionMm: number]\n 'guide-move': [id: string, positionMm: number]\n 'guide-remove': [id: string]\n 'clone-element': [element: RuntimeElement, position: { left: number; top: number }]\n}>()\n\nconst contentRef = ref<HTMLElement | null>(null)\n\n/** 根据纸张尺寸和方向计算宽高(mm) */\nconst paperWidthMM = computed(() => {\n return getPaperDimensions(props.templateData).width\n})\nconst paperHeightMM = computed(() => {\n return getPaperDimensions(props.templateData).height\n})\n\n/** 三区矩形(mm,纸面坐标系):上边距→页眉→内容→页脚→下边距 */\nconst zoneRectsMM = computed(() => {\n const m = props.templateData.margins\n const headerH = props.templateData.header.height\n const footerH = props.templateData.footer.height\n const contentW = paperWidthMM.value - m.left - m.right\n return {\n header: { left: m.left, top: m.top, width: contentW, height: headerH },\n content: {\n left: m.left,\n top: m.top + headerH,\n width: contentW,\n height: paperHeightMM.value - m.top - m.bottom - headerH - footerH,\n },\n footer: {\n left: m.left,\n top: paperHeightMM.value - m.bottom - footerH,\n width: contentW,\n height: footerH,\n },\n }\n})\n\nfunction layerStyle(r: { left: number; top: number; width: number; height: number }) {\n return {\n position: 'absolute' as const,\n left: r.left + 'mm',\n top: r.top + 'mm',\n width: r.width + 'mm',\n height: r.height + 'mm',\n }\n}\n\n// 优化:一次遍历完成三区分类,避免三次全量 filter\nconst zoneElements = computed(() => {\n const result = { header: [] as RuntimeElement[], footer: [] as RuntimeElement[], content: [] as RuntimeElement[] }\n for (const el of props.runtimeElements) {\n if (el.zone === 'header') result.header.push(el)\n else if (el.zone === 'footer') result.footer.push(el)\n else result.content.push(el)\n }\n return result\n})\nconst headerElements = computed(() => zoneElements.value.header)\nconst footerElements = computed(() => zoneElements.value.footer)\nconst contentElements = computed(() => zoneElements.value.content)\n\n// 吸附管理器:仅同区元素间吸附,引导线通过 Vue 响应式渲染\nlet currentDragZone: ElementZone = 'content'\n\nconst { requestAdsorb: rawRequestAdsorb, clearGuides, guideLines, paperSize: guidePaperSize } = useAdsorbManager({\n // 优化:直接使用预计算的 zoneElements,避免每次拖拽都 filter\n getElements: () => zoneElements.value[currentDragZone],\n getPaperSize: () => {\n const r = zoneRectsMM.value[currentDragZone]\n return { width: r.width, height: r.height }\n },\n getGuides: () => {\n const v: number[] = [], h: number[] = []\n for (const g of props.guides ?? []) {\n if (g.type === 'vertical') v.push(g.position)\n else h.push(g.position)\n }\n return { vertical: v, horizontal: h }\n },\n})\n\nfunction requestAdsorb(rect: ElementRect): ReturnType<typeof rawRequestAdsorb> {\n const el = props.runtimeElements.find(e => e.id === rect.id)\n currentDragZone = el?.zone || 'content'\n const result = rawRequestAdsorb(rect)\n // 位置被修正即发生吸附,在元素中心闪烁网格高亮点\n if (result.left !== rect.left || result.top !== rect.top) {\n showSnapIndicator(result.left + rect.width / 2, result.top + rect.height / 2)\n }\n return result\n}\n\n/** 拖动手动参考线 */\nfunction onGuideDown(e: MouseEvent, g: AlignLine) {\n const startPt = g.position\n const startX = e.clientX, startY = e.clientY\n const s = props.scale ?? 1\n const MM_PER_PX = 25.4 / 96\n const onMove = (ev: MouseEvent) => {\n const delta = (g.type === 'vertical' ? (ev.clientX - startX) : (ev.clientY - startY)) / s * MM_PER_PX\n emit('guide-move', g.id!, startPt + delta)\n }\n const onUp = () => {\n window.removeEventListener('mousemove', onMove)\n window.removeEventListener('mouseup', onUp)\n }\n window.addEventListener('mousemove', onMove)\n window.addEventListener('mouseup', onUp)\n}\n\nconst paperStyle = computed(() => ({\n width: paperWidthMM.value + 'mm',\n minHeight: paperHeightMM.value + 'mm',\n background: 'var(--pd-paper, #fff)',\n boxShadow: 'var(--pd-shadow-paper, 0 1px 2px rgba(0,0,0,.12), 0 8px 24px rgba(0,0,0,.08))',\n margin: '0 auto',\n overflow: 'hidden',\n position: 'relative' as const,\n transform: props.scale ? `scale(${props.scale})` : undefined,\n transformOrigin: '0 0',\n}))\n\nconst contentStyle = computed(() => {\n const m = props.templateData.margins\n return {\n padding: `${m.top}mm ${m.right}mm ${m.bottom}mm ${m.left}mm`,\n position: 'relative' as const,\n minHeight: paperHeightMM.value + 'mm',\n }\n})\n\nconst showRulerComputed = computed(() => props.showRuler !== false && !!props.designMode)\n\nconst gridBgStyle = computed(() => {\n const size = 5 // mm\n // 虚线网格:SVG 平铺图案,颜色调淡避免干扰元素视觉\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"><path d=\"M0 .5H20M.5 0V20\" fill=\"none\" stroke=\"rgba(0,0,0,0.08)\" stroke-width=\"1\" stroke-dasharray=\"4 4\"/></svg>`\n return {\n backgroundImage: `url(\"data:image/svg+xml,${encodeURIComponent(svg)}\")`,\n backgroundSize: `${size}mm ${size}mm`,\n backgroundPosition: '0 0',\n }\n})\n\n// ─── 吸附高亮指示 ───\nlet snapSeq = 0\nlet snapTimer: ReturnType<typeof setTimeout> | null = null\nconst snapIndicator = ref<{ left: number; top: number; key: number } | null>(null)\n\n/** 在吸附对齐位置闪烁一个高亮点 */\nfunction showSnapIndicator(left: number, top: number) {\n snapSeq += 1\n snapIndicator.value = { left, top, key: snapSeq }\n if (snapTimer) clearTimeout(snapTimer)\n snapTimer = setTimeout(() => {\n snapIndicator.value = null\n }, 300)\n}\n\n// ─── 水印渲染 ───\nconst watermarkVisible = computed(() => {\n const w = props.templateData.watermark\n if (!w) return false\n // 向后兼容:如果没有 mode 字段,使用 content\n if (!w.mode || w.mode === 'fixed') {\n return !!w.content && w.content.trim().length > 0\n }\n // 绑定字段模式\n return !!w.binding\n})\n\nconst watermarkStyle = computed(() => {\n const w = props.templateData.watermark || {}\n const color = w.color || '#cccccc'\n const opacity = w.opacity ?? 0.15\n const rotate = w.rotate ?? -30\n // 获取水印文本\n let text = getWatermarkText(w)\n if (w.timestamp) {\n const now = new Date()\n const ts = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`\n text = text ? `${text} ${ts}` : ts\n }\n return {\n position: 'absolute' as const,\n top: '0',\n left: '0',\n width: '100%',\n height: '100%',\n pointerEvents: 'none' as const,\n zIndex: '0',\n overflow: 'hidden',\n opacity: String(opacity),\n backgroundImage: buildWatermarkSvg(text, color, rotate),\n backgroundRepeat: 'repeat',\n }\n})\n\n/** 获取水印文本(支持绑定字段) */\nfunction getWatermarkText(w: { mode?: 'fixed' | 'binding'; content?: string; binding?: string; testData?: string }): string {\n // 向后兼容:如果没有 mode 字段,使用 content\n if (!w.mode || w.mode === 'fixed') {\n return w.content || ''\n }\n // 绑定字段模式\n if (w.binding) {\n // 从打印数据中取值\n const printData = props.printData?.[0]\n if (printData && printData[w.binding] !== undefined && printData[w.binding] !== null) {\n return String(printData[w.binding])\n }\n // 回退到测试值\n return w.testData || `[${w.binding}]`\n }\n return ''\n}\n\n/** 用内联 SVG 生成水印背景图案 */\nfunction buildWatermarkSvg(text: string, color: string, rotate: number): string {\n const escaped = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"260\" height=\"180\">\n <text x=\"130\" y=\"90\" font-size=\"16\" fill=\"${color}\" text-anchor=\"middle\" dominant-baseline=\"middle\" transform=\"rotate(${rotate},130,90)\">${escaped}</text>\n </svg>`\n return `url(\"data:image/svg+xml,${encodeURIComponent(svg)}\")`\n}\n\n// ─── 页眉/页脚高度拖拽 ───\nconst zoneResizing = ref<{ zone: 'header' | 'footer'; startY: number; startH: number } | null>(null)\n\nfunction startZoneResize(zone: 'header' | 'footer', e: MouseEvent) {\n // 防止重复绑定:先清理再绑定\n cleanupZoneResize()\n zoneResizing.value = { zone, startY: e.clientY, startH: props.templateData[zone].height }\n window.addEventListener('mousemove', onZoneResizeMove)\n window.addEventListener('mouseup', onZoneResizeUp)\n}\n\nfunction onZoneResizeMove(e: MouseEvent) {\n if (!zoneResizing.value) return\n const { zone, startY, startH } = zoneResizing.value\n const dyPx = (e.clientY - startY) / (props.scale || 1)\n const dyMM = dyPx * 25.4 / 96\n const delta = zone === 'header' ? dyMM : -dyMM\n // 0.1mm 步进;上限 100mm 与属性面板一致,且保证内容区至少 10mm\n const maxH = Math.min(\n 100,\n paperHeightMM.value - props.templateData.margins.top - props.templateData.margins.bottom\n - (zone === 'header' ? props.templateData.footer.height : props.templateData.header.height)\n - 10,\n )\n const h = Math.min(maxH, Math.max(0, Math.round((startH + delta) * 10) / 10))\n emit('zone-height-change', zone, h)\n}\n\nfunction onZoneResizeUp() {\n if (!zoneResizing.value) return\n const zone = zoneResizing.value.zone\n zoneResizing.value = null\n window.removeEventListener('mousemove', onZoneResizeMove)\n window.removeEventListener('mouseup', onZoneResizeUp)\n emit('zone-height-commit', zone)\n}\n\n/** 清理区域拖拽事件监听器 */\nfunction cleanupZoneResize() {\n window.removeEventListener('mousemove', onZoneResizeMove)\n window.removeEventListener('mouseup', onZoneResizeUp)\n zoneResizing.value = null\n}\n\nonUnmounted(() => {\n cleanupZoneResize()\n if (snapTimer) clearTimeout(snapTimer)\n})\n\nfunction onSelectElement(id: string, multiple: boolean) {\n emit('select', id, multiple)\n}\n\ndefineExpose({ contentRef })\n</script>\n\n<style scoped>\n/* 纸张缩放平滑过渡(配合鼠标位置缩放中心) */\n.hiprint-printPaper {\n transition: transform 0.15s ease-out;\n}\n/* ─── 三段式区域层 ─── */\n.zone-layer {\n box-sizing: border-box;\n}\n.zone-layer.zone-header.design-mode,\n.zone-layer.zone-footer.design-mode {\n outline: 1px dashed var(--pd-ink-green, #67c23a);\n background: rgba(103, 194, 58, 0.04);\n}\n.zone-layer.zone-content.design-mode {\n outline: 1px dashed #C3C9D6;\n}\n.zone-overlay {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n outline: 1px dashed #06B6D4;\n background: rgba(6, 182, 212, 0.04);\n box-sizing: border-box;\n pointer-events: none;\n z-index: 1;\n}\n.zone-label {\n position: absolute;\n top: 2px;\n right: 4px;\n font-size: 9px;\n color: #909399;\n pointer-events: none;\n user-select: none;\n}\n/* 区域高度拖拽手柄 */\n.zone-resize-handle {\n position: absolute;\n left: 0;\n width: 100%;\n height: 6px;\n cursor: ns-resize;\n z-index: 5;\n}\n.zone-resize-handle.handle-bottom {\n bottom: -3px;\n}\n.zone-resize-handle.handle-top {\n top: -3px;\n}\n.zone-resize-handle:hover {\n background: rgba(16, 185, 129, 0.25);\n}\n.zone-height-tip {\n position: absolute;\n right: 4px;\n top: -22px;\n padding: 1px 6px;\n font-size: 11px;\n color: #fff;\n background: #10B981;\n border-radius: 3px;\n white-space: nowrap;\n pointer-events: none;\n}\n/* 刻度标尺由 Ruler.vue Canvas 绘制 */\n.grid-bg {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n z-index: 0;\n}\n/* 吸附高亮指示点 */\n.snap-indicator {\n position: absolute;\n width: 6px;\n height: 6px;\n background: var(--pd-accent, #165DFF);\n border-radius: 50%;\n transform: translate(-50%, -50%);\n pointer-events: none;\n z-index: 10;\n animation: snap-pulse 0.3s ease-out;\n}\n@keyframes snap-pulse {\n from { transform: translate(-50%, -50%) scale(2); opacity: 0.5; }\n to { transform: translate(-50%, -50%) scale(1); opacity: 0; }\n}\n/* 水印层 */\n.watermark-layer {\n pointer-events: none;\n}\n/* 吸附引导线 */\n.adsorb-guide {\n position: absolute;\n pointer-events: none;\n z-index: 9999;\n}\n.adsorb-guide.guide-vertical {\n border-left: 1px dashed var(--pd-accent-secondary, #f56c6c);\n}\n.adsorb-guide.guide-horizontal {\n border-top: 1px dashed var(--pd-accent-secondary, #f56c6c);\n}\n/* 手动参考线 */\n.manual-guide { position: absolute; pointer-events: auto; z-index: 9998; cursor: move; }\n.manual-guide.guide-vertical { border-left: 1px solid #3B82F6; width: 0; }\n.manual-guide.guide-horizontal { border-top: 1px solid #3B82F6; height: 0; }\n.manual-guide:hover { border-color: #EF4444 !important; }\n</style>\n","<template>\n <div\n ref=\"rootRef\"\n class=\"canvas-area\"\n @dragover.prevent\n @drop=\"onDrop\"\n @mousedown=\"onCanvasMouseDown\"\n @mousemove=\"onMouseMove\"\n @mouseleave=\"onMouseLeave\"\n @wheel=\"onWheel\"\n @contextmenu.prevent=\"onContextMenu\"\n >\n <div class=\"canvas-scroll\">\n <CanvasPaper\n :template-data=\"templateData\"\n :runtime-elements=\"elements\"\n :design-mode=\"true\"\n :print-data=\"[]\"\n :scale=\"scale\"\n :show-grid=\"showGrid\"\n :snap-to-grid=\"snapToGrid\"\n :show-table-ghost-border=\"showTableGhostBorder\"\n :guides=\"guides\"\n @select=\"onSelectElement\"\n @add-guide=\"(t: 'vertical' | 'horizontal', p: number) => $emit('add-guide', t, p)\"\n @guide-move=\"(id: string, p: number) => $emit('guide-move', id, p)\"\n @guide-remove=\"(id: string) => $emit('guide-remove', id)\"\n @drag-start=\"$emit('drag-start')\"\n @drag-stop=\"$emit('drag-stop')\"\n @dblclick-element=\"(id: string) => $emit('dblclick-element', id)\"\n @dblclick-cell=\"(id: string, r: number, c: number) => $emit('dblclick-cell', id, r, c)\"\n @contextmenu=\"(id: string, e: MouseEvent) => onContextMenu(e, id)\"\n @zone-height-change=\"(zone: 'header' | 'footer', h: number) => $emit('zone-height-change', zone, h)\"\n @zone-height-commit=\"(zone: 'header' | 'footer') => $emit('zone-height-commit', zone)\"\n @clone-element=\"(el, pos) => $emit('clone-element', el, pos)\"\n />\n <!-- 叠层对比截图 -->\n <div v-if=\"overlayVisible && screenshotUrl\" class=\"overlay-layer\">\n <img :src=\"screenshotUrl\" class=\"overlay-image\" :style=\"{ opacity: overlayOpacity ?? 0.5 }\" />\n </div>\n </div>\n\n <!-- 框选选框 -->\n <div\n v-if=\"marquee.visible\"\n class=\"marquee-selection\"\n :style=\"{\n left: marquee.x + 'px',\n top: marquee.y + 'px',\n width: marquee.w + 'px',\n height: marquee.h + 'px',\n }\"\n />\n\n <!-- 右键菜单 -->\n <div\n v-if=\"contextMenu.visible\"\n class=\"context-menu\"\n :style=\"{ left: contextMenu.x + 'px', top: contextMenu.y + 'px' }\"\n >\n <template v-if=\"contextMenu.targetId\">\n <div class=\"context-menu-item\" @click=\"emitAction('copy')\">复制</div>\n <div class=\"context-menu-item\" @click=\"emitAction('cut')\">剪切</div>\n <div class=\"context-menu-item\" :class=\"{ disabled: !hasClipboard }\" @click=\"emitAction('paste')\">粘贴</div>\n <div class=\"context-menu-item\" @click=\"emitAction('delete')\">删除</div>\n <div class=\"context-menu-sep\" />\n <div class=\"context-menu-item\" @click=\"emitAction('move-layer', 'top')\">置顶</div>\n <div class=\"context-menu-item\" @click=\"emitAction('move-layer', 'up')\">上移</div>\n <div class=\"context-menu-item\" @click=\"emitAction('move-layer', 'down')\">下移</div>\n <div class=\"context-menu-item\" @click=\"emitAction('move-layer', 'bottom')\">置底</div>\n <div class=\"context-menu-sep\" />\n <div class=\"context-menu-item\" @click=\"emitAction('group')\">编组 Ctrl+G</div>\n <div class=\"context-menu-item\" :class=\"{ disabled: !selectedElementHasGroup }\" @click=\"emitAction('ungroup')\">取消编组 Ctrl+Shift+G</div>\n </template>\n <template v-else>\n <div class=\"context-menu-item\" :class=\"{ disabled: !hasClipboard }\" @click=\"handlePaste\">粘贴</div>\n <div class=\"context-menu-item\" @click=\"handleSelectAll\">全选</div>\n <div class=\"context-menu-item\" @click=\"handleClearSelection\">取消选择</div>\n </template>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, reactive, onBeforeUnmount } from 'vue'\nimport type { RuntimeElement, TemplateData, AlignLine } from '../types'\nimport { pxToMm } from '../utils/units'\nimport CanvasPaper from './CanvasPaper.vue'\n\nconst props = defineProps<{\n templateData: TemplateData\n elements: RuntimeElement[]\n scale: number\n showGrid?: boolean\n snapToGrid?: boolean\n showTableGhostBorder?: boolean\n hasClipboard?: boolean\n guides?: AlignLine[]\n overlayVisible?: boolean\n screenshotUrl?: string\n overlayOpacity?: number\n selectedElementHasGroup?: boolean\n}>()\n\nconst emit = defineEmits<{\n select: [id: string, multiple: boolean]\n 'drop-element': [type: string, dropPoint?: { x: number; y: number }]\n 'drop-field': [field: { fieldKey: string; fieldLabel: string }, dropPoint?: { x: number; y: number }]\n 'drag-start': []\n 'drag-stop': []\n 'dblclick-element': [id: string]\n 'dblclick-cell': [elementId: string, r: number, c: number]\n 'zone-height-change': [zone: 'header' | 'footer', height: number]\n 'zone-height-commit': [zone: 'header' | 'footer']\n 'select-all': []\n 'clear-selection': []\n 'preview': [ids: string[]]\n 'commit-preview': []\n 'paste': []\n 'copy': []\n 'cut': []\n 'delete': []\n 'move-layer': [direction: string]\n group: []\n ungroup: []\n 'coordinate': [pos: { x: number; y: number } | null]\n 'add-guide': [type: 'vertical' | 'horizontal', positionMm: number]\n 'guide-move': [id: string, positionMm: number]\n 'guide-remove': [id: string]\n 'zoom': [delta: number]\n 'clone-element': [element: RuntimeElement, position: { left: number; top: number }]\n}>()\n\nfunction onSelectElement(id: string, multiple: boolean) {\n emit('select', id, multiple)\n}\n\nconst rootRef = ref<HTMLElement | null>(null)\n\n/** 客户端坐标 → 纸面 mm 坐标;纸张未挂载或落点在纸外时返回 undefined(走默认落位) */\nfunction toPaperPoint(e: DragEvent): { x: number; y: number } | undefined {\n const paper = rootRef.value?.querySelector('.hiprint-printPaper') as HTMLElement | null\n if (!paper) return undefined\n const rect = paper.getBoundingClientRect()\n const scale = props.scale || 1\n const x = pxToMm((e.clientX - rect.left) / scale)\n const y = pxToMm((e.clientY - rect.top) / scale)\n if (x < 0 || y < 0) return undefined\n return { x, y }\n}\n\nfunction onDrop(e: DragEvent) {\n const dropPoint = toPaperPoint(e)\n const fieldData = e.dataTransfer?.getData('fieldData')\n if (fieldData) {\n try {\n const field = JSON.parse(fieldData) as { fieldKey: string; fieldLabel: string }\n emit('drop-field', field, dropPoint)\n return\n } catch {\n // 解析失败,忽略\n }\n }\n const elementType = e.dataTransfer?.getData('elementType')\n if (elementType) {\n emit('drop-element', elementType, dropPoint)\n }\n}\n\n// ─── 鼠标框选 ───\nconst marquee = reactive({ visible: false, x: 0, y: 0, w: 0, h: 0 })\nlet marqueeStart = { x: 0, y: 0 }\n\n/** 判断点击目标是否为画布空白区域(非元素) */\nfunction isCanvasBackground(target: EventTarget | null): boolean {\n if (!target || !(target instanceof HTMLElement)) return false\n // 点击在画布容器、滚动层、纸张本身上视为空白区域\n if (target === rootRef.value) return true\n if (target.classList.contains('canvas-scroll')) return true\n if (target.classList.contains('hiprint-printPaper')) return true\n if (target.classList.contains('hiprint-printPaper-content')) return true\n if (target.classList.contains('zone-layer')) return true\n if (target.classList.contains('grid-bg')) return true\n if (target.classList.contains('watermark-layer')) return true\n return false\n}\n\nconst MM_TO_PX = 96 / 25.4\nfunction onMouseMove(e: MouseEvent) {\n const paper = rootRef.value?.querySelector('.hiprint-printPaper') as HTMLElement | null\n if (!paper) return\n const rect = paper.getBoundingClientRect()\n const s = props.scale || 1\n const xMm = pxToMm((e.clientX - rect.left) / s)\n const yMm = pxToMm((e.clientY - rect.top) / s)\n if (xMm < 0 || yMm < 0) { emit('coordinate', null); return }\n emit('coordinate', { x: xMm, y: yMm })\n}\nfunction onMouseLeave() { emit('coordinate', null) }\n\n/** Ctrl/Cmd+滚轮缩放:以鼠标位置为缩放中心,缩放前后保持鼠标下的内容点不动 */\nfunction onWheel(e: WheelEvent) {\n if (!(e.ctrlKey || e.metaKey)) return\n e.preventDefault()\n const oldScale = props.scale\n const newScale = Math.max(0.25, Math.min(3, oldScale + (e.deltaY > 0 ? -0.1 : 0.1)))\n if (newScale === oldScale) return\n\n // 缩放中心换算:scroll' = (scroll + mouse) * ratio - mouse\n const container = rootRef.value\n if (container) {\n const rect = container.getBoundingClientRect()\n const mouseX = e.clientX - rect.left\n const mouseY = e.clientY - rect.top\n const ratio = newScale / oldScale\n container.scrollLeft = (container.scrollLeft + mouseX) * ratio - mouseX\n container.scrollTop = (container.scrollTop + mouseY) * ratio - mouseY\n }\n\n // 以百分比增量上报(父级 scale 为百分比)\n emit('zoom', (newScale - oldScale) * 100)\n}\n\nfunction onCanvasMouseDown(e: MouseEvent) {\n // 右键由 contextmenu 处理\n if (e.button === 2) return\n if (!isCanvasBackground(e.target)) return\n\n // 点击空白区域取消选择\n emit('clear-selection')\n\n // 启动框选\n marqueeStart = { x: e.clientX, y: e.clientY }\n marquee.visible = true\n marquee.x = e.clientX\n marquee.y = e.clientY\n marquee.w = 0\n marquee.h = 0\n\n window.addEventListener('mousemove', onMarqueeMove)\n window.addEventListener('mouseup', onMarqueeUp)\n}\n\n/** 框选命中测试:左->右拖=交集,右->左拖=包含;返回命中元素 id */\nfunction hitTestIds(): string[] {\n if (marquee.w < 3 || marquee.h < 3) return []\n const paper = rootRef.value?.querySelector('.hiprint-printPaper') as HTMLElement | null\n if (!paper) return []\n const paperRect = paper.getBoundingClientRect()\n const s = props.scale || 1\n // marquee.x 是选框左边缘;小于起点 x 表示从右向左拖(包含模式)\n const containMode = marquee.x < marqueeStart.x\n const ids: string[] = []\n for (const el of props.elements) {\n if (el.options.visible === false || el.options.locked) continue\n const elLeft = paperRect.left + el.options.left * MM_TO_PX * s\n const elTop = paperRect.top + el.options.top * MM_TO_PX * s\n const elRight = elLeft + el.options.width * MM_TO_PX * s\n const elBottom = elTop + el.options.height * MM_TO_PX * s\n const inter = elLeft < marquee.x + marquee.w && elRight > marquee.x\n && elTop < marquee.y + marquee.h && elBottom > marquee.y\n const contained = elLeft >= marquee.x && elRight <= marquee.x + marquee.w\n && elTop >= marquee.y && elBottom <= marquee.y + marquee.h\n if (containMode ? contained : inter) ids.push(el.id)\n }\n return ids\n}\n\nfunction onMarqueeMove(e: MouseEvent) {\n const dx = e.clientX - marqueeStart.x\n const dy = e.clientY - marqueeStart.y\n marquee.x = dx >= 0 ? marqueeStart.x : e.clientX\n marquee.y = dy >= 0 ? marqueeStart.y : e.clientY\n marquee.w = Math.abs(dx)\n marquee.h = Math.abs(dy)\n // 实时预选高亮\n emit('preview', hitTestIds())\n}\n\nfunction onMarqueeUp() {\n window.removeEventListener('mousemove', onMarqueeMove)\n window.removeEventListener('mouseup', onMarqueeUp)\n\n const ids = hitTestIds()\n emit('preview', ids) // 确保预选为最终状态\n if (ids.length > 0) emit('commit-preview')\n else emit('clear-selection')\n emit('preview', []) // 清除预选高亮\n\n marquee.visible = false\n}\n\n// ─── 右键菜单 ───\nconst contextMenu = reactive({ visible: false, x: 0, y: 0, targetId: null as string | null })\n\nfunction onContextMenu(e: MouseEvent, elId?: string) {\n // 元素右键:由 BaseElement 上抛(已 stop);空白右键:无 elId,仅背景区域弹菜单\n if (!elId && !isCanvasBackground(e.target)) return\n const containerRect = rootRef.value?.getBoundingClientRect()\n if (!containerRect) return\n contextMenu.x = e.clientX - containerRect.left\n contextMenu.y = e.clientY - containerRect.top\n contextMenu.targetId = elId ?? null\n contextMenu.visible = true\n\n // 点击其他区域关闭:先清理旧监听器防止重复绑定\n window.removeEventListener('mousedown', closeContextMenu)\n setTimeout(() => {\n window.addEventListener('mousedown', closeContextMenu, { once: true })\n }, 0)\n}\n\nfunction closeContextMenu() {\n contextMenu.visible = false\n window.removeEventListener('mousedown', closeContextMenu)\n}\n\nfunction handlePaste() {\n contextMenu.visible = false\n if (props.hasClipboard) emit('paste')\n}\n\nfunction handleSelectAll() {\n contextMenu.visible = false\n emit('select-all')\n}\n\nfunction handleClearSelection() {\n contextMenu.visible = false\n emit('clear-selection')\n}\n\n/** 元素右键菜单动作派发 */\nfunction emitAction(action: string, arg?: string) {\n contextMenu.visible = false\n if (action === 'copy') emit('copy')\n else if (action === 'cut') emit('cut')\n else if (action === 'paste') emit('paste')\n else if (action === 'delete') emit('delete')\n else if (action === 'move-layer') emit('move-layer', arg!)\n else if (action === 'group') emit('group')\n else if (action === 'ungroup' && props.selectedElementHasGroup) emit('ungroup')\n}\n\nonBeforeUnmount(() => {\n window.removeEventListener('mousemove', onMarqueeMove)\n window.removeEventListener('mouseup', onMarqueeUp)\n})\n</script>\n\n<style scoped>\n.canvas-area {\n flex: 1;\n overflow: auto;\n /* 制图垫:略深冷灰 + 极淡点阵,让白纸浮起 */\n background-color: var(--pd-canvas-bg, #e6e9f0);\n background-image: radial-gradient(circle, rgba(23, 32, 60, .13) 1px, transparent 1.2px);\n background-size: 20px 20px;\n background-position: center;\n display: flex;\n justify-content: center;\n padding: 44px 28px 32px 44px;\n position: relative;\n}\n.canvas-scroll {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 20px;\n position: relative;\n}\n/* 叠层对比 */\n.overlay-layer {\n position: absolute;\n top: 0;\n left: 0;\n pointer-events: none;\n z-index: 100;\n}\n.overlay-image {\n width: 100%;\n display: block;\n}\n/* 框选选框 */\n.marquee-selection {\n position: fixed;\n border: 1.5px solid rgba(22, 93, 255, 0.7);\n background: rgba(22, 93, 255, 0.08);\n border-radius: 2px;\n pointer-events: none;\n z-index: 10000;\n}\n/* 右键菜单 */\n.context-menu {\n position: absolute;\n background: var(--pd-surface, #ffffff);\n border: 1px solid var(--pd-border-soft, #e9ecf2);\n border-radius: 8px;\n box-shadow: var(--pd-shadow-md, 0 10px 28px rgba(23, 32, 60, .12));\n padding: 5px;\n z-index: 10001;\n min-width: 132px;\n}\n.context-menu-item {\n padding: 7px 12px;\n border-radius: 5px;\n font-size: 12.5px;\n cursor: pointer;\n color: var(--pd-text, #2a2e37);\n user-select: none;\n transition: background .12s ease, color .12s ease;\n}\n.context-menu-item:hover {\n background: var(--pd-accent-soft, rgba(22, 93, 255, .09));\n color: var(--pd-accent, #165DFF);\n}\n.context-menu-item.disabled {\n color: var(--pd-text-faint, #b4b9c4);\n cursor: not-allowed;\n}\n.context-menu-item.disabled:hover {\n background: transparent;\n color: var(--pd-text-faint, #b4b9c4);\n}\n.context-menu-sep {\n height: 1px;\n background: var(--pd-border-soft, #e9ecf2);\n margin: 5px 8px;\n}\n</style>\n","/** 属性面板搜索注册表:分组 → 表单项 → 关键词 */\nexport interface PropertyItem {\n key: string\n keywords: string[]\n}\n\nexport interface PropertyGroupDef {\n group: string\n groupLabel: string\n items: PropertyItem[]\n}\n\nexport const PROPERTY_REGISTRY: PropertyGroupDef[] = [\n {\n group: 'position-size',\n groupLabel: '位置与尺寸',\n items: [\n { key: 'ps-left', keywords: ['X', '横坐标', 'left', '位置'] },\n { key: 'ps-top', keywords: ['Y', '纵坐标', 'top', '位置'] },\n { key: 'ps-width', keywords: ['W', '宽度', 'width', '尺寸'] },\n { key: 'ps-height', keywords: ['H', '高度', 'height', '尺寸'] },\n ],\n },\n {\n group: 'appearance',\n groupLabel: '外观',\n items: [\n { key: 'ap-font-size', keywords: ['字体大小', 'fontsize', '字号'] },\n { key: 'ap-font-weight', keywords: ['字体粗细', '粗体', 'bold'] },\n { key: 'ap-align', keywords: ['对齐', 'align'] },\n { key: 'ap-vertical-align', keywords: ['垂直对齐', 'verticalalign', '顶对齐', '底对齐'] },\n { key: 'ap-color', keywords: ['颜色', 'color'] },\n { key: 'ap-bg-color', keywords: ['背景色', 'background'] },\n { key: 'ap-line-height', keywords: ['行高', 'lineheight'] },\n { key: 'ap-letter-spacing', keywords: ['字间距', 'letterspacing'] },\n ],\n },\n {\n group: 'content',\n groupLabel: '内容',\n items: [\n { key: 'ct-title', keywords: ['内容', '文本', 'title'] },\n { key: 'ct-formatter', keywords: ['格式化', '表达式', 'formatter'] },\n { key: 'ct-table-mode', keywords: ['数据模式', '静态布局', '动态数据'] },\n { key: 'ct-table-source', keywords: ['数据源', '列表字段'] },\n { key: 'ct-table-font', keywords: ['默认字号', '默认颜色', '默认内边距'] },\n { key: 'ct-table-cols', keywords: ['列宽', '表格列'] },\n ],\n },\n {\n group: 'border-bg',\n groupLabel: '边框与背景',\n items: [\n { key: 'bb-border-width', keywords: ['边框宽度', 'border'] },\n { key: 'bb-border-color', keywords: ['边框颜色'] },\n { key: 'bb-bg-color', keywords: ['背景色', 'background'] },\n ],\n },\n {\n group: 'binding',\n groupLabel: '字段绑定',\n items: [\n { key: 'bd-formatter', keywords: ['格式化', '表达式', 'formatter', 'fx', '字段', '绑定', 'field'] },\n { key: 'bd-content', keywords: ['内容', '表达式', '文本', '变量'] },\n ],\n },\n {\n group: 'pagination',\n groupLabel: '分页',\n items: [\n { key: 'pg-enabled', keywords: ['分页', 'pagination', '启用分页'] },\n { key: 'pg-pageable', keywords: ['参与分页', 'pageable'] },\n { key: 'pg-keep-with-next', keywords: ['同页', 'keepWithNext'] },\n ],\n },\n {\n group: 'advanced',\n groupLabel: '高级',\n items: [\n { key: 'ad-locked', keywords: ['锁定', 'lock'] },\n { key: 'ad-fixed', keywords: ['每页重复', 'repeat'] },\n { key: 'ad-z-index', keywords: ['层级', 'zindex'] },\n { key: 'ad-delete', keywords: ['删除'] },\n ],\n },\n]\n\n/** 正向包含匹配:任一关键词包含搜索词即命中;空搜索恒命中 */\nexport function matchKeywords(search: string, keywords: string[]): boolean {\n const s = search.trim().toLowerCase()\n if (!s) {\n return true\n }\n return keywords.some(k => k.toLowerCase().includes(s))\n}\n\n/** 计算命中的分组与表单项 key 集合 */\nexport function searchProperties(search: string): { groups: string[]; itemKeys: Set<string> } {\n const groups: string[] = []\n const itemKeys = new Set<string>()\n for (const g of PROPERTY_REGISTRY) {\n const matched = g.items.filter(item => matchKeywords(search, [...item.keywords, g.groupLabel]))\n if (matched.length > 0) {\n groups.push(g.group)\n for (const item of matched) {\n itemKeys.add(item.key)\n }\n }\n }\n return { groups, itemKeys }\n}\n","<template>\n <div class=\"property-search\">\n <input\n v-model=\"searchText\"\n class=\"pd-input\"\n type=\"search\"\n placeholder=\"搜索属性...\"\n aria-label=\"搜索属性\"\n @input=\"onSearch\"\n >\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue'\n\nconst searchText = ref('')\nconst emit = defineEmits<{ search: [text: string] }>()\n\nfunction onSearch() {\n emit('search', searchText.value)\n}\n</script>\n\n<style scoped>\n.property-search {\n padding: 0 0 10px;\n background: transparent;\n}\n</style>\n","<template>\n <div class=\"property-group\" :class=\"{ 'is-expanded': isExpanded }\">\n <div class=\"group-header\" @click=\"toggle\">\n <span class=\"group-icon\">{{ iconChar }}</span>\n <span class=\"group-title\">{{ title }}</span>\n <span class=\"expand-icon\">{{ isExpanded ? '▾' : '▸' }}</span>\n </div>\n <div v-show=\"isExpanded\" class=\"group-content\">\n <slot />\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted } from 'vue'\n\nconst props = defineProps<{\n title: string\n icon: string\n defaultExpanded?: boolean\n groupKey: string\n}>()\n\nconst isExpanded = ref(props.defaultExpanded ?? true)\n\nconst iconMap: Record<string, string> = {\n Document: '≡',\n Brush: '◧',\n Setting: '⚙',\n}\nconst iconChar = iconMap[props.icon] || '•'\n\nfunction toggle() {\n isExpanded.value = !isExpanded.value\n saveState()\n}\n\nfunction saveState() {\n const key = `property-group-${props.groupKey}`\n try {\n localStorage.setItem(key, String(isExpanded.value))\n } catch {\n // 隐私模式或存储满,忽略持久化失败\n }\n}\n\nfunction loadState() {\n const key = `property-group-${props.groupKey}`\n try {\n const saved = localStorage.getItem(key)\n if (saved !== null) {\n isExpanded.value = saved === 'true'\n }\n } catch {\n // 读取失败保持默认展开状态\n }\n}\n\nonMounted(() => {\n loadState()\n})\n</script>\n\n<style scoped>\n.property-group {\n border: 1px solid var(--pd-border-soft, #e9ecf2);\n border-radius: 8px;\n margin-bottom: 10px;\n background: var(--pd-surface, #ffffff);\n overflow: hidden;\n transition: border-color .14s ease, box-shadow .14s ease;\n}\n.property-group:last-child {\n margin-bottom: 2px;\n}\n.property-group.is-expanded {\n border-color: var(--pd-border-soft, #e9ecf2);\n}\n.group-header {\n display: flex;\n align-items: center;\n padding: 9px 12px;\n cursor: pointer;\n user-select: none;\n background: var(--pd-field-bg, #f4f6fa);\n transition: background .14s ease;\n}\n.group-header:hover {\n background: var(--pd-sidebar-hover, #f0f3f9);\n}\n.property-group.is-expanded .group-header {\n border-bottom: 1px solid var(--pd-border-soft, #e9ecf2);\n}\n.group-icon {\n margin-right: 8px;\n color: var(--pd-accent, #165DFF);\n}\n.group-title {\n flex: 1;\n font-size: 12px;\n font-weight: 600;\n color: var(--pd-text, #2a2e37);\n letter-spacing: .3px;\n}\n.expand-icon {\n color: var(--pd-text-muted, #8b909c);\n font-size: 10px;\n}\n.group-content {\n padding: 10px 12px 12px;\n background: var(--pd-surface, #ffffff);\n}\n</style>","<template>\n <PropertyGroup title=\"位置与尺寸\" icon=\"Location\" default-expanded group-key=\"position-size\">\n <form class=\"pd-form\" @submit.prevent>\n <div class=\"position-grid\">\n <div class=\"pd-field\" v-show=\"showItem('ps-left')\"><span class=\"pd-label\">X</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.left\"\n :min=\"0\"\n :step=\"0.01\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ps-top')\"><span class=\"pd-label\">Y</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.top\"\n :min=\"0\"\n :step=\"0.01\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ps-width')\"><span class=\"pd-label\">W</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.width\"\n :min=\"3.5\"\n :step=\"0.01\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ps-height')\"><span class=\"pd-label\">H</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.height\"\n :min=\"3.5\"\n :step=\"0.01\" />\n </div>\n </div>\n </form>\n </PropertyGroup>\n</template>\n\n<script setup lang=\"ts\">\nimport type { RuntimeElement } from '../../types'\nimport PropertyGroup from './PropertyGroup.vue'\n\nconst props = defineProps<{\n element: RuntimeElement\n matchedKeys?: Set<string>\n searching?: boolean\n}>()\n\nfunction showItem(key: string): boolean {\n if (!props.searching) {\n return true\n }\n return props.matchedKeys?.has(key) ?? true\n}\n</script>\n\n<style scoped>\n.position-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px;\n}\n</style>\n","/** 打印设计器常见预设颜色(12 色) */\nexport const PRESET_COLORS = [\n '#000000',\n '#333333',\n '#666666',\n '#999999',\n '#cccccc',\n '#ffffff',\n '#e53935',\n '#fb8c00',\n '#1e88e5',\n '#43a047',\n '#8d6e63',\n '#00acc1',\n] as const\n","<template>\n <button\n ref=\"triggerRef\"\n type=\"button\"\n class=\"preset-color-trigger\"\n :aria-expanded=\"visible\"\n aria-haspopup=\"dialog\"\n :title=\"modelValue || '自动'\"\n @click=\"toggle\"\n >\n <span class=\"preset-color-swatch\" :style=\"{ background: normalizedValue }\"></span>\n </button>\n\n <Teleport to=\"body\">\n <div\n v-if=\"visible\"\n ref=\"panelRef\"\n class=\"preset-color-panel\"\n role=\"dialog\"\n aria-label=\"颜色选择\"\n :style=\"panelStyle\"\n @pointerdown.stop\n >\n <div class=\"picker-preview\">\n <span class=\"picker-current\" :style=\"{ background: activeColor }\"></span>\n <input\n v-model=\"hexInput\"\n class=\"picker-hex\"\n type=\"text\"\n maxlength=\"7\"\n spellcheck=\"false\"\n aria-label=\"颜色值\"\n @input=\"onHexInput\"\n />\n </div>\n\n <div\n ref=\"areaRef\"\n class=\"picker-area\"\n :style=\"{ '--picker-hue': `${Math.round(hue)}deg` }\"\n aria-label=\"自定义颜色\"\n tabindex=\"0\"\n @pointerdown=\"startAreaDrag\"\n @pointermove=\"moveAreaDrag\"\n @pointerup=\"endAreaDrag\"\n @pointercancel=\"endAreaDrag\"\n @keydown=\"onAreaKeydown\"\n >\n <span class=\"picker-handle\" :style=\"{ left: `${saturation * 100}%`, top: `${(1 - value) * 100}%`, background: activeColor }\"></span>\n </div>\n\n <input\n v-model.number=\"hueModel\"\n class=\"picker-hue\"\n type=\"range\"\n min=\"0\"\n max=\"360\"\n step=\"1\"\n aria-label=\"色相\"\n />\n\n <div class=\"picker-heading\">常用颜色</div>\n <div class=\"preset-color-grid\">\n <button\n v-for=\"color in PRESET_COLORS\"\n :key=\"color\"\n type=\"button\"\n class=\"preset-color-item\"\n :class=\"{ active: color.toLowerCase() === activeColor.toLowerCase() }\"\n :style=\"{ background: color }\"\n :title=\"color\"\n :aria-label=\"color\"\n @click=\"select(color)\"\n ></button>\n </div>\n </div>\n </Teleport>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { PRESET_COLORS } from '../utils/preset-colors'\n\nconst props = defineProps<{\n modelValue?: string\n}>()\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string]\n}>()\n\nconst visible = ref(false)\nconst triggerRef = ref<HTMLElement>()\nconst panelRef = ref<HTMLElement>()\nconst areaRef = ref<HTMLElement>()\nconst panelStyle = ref<Record<string, string>>({})\n\nconst hue = ref(0)\nconst saturation = ref(0)\nconst value = ref(0)\nconst hexInput = ref('#000000')\nconst areaDragging = ref(false)\n\nconst normalizedValue = computed({\n get: () => props.modelValue || '#000000',\n set: (color: string) => emit('update:modelValue', color),\n})\n\nconst activeColor = computed(() => {\n return rgbToHex(hsvToRgb(hue.value, saturation.value, value.value))\n})\n\nconst hueModel = computed({\n get: () => Math.round(hue.value),\n set: (degree: number) => setHsv(clampDegree(degree), saturation.value, value.value),\n})\n\nwatch(normalizedValue, syncFromColor, { immediate: true })\n\nfunction select(color: string) {\n hexInput.value = color.toUpperCase()\n syncFromColor(color)\n emit('update:modelValue', color)\n}\n\nfunction onHexInput(event: Event) {\n const input = event.target as HTMLInputElement\n const color = input.value.trim()\n if (!parseHex(color)) return\n syncFromColor(color)\n emit('update:modelValue', normalizeHex(color))\n}\n\nfunction syncFromColor(color: string) {\n const rgb = parseHex(color)\n if (!rgb) return\n const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b)\n hue.value = hsv.h\n saturation.value = hsv.s\n value.value = hsv.v\n hexInput.value = normalizeHex(color).toUpperCase()\n}\n\nfunction setHsv(h: number, s: number, v: number) {\n hue.value = clampDegree(h)\n saturation.value = clamp01(s)\n value.value = clamp01(v)\n hexInput.value = activeColor.value.toUpperCase()\n emit('update:modelValue', activeColor.value)\n}\n\nfunction startAreaDrag(event: PointerEvent) {\n const area = event.currentTarget as HTMLElement\n area.setPointerCapture(event.pointerId)\n areaDragging.value = true\n setAreaFromEvent(event)\n}\n\nfunction moveAreaDrag(event: PointerEvent) {\n if (!areaDragging.value) return\n setAreaFromEvent(event)\n}\n\nfunction endAreaDrag(event: PointerEvent) {\n areaDragging.value = false\n const area = event.currentTarget as HTMLElement\n if (area.hasPointerCapture(event.pointerId)) {\n area.releasePointerCapture(event.pointerId)\n }\n}\n\nfunction setAreaFromEvent(event: PointerEvent) {\n const area = areaRef.value\n if (!area) return\n const rect = area.getBoundingClientRect()\n const s = clamp01((event.clientX - rect.left) / rect.width)\n const v = clamp01(1 - (event.clientY - rect.top) / rect.height)\n setHsv(hue.value, s, v)\n}\n\nfunction onAreaKeydown(event: KeyboardEvent) {\n const step = event.shiftKey ? 0.1 : 0.02\n let handled = true\n if (event.key === 'ArrowLeft') setHsv(hue.value, saturation.value - step, value.value)\n else if (event.key === 'ArrowRight') setHsv(hue.value, saturation.value + step, value.value)\n else if (event.key === 'ArrowUp') setHsv(hue.value, saturation.value, value.value + step)\n else if (event.key === 'ArrowDown') setHsv(hue.value, saturation.value, value.value - step)\n else handled = false\n if (handled) event.preventDefault()\n}\n\nfunction toggle() {\n visible.value ? close() : open()\n}\n\nasync function open() {\n const trigger = triggerRef.value\n if (!trigger) return\n syncFromColor(normalizedValue.value)\n visible.value = true\n await nextTick()\n const rect = trigger.getBoundingClientRect()\n const panelWidth = 190\n const panelHeight = panelRef.value?.offsetHeight ?? 216\n const margin = 8\n const left = Math.min(rect.left, window.innerWidth - panelWidth - margin)\n const below = rect.bottom + 6\n const top = below + panelHeight > window.innerHeight - margin\n ? Math.max(margin, rect.top - panelHeight - 6)\n : below\n\n panelStyle.value = {\n left: `${Math.max(margin, left)}px`,\n top: `${top}px`,\n }\n}\n\nfunction close() {\n visible.value = false\n}\n\nfunction onDocumentPointerDown(event: PointerEvent) {\n const target = event.target as Node\n if (triggerRef.value?.contains(target) || panelRef.value?.contains(target)) return\n close()\n}\n\nfunction onWindowCloseEvents() {\n if (visible.value) close()\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape' && visible.value) close()\n}\n\nfunction parseHex(color: string): { r: number; g: number; b: number } | null {\n const match = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(color.trim())\n if (!match) return null\n const hex = match[1]!\n const full = hex.length === 3\n ? hex.split('').map(char => char + char).join('')\n : hex\n return {\n r: Number.parseInt(full.slice(0, 2), 16),\n g: Number.parseInt(full.slice(2, 4), 16),\n b: Number.parseInt(full.slice(4, 6), 16),\n }\n}\n\nfunction normalizeHex(color: string): string {\n const rgb = parseHex(color)\n return rgb ? rgbToHex(rgb) : '#000000'\n}\n\nfunction rgbToHex({ r, g, b }: { r: number; g: number; b: number }): string {\n return `#${[r, g, b].map(part => Math.round(clamp01(part / 255) * 255).toString(16).padStart(2, '0')).join('')}`\n}\n\nfunction rgbToHsv(r: number, g: number, b: number): { h: number; s: number; v: number } {\n const red = r / 255\n const green = g / 255\n const blue = b / 255\n const max = Math.max(red, green, blue)\n const min = Math.min(red, green, blue)\n const delta = max - min\n let h = 0\n if (delta !== 0) {\n if (max === red) h = ((green - blue) / delta) % 6\n else if (max === green) h = (blue - red) / delta + 2\n else h = (red - green) / delta + 4\n h *= 60\n if (h < 0) h += 360\n }\n return { h, s: max === 0 ? 0 : delta / max, v: max }\n}\n\nfunction hsvToRgb(h: number, s: number, v: number): { r: number; g: number; b: number } {\n const c = v * s\n const hh = (((h % 360) + 360) % 360) / 60\n const x = c * (1 - Math.abs((hh % 2) - 1))\n const [r1, g1, b1] = hh < 1 ? [c, x, 0]\n : hh < 2 ? [x, c, 0]\n : hh < 3 ? [0, c, x]\n : hh < 4 ? [0, x, c]\n : hh < 5 ? [x, 0, c]\n : [c, 0, x]\n const m = v - c\n return { r: (r1 + m) * 255, g: (g1 + m) * 255, b: (b1 + m) * 255 }\n}\n\nfunction clampDegree(degree: number): number {\n return (((Number.isFinite(degree) ? degree : 0) % 360) + 360) % 360\n}\n\nfunction clamp01(number: number): number {\n return Math.min(1, Math.max(0, Number.isFinite(number) ? number : 0))\n}\n\nonMounted(() => {\n document.addEventListener('pointerdown', onDocumentPointerDown, true)\n window.addEventListener('scroll', onWindowCloseEvents, true)\n window.addEventListener('resize', onWindowCloseEvents)\n document.addEventListener('keydown', onKeydown)\n})\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown, true)\n window.removeEventListener('scroll', onWindowCloseEvents, true)\n window.removeEventListener('resize', onWindowCloseEvents)\n document.removeEventListener('keydown', onKeydown)\n})\n</script>\n\n<style scoped>\n.preset-color-trigger {\n display: flex;\n align-items: center;\n width: 100%;\n min-height: 26px;\n padding: 1px;\n border: 1px solid var(--pd-border, #d9dde6);\n border-radius: 6px;\n background: #fff;\n cursor: pointer;\n transition: border-color .14s ease, box-shadow .14s ease;\n}\n\n.preset-color-trigger:hover,\n.preset-color-trigger[aria-expanded=\"true\"] {\n border-color: var(--pd-accent, #165DFF);\n}\n\n.preset-color-trigger:focus-visible {\n outline: none;\n border-color: var(--pd-accent, #165DFF);\n box-shadow: 0 0 0 2px rgb(22 93 255 / 12%);\n}\n\n.preset-color-swatch {\n width: 100%;\n height: 22px;\n border-radius: 4px;\n background-image: linear-gradient(45deg, #e9ecef 25%, transparent 25%, transparent 75%, #e9ecef 75%);\n background-size: 8px 8px;\n background-position: 0 0, 4px 4px;\n}\n\n.preset-color-panel {\n position: fixed;\n z-index: 3000;\n width: 190px;\n padding: 10px;\n border: 1px solid var(--pd-border, #d9dde6);\n border-radius: 8px;\n background: #fff;\n box-shadow: 0 8px 24px rgb(23 32 60 / 16%);\n}\n\n.picker-preview {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 8px;\n}\n\n.picker-current {\n flex: 0 0 26px;\n height: 24px;\n border: 1px solid rgb(0 0 0 / 12%);\n border-radius: 5px;\n}\n\n.picker-hex {\n flex: 1;\n min-width: 0;\n height: 24px;\n padding: 0 6px;\n border: 1px solid var(--pd-border, #d9dde6);\n border-radius: 5px;\n color: var(--pd-text, #303133);\n font: inherit;\n font-size: 11px;\n text-transform: uppercase;\n}\n\n.picker-hex:focus {\n outline: none;\n border-color: var(--pd-accent, #165DFF);\n box-shadow: 0 0 0 2px rgb(22 93 255 / 12%);\n}\n\n.picker-area {\n position: relative;\n height: 100px;\n border: 1px solid rgb(0 0 0 / 12%);\n border-radius: 6px;\n overflow: hidden;\n cursor: crosshair;\n touch-action: none;\n background:\n linear-gradient(to top, #000, transparent),\n linear-gradient(to right, #fff, hsl(var(--picker-hue) 100% 50%));\n}\n\n.picker-handle {\n position: absolute;\n width: 12px;\n height: 12px;\n border: 2px solid #fff;\n border-radius: 50%;\n transform: translate(-50%, -50%);\n box-shadow: 0 0 3px rgb(0 0 0 / 45%);\n pointer-events: none;\n}\n\n.picker-hue {\n width: 100%;\n height: 14px;\n margin: 10px 0 0;\n appearance: none;\n border: 1px solid rgb(0 0 0 / 12%);\n border-radius: 999px;\n background: linear-gradient(to right, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00);\n cursor: pointer;\n}\n\n.picker-hue::-webkit-slider-thumb {\n appearance: none;\n width: 12px;\n height: 12px;\n border: 2px solid #fff;\n border-radius: 50%;\n background: transparent;\n box-shadow: 0 0 3px rgb(0 0 0 / 45%);\n}\n\n.picker-hue::-moz-range-thumb {\n width: 8px;\n height: 8px;\n border: 2px solid #fff;\n border-radius: 50%;\n background: transparent;\n box-shadow: 0 0 3px rgb(0 0 0 / 45%);\n}\n\n.picker-heading {\n margin-top: 10px;\n margin-bottom: 6px;\n font-size: 11px;\n color: var(--pd-text-muted, #909399);\n}\n\n.preset-color-grid {\n display: grid;\n grid-template-columns: repeat(6, 1fr);\n gap: 5px;\n}\n\n.preset-color-item {\n width: 22px;\n height: 22px;\n padding: 0;\n border: 1px solid rgb(0 0 0 / 12%);\n border-radius: 5px;\n cursor: pointer;\n}\n\n.preset-color-item.active {\n box-shadow: 0 0 0 2px #fff, 0 0 0 3px var(--pd-accent, #165DFF);\n}\n</style>\n","<template>\n <PropertyGroup title=\"外观\" icon=\"Brush\" default-expanded group-key=\"appearance\">\n <form class=\"pd-form\" @submit.prevent>\n <template v-if=\"isTextType\">\n <div class=\"pd-field\" v-show=\"showItem('ap-font-size')\"><span class=\"pd-label\">字体大小</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.fontSize\"\n :min=\"8\"\n :max=\"72\"\n style=\"width: 100%\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ap-font-weight')\"><span class=\"pd-label\">字体粗细</span>\n <select class=\"pd-select\" v-model=\"element.options.fontWeight\" style=\"width: 100%\">\n <option value=\"normal\">正常</option>\n <option value=\"bold\">粗体</option>\n <option value=\"bolder\">更粗</option>\n <option value=\"lighter\">细体</option>\n </select>\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ap-align')\"><span class=\"pd-label\">对齐</span>\n <div class=\"pd-radio-group\" role=\"radiogroup\">\n <label class=\"pd-radio\"><input type=\"radio\" v-model=\"element.options.textAlign\" value=\"left\"><span>左</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" v-model=\"element.options.textAlign\" value=\"center\"><span>中</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" v-model=\"element.options.textAlign\" value=\"right\"><span>右</span></label>\n </div>\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ap-vertical-align')\"><span class=\"pd-label\">垂直对齐</span>\n <div class=\"pd-radio-group\" role=\"radiogroup\">\n <label class=\"pd-radio\"><input type=\"radio\" v-model=\"element.options.verticalAlign\" value=\"top\"><span>顶</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" v-model=\"element.options.verticalAlign\" value=\"middle\"><span>中</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" v-model=\"element.options.verticalAlign\" value=\"bottom\"><span>底</span></label>\n </div>\n </div>\n <div class=\"color-row\">\n <div class=\"pd-field\" v-show=\"showItem('ap-color')\"><span class=\"pd-label\">颜色</span>\n <PresetColorPicker v-model=\"element.options.color\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ap-bg-color')\"><span class=\"pd-label\">背景色</span>\n <PresetColorPicker v-model=\"element.options.backgroundColor\" />\n </div>\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ap-line-height')\"><span class=\"pd-label\">行高</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.lineHeight\"\n :min=\"0\"\n :max=\"100\"\n style=\"width: 100%\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ap-letter-spacing')\"><span class=\"pd-label\">字间距</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.letterSpacing\"\n :min=\"0\"\n :max=\"20\"\n :step=\"0.5\"\n style=\"width: 100%\" />\n </div>\n </template>\n\n <p class=\"pd-empty\" v-if=\"!isTextType && !isTableType\">当前元素不支持外观设置</p>\n </form>\n </PropertyGroup>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { RuntimeElement } from '../../types'\nimport PresetColorPicker from '../PresetColorPicker.vue'\nimport PropertyGroup from './PropertyGroup.vue'\n\nconst props = defineProps<{\n element: RuntimeElement\n isTextType: boolean\n matchedKeys?: Set<string>\n searching?: boolean\n}>()\n\nfunction showItem(key: string): boolean {\n if (!props.searching) {\n return true\n }\n return props.matchedKeys?.has(key) ?? true\n}\n\nconst isTableType = computed(() => {\n return props.element.printElementType.type === 'table'\n})\n</script>\n\n<style scoped>\n.color-row {\n display: flex;\n gap: 16px;\n}</style>","<template>\n <div v-if=\"visible\" class=\"pd-dialog-overlay\" @keydown.esc=\"visible = false\">\n <section class=\"pd-dialog pd-dialog-large\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"expression-editor-title\">\n <header class=\"pd-dialog-header\">\n <strong id=\"expression-editor-title\">编辑表达式</strong>\n <button type=\"button\" class=\"pd-close\" aria-label=\"关闭\" @click=\"visible = false\">×</button>\n </header>\n <div class=\"expression-editor\">\n <!-- 左侧导航栏 -->\n <div class=\"ee-nav\">\n <div class=\"ee-nav-title\">类型</div>\n <div class=\"ee-nav-tabs\">\n <div\n class=\"ee-nav-tab\"\n :class=\"{ active: activeTab === 'field' }\"\n @click=\"activeTab = 'field'\"\n >\n 📁 字段\n </div>\n <div\n class=\"ee-nav-tab\"\n :class=\"{ active: activeTab === 'variable' }\"\n @click=\"activeTab = 'variable'\"\n >\n 🔧 变量\n </div>\n <div\n class=\"ee-nav-tab\"\n :class=\"{ active: activeTab === 'function' }\"\n @click=\"activeTab = 'function'\"\n >\n ⚡ 函数\n </div>\n </div>\n </div>\n\n <!-- 中间内容区 -->\n <div class=\"ee-content\">\n <div class=\"ee-content-search\">\n <input class=\"pd-input\" v-model=\"searchText\"\n :placeholder=\"searchPlaceholder\" />\n </div>\n <div class=\"ee-content-list\">\n <!-- 字段列表(按 fieldKey 首段分组:supplier.*/receiver.*/goods.* 等) -->\n <template v-if=\"activeTab === 'field'\">\n <template v-for=\"group in filteredGroups\" :key=\"group.key || '_top'\">\n <div v-if=\"group.key\" class=\"ee-field-group\" :class=\"{ 'is-list': group.isList }\">\n <span class=\"ee-field-group-icon\">{{ group.isList ? '📋' : '📁' }}</span>\n <span>{{ group.label }}</span>\n </div>\n <div\n v-for=\"field in group.fields\"\n :key=\"field.fieldKey\"\n class=\"ee-list-item ee-field-item\"\n :style=\"{ paddingLeft: group.key ? '22px' : '10px' }\"\n @dblclick=\"handleFieldDoubleClick(field)\"\n >\n <label class=\"ee-field-row\">\n <input\n type=\"checkbox\"\n class=\"pd-checkbox\"\n :checked=\"selectedFields.has(field.fieldKey)\"\n @change=\"toggleField(field)\"\n @click.stop\n />\n <span class=\"ee-item-label\">{{ field.fieldLabel }}</span>\n <span class=\"ee-item-key\">{{ field.fieldKey }}</span>\n </label>\n </div>\n </template>\n <p v-if=\"filteredGroups.length === 0\" class=\"pd-empty\">暂无字段</p>\n </template>\n\n <!-- 变量列表 -->\n <template v-if=\"activeTab === 'variable'\">\n <div\n v-for=\"sv in filteredSystemVars\"\n :key=\"sv.name\"\n class=\"ee-list-item\"\n @dblclick=\"handleItemDoubleClick(sv.template)\"\n >\n <div class=\"ee-item-label\">{{ sv.label }}</div>\n <div class=\"ee-item-key\">{{ sv.name }}</div>\n </div>\n </template>\n\n <!-- 函数列表 -->\n <template v-if=\"activeTab === 'function'\">\n <div class=\"ee-func-group\">\n <div class=\"ee-func-group-title\">聚合函数</div>\n <div\n v-for=\"fn in filteredAggregateFuncs\"\n :key=\"fn.name\"\n class=\"ee-list-item\"\n @dblclick=\"handleAggregateDoubleClick(fn)\"\n >\n <div class=\"ee-item-label\">{{ fn.label }}</div>\n <div class=\"ee-item-key\">{{ fn.name }}</div>\n </div>\n </div>\n <div class=\"ee-func-group\">\n <div class=\"ee-func-group-title\">格式化函数</div>\n <div\n v-for=\"fn in filteredFormatFuncs\"\n :key=\"fn.name\"\n class=\"ee-list-item\"\n @dblclick=\"handleItemDoubleClick(fn.template)\"\n >\n <div class=\"ee-item-label\">{{ fn.label }}</div>\n <div class=\"ee-item-key\">{{ fn.name }}</div>\n </div>\n </div>\n </template>\n </div>\n </div>\n\n <!-- 右侧编辑区 -->\n <div class=\"ee-editor\">\n <div class=\"ee-editor-section\">\n <div class=\"ee-editor-title\">表达式编辑</div>\n <textarea\n ref=\"textareaRef\"\n v-model=\"localExpression\"\n class=\"ee-textarea\"\n rows=\"6\"\n placeholder=\"双击左侧字段/函数插入表达式,如: {fieldKey} 或 SUM(amount)\"\n />\n </div>\n\n <div class=\"ee-editor-section\">\n <div class=\"ee-editor-title\">预览结果</div>\n <div class=\"ee-preview\" :class=\"{ 'ee-preview-error': previewResult === '(表达式错误)' }\">{{ previewResult }}</div>\n </div>\n\n <div class=\"ee-help-section\">\n <div class=\"ee-help-title\">帮助信息</div>\n <div class=\"ee-help-grid\">\n <div class=\"ee-help-card ee-help-field\">\n <div class=\"ee-help-card-title\">字段绑定</div>\n <div class=\"ee-help-card-content\">\n 使用 {字段名} 格式<br>\n 示例: {order.no}\n </div>\n </div>\n <div class=\"ee-help-card ee-help-function\">\n <div class=\"ee-help-card-title\">函数使用</div>\n <div class=\"ee-help-card-content\">\n SUM(字段) - 求和<br>\n AVG(字段) - 平均值<br>\n COUNT(字段) - 计数\n </div>\n </div>\n <div class=\"ee-help-card ee-help-variable\">\n <div class=\"ee-help-card-title\">系统变量</div>\n <div class=\"ee-help-card-content\">\n {page} - 当前页码<br>\n {total} - 总页数<br>\n {row} - 当前行号\n </div>\n </div>\n <div class=\"ee-help-card ee-help-conditional\">\n <div class=\"ee-help-card-title\">条件判断</div>\n <div class=\"ee-help-card-content\">\n IF(条件, 真值, 假值)<br>\n 示例: IF(amount>1000, \"大单\", \"小单\")\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <footer class=\"pd-dialog-footer\">\n <button type=\"button\" class=\"pd-button\" @click=\"visible = false\">取消</button>\n <button type=\"button\" class=\"pd-button primary\" @click=\"onConfirm\">确定</button>\n </footer>\n </section>\n</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, nextTick } from 'vue'\nimport type { PrintBusinessField } from '../types'\nimport { evaluateTemplate } from '../utils/expression-eval'\nimport { DEFAULT_DEMO_DATA } from '../utils/demo-data'\nimport { groupFields, filterGroups } from '../utils/field-groups'\n\nconst props = defineProps<{\n modelValue: boolean\n expression: string\n /** 宿主传入的业务字段(字段页数据源) */\n fields?: PrintBusinessField[]\n}>()\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: boolean]\n 'update:expression': [value: string]\n}>()\n\nconst visible = computed({\n get: () => props.modelValue,\n set: (val) => emit('update:modelValue', val),\n})\n\n// 新增状态\nconst activeTab = ref<'field' | 'variable' | 'function'>('field')\n\n// 搜索占位符\nconst searchPlaceholder = computed(() => {\n switch (activeTab.value) {\n case 'field': return '搜索字段...'\n case 'variable': return '搜索变量...'\n case 'function': return '搜索函数...'\n default: return '搜索...'\n }\n})\n\n// 字段列表(宿主注入的扁平业务字段,按 fieldKey 首段分组展示)\nconst searchText = ref('')\nconst filteredGroups = computed(() =>\n filterGroups(groupFields(props.fields ?? []), searchText.value),\n)\n\n// 字段多选模式\nconst selectedFields = ref<Set<string>>(new Set())\n\nfunction toggleField(field: PrintBusinessField) {\n const key = field.fieldKey\n const next = new Set(selectedFields.value)\n if (next.has(key)) {\n next.delete(key)\n } else {\n next.add(key)\n }\n selectedFields.value = next\n}\n\n// 当弹出框打开时,根据当前 expression 值尝试匹配已选字段\nwatch(visible, (val) => {\n if (val) {\n // 每次打开时重置为外部传入值,避免携带上次编辑残留\n localExpression.value = props.expression || ''\n const found = (props.fields ?? []).find(\n f => props.expression === f.fieldKey || props.expression === `{${f.fieldKey}}`,\n )\n if (found) {\n selectedFields.value = new Set([found.fieldKey])\n }\n } else {\n selectedFields.value = new Set()\n }\n})\n\n// 字段双击处理\nfunction handleFieldDoubleClick(field: PrintBusinessField) {\n insertAtCursor(`{${field.fieldKey}}`)\n}\n\n// 聚合函数双击 — 自动填充选中字段\nfunction handleAggregateDoubleClick(fn: { name: string; template: string }) {\n if (selectedFields.value.size > 0) {\n const fields = Array.from(selectedFields.value).join(', ')\n insertAtCursor(`${fn.name}(${fields})`)\n } else {\n insertAtCursor(fn.template)\n }\n}\n\n// 通用双击处理(变量和格式化函数)\nfunction handleItemDoubleClick(text: string) {\n insertAtCursor(text)\n}\n\n// 过滤后的系统变量\nconst filteredSystemVars = computed(() => {\n if (!searchText.value.trim()) return systemVars\n const keyword = searchText.value.trim().toLowerCase()\n return systemVars.filter(sv =>\n sv.label.toLowerCase().includes(keyword) ||\n sv.name.toLowerCase().includes(keyword)\n )\n})\n\n// 过滤后的聚合函数\nconst filteredAggregateFuncs = computed(() => {\n if (!searchText.value.trim()) return aggregateFunctions\n const keyword = searchText.value.trim().toLowerCase()\n return aggregateFunctions.filter(fn =>\n fn.label.toLowerCase().includes(keyword) || fn.name.toLowerCase().includes(keyword)\n )\n})\n\n// 过滤后的格式化函数\nconst filteredFormatFuncs = computed(() => {\n if (!searchText.value.trim()) return formatFunctions\n const keyword = searchText.value.trim().toLowerCase()\n return formatFunctions.filter(fn =>\n fn.label.toLowerCase().includes(keyword) || fn.name.toLowerCase().includes(keyword)\n )\n})\n\n// 表达式编辑模式\nconst localExpression = ref(props.expression || '')\nconst textareaRef = ref<HTMLTextAreaElement | null>(null)\n\nwatch(() => props.expression, (val) => {\n localExpression.value = val || ''\n})\n\nconst aggregateFunctions = [\n { name: 'SUM', label: '求和', template: 'SUM()' },\n { name: 'AVG', label: '平均值', template: 'AVG()' },\n { name: 'COUNT', label: '计数', template: 'COUNT()' },\n { name: 'MIN', label: '最小值', template: 'MIN()' },\n { name: 'MAX', label: '最大值', template: 'MAX()' },\n]\n\nconst formatFunctions = [\n { name: 'MONEY', label: '金额格式化', template: 'MONEY()' },\n { name: 'DATE', label: '日期格式化', template: 'DATE()' },\n { name: 'UPPER', label: '大写金额', template: 'UPPER()' },\n { name: 'IF', label: '条件判断', template: 'IF()' },\n]\n\nconst systemVars = [\n { name: 'pageIndex', label: '当前页码', template: '{pageIndex}' },\n { name: 'totalPages', label: '总页数', template: '{totalPages}' },\n { name: 'printDate', label: '打印日期', template: '{printDate}' },\n { name: 'printTime', label: '打印时间', template: '{printTime}' },\n]\n\nconst previewResult = computed(() => {\n if (!localExpression.value.trim()) return '(输入表达式后预览)'\n try {\n const ctx = {\n ...DEFAULT_DEMO_DATA,\n // 系统变量示例值,与渲染端一致(print-render 在生成 HTML 时替换)\n pageIndex: 1,\n totalPages: 1,\n printDate: new Date().toISOString().split('T')[0],\n printTime: Date.now(),\n }\n const result = evaluateTemplate(localExpression.value, ctx)\n if (result === undefined || result === null) return '(无法计算)'\n return String(result)\n } catch (e) {\n return '(表达式错误)'\n }\n})\n\nfunction insertAtCursor(text: string) {\n const ta = textareaRef.value\n if (!ta) {\n localExpression.value += text\n return\n }\n const start = ta.selectionStart\n const end = ta.selectionEnd\n const before = localExpression.value.substring(0, start)\n const after = localExpression.value.substring(end)\n localExpression.value = before + text + after\n nextTick(() => {\n ta.focus()\n ta.selectionStart = ta.selectionEnd = start + text.length\n })\n}\n\nfunction onConfirm() {\n emit('update:expression', localExpression.value)\n visible.value = false\n}\n</script>\n\n<style scoped>\n/* 主容器 */\n.expression-editor {\n display: flex;\n height: 450px;\n gap: 0;\n}\n\n/* 左侧导航 */\n.ee-nav {\n width: 100px;\n background: var(--pd-sidebar);\n border-right: 1px solid var(--pd-border);\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n}\n\n.ee-nav-title {\n padding: 10px;\n border-bottom: 1px solid var(--pd-border);\n font-weight: 600;\n font-size: 13px;\n color: var(--pd-text);\n text-align: center;\n}\n\n.ee-nav-tabs {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: 6px;\n gap: 4px;\n}\n\n.ee-nav-tab {\n padding: 8px 10px;\n border-radius: 6px;\n cursor: pointer;\n font-size: 12px;\n text-align: center;\n transition: all 0.2s;\n}\n\n.ee-nav-tab.active {\n background: var(--pd-accent);\n color: white;\n}\n\n.ee-nav-tab:not(.active) {\n background: white;\n border: 1px solid var(--pd-border);\n color: var(--pd-text);\n}\n\n.ee-nav-tab:hover:not(.active) {\n background: #ecf5ff;\n border-color: var(--pd-accent);\n}\n\n/* 中间内容区 */\n.ee-content {\n width: 300px;\n display: flex;\n flex-direction: column;\n border-right: 1px solid var(--pd-border);\n flex-shrink: 0;\n}\n\n.ee-content-search {\n padding: 10px;\n border-bottom: 1px solid var(--pd-border);\n}\n\n.ee-content-list {\n flex: 1;\n padding: 8px;\n overflow-y: auto;\n min-height: 0;\n}\n\n/* 函数分组 */\n.ee-func-group {\n margin-bottom: 12px;\n}\n\n.ee-func-group-title {\n font-size: 11px;\n font-weight: 600;\n color: var(--pd-text-muted);\n padding: 4px 10px 6px;\n border-bottom: 1px solid var(--pd-border);\n margin-bottom: 4px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* 字段分组标题 */\n.ee-field-group {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 6px 10px;\n font-size: 12px;\n font-weight: 600;\n color: var(--pd-text);\n}\n.ee-field-group.is-list {\n color: var(--pd-accent, #165DFF);\n}\n.ee-field-group-icon {\n font-size: 13px;\n filter: saturate(.6);\n}\n/* 列表项 */\n.ee-list-item {\n padding: 8px 10px;\n cursor: pointer;\n border-radius: 4px;\n margin-bottom: 4px;\n transition: all 0.2s;\n}\n.ee-field-row {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n.ee-field-row .ee-item-label {\n flex: 1;\n}\n\n.ee-list-item:hover {\n background: #ecf5ff;\n border-color: var(--pd-accent);\n}\n\n.ee-list-item .ee-item-label {\n font-size: 12px;\n color: var(--pd-text);\n}\n\n.ee-list-item .ee-item-key {\n font-size: 10px;\n color: var(--pd-text-muted);\n font-family: monospace;\n margin-top: 2px;\n}\n\n/* 右侧编辑区 */\n.ee-editor {\n flex: 1;\n display: flex;\n flex-direction: column;\n background: var(--pd-sidebar);\n min-width: 0;\n}\n\n.ee-editor-section {\n padding: 12px;\n border-bottom: 1px solid var(--pd-border);\n}\n\n.ee-editor-title {\n font-size: 11px;\n color: var(--pd-text-muted);\n margin-bottom: 6px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* 表达式编辑框 */\n.ee-textarea {\n width: 100%;\n border: 1px solid var(--pd-border);\n border-radius: 6px;\n padding: 10px;\n font-family: monospace;\n font-size: 13px;\n resize: vertical;\n box-sizing: border-box;\n min-height: 100px;\n}\n\n.ee-textarea:focus {\n outline: none;\n border-color: var(--pd-accent);\n}\n\n/* 预览结果 */\n.ee-preview {\n padding: 10px;\n background: var(--pd-bg);\n border: 1px solid var(--pd-border);\n border-radius: 6px;\n min-height: 30px;\n font-size: 13px;\n color: var(--pd-text);\n line-height: 1.6;\n}\n\n.ee-preview-error {\n color: #e53e3e;\n background: #fef2f2;\n border-color: #fecaca;\n}\n\n/* 帮助信息 */\n.ee-help-section {\n flex: 1;\n padding: 12px;\n overflow-y: auto;\n min-height: 0;\n}\n\n.ee-help-title {\n font-size: 11px;\n color: var(--pd-text-muted);\n margin-bottom: 8px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.ee-help-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px;\n}\n\n.ee-help-card {\n border-radius: 6px;\n padding: 10px;\n}\n\n.ee-help-card-title {\n font-size: 12px;\n font-weight: 600;\n margin-bottom: 4px;\n}\n\n.ee-help-card-content {\n font-size: 11px;\n line-height: 1.5;\n color: var(--pd-text);\n}\n\n.ee-help-field {\n background: #f0f9ff;\n border: 1px solid #bae6fd;\n}\n\n.ee-help-field .ee-help-card-title {\n color: #0369a1;\n}\n\n.ee-help-function {\n background: #f0fdf4;\n border: 1px solid #bbf7d0;\n}\n\n.ee-help-function .ee-help-card-title {\n color: #166534;\n}\n\n.ee-help-variable {\n background: #fefce8;\n border: 1px solid #fde68a;\n}\n\n.ee-help-variable .ee-help-card-title {\n color: #854d0e;\n}\n\n.ee-help-conditional {\n background: #fdf2f8;\n border: 1px solid #fbcfe8;\n}\n\n.ee-help-conditional .ee-help-card-title {\n color: #9d174d;\n}\n\n/* 弹窗内容区域 */\n.expression-editor {\n max-height: min(600px, 80vh);\n overflow-y: auto;\n padding: 16px;\n}\n</style>\n","<template>\n <div class=\"pd-field\"><span class=\"pd-label\">{{ descriptor.label }}</span>\n <input :value=\"modelValue\" class=\"pd-input\"\n :placeholder=\"descriptor.placeholder || '输入内容,支持 {字段} 表达式'\"\n @input=\"emit('update:modelValue', ($event.target as HTMLInputElement).value)\"\n @dblclick=\"openEditor\" />\n </div>\n <ExpressionEditor\n v-model=\"editorVisible\"\n :fields=\"fields\"\n :expression=\"modelValue\"\n @update:expression=\"(v: string) => emit('update:modelValue', v)\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport type { BindingDescriptor, PrintBusinessField } from '../../types'\nimport ExpressionEditor from '../ExpressionEditor.vue'\n\nconst props = defineProps<{\n descriptor: BindingDescriptor\n modelValue: string\n fields?: PrintBusinessField[]\n}>()\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n}>()\n\nconst editorVisible = ref(false)\n\nfunction openEditor() {\n editorVisible.value = true\n}\n</script>\n\n<style scoped>\n.binding-control {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n</style>","<template>\n <PropertyGroup title=\"表格设置\" icon=\"Grid\" default-expanded group-key=\"table-settings\">\n <form class=\"pd-form\" @submit.prevent>\n <div class=\"pd-field\"><span class=\"pd-label\">列表数据源字段</span>\n <select :value=\"element.options.dataSource\" class=\"pd-select\"\n style=\"width: 100%\" @change=\"onSourceChange(($event.target as HTMLSelectElement).value)\">\n <option v-for=\"f in listFieldOptions\" :key=\"f.value\" :value=\"f.value\">{{ f.label }}</option>\n </select>\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">默认字号 (pt)</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.tableDefaultFontSize\" :min=\"5\" :max=\"72\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">默认文字颜色</span>\n <PresetColorPicker v-model=\"element.options.tableDefaultColor\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">默认内边距 (mm)</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.tableDefaultPadding\" :min=\"0\" :max=\"10\" :step=\"0.5\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">列宽 (mm)</span>\n <div v-for=\"(w, i) in element.options.tableColWidths\" :key=\"i\" class=\"col-width-row\">\n <span style=\"width: 60px\">列{{ i + 1 }}</span>\n <input :value=\"w\" type=\"number\" class=\"pd-input\" :min=\"5\" :max=\"200\" :step=\"1\" @input=\"onColWidthChange(i, ($event.target as HTMLInputElement).valueAsNumber)\" />\n </div>\n </div>\n </form>\n </PropertyGroup>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, inject } from 'vue'\nimport PresetColorPicker from '../PresetColorPicker.vue'\nimport type { RuntimeElement, PrintBusinessField } from '../../types'\nimport { TABLE_EDIT_KEY } from '../../composables/useTableSelection'\nimport { syncTableElementSize } from '../../utils/table-matrix'\nimport PropertyGroup from './PropertyGroup.vue'\n\nconst props = defineProps<{\n element: RuntimeElement\n fields: PrintBusinessField[]\n}>()\n\nconst tableEditCtx = inject(TABLE_EDIT_KEY, null)\n\n/** 列表数据源选项:宿主以 fieldType='list' 声明明细列表字段 */\nconst listFieldOptions = computed(() => {\n return props.fields\n .filter(f => f.fieldType === 'list')\n .map(f => ({ label: f.fieldLabel, value: f.fieldKey }))\n})\n\nfunction onSourceChange(v: string) {\n props.element.options.dataSource = v || undefined\n tableEditCtx?.recordHistory()\n}\n\nfunction onColWidthChange(i: number, v: number | undefined) {\n if (v === undefined) return\n const widths = props.element.options.tableColWidths!\n const maxW = tableEditCtx?.maxTableWidth.value ?? Infinity\n const othersW = widths.reduce((s, w, idx) => idx === i ? s : s + w, 0)\n if (othersW + v > maxW) {\n const clamped = Math.max(5, Math.round((maxW - othersW) * 10) / 10)\n alert(`表格总宽不能超过打印范围宽度 ${maxW}mm,列${i + 1} 已调整为 ${clamped}mm`)\n widths[i] = clamped\n } else {\n widths[i] = v\n }\n syncTableElementSize(props.element.options)\n tableEditCtx?.recordHistory()\n}\n</script>\n\n<style scoped>\n.col-width-row {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 4px;\n width: 100%;\n}\n</style>","<template>\n <PropertyGroup title=\"边框与背景\" icon=\"Picture\" default-expanded group-key=\"border-bg\">\n <form class=\"pd-form\" @submit.prevent>\n <div class=\"border-row\">\n <div class=\"pd-field\" v-show=\"showItem('bb-border-width')\"><span class=\"pd-label\">边框宽度</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.borderWidth\"\n :min=\"0\"\n :max=\"20\"\n :step=\"0.25\"\n />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('bb-border-color')\"><span class=\"pd-label\">边框颜色</span>\n <PresetColorPicker v-model=\"element.options.borderColor\" />\n </div>\n </div>\n <div class=\"pd-field\" v-show=\"showItem('bb-bg-color')\"><span class=\"pd-label\">背景色</span>\n <PresetColorPicker v-model=\"element.options.backgroundColor\" />\n </div>\n </form>\n </PropertyGroup>\n</template>\n\n<script setup lang=\"ts\">\nimport type { RuntimeElement } from '../../types'\nimport PresetColorPicker from '../PresetColorPicker.vue'\nimport PropertyGroup from './PropertyGroup.vue'\n\nconst props = defineProps<{\n element: RuntimeElement\n matchedKeys?: Set<string>\n searching?: boolean\n}>()\n\nfunction showItem(key: string): boolean {\n if (!props.searching) {\n return true\n }\n return props.matchedKeys?.has(key) ?? true\n}\n</script>\n\n<style scoped>\n.border-row {\n display: flex;\n gap: 16px;\n}</style>","<template>\n <PropertyGroup title=\"高级设置\" icon=\"Setting\" group-key=\"advanced\">\n <form class=\"pd-form\" @submit.prevent>\n <div class=\"advanced-row\">\n <div class=\"pd-field\" v-show=\"showItem('ad-locked')\"><span class=\"pd-label\">锁定</span>\n <input type=\"checkbox\" class=\"pd-switch\" v-model=\"element.options.locked\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ad-fixed')\"><span class=\"pd-label\">每页重复</span>\n <input type=\"checkbox\" class=\"pd-switch\" v-model=\"element.options.fixed\" />\n </div>\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ad-z-index')\"><span class=\"pd-label\">层级</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.zIndex\"\n :min=\"0\"\n :max=\"999\"\n style=\"width: 100%\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ad-delete')\">\n <button type=\"button\" class=\"pd-button danger\" @click=\"$emit('delete-element')\">\n 删除元素\n </button>\n </div>\n </form>\n </PropertyGroup>\n</template>\n\n<script setup lang=\"ts\">\nimport type { RuntimeElement } from '../../types'\nimport PropertyGroup from './PropertyGroup.vue'\n\nconst props = defineProps<{\n element: RuntimeElement\n matchedKeys?: Set<string>\n searching?: boolean\n}>()\n\nfunction showItem(key: string): boolean {\n if (!props.searching) {\n return true\n }\n return props.matchedKeys?.has(key) ?? true\n}\n\ndefineEmits<{\n 'delete-element': []\n}>()\n</script>\n\n<style scoped>\n.advanced-row {\n display: flex;\n gap: 16px;\n}\n</style>\n","<template>\n <PropertyGroup title=\"分页配置\" icon=\"Document\" group-key=\"pagination\">\n <form class=\"pd-form\" @submit.prevent>\n <!-- 表格元素分页配置 -->\n <template v-if=\"isTable\">\n <div class=\"pd-field\" v-show=\"showItem('pg-enabled')\"><span class=\"pd-label\">启用分页</span>\n <input type=\"checkbox\" class=\"pd-switch\" :checked=\"tablePaginationEnabled\" @change=\"onTablePaginationChange(($event.target as HTMLInputElement).checked)\" />\n </div>\n </template>\n <!-- 非表格元素分页配置 -->\n <template v-else>\n <div class=\"pd-field\" v-show=\"showItem('pg-pageable')\"><span class=\"pd-label\">参与分页</span>\n <input type=\"checkbox\" class=\"pd-switch\" :checked=\"paginationPageable\" @change=\"onPageableChange(($event.target as HTMLInputElement).checked)\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('pg-keep-with-next')\"><span class=\"pd-label\">与下元素同页</span>\n <input type=\"checkbox\" class=\"pd-switch\" :checked=\"paginationKeepWithNext\" @change=\"onKeepWithNextChange(($event.target as HTMLInputElement).checked)\" />\n </div>\n </template>\n </form>\n </PropertyGroup>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { RuntimeElement } from '../../types'\nimport PropertyGroup from './PropertyGroup.vue'\n\nconst props = defineProps<{\n element: RuntimeElement\n matchedKeys?: Set<string>\n searching?: boolean\n}>()\n\nconst isTable = computed(() => props.element.printElementType.type === 'table')\n\n// 表格分页\nconst tablePaginationEnabled = computed({\n get: () => props.element.options.tablePagination?.enabled ?? true,\n set: () => { /* 由 change 处理 */ },\n})\n\nfunction onTablePaginationChange(checked: boolean) {\n props.element.options.tablePagination = {\n enabled: checked,\n }\n}\n\n// 非表格分页\nconst paginationPageable = computed({\n get: () => props.element.options.pagination?.pageable ?? true,\n set: () => { /* 由 change 处理 */ },\n})\n\nconst paginationKeepWithNext = computed({\n get: () => props.element.options.pagination?.keepWithNext ?? false,\n set: () => { /* 由 change 处理 */ },\n})\n\nfunction onPageableChange(checked: boolean) {\n props.element.options.pagination = {\n pageable: checked,\n keepWithNext: paginationKeepWithNext.value,\n }\n}\n\nfunction onKeepWithNextChange(checked: boolean) {\n props.element.options.pagination = {\n pageable: paginationPageable.value,\n keepWithNext: checked,\n }\n}\n\nfunction showItem(key: string): boolean {\n if (!props.searching) return true\n return props.matchedKeys?.has(key) ?? true\n}\n</script>\n","<template>\n <div class=\"image-content-upload\">\n <label class=\"pd-button small upload-label\" :class=\"{ disabled: uploadDisabled }\">\n <svg class=\"pd-icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M12 3l4 4h-3v7h-2V7H8zm-7 12h14v5H5Z\" /></svg>\n {{ uploading ? '上传中...' : '上传图片' }}\n <input\n class=\"visually-hidden\"\n type=\"file\"\n accept=\"image/*\"\n :disabled=\"uploadDisabled\"\n @change=\"handleFileChange\"\n >\n </label>\n <p class=\"upload-tip\">支持 jpg/png/gif/bmp/webp/svg 等图片,上传后填入相对路径</p>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, inject, computed } from 'vue'\nimport { UPLOAD_IMAGE_KEY } from '../../composables/useHostAdapter'\n\nconst props = defineProps<{ disabled?: boolean }>()\n\nconst emit = defineEmits<{ success: [url: string] }>()\n\nconst uploading = ref(false)\n// 宿主注入的图片上传适配器;未注入时上传不可用\nconst uploadImage = inject(UPLOAD_IMAGE_KEY, computed(() => undefined))\nconst uploadDisabled = computed(() => props.disabled || uploading.value || !uploadImage.value)\n\nasync function handleFileChange(event: Event) {\n const input = event.target as HTMLInputElement\n const file = input.files?.[0]\n if (!file) return\n if (!file.type.startsWith('image/')) {\n alert('仅支持上传图片文件')\n input.value = ''\n return\n }\n if (!uploadImage.value) {\n alert('图片上传能力未配置')\n input.value = ''\n return\n }\n uploading.value = true\n try {\n const url = await uploadImage.value(file)\n if (url) {\n emit('success', url)\n } else {\n alert('图片上传失败')\n }\n } catch (err) {\n alert(err instanceof Error ? err.message : '图片上传失败')\n } finally {\n uploading.value = false\n input.value = ''\n }\n}\n</script>\n\n<style scoped>\n.image-content-upload {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 4px;\n margin-top: 4px;\n}\n.upload-label {\n cursor: pointer;\n}\n.upload-label.disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n.upload-tip {\n margin: 0;\n font-size: 11px;\n color: var(--pd-text-muted, #909399);\n}\n.visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n}\n</style>\n","<!-- 表格行属性分组:行类型/行高/每页重复(小计行按页重复) -->\n<template>\n <PropertyGroup title=\"行属性\" icon=\"Grid\" default-expanded group-key=\"table-row\">\n <form class=\"pd-form\" @submit.prevent>\n <div class=\"pd-field\"><span class=\"pd-label\">行类型</span>\n <select :value=\"row.type\" class=\"pd-select\" style=\"width: 100%\" @change=\"onTypeChange(($event.target as HTMLSelectElement).value as TableRowType)\">\n <option value=\"header\">标题行</option>\n <option value=\"data\">数据行</option>\n <option value=\"subtotal\">小计行(每页小计)</option>\n <option value=\"summary\">汇总行</option>\n </select>\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">行高 (mm)</span>\n <input :value=\"row.height\" type=\"number\" class=\"pd-input\"\n :min=\"3\"\n :max=\"100\"\n :step=\"0.5\"\n style=\"width: 100%\" @input=\"onHeightChange(($event.target as HTMLInputElement).valueAsNumber)\" />\n </div>\n <div class=\"pd-field\" v-if=\"row.type === 'header'\"><span class=\"pd-label\">每页顶部重复</span>\n <input :checked=\"row.repeatOnPage ?? false\" type=\"checkbox\" class=\"pd-switch\" @input=\"onRepeatChange(!!($event.target as HTMLInputElement).checked)\" />\n </div>\n </form>\n </PropertyGroup>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, inject } from 'vue'\nimport type { RuntimeElement, TableSelection, TableRowType } from '../../types'\nimport { setRowType, syncTableElementSize } from '../../utils/table-matrix'\nimport { TABLE_EDIT_KEY } from '../../composables/useTableSelection'\nimport PropertyGroup from './PropertyGroup.vue'\n\nconst props = defineProps<{ element: RuntimeElement; selection: TableSelection }>()\nconst ctx = inject(TABLE_EDIT_KEY)!\n\nconst row = computed(() => props.element.options.tableRows![props.selection.r1]!)\n\nfunction onTypeChange(t: TableRowType) {\n const err = setRowType(\n props.element.options.tableRows!,\n props.selection.r1,\n t,\n )\n if (err) {\n alert(err)\n return\n }\n ctx.recordHistory()\n}\n\nfunction onHeightChange(v: number | undefined) {\n if (v === undefined) return\n row.value.height = v\n syncTableElementSize(props.element.options)\n ctx.recordHistory()\n}\n\nfunction onRepeatChange(v: boolean) {\n row.value.repeatOnPage = v\n ctx.recordHistory()\n}\n</script>\n","<!-- 表格单元格分组:格式化/样式/边框/合并拆分 -->\n<template>\n <PropertyGroup title=\"单元格\" icon=\"Menu\" default-expanded group-key=\"table-cell\">\n <form class=\"pd-form\" @submit.prevent>\n <div class=\"pd-field\"><span class=\"pd-label\">单元格类型</span>\n <div class=\"pd-radio-group\" role=\"radiogroup\">\n <label class=\"pd-radio\"><input type=\"radio\" value=\"text\" :checked=\"(mainCell.cellType || 'text') === 'text'\" @change=\"onCellTypeChange(($event.target as HTMLInputElement).value)\"><span>文本</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" value=\"barcode\" :checked=\"mainCell.cellType === 'barcode'\" @change=\"onCellTypeChange(($event.target as HTMLInputElement).value)\"><span>条形码</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" value=\"qrcode\" :checked=\"mainCell.cellType === 'qrcode'\" @change=\"onCellTypeChange(($event.target as HTMLInputElement).value)\"><span>二维码</span></label>\n </div>\n </div>\n\n <div class=\"pd-field\" v-if=\"isBarcodeCell\"><span class=\"pd-label\">码制</span>\n <select :value=\"mainCell.barcodeType || 'CODE128'\" class=\"pd-select\" @change=\"write(c => { c.barcodeType = ($event.target as HTMLSelectElement).value || undefined })\">\n <option value=\"CODE128\">CODE128(通用)</option>\n <option value=\"EAN13\">EAN13(商品码)</option>\n <option value=\"EAN8\">EAN8</option>\n <option value=\"UPC\">UPC</option>\n <option value=\"CODE39\">CODE39</option>\n <option value=\"ITF14\">ITF14</option>\n </select>\n </div>\n <div class=\"pd-field\" v-if=\"isBarcodeCell\"><span class=\"pd-label\">显示文本</span>\n <input :checked=\"mainCell.showBarcodeText !== false\" type=\"checkbox\" class=\"pd-switch\" @input=\"write(c => { c.showBarcodeText = !!($event.target as HTMLInputElement).checked })\" />\n </div>\n <div class=\"pd-field\" v-if=\"isQrcodeCell\"><span class=\"pd-label\">纠错级别</span>\n <select :value=\"mainCell.qrCodeLevel || 'M'\" class=\"pd-select\" @change=\"write(c => { c.qrCodeLevel = ($event.target as HTMLSelectElement).value || undefined })\">\n <option value=\"L\">L(最低,容量大)</option>\n <option value=\"M\">M(推荐)</option>\n <option value=\"Q\">Q</option>\n <option value=\"H\">H(最高)</option>\n </select>\n </div>\n\n <div class=\"pd-field\"><span class=\"pd-label\">内容</span>\n <input :value=\"mainCell.formatter || ''\" class=\"pd-input\"\n placeholder=\"输入内容,支持 {字段} 表达式\"\n @input=\"write(c => { c.formatter = ($event.target as HTMLInputElement).value || undefined })\"\n @dblclick=\"openFormatterEditor\" />\n </div>\n\n <div class=\"pd-field\"><span class=\"pd-label\">水平对齐</span>\n <div class=\"pd-radio-group\" role=\"radiogroup\">\n <label class=\"pd-radio\"><input type=\"radio\" value=\"left\" :checked=\"mainCell.align === 'left'\" @change=\"onAlignChange(($event.target as HTMLInputElement).value)\"><span>左</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" value=\"center\" :checked=\"mainCell.align === 'center'\" @change=\"onAlignChange(($event.target as HTMLInputElement).value)\"><span>中</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" value=\"right\" :checked=\"mainCell.align === 'right'\" @change=\"onAlignChange(($event.target as HTMLInputElement).value)\"><span>右</span></label>\n </div>\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">垂直对齐</span>\n <div class=\"pd-radio-group\" role=\"radiogroup\">\n <label class=\"pd-radio\"><input type=\"radio\" value=\"top\" :checked=\"mainCell.valign === 'top'\" @change=\"onValignChange(($event.target as HTMLInputElement).value)\"><span>上</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" value=\"middle\" :checked=\"mainCell.valign === 'middle'\" @change=\"onValignChange(($event.target as HTMLInputElement).value)\"><span>中</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" value=\"bottom\" :checked=\"mainCell.valign === 'bottom'\" @change=\"onValignChange(($event.target as HTMLInputElement).value)\"><span>下</span></label>\n </div>\n </div>\n <div class=\"cell-style-grid\">\n <div class=\"pd-field\"><span class=\"pd-label\">字体</span>\n <select :value=\"mainCell.fontFamily\" class=\"pd-select\"\n placeholder=\"继承默认\" @change=\"write(c => { c.fontFamily = ($event.target as HTMLSelectElement).value || undefined })\">\n <option value=\"SimSun\">宋体</option>\n <option value=\"SimHei\">黑体</option>\n <option value=\"Microsoft YaHei\">微软雅黑</option>\n <option value=\"KaiTi\">楷体</option>\n <option value=\"FangSong\">仿宋</option>\n <option value=\"Arial\">Arial</option>\n </select>\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">字号 (pt)</span>\n <input :value=\"mainCell.fontSize\" type=\"number\" class=\"pd-input\"\n :min=\"5\"\n :max=\"72\" @input=\"write(c => { c.fontSize = ($event.target as HTMLInputElement).valueAsNumber ?? undefined })\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">加粗</span>\n <input :checked=\"mainCell.fontWeight === 'bold'\" type=\"checkbox\" class=\"pd-switch\" @input=\"write(c => { c.fontWeight = ($event.target as HTMLInputElement).checked ? 'bold' : undefined })\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">文字颜色</span>\n <PresetColorPicker :model-value=\"mainCell.color\" @update:model-value=\"write(c => { c.color = $event })\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">背景色</span>\n <PresetColorPicker :model-value=\"mainCell.backgroundColor\" @update:model-value=\"write(c => { c.backgroundColor = $event })\" />\n </div>\n </div>\n\n <h3 class=\"pd-divider\">边框</h3>\n <div class=\"border-style-row\">\n <select class=\"pd-select\" v-model=\"borderStyle\" style=\"width: 90px\">\n <option value=\"solid\">实线</option>\n <option value=\"dashed\">虚线</option>\n <option value=\"dotted\">点线</option>\n <option value=\"double\">双线</option>\n </select>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"borderWidth\"\n :min=\"0.25\"\n :max=\"5\"\n :step=\"0.25\"\n style=\"width: 90px\" />\n <PresetColorPicker v-model=\"borderColor\" />\n </div>\n <div class=\"pd-button-group border-presets\">\n <button type=\"button\" class=\"pd-button small\" @click=\"preset('all')\">全部</button>\n <button type=\"button\" class=\"pd-button small\" @click=\"preset('outer')\">外侧</button>\n <button type=\"button\" class=\"pd-button small\" @click=\"preset('inner')\">内部</button>\n <button type=\"button\" class=\"pd-button small\" @click=\"preset('none')\">无</button>\n </div>\n <div class=\"pd-checkbox-group\">\n <label class=\"pd-checkbox\"><input type=\"checkbox\" v-model=\"edgeChecks\" value=\"top\" @change=\"onEdgesChange($event)\"><span>上</span></label>\n <label class=\"pd-checkbox\"><input type=\"checkbox\" v-model=\"edgeChecks\" value=\"right\" @change=\"onEdgesChange($event)\"><span>右</span></label>\n <label class=\"pd-checkbox\"><input type=\"checkbox\" v-model=\"edgeChecks\" value=\"bottom\" @change=\"onEdgesChange($event)\"><span>下</span></label>\n <label class=\"pd-checkbox\"><input type=\"checkbox\" v-model=\"edgeChecks\" value=\"left\" @change=\"onEdgesChange($event)\"><span>左</span></label>\n </div>\n\n <div class=\"pd-field\"><span class=\"pd-label\">内边距 (mm)</span>\n <input :value=\"mainCell.padding\" type=\"number\" class=\"pd-input\"\n :min=\"0\"\n :max=\"10\"\n :step=\"0.5\" @input=\"write(c => { c.padding = ($event.target as HTMLInputElement).valueAsNumber ?? undefined })\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">自动换行</span>\n <input :checked=\"mainCell.wordWrap ?? true\" type=\"checkbox\" class=\"pd-switch\" @input=\"write(c => { c.wordWrap = !!($event.target as HTMLInputElement).checked })\" />\n </div>\n\n <div class=\"merge-btns\">\n <button type=\"button\" class=\"pd-button small\" :disabled=\"!!mergeReason\" :title=\"mergeReason || ''\" @click=\"doMerge\">\n 合并单元格\n </button>\n <button type=\"button\" class=\"pd-button small\" :disabled=\"!canSplit\" @click=\"doSplit\">拆分单元格</button>\n </div>\n </form>\n </PropertyGroup>\n\n <ExpressionEditor\n v-model=\"formatterEditorVisible\"\n :fields=\"fields\"\n :expression=\"pendingFormatterValue\"\n @update:expression=\"onFormatterEditorConfirm\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, inject, ref } from 'vue'\nimport type {\n RuntimeElement, TableSelection, TableCell, TableCellBorder, TableCellBorders, TableCellType, TextAlign,\n PrintBusinessField,\n} from '../../types'\nimport {\n canMergeReason, mergeCells, splitCells, applyBorderPreset, findMainCell, type BorderPreset,\n} from '../../utils/table-matrix'\nimport { TABLE_EDIT_KEY } from '../../composables/useTableSelection'\nimport PropertyGroup from './PropertyGroup.vue'\nimport ExpressionEditor from '../ExpressionEditor.vue'\nimport PresetColorPicker from '../PresetColorPicker.vue'\n\nconst props = defineProps<{\n element: RuntimeElement\n selection: TableSelection\n fields: PrintBusinessField[]\n}>()\nconst ctx = inject(TABLE_EDIT_KEY)!\n\nconst rows = computed(() => props.element.options.tableRows!)\n\nconst mainCell = computed<TableCell>(() => {\n const m = findMainCell(rows.value, props.selection.r1, props.selection.c1)\n return rows.value[m.r]!.cells[m.c]!\n})\n\nconst formatterEditorVisible = ref(false)\nconst pendingFormatterValue = ref('')\n\nconst isBarcodeCell = computed(() => mainCell.value.cellType === 'barcode')\nconst isQrcodeCell = computed(() => mainCell.value.cellType === 'qrcode')\n\nfunction onAlignChange(v: string) {\n write(c => { c.align = v as TextAlign })\n}\n\nfunction onValignChange(v: string) {\n write(c => { c.valign = v as TableCell['valign'] })\n}\n\nfunction onCellTypeChange(v: string) {\n write(c => {\n c.cellType = v === 'text' ? undefined : (v as TableCellType)\n if (v !== 'barcode') {\n c.barcodeType = undefined\n c.showBarcodeText = undefined\n }\n if (v !== 'qrcode') c.qrCodeLevel = undefined\n })\n}\n\nfunction openFormatterEditor() {\n pendingFormatterValue.value = mainCell.value.formatter || ''\n formatterEditorVisible.value = true\n}\n\nfunction onFormatterEditorConfirm(val: string) {\n write(c => { c.formatter = val || undefined })\n}\n\nfunction write(fn: (c: TableCell) => void) {\n const s = props.selection\n for (let r = s.r1; r <= s.r2; r++) {\n for (let c = s.c1; c <= s.c2; c++) {\n const cell = rows.value[r]!.cells[c]!\n if (!cell.merged) fn(cell)\n }\n }\n ctx.recordHistory()\n}\n\nconst borderStyle = ref<TableCellBorder['style']>('solid')\nconst borderWidth = ref(0.75)\nconst borderColor = ref('#333333')\nconst edgeChecks = ref<string[]>([])\n\nfunction currentBorder(): TableCellBorder {\n return { width: borderWidth.value, style: borderStyle.value, color: borderColor.value }\n}\n\nfunction preset(p: BorderPreset) {\n applyBorderPreset(rows.value, props.selection, p, currentBorder())\n ctx.recordHistory()\n}\n\nfunction onEdgesChange(event: Event) {\n const input = event.target as HTMLInputElement\n const edges = new Set(edgeChecks.value)\n if (input.checked) edges.add(input.value)\n else edges.delete(input.value)\n edgeChecks.value = [...edges]\n const b = currentBorder()\n write(c => {\n const nb = { ...(c.borders ?? {}) } as Record<string, TableCellBorder | undefined>\n for (const side of ['top', 'right', 'bottom', 'left']) {\n if (edges.has(side)) nb[side] = { ...b }\n else delete nb[side]\n }\n c.borders = nb as TableCellBorders\n })\n}\n\nconst mergeReason = computed(() => canMergeReason(rows.value, props.selection))\n\nconst canSplit = computed(() => {\n const s = props.selection\n for (let r = s.r1; r <= s.r2; r++) {\n for (let c = s.c1; c <= s.c2; c++) {\n const cell = rows.value[r]!.cells[c]!\n if (!cell.merged && ((cell.rowspan ?? 1) > 1 || (cell.colspan ?? 1) > 1)) return true\n }\n }\n return false\n})\n\nfunction doMerge() {\n mergeCells(rows.value, props.selection)\n ctx.recordHistory()\n}\n\nfunction doSplit() {\n splitCells(rows.value, props.selection)\n ctx.recordHistory()\n}\n\ndefineExpose({ openFormatterEditor })\n</script>\n\n<style scoped>\n.cell-style-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 0 8px;\n}\n.border-style-row {\n display: flex;\n gap: 6px;\n margin-bottom: 8px;\n}\n.border-presets {\n margin-bottom: 8px;\n}\n.merge-btns {\n margin-top: 8px;\n display: flex;\n gap: 8px;\n}\n.field-row {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n}\n</style>\n","import type { BindingDescriptor } from '../types'\n\n/**\n * 元素绑定声明注册表\n * 每个元素类型声明其支持的 formatter 绑定位置\n */\nexport const ELEMENT_BINDING_REGISTRY: Record<string, BindingDescriptor[]> = {\n text: [\n { targetPath: 'options.formatter', label: '内容', dataSource: 'main' },\n ],\n longText: [\n { targetPath: 'options.formatter', label: '内容', dataSource: 'main' },\n { targetPath: 'options.styler', label: '样式', dataSource: 'main' },\n ],\n barcode: [\n { targetPath: 'options.formatter', label: '内容', dataSource: 'main' },\n ],\n qrcode: [\n { targetPath: 'options.formatter', label: '内容', dataSource: 'main' },\n ],\n image: [\n { targetPath: 'options.src', label: '内容', dataSource: 'main', placeholder: '输入图片路径,支持 /docfiles/... 相对路径、绝对 URL 或 {字段} 表达式' },\n ],\n table: [],\n}\n\nexport function getTableCellBindings(\n rowType: string,\n rowIndex: number,\n cellIndex: number,\n listField?: string,\n): BindingDescriptor[] {\n if (rowType === 'data') {\n return [{\n targetPath: `options.tableRows[${rowIndex}].cells[${cellIndex}].formatter`,\n label: '内容',\n dataSource: 'list',\n listField,\n placeholder: '{name}',\n }]\n }\n if (rowType === 'subtotal') {\n return [{\n targetPath: `options.tableRows[${rowIndex}].cells[${cellIndex}].formatter`,\n label: '内容',\n dataSource: 'subtotal',\n placeholder: '{MONEY(SUM(amount))}',\n }]\n }\n if (rowType === 'summary') {\n return [{\n targetPath: `options.tableRows[${rowIndex}].cells[${cellIndex}].formatter`,\n label: '内容',\n dataSource: 'summary',\n placeholder: '{MONEY(SUM(amount))}',\n }]\n }\n return [{\n targetPath: `options.tableRows[${rowIndex}].cells[${cellIndex}].formatter`,\n label: '内容',\n dataSource: 'main',\n placeholder: '合计: {order.total}',\n }]\n}\n\nexport function getElementBindings(element: any): BindingDescriptor[] {\n const type = element.printElementType.type\n const staticBindings = ELEMENT_BINDING_REGISTRY[type] ?? []\n const dynamicBindings: BindingDescriptor[] = []\n\n if (type === 'table') {\n const listField = element.options.dataSource\n for (const [ri, row] of (element.options.tableRows ?? []).entries()) {\n for (const [ci, cell] of row.cells.entries()) {\n if (cell.merged) continue\n dynamicBindings.push(...getTableCellBindings(row.type, ri, ci, listField))\n }\n }\n }\n\n return [...staticBindings, ...dynamicBindings]\n}\n","<template>\n <div class=\"property-panel\" :class=\"{ collapsed }\">\n <!-- 折叠态:竖排图标,点击即展开对应页签 -->\n <div v-if=\"collapsed\" class=\"prop-collapsed\">\n <button class=\"pc-btn\" title=\"展开属性台\" @click=\"expandTab(currentTab)\">«</button>\n <button class=\"pc-btn\" :class=\"{ on: currentTab === 'element' }\" title=\"元素属性\" @click=\"expandTab('element')\">▦</button>\n <button class=\"pc-btn\" :class=\"{ on: currentTab === 'page' }\" title=\"页面属性\" @click=\"expandTab('page')\">▤</button>\n </div>\n <template v-else>\n <div class=\"prop-head\">\n <span class=\"prop-title\">属性台</span>\n <button class=\"collapse-btn\" title=\"收起属性台\" @click=\"$emit('toggle-collapse')\">»</button>\n </div>\n <div class=\"pd-tabs prop-tabs\">\n <div class=\"pd-tab-bar\" role=\"tablist\">\n <button type=\"button\" class=\"pd-tab\" :class=\"{ active: (activeTab || 'page') === 'element' }\" @click=\"$emit('update:activeTab', 'element')\">元素属性</button>\n <button type=\"button\" class=\"pd-tab\" :class=\"{ active: (activeTab || 'page') === 'page' }\" @click=\"$emit('update:activeTab', 'page')\">页面属性</button>\n </div>\n <div v-show=\"(activeTab || 'page') === 'element'\" class=\"pd-tab-pane\" role=\"tabpanel\">\n <template v-if=\"element\">\n <PropertySearch @search=\"onSearch\" />\n <div class=\"property-content\">\n <PositionSizeGroup v-if=\"filteredGroups.includes('position-size') && !isTableCellSelected\" :element=\"element\" :matched-keys=\"matchedKeys\" :searching=\"searching\" />\n <AppearanceGroup v-if=\"filteredGroups.includes('appearance')\" :element=\"element\" :is-text-type=\"isTextType\" :matched-keys=\"matchedKeys\" :searching=\"searching\" />\n <PropertyGroup v-if=\"filteredGroups.includes('binding')\" title=\"内容\" icon=\"Document\" default-expanded group-key=\"binding\">\n <BindingControl\n v-for=\"desc in bindingDescriptors\"\n :key=\"desc.targetPath\"\n :descriptor=\"desc\"\n :fields=\"fields\"\n :model-value=\"getBindingValue(desc.targetPath)\"\n @update:model-value=\"(v: string) => setBindingValue(desc.targetPath, v)\"\n />\n <ImageContentUpload\n v-if=\"isImageType\"\n @success=\"onImageUploadSuccess\"\n />\n </PropertyGroup>\n <!-- 表格行/单元格属性(需有选区) -->\n <template v-if=\"isTableType && tableSelection && tableSelection.elementId === element!.id\">\n <TableRowGroup :element=\"element!\" :selection=\"tableSelection\" />\n <TableCellGroup :element=\"element!\" :selection=\"tableSelection\" :fields=\"fields\" />\n </template>\n <!-- 表格设置(表格元素时显示) -->\n <TableSettingsGroup\n v-if=\"isTableType && filteredGroups.includes('content')\"\n :element=\"element!\"\n :fields=\"fields\"\n />\n <BorderBgGroup v-if=\"filteredGroups.includes('border-bg')\" :element=\"element\" :matched-keys=\"matchedKeys\" :searching=\"searching\" />\n <!-- 分页配置(表格元素) -->\n <PaginationGroup\n v-if=\"filteredGroups.includes('pagination') && isTableType\"\n :element=\"element\"\n :matched-keys=\"matchedKeys\"\n :searching=\"searching\"\n />\n <!-- 分页配置(非表格元素) -->\n <PaginationGroup\n v-if=\"filteredGroups.includes('pagination') && !isTableType\"\n :element=\"element\"\n :matched-keys=\"matchedKeys\"\n :searching=\"searching\"\n />\n <AdvancedGroup v-if=\"filteredGroups.includes('advanced')\" :element=\"element\" :matched-keys=\"matchedKeys\" :searching=\"searching\" @delete-element=\"$emit('delete-element')\" />\n </div>\n </template>\n <p class=\"pd-empty\" v-else>请在画布中选择一个元素</p>\n </div>\n\n <div v-show=\"(activeTab || 'page') === 'page'\" class=\"pd-tab-pane\" role=\"tabpanel\">\n <form class=\"pd-form\" @submit.prevent>\n <h3 class=\"pd-divider\">纸张设置</h3>\n\n <div class=\"pd-field\"><span class=\"pd-label\">纸张尺寸</span>\n <select :value=\"paperSizeModel\" class=\"pd-select\" @change=\"onPaperSizeChange(($event.target as HTMLSelectElement).value)\" style=\"width: 100%\">\n <option v-for=\"(_ps, key) in paperPresets\" :key=\"key\" :value=\"key\">{{ key }}</option>\n <option value=\"CUSTOM\">自定义</option>\n </select>\n </div>\n <div class=\"pd-field\" v-if=\"paperSizeModel === 'CUSTOM'\"><span class=\"pd-label\">自定义宽高 (mm)</span>\n <div class=\"custom-size-grid\">\n <input :value=\"customWidth\" type=\"number\" class=\"pd-input\"\n @input=\"onCustomWidthChange(($event.target as HTMLInputElement).valueAsNumber)\"\n :min=\"25\"\n :max=\"2000\"\n :step=\"1\"\n style=\"width: 100%\" />\n <span class=\"custom-size-x\">×</span>\n <input :value=\"customHeight\" type=\"number\" class=\"pd-input\"\n @input=\"onCustomHeightChange(($event.target as HTMLInputElement).valueAsNumber)\"\n :min=\"25\"\n :max=\"2000\"\n :step=\"1\"\n style=\"width: 100%\" />\n </div>\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">方向</span>\n <div class=\"pd-radio-group\" role=\"radiogroup\">\n <label class=\"pd-radio\"><input type=\"radio\" value=\"portrait\" :checked=\"orientationModel === 'portrait'\" @change=\"onOrientationChange(($event.target as HTMLInputElement).value)\"><span>纵向</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" value=\"landscape\" :checked=\"orientationModel === 'landscape'\" @change=\"onOrientationChange(($event.target as HTMLInputElement).value)\"><span>横向</span></label>\n </div>\n </div>\n\n <h3 class=\"pd-divider\">页边距 (mm)</h3>\n <div class=\"margin-grid\">\n <div class=\"pd-field\"><span class=\"pd-label\">上</span>\n <input :value=\"marginTop\" type=\"number\" class=\"pd-input\" @input=\"onMarginTopChange(($event.target as HTMLInputElement).valueAsNumber)\" :min=\"0\" :max=\"50\" :step=\"1\" style=\"width: 100%\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">下</span>\n <input :value=\"marginBottom\" type=\"number\" class=\"pd-input\" @input=\"onMarginBottomChange(($event.target as HTMLInputElement).valueAsNumber)\" :min=\"0\" :max=\"50\" :step=\"1\" style=\"width: 100%\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">左</span>\n <input :value=\"marginLeft\" type=\"number\" class=\"pd-input\" @input=\"onMarginLeftChange(($event.target as HTMLInputElement).valueAsNumber)\" :min=\"0\" :max=\"50\" :step=\"1\" style=\"width: 100%\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">右</span>\n <input :value=\"marginRight\" type=\"number\" class=\"pd-input\" @input=\"onMarginRightChange(($event.target as HTMLInputElement).valueAsNumber)\" :min=\"0\" :max=\"50\" :step=\"1\" style=\"width: 100%\" />\n </div>\n </div>\n\n <h3 class=\"pd-divider\">三区高度 (mm)</h3>\n <div class=\"pd-field\"><span class=\"pd-label\">页眉高度</span>\n <input :value=\"headerHeight\" type=\"number\" class=\"pd-input\" @input=\"onHeaderHeightChange(($event.target as HTMLInputElement).valueAsNumber)\" :min=\"0\" :max=\"100\" :step=\"0.1\" style=\"width: 100%\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">页脚高度</span>\n <input :value=\"footerHeight\" type=\"number\" class=\"pd-input\" @input=\"onFooterHeightChange(($event.target as HTMLInputElement).valueAsNumber)\" :min=\"0\" :max=\"100\" :step=\"0.1\" style=\"width: 100%\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">首页叠加高度</span>\n <input :value=\"overlayHeight\" type=\"number\" class=\"pd-input\" @input=\"onOverlayHeightChange(($event.target as HTMLInputElement).valueAsNumber)\" :min=\"0\" :max=\"200\" style=\"width: 100%\" />\n </div>\n </form>\n </div>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport type { RuntimeElement, PrintBusinessField, TemplateData, TableSelection } from '../types'\nimport { PAPER_PRESETS } from '../utils/default-config'\nimport { searchProperties } from '../utils/property-search'\nimport PropertySearch from './property/PropertySearch.vue'\nimport PositionSizeGroup from './property/PositionSizeGroup.vue'\nimport AppearanceGroup from './property/AppearanceGroup.vue'\nimport PropertyGroup from './property/PropertyGroup.vue'\nimport BindingControl from './property/BindingControl.vue'\nimport TableSettingsGroup from './property/TableSettingsGroup.vue'\nimport BorderBgGroup from './property/BorderBgGroup.vue'\nimport AdvancedGroup from './property/AdvancedGroup.vue'\nimport PaginationGroup from './property/PaginationGroup.vue'\nimport ImageContentUpload from './property/ImageContentUpload.vue'\nimport TableRowGroup from './property/TableRowGroup.vue'\nimport TableCellGroup from './property/TableCellGroup.vue'\nimport { getElementBindings, getTableCellBindings } from '../utils/binding-registry'\nimport type { BindingDescriptor } from '../types'\n\nconst props = defineProps<{\n element: RuntimeElement | null\n templateData?: TemplateData\n fields: PrintBusinessField[]\n activeTab?: 'element' | 'page'\n tableSelection?: TableSelection | null\n recordHistory?: () => void\n collapsed: boolean\n}>()\n\nconst emit = defineEmits<{\n 'delete-element': []\n 'update:templateData': [data: TemplateData]\n 'update:activeTab': [tab: 'element' | 'page']\n 'toggle-collapse': []\n}>()\n\nconst paperPresets = PAPER_PRESETS\nconst searchText = ref('')\n\nconst isTextType = computed(() => {\n if (!props.element) return false\n return ['text', 'longText'].includes(props.element.printElementType.type)\n})\n\nconst isImageType = computed(() => {\n if (!props.element) return false\n return props.element.printElementType.type === 'image'\n})\n\n/** 是否处于表格单元格选中态:单元格的位置与宽高由行高/列宽控制,隐藏「位置与尺寸」组 */\nconst isTableCellSelected = computed(() => {\n if (!props.element) return false\n if (props.element.printElementType.type !== 'table') return false\n return !!props.tableSelection && props.tableSelection.elementId === props.element.id\n})\n\nconst isTableType = computed(() => {\n if (!props.element) return false\n return props.element.printElementType.type === 'table'\n})\n\nconst searchResult = computed(() => searchProperties(searchText.value))\nconst filteredGroups = computed(() => searchResult.value.groups)\nconst matchedKeys = computed(() => searchResult.value.itemKeys)\nconst searching = computed(() => !!searchText.value.trim())\n\nconst bindingDescriptors = computed<BindingDescriptor[]>(() => {\n if (!props.element) return []\n\n // 当有表格选区时,只返回选中单元格的绑定描述符\n if (props.element.printElementType.type === 'table' && props.tableSelection) {\n const { r1, c1 } = props.tableSelection\n const rows = props.element.options.tableRows\n if (rows && rows[r1]) {\n const row = rows[r1]\n const listField = props.element.options.fields?.[0]?.dataSource\n return getTableCellBindings(row.type, r1, c1, listField)\n }\n }\n\n return getElementBindings(props.element)\n})\n\n/**\n * 统一解析带点分段与数组下标的 targetPath 为段/索引混排数组\n * 例:'options.formatter' → ['options','formatter']\n * 例:'options.tableRows[0].cells[1].formatter' → ['options','tableRows',0,'cells',1,'formatter']\n */\nfunction parsePath(targetPath: string): (string | number)[] {\n return targetPath.split('.').flatMap(segment => {\n const match = segment.match(/^([^\\[]+)((?:\\[\\d+\\])*)$/)\n if (!match) return [segment]\n const baseName = match[1]!\n const indices = [...match[2]!.matchAll(/\\[(\\d+)\\]/g)].map(m => Number(m[1]!))\n return [baseName, ...indices]\n })\n}\n\nfunction getBindingValue(targetPath: string): string {\n if (!props.element) return ''\n const segments = parsePath(targetPath)\n const result = segments.reduce((current, seg) => {\n if (current === null || current === undefined) return ''\n return current[seg as keyof typeof current]\n }, props.element as any)\n return result ?? ''\n}\n\nfunction setBindingValue(targetPath: string, value: string) {\n if (!props.element) return\n const segments = parsePath(targetPath)\n const lastKey = segments.pop()!\n const obj = segments.reduce((current, seg) => {\n if (current[seg] === undefined || current[seg] === null) current[seg] = {}\n return current[seg]\n }, props.element as any)\n obj[lastKey] = value || undefined\n props.recordHistory?.()\n}\n\nfunction onSearch(text: string) {\n searchText.value = text\n}\n\n/** 图片上传成功:将相对路径写入 options.src(内容输入框绑定路径) */\nfunction onImageUploadSuccess(url: string) {\n if (!props.element) return\n setBindingValue('options.src', url)\n}\n\n// ─── 页面属性模型(直接读写 templateData) ───\n\nconst paperSizeModel = computed(() => props.templateData?.paperSize || 'A4')\nconst orientationModel = computed(() => props.templateData?.orientation || 'portrait')\n\nconst marginTop = computed(() => props.templateData?.margins.top ?? 10)\nconst marginBottom = computed(() => props.templateData?.margins.bottom ?? 10)\nconst marginLeft = computed(() => props.templateData?.margins.left ?? 10)\nconst marginRight = computed(() => props.templateData?.margins.right ?? 10)\n\nconst headerHeight = computed(() => props.templateData?.header.height ?? 10)\nconst footerHeight = computed(() => props.templateData?.footer.height ?? 10)\nconst overlayHeight = computed(() => props.templateData?.firstPageOverlay.height ?? 0)\n\nconst customWidth = computed(() => props.templateData?.customWidth ?? 210)\nconst customHeight = computed(() => props.templateData?.customHeight ?? 297)\n\nfunction emitUpdate(partial: Partial<TemplateData>) {\n if (!props.templateData) return\n emit('update:templateData', { ...props.templateData, ...partial })\n}\n\nfunction onPaperSizeChange(size: string) {\n if (size === 'CUSTOM') {\n emitUpdate({ paperSize: 'CUSTOM' })\n return\n }\n if (!paperPresets[size]) return\n emitUpdate({ paperSize: size as TemplateData['paperSize'] })\n}\n\nfunction onOrientationChange(val: string | number | boolean | undefined) {\n emitUpdate({ orientation: String(val) as TemplateData['orientation'] })\n}\n\nfunction onCustomWidthChange(v: number | undefined) {\n if (v === undefined) return\n emitUpdate({ customWidth: v })\n}\n\nfunction onCustomHeightChange(v: number | undefined) {\n if (v === undefined) return\n emitUpdate({ customHeight: v })\n}\n\nfunction onMarginTopChange(v: number | undefined) {\n if (v === undefined) return\n emitUpdate({ margins: { ...props.templateData!.margins, top: v } })\n}\nfunction onMarginBottomChange(v: number | undefined) {\n if (v === undefined) return\n emitUpdate({ margins: { ...props.templateData!.margins, bottom: v } })\n}\nfunction onMarginLeftChange(v: number | undefined) {\n if (v === undefined) return\n emitUpdate({ margins: { ...props.templateData!.margins, left: v } })\n}\nfunction onMarginRightChange(v: number | undefined) {\n if (v === undefined) return\n emitUpdate({ margins: { ...props.templateData!.margins, right: v } })\n}\n\nfunction onHeaderHeightChange(v: number | undefined) {\n if (v === undefined) return\n emitUpdate({ header: { ...props.templateData!.header, height: v } })\n}\n\nfunction onFooterHeightChange(v: number | undefined) {\n if (v === undefined) return\n emitUpdate({ footer: { ...props.templateData!.footer, height: v } })\n}\n\nfunction onOverlayHeightChange(v: number | undefined) {\n if (v === undefined) return\n emitUpdate({\n firstPageOverlay: { ...props.templateData!.firstPageOverlay, height: v },\n })\n}\n\nconst currentTab = computed(() => props.activeTab || 'page')\n\nfunction expandTab(tab: 'element' | 'page') {\n emit('update:activeTab', tab)\n emit('toggle-collapse')\n}\n</script>\n\n<style scoped>\n.property-panel {\n width: 280px;\n min-width: 280px;\n background: var(--pd-sidebar, #ffffff);\n border-left: 1px solid var(--pd-border-soft, #e9ecf2);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n transition: width .18s ease;\n}\n.property-panel.collapsed {\n width: 36px;\n min-width: 36px;\n border-left: 1px solid var(--pd-border-soft, #e9ecf2);\n}\n.prop-collapsed {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding-top: 12px;\n flex: 1;\n}\n.pc-btn {\n width: 26px;\n height: 26px;\n border-radius: 6px;\n border: 1px solid transparent;\n background: transparent;\n color: var(--pd-text-muted, #8b909c);\n font-size: 12px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all .14s ease;\n}\n.pc-btn:hover {\n color: var(--pd-text, #2a2e37);\n background: var(--pd-sidebar-hover, #f0f3f9);\n}\n.pc-btn.on {\n color: var(--pd-accent, #165DFF);\n background: var(--pd-accent-soft, rgba(22, 93, 255, .09));\n}\n.prop-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n height: 42px;\n padding: 0 12px;\n flex-shrink: 0;\n border-bottom: 1px solid var(--pd-border-soft, #e9ecf2);\n}\n.prop-title {\n font-size: 12px;\n font-weight: 600;\n color: var(--pd-text, #2a2e37);\n letter-spacing: 1.2px;\n display: inline-flex;\n align-items: center;\n gap: 7px;\n}\n.prop-title::before {\n content: \"\";\n width: 3px;\n height: 12px;\n border-radius: 2px;\n background: linear-gradient(180deg, var(--pd-accent-2, #3D7BFF), var(--pd-accent, #165DFF));\n}\n.collapse-btn {\n border: none;\n background: transparent;\n color: var(--pd-text-muted, #8b909c);\n font-size: 14px;\n cursor: pointer;\n width: 24px;\n height: 24px;\n border-radius: 5px;\n transition: all .14s ease;\n}\n.collapse-btn:hover {\n color: var(--pd-text, #2a2e37);\n background: var(--pd-sidebar-hover, #f0f3f9);\n}\n.prop-tabs {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.prop-tabs .pd-tab-pane {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 12px;\n}\n.property-content {\n padding: 0;\n}\n.margin-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 0 12px;\n}\n.custom-size-grid {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n align-items: center;\n gap: 4px;\n width: 100%;\n}\n.custom-size-x {\n color: var(--pd-text-muted, #8b909c);\n font-size: 12px;\n}\n</style>\n","<template>\n <div class=\"status-bar\">\n <span class=\"status-item coord\" v-if=\"coordinate\">\n x:{{ coordinate.x.toFixed(1) }}&nbsp;y:{{ coordinate.y.toFixed(1) }}mm\n </span>\n <span class=\"status-item\">缩放 {{ scale }}%</span>\n <span class=\"status-item\">元素 {{ elementCount }}{{ selectedCount ? ` (选中 ${selectedCount})` : '' }}</span>\n <span class=\"status-dirty\" :class=\"{ on: dirty }\">\n <span class=\"dirty-dot\" />{{ dirty ? '未保存' : '已保存' }}\n </span>\n <span class=\"status-item status-paper\">{{ paper }}</span>\n </div>\n</template>\n\n<script setup lang=\"ts\">\ndefineProps<{\n coordinate: { x: number; y: number } | null\n scale: number\n elementCount: number\n selectedCount: number\n paper: string\n dirty: boolean\n}>()\n</script>\n\n<style scoped>\n.status-bar {\n display: flex;\n align-items: center;\n gap: 20px;\n height: 30px;\n padding: 0 16px;\n background: var(--pd-surface, #ffffff);\n border-top: 1px solid var(--pd-border-soft, #e9ecf2);\n box-shadow: 0 -1px 2px rgba(23, 32, 60, .03);\n font-size: 11.5px;\n color: var(--pd-text-muted, #8b909c);\n user-select: none;\n flex-shrink: 0;\n}\n.status-item {\n white-space: nowrap;\n font-variant-numeric: tabular-nums;\n display: inline-flex;\n align-items: center;\n}\n.coord {\n font-variant-numeric: tabular-nums;\n color: var(--pd-text, #2a2e37);\n}\n.status-paper {\n margin-left: auto;\n font-variant-numeric: tabular-nums;\n color: var(--pd-accent, #165DFF);\n font-weight: 600;\n}\n.status-dirty {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n white-space: nowrap;\n color: var(--pd-text-muted, #8b909c);\n}\n.status-dirty.on {\n color: var(--pd-accent-secondary, #f56c6c);\n}\n.dirty-dot {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--pd-ink-green, #67c23a);\n}\n.status-dirty.on .dirty-dot {\n background: var(--pd-accent-secondary, #f56c6c);\n box-shadow: 0 0 0 3px rgba(245, 108, 108, .14);\n animation: dirty-pulse 1.6s ease-in-out infinite;\n}\n@keyframes dirty-pulse {\n 0%, 100% { box-shadow: 0 0 0 2px rgba(245, 108, 108, .12); }\n 50% { box-shadow: 0 0 0 4px rgba(245, 108, 108, .05); }\n}\n@media (prefers-reduced-motion: reduce) {\n .status-dirty.on .dirty-dot { animation: none; }\n}\n</style>\n","import { ref, watch } from 'vue'\n\nconst LEFT_KEY = 'print-studio:left'\nconst RIGHT_KEY = 'print-studio:right'\n\nfunction readStored(key: string, fallback: boolean): boolean {\n try {\n const raw = localStorage.getItem(key)\n return raw === null ? fallback : raw === '1'\n } catch {\n return fallback\n }\n}\n\nexport function useStudioChrome() {\n const leftCollapsed = ref(readStored(LEFT_KEY, false))\n const rightCollapsed = ref(readStored(RIGHT_KEY, false))\n const dirty = ref(false)\n\n watch(leftCollapsed, v => { try { localStorage.setItem(LEFT_KEY, v ? '1' : '0') } catch { /* ignore */ } }, { flush: 'sync' })\n watch(rightCollapsed, v => { try { localStorage.setItem(RIGHT_KEY, v ? '1' : '0') } catch { /* ignore */ } }, { flush: 'sync' })\n\n function toggleLeft() { leftCollapsed.value = !leftCollapsed.value }\n function toggleRight() { rightCollapsed.value = !rightCollapsed.value }\n function markSaved() { dirty.value = false }\n\n return { leftCollapsed, rightCollapsed, toggleLeft, toggleRight, dirty, markSaved }\n}\n","<template>\n <div class=\"designer-container\">\n <DesignerToolbar\n :is-edit=\"isEdit\"\n :can-undo=\"canUndo\"\n :can-redo=\"canRedo\"\n :has-multi-selection=\"selectedIds.size >= 2\"\n :has-selection=\"selectedIds.size >= 1\"\n :show-grid=\"showGrid\"\n :snap-to-grid=\"snapToGrid\"\n :show-table-ghost-border=\"showTableGhostBorder\"\n :selected-element-has-group=\"selectedElement?.options.groupId ? true : false\"\n :overlay-visible=\"overlayVisible\"\n :show-load-default=\"!!loadDefaultTemplate\"\n v-model:scale=\"scale\"\n @back=\"$emit('back')\"\n @preview=\"$emit('preview')\"\n @save=\"handleSave\"\n @load-default=\"handleLoadDefault\"\n @undo=\"onUndo\"\n @redo=\"onRedo\"\n @align=\"(mode: string) => onAlign(mode as AlignMode)\"\n @move-layer=\"onMoveLayer\"\n @toggle-grid=\"showGrid = !showGrid\"\n @toggle-snap=\"snapToGrid = !snapToGrid\"\n @toggle-table-ghost-border=\"showTableGhostBorder = !showTableGhostBorder\"\n @toggle-overlay=\"toggleOverlay\"\n @group=\"onGroup\"\n @ungroup=\"onUngroup\"\n @add-overlay-element=\"onAddOverlayElement\"\n @fit-window=\"onFitWindow\"\n @zoom=\"onZoom\"\n />\n\n <!-- 三栏布局 -->\n <div class=\"designer-body\">\n <LeftPanel\n :fields=\"fields\"\n :elements=\"elements\"\n :selected-ids=\"selectedIds\"\n :collapsed=\"leftCollapsed\"\n @select=\"onSelectElement\"\n @move-layer=\"onMoveLayer\"\n @toggle-visible=\"onToggleVisible\"\n @toggle-locked=\"onToggleLocked\"\n @toggle-collapse=\"toggleLeft\"\n />\n <CanvasArea\n ref=\"canvasAreaRef\"\n :template-data=\"templateData\"\n :elements=\"elements\"\n :scale=\"scale / 100\"\n :show-grid=\"showGrid\"\n :snap-to-grid=\"snapToGrid\"\n :show-table-ghost-border=\"showTableGhostBorder\"\n :has-clipboard=\"hasClipboard\"\n :guides=\"guides\"\n :overlay-visible=\"overlayVisible\"\n :screenshot-url=\"screenshotUrl\"\n :overlay-opacity=\"overlayOpacity\"\n :selected-element-has-group=\"selectedElement?.options.groupId ? true : false\"\n @select=\"onSelectElement\"\n @drop-element=\"onDropElement\"\n @drop-field=\"onDropField\"\n @drag-start=\"onDragStart\"\n @drag-stop=\"onDragStop\"\n @dblclick-element=\"onDblClickElement\"\n @dblclick-cell=\"onDblClickCell\"\n @zone-height-change=\"onZoneHeightChange\"\n @zone-height-commit=\"onZoneHeightCommit\"\n @select-all=\"selectAll\"\n @clear-selection=\"clearSelection\"\n @preview=\"setPreview\"\n @commit-preview=\"commitPreview\"\n @paste=\"paste\"\n @copy=\"copy\"\n @cut=\"cutSelected\"\n @delete=\"onDeleteElement\"\n @move-layer=\"onMoveLayer\"\n @coordinate=\"onCoordinate\"\n @group=\"onGroup\"\n @ungroup=\"onUngroup\"\n @add-guide=\"addGuide\"\n @guide-move=\"moveGuide\"\n @guide-remove=\"removeGuide\"\n @zoom=\"onZoom\"\n @clone-element=\"onCloneElement\"\n />\n <PropertyPanel\n :element=\"selectedElement\"\n :template-data=\"templateData\"\n :fields=\"fields\"\n :table-selection=\"tableSelection\"\n :record-history=\"recordHistory\"\n :collapsed=\"rightCollapsed\"\n v-model:active-tab=\"activePropertyTab\"\n @delete-element=\"onDeleteElement\"\n @update:template-data=\"onTemplateDataChanged\"\n @toggle-collapse=\"toggleRight\"\n />\n </div>\n <StatusBar\n :coordinate=\"coordinate\"\n :scale=\"scale\"\n :element-count=\"elements.length\"\n :selected-count=\"selectedIds.size\"\n :paper=\"paperLabel\"\n :dirty=\"dirty\"\n />\n\n <!-- 设计稿双击元素/单元格打开的表达式编辑器 -->\n <ExpressionEditor\n v-model=\"dblEditorVisible\"\n :fields=\"fields\"\n :expression=\"dblEditorExpression\"\n @update:expression=\"onDblEditorConfirm\"\n />\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport '../styles/native-controls.css'\nimport { ref, watch, provide, computed, onMounted, onUnmounted } from 'vue'\nimport type { RuntimeElement, PrintBusinessField, TemplateData, TableCell, RequestScreenshotFn, UploadImageFn } from '../types'\nimport { useDesignerState } from '../composables/useDesignerState'\nimport { useGuides } from '../composables/useGuides'\nimport { TABLE_EDIT_KEY } from '../composables/useTableSelection'\nimport { SELECTED_IDS_KEY, PREVIEW_IDS_KEY } from '../composables/useSelection'\nimport { getZoneRects } from '../utils/zone-layout'\nimport { getPaperDimensions } from '../utils/default-config'\nimport { DEFAULT_DEMO_DATA } from '../utils/demo-data'\nimport { findMainCell } from '../utils/table-matrix'\nimport { UPLOAD_IMAGE_KEY } from '../composables/useHostAdapter'\nimport type { AlignMode } from '../composables/useAlign'\nimport DesignerToolbar from './DesignerToolbar.vue'\nimport LeftPanel from './LeftPanel.vue'\nimport CanvasArea from './CanvasArea.vue'\nimport PropertyPanel from './PropertyPanel.vue'\nimport StatusBar from './StatusBar.vue'\nimport ExpressionEditor from './ExpressionEditor.vue'\nimport { useStudioChrome } from '../composables/useStudioChrome'\n\nconst props = defineProps<{\n initialTemplate?: TemplateData\n initialElements?: RuntimeElement[]\n fields?: PrintBusinessField[]\n isEdit?: boolean\n /** 截图适配器(叠层对比):未注入时该功能不可用 */\n requestScreenshot?: RequestScreenshotFn\n /** 图片上传适配器:未注入时图片上传不可用 */\n uploadImage?: UploadImageFn\n /** 加载默认布局回调(宿主实现业务逻辑;未注入时工具栏不展示该按钮),返回 null/undefined 视为无默认布局 */\n loadDefaultTemplate?: () => TemplateData | Promise<TemplateData | null | undefined> | null | undefined\n}>()\n\nconst emit = defineEmits<{\n back: []\n preview: []\n save: [json: string]\n}>()\n\n// 装配层状态:面板折叠(localStorage 持久)+ 未保存 dirty\nconst { leftCollapsed, rightCollapsed, toggleLeft, toggleRight, dirty, markSaved } = useStudioChrome()\n\n// 设计器核心状态统一由 useDesignerState 管理\nconst {\n scale, showGrid, snapToGrid, showTableGhostBorder,\n templateData, elements, fields,\n selectedIds, selectedElement, select, clearSelection, selectAll,\n previewIds, setPreview, commitPreview,\n hasClipboard, copy, paste, cutSelected,\n canUndo, canRedo, undo: onUndo, redo: onRedo,\n alignSelected: onAlign,\n groupSelected: onGroup, ungroupSelected: onUngroup, deleteSelected: onDeleteElement,\n dragStart: onDragStart, dragStop: onDragStop,\n addElement: onDropElement, addFieldElement: onDropField,\n moveLayer: onMoveLayer, updateTemplateData, fitToWindow,\n getTemplateJson, loadTemplate,\n tableSelection, setTableSelection, recordHistory,\n} = useDesignerState({\n initialTemplate: props.initialTemplate,\n initialElements: props.initialElements,\n initialFields: props.fields,\n})\n\n// 未保存信号:任何元素/模板数据变化点亮\nwatch([elements, templateData], () => { dirty.value = true }, { deep: true })\n\nconst { guides, addGuide, moveGuide, removeGuide } = useGuides(templateData, recordHistory)\n\n// 表格单元格编辑上下文\nconst maxTableWidth = computed(() => {\n const t = templateData.value\n const { width: paperW } = getPaperDimensions(t)\n return paperW - t.margins.left - t.margins.right\n})\nprovide(TABLE_EDIT_KEY, { tableSelection, setTableSelection, recordHistory, maxTableWidth })\nprovide(SELECTED_IDS_KEY, selectedIds)\nprovide(PREVIEW_IDS_KEY, previewIds)\n\nprovide(UPLOAD_IMAGE_KEY, computed(() => props.uploadImage))\nwatch(selectedElement, el => {\n if (!el || el.printElementType.type !== 'table') setTableSelection(null)\n})\n\nconst canvasAreaRef = ref<InstanceType<typeof CanvasArea> | null>(null)\n\n// 叠层对比模式\nconst overlayVisible = ref(false)\nconst screenshotUrl = ref('')\nconst overlayOpacity = ref(0.5)\n\nasync function toggleOverlay() {\n if (overlayVisible.value) {\n overlayVisible.value = false\n return\n }\n const templateJson = getTemplateJson()\n if (!templateJson) {\n alert('模板数据为空')\n return\n }\n if (!props.requestScreenshot) {\n alert('截图服务未配置')\n return\n }\n try {\n const blob = await props.requestScreenshot({ templateJson, printData: DEFAULT_DEMO_DATA })\n if (screenshotUrl.value) URL.revokeObjectURL(screenshotUrl.value)\n screenshotUrl.value = URL.createObjectURL(blob)\n overlayVisible.value = true\n } catch {\n alert('截图生成失败')\n }\n}\n\n// 状态栏:鼠标坐标(纸面 mm)\nconst coordinate = ref<{ x: number; y: number } | null>(null)\nfunction onCoordinate(pos: { x: number; y: number } | null) { coordinate.value = pos }\n\nconst paperLabel = computed(() => {\n const t = templateData.value\n const dim = getPaperDimensions(t)\n const orient = t.orientation === 'landscape' ? '横向' : '纵向'\n return `${t.paperSize} ${orient} ${Math.round(dim.width)}×${Math.round(dim.height)}mm`\n})\n\nfunction onFitWindow() {\n const el = (canvasAreaRef.value as any)?.$el as HTMLElement | undefined\n if (el) fitToWindow(el.clientWidth, el.clientHeight)\n}\nfunction onZoom(delta: number) {\n scale.value = Math.min(200, Math.max(50, scale.value + delta))\n}\n\n// Ctrl+0 适应窗口:需容器尺寸,由本组件单独监听(useKeyboard 不处理)\nfunction onKeyFitWindow(e: KeyboardEvent) {\n const tag = (e.target as HTMLElement).tagName\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return\n if ((e.ctrlKey || e.metaKey) && e.key === '0') {\n e.preventDefault()\n onFitWindow()\n }\n}\nonMounted(() => document.addEventListener('keydown', onKeyFitWindow))\nonUnmounted(() => document.removeEventListener('keydown', onKeyFitWindow))\n\nfunction onTemplateDataChanged(data: TemplateData) {\n const prevHeader = templateData.value.header.height\n const prevFooter = templateData.value.footer.height\n updateTemplateData(data)\n if (data.header.height < prevHeader) warnZoneOverflow('header')\n if (data.footer.height < prevFooter) warnZoneOverflow('footer')\n}\n\nfunction onZoneHeightChange(zone: 'header' | 'footer', height: number) {\n templateData.value = {\n ...templateData.value,\n [zone]: { ...templateData.value[zone], height },\n }\n}\n\nfunction onZoneHeightCommit(zone: 'header' | 'footer') {\n updateTemplateData({ ...templateData.value })\n warnZoneOverflow(zone)\n}\n\nfunction warnZoneOverflow(zone: 'header' | 'footer') {\n const rect = getZoneRects(templateData.value)[zone]\n const overflow = elements.value.some(e => e.zone === zone\n && (e.options.top + e.options.height > rect.height\n || e.options.left + e.options.width > rect.width))\n if (overflow) {\n alert(`${zone === 'header' ? '页眉' : '页脚'}高度已小于区域内元素,请手动调整元素位置`)\n }\n}\n\nfunction onAddOverlayElement() {\n const overlay = templateData.value.firstPageOverlay\n const newEl = {\n options: { left: 0, top: 0, width: 50, height: 10, title: '首页叠加' },\n printElementType: { type: 'text' as const, title: '首页叠加' },\n }\n templateData.value = {\n ...templateData.value,\n firstPageOverlay: { ...overlay, elements: [...overlay.elements, newEl] },\n }\n}\n\nconst onSelectElement = select\n\nfunction onToggleVisible(id: string) {\n const el = elements.value.find(e => e.id === id)\n if (el) el.options.visible = el.options.visible === false ? true : false\n}\n\nfunction onToggleLocked(id: string) {\n const el = elements.value.find(e => e.id === id)\n if (el) el.options.locked = !el.options.locked\n}\n\nconst activePropertyTab = ref<'element' | 'page'>('page')\nwatch(selectedElement, (el) => {\n activePropertyTab.value = el ? 'element' : 'page'\n})\n\n/** 双击可打开表达式编辑器的元素类型 → 对应表达式字段(无内容表达式的类型不在此列) */\nconst DBL_EDITABLE_FIELD: Record<string, string> = {\n text: 'formatter',\n longText: 'formatter',\n barcode: 'formatter',\n qrcode: 'formatter',\n}\nconst dblEditorVisible = ref(false)\nconst dblEditTarget = ref<\n { kind: 'element'; element: RuntimeElement; field: string } | { kind: 'cell'; cell: TableCell } | null\n>(null)\nconst dblEditorExpression = ref('')\n\nfunction onDblClickElement(id: string) {\n const el = elements.value.find(e => e.id === id)\n if (!el) return\n select(id, false)\n activePropertyTab.value = 'element'\n // 锁定元素不弹编辑器(保持选中,避免绕过锁定护栏)\n if (el.options.locked) return\n const field = DBL_EDITABLE_FIELD[el.printElementType.type]\n if (!field) return\n dblEditTarget.value = { kind: 'element', element: el, field }\n dblEditorExpression.value = (el.options as any)[field] || ''\n dblEditorVisible.value = true\n}\n\nfunction onDblClickCell(elId: string, r: number, c: number) {\n const el = elements.value.find(e => e.id === elId)\n if (!el) return\n select(elId, false)\n activePropertyTab.value = 'element'\n if (el.options.locked) return\n const rows = el.options.tableRows ?? []\n const main = findMainCell(rows, r, c)\n const cell = rows[main.r]?.cells[main.c]\n if (!cell) return\n dblEditTarget.value = { kind: 'cell', cell }\n dblEditorExpression.value = cell.formatter || ''\n dblEditorVisible.value = true\n}\n\nfunction onDblEditorConfirm(value: string) {\n const t = dblEditTarget.value\n if (t?.kind === 'element') {\n ;(t.element.options as any)[t.field] = value || undefined\n } else if (t?.kind === 'cell') {\n t.cell.formatter = value || undefined\n }\n recordHistory()\n dblEditorVisible.value = false\n dblEditTarget.value = null\n}\n\n/** Alt+拖拽克隆元素:将克隆元素添加到元素池并选中 */\nfunction onCloneElement(el: RuntimeElement, _pos: { left: number; top: number }) {\n elements.value.push(el)\n select(el.id, false)\n recordHistory()\n}\n\nwatch(() => props.initialTemplate, (t) => {\n if (t) loadTemplate(t, props.initialElements)\n})\nwatch(() => props.initialElements, (els) => {\n if (els && !props.initialTemplate) {\n templateData.value = {\n ...templateData.value,\n elements: els.map(e => ({ ...e, options: { ...e.options }, printElementType: { ...e.printElementType } })),\n }\n }\n})\nwatch(() => props.fields, (f) => { fields.value = f || [] })\n\ndefineExpose({ getTemplateJson })\n\nasync function handleLoadDefault() {\n if (!props.loadDefaultTemplate) return\n if (!confirm('将覆盖当前画布内容,是否继续?')) return\n try {\n const tpl = await props.loadDefaultTemplate()\n if (!tpl) {\n alert('未获取到默认布局')\n return\n }\n loadTemplate(tpl)\n alert('默认布局已加载')\n } catch {\n alert('加载默认布局失败')\n }\n}\n\nfunction handleSave() {\n emit('save', JSON.stringify(getTemplateJson()))\n markSaved()\n}\n</script>\n\n<style scoped>\n.designer-container {\n /* ── 精工排版工作台令牌:冷灰底 + 白纸 + 蓝墨点缀 ── */\n --pd-bg: #f3f5f9; /* 应用底色 / 内嵌控件底 */\n --pd-surface: #ffffff; /* 工具栏、状态栏、面板表面 */\n --pd-field-bg: #f4f6fa; /* 卡片、内嵌输入槽 */\n --pd-sidebar: #ffffff;\n --pd-sidebar-hover: #f0f3f9;\n --pd-canvas-bg: #e6e9f0; /* 排版垫:略深,托起纸张 */\n --pd-paper: #FFFFFF;\n --pd-accent: #165DFF;\n --pd-accent-2: #3D7BFF;\n --pd-accent-soft: rgba(22, 93, 255, .09);\n --pd-accent-secondary: #f56c6c;\n --pd-danger-soft: rgba(245, 108, 108, .10);\n --pd-ink-green: #67c23a;\n --pd-text: #2a2e37;\n --pd-text-muted: #8b909c;\n --pd-text-faint: #b4b9c4;\n --pd-border: #d9dde6;\n --pd-border-soft: #e9ecf2;\n --pd-handle: #165DFF;\n --pd-ruler: #9aa1af;\n --pd-ruler-bg: #f8f9fc;\n --pd-ruler-cursor: #165DFF;\n --pd-radius: 6px;\n --pd-shadow-sm: 0 1px 2px rgba(23, 32, 60, .05);\n --pd-shadow-md: 0 2px 8px rgba(23, 32, 60, .06), 0 10px 28px rgba(23, 32, 60, .07);\n --pd-shadow-paper: 0 0 0 1px rgba(23, 32, 60, .05),\n 0 1px 2px rgba(23, 32, 60, .06),\n 0 8px 20px rgba(23, 32, 60, .08),\n 0 26px 60px rgba(23, 32, 60, .15);\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--pd-bg);\n}\n.designer-body {\n flex: 1;\n display: flex;\n overflow: hidden;\n}\n</style>\n","// print-canvas/src/render/browser-pagination.ts\n// 浏览器内两遍渲染:隐藏 iframe 写入测量 HTML → 读取元素实测高度 →\n// 复用 print-core 分页算法 → 生成最终多页 HTML(与 print-render 的 pdf-render 同款逻辑)。\n\nimport {\n bindData,\n generateHtml,\n paginate,\n getPaperDimensions,\n} from '@worm-vue3-print/core'\nimport type {\n PrintTemplateData,\n MeasuredElement,\n PageLayout,\n CodeRenderer,\n} from '@worm-vue3-print/core'\n\n/** 96dpi 下 1mm ≈ 3.78px(与服务端 page.evaluate 一致) */\nconst PX_PER_MM = 3.7795275591\n/** 字体/图片等待兜底超时 */\nconst READY_TIMEOUT_MS = 3000\n\nexport interface BrowserRenderResult {\n /** 最终多页 HTML 字符串 */\n html: string\n /** 总页数 */\n pageCount: number\n /** 分页布局(调试/高级用途) */\n pageLayouts: PageLayout[]\n}\n\n/**\n * 浏览器内完成「数据绑定 → 测量 → 分页 → 最终 HTML」全流程。\n * @param template 模板 JSON(设计器 TemplateData 结构兼容)\n * @param printData 业务数据\n * @param baseUrl 图片相对路径拼接前缀\n * @param codeRenderer 条码渲染器(browserCodeRenderer)\n */\nexport async function renderHtmlPages(\n template: PrintTemplateData,\n printData?: Record<string, any> | Record<string, any>[],\n baseUrl?: string,\n codeRenderer?: CodeRenderer,\n): Promise<BrowserRenderResult> {\n // Step 1: 数据绑定\n const boundTemplate = bindData(template, printData, baseUrl)\n\n // Step 2: 第一遍测量(隐藏 iframe)\n const measuredElements = await measureElements(boundTemplate, codeRenderer)\n\n // Step 3: 分页计算(与服务端同一套算法)\n const pageLayouts = paginate(boundTemplate, measuredElements)\n\n // Step 4: 最终多页 HTML\n const html = generateHtml(boundTemplate, pageLayouts, printData as Record<string, any>, {\n codeRenderer,\n })\n\n return { html, pageCount: pageLayouts.length, pageLayouts }\n}\n\n// ─── 隐藏 iframe 测量 ───\n\n/** 渲染测量模式 HTML 到离屏 iframe,读取每个元素的实际高度(mm) */\nasync function measureElements(\n template: PrintTemplateData,\n codeRenderer?: CodeRenderer,\n): Promise<Map<string, MeasuredElement>> {\n const paper = getPaperDimensions(template)\n const measureHtml = generateHtml(template, [], undefined, {\n isMeasurementPass: true,\n codeRenderer,\n })\n\n const iframe = document.createElement('iframe')\n iframe.setAttribute('aria-hidden', 'true')\n // 禁用 display:none(会导致 offsetHeight=0);移出视口 + 不可见即可\n iframe.style.cssText =\n `position:fixed;left:-10000px;top:0;width:${paper.width}mm;height:${paper.height}mm;` +\n 'border:0;visibility:hidden;pointer-events:none;'\n document.body.appendChild(iframe)\n\n try {\n const win = iframe.contentWindow\n const doc = iframe.contentDocument\n if (!win || !doc) throw new Error('无法创建测量 iframe')\n\n doc.open()\n doc.write(measureHtml)\n doc.close()\n\n await waitForRenderReady(win)\n\n const measurements = readMeasurements(doc)\n\n // 转换为 Map(表格元素补算重复表头段高度),与服务端 pdf-render 一致\n const measuredMap = new Map<string, MeasuredElement>()\n const elementIndex = new Map(template.elements.map(el => [el.id, el]))\n for (const m of measurements) {\n const el = elementIndex.get(m.id)\n const repeatCount: number = el?.options?._repeatHeaderCount ?? 0\n measuredMap.set(m.id, {\n id: m.id,\n measuredHeight: m.height,\n measuredRowHeights: m.rowHeights,\n repeatHeaderHeight: m.rowHeights && repeatCount > 0\n ? m.rowHeights.slice(0, repeatCount).reduce((s: number, h: number) => s + h, 0)\n : 0,\n })\n }\n return measuredMap\n } finally {\n iframe.remove()\n }\n}\n\n/** 等待 iframe 文档加载完成、字体就绪、图片解码完成(带超时兜底) */\nfunction waitForRenderReady(win: Window): Promise<void> {\n return new Promise(resolve => {\n let settled = false\n const finish = () => {\n if (!settled) {\n settled = true\n resolve()\n }\n }\n const timer = setTimeout(finish, READY_TIMEOUT_MS)\n\n const run = async () => {\n try {\n const fonts = (win.document as Document & { fonts?: FontFaceSet }).fonts\n if (fonts?.ready) {\n await Promise.race([fonts.ready, timeout(READY_TIMEOUT_MS)])\n }\n await Promise.race([waitForImages(win.document), timeout(READY_TIMEOUT_MS)])\n } catch {\n // 测量兜底:即使资源加载失败也继续\n } finally {\n clearTimeout(timer)\n finish()\n }\n }\n\n if (win.document.readyState === 'complete') {\n void run()\n } else {\n win.addEventListener('load', () => void run(), { once: true })\n // load 事件意外缺失时兜底\n setTimeout(finish, READY_TIMEOUT_MS)\n }\n })\n}\n\nfunction timeout(ms: number): Promise<never> {\n return new Promise((_resolve, reject) => setTimeout(() => reject(new Error('timeout')), ms))\n}\n\n/** 等待文档内全部图片完成(成功或失败均放行) */\nfunction waitForImages(doc: Document): Promise<void> {\n const imgs = Array.from(doc.images ?? [])\n return Promise.all(\n imgs.map(img =>\n img.complete\n ? Promise.resolve()\n : new Promise<void>(resolve => {\n img.addEventListener('load', () => resolve(), { once: true })\n img.addEventListener('error', () => resolve(), { once: true })\n }),\n ),\n ).then(() => undefined)\n}\n\n/** 读取 [data-measure-id] 元素高度与表格行高(逻辑同服务端 page.evaluate) */\nfunction readMeasurements(doc: Document): Array<{\n id: string\n height: number\n rowHeights?: number[]\n}> {\n const result: Array<{ id: string; height: number; rowHeights?: number[] }> = []\n const elements = doc.querySelectorAll('[data-measure-id]')\n for (const el of elements) {\n const htmlEl = el as HTMLElement\n const id = htmlEl.getAttribute('data-measure-id')\n if (!id) continue\n const heightPx = htmlEl.offsetHeight\n\n const table = htmlEl.querySelector('table.print-table')\n if (table) {\n const rowHeights: number[] = []\n const rows = table.querySelectorAll('tbody > tr[data-row-index]')\n for (const row of rows) {\n rowHeights.push((row as HTMLElement).offsetHeight / PX_PER_MM)\n }\n result.push({ id, height: heightPx / PX_PER_MM, rowHeights })\n } else {\n result.push({ id, height: heightPx / PX_PER_MM })\n }\n }\n return result\n}\n","// print-canvas/src/render/browser-code-renderer.ts\n// 浏览器侧 CodeRenderer:jsbarcode(条形码)+ qrcode(二维码矩阵拼 SVG),纯前端无服务依赖。\n\nimport JsBarcode from 'jsbarcode'\nimport QRCode from 'qrcode'\nimport type { CodeRenderer, CodeRenderOptions } from '@worm-vue3-print/core'\n\nconst SVG_NS = 'http://www.w3.org/2000/svg'\n\n/** 条形码:jsbarcode 渲染到离体 SVG 元素,取 outerHTML */\nfunction renderBarcodeSvg(value: string, opts: CodeRenderOptions): string {\n const svg = document.createElementNS(SVG_NS, 'svg') as SVGSVGElement\n JsBarcode(svg as unknown as SVGElement, value, {\n format: (opts.barcodeType || 'CODE128') as unknown as string,\n width: Math.max(1, (opts.barWidth ?? 2) / 2),\n height: 30,\n displayValue: opts.showText !== false,\n fontSize: opts.fontSize ?? 10,\n margin: 0,\n marginBottom: 2,\n })\n return svg.outerHTML\n}\n\n/** 二维码:QRCode.create 同步取模块矩阵,拼接 SVG(静态白边 4 模块) */\nfunction renderQrSvg(value: string, opts: CodeRenderOptions): string {\n const level = (opts.qrCodeLevel ?? 'M').toUpperCase()\n const qr = QRCode.create(value, {\n errorCorrectionLevel: (['L', 'M', 'Q', 'H'].includes(level) ? level : 'M') as 'L' | 'M' | 'Q' | 'H',\n })\n const modules = qr.modules\n const size = modules.size\n const dot = 4\n const quiet = 4 * dot\n const dim = size * dot + quiet * 2\n let rects = ''\n for (let y = 0; y < size; y++) {\n for (let x = 0; x < size; x++) {\n if (modules.get(x, y)) {\n rects += `<rect x=\"${quiet + x * dot}\" y=\"${quiet + y * dot}\" width=\"${dot}\" height=\"${dot}\" fill=\"#000\"/>`\n }\n }\n }\n return `<svg xmlns=\"${SVG_NS}\" viewBox=\"0 0 ${dim} ${dim}\" width=\"${dim}\" height=\"${dim}\" shape-rendering=\"crispEdges\">${rects}</svg>`\n}\n\n/** 浏览器条码/二维码渲染器;码值非法或为空时抛错,由渲染管线降级文本占位 */\nexport const browserCodeRenderer: CodeRenderer = {\n render(value: string, cellType: 'barcode' | 'qrcode', opts: CodeRenderOptions = {}): string {\n if (!value) throw new Error('empty barcode value')\n return cellType === 'qrcode' ? renderQrSvg(value, opts) : renderBarcodeSvg(value, opts)\n },\n}\n","<!--\n PrintHtmlPreview:浏览器端 HTML 打印预览(不依赖服务端 PDF)。\n 内部完成 数据绑定 → 隐藏 iframe 测量 → 分页 → 多页 HTML 渲染;\n 父组件通过 ref 调用 print() 触发浏览器原生打印(@page 控制纸张与分页)。\n-->\n<template>\n <div class=\"print-html-preview\">\n <div v-if=\"errorMsg\" class=\"print-html-preview-error\">\n <span>预览渲染失败:{{ errorMsg }}</span>\n </div>\n <div v-else-if=\"rendering\" class=\"print-html-preview-loading\">预览渲染中…</div>\n <iframe\n v-show=\"!rendering && !errorMsg\"\n ref=\"iframeRef\"\n class=\"print-html-preview-iframe\"\n title=\"打印预览\"\n />\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch, onBeforeUnmount } from 'vue'\nimport type { PrintTemplateData } from '@worm-vue3-print/core'\nimport { renderHtmlPages } from '../render/browser-pagination'\nimport { browserCodeRenderer } from '../render/browser-code-renderer'\n\nconst props = defineProps<{\n /** 模板 JSON(设计器 TemplateData 结构兼容) */\n templateJson?: Record<string, any> | null\n /** 业务打印数据 */\n printData?: Record<string, any> | Record<string, any>[]\n /** 图片相对路径拼接前缀(与服务端 baseUrl 同源) */\n baseUrl?: string\n}>()\n\nconst emit = defineEmits<{\n /** 渲染完成,回传总页数 */\n rendered: [pageCount: number]\n /** 渲染失败 */\n error: [message: string]\n}>()\n\nconst iframeRef = ref<HTMLIFrameElement>()\nconst rendering = ref(false)\nconst errorMsg = ref('')\n/** 渲染序列:过期的渲染结果丢弃,避免快速重渲染竞态 */\nlet renderSeq = 0\n\nasync function rerender() {\n if (!props.templateJson) {\n errorMsg.value = ''\n rendering.value = false\n return\n }\n const seq = ++renderSeq\n rendering.value = true\n errorMsg.value = ''\n try {\n const { html, pageCount } = await renderHtmlPages(\n props.templateJson as PrintTemplateData,\n props.printData,\n props.baseUrl,\n browserCodeRenderer,\n )\n if (seq !== renderSeq) return\n const doc = iframeRef.value?.contentWindow?.document\n if (doc) {\n doc.open()\n doc.write(html)\n doc.close()\n }\n emit('rendered', pageCount)\n } catch (e) {\n if (seq !== renderSeq) return\n errorMsg.value = e instanceof Error ? e.message : '未知错误'\n emit('error', errorMsg.value)\n } finally {\n if (seq === renderSeq) rendering.value = false\n }\n}\n\n/** 触发浏览器原生打印(iframe 内 @page 规则控制纸张尺寸与分页) */\nfunction print() {\n const win = iframeRef.value?.contentWindow\n if (!win) return\n win.focus()\n win.print()\n}\n\nwatch(\n () => [props.templateJson, props.printData, props.baseUrl],\n () => void rerender(),\n { immediate: true, deep: true },\n)\n\nonBeforeUnmount(() => {\n renderSeq++\n})\n\ndefineExpose({ print, rerender })\n</script>\n\n<style scoped>\n.print-html-preview {\n width: 100%;\n height: 100%;\n position: relative;\n background: #e9ebee;\n}\n.print-html-preview-iframe {\n width: 100%;\n height: 100%;\n border: 0;\n background: #fff;\n}\n.print-html-preview-loading,\n.print-html-preview-error {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #909399;\n font-size: 14px;\n}\n.print-html-preview-error {\n color: #f56c6c;\n}\n</style>\n"],"names":["createCellIdGenerator","seq","createRowIdGenerator","genCellId","genRowId","DEFAULT_BORDER","deepClone","v","createCell","partial","createDefaultTable","colWidths","mk","type","repeat","header","c","findMainCell","rows","r","ri","ci","cell","rs","cs","getSpanRect","main","normalizeSelection","a","b","rect","changed","span","merged","canMergeReason","types","norm","mergeCells","contents","splitCells","styleSrc","sr","sc","t","copyCellStyle","src","dst","insertRow","index","position","insertAt","ref","colCount","newRow","deleteRow","row","next","insertCol","newCell","deleteCol","setRowType","existing","i","dataIdx","applyBorderPreset","preset","border","atTop","atBottom","atLeft","atRight","GHOST_BORDER_CSS","resolveCellBorderCss","opts","syncTableElementSize","options","wMm","s","w","hMm","generateId","createDefaultOptions","base","totalW","totalH","createRuntimeElement","typeMetaMap","engine","TemplateEngine","getDemoData","DEFAULT_DEMO_DATA","EXTENDED_FUNCTIONS","formatMoney","args","ifFn","value","str","start","len","num","decimals","defaultVal","char","from","to","formatDate","toUpperCaseAmount","name","fn","aggregate","field","sum","avg","count","min","max","evaluateTemplate","text","ctx","processedText","_match","inner","expr","_m","arg","createFieldElement","resolveTextBinding","data","lookupDemoPath","path","cur","seg","resolveBarcodeDesignValue","formatter","listSource","first","_","key","ptToMm","pt","pxToMm","px","PT_KEYS","convertElement","el","round2","n","normalizeTemplateUnits","convert","els","PAPER_PRESETS","getPaperDimensions","computeFitScale","containerW","containerH","paperW","paperH","ratio","fit","pct","ZONE_ALLOWED_TYPES","getPaperSizeMM","getZoneRects","paper","m","headerH","footerH","contentW","contentH","l","tp","h","zoneFromPaperPoint","_x","y","clampToZone","zone","o","finalizeElementZone","rects","fromZone","cx","cy","target","rejected","SELECTED_IDS_KEY","PREVIEW_IDS_KEY","useSelection","elements","selectedIds","previewIds","selectedElements","computed","e","hasSelection","select","id","multiple","clearSelection","selectAll","allIds","setPreview","ids","clearPreview","commitPreview","getSelectionBounds","minL","minT","maxR","maxB","useClipboard","clipboard","copy","paste","offset","item","hasData","useAlign","align","mode","bounds","centerX","centerY","sorted","gap","x","generateGroupId","useGroup","group","groupId","ungroup","selected","groupIds","getGroupedIds","selectedId","useHistory","undoStack","redoStack","canUndo","canRedo","updateFlags","clone","state","cloneState","push","undo","currentState","popped","redo","clear","STEP","STEP_LARGE","STEP_SMALL","useKeyboard","handlers","onKeyDown","tag","ctrl","step","dx","dy","k","setup","cleanup","createDefaultTemplate","toRuntimePool","useDesignerState","scale","showGrid","snapToGrid","showTableGhostBorder","templateData","fields","selectAllIds","groupElements","ungroupElements","copyElements","pasteElements","hasClipboardData","pushHistory","undoHistory","redoHistory","selectedElement","tableSelection","setTableSelection","getHistoryState","recordHistory","cutSelected","deleteSelected","pasted","duplicateSelected","resetZoom","hasClipboard","moveSessionActive","moveDebounceTimer","MOVE_SESSION_GAP_MS","moveSelected","movable","alignSelected","groupSelected","ungroupSelected","setupKeyboard","cleanupKeyboard","draggingBeforeState","dragStart","dragStop","before","prev","sig","beforeIds","afterIds","placeAtDropPoint","dropPoint","addElement","addFieldElement","moveLayer","direction","currentZ","allZ","maxZ","minZ","fitToWindow","width","height","MM_TO_PX","updateTemplateData","getTemplateJson","all","ser","loadTemplate","migrated","onMounted","onUnmounted","guideSeq","genId","useGuides","guides","mutate","addGuide","list","moveGuide","g","removeGuide","getGuidePositions","TABLE_EDIT_KEY","UPLOAD_IMAGE_KEY","_useModel","__props","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","$emit","_hoisted_3","_hoisted_4","_toDisplayString","_cache","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_normalizeClass","_hoisted_13","_hoisted_14","_hoisted_15","props","sortedLayers","elementIconMap","layerIcon","layerName","zoneTag","_Fragment","_renderList","layer","$event","groupFields","groupMap","groupOrder","f","dot","groups","standalone","filterGroups","keyword","kw","emit","__emit","searchText","collapsedGroups","searching","filteredGroups","toggleGroup","onDragStart","event","_normalizeStyle","activeTab","elementTypes","onFieldDrag","expandTab","tab","_withDirectives","_createVNode","FieldTreePanel","LayerPanel","d","useDrag","isDragging","dragPreview","startX","startY","startLeft","startTop","downAltKey","onMouseDown","targetEl","onMouseMove","onMouseUp","computePos","newLeft","newTop","result","pos","RESIZE_POINTS","calcResizeRect","point","startRect","minW","minH","left","top","useResize","activePoint","startResize","onResizeMove","onResizeEnd","getNestedValue","obj","current","useBindingDisplay","getBindingDisplayState","element","title","demoData","fieldMatch","fieldPath","demoValue","V_ALIGN_FLEX","H_ALIGN_FLEX","textStyle","displayText","imageSrc","raw","hasError","onError","watch","imgStyle","ROW_TYPES","emitAction","payload","_createBlock","_Teleport","barcodeSvg","svgOk","dataUrl","renderBarcode","JsBarcode","renderQrcode","QRCode","render","_vShow","PX_PER_MM","HEIGHT_EPSILON_MM","ROW_TYPE_BADGE","editCtx","inject","defaultFontSize","defaultColor","selection","rowTopMm","tableRef","rowLayoutMm","measureTable","table","tableHpx","tableHmm","baseTop","tr","badgeTopMm","badgeHeightMm","demoList","ds","isCodeCell","cellDisplay","_row","cellStyle","borderOpts","cellClass","dragAnchor","applySelection","onCellMouseDown","onCellMouseEnter","onCellDblClick","menu","reactive","onCellContextMenu","mergeReason","canSplit","rowTypeReason","cloned","syncElementSize","checkColWidthLimit","cw","maxW","onMenuAction","err","_withModifiers","CellBarcode","TableContextMenu","isHline","lineStyle","bw","bs","bc","isOval","shapeStyle","svgRef","showText","fontSizePx","totalPx","textH","barH","size","htmlContent","DOMPurify","elRef","injectedSelectedIds","isSelected","injectedPreviewIds","isPreviewed","componentMap","markRaw","TextElement","ImageElement","LongTextElement","TableElement","LineElement","ShapeElement","BarcodeElement","QrcodeElement","HtmlElement","PageNumberElement","bindingState","contentComponent","contentAttrs","elementStyle","posLabel","dragStartLeft","dragStartTop","dragConfig","info","finalDx","finalDy","sibling","setupDrag","cleanupDrag","watchEffect","resizeEnabled","cleanupResize","onDblClick","onDblClickCell","elementId","_unref","_resolveDynamicComponent","_mergeProps","p","buildRulerTicks","lengthMM","ticks","mm","rounded","major","THICKNESS","canvasRef","cssSize","draw","canvas","dpr","lengthPx","horizontal","style","bg","fg","tick","dragging","onDown","onMove","onUp","posMM","useAdsorb","config","adsorbMin","adsorbLineMin","showAdsorbLine","guideLines","paperSize","SNAP_COLORS","snapColor","check","movingRect","others","lines","minDist","other","hPairs","vPairs","ok","dist","m2","hKeys","vKeys","adjustedM","seen","renderLines","clearLines","useAdsorbManager","requestAdsorb","clearGuides","contentRef","paperWidthMM","paperHeightMM","zoneRectsMM","layerStyle","zoneElements","headerElements","footerElements","contentElements","currentDragZone","rawRequestAdsorb","guidePaperSize","showSnapIndicator","onGuideDown","startPt","MM_PER_PX","ev","delta","paperStyle","contentStyle","showRulerComputed","gridBgStyle","snapSeq","snapTimer","snapIndicator","watermarkVisible","watermarkStyle","color","opacity","rotate","getWatermarkText","now","ts","buildWatermarkSvg","printData","escaped","svg","zoneResizing","startZoneResize","cleanupZoneResize","onZoneResizeMove","onZoneResizeUp","startH","dyMM","maxH","onSelectElement","__expose","Ruler","BaseElement","line","idx","rootRef","toPaperPoint","onDrop","fieldData","elementType","marquee","marqueeStart","isCanvasBackground","xMm","yMm","onMouseLeave","onWheel","oldScale","newScale","container","mouseX","mouseY","onCanvasMouseDown","onMarqueeMove","onMarqueeUp","hitTestIds","paperRect","containMode","elLeft","elTop","elRight","elBottom","inter","contained","contextMenu","onContextMenu","elId","containerRect","closeContextMenu","handlePaste","handleSelectAll","handleClearSelection","action","onBeforeUnmount","CanvasPaper","PROPERTY_REGISTRY","matchKeywords","search","keywords","searchProperties","itemKeys","matched","onSearch","isExpanded","iconChar","toggle","saveState","loadState","saved","_renderSlot","_ctx","showItem","PropertyGroup","PRESET_COLORS","visible","triggerRef","panelRef","areaRef","panelStyle","hue","saturation","hexInput","areaDragging","normalizedValue","activeColor","rgbToHex","hsvToRgb","hueModel","degree","setHsv","clampDegree","syncFromColor","onHexInput","parseHex","normalizeHex","rgb","hsv","rgbToHsv","clamp01","startAreaDrag","setAreaFromEvent","moveAreaDrag","endAreaDrag","area","onAreaKeydown","handled","close","open","trigger","nextTick","panelWidth","panelHeight","margin","below","onDocumentPointerDown","onWindowCloseEvents","onKeydown","match","hex","full","part","red","green","blue","hh","r1","g1","b1","number","isTableType","PresetColorPicker","_hoisted_16","_hoisted_17","_hoisted_18","val","searchPlaceholder","selectedFields","toggleField","localExpression","found","handleFieldDoubleClick","insertAtCursor","handleAggregateDoubleClick","handleItemDoubleClick","filteredSystemVars","systemVars","sv","filteredAggregateFuncs","aggregateFunctions","filteredFormatFuncs","formatFunctions","textareaRef","previewResult","ta","end","after","onConfirm","_hoisted_19","_hoisted_20","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_26","_hoisted_27","_hoisted_28","_hoisted_29","_hoisted_30","_hoisted_31","editorVisible","openEditor","ExpressionEditor","tableEditCtx","listFieldOptions","onSourceChange","onColWidthChange","widths","othersW","clamped","isTable","tablePaginationEnabled","onTablePaginationChange","checked","paginationPageable","paginationKeepWithNext","onPageableChange","onKeepWithNextChange","uploading","uploadImage","uploadDisabled","handleFileChange","input","file","url","onTypeChange","onHeightChange","onRepeatChange","mainCell","formatterEditorVisible","pendingFormatterValue","isBarcodeCell","isQrcodeCell","onAlignChange","write","onValignChange","onCellTypeChange","openFormatterEditor","onFormatterEditorConfirm","borderStyle","borderWidth","borderColor","edgeChecks","currentBorder","onEdgesChange","edges","nb","side","doMerge","doSplit","_hoisted_21","_hoisted_25","_hoisted_33","_hoisted_34","_hoisted_36","_hoisted_38","_hoisted_40","_hoisted_41","_hoisted_42","_hoisted_43","_hoisted_44","_hoisted_45","_hoisted_46","_hoisted_47","_hoisted_48","_hoisted_49","_hoisted_51","_hoisted_53","_hoisted_54","_hoisted_55","ELEMENT_BINDING_REGISTRY","getTableCellBindings","rowType","rowIndex","cellIndex","listField","getElementBindings","staticBindings","dynamicBindings","paperPresets","isTextType","isImageType","isTableCellSelected","searchResult","matchedKeys","bindingDescriptors","c1","parsePath","targetPath","segment","baseName","indices","getBindingValue","setBindingValue","segments","lastKey","onImageUploadSuccess","paperSizeModel","orientationModel","marginTop","marginBottom","marginLeft","marginRight","headerHeight","footerHeight","overlayHeight","customWidth","customHeight","emitUpdate","onPaperSizeChange","onOrientationChange","onCustomWidthChange","onCustomHeightChange","onMarginTopChange","onMarginBottomChange","onMarginLeftChange","onMarginRightChange","onHeaderHeightChange","onFooterHeightChange","onOverlayHeightChange","currentTab","PropertySearch","PositionSizeGroup","AppearanceGroup","desc","BindingControl","ImageContentUpload","TableRowGroup","TableCellGroup","TableSettingsGroup","BorderBgGroup","PaginationGroup","AdvancedGroup","_ps","_hoisted_35","LEFT_KEY","RIGHT_KEY","readStored","fallback","useStudioChrome","leftCollapsed","rightCollapsed","dirty","toggleLeft","toggleRight","markSaved","onUndo","onRedo","onAlign","onGroup","onUngroup","onDeleteElement","onDragStop","onDropElement","onDropField","onMoveLayer","maxTableWidth","provide","canvasAreaRef","overlayVisible","screenshotUrl","overlayOpacity","toggleOverlay","templateJson","blob","coordinate","onCoordinate","paperLabel","dim","orient","onFitWindow","onZoom","onKeyFitWindow","onTemplateDataChanged","prevHeader","prevFooter","onZoneHeightChange","onZoneHeightCommit","warnZoneOverflow","onAddOverlayElement","overlay","newEl","onToggleVisible","onToggleLocked","activePropertyTab","DBL_EDITABLE_FIELD","dblEditorVisible","dblEditTarget","dblEditorExpression","onDblClickElement","onDblEditorConfirm","onCloneElement","_pos","handleLoadDefault","tpl","handleSave","DesignerToolbar","LeftPanel","CanvasArea","PropertyPanel","StatusBar","READY_TIMEOUT_MS","renderHtmlPages","template","baseUrl","codeRenderer","boundTemplate","bindData","measuredElements","measureElements","pageLayouts","paginate","generateHtml","measureHtml","iframe","win","doc","waitForRenderReady","measurements","readMeasurements","measuredMap","elementIndex","repeatCount","resolve","settled","finish","timer","run","fonts","timeout","waitForImages","ms","_resolve","reject","imgs","img","htmlEl","heightPx","rowHeights","SVG_NS","renderBarcodeSvg","renderQrSvg","level","modules","quiet","browserCodeRenderer","cellType","iframeRef","rendering","errorMsg","renderSeq","rerender","html","pageCount","print"],"mappings":"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"}