@worm-vue3-print/canvas 1.1.0 → 1.2.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.
package/dist/index.js.map CHANGED
@@ -1 +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/CellImage.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/StepperInput.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\n/** 列宽拖拽的最小列宽(mm),与属性面板列宽输入下限一致 */\nexport const MIN_COL_WIDTH_MM = 5\n\n/**\n * 列宽拖拽钳制(纯函数,不修改入参,调用方负责回写):\n * 返回目标列宽在 [MIN_COL_WIDTH_MM, maxTableWidth - 其余列和] 范围内的钳制值,\n * 结果保留 0.1mm 精度。maxTableWidth 为 Infinity 时不设总宽上限。\n */\nexport function clampResizedColumnWidth(\n colWidths: number[],\n index: number,\n targetMm: number,\n maxTableWidth: number,\n): number {\n const others = colWidths.reduce((s, w, i) => (i === index ? s : s + w), 0)\n const cap = maxTableWidth === Infinity\n ? Infinity\n : Math.max(MIN_COL_WIDTH_MM, maxTableWidth - others)\n const rounded = Math.round(targetMm * 10) / 10\n return Math.min(Math.max(rounded, MIN_COL_WIDTH_MM), cap)\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 <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')\" data-tip=\"置顶\">⤒</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('move-layer', 'up')\" data-tip=\"上移一层\">↑</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('move-layer', 'down')\" data-tip=\"下移一层\">↓</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('move-layer', 'bottom')\" data-tip=\"置底\">⤓</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 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-btn[data-tip] {\n position: relative;\n}\n.tb-btn[data-tip]::after {\n content: attr(data-tip);\n position: absolute;\n bottom: -32px;\n left: 50%;\n transform: translateX(-50%);\n padding: 4px 8px;\n font-size: 12px;\n color: #fff;\n background: rgba(30, 35, 48, .88);\n border-radius: 4px;\n white-space: nowrap;\n opacity: 0;\n pointer-events: none;\n transition: opacity .15s ease;\n z-index: 100;\n}\n.tb-btn[data-tip]:hover::after {\n opacity: 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\" :style=\"svgStyle\"></svg>\n <img v-if=\"cellType === 'qrcode' && dataUrl\" :src=\"dataUrl\" alt=\"qrcode\" :style=\"imgStyle\" />\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, computed, 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 fit?: string\n maxWidth?: number\n maxHeight?: number\n}>()\n\nconst barcodeSvg = ref<SVGSVGElement | null>(null)\nconst svgOk = ref(false)\nconst dataUrl = ref('')\n\nconst svgStyle = computed(() => ({\n objectFit: (props.fit || 'contain') as any,\n maxWidth: props.maxWidth ? `${props.maxWidth}mm` : '100%',\n maxHeight: props.maxHeight ? `${props.maxHeight}mm` : '100%',\n}))\n\nconst imgStyle = computed(() => ({\n objectFit: (props.fit || 'contain') as any,\n maxWidth: props.maxWidth ? `${props.maxWidth}mm` : '100%',\n maxHeight: props.maxHeight ? `${props.maxHeight}mm` : '100%',\n}))\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","<!-- 表格单元格内图片渲染:设计态与预览态共用 -->\n<template>\n <div class=\"cell-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 { evaluateTemplate } from '../../utils/expression-eval'\nimport { DEFAULT_DEMO_DATA } from '../../utils/demo-data'\n\nconst props = defineProps<{\n value: string\n fit?: string\n maxWidth?: number\n maxHeight?: number\n designMode?: boolean\n data?: Record<string, any>[]\n}>()\n\nconst imageSrc = computed(() => {\n const raw = props.value || ''\n if (!raw) return ''\n \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 \n return raw\n})\n\n// 加载失败兜底\nconst hasError = ref(false)\nfunction onError() {\n hasError.value = true\n}\n\n// src 变化时重置错误态\nwatch(imageSrc, () => {\n hasError.value = false\n})\n\nconst imgStyle = computed(() => ({\n objectFit: (props.fit || 'contain') as any,\n maxWidth: props.maxWidth ? `${props.maxWidth}mm` : '100%',\n maxHeight: props.maxHeight ? `${props.maxHeight}mm` : '100%',\n}))\n</script>\n\n<style scoped>\n.cell-image {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n}\n.cell-image img {\n max-width: 100%;\n max-height: 100%;\n display: block;\n}\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>","<!-- 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 :fit=\"cell.fit\"\n :max-width=\"cell.maxWidth\"\n :max-height=\"cell.maxHeight\"\n />\n <CellImage\n v-else-if=\"cell.cellType === 'image'\"\n :value=\"cell.formatter || ''\"\n :fit=\"cell.fit\"\n :max-width=\"cell.maxWidth\"\n :max-height=\"cell.maxHeight\"\n :design-mode=\"designMode\"\n :data=\"imageData\"\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=\"colResizeEnabled\" class=\"col-resize-layer\">\n <div\n v-for=\"i in colResizeBoundaries\"\n :key=\"i\"\n class=\"col-resize-handle\"\n :class=\"{ dragging: colResizeBoundary === i }\"\n :style=\"{ left: colBoundaryLeftMm(i) + 'mm' }\"\n @mousedown.stop.prevent=\"onColResizeStart(i, $event)\"\n />\n </div>\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, onUnmounted, 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, clampResizedColumnWidth,\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 CellImage from './CellImage.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 /** 画布缩放倍率(用于列宽拖拽 px→mm 换算) */\n scale?: number\n /** 打印数据(用于运行态图片等动态内容) */\n data?: Record<string, any>[]\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\n// 添加图片数据处理\nconst imageData = computed(() => {\n // 运行态:使用打印数据\n if (props.data) {\n return props.data\n }\n // 设计态:使用 demo 数据\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\n// ─── 列宽拖拽 ───\n// 仅设计态选中且未锁定的多列表格渲染内部列边界手柄;拖拽期间实时回写列宽,\n// mouseup 时同步元素尺寸并记一次历史(与右键菜单结构操作一致)。\nconst colResizeEnabled = computed(\n () => props.designMode && !!props.isSelected && !props.element.options.locked && colWidths.value.length > 1,\n)\n/** 内部列边界索引(1..n-1),单列无边界 */\nconst colResizeBoundaries = computed<number[]>(() =>\n colWidths.value.length > 1\n ? Array.from({ length: colWidths.value.length - 1 }, (_, k) => k + 1)\n : [],\n)\n/** 第 i 列左边界位置(mm)= 前 i 列宽和 */\nfunction colBoundaryLeftMm(i: number): number {\n return colWidths.value.slice(0, i).reduce((s, w) => s + w, 0)\n}\n\nconst colResizeBoundary = ref<number | null>(null)\nlet resizeStartX = 0\nlet resizeStartWidth = 0\n\n/** 拖拽边界 i(第 i 列左边界):调整其左侧第 i-1 列的宽度,使被拖动的边界线跟随光标 */\nfunction onColResizeStart(i: number, e: MouseEvent) {\n if (!colResizeEnabled.value) return\n colResizeBoundary.value = i\n resizeStartX = e.clientX\n resizeStartWidth = colWidths.value[i - 1]!\n document.addEventListener('mousemove', onColResizeMove)\n document.addEventListener('mouseup', onColResizeEnd)\n}\n\nfunction onColResizeMove(e: MouseEvent) {\n if (colResizeBoundary.value === null) return\n const scale = props.scale || 1\n const deltaMm = (e.clientX - resizeStartX) / scale\n const colIndex = colResizeBoundary.value - 1\n const widths = props.element.options.tableColWidths!\n widths[colIndex] = clampResizedColumnWidth(\n widths, colIndex, resizeStartWidth + deltaMm, editCtx.maxTableWidth.value,\n )\n}\n\nfunction onColResizeEnd() {\n document.removeEventListener('mousemove', onColResizeMove)\n document.removeEventListener('mouseup', onColResizeEnd)\n if (colResizeBoundary.value === null) return\n colResizeBoundary.value = null\n syncElementSize()\n editCtx.recordHistory()\n}\n\nonUnmounted(() => {\n document.removeEventListener('mousemove', onColResizeMove)\n document.removeEventListener('mouseup', onColResizeEnd)\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.col-resize-layer {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 3;\n}\n.col-resize-handle {\n position: absolute;\n top: 0;\n bottom: 0;\n width: 6px;\n transform: translateX(-50%);\n cursor: col-resize;\n pointer-events: auto;\n}\n/* 手柄 hover/拖拽时显示主题色竖线,提示列边界位置 */\n.col-resize-handle::after {\n content: '';\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n border-left: 1px solid transparent;\n}\n.col-resize-handle:hover::after,\n.col-resize-handle.dragging::after {\n border-left-color: var(--pd-accent, #165DFF);\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, scale: props.scale }\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: props.templateData.pageBackground || '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 boxSizing: 'border-box' 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 <div class=\"pd-stepper\">\n <button\n type=\"button\"\n class=\"pd-step-btn pd-step-minus\"\n :disabled=\"atMin\"\n title=\"减小\"\n aria-label=\"减小\"\n @click=\"stepBy(-1)\"\n >−</button>\n <input\n type=\"number\"\n class=\"pd-input pd-step-input\"\n :value=\"draft\"\n :placeholder=\"placeholder\"\n :min=\"min\"\n :max=\"max\"\n :step=\"step\"\n @input=\"onInput\"\n @change=\"commit\"\n @blur=\"commit\"\n @keydown.enter.prevent=\"($event.target as HTMLInputElement).blur()\"\n />\n <button\n type=\"button\"\n class=\"pd-step-btn pd-step-plus\"\n :disabled=\"atMax\"\n title=\"增大\"\n aria-label=\"增大\"\n @click=\"stepBy(1)\"\n >+</button>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\n\nconst props = withDefaults(defineProps<{\n /** 数值;undefined 表示未设置(继承默认),输入框显示空占位 */\n modelValue?: number\n min?: number\n max?: number\n /** 步进单位,默认 1(整数);小数步进时按小数位数保留精度 */\n step?: number\n /** 未设置(继承默认)时输入框的占位提示 */\n placeholder?: string\n}>(), {\n step: 1,\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: number | undefined]\n}>()\n\n/** 步进小数位数:由 step 推导(0.5→1 位,0.25→2 位,0.1→1 位,1→0 位) */\nconst precision = computed(() => {\n const s = String(props.step)\n const dot = s.indexOf('.')\n return dot === -1 ? 0 : s.length - dot - 1\n})\n\n/** 按 step 精度取整,规避浮点误差(0.30000000000000004 → 0.3) */\nfunction roundTo(v: number): number {\n if (!Number.isFinite(v)) return 0\n return Number(v.toFixed(precision.value))\n}\n\n/** 当前有效值:undefined 表示未设置(继承默认) */\nconst current = computed<number | undefined>(() => {\n const v = props.modelValue\n if (v === undefined || v === null || !Number.isFinite(v)) return undefined\n return roundTo(v)\n})\n\n/** 输入框草稿:输入过程中保留原文,失焦/回车后按精度规范化 */\nconst draft = ref(current.value === undefined ? '' : String(current.value))\nwatch(current, (v) => {\n draft.value = v === undefined ? '' : String(v)\n})\n\n/** 步进基准:未设置时从 min(无 min 则为 0)起步 */\nconst base = computed(() => {\n if (current.value !== undefined) return current.value\n return props.min !== undefined ? props.min : 0\n})\n\nconst atMin = computed(() => props.min !== undefined && base.value <= props.min)\nconst atMax = computed(() => props.max !== undefined && base.value >= props.max)\n\n/** 夹取到 [min, max],并按 step 精度取整 */\nfunction clamp(v: number): number {\n let next = roundTo(v)\n if (props.min !== undefined && next < props.min) next = props.min\n if (props.max !== undefined && next > props.max) next = props.max\n return next\n}\n\nfunction stepBy(dir: 1 | -1) {\n if ((dir < 0 && atMin.value) || (dir > 0 && atMax.value)) return\n const next = clamp(base.value + dir * props.step)\n draft.value = String(next)\n emit('update:modelValue', next)\n}\n\nfunction onInput(e: Event) {\n draft.value = (e.target as HTMLInputElement).value\n}\n\n/** 失焦/回车提交:解析草稿并按精度取整;空值回退为当前值(未设置则保持未设置) */\nfunction commit() {\n const raw = draft.value.trim()\n if (raw === '') {\n if (current.value !== undefined) {\n draft.value = String(current.value)\n }\n return\n }\n const num = Number(raw)\n if (!Number.isFinite(num)) {\n draft.value = current.value === undefined ? '' : String(current.value)\n return\n }\n const next = clamp(num)\n draft.value = String(next)\n // change 与 blur 会先后触发,仅当值真正变化时 emit,避免重复提交\n if (next !== current.value) {\n emit('update:modelValue', next)\n }\n}\n</script>\n\n<style scoped>\n.pd-stepper {\n display: flex;\n align-items: center;\n width: 100%;\n}\n.pd-step-btn {\n width: 26px;\n height: 26px;\n flex-shrink: 0;\n border: 1px solid var(--pd-border, #d9dde6);\n background: var(--pd-field-bg, #f4f6fa);\n color: var(--pd-text, #2a2e37);\n font-size: 14px;\n line-height: 1;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background .14s ease, border-color .14s ease, color .14s ease;\n}\n.pd-step-btn:hover:not(:disabled) {\n background: var(--pd-sidebar-hover, #f0f3f9);\n border-color: var(--pd-text-faint, #b4b9c4);\n}\n.pd-step-btn:disabled {\n opacity: 0.45;\n cursor: not-allowed;\n}\n.pd-step-minus {\n border-radius: 6px 0 0 6px;\n border-right: none;\n}\n.pd-step-plus {\n border-radius: 0 6px 6px 0;\n border-left: none;\n}\n.pd-step-input.pd-input {\n border-radius: 0;\n min-width: 0;\n flex: 1;\n text-align: center;\n -moz-appearance: textfield;\n}\n.pd-step-input.pd-input::-webkit-outer-spin-button,\n.pd-step-input.pd-input::-webkit-inner-spin-button {\n -webkit-appearance: none;\n margin: 0;\n}\n</style>\n","<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 <StepperInput v-model=\"element.options.left\"\n :min=\"0\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ps-top')\"><span class=\"pd-label\">Y</span>\n <StepperInput v-model=\"element.options.top\"\n :min=\"0\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ps-width')\"><span class=\"pd-label\">W</span>\n <StepperInput v-model=\"element.options.width\"\n :min=\"4\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ps-height')\"><span class=\"pd-label\">H</span>\n <StepperInput v-model=\"element.options.height\"\n :min=\"4\" />\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'\nimport StepperInput from './StepperInput.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 <StepperInput v-model=\"element.options.fontSize\"\n :min=\"8\"\n :max=\"72\" />\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 <StepperInput v-model=\"element.options.lineHeight\"\n :min=\"0\"\n :max=\"100\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ap-letter-spacing')\"><span class=\"pd-label\">字间距</span>\n <StepperInput v-model=\"element.options.letterSpacing\"\n :min=\"0\"\n :max=\"20\"\n :step=\"0.5\" />\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'\nimport StepperInput from './StepperInput.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 <div class=\"ee-field-info\">\n <span class=\"ee-item-label\">{{ field.fieldLabel }}</span>\n <span class=\"ee-item-key\">{{ field.fieldKey }}</span>\n </div>\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=\"handleVariableDoubleClick(sv)\"\n >\n <div class=\"ee-field-info\">\n <span class=\"ee-item-label\">{{ sv.label }}</span>\n <span class=\"ee-item-key\">{{ sv.template }}</span>\n </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=\"handleFunctionDoubleClick(fn)\"\n >\n <div class=\"ee-field-info\">\n <span class=\"ee-item-label\">{{ fn.label }}</span>\n <span class=\"ee-item-key\">{{ fn.name }}()</span>\n </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=\"handleFunctionDoubleClick(fn)\"\n >\n <div class=\"ee-field-info\">\n <span class=\"ee-item-label\">{{ fn.label }}</span>\n <span class=\"ee-item-key\">{{ fn.name }}()</span>\n </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=\"双击左侧字段/变量/函数插入,或直接输入静态内容\"\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 静态数据直接输入即可,如:供应商名称<br>\n 动态解析字段、变量、函数必须用 {} 包裹<br>\n 示例:{SUM(supplier.name)}<br>\n 注意:只能嵌套一层\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(字段) - 计数<br>\n IF(条件, 真值, 假值) - 条件判断\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 {pageIndex} - 当前页码<br>\n {totalPages} - 总页数<br>\n {printDate} - 打印日期\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 静态文本:供应商名称<br>\n 动态字段:{supplier.name}<br>\n 函数调用:{SUM(amount)}<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// 当弹出框打开时,重置为外部传入值\nwatch(visible, (val) => {\n if (val) {\n localExpression.value = props.expression || ''\n }\n})\n\n// 字段双击:函数参数内插入裸字段(去大括号),其余场景保持 {字段} 包裹\nfunction handleFieldDoubleClick(field: PrintBusinessField) {\n const { insideParens } = getCursorRegion()\n insertAtCursor(insideParens ? field.fieldKey : `{${field.fieldKey}}`)\n}\n\n// 变量双击:函数参数内去大括号,其余场景保持 {变量} 原样\nfunction handleVariableDoubleClick(sv: { name: string; template: string }) {\n const { insideParens } = getCursorRegion()\n insertAtCursor(insideParens ? sv.template.replace(/^\\{|\\}$/g, '') : sv.template)\n}\n\n// 函数双击:已在 {…} 块内则裸插入,否则自动包裹大括号;光标定位到 () 内部\nfunction handleFunctionDoubleClick(fn: { name: string; template: string }) {\n const { insideBlock } = getCursorRegion()\n const text = insideBlock ? fn.template : `{${fn.template}}`\n const caretOffset = text.indexOf('(') + 1\n insertAtCursor(text, caretOffset)\n}\n\n// 根据光标位置判断插入上下文:是否在 {…} 表达式块内、是否在函数参数 (…) 内\nfunction getCursorRegion(): { insideBlock: boolean; insideParens: boolean } {\n const ta = textareaRef.value\n const start = ta?.selectionStart ?? localExpression.value.length\n const before = localExpression.value.substring(0, start)\n\n // 光标前最近的 { 未被 } 闭合 → 在表达式块内\n let insideBlock = false\n const lastBlockOpen = before.lastIndexOf('{')\n if (lastBlockOpen !== -1 && !before.slice(lastBlockOpen + 1).includes('}')) {\n insideBlock = true\n }\n\n // 光标前最近的 ( 未被 ) 闭合 → 在函数参数内\n let insideParens = false\n const lastParenOpen = before.lastIndexOf('(')\n if (lastParenOpen !== -1 && !before.slice(lastParenOpen + 1).includes(')')) {\n insideParens = true\n }\n\n return { insideBlock, insideParens }\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, caretOffset = text.length) {\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 const caretPos = start + caretOffset\n nextTick(() => {\n ta.focus()\n ta.selectionStart = ta.selectionEnd = caretPos\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: 6px 10px;\n margin-bottom: 2px;\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: 7px 10px;\n cursor: pointer;\n border-radius: 4px;\n margin-bottom: 2px;\n transition: background 0.15s;\n}\n.ee-field-info {\n display: flex;\n flex-direction: column;\n gap: 1px;\n}\n.ee-field-info .ee-item-label {\n font-size: 12px;\n color: var(--pd-text);\n}\n.ee-field-info .ee-item-key {\n font-size: 10px;\n color: var(--pd-text-muted);\n font-family: monospace;\n}\n\n.ee-list-item:hover {\n background: #ecf5ff;\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 <StepperInput v-model=\"element.options.tableDefaultFontSize\" :min=\"5\" :max=\"72\" placeholder=\"默认\" />\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 <StepperInput v-model=\"element.options.tableDefaultPadding\" :min=\"0\" :max=\"10\" :step=\"0.5\" placeholder=\"默认\" />\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 <StepperInput :model-value=\"w\" :min=\"5\" :max=\"200\" @update:model-value=\"onColWidthChange(i, $event)\" />\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'\nimport StepperInput from './StepperInput.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 <StepperInput v-model=\"element.options.borderWidth\"\n :min=\"0\"\n :max=\"20\"\n :step=\"0.25\" />\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'\nimport StepperInput from './StepperInput.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: 10px;\n}\n.border-row .pd-field {\n flex: 1;\n min-width: 0;\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 <StepperInput v-model=\"element.options.zIndex\"\n :min=\"0\"\n :max=\"999\" />\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'\nimport StepperInput from './StepperInput.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 <StepperInput :model-value=\"row.height\"\n :min=\"3\"\n :max=\"100\"\n :step=\"0.5\" @update:model-value=\"onHeightChange\" />\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'\nimport StepperInput from './StepperInput.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 <label class=\"pd-radio\"><input type=\"radio\" value=\"image\" :checked=\"mainCell.cellType === 'image'\" @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\" v-if=\"isBarcodeCell || isQrcodeCell || isImageCell\"><span class=\"pd-label\">缩放模式</span>\n <select :value=\"mainCell.fit || 'contain'\" class=\"pd-select\" @change=\"write(c => { c.fit = ($event.target as HTMLSelectElement).value as any })\">\n <option value=\"contain\">包含(保持比例)</option>\n <option value=\"cover\">覆盖(保持比例)</option>\n <option value=\"fill\">拉伸填满</option>\n <option value=\"none\">原始尺寸</option>\n <option value=\"scale-down\">缩小(保持比例)</option>\n </select>\n </div>\n <div class=\"pd-field\" v-if=\"isBarcodeCell || isQrcodeCell || isImageCell\"><span class=\"pd-label\">最大宽度 (mm)</span>\n <StepperInput :model-value=\"mainCell.maxWidth\"\n :min=\"1\"\n :max=\"200\"\n placeholder=\"默认\" @update:model-value=\"write(c => { c.maxWidth = $event ?? undefined })\" />\n </div>\n <div class=\"pd-field\" v-if=\"isBarcodeCell || isQrcodeCell || isImageCell\"><span class=\"pd-label\">最大高度 (mm)</span>\n <StepperInput :model-value=\"mainCell.maxHeight\"\n :min=\"1\"\n :max=\"200\"\n placeholder=\"默认\" @update:model-value=\"write(c => { c.maxHeight = $event ?? undefined })\" />\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 <StepperInput :model-value=\"mainCell.fontSize\"\n :min=\"5\"\n :max=\"72\"\n placeholder=\"默认\" @update:model-value=\"write(c => { c.fontSize = $event ?? 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 <div style=\"width: 112px; flex-shrink: 0\"><StepperInput v-model=\"borderWidth\"\n :min=\"0.25\"\n :max=\"5\"\n :step=\"0.25\" /></div>\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 <StepperInput :model-value=\"mainCell.padding\"\n :min=\"0\"\n :max=\"10\"\n :step=\"0.5\"\n placeholder=\"默认\" @update:model-value=\"write(c => { c.padding = $event ?? 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 StepperInput from './StepperInput.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')\nconst isImageCell = computed(() => mainCell.value.cellType === 'image')\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 // fit、maxWidth、maxHeight 对所有类型都有效,不再清除\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 <StepperInput :model-value=\"customWidth\"\n :min=\"25\"\n :max=\"2000\"\n @update:model-value=\"onCustomWidthChange\" />\n <span class=\"custom-size-x\">×</span>\n <StepperInput :model-value=\"customHeight\"\n :min=\"25\"\n :max=\"2000\"\n @update:model-value=\"onCustomHeightChange\" />\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 <div class=\"pd-field\"><span class=\"pd-label\">页面背景色</span>\n <div class=\"page-bg-row\">\n <PresetColorPicker v-model=\"pageBackgroundModel\" class=\"page-bg-picker\" />\n <button type=\"button\" class=\"pd-reset\" title=\"恢复为默认白色\" @click=\"onPageBackgroundReset\">默认</button>\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 <StepperInput :model-value=\"marginTop\" :min=\"0\" :max=\"50\" @update:model-value=\"onMarginTopChange\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">下</span>\n <StepperInput :model-value=\"marginBottom\" :min=\"0\" :max=\"50\" @update:model-value=\"onMarginBottomChange\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">左</span>\n <StepperInput :model-value=\"marginLeft\" :min=\"0\" :max=\"50\" @update:model-value=\"onMarginLeftChange\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">右</span>\n <StepperInput :model-value=\"marginRight\" :min=\"0\" :max=\"50\" @update:model-value=\"onMarginRightChange\" />\n </div>\n </div>\n\n <h3 class=\"pd-divider\">三区高度 (mm)</h3>\n <div class=\"pd-field\"><span class=\"pd-label\">页眉高度</span>\n <StepperInput :model-value=\"headerHeight\" :min=\"0\" :max=\"100\" :step=\"0.1\" @update:model-value=\"onHeaderHeightChange\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">页脚高度</span>\n <StepperInput :model-value=\"footerHeight\" :min=\"0\" :max=\"100\" :step=\"0.1\" @update:model-value=\"onFooterHeightChange\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">首页叠加高度</span>\n <StepperInput :model-value=\"overlayHeight\" :min=\"0\" :max=\"200\" @update:model-value=\"onOverlayHeightChange\" />\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 StepperInput from './property/StepperInput.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 PresetColorPicker from './PresetColorPicker.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 pageBackgroundModel = computed({\n get: () => props.templateData?.pageBackground || '#ffffff',\n set: (v: string) => onPageBackgroundChange(v),\n})\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 onPageBackgroundChange(v: string) {\n const value = v && v.toLowerCase() !== '#ffffff' && v.toLowerCase() !== '#fff' ? v : undefined\n emitUpdate(value === undefined ? { pageBackground: undefined } : { pageBackground: value })\n}\n\nfunction onPageBackgroundReset() {\n emitUpdate({ pageBackground: undefined })\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.page-bg-row {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.page-bg-picker {\n flex: 1;\n min-width: 0;\n}\n.pd-reset {\n height: 26px;\n padding: 0 8px;\n border: 1px solid var(--pd-border, #d9dde6);\n border-radius: 5px;\n background: var(--pd-field-bg, #f4f6fa);\n color: var(--pd-text-muted, #8b909c);\n font-size: 12px;\n cursor: pointer;\n flex-shrink: 0;\n transition: all .14s ease;\n}\n.pd-reset:hover {\n color: var(--pd-accent, #165DFF);\n border-color: var(--pd-accent, #165DFF);\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 @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 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 image: 'src',\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","i","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","dataIdx","applyBorderPreset","preset","border","atTop","atBottom","atLeft","atRight","GHOST_BORDER_CSS","resolveCellBorderCss","opts","syncTableElementSize","options","wMm","s","w","hMm","MIN_COL_WIDTH_MM","clampResizedColumnWidth","targetMm","maxTableWidth","others","cap","rounded","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","_hoisted_3","_hoisted_4","_toDisplayString","_cache","_hoisted_5","$emit","_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","svgStyle","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","imageData","isCodeCell","cellDisplay","_row","cellStyle","borderOpts","cellClass","dragAnchor","applySelection","onCellMouseDown","onCellMouseEnter","onCellDblClick","menu","reactive","onCellContextMenu","mergeReason","canSplit","rowTypeReason","cloned","syncElementSize","checkColWidthLimit","cw","maxW","onMenuAction","err","colResizeEnabled","colResizeBoundaries","colBoundaryLeftMm","colResizeBoundary","resizeStartX","resizeStartWidth","onColResizeStart","onColResizeMove","onColResizeEnd","deltaMm","colIndex","widths","_withModifiers","CellBarcode","CellImage","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","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","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","precision","roundTo","draft","atMin","atMax","clamp","stepBy","dir","onInput","commit","_withKeys","showItem","PropertyGroup","StepperInput","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","localExpression","handleFieldDoubleClick","insideParens","getCursorRegion","insertAtCursor","handleVariableDoubleClick","sv","handleFunctionDoubleClick","insideBlock","caretOffset","textareaRef","lastBlockOpen","lastParenOpen","filteredSystemVars","systemVars","filteredAggregateFuncs","aggregateFunctions","filteredFormatFuncs","formatFunctions","previewResult","ta","end","after","caretPos","onConfirm","_hoisted_19","_hoisted_20","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","_hoisted_27","_hoisted_28","_hoisted_29","_hoisted_30","_hoisted_31","_hoisted_32","_hoisted_33","editorVisible","openEditor","ExpressionEditor","tableEditCtx","listFieldOptions","onSourceChange","onColWidthChange","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","isImageCell","onAlignChange","write","onValignChange","onCellTypeChange","openFormatterEditor","onFormatterEditorConfirm","borderStyle","borderWidth","borderColor","edgeChecks","currentBorder","onEdgesChange","edges","nb","side","doMerge","doSplit","_hoisted_21","_hoisted_35","_hoisted_37","_hoisted_39","_hoisted_40","_hoisted_42","_hoisted_43","_hoisted_45","_hoisted_46","_hoisted_47","_hoisted_48","_hoisted_49","_hoisted_50","_hoisted_51","_hoisted_52","_hoisted_53","_hoisted_54","_hoisted_55","_hoisted_56","_hoisted_58","_hoisted_59","_hoisted_60","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","pageBackgroundModel","onPageBackgroundChange","marginTop","marginBottom","marginLeft","marginRight","headerHeight","footerHeight","overlayHeight","customWidth","customHeight","emitUpdate","onPaperSizeChange","onOrientationChange","onPageBackgroundReset","onCustomWidthChange","onCustomHeightChange","onMarginTopChange","onMarginBottomChange","onMarginLeftChange","onMarginRightChange","onHeaderHeightChange","onFooterHeightChange","onOverlayHeightChange","currentTab","PropertySearch","PositionSizeGroup","AppearanceGroup","desc","BindingControl","ImageContentUpload","TableRowGroup","TableCellGroup","TableSettingsGroup","BorderBgGroup","PaginationGroup","AdvancedGroup","_ps","_hoisted_26","LEFT_KEY","RIGHT_KEY","readStored","fallback","useStudioChrome","leftCollapsed","rightCollapsed","dirty","toggleLeft","toggleRight","markSaved","onUndo","onRedo","onAlign","onGroup","onUngroup","onDeleteElement","onDragStop","onDropElement","onDropField","onMoveLayer","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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"}
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/HelpButton.vue","../src/components/DesignerToolbar.vue","../src/components/LayerPanel.vue","../src/utils/field-groups.ts","../src/components/FieldTreePanel.vue","../src/components/LeftPanel.vue","../src/utils/ruler.ts","../src/composables/useDrag.ts","../src/composables/useResize.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/CellImage.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/composables/useAdsorb.ts","../src/composables/useAdsorbManager.ts","../src/components/CanvasPaper.vue","../src/components/Ruler.vue","../src/components/CanvasArea.vue","../src/utils/property-search.ts","../src/components/property/PropertySearch.vue","../src/components/property/PropertyGroup.vue","../src/components/property/StepperInput.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/help-content/getting-started.ts","../src/help-content/features.ts","../src/help-content/shortcuts.ts","../src/help-content/faq.ts","../src/help-content/changelog.ts","../src/help-content/index.ts","../src/components/HelpModal.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\n/** 列宽拖拽的最小列宽(mm),与属性面板列宽输入下限一致 */\nexport const MIN_COL_WIDTH_MM = 5\n\n/**\n * 列宽拖拽钳制(纯函数,不修改入参,调用方负责回写):\n * 返回目标列宽在 [MIN_COL_WIDTH_MM, maxTableWidth - 其余列和] 范围内的钳制值,\n * 结果保留 0.1mm 精度。maxTableWidth 为 Infinity 时不设总宽上限。\n */\nexport function clampResizedColumnWidth(\n colWidths: number[],\n index: number,\n targetMm: number,\n maxTableWidth: number,\n): number {\n const others = colWidths.reduce((s, w, i) => (i === index ? s : s + w), 0)\n const cap = maxTableWidth === Infinity\n ? Infinity\n : Math.max(MIN_COL_WIDTH_MM, maxTableWidth - others)\n const rounded = Math.round(targetMm * 10) / 10\n return Math.min(Math.max(rounded, MIN_COL_WIDTH_MM), cap)\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\n/** mm 转 px(基于 96dpi 屏幕) */\nexport function mmToPx(mm: number): number {\n return mm * (96 / 25.4)\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/** 最小缩放百分比,低于此值画布难以查看与操作;放大方向不设上限 */\nexport const MIN_SCALE_PERCENT = 25\n\n/** 适应窗口时允许的最小缩放百分比(可低于交互缩放下限,保证超大纸张也能整版容纳) */\nexport const FIT_SCALE_MIN_PERCENT = 5\n\n/** 将缩放百分比钳制到允许范围:仅保留下限,放大不设上限 */\nexport function clampScalePercent(percent: number): number {\n return Math.max(MIN_SCALE_PERCENT, percent)\n}\n\n/**\n * 滚轮缩放:乘性步进(默认 ×1.1 / ÷1.1),大倍数下仍保持平滑手感,\n * 返回取整后的百分比,避免浮点累加产生脏显示(如 110.00000001)\n * @param percent 当前缩放百分比\n * @param direction 1 放大,-1 缩小\n */\nexport function nextWheelScale(percent: number, direction: 1 | -1, factor = 1.1): number {\n const next = direction > 0 ? percent * factor : percent / factor\n return clampScalePercent(Math.round(next))\n}\n\n/** 计算适应窗口的缩放百分比,允许小于交互缩放下限,保证整版纸张可见 */\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.max(FIT_SCALE_MIN_PERCENT, 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 showRuler = ref(true)\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, showRuler, 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 <button\n class=\"help-button\"\n title=\"帮助文档\"\n @click=\"$emit('click')\"\n >\n <span class=\"help-icon\">?</span>\n </button>\n</template>\n\n<script setup lang=\"ts\">\ndefineEmits<{\n click: []\n}>()\n</script>\n\n<style scoped>\n.help-button {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n border-radius: 4px;\n background: transparent;\n cursor: pointer;\n transition: background-color 0.15s;\n}\n\n.help-button:hover {\n background: var(--pd-sidebar-hover, #f0f3f9);\n}\n\n.help-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: var(--pd-accent, #165DFF);\n color: white;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n}\n</style>\n","<template>\n <div class=\"designer-toolbar\">\n <!-- 文件 -->\n <div class=\"tb-group\">\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')\" data-tip=\"撤销\">↶</button>\n <button class=\"tb-btn tb-icon\" :disabled=\"!canRedo\" @click=\"$emit('redo')\" data-tip=\"重做\">↷</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')\" data-tip=\"置顶\">⤒</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('move-layer', 'up')\" data-tip=\"上移一层\">↑</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('move-layer', 'down')\" data-tip=\"下移一层\">↓</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('move-layer', 'bottom')\" data-tip=\"置底\">⤓</button>\n </div>\n <!-- 视图 -->\n <div class=\"tb-group\">\n <button class=\"tb-btn\" :class=\"{ on: showRuler }\" data-tip=\"显示/隐藏标尺\" @click=\"$emit('toggle-ruler')\">\n <span class=\"dot\" /> 标尺\n </button>\n <button class=\"tb-btn\" :class=\"{ on: showGrid }\" data-tip=\"显示/隐藏网格背景\" @click=\"$emit('toggle-grid')\">\n <span class=\"dot\" /> 网格\n </button>\n <button class=\"tb-btn\" :class=\"{ on: showTableGhostBorder }\" data-tip=\"显示/隐藏无边框表格的虚拟虚线\" @click=\"$emit('toggle-table-ghost-border')\">\n <span class=\"dot\" /> 虚框\n </button>\n <button class=\"tb-btn\" :class=\"{ on: snapToGrid }\" data-tip=\"开启/关闭元素吸附到网格\" @click=\"$emit('toggle-snap')\">\n <span class=\"dot\" /> 吸附\n </button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('fit-window')\" data-tip=\"适应窗口\">⤢</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('zoom', -10)\" data-tip=\"缩小\">−</button>\n <span class=\"tb-zoom\">{{ scale }}%</span>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('zoom', 10)\" data-tip=\"放大\">+</button>\n </div>\n <!-- 操作 -->\n <div class=\"tb-spacer\" />\n <div class=\"tb-group\" v-if=\"showHelp\">\n <HelpButton @click=\"$emit('help')\" />\n </div>\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\">\nimport HelpButton from './HelpButton.vue'\n\nconst scale = defineModel<number>('scale', { default: 100 })\n\nwithDefaults(defineProps<{\n isEdit?: boolean\n canUndo?: boolean\n canRedo?: boolean\n hasMultiSelection?: boolean\n hasSelection?: boolean\n showRuler?: boolean\n showGrid?: boolean\n snapToGrid?: boolean\n showTableGhostBorder?: boolean\n selectedElementHasGroup?: boolean\n overlayVisible?: boolean\n /** 是否展示「加载默认布局」按钮(宿主注入 loadDefaultTemplate 时由 PrintDesigner 开启) */\n showLoadDefault?: boolean\n /** 是否展示帮助入口(工具栏帮助按钮);默认开启,传 false 关闭 */\n showHelp?: boolean\n}>(), {\n showRuler: true,\n showHelp: true,\n})\n\ndefineEmits<{\n preview: []\n save: []\n 'load-default': []\n undo: []\n redo: []\n align: [mode: string]\n 'move-layer': [direction: string]\n 'toggle-ruler': []\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 help: []\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: 100;\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-btn[data-tip] {\n position: relative;\n}\n.tb-btn[data-tip]::after {\n content: attr(data-tip);\n position: absolute;\n bottom: -32px;\n left: 50%;\n transform: translateX(-50%);\n padding: 4px 8px;\n font-size: 12px;\n color: #fff;\n background: rgba(30, 35, 48, .88);\n border-radius: 4px;\n white-space: nowrap;\n opacity: 0;\n pointer-events: none;\n transition: opacity .15s ease;\n z-index: 100;\n}\n.tb-btn[data-tip]:hover::after {\n opacity: 1;\n}\n.tb-btn:disabled[data-tip]::after {\n display: none;\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","// 标尺刻度纯函数:步长选择与可见范围刻度生成\n\n/** 视口固定尺条厚度(px),CanvasArea 布局与左上角块共用 */\nexport const RULER_THICKNESS = 22\n\nexport interface RulerTick {\n /** 刻度在纸面坐标系上的位置(mm,可为负,表示纸张原点之外) */\n mm: number\n /** 是否为主刻度(带数字标签) */\n major: boolean\n label?: string\n}\n\n/** 漂亮数步长序列:1/2/5 × 10^n,单位 mm */\nconst STEP_SEQUENCE = [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000] as const\n\n/**\n * 按缩放选择主刻度步长(mm):取漂亮数序列中使屏幕间距\n * 不小于 targetPx 的最小步长,保证任意缩放下标签不重叠\n * @param scale 画布缩放比例(1 = 100%)\n * @param targetPx 主刻度之间的目标屏幕间距(px)\n */\nexport function chooseMajorStepMM(scale: number, targetPx = 64): number {\n const pxPerMM = scale * (96 / 25.4)\n for (const step of STEP_SEQUENCE) {\n if (step * pxPerMM >= targetPx) return step\n }\n return STEP_SEQUENCE[STEP_SEQUENCE.length - 1]\n}\n\n/**\n * 次刻度步长:5 系(5/50/500…)五等分、2 系(2/20/200…)二等分、\n * 10 的幂从 10mm 起五等分(10→2mm、100→20mm),1mm 时无次刻度\n */\nexport function minorStepMM(majorStepMM: number): number | null {\n const exp = Math.floor(Math.log10(majorStepMM) + 1e-9)\n const base = majorStepMM / 10 ** exp // 归一化到 1 / 2 / 5\n if (base === 5 || (base === 1 && majorStepMM >= 10)) return majorStepMM / 5\n if (base === 2) return majorStepMM / 2\n return null\n}\n\n/** 消除浮点误差,保留到 0.001mm */\nfunction roundMM(mm: number): number {\n return Math.round(mm * 1000) / 1000\n}\n\n/**\n * 生成可见毫米范围内的全部刻度(升序):\n * 从首个对齐的次刻度开始,主刻度带数字标签\n * @param startMM 可见范围起点(纸面坐标,可为负)\n * @param endMM 可见范围终点\n * @param majorStepMM 主刻度步长(由 chooseMajorStepMM 选出)\n */\nexport function buildRulerTicks(\n startMM: number,\n endMM: number,\n majorStepMM: number,\n): RulerTick[] {\n if (endMM < startMM || majorStepMM <= 0) return []\n const minor = minorStepMM(majorStepMM)\n const fine = minor ?? majorStepMM\n const first = Math.ceil(startMM / fine - 1e-9) * fine\n const lastIndex = Math.floor((endMM - first) / fine + 1e-9)\n const ticks: RulerTick[] = []\n for (let i = 0; i <= lastIndex; i++) {\n const mm = roundMM(first + i * fine)\n const isMajor = Math.abs(mm / majorStepMM - Math.round(mm / majorStepMM)) < 1e-6\n if (isMajor) {\n ticks.push({ mm, major: true, label: String(mm) })\n } else {\n ticks.push({ mm, major: false })\n }\n }\n return ticks\n}\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","<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\" :style=\"svgStyle\"></svg>\n <img v-if=\"cellType === 'qrcode' && dataUrl\" :src=\"dataUrl\" alt=\"qrcode\" :style=\"imgStyle\" />\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, computed, 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 fit?: string\n maxWidth?: number\n maxHeight?: number\n}>()\n\nconst barcodeSvg = ref<SVGSVGElement | null>(null)\nconst svgOk = ref(false)\nconst dataUrl = ref('')\n\nconst svgStyle = computed(() => ({\n objectFit: (props.fit || 'contain') as any,\n maxWidth: props.maxWidth ? `${props.maxWidth}mm` : '100%',\n maxHeight: props.maxHeight ? `${props.maxHeight}mm` : '100%',\n}))\n\nconst imgStyle = computed(() => ({\n objectFit: (props.fit || 'contain') as any,\n maxWidth: props.maxWidth ? `${props.maxWidth}mm` : '100%',\n maxHeight: props.maxHeight ? `${props.maxHeight}mm` : '100%',\n}))\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","<!-- 表格单元格内图片渲染:设计态与预览态共用 -->\n<template>\n <div class=\"cell-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 { evaluateTemplate } from '../../utils/expression-eval'\nimport { DEFAULT_DEMO_DATA } from '../../utils/demo-data'\n\nconst props = defineProps<{\n value: string\n fit?: string\n maxWidth?: number\n maxHeight?: number\n designMode?: boolean\n data?: Record<string, any>[]\n}>()\n\nconst imageSrc = computed(() => {\n const raw = props.value || ''\n if (!raw) return ''\n \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 \n return raw\n})\n\n// 加载失败兜底\nconst hasError = ref(false)\nfunction onError() {\n hasError.value = true\n}\n\n// src 变化时重置错误态\nwatch(imageSrc, () => {\n hasError.value = false\n})\n\nconst imgStyle = computed(() => ({\n objectFit: (props.fit || 'contain') as any,\n maxWidth: props.maxWidth ? `${props.maxWidth}mm` : '100%',\n maxHeight: props.maxHeight ? `${props.maxHeight}mm` : '100%',\n}))\n</script>\n\n<style scoped>\n.cell-image {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n}\n.cell-image img {\n max-width: 100%;\n max-height: 100%;\n display: block;\n}\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>","<!-- 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 :fit=\"cell.fit\"\n :max-width=\"cell.maxWidth\"\n :max-height=\"cell.maxHeight\"\n />\n <CellImage\n v-else-if=\"cell.cellType === 'image'\"\n :value=\"cell.formatter || ''\"\n :fit=\"cell.fit\"\n :max-width=\"cell.maxWidth\"\n :max-height=\"cell.maxHeight\"\n :design-mode=\"designMode\"\n :data=\"imageData\"\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=\"colResizeEnabled\" class=\"col-resize-layer\">\n <div\n v-for=\"i in colResizeBoundaries\"\n :key=\"i\"\n class=\"col-resize-handle\"\n role=\"separator\"\n :aria-label=\"'列宽手柄' + i\"\n :class=\"{ dragging: colResizeBoundary === i }\"\n :style=\"{ left: colBoundaryLeftMm(i) + 'mm' }\"\n @mousedown.stop.prevent=\"onColResizeStart(i, $event)\"\n />\n </div>\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, onUnmounted, 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, clampResizedColumnWidth,\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 CellImage from './CellImage.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 /** 画布缩放倍率(用于列宽拖拽 px→mm 换算) */\n scale?: number\n /** 打印数据(用于运行态图片等动态内容) */\n data?: Record<string, any>[]\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\n// 添加图片数据处理\nconst imageData = computed(() => {\n // 运行态:使用打印数据\n if (props.data) {\n return props.data\n }\n // 设计态:使用 demo 数据\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\n// ─── 列宽拖拽 ───\n// 设计态选中且未锁定即渲染列边界手柄:1..n-1 为内部列边界(= 第 i 列右边缘),\n// 拖拽时调整其左侧第 i-1 列宽,使边界跟随光标移动;n 为最后一列右边界,\n// 拖拽时调整末列宽(右拖增宽、左拖缩窄)。拖拽期间实时回写列宽,\n// mouseup 时同步元素尺寸并记一次历史(与右键菜单结构操作一致)。\nconst colResizeEnabled = computed(\n () => props.designMode && !!props.isSelected && !props.element.options.locked && colWidths.value.length >= 1,\n)\n/** 列边界索引(1..n),n 为最后一列右边界 */\nconst colResizeBoundaries = computed<number[]>(() =>\n Array.from({ length: colWidths.value.length }, (_, k) => k + 1),\n)\n/** 边界 i 的水平位置(mm)= 前 i 列宽度和;i=n 时即表格右边界 */\nfunction colBoundaryLeftMm(i: number): number {\n return colWidths.value.slice(0, i).reduce((s, w) => s + w, 0)\n}\n\nconst colResizeBoundary = ref<number | null>(null)\nlet resizeStartX = 0\nlet resizeStartWidth = 0\n\n/** 拖拽边界 i:始终调整其左侧第 i-1 列(即第 i 列)宽 = startWidth + deltaMm,\n * 让边界线跟随光标移动。clampResizedColumnWidth 负责最小列宽与总宽上限钳制。 */\nfunction onColResizeStart(i: number, e: MouseEvent) {\n if (!colResizeEnabled.value) return\n colResizeBoundary.value = i\n resizeStartX = e.clientX\n resizeStartWidth = colWidths.value[i - 1]!\n document.addEventListener('mousemove', onColResizeMove)\n document.addEventListener('mouseup', onColResizeEnd)\n}\n\nfunction onColResizeMove(e: MouseEvent) {\n if (colResizeBoundary.value === null) return\n const scale = props.scale || 1\n // 鼠标位移 px → mm:画布 transform:scale(props.scale) 下 1mm ≈ PX_PER_MM*scale px\n const deltaMm = (e.clientX - resizeStartX) / (scale * PX_PER_MM)\n const colIndex = colResizeBoundary.value - 1\n const widths = props.element.options.tableColWidths!\n widths[colIndex] = clampResizedColumnWidth(\n widths, colIndex, resizeStartWidth + deltaMm, editCtx.maxTableWidth.value,\n )\n // 实时同步元素 width = 列宽和:避免 table-layout:fixed 下表格 CSS width(100%)\n // 与列宽和失配导致浏览器按比例拉伸列,进而使边界线与右侧内容偏离光标。\n syncElementSize()\n}\n\nfunction onColResizeEnd() {\n document.removeEventListener('mousemove', onColResizeMove)\n document.removeEventListener('mouseup', onColResizeEnd)\n if (colResizeBoundary.value === null) return\n colResizeBoundary.value = null\n syncElementSize()\n editCtx.recordHistory()\n}\n\nonUnmounted(() => {\n document.removeEventListener('mousemove', onColResizeMove)\n document.removeEventListener('mouseup', onColResizeEnd)\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.col-resize-layer {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 3;\n}\n.col-resize-handle {\n position: absolute;\n top: 0;\n bottom: 0;\n width: 6px;\n transform: translateX(-50%);\n cursor: col-resize;\n pointer-events: auto;\n}\n/* 手柄 hover/拖拽时显示主题色竖线,提示列边界位置 */\n.col-resize-handle::after {\n content: '';\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n border-left: 1px solid transparent;\n}\n.col-resize-handle:hover::after,\n.col-resize-handle.dragging::after {\n border-left-color: var(--pd-accent, #165DFF);\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>\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 { mmToPx } from '../../utils/units'\n\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 contentComponent = computed(() => componentMap[props.element.printElementType.type])\n\n/** 仅表格元素需要虚拟虚线开关,避免其它元素根节点出现无关 attribute */\nconst contentAttrs = computed(() =>\n props.element.printElementType.type === 'table'\n ? { showTableGhostBorder: props.showTableGhostBorder, scale: props.scale }\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) * mmToPx(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) * mmToPx(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.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","// 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=\"paper-wrapper\"\n :style=\"wrapperStyle\"\n >\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 <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', '--guide-hit': guideHitPx }\n : { top: g.position + 'mm', left: '0', width: paperWidthMM + 'mm', '--guide-hit': guideHitPx }\"\n @mousedown.prevent.stop=\"onGuideDown($event, g)\"\n @dblclick.prevent.stop=\"g.id && emit('guide-remove', g.id)\"\n />\n </div>\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 { mmToPx } from '../utils/units'\nimport BaseElement from './elements/BaseElement.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 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 '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/** 参考线交互热区:换算到缩放前坐标,保证任意缩放比例下屏幕热区恒定 */\nconst guideHitPx = computed(() => `${8 / (props.scale || 1)}px`)\n\n/** wrapper 尺寸:缩放后的实际像素尺寸,让滚动容器正确感知内容大小 */\nconst wrapperStyle = computed(() => {\n const s = props.scale || 1\n const widthPx = mmToPx(paperWidthMM.value) * s\n const heightPx = mmToPx(paperHeightMM.value) * s\n return {\n width: widthPx + 'px',\n height: heightPx + 'px',\n position: 'relative' as const,\n }\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 const maxPosition = g.type === 'vertical' ? paperWidthMM.value : paperHeightMM.value\n const nextPosition = Math.min(Math.max(startPt + delta, 0), maxPosition)\n emit('guide-move', g.id!, nextPosition)\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: props.templateData.pageBackground || '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 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 boxSizing: 'border-box' as const,\n minHeight: paperHeightMM.value + 'mm',\n }\n})\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/* wrapper:承载缩放后的实际尺寸,让滚动容器正确感知内容大小 */\n.paper-wrapper {\n /* 仅承载缩放后的布局尺寸(宽高 = 纸张尺寸 × scale,见 wrapperStyle)。\n 纸张固定以左上角为原点缩放(transform-origin: 0 0),wrapper 内不能再居中,\n 否则缩小时 flex 压缩布局宽度会使视觉宽度变为 W·s²、放大时纸张向右偏移;\n 水平居中统一由外层 .canvas-scroll 的 align-items: center 负责。 */\n display: block;\n}\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.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::before {\n content: '';\n position: absolute;\n pointer-events: auto;\n}\n.manual-guide.guide-vertical::before {\n top: 0;\n bottom: 0;\n left: 50%;\n width: var(--guide-hit, 8px);\n transform: translateX(-50%);\n}\n.manual-guide.guide-horizontal::before {\n left: 0;\n right: 0;\n top: 50%;\n height: var(--guide-hit, 8px);\n transform: translateY(-50%);\n}\n.manual-guide:hover { border-color: #EF4444 !important; }\n</style>\n","<!--\n 视口固定式标尺(单条)\n - 尺条固定在设计区边缘,不随纸张缩放/滚动;刻度随滚动平移、随缩放变密度\n - 横尺产生垂直参考线,竖尺产生水平参考线(与历史语义一致)\n - 在尺上按下并移动显示预览线,松开即生成参考线;主坐标超出尺长则取消\n-->\n<template>\n <canvas\n ref=\"canvasRef\"\n class=\"pd-ruler\"\n :class=\"`is-${orientation}`\"\n :style=\"cssSize\"\n @mousedown=\"onDown\"\n @mousemove=\"onHoverMove\"\n @mouseleave=\"onHoverLeave\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue'\nimport { mmToPx } from '../utils/units'\nimport {\n buildRulerTicks,\n chooseMajorStepMM,\n RULER_THICKNESS,\n} from '../utils/ruler'\n\nconst props = defineProps<{\n orientation: 'horizontal' | 'vertical'\n /** 尺条可见长度(屏幕 px,不随缩放变化) */\n viewportPx: number\n /** 纸张 0mm 点相对尺条起点的屏幕偏移(滚动时由父级实时更新) */\n originPx: number\n /** 纸张该方向长度(mm),用于边界标记与参考线落点限制 */\n paperLengthMM: number\n scale: number\n /** 鼠标在尺条轴向上的位置(屏幕 px),由画布 mousemove 转发 */\n cursorPx?: number | null\n}>()\n\nconst emit = defineEmits<{\n 'add-guide': [type: 'vertical' | 'horizontal', positionMm: number]\n /** 拖拽参考线过程中的虚线预览,null 表示隐藏 */\n 'guide-dragging': [mm: number | null]\n}>()\n\nconst horizontal = computed(() => props.orientation === 'horizontal')\n/** 横尺界定横向位置,产生的是垂直参考线 */\nconst guideType = computed<'vertical' | 'horizontal'>(() =>\n horizontal.value ? 'vertical' : 'horizontal',\n)\n\nconst canvasRef = ref<HTMLCanvasElement | null>(null)\n/** 鼠标悬停在尺条上的轴向位置(优先于外部传入的 cursorPx) */\nconst hoverPx = ref<number | null>(null)\nconst effectiveCursorPx = computed(() => hoverPx.value ?? props.cursorPx ?? null)\n\nconst cssSize = computed(() => {\n if (horizontal.value) {\n return { width: props.viewportPx + 'px', height: RULER_THICKNESS + 'px' }\n }\n return { width: RULER_THICKNESS + 'px', height: props.viewportPx + 'px' }\n})\n\nlet rafId = 0\nfunction scheduleDraw() {\n if (rafId) return\n rafId = requestAnimationFrame(() => {\n rafId = 0\n draw()\n })\n}\n\nfunction draw() {\n const canvas = canvasRef.value\n if (!canvas) return\n const ctx = canvas.getContext('2d')\n // happy-dom 等无 canvas 环境直接跳过绘制\n if (!ctx) return\n\n const dpr = window.devicePixelRatio || 1\n const length = Math.max(0, Math.round(props.viewportPx))\n const thickness = RULER_THICKNESS\n canvas.width = (horizontal.value ? length : thickness) * dpr\n canvas.height = (horizontal.value ? thickness : length) * dpr\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\n\n const style = getComputedStyle(canvas)\n const bg = style.getPropertyValue('--pd-ruler-bg').trim() || '#F8F9FC'\n const fg = style.getPropertyValue('--pd-ruler').trim() || '#9AA1AF'\n const accent = style.getPropertyValue('--pd-accent').trim() || '#165DFF'\n\n // 背景\n ctx.fillStyle = bg\n ctx.fillRect(0, 0, horizontal.value ? length : thickness, horizontal.value ? thickness : length)\n\n const s = props.scale > 0 ? props.scale : 1\n const pxPerMM = mmToPx(1) * s\n if (pxPerMM <= 0) return\n\n // 可见毫米范围(含纸张外区域)\n const startMM = -props.originPx / pxPerMM\n const endMM = (length - props.originPx) / pxPerMM\n const majorStep = chooseMajorStepMM(s)\n const ticks = buildRulerTicks(startMM, endMM, majorStep)\n\n // 纸外刻度淡化处理:先画纸外,再画纸内\n drawTicks(ctx, ticks, pxPerMM, fg, true)\n drawTicks(ctx, ticks, pxPerMM, fg, false)\n\n // 纸张 0 / 末端边界标记\n drawPaperEdge(ctx, 0, accent)\n drawPaperEdge(ctx, props.paperLengthMM, accent)\n\n // 鼠标位置指示线\n const cursor = effectiveCursorPx.value\n if (cursor !== null && cursor >= 0 && cursor <= length) {\n ctx.strokeStyle = accent\n ctx.lineWidth = 1.5\n ctx.beginPath()\n if (horizontal.value) {\n const x = Math.round(cursor) + 0.5\n ctx.moveTo(x, 0)\n ctx.lineTo(x, thickness)\n } else {\n const y = Math.round(cursor) + 0.5\n ctx.moveTo(0, y)\n ctx.lineTo(thickness, y)\n }\n ctx.stroke()\n }\n}\n\nfunction drawTicks(\n ctx: CanvasRenderingContext2D,\n ticks: ReturnType<typeof buildRulerTicks>,\n pxPerMM: number,\n fg: string,\n outside: boolean,\n) {\n const thickness = RULER_THICKNESS\n ctx.strokeStyle = fg\n ctx.fillStyle = fg\n ctx.globalAlpha = outside ? 0.32 : 1\n ctx.lineWidth = 1\n ctx.font = '9px ui-monospace, Menlo, monospace'\n ctx.textBaseline = 'top'\n\n for (const tick of ticks) {\n const isOutside = tick.mm < 0 || tick.mm > props.paperLengthMM\n if (isOutside !== outside) continue\n const pos = Math.round(props.originPx + tick.mm * pxPerMM) + 0.5\n const len = tick.major ? 8 : 4\n ctx.beginPath()\n if (horizontal.value) {\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.value) {\n ctx.fillText(tick.label, pos + 2, 11)\n } else {\n ctx.save()\n // 旋转 -90° 后,文字沿屏幕 +x 方向铺开(9px 字体约占 9px)。\n // x=11 时文字落在 11..20px,完整处于 22px 尺宽内,\n // 且与横尺标签(y=11)对称;此前 x=18 会延伸到 27px 被裁切。\n ctx.translate(11, pos + 2)\n ctx.rotate(-Math.PI / 2)\n ctx.fillText(tick.label, 0, 0)\n ctx.restore()\n }\n }\n }\n ctx.globalAlpha = 1\n}\n\nfunction drawPaperEdge(ctx: CanvasRenderingContext2D, mm: number, color: string) {\n const pxPerMM = mmToPx(1) * (props.scale > 0 ? props.scale : 1)\n const pos = Math.round(props.originPx + mm * pxPerMM) + 0.5\n if (pos <= 0 || pos >= props.viewportPx) return\n ctx.strokeStyle = color\n ctx.globalAlpha = 0.55\n ctx.lineWidth = 1\n ctx.beginPath()\n if (horizontal.value) {\n ctx.moveTo(pos, 0)\n ctx.lineTo(pos, RULER_THICKNESS)\n } else {\n ctx.moveTo(0, pos)\n ctx.lineTo(RULER_THICKNESS, pos)\n }\n ctx.stroke()\n ctx.globalAlpha = 1\n}\n\nwatch(\n () => [props.viewportPx, props.originPx, props.paperLengthMM, props.scale, props.cursorPx, props.orientation],\n scheduleDraw,\n)\nonMounted(scheduleDraw)\nonBeforeUnmount(() => { if (rafId) cancelAnimationFrame(rafId) })\n\n// ─── 拖出参考线 ───\nlet dragging = false\n\nfunction axialFromEvent(e: MouseEvent): number | null {\n const canvas = canvasRef.value\n if (!canvas) return null\n const rect = canvas.getBoundingClientRect()\n const along = horizontal.value ? e.clientX - rect.left : e.clientY - rect.top\n // 主坐标超出尺条长度(含两端)即视为取消;横向/纵向另一方向不限制,允许拖入纸面\n if (along < 0 || along > props.viewportPx) return null\n const pxPerMM = mmToPx(1) * (props.scale > 0 ? props.scale : 1)\n return (along - props.originPx) / pxPerMM\n}\n\nfunction onDown(e: MouseEvent) {\n dragging = true\n e.preventDefault()\n window.addEventListener('mousemove', onWinMove)\n window.addEventListener('mouseup', onWinUp)\n updateDragPreview(e)\n}\n\nfunction onHoverMove(e: MouseEvent) {\n const canvas = canvasRef.value\n if (!canvas) return\n const rect = canvas.getBoundingClientRect()\n hoverPx.value = horizontal.value ? e.clientX - rect.left : e.clientY - rect.top\n scheduleDraw()\n}\n\nfunction onHoverLeave() {\n hoverPx.value = null\n scheduleDraw()\n}\n\nfunction updateDragPreview(e: MouseEvent) {\n const mm = axialFromEvent(e)\n emit('guide-dragging', mm)\n}\n\nfunction onWinMove(e: MouseEvent) {\n if (!dragging) return\n updateDragPreview(e)\n}\n\nfunction onWinUp(e: MouseEvent) {\n if (!dragging) return\n dragging = false\n window.removeEventListener('mousemove', onWinMove)\n window.removeEventListener('mouseup', onWinUp)\n const mm = axialFromEvent(e)\n if (mm !== null && mm >= 0 && mm <= props.paperLengthMM) {\n emit('add-guide', guideType.value, mm)\n }\n emit('guide-dragging', null)\n}\n\nonBeforeUnmount(() => {\n window.removeEventListener('mousemove', onWinMove)\n window.removeEventListener('mouseup', onWinUp)\n})\n</script>\n\n<style scoped>\n.pd-ruler {\n position: absolute;\n display: block;\n pointer-events: auto;\n cursor: crosshair;\n z-index: 1;\n background: var(--pd-ruler-bg, #f8f9fc);\n}\n.pd-ruler.is-horizontal {\n box-shadow: 0 1px 0 var(--pd-border-soft, #e9ecf2);\n}\n.pd-ruler.is-vertical {\n box-shadow: 1px 0 0 var(--pd-border-soft, #e9ecf2);\n}\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 @scroll=\"onScroll\"\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 @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 v-if=\"showRuler\" class=\"ruler-overlay\" :style=\"overlayStyle\">\n <div class=\"ruler-corner\" />\n <Ruler\n orientation=\"horizontal\"\n :viewport-px=\"rulerGeom.viewW\"\n :origin-px=\"rulerGeom.originX\"\n :paper-length-m-m=\"paperWidthMM\"\n :scale=\"rulerGeom.paperScale\"\n :cursor-px=\"rulerCursor.x\"\n @add-guide=\"(t: 'vertical' | 'horizontal', p: number) => emit('add-guide', t, p)\"\n @guide-dragging=\"(mm: number | null) => onGuideDragging('vertical', mm)\"\n />\n <Ruler\n orientation=\"vertical\"\n :viewport-px=\"rulerGeom.viewH\"\n :origin-px=\"rulerGeom.originY\"\n :paper-length-m-m=\"paperHeightMM\"\n :scale=\"rulerGeom.paperScale\"\n :cursor-px=\"rulerCursor.y\"\n @add-guide=\"(t: 'vertical' | 'horizontal', p: number) => emit('add-guide', t, p)\"\n @guide-dragging=\"(mm: number | null) => onGuideDragging('horizontal', mm)\"\n />\n </div>\n <!-- 从标尺拖出参考线时的预览虚线(fixed 定位,不能放进带 transform 的 overlay) -->\n <div\n v-if=\"guidePreview\"\n class=\"ruler-guide-preview\"\n :class=\"`guide-${guidePreview.type}`\"\n :style=\"guidePreviewStyle\"\n />\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, computed, watch, nextTick, onMounted, onBeforeUnmount } from 'vue'\nimport type { RuntimeElement, TemplateData, AlignLine } from '../types'\nimport { pxToMm, mmToPx } from '../utils/units'\nimport { nextWheelScale, FIT_SCALE_MIN_PERCENT } from '../utils/scale'\nimport { getPaperDimensions } from '../utils/default-config'\nimport { RULER_THICKNESS } from '../utils/ruler'\nimport CanvasPaper from './CanvasPaper.vue'\nimport Ruler from './Ruler.vue'\n\nconst props = withDefaults(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 showRuler?: boolean\n}>(), {\n showRuler: true,\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// ─── 视口固定标尺:纸张几何测量与滚动/缩放同步 ───\nconst paperWidthMM = computed(() => getPaperDimensions(props.templateData).width)\nconst paperHeightMM = computed(() => getPaperDimensions(props.templateData).height)\n\n/** 纸张原点相对各尺条起点的屏幕偏移 + 尺条可见长度 */\nconst rulerGeom = reactive({ originX: 0, originY: 0, viewW: 0, viewH: 0, paperScale: 1 })\n/** 鼠标相对各尺条起点的屏幕位置,驱动尺上指示线 */\nconst rulerCursor = reactive<{ x: number | null; y: number | null }>({ x: null, y: null })\n/** 滚动偏移:绝对定位的标尺层会随滚动内容移动,用同向 transform 补偿以保持视口固定 */\nconst scrollPos = reactive({ x: 0, y: 0 })\nconst overlayStyle = computed(() => ({\n transform: `translate(${scrollPos.x}px, ${scrollPos.y}px)`,\n}))\n\nfunction measureRuler() {\n const area = rootRef.value\n // 读取纸张本体而非 wrapper:缩放时 wrapper 尺寸立即变为目标值,\n // 纸张本体有 150ms transform 过渡,标尺需要跟随实时视觉位置与比例。\n const paper = area?.querySelector('.hiprint-printPaper') as HTMLElement | null\n if (!area || !paper) return\n const ar = area.getBoundingClientRect()\n const pr = paper.getBoundingClientRect()\n const targetScale = props.scale || 1\n const measuredScale = pr.width / mmToPx(paperWidthMM.value)\n // 过渡终点附近消除子像素误差,静止时保持与业务 scale 完全一致\n rulerGeom.paperScale = Math.abs(measuredScale - targetScale) < 0.002\n ? targetScale\n : measuredScale\n rulerGeom.originX = pr.left - ar.left - RULER_THICKNESS\n rulerGeom.originY = pr.top - ar.top - RULER_THICKNESS\n rulerGeom.viewW = area.clientWidth - RULER_THICKNESS\n rulerGeom.viewH = area.clientHeight - RULER_THICKNESS\n}\n\nfunction onScroll() {\n scrollPos.x = rootRef.value?.scrollLeft ?? 0\n scrollPos.y = rootRef.value?.scrollTop ?? 0\n measureRuler()\n}\n\nlet resizeObserver: ResizeObserver | null = null\n/** 缩放切换后纸张有 150ms CSS 过渡,期间持续重测,刻度才不会跳变 */\nlet scaleMeasureRaf = 0\nfunction startScaleMeasureLoop() {\n cancelAnimationFrame(scaleMeasureRaf)\n const endAt = performance.now() + 220\n const loop = () => {\n measureRuler()\n if (performance.now() < endAt) scaleMeasureRaf = requestAnimationFrame(loop)\n }\n scaleMeasureRaf = requestAnimationFrame(loop)\n}\n\n/** 从标尺拖出参考线的预览态(纸面 mm 坐标) */\nconst guidePreview = ref<{ type: 'vertical' | 'horizontal'; mm: number } | null>(null)\nfunction onGuideDragging(type: 'vertical' | 'horizontal', mm: number | null) {\n guidePreview.value = mm === null ? null : { type, mm }\n}\nconst guidePreviewStyle = computed(() => {\n const g = guidePreview.value\n const paper = rootRef.value?.querySelector('.hiprint-printPaper') as HTMLElement | null\n if (!g || !paper) return {}\n // position: fixed,直接采用视口坐标(与框选选框一致)\n const pr = paper.getBoundingClientRect()\n const liveScale = pr.width / mmToPx(paperWidthMM.value)\n const along = mmToPx(g.mm) * (liveScale > 0 ? liveScale : (props.scale || 1))\n if (g.type === 'vertical') {\n return { left: pr.left + along + 'px', top: pr.top + 'px', height: pr.height + 'px' }\n }\n return { left: pr.left + 'px', top: pr.top + along + 'px', width: pr.width + 'px' }\n})\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 area = rootRef.value\n const paper = area?.querySelector('.hiprint-printPaper') as HTMLElement | null\n if (!area || !paper) return\n const areaRect = area.getBoundingClientRect()\n rulerCursor.x = e.clientX - areaRect.left - RULER_THICKNESS\n rulerCursor.y = e.clientY - areaRect.top - RULER_THICKNESS\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() {\n emit('coordinate', null)\n rulerCursor.x = null\n rulerCursor.y = null\n}\n\n/** Ctrl/Cmd+滚轮缩放:以鼠标位置为缩放中心,缩放前后保持鼠标下的内容点不动 */\nfunction onWheel(e: WheelEvent) {\n if (!(e.ctrlKey || e.metaKey)) return\n e.preventDefault()\n // props.scale 为小数;统一在百分比整数域做乘性步进,\n // 取消放大上限,同时避免浮点累加产生脏显示\n const oldScale = props.scale || 1\n const oldPercent = Math.round(oldScale * 100)\n const newPercent = nextWheelScale(oldPercent, e.deltaY > 0 ? -1 : 1)\n if (newPercent === oldPercent) return\n const newScale = newPercent / 100\n\n const container = rootRef.value\n // 记录鼠标下的内容点(相对滚动内容原点)。容器存在非对称 padding,\n // 换算时必须扣除,否则每次缩放锚点会漂移 pad*(ratio-1)\n let anchor: { x: number; y: number; ratio: number; mouseX: number; mouseY: number } | null = null\n if (container) {\n const rect = container.getBoundingClientRect()\n const cs = getComputedStyle(container)\n const padX = parseFloat(cs.paddingLeft) || 0\n const padY = parseFloat(cs.paddingTop) || 0\n anchor = {\n x: container.scrollLeft + (e.clientX - rect.left) - padX,\n y: container.scrollTop + (e.clientY - rect.top) - padY,\n ratio: newScale / oldScale,\n mouseX: e.clientX - rect.left,\n mouseY: e.clientY - rect.top,\n }\n }\n\n // 以百分比整数增量上报(父级 scale 为百分比)\n emit('zoom', newPercent - oldPercent)\n\n // 待新比例应用到 DOM 后再校正滚动位置:缩放前若该方向没有滚动条,\n // 提前写入 scrollTop/Left 会被浏览器钳制为 0,导致锚点失效\n if (container && anchor) {\n const a = anchor\n void nextTick(() => {\n const cs = getComputedStyle(container)\n const padX = parseFloat(cs.paddingLeft) || 0\n const padY = parseFloat(cs.paddingTop) || 0\n container.scrollLeft = a.x * a.ratio - a.mouseX + padX\n container.scrollTop = a.y * a.ratio - a.mouseY + padY\n })\n }\n}\n\n// ─── 适应窗口:一步到位(调用方已算好目标比例),以视口中心为锚点,\n// 与 Ctrl+滚轮同一管线;平滑动画由纸张 150ms transform 过渡自然产生 ───\nfunction fitToWindow(targetPercent: number) {\n const container = rootRef.value\n if (!container) return\n const target = Math.max(FIT_SCALE_MIN_PERCENT, Math.round(targetPercent))\n const cur = Math.round((props.scale || 1) * 100)\n if (target === cur) return\n\n // 锚点取视口几何中心(相对内容原点,扣除容器 padding),与 onWheel 换算一致\n const oldScale = props.scale || 1\n const newScale = target / 100\n const ratio = newScale / oldScale\n const cs = getComputedStyle(container)\n const padX = parseFloat(cs.paddingLeft) || 0\n const padY = parseFloat(cs.paddingTop) || 0\n const mouseX = container.clientWidth / 2\n const mouseY = container.clientHeight / 2\n const ax = container.scrollLeft + mouseX - padX\n const ay = container.scrollTop + mouseY - padY\n\n emit('zoom', target - cur)\n void nextTick(() => {\n const cs2 = getComputedStyle(container)\n const padX2 = parseFloat(cs2.paddingLeft) || 0\n const padY2 = parseFloat(cs2.paddingTop) || 0\n container.scrollLeft = ax * ratio - mouseX + padX2\n container.scrollTop = ay * ratio - mouseY + padY2\n })\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\nonMounted(() => {\n nextTick(measureRuler)\n if (rootRef.value && typeof ResizeObserver !== 'undefined') {\n resizeObserver = new ResizeObserver(measureRuler)\n resizeObserver.observe(rootRef.value)\n }\n})\n\nwatch(() => props.scale, startScaleMeasureLoop)\nwatch([paperWidthMM, paperHeightMM], () => nextTick(measureRuler))\n\n/** 适应窗口后将滚动位置归中。\n * 纸张有 150ms CSS transform 过渡,期间 scrollWidth/Height 持续变化,\n * 用多帧检测数值稳定后再设置居中,避免固定 setTimeout 落在过渡中间。 */\nfunction centerScroll() {\n const container = rootRef.value\n if (!container) return\n let stableFrames = 0\n let prevSW = 0, prevSH = 0\n const deadline = performance.now() + 800\n const loop = () => {\n const { scrollWidth: sw, scrollHeight: sh } = container\n if (sw === prevSW && sh === prevSH) {\n stableFrames++\n } else {\n stableFrames = 0\n }\n prevSW = sw; prevSH = sh\n if (stableFrames >= 2 || performance.now() > deadline) {\n const sw2 = container.scrollWidth, sh2 = container.scrollHeight\n const cw = container.clientWidth, ch = container.clientHeight\n container.scrollLeft = Math.max(0, (sw2 - cw) / 2)\n container.scrollTop = Math.max(0, (sh2 - ch) / 2)\n return\n }\n requestAnimationFrame(loop)\n }\n requestAnimationFrame(loop)\n}\n\ndefineExpose({ centerScroll, fitToWindow })\n\nonBeforeUnmount(() => {\n window.removeEventListener('mousemove', onMarqueeMove)\n window.removeEventListener('mouseup', onMarqueeUp)\n resizeObserver?.disconnect()\n cancelAnimationFrame(scaleMeasureRaf)\n})\n</script>\n\n<style scoped>\n.canvas-area {\n flex: 1;\n overflow: auto;\n /* flex + margin:auto:纸张在可视区内水平/垂直居中;内容超出容器时\n margin auto 自动退化为起点对齐,滚动条仍可达纸张两端 */\n display: flex;\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 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 /* 禁 dock 到容器的收缩,部件宽高始终以纸张真实尺寸为准 */\n flex: none;\n margin: auto;\n width: fit-content;\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\n/* ─── 视口固定标尺 ─── */\n.ruler-overlay {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 60;\n}\n.ruler-corner {\n position: absolute;\n top: 0;\n left: 0;\n width: 22px;\n height: 22px;\n background: var(--pd-ruler-bg, #f8f9fc);\n box-shadow: 1px 1px 0 var(--pd-border-soft, #e9ecf2);\n z-index: 2;\n}\n.ruler-overlay :deep(.pd-ruler.is-horizontal) {\n top: 0;\n left: 22px;\n}\n.ruler-overlay :deep(.pd-ruler.is-vertical) {\n top: 22px;\n left: 0;\n}\n/* 拖出参考线的预览虚线 */\n.ruler-guide-preview {\n position: fixed;\n pointer-events: none;\n z-index: 9997;\n}\n.ruler-guide-preview.guide-vertical {\n width: 0;\n border-left: 1px dashed var(--pd-accent, #165dff);\n}\n.ruler-guide-preview.guide-horizontal {\n height: 0;\n border-top: 1px dashed var(--pd-accent, #165dff);\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 <div class=\"pd-stepper\">\n <button\n type=\"button\"\n class=\"pd-step-btn pd-step-minus\"\n :disabled=\"atMin\"\n title=\"减小\"\n aria-label=\"减小\"\n @click=\"stepBy(-1)\"\n >−</button>\n <input\n type=\"number\"\n class=\"pd-input pd-step-input\"\n :value=\"draft\"\n :placeholder=\"placeholder\"\n :min=\"min\"\n :max=\"max\"\n :step=\"step\"\n @input=\"onInput\"\n @change=\"commit\"\n @blur=\"commit\"\n @keydown.enter.prevent=\"($event.target as HTMLInputElement).blur()\"\n />\n <button\n type=\"button\"\n class=\"pd-step-btn pd-step-plus\"\n :disabled=\"atMax\"\n title=\"增大\"\n aria-label=\"增大\"\n @click=\"stepBy(1)\"\n >+</button>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\n\nconst props = withDefaults(defineProps<{\n /** 数值;undefined 表示未设置(继承默认),输入框显示空占位 */\n modelValue?: number\n min?: number\n max?: number\n /** 步进单位,默认 1(整数);小数步进时按小数位数保留精度 */\n step?: number\n /** 未设置(继承默认)时输入框的占位提示 */\n placeholder?: string\n}>(), {\n step: 1,\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: number | undefined]\n}>()\n\n/** 步进小数位数:由 step 推导(0.5→1 位,0.25→2 位,0.1→1 位,1→0 位) */\nconst precision = computed(() => {\n const s = String(props.step)\n const dot = s.indexOf('.')\n return dot === -1 ? 0 : s.length - dot - 1\n})\n\n/** 按 step 精度取整,规避浮点误差(0.30000000000000004 → 0.3) */\nfunction roundTo(v: number): number {\n if (!Number.isFinite(v)) return 0\n return Number(v.toFixed(precision.value))\n}\n\n/** 当前有效值:undefined 表示未设置(继承默认) */\nconst current = computed<number | undefined>(() => {\n const v = props.modelValue\n if (v === undefined || v === null || !Number.isFinite(v)) return undefined\n return roundTo(v)\n})\n\n/** 输入框草稿:输入过程中保留原文,失焦/回车后按精度规范化 */\nconst draft = ref(current.value === undefined ? '' : String(current.value))\nwatch(current, (v) => {\n draft.value = v === undefined ? '' : String(v)\n})\n\n/** 步进基准:未设置时从 min(无 min 则为 0)起步 */\nconst base = computed(() => {\n if (current.value !== undefined) return current.value\n return props.min !== undefined ? props.min : 0\n})\n\nconst atMin = computed(() => props.min !== undefined && base.value <= props.min)\nconst atMax = computed(() => props.max !== undefined && base.value >= props.max)\n\n/** 夹取到 [min, max],并按 step 精度取整 */\nfunction clamp(v: number): number {\n let next = roundTo(v)\n if (props.min !== undefined && next < props.min) next = props.min\n if (props.max !== undefined && next > props.max) next = props.max\n return next\n}\n\nfunction stepBy(dir: 1 | -1) {\n if ((dir < 0 && atMin.value) || (dir > 0 && atMax.value)) return\n const next = clamp(base.value + dir * props.step)\n draft.value = String(next)\n emit('update:modelValue', next)\n}\n\nfunction onInput(e: Event) {\n draft.value = (e.target as HTMLInputElement).value\n}\n\n/** 失焦/回车提交:解析草稿并按精度取整;空值回退为当前值(未设置则保持未设置) */\nfunction commit() {\n const raw = draft.value.trim()\n if (raw === '') {\n if (current.value !== undefined) {\n draft.value = String(current.value)\n }\n return\n }\n const num = Number(raw)\n if (!Number.isFinite(num)) {\n draft.value = current.value === undefined ? '' : String(current.value)\n return\n }\n const next = clamp(num)\n draft.value = String(next)\n // change 与 blur 会先后触发,仅当值真正变化时 emit,避免重复提交\n if (next !== current.value) {\n emit('update:modelValue', next)\n }\n}\n</script>\n\n<style scoped>\n.pd-stepper {\n display: flex;\n align-items: center;\n width: 100%;\n}\n.pd-step-btn {\n width: 26px;\n height: 26px;\n flex-shrink: 0;\n border: 1px solid var(--pd-border, #d9dde6);\n background: var(--pd-field-bg, #f4f6fa);\n color: var(--pd-text, #2a2e37);\n font-size: 14px;\n line-height: 1;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background .14s ease, border-color .14s ease, color .14s ease;\n}\n.pd-step-btn:hover:not(:disabled) {\n background: var(--pd-sidebar-hover, #f0f3f9);\n border-color: var(--pd-text-faint, #b4b9c4);\n}\n.pd-step-btn:disabled {\n opacity: 0.45;\n cursor: not-allowed;\n}\n.pd-step-minus {\n border-radius: 6px 0 0 6px;\n border-right: none;\n}\n.pd-step-plus {\n border-radius: 0 6px 6px 0;\n border-left: none;\n}\n.pd-step-input.pd-input {\n border-radius: 0;\n min-width: 0;\n flex: 1;\n text-align: center;\n -moz-appearance: textfield;\n}\n.pd-step-input.pd-input::-webkit-outer-spin-button,\n.pd-step-input.pd-input::-webkit-inner-spin-button {\n -webkit-appearance: none;\n margin: 0;\n}\n</style>\n","<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 <StepperInput v-model=\"element.options.left\"\n :min=\"0\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ps-top')\"><span class=\"pd-label\">Y</span>\n <StepperInput v-model=\"element.options.top\"\n :min=\"0\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ps-width')\"><span class=\"pd-label\">W</span>\n <StepperInput v-model=\"element.options.width\"\n :min=\"4\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ps-height')\"><span class=\"pd-label\">H</span>\n <StepperInput v-model=\"element.options.height\"\n :min=\"4\" />\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'\nimport StepperInput from './StepperInput.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 <StepperInput v-model=\"element.options.fontSize\"\n :min=\"8\"\n :max=\"72\" />\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 <StepperInput v-model=\"element.options.lineHeight\"\n :min=\"0\"\n :max=\"100\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ap-letter-spacing')\"><span class=\"pd-label\">字间距</span>\n <StepperInput v-model=\"element.options.letterSpacing\"\n :min=\"0\"\n :max=\"20\"\n :step=\"0.5\" />\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'\nimport StepperInput from './StepperInput.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 <div class=\"ee-field-info\">\n <span class=\"ee-item-label\">{{ field.fieldLabel }}</span>\n <span class=\"ee-item-key\">{{ field.fieldKey }}</span>\n </div>\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=\"handleVariableDoubleClick(sv)\"\n >\n <div class=\"ee-field-info\">\n <span class=\"ee-item-label\">{{ sv.label }}</span>\n <span class=\"ee-item-key\">{{ sv.template }}</span>\n </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=\"handleFunctionDoubleClick(fn)\"\n >\n <div class=\"ee-field-info\">\n <span class=\"ee-item-label\">{{ fn.label }}</span>\n <span class=\"ee-item-key\">{{ fn.name }}()</span>\n </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=\"handleFunctionDoubleClick(fn)\"\n >\n <div class=\"ee-field-info\">\n <span class=\"ee-item-label\">{{ fn.label }}</span>\n <span class=\"ee-item-key\">{{ fn.name }}()</span>\n </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=\"双击左侧字段/变量/函数插入,或直接输入静态内容\"\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 静态数据直接输入即可,如:供应商名称<br>\n 动态解析字段、变量、函数必须用 {} 包裹<br>\n 示例:{SUM(supplier.name)}<br>\n 注意:只能嵌套一层\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(字段) - 计数<br>\n IF(条件, 真值, 假值) - 条件判断\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 {pageIndex} - 当前页码<br>\n {totalPages} - 总页数<br>\n {printDate} - 打印日期\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 静态文本:供应商名称<br>\n 动态字段:{supplier.name}<br>\n 函数调用:{SUM(amount)}<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// 当弹出框打开时,重置为外部传入值\nwatch(visible, (val) => {\n if (val) {\n localExpression.value = props.expression || ''\n }\n})\n\n// 字段双击:函数参数内插入裸字段(去大括号),其余场景保持 {字段} 包裹\nfunction handleFieldDoubleClick(field: PrintBusinessField) {\n const { insideParens } = getCursorRegion()\n insertAtCursor(insideParens ? field.fieldKey : `{${field.fieldKey}}`)\n}\n\n// 变量双击:函数参数内去大括号,其余场景保持 {变量} 原样\nfunction handleVariableDoubleClick(sv: { name: string; template: string }) {\n const { insideParens } = getCursorRegion()\n insertAtCursor(insideParens ? sv.template.replace(/^\\{|\\}$/g, '') : sv.template)\n}\n\n// 函数双击:已在 {…} 块内则裸插入,否则自动包裹大括号;光标定位到 () 内部\nfunction handleFunctionDoubleClick(fn: { name: string; template: string }) {\n const { insideBlock } = getCursorRegion()\n const text = insideBlock ? fn.template : `{${fn.template}}`\n const caretOffset = text.indexOf('(') + 1\n insertAtCursor(text, caretOffset)\n}\n\n// 根据光标位置判断插入上下文:是否在 {…} 表达式块内、是否在函数参数 (…) 内\nfunction getCursorRegion(): { insideBlock: boolean; insideParens: boolean } {\n const ta = textareaRef.value\n const start = ta?.selectionStart ?? localExpression.value.length\n const before = localExpression.value.substring(0, start)\n\n // 光标前最近的 { 未被 } 闭合 → 在表达式块内\n let insideBlock = false\n const lastBlockOpen = before.lastIndexOf('{')\n if (lastBlockOpen !== -1 && !before.slice(lastBlockOpen + 1).includes('}')) {\n insideBlock = true\n }\n\n // 光标前最近的 ( 未被 ) 闭合 → 在函数参数内\n let insideParens = false\n const lastParenOpen = before.lastIndexOf('(')\n if (lastParenOpen !== -1 && !before.slice(lastParenOpen + 1).includes(')')) {\n insideParens = true\n }\n\n return { insideBlock, insideParens }\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, caretOffset = text.length) {\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 const caretPos = start + caretOffset\n nextTick(() => {\n ta.focus()\n ta.selectionStart = ta.selectionEnd = caretPos\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: 6px 10px;\n margin-bottom: 2px;\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: 7px 10px;\n cursor: pointer;\n border-radius: 4px;\n margin-bottom: 2px;\n transition: background 0.15s;\n}\n.ee-field-info {\n display: flex;\n flex-direction: column;\n gap: 1px;\n}\n.ee-field-info .ee-item-label {\n font-size: 12px;\n color: var(--pd-text);\n}\n.ee-field-info .ee-item-key {\n font-size: 10px;\n color: var(--pd-text-muted);\n font-family: monospace;\n}\n\n.ee-list-item:hover {\n background: #ecf5ff;\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 <StepperInput v-model=\"element.options.tableDefaultFontSize\" :min=\"5\" :max=\"72\" placeholder=\"默认\" />\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 <StepperInput v-model=\"element.options.tableDefaultPadding\" :min=\"0\" :max=\"10\" :step=\"0.5\" placeholder=\"默认\" />\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 <StepperInput :model-value=\"w\" :min=\"5\" :max=\"200\" @update:model-value=\"onColWidthChange(i, $event)\" />\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'\nimport StepperInput from './StepperInput.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 <StepperInput v-model=\"element.options.borderWidth\"\n :min=\"0\"\n :max=\"20\"\n :step=\"0.25\" />\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'\nimport StepperInput from './StepperInput.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: 10px;\n}\n.border-row .pd-field {\n flex: 1;\n min-width: 0;\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 <StepperInput v-model=\"element.options.zIndex\"\n :min=\"0\"\n :max=\"999\" />\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'\nimport StepperInput from './StepperInput.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 <StepperInput :model-value=\"row.height\"\n :min=\"3\"\n :max=\"100\"\n :step=\"0.5\" @update:model-value=\"onHeightChange\" />\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'\nimport StepperInput from './StepperInput.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 <label class=\"pd-radio\"><input type=\"radio\" value=\"image\" :checked=\"mainCell.cellType === 'image'\" @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\" v-if=\"isBarcodeCell || isQrcodeCell || isImageCell\"><span class=\"pd-label\">缩放模式</span>\n <select :value=\"mainCell.fit || 'contain'\" class=\"pd-select\" @change=\"write(c => { c.fit = ($event.target as HTMLSelectElement).value as any })\">\n <option value=\"contain\">包含(保持比例)</option>\n <option value=\"cover\">覆盖(保持比例)</option>\n <option value=\"fill\">拉伸填满</option>\n <option value=\"none\">原始尺寸</option>\n <option value=\"scale-down\">缩小(保持比例)</option>\n </select>\n </div>\n <div class=\"pd-field\" v-if=\"isBarcodeCell || isQrcodeCell || isImageCell\"><span class=\"pd-label\">最大宽度 (mm)</span>\n <StepperInput :model-value=\"mainCell.maxWidth\"\n :min=\"1\"\n :max=\"200\"\n placeholder=\"默认\" @update:model-value=\"write(c => { c.maxWidth = $event ?? undefined })\" />\n </div>\n <div class=\"pd-field\" v-if=\"isBarcodeCell || isQrcodeCell || isImageCell\"><span class=\"pd-label\">最大高度 (mm)</span>\n <StepperInput :model-value=\"mainCell.maxHeight\"\n :min=\"1\"\n :max=\"200\"\n placeholder=\"默认\" @update:model-value=\"write(c => { c.maxHeight = $event ?? undefined })\" />\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 <StepperInput :model-value=\"mainCell.fontSize\"\n :min=\"5\"\n :max=\"72\"\n placeholder=\"默认\" @update:model-value=\"write(c => { c.fontSize = $event ?? 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 <div style=\"width: 112px; flex-shrink: 0\"><StepperInput v-model=\"borderWidth\"\n :min=\"0.25\"\n :max=\"5\"\n :step=\"0.25\" /></div>\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 <StepperInput :model-value=\"mainCell.padding\"\n :min=\"0\"\n :max=\"10\"\n :step=\"0.5\"\n placeholder=\"默认\" @update:model-value=\"write(c => { c.padding = $event ?? 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 StepperInput from './StepperInput.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')\nconst isImageCell = computed(() => mainCell.value.cellType === 'image')\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 // fit、maxWidth、maxHeight 对所有类型都有效,不再清除\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 <StepperInput :model-value=\"customWidth\"\n :min=\"25\"\n :max=\"2000\"\n @update:model-value=\"onCustomWidthChange\" />\n <span class=\"custom-size-x\">×</span>\n <StepperInput :model-value=\"customHeight\"\n :min=\"25\"\n :max=\"2000\"\n @update:model-value=\"onCustomHeightChange\" />\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 <div class=\"pd-field\"><span class=\"pd-label\">页面背景色</span>\n <div class=\"page-bg-row\">\n <PresetColorPicker v-model=\"pageBackgroundModel\" class=\"page-bg-picker\" />\n <button type=\"button\" class=\"pd-reset\" title=\"恢复为默认白色\" @click=\"onPageBackgroundReset\">默认</button>\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 <StepperInput :model-value=\"marginTop\" :min=\"0\" :max=\"50\" @update:model-value=\"onMarginTopChange\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">下</span>\n <StepperInput :model-value=\"marginBottom\" :min=\"0\" :max=\"50\" @update:model-value=\"onMarginBottomChange\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">左</span>\n <StepperInput :model-value=\"marginLeft\" :min=\"0\" :max=\"50\" @update:model-value=\"onMarginLeftChange\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">右</span>\n <StepperInput :model-value=\"marginRight\" :min=\"0\" :max=\"50\" @update:model-value=\"onMarginRightChange\" />\n </div>\n </div>\n\n <h3 class=\"pd-divider\">三区高度 (mm)</h3>\n <div class=\"pd-field\"><span class=\"pd-label\">页眉高度</span>\n <StepperInput :model-value=\"headerHeight\" :min=\"0\" :max=\"100\" :step=\"0.1\" @update:model-value=\"onHeaderHeightChange\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">页脚高度</span>\n <StepperInput :model-value=\"footerHeight\" :min=\"0\" :max=\"100\" :step=\"0.1\" @update:model-value=\"onFooterHeightChange\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">首页叠加高度</span>\n <StepperInput :model-value=\"overlayHeight\" :min=\"0\" :max=\"200\" @update:model-value=\"onOverlayHeightChange\" />\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 StepperInput from './property/StepperInput.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 PresetColorPicker from './PresetColorPicker.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 pageBackgroundModel = computed({\n get: () => props.templateData?.pageBackground || '#ffffff',\n set: (v: string) => onPageBackgroundChange(v),\n})\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 onPageBackgroundChange(v: string) {\n const value = v && v.toLowerCase() !== '#ffffff' && v.toLowerCase() !== '#fff' ? v : undefined\n emitUpdate(value === undefined ? { pageBackground: undefined } : { pageBackground: value })\n}\n\nfunction onPageBackgroundReset() {\n emitUpdate({ pageBackground: undefined })\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.page-bg-row {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.page-bg-picker {\n flex: 1;\n min-width: 0;\n}\n.pd-reset {\n height: 26px;\n padding: 0 8px;\n border: 1px solid var(--pd-border, #d9dde6);\n border-radius: 5px;\n background: var(--pd-field-bg, #f4f6fa);\n color: var(--pd-text-muted, #8b909c);\n font-size: 12px;\n cursor: pointer;\n flex-shrink: 0;\n transition: all .14s ease;\n}\n.pd-reset:hover {\n color: var(--pd-accent, #165DFF);\n border-color: var(--pd-accent, #165DFF);\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","export default {\n id: 'getting-started',\n title: '快速入门',\n content: `\n<h2>界面布局</h2>\n<p>打印模板设计器采用三栏布局:</p>\n<ul>\n <li><strong>左侧面板</strong>:字段树和图层管理,用于查看和管理画布上的元素</li>\n <li><strong>中间画布</strong>:设计区域,支持标尺、参考线、网格显示</li>\n <li><strong>右侧面板</strong>:属性设置和模板配置</li>\n <li><strong>顶部工具栏</strong>:常用操作按钮</li>\n <li><strong>底部状态栏</strong>:显示坐标、缩放比例、元素数量</li>\n</ul>\n\n<h2>添加第一个元素</h2>\n<ol>\n <li>从左侧面板选择元素类型(文本、图片、条码等)</li>\n <li>拖拽到画布上松开</li>\n <li>选中元素后,通过拖拽调整位置</li>\n <li>拖拽元素边角手柄调整大小</li>\n</ol>\n\n<h2>数据绑定基础</h2>\n<p>使用花括号 <code>{field.path}</code> 语法绑定数据字段:</p>\n<pre><code>供应商:{supplier.name}\n日期:{order.date}\n金额:{MONEY(order.total)}</code></pre>\n<p>双击元素可打开表达式编辑器配置绑定。</p>\n\n<h2>保存与预览</h2>\n<ul>\n <li>点击工具栏\"保存\"按钮,模板以 JSON 格式导出</li>\n <li>点击\"预览\"按钮查看打印效果</li>\n <li>模板数据包含页面设置、元素定义、样式配置</li>\n</ul>\n\n<h2>关于项目</h2>\n<p><strong>项目名称:</strong>worm-vue3-print</p>\n<p><strong>仓库地址:</strong><a href=\"https://gitee.com/liulong_oschina/worm-vue3-print\" target=\"_blank\" rel=\"noopener noreferrer\">https://gitee.com/liulong_oschina/worm-vue3-print</a></p>\n<p>基于 Vue 3 的可视化打印模板设计器,支持拖拽式模板编辑、表达式数据绑定和浏览器端打印预览。</p>\n `\n}\n","export default {\n id: 'features',\n title: '功能说明',\n content: `\n<h2>元素类型</h2>\n<table>\n <thead>\n <tr><th>类型</th><th>说明</th></tr>\n </thead>\n <tbody>\n <tr><td>文本</td><td>静态或动态文本,支持表达式绑定</td></tr>\n <tr><td>长文本</td><td>多行文本,支持自动换行</td></tr>\n <tr><td>数据表格</td><td>动态行列,支持分页、表头重复、序号/小计/汇总</td></tr>\n <tr><td>条形码</td><td>支持 code128 等多种码制</td></tr>\n <tr><td>二维码</td><td>支持 L/M/Q/H 纠错级别</td></tr>\n <tr><td>图片</td><td>静态或动态图片</td></tr>\n <tr><td>线条</td><td>水平线或垂直线</td></tr>\n <tr><td>形状</td><td>矩形、椭圆,支持边框和背景色</td></tr>\n <tr><td>HTML</td><td>自定义 HTML 内容</td></tr>\n <tr><td>页码</td><td>自动页码显示</td></tr>\n </tbody>\n</table>\n\n<h2>表达式编辑器</h2>\n<h3>基础语法</h3>\n<p>使用花括号 <code>{}</code> 包裹表达式,花括号外为字面文本。</p>\n\n<h3>内置函数</h3>\n<table>\n <thead>\n <tr><th>函数</th><th>说明</th><th>示例</th></tr>\n </thead>\n <tbody>\n <tr><td><code>MONEY(value)</code></td><td>金额格式化(千分位+两位小数)</td><td><code>{MONEY(order.total)}</code> -> \"69,543.75\"</td></tr>\n <tr><td><code>DATE(value, format)</code></td><td>日期格式化</td><td><code>{DATE(order.date, 'YYYY-MM-DD')}</code></td></tr>\n <tr><td><code>UPPER(value)</code></td><td>数字转大写金额</td><td><code>{UPPER(order.total)}</code> -> \"陆万玖仟伍佰肆拾叁元柒角伍分\"</td></tr>\n <tr><td><code>IF(cond, true, false)</code></td><td>条件判断</td><td><code>{IF(qty > 100, '大量', '少量')}</code></td></tr>\n <tr><td><code>CONCAT(str1, str2, ...)</code></td><td>字符串拼接</td><td><code>{CONCAT(name, '-', spec)}</code></td></tr>\n <tr><td><code>IFEMPTY(value, default)</code></td><td>空值默认</td><td><code>{IFEMPTY(remark, '无')}</code></td></tr>\n <tr><td><code>ROUND(num, decimals)</code></td><td>四舍五入</td><td><code>{ROUND(price, 2)}</code></td></tr>\n <tr><td><code>NOW()</code></td><td>当前日期</td><td><code>{NOW()}</code></td></tr>\n <tr><td><code>SUBSTR(str, start, len)</code></td><td>子字符串</td><td><code>{SUBSTR(name, 0, 3)}</code></td></tr>\n <tr><td><code>LEN(str)</code></td><td>字符串长度</td><td><code>{LEN(name)}</code></td></tr>\n <tr><td><code>PAD(value, len, char)</code></td><td>左侧补位</td><td><code>{PAD(qty, 5, '0')}</code></td></tr>\n </tbody>\n</table>\n\n<h3>聚合函数(表格小计/汇总行使用)</h3>\n<table>\n <thead>\n <tr><th>函数</th><th>说明</th></tr>\n </thead>\n <tbody>\n <tr><td><code>SUM(field)</code></td><td>求和</td></tr>\n <tr><td><code>AVG(field)</code></td><td>平均值</td></tr>\n <tr><td><code>COUNT(field)</code></td><td>计数</td></tr>\n <tr><td><code>MIN(field)</code></td><td>最小值</td></tr>\n <tr><td><code>MAX(field)</code></td><td>最大值</td></tr>\n </tbody>\n</table>\n\n<h3>系统变量</h3>\n<table>\n <thead>\n <tr><th>变量</th><th>说明</th></tr>\n </thead>\n <tbody>\n <tr><td><code>pageIndex</code></td><td>当前页码</td></tr>\n <tr><td><code>totalPages</code></td><td>总页数</td></tr>\n <tr><td><code>printDate</code></td><td>打印日期 (YYYY-MM-DD)</td></tr>\n <tr><td><code>printTime</code></td><td>打印时间戳</td></tr>\n </tbody>\n</table>\n\n<h2>数据表格配置</h2>\n<h3>行类型</h3>\n<ul>\n <li><strong>标题行 (header)</strong>:可设置每页重复显示</li>\n <li><strong>数据行 (data)</strong>:绑定列表数据源迭代显示</li>\n <li><strong>小计行 (subtotal)</strong>:当前页末尾显示汇总</li>\n <li><strong>汇总行 (summary)</strong>:仅最后一页显示</li>\n</ul>\n\n<h3>表格操作</h3>\n<ul>\n <li>右键菜单支持插入/删除行和列</li>\n <li>支持单元格合并/拆分</li>\n <li>支持边框预设:全部/外边框/内边框/无</li>\n <li>无边框表格设计态显示虚拟虚线</li>\n <li><strong>调整列宽</strong>:需要先在左侧面板的图层中选中对应的表格元素,然后才能在画布上拖动列宽分隔线</li>\n <li><strong>调整表格属性</strong>:必须确保当前没有任何单元格被选中。如有选中的单元格,先点击画布空白区域取消选中,再在图层中选择表格元素</li>\n <li><strong>单元格图片处理</strong>:若单元格中图片无法缩小,请将图片处理方式设置为\"缩小保持比例\"</li>\n</ul>\n\n<h2>对齐与吸附</h2>\n<h3>自动对齐</h3>\n<p>拖拽元素时自动显示对齐引导线:</p>\n<ul>\n <li>蓝色:左/顶对齐</li>\n <li>绿色:居中对齐</li>\n <li>橙色:右/底对齐</li>\n</ul>\n\n<h3>网格吸附</h3>\n<p>开启吸附功能后,元素自动吸附到网格点。</p>\n\n<h3>手动参考线</h3>\n<p>通过标尺区域拖拽添加参考线,参考线参与吸附检测。</p>\n\n<h2>图层管理</h2>\n<ul>\n <li>调整元素显示顺序(置顶/置底/上移/下移)</li>\n <li>显示/隐藏元素</li>\n <li>锁定/解锁元素(锁定后不可编辑)</li>\n</ul>\n\n<h2>三区布局</h2>\n<p>页面分为三个区域:</p>\n<ul>\n <li><strong>页眉 (header)</strong>:顶部区域</li>\n <li><strong>内容区 (content)</strong>:主体区域</li>\n <li><strong>页脚 (footer)</strong>:底部区域</li>\n</ul>\n<p>页眉/页脚支持的元素类型:文本、图片、线条、形状、条形码、二维码</p>\n\n<h2>水印配置</h2>\n<ul>\n <li>支持固定文本或绑定字段</li>\n <li>可设置旋转角度和透明度</li>\n <li>支持显示打印时间戳</li>\n</ul>\n `\n}\n","export default {\n id: 'shortcuts',\n title: '快捷键',\n content: `\n<h2>常用操作</h2>\n<table>\n <thead>\n <tr><th>快捷键</th><th>功能</th></tr>\n </thead>\n <tbody>\n <tr><td><code>Ctrl + C</code></td><td>复制选中元素</td></tr>\n <tr><td><code>Ctrl + V</code></td><td>粘贴元素(偏移 10mm)</td></tr>\n <tr><td><code>Ctrl + D</code></td><td>原地复制(偏移 5mm, 5mm)</td></tr>\n <tr><td><code>Ctrl + A</code></td><td>全选元素</td></tr>\n <tr><td><code>Delete / Backspace</code></td><td>删除选中元素</td></tr>\n <tr><td><code>Ctrl + Z</code></td><td>撤销</td></tr>\n <tr><td><code>Ctrl + Shift + Z</code> / <code>Ctrl + Y</code></td><td>重做</td></tr>\n </tbody>\n</table>\n\n<h2>元素移动</h2>\n<table>\n <thead>\n <tr><th>快捷键</th><th>功能</th></tr>\n </thead>\n <tbody>\n <tr><td><code>方向键</code></td><td>移动 1mm</td></tr>\n <tr><td><code>Shift + 方向键</code></td><td>移动 10mm</td></tr>\n <tr><td><code>Ctrl + 方向键</code></td><td>移动 0.5mm</td></tr>\n </tbody>\n</table>\n\n<h2>缩放控制</h2>\n<table>\n <thead>\n <tr><th>快捷键</th><th>功能</th></tr>\n </thead>\n <tbody>\n <tr><td><code>Ctrl + 1</code></td><td>重置缩放至 100%</td></tr>\n <tr><td><code>Ctrl + 0</code></td><td>适应窗口</td></tr>\n </tbody>\n</table>\n\n<h2>对齐操作(多选时)</h2>\n<table>\n <thead>\n <tr><th>快捷键</th><th>功能</th></tr>\n </thead>\n <tbody>\n <tr><td><code>Ctrl + L</code></td><td>左对齐</td></tr>\n <tr><td><code>Ctrl + R</code></td><td>右对齐</td></tr>\n <tr><td><code>Ctrl + E</code></td><td>水平居中</td></tr>\n <tr><td><code>Ctrl + T</code></td><td>顶对齐</td></tr>\n <tr><td><code>Ctrl + B</code></td><td>底对齐</td></tr>\n </tbody>\n</table>\n\n<h2>组合操作</h2>\n<table>\n <thead>\n <tr><th>快捷键</th><th>功能</th></tr>\n </thead>\n <tbody>\n <tr><td><code>Ctrl + G</code></td><td>组合选中元素</td></tr>\n <tr><td><code>Ctrl + Shift + G</code></td><td>取消组合</td></tr>\n </tbody>\n</table>\n\n<blockquote>\n <p><strong>注意</strong>:当焦点在输入框、文本框、下拉框内时,快捷键不生效。</p>\n</blockquote>\n `\n}\n","export default {\n id: 'faq',\n title: '常见问题',\n content: `\n<h2>如何调整纸张大小?</h2>\n<ol>\n <li>在右侧面板选择\"页面设置\"</li>\n <li>选择预设纸张(A4、A3、A5、Letter、Legal)</li>\n <li>或选择\"自定义\"输入宽度和高度(mm)</li>\n <li>设置方向:纵向(portrait)或横向(landscape)</li>\n</ol>\n\n<h2>如何处理分页?</h2>\n<p>数据表格支持自动分页:</p>\n<ol>\n <li>在表格属性中设置\"每页显示行数\"</li>\n <li>启用\"表头重复\"确保跨页时显示标题行</li>\n <li>添加小计行显示当前页汇总</li>\n <li>添加汇总行显示整表汇总</li>\n</ol>\n\n<h2>如何导入外部数据?</h2>\n<p>通过组件 props 传入数据:</p>\n<ul>\n <li><code>fields</code>:字段定义数组,用于字段树显示</li>\n <li><code>initialTemplate</code>:初始模板数据</li>\n <li><code>loadDefaultTemplate</code>:加载默认模板的回调函数</li>\n</ul>\n\n<h2>如何使用表达式绑定字段?</h2>\n<ol>\n <li>双击元素打开表达式编辑器</li>\n <li>使用 <code>{field.path}</code> 语法绑定字段</li>\n <li>使用内置函数格式化数据(如 <code>{MONEY(price)}</code>)</li>\n <li>点击确认保存</li>\n</ol>\n\n<h2>如何调整元素层级?</h2>\n<ol>\n <li>选中一个或多个元素</li>\n <li>点击工具栏的层级按钮:\n <ul>\n <li>⤒ 置顶</li>\n <li>↑ 上移一层</li>\n <li>↓ 下移一层</li>\n <li>⤓ 置底</li>\n </ul>\n </li>\n</ol>\n<p>或使用快捷键在图层面板中调整。</p>\n\n<h2>如何组合多个元素?</h2>\n<ol>\n <li>按住 Ctrl 逐个点击选中多个元素</li>\n <li>点击工具栏\"组合\"按钮,或按 <code>Ctrl + G</code></li>\n <li>组合后点击任一元素可选中整个组</li>\n <li>取消组合:选中组合后点击\"取消组合\",或按 <code>Ctrl + Shift + G</code></li>\n</ol>\n\n<h2>如何使用参考线?</h2>\n<ol>\n <li>在标尺区域拖拽添加参考线</li>\n <li>参考线自动参与吸附检测</li>\n <li>拖拽参考线可调整位置</li>\n <li>双击参考线可删除</li>\n</ol>\n\n<h2>如何预览打印效果?</h2>\n<ol>\n <li>点击工具栏\"预览\"按钮</li>\n <li>预览使用同构渲染管线,确保与实际打印一致</li>\n <li>可通过\"叠层对比\"功能对比设计稿与截图</li>\n</ol>\n\n<h2>模板数据格式是什么?</h2>\n<p>模板以 JSON 格式存储,包含:</p>\n<ul>\n <li><code>paperSize</code>:纸张大小</li>\n <li><code>orientation</code>:方向</li>\n <li><code>margins</code>:页边距</li>\n <li><code>header</code>:页眉配置</li>\n <li><code>footer</code>:页脚配置</li>\n <li><code>elements</code>:元素数组</li>\n <li><code>watermark</code>:水印配置</li>\n</ul>\n\n<h2>如何调整表格列宽?</h2>\n<ol>\n <li>在左侧面板的图层列表中,点击选中对应的表格元素</li>\n <li>此时画布上的表格会显示列宽分隔线</li>\n <li>拖动列宽分隔线即可调整列宽</li>\n</ol>\n<blockquote>\n <p><strong>注意</strong>:必须先选中表格元素,才能激活列宽拖动功能。</p>\n</blockquote>\n\n<h2>如何调整表格属性?</h2>\n<ol>\n <li>确保当前没有任何单元格被选中(如有选中,点击画布空白区域取消选中)</li>\n <li>在左侧面板的图层列表中,点击选中对应的表格元素</li>\n <li>右侧面板会显示表格属性设置</li>\n</ol>\n<blockquote>\n <p><strong>注意</strong>:如果存在选中的单元格,右侧面板将显示单元格属性而非表格属性。</p>\n</blockquote>\n `\n}\n","export default {\n id: 'changelog',\n title: '更新记录',\n content: `\n<h2>v1.2.1 <small>2026-09-11</small></h2>\n\n<h3>变更</h3>\n<ul>\n <li>工具栏编辑区/层级区/视图区图标按钮统一使用 data-tip 自定义悬浮提示,补齐「网格」「吸附」缺失提示;提升提示层级,不再被画布顶部标尺遮挡。</li>\n <li>优化「适应窗口」:以视口中心为锚点一步缩放到位(与 Ctrl+滚轮同一缩放换算管线),缩放平滑过渡;允许低于交互缩放下限(最小可至 5%),超大纸张也能整版容纳,纸张在画布视口内水平垂直居中。</li>\n <li>新增 <code>showHelp</code> 配置:控制帮助入口(帮助按钮与帮助弹框)显示,默认开启,传入 <code>false</code> 即可隐藏。</li>\n</ul>\n\n<h3>修复</h3>\n<ul>\n <li>工具栏悬浮提示气泡被画布顶部固定标尺遮挡无法显示。</li>\n <li>「适应窗口」后超大纸张仍残留滚动条、纸张未在画布视口居中(垂直偏上)。</li>\n</ul>\n\n<h3>文档</h3>\n<ul>\n <li>新增打印设计工作台布局线框图文档(<code>docs/中文/打印设计工作台-布局线框图.md</code>),标注各区域名称、功能与对应组件文件。</li>\n</ul>\n\n<h2>v1.2.0 <small>2026-09-10</small></h2>\n\n<h3>新增</h3>\n<ul>\n <li>帮助文档模态框(HelpModal):内置功能介绍、快捷键一览、常见问题与更新记录,按 Esc 或点击遮罩关闭。</li>\n <li>标尺参考线增强:支持从标尺拖拽添加参考线、双击编辑、删除,参考线对齐吸附实时显示。</li>\n <li>表格列宽拖拽新增末列右边界手柄:可直接拖拽末列右边界调整末列宽,受打印范围宽度与最小列宽 5mm 钳制。</li>\n</ul>\n\n<h3>变更</h3>\n<ul>\n <li>优化缩放逻辑:取消放大上限,支持滚轮乘性步进缩放,修复缩放锚点漂移问题。</li>\n <li>移除设计态元素左上角的 fx 绑定标签提示,简化元素视觉呈现。</li>\n</ul>\n\n<h3>文档</h3>\n<ul>\n <li>仓库根目录新增 <code>AGENTS.md</code>:AI 代理行为规范,明确代理在本仓库工作时的语言、专家态度、协作约定等强制要求。</li>\n <li>新增 <code>worm-vue3-print</code> 集成支持 skill:包含安装指南、集成 API、故障排查等参考文档。</li>\n</ul>\n\n<h3>修复</h3>\n<ul>\n <li>表格列宽拖拽存在的多个缺陷:\n <ul>\n <li>内部列边界向左拖时左列宽度不变,导致边界线不跟随光标。</li>\n <li>px → mm 单位换算缺失,拖拽距离存在约 3.78 倍偏差。</li>\n <li><code>table-layout: fixed</code> 下拖拽过程中表格 CSS <code>width(100%)</code> 与列宽和失配,导致浏览器按比例拉伸列,使边界线与右侧内容偏离光标。</li>\n <li>删除 <code>onColResizeStart</code> 中残留的 <code>document.title</code> 调试代码。</li>\n </ul>\n </li>\n</ul>\n\n<h2>v1.1.0 <small>2026-09-06</small></h2>\n\n<h3>新增</h3>\n<ul>\n <li>表格元素支持列宽拖拽:设计态选中表格后,在列边界悬停并拖动即可调整该列宽(左侧列),实时更新画布与元素尺寸;受打印范围宽度与最小列宽 5mm 钳制,拖拽结束后计入一次撤销历史。属性面板的列宽数值输入保留作为精确输入兜底。</li>\n <li>表格单元格支持图片类型:单元格可切换为图片类型,设计态支持选择图片与设置 fit/maxWidth/maxHeight,预览与打印输出完整渲染。</li>\n <li>条形码与二维码单元格支持 fit/maxWidth/maxHeight 属性。</li>\n <li>属性面板位置尺寸改用 StepperInput 控件:支持按钮微调数值;StepperInput 支持可选值列表和小数步进。</li>\n <li>新增统一颜色选择器并重构属性面板字段分组。</li>\n <li>支持页面(纸张)背景色 <code>pageBackground</code>,预览与打印/PDF 输出一致。</li>\n <li>支持 canvas 库模式构建与 npm 发布。</li>\n</ul>\n\n<h3>修复</h3>\n<ul>\n <li>打印/导出 PDF 保留元素背景色(<code>print-color-adjust: exact</code>)。</li>\n <li>打印预览保留元素重叠,表格下方跟随元素按设计坐标绝对定位并透传层级 z-index。</li>\n <li>打印页眉页脚区域贴页面底部,修复页边距失效。</li>\n <li>条形码渲染缺少 <code>object-fit: contain</code>。</li>\n <li>修复 canvas 测试在 vitest v4 + happy-dom 环境下 <code>localStorage</code> 未定义的问题,补充 mock 以兼容测试环境。</li>\n</ul>\n\n<h2>v1.0.0 <small>2026-09-02</small></h2>\n\n<h3>新增</h3>\n<ul>\n <li>首次开源发布。</li>\n <li><code>@worm-vue3-print/core</code>:模板表达式引擎与同构渲染管线(HTML 生成 / 分页 / 数据绑定)。</li>\n <li><code>@worm-vue3-print/canvas</code>:Vue 3 可视化打印模板设计器画布。</li>\n <li>渲染微服务拆分为独立仓库 <code>worm-vue3-print-render</code>(仅 Docker 部署,不上 npm)。</li>\n</ul>\n\n<blockquote>\n <p>完整更新记录请查阅仓库 <code>docs/中文/CHANGELOG.md</code> 与 <code>docs/en/CHANGELOG.en.md</code>。</p>\n</blockquote>\n `\n}\n","import gettingStarted from './getting-started'\nimport features from './features'\nimport shortcuts from './shortcuts'\nimport faq from './faq'\nimport changelog from './changelog'\n\nexport type HelpSection = {\n id: string\n title: string\n content: string\n}\n\nexport const helpSections: HelpSection[] = [\n gettingStarted,\n features,\n shortcuts,\n faq,\n changelog,\n]\n\nexport type { HelpSection as default }\n","<template>\n <Teleport to=\"body\">\n <Transition name=\"help-modal\">\n <div\n v-if=\"visible\"\n class=\"help-modal-overlay\"\n @click.self=\"$emit('close')\"\n >\n <div class=\"help-modal\">\n <div class=\"help-modal-header\">\n <div class=\"help-modal-title-wrap\">\n <h2 class=\"help-modal-title\">帮助文档</h2>\n <span class=\"help-modal-project\">worm-vue3-print</span>\n </div>\n <button\n class=\"help-modal-close\"\n title=\"关闭\"\n @click=\"$emit('close')\"\n >\n ×\n </button>\n </div>\n \n <div class=\"help-modal-body\">\n <div class=\"help-modal-sidebar\">\n <button\n v-for=\"section in sections\"\n :key=\"section.id\"\n :class=\"['help-tab', { active: activeTab === section.id }]\"\n @click=\"switchTab(section.id)\"\n >\n {{ section.title }}\n </button>\n </div>\n \n <div class=\"help-modal-content\">\n <div\n class=\"help-content\"\n v-html=\"currentContent\"\n />\n </div>\n </div>\n </div>\n </div>\n </Transition>\n </Teleport>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, onMounted, onUnmounted } from 'vue'\nimport { helpSections } from '../help-content'\n\nconst props = withDefaults(defineProps<{\n visible: boolean\n initialTab?: string\n}>(), {\n initialTab: 'getting-started'\n})\n\nconst emit = defineEmits<{\n close: []\n 'update:tab': [tab: string]\n}>()\n\nconst sections = helpSections\nconst activeTab = ref(props.initialTab)\n\nconst STORAGE_KEY = 'worm-print-help-tab'\nonMounted(() => {\n const saved = localStorage.getItem(STORAGE_KEY)\n if (saved && sections.some(s => s.id === saved)) {\n activeTab.value = saved\n }\n})\n\nwatch(() => props.visible, (v) => {\n if (v) {\n const saved = localStorage.getItem(STORAGE_KEY)\n if (saved && sections.some(s => s.id === saved)) {\n activeTab.value = saved\n }\n }\n})\n\nfunction switchTab(tabId: string) {\n activeTab.value = tabId\n localStorage.setItem(STORAGE_KEY, tabId)\n emit('update:tab', tabId)\n}\n\nconst currentContent = computed(() => {\n const section = sections.find(s => s.id === activeTab.value)\n return section?.content || ''\n})\n\nfunction handleKeydown(e: KeyboardEvent) {\n if (e.key === 'Escape' && props.visible) {\n emit('close')\n }\n}\n\nonMounted(() => {\n document.addEventListener('keydown', handleKeydown)\n})\n\nonUnmounted(() => {\n document.removeEventListener('keydown', handleKeydown)\n})\n</script>\n\n<style scoped>\n.help-modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.help-modal {\n width: 800px;\n max-width: 90vw;\n height: 600px;\n max-height: 85vh;\n background: var(--pd-surface, #ffffff);\n border-radius: 8px;\n box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.help-modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--pd-border, #d9dde6);\n}\n\n.help-modal-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--pd-text, #2a2e37);\n}\n\n.help-modal-title-wrap {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.help-modal-project {\n padding: 2px 8px;\n border-radius: 4px;\n background: var(--pd-accent-soft, rgba(22, 93, 255, 0.09));\n color: var(--pd-accent, #165DFF);\n font-size: 12px;\n font-weight: 500;\n}\n\n.help-modal-close {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--pd-text-muted, #8b909c);\n font-size: 20px;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.help-modal-close:hover {\n background: var(--pd-sidebar-hover, #f0f3f9);\n color: var(--pd-text, #2a2e37);\n}\n\n.help-modal-body {\n flex: 1;\n display: flex;\n overflow: hidden;\n}\n\n.help-modal-sidebar {\n width: 160px;\n padding: 12px;\n border-right: 1px solid var(--pd-border, #d9dde6);\n background: var(--pd-field-bg, #f4f6fa);\n overflow-y: auto;\n}\n\n.help-tab {\n display: block;\n width: 100%;\n padding: 10px 12px;\n margin-bottom: 4px;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--pd-text, #2a2e37);\n font-size: 13px;\n text-align: left;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.help-tab:hover {\n background: var(--pd-sidebar-hover, #f0f3f9);\n}\n\n.help-tab.active {\n background: var(--pd-accent-soft, rgba(22, 93, 255, 0.09));\n color: var(--pd-accent, #165DFF);\n font-weight: 500;\n}\n\n.help-modal-content {\n flex: 1;\n padding: 20px;\n overflow-y: auto;\n}\n\n.help-content {\n font-size: 14px;\n line-height: 1.6;\n color: var(--pd-text, #2a2e37);\n}\n\n.help-content :deep(h2) {\n margin: 0 0 16px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--pd-border-soft, #e9ecf2);\n font-size: 18px;\n font-weight: 600;\n}\n\n.help-content :deep(h3) {\n margin: 20px 0 12px;\n font-size: 15px;\n font-weight: 600;\n}\n\n.help-content :deep(p) {\n margin: 0 0 12px;\n}\n\n.help-content :deep(ul),\n.help-content :deep(ol) {\n margin: 0 0 12px;\n padding-left: 24px;\n}\n\n.help-content :deep(li) {\n margin-bottom: 4px;\n}\n\n.help-content :deep(code) {\n padding: 2px 6px;\n border-radius: 3px;\n background: var(--pd-field-bg, #f4f6fa);\n font-family: 'SF Mono', Monaco, monospace;\n font-size: 13px;\n}\n\n.help-content :deep(pre) {\n margin: 0 0 12px;\n padding: 12px;\n border-radius: 4px;\n background: var(--pd-field-bg, #f4f6fa);\n overflow-x: auto;\n}\n\n.help-content :deep(pre code) {\n padding: 0;\n background: transparent;\n}\n\n.help-content :deep(table) {\n width: 100%;\n margin: 0 0 12px;\n border-collapse: collapse;\n}\n\n.help-content :deep(th),\n.help-content :deep(td) {\n padding: 8px 12px;\n border: 1px solid var(--pd-border, #d9dde6);\n text-align: left;\n}\n\n.help-content :deep(th) {\n background: var(--pd-field-bg, #f4f6fa);\n font-weight: 600;\n}\n\n.help-content :deep(blockquote) {\n margin: 0 0 12px;\n padding: 12px 16px;\n border-left: 3px solid var(--pd-accent, #165DFF);\n background: var(--pd-accent-soft, rgba(22, 93, 255, 0.09));\n}\n\n.help-modal-enter-active,\n.help-modal-leave-active {\n transition: opacity 0.2s ease;\n}\n\n.help-modal-enter-active .help-modal,\n.help-modal-leave-active .help-modal {\n transition: transform 0.2s ease;\n}\n\n.help-modal-enter-from,\n.help-modal-leave-to {\n opacity: 0;\n}\n\n.help-modal-enter-from .help-modal,\n.help-modal-leave-to .help-modal {\n transform: scale(0.95);\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-ruler=\"showRuler\"\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 :show-help=\"showHelp !== false\"\n v-model:scale=\"scale\"\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-ruler=\"showRuler = !showRuler\"\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 @help=\"helpVisible = true\"\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-ruler=\"showRuler\"\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\n <!-- 帮助文档模态框 -->\n <HelpModal\n :visible=\"helpVisible\"\n @close=\"helpVisible = false\"\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 { computeFitScale, FIT_SCALE_MIN_PERCENT } from '../utils/scale'\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 HelpModal from './HelpModal.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 /** 是否展示帮助入口(帮助按钮与帮助弹框);默认开启,传 false 关闭 */\n showHelp?: boolean\n}>()\n\nconst emit = defineEmits<{\n preview: []\n save: [json: string]\n}>()\n\n// 帮助文档状态\nconst helpVisible = ref(false)\n\n// showHelp 关闭时强制收起帮助弹框(并隐藏工具栏帮助入口)\nwatch(() => props.showHelp, (v) => {\n if (v === false) helpVisible.value = false\n})\n\n// 装配层状态:面板折叠(localStorage 持久)+ 未保存 dirty\nconst { leftCollapsed, rightCollapsed, toggleLeft, toggleRight, dirty, markSaved } = useStudioChrome()\n\n// 设计器核心状态统一由 useDesignerState 管理\nconst {\n scale, showRuler, 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,\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) {\n // canvas-area 有非对称 padding(上44/右28/下32/左44),\n // 需扣除后方为真实可用视口,否则 padding 会被算进可用空间,导致适应后仍有溢出\n const cs = getComputedStyle(el)\n const padX = parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight)\n const padY = parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom)\n const dim = getPaperDimensions(templateData.value)\n const MM_TO_PX = 96 / 25.4\n // 目标比例由纸张尺寸与可用视口算出;CanvasArea 的 fitToWindow\n // 以视口中心为锚点一步到位,平滑动画由纸张 transform 过渡产生\n const target = computeFitScale(\n el.clientWidth - padX,\n el.clientHeight - padY,\n dim.width * MM_TO_PX,\n dim.height * MM_TO_PX,\n )\n canvasAreaRef.value?.fitToWindow(target)\n }\n}\nfunction onZoom(delta: number) {\n // 交互缩放下限保持 25%;适应窗口动画可达更低(见 FIT_SCALE_MIN_PERCENT),故不再钳制到 25\n scale.value = Math.max(FIT_SCALE_MIN_PERCENT, 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 image: 'src',\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","i","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","dataIdx","applyBorderPreset","preset","border","atTop","atBottom","atLeft","atRight","GHOST_BORDER_CSS","resolveCellBorderCss","opts","syncTableElementSize","options","wMm","s","w","hMm","MIN_COL_WIDTH_MM","clampResizedColumnWidth","targetMm","maxTableWidth","others","cap","rounded","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","mmToPx","mm","PT_KEYS","convertElement","el","round2","n","normalizeTemplateUnits","convert","els","PAPER_PRESETS","getPaperDimensions","MIN_SCALE_PERCENT","FIT_SCALE_MIN_PERCENT","clampScalePercent","percent","nextWheelScale","direction","factor","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","showRuler","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","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","_createElementBlock","$emit","_createElementVNode","_useModel","__props","_openBlock","_hoisted_1","_hoisted_2","_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","_createVNode","HelpButton","_hoisted_15","_hoisted_16","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","FieldTreePanel","LayerPanel","d","RULER_THICKNESS","STEP_SEQUENCE","chooseMajorStepMM","targetPx","pxPerMM","minorStepMM","majorStepMM","exp","roundMM","buildRulerTicks","startMM","endMM","fine","lastIndex","ticks","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","V_ALIGN_FLEX","H_ALIGN_FLEX","textStyle","displayText","imageSrc","raw","hasError","onError","watch","imgStyle","ROW_TYPES","emitAction","payload","_createBlock","_Teleport","barcodeSvg","svgOk","dataUrl","svgStyle","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","imageData","isCodeCell","cellDisplay","_row","cellStyle","borderOpts","cellClass","dragAnchor","applySelection","onCellMouseDown","onCellMouseEnter","onCellDblClick","menu","reactive","onCellContextMenu","mergeReason","canSplit","rowTypeReason","cloned","syncElementSize","checkColWidthLimit","cw","maxW","onMenuAction","err","colResizeEnabled","colResizeBoundaries","colBoundaryLeftMm","colResizeBoundary","resizeStartX","resizeStartWidth","onColResizeStart","onColResizeMove","onColResizeEnd","deltaMm","colIndex","widths","_withModifiers","CellBarcode","CellImage","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","contentComponent","contentAttrs","elementStyle","posLabel","dragStartLeft","dragStartTop","dragConfig","info","finalDx","finalDy","sibling","setupDrag","cleanupDrag","watchEffect","resizeEnabled","cleanupResize","onDblClick","onDblClickCell","elementId","_unref","_resolveDynamicComponent","_mergeProps","p","useAdsorb","config","adsorbMin","adsorbLineMin","showAdsorbLine","guideLines","paperSize","SNAP_COLORS","snapColor","check","movingRect","lines","minDist","other","hPairs","vPairs","ok","dist","m2","hKeys","vKeys","adjustedM","seen","renderLines","clearLines","useAdsorbManager","requestAdsorb","clearGuides","contentRef","paperWidthMM","paperHeightMM","guideHitPx","wrapperStyle","widthPx","heightPx","zoneRectsMM","layerStyle","zoneElements","headerElements","footerElements","contentElements","currentDragZone","rawRequestAdsorb","guidePaperSize","showSnapIndicator","onGuideDown","startPt","MM_PER_PX","onMove","ev","delta","maxPosition","nextPosition","onUp","paperStyle","contentStyle","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","BaseElement","line","idx","horizontal","guideType","canvasRef","hoverPx","effectiveCursorPx","cssSize","rafId","scheduleDraw","draw","canvas","dpr","length","thickness","style","bg","fg","accent","majorStep","drawTicks","drawPaperEdge","cursor","outside","tick","onBeforeUnmount","dragging","axialFromEvent","along","onDown","onWinMove","onWinUp","updateDragPreview","onHoverMove","onHoverLeave","rootRef","rulerGeom","rulerCursor","scrollPos","overlayStyle","measureRuler","area","ar","pr","targetScale","measuredScale","onScroll","resizeObserver","scaleMeasureRaf","startScaleMeasureLoop","endAt","loop","guidePreview","onGuideDragging","guidePreviewStyle","liveScale","toPaperPoint","onDrop","fieldData","elementType","marquee","marqueeStart","isCanvasBackground","areaRect","xMm","yMm","onMouseLeave","onWheel","oldScale","oldPercent","newPercent","newScale","container","anchor","padX","padY","nextTick","targetPercent","mouseX","mouseY","ax","ay","cs2","padX2","padY2","onCanvasMouseDown","onMarqueeMove","onMarqueeUp","hitTestIds","paperRect","containMode","elLeft","elTop","elRight","elBottom","inter","contained","contextMenu","onContextMenu","elId","containerRect","closeContextMenu","handlePaste","handleSelectAll","handleClearSelection","action","centerScroll","stableFrames","prevSW","prevSH","deadline","sw","sh","sw2","sh2","ch","CanvasPaper","Ruler","PROPERTY_REGISTRY","matchKeywords","search","keywords","searchProperties","itemKeys","matched","onSearch","isExpanded","iconChar","toggle","saveState","loadState","saved","_renderSlot","_ctx","precision","roundTo","current","draft","atMin","atMax","clamp","stepBy","dir","onInput","commit","_withKeys","showItem","PropertyGroup","StepperInput","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","onAreaKeydown","handled","close","open","trigger","panelWidth","panelHeight","margin","below","onDocumentPointerDown","onWindowCloseEvents","onKeydown","match","hex","full","part","red","green","blue","hh","r1","g1","b1","number","isTableType","PresetColorPicker","_hoisted_17","_hoisted_18","val","searchPlaceholder","localExpression","handleFieldDoubleClick","insideParens","getCursorRegion","insertAtCursor","handleVariableDoubleClick","sv","handleFunctionDoubleClick","insideBlock","caretOffset","textareaRef","lastBlockOpen","lastParenOpen","filteredSystemVars","systemVars","filteredAggregateFuncs","aggregateFunctions","filteredFormatFuncs","formatFunctions","previewResult","ta","end","after","caretPos","onConfirm","_hoisted_19","_hoisted_20","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","_hoisted_27","_hoisted_28","_hoisted_29","_hoisted_30","_hoisted_31","_hoisted_32","_hoisted_33","editorVisible","openEditor","ExpressionEditor","tableEditCtx","listFieldOptions","onSourceChange","onColWidthChange","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","isImageCell","onAlignChange","write","onValignChange","onCellTypeChange","openFormatterEditor","onFormatterEditorConfirm","borderStyle","borderWidth","borderColor","edgeChecks","currentBorder","onEdgesChange","edges","nb","side","doMerge","doSplit","_hoisted_21","_hoisted_35","_hoisted_37","_hoisted_39","_hoisted_40","_hoisted_42","_hoisted_43","_hoisted_45","_hoisted_46","_hoisted_47","_hoisted_48","_hoisted_49","_hoisted_50","_hoisted_51","_hoisted_52","_hoisted_53","_hoisted_54","_hoisted_55","_hoisted_56","_hoisted_58","_hoisted_59","_hoisted_60","ELEMENT_BINDING_REGISTRY","getTableCellBindings","rowType","rowIndex","cellIndex","listField","getElementBindings","element","staticBindings","dynamicBindings","paperPresets","isTextType","isImageType","isTableCellSelected","searchResult","matchedKeys","bindingDescriptors","c1","parsePath","targetPath","segment","baseName","indices","getBindingValue","setBindingValue","segments","lastKey","obj","onImageUploadSuccess","paperSizeModel","orientationModel","pageBackgroundModel","onPageBackgroundChange","marginTop","marginBottom","marginLeft","marginRight","headerHeight","footerHeight","overlayHeight","customWidth","customHeight","emitUpdate","onPaperSizeChange","onOrientationChange","onPageBackgroundReset","onCustomWidthChange","onCustomHeightChange","onMarginTopChange","onMarginBottomChange","onMarginLeftChange","onMarginRightChange","onHeaderHeightChange","onFooterHeightChange","onOverlayHeightChange","currentTab","PropertySearch","PositionSizeGroup","AppearanceGroup","desc","BindingControl","ImageContentUpload","TableRowGroup","TableCellGroup","TableSettingsGroup","BorderBgGroup","PaginationGroup","AdvancedGroup","_ps","_hoisted_26","gettingStarted","features","shortcuts","faq","changelog","helpSections","STORAGE_KEY","sections","switchTab","tabId","currentContent","handleKeydown","_Transition","section","LEFT_KEY","RIGHT_KEY","readStored","fallback","useStudioChrome","leftCollapsed","rightCollapsed","dirty","toggleLeft","toggleRight","markSaved","helpVisible","onUndo","onRedo","onAlign","onGroup","onUngroup","onDeleteElement","onDragStop","onDropElement","onDropField","onMoveLayer","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","HelpModal","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","rowHeights","SVG_NS","renderBarcodeSvg","renderQrSvg","level","modules","quiet","browserCodeRenderer","cellType","iframeRef","rendering","errorMsg","renderSeq","rerender","html","pageCount","print"],"mappings":"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"}