@worm-vue3-print/canvas 1.0.1 → 1.2.0

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/TableElement.vue","../src/components/elements/LineElement.vue","../src/components/elements/ShapeElement.vue","../src/components/elements/BarcodeElement.vue","../src/components/elements/QrcodeElement.vue","../src/components/elements/HtmlElement.vue","../src/components/elements/PageNumberElement.vue","../src/components/elements/BaseElement.vue","../src/utils/ruler.ts","../src/components/Ruler.vue","../src/composables/useAdsorb.ts","../src/composables/useAdsorbManager.ts","../src/components/CanvasPaper.vue","../src/components/CanvasArea.vue","../src/utils/property-search.ts","../src/components/property/PropertySearch.vue","../src/components/property/PropertyGroup.vue","../src/components/property/PositionSizeGroup.vue","../src/utils/preset-colors.ts","../src/components/PresetColorPicker.vue","../src/components/property/AppearanceGroup.vue","../src/components/ExpressionEditor.vue","../src/components/property/BindingControl.vue","../src/components/property/TableSettingsGroup.vue","../src/components/property/BorderBgGroup.vue","../src/components/property/AdvancedGroup.vue","../src/components/property/PaginationGroup.vue","../src/components/property/ImageContentUpload.vue","../src/components/property/TableRowGroup.vue","../src/components/property/TableCellGroup.vue","../src/utils/binding-registry.ts","../src/components/PropertyPanel.vue","../src/components/StatusBar.vue","../src/composables/useStudioChrome.ts","../src/components/PrintDesigner.vue","../src/render/browser-pagination.ts","../src/render/browser-code-renderer.ts","../src/components/PrintHtmlPreview.vue"],"sourcesContent":["// web/src/components/print/utils/table-matrix.ts\n// Excel 风格表格矩阵结构操作纯函数库。\n// 约定:函数原地修改传入的 rows/colWidths;返回 string 的函数以非空字符串为拒绝原因。\nimport type { TableRow, TableRowType, TableCell, TableCellBorder, ElementOptions } from '../types'\n\nexport interface CellRect { r1: number; c1: number; r2: number; c2: number }\n\n/** 单元格 ID 生成器:使用闭包隔离的计数器,避免全局变量冲突 */\nfunction createCellIdGenerator() {\n let seq = 0\n return function genCellId(): string {\n seq += 1\n return `cell-${Date.now().toString(36)}-${seq}`\n }\n}\n\n/** 行 ID 生成器:使用闭包隔离的计数器 */\nfunction createRowIdGenerator() {\n let seq = 0\n return function genRowId(): string {\n seq += 1\n return `row-${Date.now().toString(36)}-${seq}`\n }\n}\n\n// 模块级单例:同一模块内共享计数器\nconst genCellId = createCellIdGenerator()\nconst genRowId = createRowIdGenerator()\n\nconst DEFAULT_BORDER: TableCellBorder = { width: 0.75, style: 'solid', color: '#333333' }\n\n/** JSON 深拷贝:兼容 Vue reactive Proxy(structuredClone 对 Proxy 抛 DataCloneError) */\nfunction deepClone<T>(v: T): T {\n return JSON.parse(JSON.stringify(v)) as T\n}\n\nexport function createCell(partial?: Partial<TableCell>): TableCell {\n return {\n id: genCellId(),\n borders: {\n top: { ...DEFAULT_BORDER }, right: { ...DEFAULT_BORDER },\n bottom: { ...DEFAULT_BORDER }, left: { ...DEFAULT_BORDER },\n },\n ...partial,\n }\n}\n\n/** 默认新建表格:3 列 × 4 行(标题/数据/小计/汇总),列宽均分 50mm,表格组件默认显示当前页小计行 */\nexport function createDefaultTable(): { rows: TableRow[]; colWidths: number[] } {\n const colWidths = [50, 50, 50]\n const mk = (type: TableRowType, repeat?: boolean): TableRow => ({\n id: genRowId(),\n type,\n height: 8,\n ...(repeat !== undefined ? { repeatOnPage: repeat } : {}),\n cells: colWidths.map(() => createCell()),\n })\n const header = mk('header', true)\n header.cells.forEach((c, i) => { c.formatter = `列${i + 1}`; c.align = 'center'; c.fontWeight = 'bold' })\n return { rows: [header, mk('data'), mk('subtotal'), mk('summary')], colWidths }\n}\n\n/** 定位覆盖 (r,c) 的主格坐标(自身非 merged 即为主格) */\nexport function findMainCell(rows: TableRow[], r: number, c: number): { r: number; c: number } {\n if (!rows[r]!.cells[c]!.merged) { return { r, c } }\n for (let ri = r; ri >= 0; ri--) {\n for (let ci = c; ci >= 0; ci--) {\n const cell = rows[ri]!.cells[ci]!\n if (cell.merged) { continue }\n const rs = cell.rowspan ?? 1\n const cs = cell.colspan ?? 1\n if (ri + rs - 1 >= r && ci + cs - 1 >= c) { return { r: ri, c: ci } }\n }\n }\n return { r, c }\n}\n\n/** 主格覆盖矩形 */\nexport function getSpanRect(rows: TableRow[], r: number, c: number): CellRect {\n const main = findMainCell(rows, r, c)\n const cell = rows[main.r]!.cells[main.c]!\n return {\n r1: main.r, c1: main.c,\n r2: main.r + (cell.rowspan ?? 1) - 1,\n c2: main.c + (cell.colspan ?? 1) - 1,\n }\n}\n\n/** 由锚点/焦点推导矩形选区,并迭代扩展至完整包含所有跨越的合并格 */\nexport function normalizeSelection(\n rows: TableRow[], a: { r: number; c: number }, b: { r: number; c: number },\n): CellRect {\n let rect: CellRect = {\n r1: Math.min(a.r, b.r), c1: Math.min(a.c, b.c),\n r2: Math.max(a.r, b.r), c2: Math.max(a.c, b.c),\n }\n for (;;) {\n let changed = false\n for (let r = rect.r1; r <= rect.r2; r++) {\n for (let c = rect.c1; c <= rect.c2; c++) {\n const span = getSpanRect(rows, r, c)\n const merged: CellRect = {\n r1: Math.min(rect.r1, span.r1), c1: Math.min(rect.c1, span.c1),\n r2: Math.max(rect.r2, span.r2), c2: Math.max(rect.c2, span.c2),\n }\n if (merged.r1 !== rect.r1 || merged.c1 !== rect.c1 || merged.r2 !== rect.r2 || merged.c2 !== rect.c2) {\n rect = merged\n changed = true\n }\n }\n }\n if (!changed) { return rect }\n }\n}\n\n/** 合并合法性校验,返回拒绝原因或 null */\nexport function canMergeReason(rows: TableRow[], rect: CellRect): string | null {\n const cellCount = (rect.r2 - rect.r1 + 1) * (rect.c2 - rect.c1 + 1)\n if (cellCount < 2) { return '至少选择 2 个单元格' }\n const types = new Set<TableRowType>()\n for (let r = rect.r1; r <= rect.r2; r++) { types.add(rows[r]!.type) }\n if (types.size > 1) { return '合并区域不能跨越不同类型的行' }\n // 与已有合并区部分重叠:normalize 后矩形应与选区一致\n const norm = normalizeSelection(rows, { r: rect.r1, c: rect.c1 }, { r: rect.r2, c: rect.c2 })\n if (norm.r1 !== rect.r1 || norm.c1 !== rect.c1 || norm.r2 !== rect.r2 || norm.c2 !== rect.c2) {\n return '选区与已有合并区域部分重叠'\n }\n return null\n}\n\n/** 合并:左上为主格,非空内容空格拼接并入主格 */\nexport function mergeCells(rows: TableRow[], rect: CellRect): void {\n const main = rows[rect.r1]!.cells[rect.c1]!\n const contents: string[] = []\n for (let r = rect.r1; r <= rect.r2; r++) {\n for (let c = rect.c1; c <= rect.c2; c++) {\n const cell = rows[r]!.cells[c]!\n if (cell.formatter) { contents.push(cell.formatter) }\n if (r === rect.r1 && c === rect.c1) { continue }\n cell.merged = true\n cell.rowspan = 1\n cell.colspan = 1\n cell.formatter = ''\n }\n }\n main.rowspan = rect.r2 - rect.r1 + 1\n main.colspan = rect.c2 - rect.c1 + 1\n main.formatter = contents.join(' ')\n}\n\n/** 拆分选区内所有合并格:占位格恢复并复制主格样式 */\nexport function splitCells(rows: TableRow[], rect: CellRect): void {\n for (let r = rect.r1; r <= rect.r2; r++) {\n for (let c = rect.c1; c <= rect.c2; c++) {\n const cell = rows[r]!.cells[c]!\n if (!cell.merged && ((cell.rowspan ?? 1) > 1 || (cell.colspan ?? 1) > 1)) {\n const span = getSpanRect(rows, r, c)\n const styleSrc = cell\n for (let sr = span.r1; sr <= span.r2; sr++) {\n for (let sc = span.c1; sc <= span.c2; sc++) {\n const t = rows[sr]!.cells[sc]!\n t.merged = false\n t.rowspan = 1\n t.colspan = 1\n copyCellStyle(styleSrc, t)\n }\n }\n cell.rowspan = 1\n cell.colspan = 1\n }\n }\n }\n}\n\nfunction copyCellStyle(src: TableCell, dst: TableCell): void {\n if (src === dst) { return }\n dst.align = src.align\n dst.valign = src.valign\n dst.fontSize = src.fontSize\n dst.fontWeight = src.fontWeight\n dst.color = src.color\n dst.backgroundColor = src.backgroundColor\n dst.borders = src.borders ? deepClone(src.borders) : undefined\n dst.padding = src.padding\n dst.wordWrap = src.wordWrap\n}\n\n/** 插入行。index 为参照行,position 决定插在其上方或下方 */\nexport function insertRow(rows: TableRow[], index: number, position: 'above' | 'below'): void {\n const insertAt = position === 'above' ? index : index + 1\n const ref = rows[index]!\n const colCount = ref.cells.length\n // 参照行为 data 时新行降级为 header(data 全表唯一)\n const type: TableRowType = ref.type === 'data' ? 'header' : ref.type\n const newRow: TableRow = {\n id: `row-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`,\n type,\n height: ref.height,\n cells: Array.from({ length: colCount }, () => createCell()),\n }\n // 处理跨越插入边界的纵向合并:主格 rowspan+1,新行对应格置 merged\n for (let c = 0; c < colCount; c++) {\n if (insertAt > 0 && insertAt < rows.length) {\n const span = getSpanRect(rows, insertAt - 1, c)\n if (span.r1 < insertAt && span.r2 >= insertAt) {\n const main = rows[span.r1]!.cells[span.c1]!\n main.rowspan = (main.rowspan ?? 1) + 1\n newRow.cells[c]!.merged = true\n }\n }\n }\n rows.splice(insertAt, 0, newRow)\n}\n\n/** 删除行;主格在被删行时移交下一行 */\nexport function deleteRow(rows: TableRow[], index: number): string | null {\n if (rows.length <= 1) { return '不能删除最后一行' }\n const row = rows[index]!\n const colCount = row.cells.length\n for (let c = 0; c < colCount; c++) {\n const cell = row.cells[c]!\n if (!cell.merged && (cell.rowspan ?? 1) > 1) {\n // 主格在被删行:移交到下一行\n const next = rows[index + 1]!.cells[c]!\n Object.assign(next, deepClone(cell), { id: next.id })\n next.rowspan = (cell.rowspan ?? 1) - 1\n next.merged = false\n } else if (cell.merged) {\n // 被删行处于某纵向合并中间:主格 rowspan-1\n const span = getSpanRect(rows, index, c)\n if (span.r1 < index && span.c1 === c) {\n const main = rows[span.r1]!.cells[span.c1]!\n main.rowspan = (main.rowspan ?? 1) - 1\n }\n }\n }\n rows.splice(index, 1)\n return null\n}\n\n/** 插入列 */\nexport function insertCol(\n rows: TableRow[], colWidths: number[], index: number, position: 'left' | 'right',\n): void {\n const insertAt = position === 'left' ? index : index + 1\n colWidths.splice(insertAt, 0, colWidths[index]!)\n for (const row of rows) {\n const newCell = createCell()\n if (insertAt > 0 && insertAt < row.cells.length) {\n const r = rows.indexOf(row)\n const span = getSpanRect(rows, r, insertAt - 1)\n if (span.c1 < insertAt && span.c2 >= insertAt) {\n const main = rows[span.r1]!.cells[span.c1]!\n // 每个横跨行都会命中一次,只在主格所在行加 colspan\n if (r === span.r1) { main.colspan = (main.colspan ?? 1) + 1 }\n newCell.merged = true\n }\n }\n row.cells.splice(insertAt, 0, newCell)\n }\n}\n\n/** 删除列;主格在被删列时移交右侧列 */\nexport function deleteCol(rows: TableRow[], colWidths: number[], index: number): string | null {\n if (colWidths.length <= 1) { return '不能删除最后一列' }\n for (let r = 0; r < rows.length; r++) {\n const cell = rows[r]!.cells[index]!\n if (!cell.merged && (cell.colspan ?? 1) > 1) {\n const next = rows[r]!.cells[index + 1]!\n Object.assign(next, deepClone(cell), { id: next.id })\n next.colspan = (cell.colspan ?? 1) - 1\n next.merged = false\n } else if (cell.merged) {\n const span = getSpanRect(rows, r, index)\n if (span.c1 < index && span.r1 === r) {\n const main = rows[span.r1]!.cells[span.c1]!\n main.colspan = (main.colspan ?? 1) - 1\n }\n }\n }\n for (const row of rows) { row.cells.splice(index, 1) }\n colWidths.splice(index, 1)\n return null\n}\n\n/** 行类型变更校验 + 写入。约束:header 顶部连续;data 唯一;subtotal/summary 在 data 之后;subtotal 在 summary 之前 */\nexport function setRowType(\n rows: TableRow[], index: number, type: TableRowType,\n): string | null {\n if (type === 'data') {\n const existing = rows.findIndex((r, i) => r.type === 'data' && i !== index)\n if (existing >= 0) { return `数据行已存在(第 ${existing + 1} 行),全表最多一行` }\n }\n if (type === 'header') {\n // 设置后 header 行必须从第 0 行起连续\n for (let i = 0; i < index; i++) {\n if (rows[i]!.type !== 'header') { return '标题行必须从表格顶部连续设置' }\n }\n }\n if (type === 'subtotal' || type === 'summary') {\n const dataIdx = rows.findIndex(r => r.type === 'data')\n if (dataIdx < 0) { return '请先设置数据行,小计/汇总行必须位于数据行之后' }\n if (index < dataIdx) { return '小计/汇总行必须位于数据行之后' }\n }\n if (type === 'subtotal') {\n // 目标状态:本行设为小计后,其上方(index 之前)不得存在汇总行(小计必须位于汇总行之前)\n if (rows.slice(0, index).some(r => r.type === 'summary')) {\n return '小计行必须位于汇总行之前'\n }\n }\n if (type === 'summary') {\n if (rows.slice(index + 1).some(r => r.type === 'subtotal')) {\n return '汇总行必须位于小计行之后'\n }\n }\n // 取消 header 时校验剩余 header 仍连续(中间行取消会断开)\n if (rows[index]!.type === 'header' && type !== 'header') {\n for (let i = index + 1; i < rows.length; i++) {\n if (rows[i]!.type === 'header') { return '取消该标题行会导致标题行不连续,请先调整后续标题行' }\n }\n }\n rows[index]!.type = type\n if (type !== 'header') { delete rows[index]!.repeatOnPage }\n return null\n}\n\nexport type BorderPreset = 'all' | 'outer' | 'inner' | 'none'\n\n/** 按预设批量写边框;none 时清空选区内所有格的 borders */\nexport function applyBorderPreset(\n rows: TableRow[], rect: CellRect, preset: BorderPreset, border: TableCellBorder,\n): void {\n for (let r = rect.r1; r <= rect.r2; r++) {\n for (let c = rect.c1; c <= rect.c2; c++) {\n const cell = rows[r]!.cells[c]!\n if (cell.merged) { continue }\n if (preset === 'none') {\n delete cell.borders\n continue\n }\n const span = getSpanRect(rows, r, c)\n const atTop = span.r1 === rect.r1\n const atBottom = span.r2 === rect.r2\n const atLeft = span.c1 === rect.c1\n const atRight = span.c2 === rect.c2\n const b = { ...(cell.borders ?? {}) }\n if (preset === 'all') {\n b.top = { ...border }; b.bottom = { ...border }; b.left = { ...border }; b.right = { ...border }\n } else if (preset === 'outer') {\n if (atTop) { b.top = { ...border } }\n if (atBottom) { b.bottom = { ...border } }\n if (atLeft) { b.left = { ...border } }\n if (atRight) { b.right = { ...border } }\n } else if (preset === 'inner') {\n if (!atTop) { b.top = { ...border } }\n if (!atBottom) { b.bottom = { ...border } }\n if (!atLeft) { b.left = { ...border } }\n if (!atRight) { b.right = { ...border } }\n }\n cell.borders = b\n }\n }\n}\n\n/** 设计态下无边框单元格的辅助虚线:与背景网格线同风格(浅灰虚线),略深保证可读 */\nexport const GHOST_BORDER_CSS = '1px dashed rgba(0,0,0,0.18)'\n\n/**\n * 解析单元格某条边的最终 CSS border 值。\n * - 有真实边框(style 非 none)→ 返回 `${width}pt ${style} ${color}`\n * - 设计态且开关开启、且该边无边框 → 返回虚拟虚线(仅设计稿展示,不影响预览/打印)\n * - 其余情况(预览态 / 开关关闭)→ 'none'\n */\nexport function resolveCellBorderCss(\n b: TableCellBorder | undefined,\n opts: { designMode?: boolean; showGhostBorder?: boolean } = {},\n): string {\n if (b && b.style !== 'none') return `${b.width}pt ${b.style} ${b.color}`\n if (opts.designMode && opts.showGhostBorder !== false) return GHOST_BORDER_CSS\n return 'none'\n}\n\n/** 表格元素尺寸派生:options.width/height 恒等于列宽和/行高和(mm),与渲染端一致 */\nexport function syncTableElementSize(options: ElementOptions): void {\n const wMm = (options.tableColWidths ?? []).reduce((s, w) => s + w, 0)\n const hMm = (options.tableRows ?? []).reduce((s, r) => s + r.height, 0)\n options.width = Math.round(wMm * 100) / 100\n options.height = Math.round(hMm * 100) / 100\n}\n","// web/src/components/print/utils/element-factory.ts\nimport type { RuntimeElement, ElementType, ElementOptions } from '../types'\nimport { createDefaultTable } from './table-matrix'\n\nexport function generateId(): string {\n return `el-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`\n}\n\nexport function createDefaultOptions(type: ElementType): ElementOptions {\n // pt → mm:20/50/120/20 → 7/17.6/42.3/7.1\n const base: ElementOptions = { left: 7, top: 17.6, width: 42.3, height: 7.1 }\n\n switch (type) {\n case 'text':\n return { ...base, formatter: '文本', fontSize: 12, textAlign: 'left', height: 5.3 }\n case 'image':\n return { ...base, width: 28.2, height: 28.2, fit: 'contain' }\n case 'longText':\n return { ...base, width: 141.1, height: 28.2, fontSize: 12, lineHeight: 18 }\n case 'table': {\n const { rows, colWidths } = createDefaultTable()\n const totalW = colWidths.reduce((s, w) => s + w, 0)\n const totalH = rows.reduce((s, r) => s + r.height, 0)\n return {\n ...base, width: totalW, height: totalH, // 表格尺寸由列宽/行高(mm)派生,与渲染端一致\n tableMode: 'dynamic',\n tableRows: rows,\n tableColWidths: colWidths,\n tableDefaultFontSize: 10,\n tableDefaultColor: '#333333',\n tableDefaultPadding: 1,\n fields: [],\n tablePagination: { enabled: true },\n }\n }\n case 'hline':\n return { ...base, width: 70.6, height: 1.8, borderWidth: 0.75 }\n case 'vline':\n return { ...base, width: 1.8, height: 35.3, borderWidth: 0.75 }\n case 'rect':\n return { ...base, width: 28.2, height: 28.2, borderWidth: 1, borderColor: '#333' }\n case 'oval':\n return { ...base, width: 28.2, height: 28.2, borderWidth: 1, borderColor: '#333' }\n case 'barcode':\n return { ...base, width: 56.4, height: 14.1, title: '条形码', barcodeType: 'code128', testData: '12345678' }\n case 'qrcode':\n return { ...base, width: 28.2, height: 28.2, title: '二维码', testData: 'qrcode' }\n case 'html':\n return { ...base, width: 28.2, height: 28.2 }\n default:\n return base\n }\n}\n\nexport function createRuntimeElement(type: ElementType, options?: Partial<ElementOptions>): RuntimeElement {\n const typeMetaMap: Record<ElementType, { title: string }> = {\n text: { title: '文本' },\n image: { title: '图片' },\n longText: { title: '长文' },\n table: { title: '表格' },\n hline: { title: '横线' },\n vline: { title: '竖线' },\n rect: { title: '矩形' },\n oval: { title: '椭圆' },\n barcode: { title: '条形码' },\n qrcode: { title: '二维码' },\n html: { title: 'HTML' },\n pageNumber: { title: '页码' },\n }\n\n return {\n id: generateId(),\n options: { ...createDefaultOptions(type), ...options },\n printElementType: { type, title: typeMetaMap[type]?.title || type },\n }\n}\n","// 打印设计器核心自持的表达式引擎单例。\n// 独立于宿主(不依赖 @/utils),便于整体抽离为开源包;扩展函数由 ./expression-eval 注册。\nimport { TemplateEngine } from '@worm-vue3-print/core'\n\nexport const engine = new TemplateEngine()\n","// web/src/components/print/utils/demo-data.ts\n// 采购收货单默认预览 demo 数据: 嵌套结构, 与字段树定义一致\n\nexport function getDemoData(): Record<string, any> {\n return DEFAULT_DEMO_DATA\n}\n\nexport const DEFAULT_DEMO_DATA: Record<string, any> = {\n supplier: {\n name: '鑫达五金有限公司',\n phone: '0571-88776655',\n address: '杭州市萧山区经济开发区88号',\n },\n receiver: {\n name: '李四',\n phone: '13912345678',\n address: '杭州市余杭区文一西路998号',\n },\n order: {\n no: 'PO20260801001',\n date: '2026-08-01',\n total: 69543.75,\n },\n // 50 条商品明细, 用于验证多页分页效果\n goods: [\n { name: '碳钢螺丝 M8', spec: 'M14×10', unit: '个', qty: 100, price: 0.50, amount: 50, remark: 'A级' },\n { name: '不锈钢螺母 M10', spec: 'M16×11', unit: '套', qty: 117, price: 0.75, amount: 87.75, remark: '' },\n { name: '弹簧垫圈 M12', spec: 'M6×12', unit: '盒', qty: 134, price: 1, amount: 134, remark: '' },\n { name: '六角螺栓 M14', spec: 'M5×13', unit: '支', qty: 151, price: 1.25, amount: 188.75, remark: '' },\n { name: '内六角螺钉 M16', spec: 'M20×14', unit: '袋', qty: 168, price: 1.50, amount: 252, remark: '' },\n { name: '平垫圈 M6', spec: 'M4×15', unit: '件', qty: 185, price: 1.75, amount: 323.75, remark: '' },\n { name: '自攻螺钉 M5', spec: 'M3×16', unit: '根', qty: 202, price: 2, amount: 404, remark: '' },\n { name: '双头螺柱 M20', spec: 'M8×17', unit: '包', qty: 219, price: 2.25, amount: 492.75, remark: 'A级' },\n { name: '紧定螺钉 M4', spec: 'M10×18', unit: '只', qty: 236, price: 2.50, amount: 590, remark: '' },\n { name: '十字盘头钉 M3', spec: 'M12×19', unit: '组', qty: 253, price: 2.75, amount: 695.75, remark: '' },\n { name: '碳钢螺丝 M8', spec: 'M14×20', unit: '个', qty: 270, price: 3, amount: 810, remark: '' },\n { name: '不锈钢螺母 M10', spec: 'M16×21', unit: '套', qty: 287, price: 3.25, amount: 932.75, remark: '' },\n { name: '弹簧垫圈 M12', spec: 'M6×22', unit: '盒', qty: 304, price: 3.50, amount: 1064, remark: '' },\n { name: '六角螺栓 M14', spec: 'M5×23', unit: '支', qty: 321, price: 3.75, amount: 1203.75, remark: '' },\n { name: '内六角螺钉 M16', spec: 'M20×24', unit: '袋', qty: 338, price: 4, amount: 1352, remark: 'A级' },\n { name: '平垫圈 M6', spec: 'M4×25', unit: '件', qty: 355, price: 4.25, amount: 1508.75, remark: '' },\n { name: '自攻螺钉 M5', spec: 'M3×26', unit: '根', qty: 372, price: 4.50, amount: 1674, remark: '' },\n { name: '双头螺柱 M20', spec: 'M8×27', unit: '包', qty: 389, price: 4.75, amount: 1847.75, remark: '' },\n { name: '紧定螺钉 M4', spec: 'M10×28', unit: '只', qty: 406, price: 5, amount: 2030, remark: '' },\n { name: '十字盘头钉 M3', spec: 'M12×29', unit: '组', qty: 423, price: 5.25, amount: 2220.75, remark: '' },\n { name: '碳钢螺丝 M8', spec: 'M14×30', unit: '个', qty: 440, price: 0.50, amount: 220, remark: '' },\n { name: '不锈钢螺母 M10', spec: 'M16×31', unit: '套', qty: 457, price: 0.75, amount: 342.75, remark: 'A级' },\n { name: '弹簧垫圈 M12', spec: 'M6×32', unit: '盒', qty: 474, price: 1, amount: 474, remark: '' },\n { name: '六角螺栓 M14', spec: 'M5×33', unit: '支', qty: 491, price: 1.25, amount: 613.75, remark: '' },\n { name: '内六角螺钉 M16', spec: 'M20×34', unit: '袋', qty: 508, price: 1.50, amount: 762, remark: '' },\n { name: '平垫圈 M6', spec: 'M4×35', unit: '件', qty: 525, price: 1.75, amount: 918.75, remark: '' },\n { name: '自攻螺钉 M5', spec: 'M3×36', unit: '根', qty: 542, price: 2, amount: 1084, remark: '' },\n { name: '双头螺柱 M20', spec: 'M8×37', unit: '包', qty: 559, price: 2.25, amount: 1257.75, remark: '' },\n { name: '紧定螺钉 M4', spec: 'M10×38', unit: '只', qty: 576, price: 2.50, amount: 1440, remark: 'A级' },\n { name: '十字盘头钉 M3', spec: 'M12×39', unit: '组', qty: 593, price: 2.75, amount: 1630.75, remark: '' },\n { name: '碳钢螺丝 M8', spec: 'M14×40', unit: '个', qty: 610, price: 3, amount: 1830, remark: '' },\n { name: '不锈钢螺母 M10', spec: 'M16×41', unit: '套', qty: 627, price: 3.25, amount: 2037.75, remark: '' },\n { name: '弹簧垫圈 M12', spec: 'M6×42', unit: '盒', qty: 644, price: 3.50, amount: 2254, remark: '' },\n { name: '六角螺栓 M14', spec: 'M5×43', unit: '支', qty: 661, price: 3.75, amount: 2478.75, remark: '' },\n { name: '内六角螺钉 M16', spec: 'M20×44', unit: '袋', qty: 678, price: 4, amount: 2712, remark: '' },\n { name: '平垫圈 M6', spec: 'M4×45', unit: '件', qty: 695, price: 4.25, amount: 2953.75, remark: 'A级' },\n { name: '自攻螺钉 M5', spec: 'M3×46', unit: '根', qty: 712, price: 4.50, amount: 3204, remark: '' },\n { name: '双头螺柱 M20', spec: 'M8×47', unit: '包', qty: 729, price: 4.75, amount: 3462.75, remark: '' },\n { name: '紧定螺钉 M4', spec: 'M10×48', unit: '只', qty: 746, price: 5, amount: 3730, remark: '' },\n { name: '十字盘头钉 M3', spec: 'M12×49', unit: '组', qty: 763, price: 5.25, amount: 4005.75, remark: '' },\n { name: '碳钢螺丝 M8', spec: 'M14×10', unit: '个', qty: 780, price: 0.50, amount: 390, remark: '' },\n { name: '不锈钢螺母 M10', spec: 'M16×11', unit: '套', qty: 797, price: 0.75, amount: 597.75, remark: '' },\n { name: '弹簧垫圈 M12', spec: 'M6×12', unit: '盒', qty: 814, price: 1, amount: 814, remark: 'A级' },\n { name: '六角螺栓 M14', spec: 'M5×13', unit: '支', qty: 831, price: 1.25, amount: 1038.75, remark: '' },\n { name: '内六角螺钉 M16', spec: 'M20×14', unit: '袋', qty: 848, price: 1.50, amount: 1272, remark: '' },\n { name: '平垫圈 M6', spec: 'M4×15', unit: '件', qty: 865, price: 1.75, amount: 1513.75, remark: '' },\n { name: '自攻螺钉 M5', spec: 'M3×16', unit: '根', qty: 882, price: 2, amount: 1764, remark: '' },\n { name: '双头螺柱 M20', spec: 'M8×17', unit: '包', qty: 899, price: 2.25, amount: 2022.75, remark: '' },\n { name: '紧定螺钉 M4', spec: 'M10×18', unit: '只', qty: 916, price: 2.50, amount: 2290, remark: '' },\n { name: '十字盘头钉 M3', spec: 'M12×19', unit: '组', qty: 933, price: 2.75, amount: 2565.75, remark: 'A级' },\n ],\n}\n","// web/src/components/print/utils/expression-eval.ts\n// 包装共享引擎,保持原有 API 兼容\n\nimport { engine } from './engine'\nimport {\n formatMoney,\n formatDate,\n toUpperCaseAmount,\n ifFn,\n sum,\n avg,\n count,\n min,\n max,\n} from '@worm-vue3-print/core'\n\n// 扩展函数库(保持原有导出)\nexport const EXTENDED_FUNCTIONS = {\n MONEY: formatMoney,\n CONCAT: (...args: any[]) => args.filter(v => v != null).join(''),\n IF: ifFn,\n FORMAT: (value: any) => {\n if (typeof value !== 'number') return String(value)\n return value.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })\n },\n SUBSTR: (str: string, start: number, len?: number) => String(str).slice(start, len ? start + len : undefined),\n LEN: (str: string) => String(str).length,\n ROUND: (num: number, decimals: number) => Number(Number(num).toFixed(decimals)),\n NOW: () => new Date().toISOString().split('T')[0],\n IFEMPTY: (value: any, defaultVal: string) => (value != null && value !== '' ? String(value) : defaultVal),\n PAD: (value: any, len: number, char: string) => String(value).padStart(len, char),\n REPLACE: (str: string, from: string, to: string) => String(str).replace(new RegExp(from, 'g'), to),\n JSON: (value: any) => JSON.stringify(value, null, 2),\n DATE: formatDate,\n UPPER: toUpperCaseAmount,\n} satisfies Record<string, (...args: any[]) => any>\n\n// 注册所有扩展函数到共享引擎\nfor (const [name, fn] of Object.entries(EXTENDED_FUNCTIONS)) {\n engine.registerFunction(name, fn)\n}\n\n// ─── 聚合函数 ───\n\nfunction aggregate(fn: string, field: string, rows: Record<string, any>[]): number {\n switch (fn.toUpperCase()) {\n case 'SUM': return sum(rows, field)\n case 'AVG': return avg(rows, field)\n case 'COUNT': return count(rows, field)\n case 'MIN': return min(rows, field)\n case 'MAX': return max(rows, field)\n default: return 0\n }\n}\n\n/**\n * 在受限沙箱内求值表达式\n * @param expr 表达式字符串\n * @param context 上下文变量\n * @param _callableNames 保留参数,实际使用共享引擎\n */\nexport function safeEval(expr: string, context: Record<string, any>, _callableNames?: string[]): any {\n return engine.evaluate(expr, context)\n}\n\n/**\n * 模板字符串求值:{表达式} 内 safeEval 求值,外为字面文本。\n * 聚合函数 SUM/AVG/COUNT/MIN/MAX(field) 预处理(需 ctx.rows)。\n * 单个 {expr} 求值失败时保留原 {expr} 文本。\n */\nexport function evaluateTemplate(text: string, ctx: Record<string, any>): string {\n if (!text) return ''\n if (!text.includes('{')) return text\n const rows: Record<string, any>[] = Array.isArray(ctx.rows) ? ctx.rows : []\n \n // 预处理聚合函数\n let processedText = text.replace(/\\{([^}]+)\\}/g, (_match, inner) => {\n let expr = inner.trim()\n // 聚合函数预处理:SUM(field) -> 数值字面量\n expr = expr.replace(/\\b(SUM|AVG|COUNT|MIN|MAX)\\(([^)]+)\\)/g, (_m: string, fn: string, arg: string) => {\n const field = arg.trim().replace(/^['\"]|['\"]$/g, '')\n return String(aggregate(fn, field, rows))\n })\n return `{${expr}}`\n })\n \n // 使用共享引擎渲染\n try {\n const result = engine.render(processedText, ctx)\n return result\n } catch {\n // 降级:保留原表达式\n return text\n }\n}\n","// web/src/components/print/utils/binding.ts\nimport type { RuntimeElement } from '../types'\nimport { createRuntimeElement } from './element-factory'\nimport { engine } from './engine'\nimport { DEFAULT_DEMO_DATA } from './demo-data'\nimport './expression-eval'\n\n/** 从业务字段创建带 formatter 绑定的文本元素 */\nexport function createFieldElement(field: { fieldKey: string; fieldLabel: string }): RuntimeElement {\n return createRuntimeElement('text', {\n formatter: `{${field.fieldKey}}`,\n title: field.fieldLabel,\n })\n}\n\n/** 非设计态文本内容解析:用共享引擎渲染 formatter */\nexport function resolveTextBinding(\n options: { formatter?: string },\n data?: Record<string, any>[],\n): string {\n if (options.formatter) {\n if (!data || data.length === 0) return ''\n const row = data[0]\n try {\n return engine.render(options.formatter, row ?? {})\n } catch {\n return options.formatter\n }\n }\n return ''\n}\n\n/** 按路径取 demo 数据值,数组节点取首项 */\nfunction lookupDemoPath(path: string): any {\n let cur: any = DEFAULT_DEMO_DATA\n for (const seg of path.split('.')) {\n if (cur == null) return undefined\n cur = Array.isArray(cur) ? cur[0]?.[seg] : cur[seg]\n }\n return cur\n}\n\n/**\n * 设计态条码/二维码单元格取值:{field} 占位符替换为 demo 数据\n * (列表字段取数据源首项,全局字段按路径取),无匹配回退通用示例码值\n */\nexport function resolveBarcodeDesignValue(\n formatter: string | undefined,\n listSource?: Record<string, any>[],\n): string {\n const first = listSource?.[0]\n const resolved = (formatter ?? '')\n .replace(/\\{([^{}]+)\\}/g, (_, expr: string) => {\n const key = expr.trim()\n const v = key.includes('.')\n ? lookupDemoPath(key)\n : (first?.[key] ?? lookupDemoPath(key))\n return v == null ? '' : String(v)\n })\n .trim()\n return resolved || '1234567890128'\n}\n","// web/src/components/print/utils/units.ts\n\n/** pt 转 mm */\nexport function ptToMm(pt: number): number {\n return pt / 2.83464566929\n}\n\n/** px 转 mm(基于 96dpi 屏幕) */\nexport function pxToMm(px: number): number {\n return px * (25.4 / 96)\n}\n","// web/src/components/print/utils/migrate.ts\n// 存量模板元素坐标 pt → mm 迁移(旧数据无 unit 标记,默认按 pt 处理)\nimport type { TemplateData, PrintElementData } from '../types'\nimport { ptToMm } from './units'\n\nconst PT_KEYS = ['left', 'top', 'width', 'height'] as const\n\nfunction convertElement(el: PrintElementData): PrintElementData {\n const options = { ...el.options }\n for (const key of PT_KEYS) {\n const v = options[key]\n if (typeof v === 'number' && Number.isFinite(v)) {\n ;(options as Record<string, unknown>)[key] = round2(ptToMm(v))\n }\n }\n return { ...el, options }\n}\n\nfunction round2(n: number): number {\n return Math.round(n * 100) / 100\n}\n\nexport function normalizeTemplateUnits(data: TemplateData): TemplateData {\n if (data.unit === 'mm') return data\n const convert = (els?: PrintElementData[]): PrintElementData[] => els?.map(convertElement) ?? []\n return {\n ...data,\n unit: 'mm',\n elements: convert(data.elements),\n header: data.header ? { ...data.header, elements: convert(data.header.elements) } : data.header,\n footer: data.footer ? { ...data.footer, elements: convert(data.footer.elements) } : data.footer,\n firstPageOverlay: data.firstPageOverlay\n ? { ...data.firstPageOverlay, elements: convert(data.firstPageOverlay.elements) }\n : data.firstPageOverlay,\n }\n}\n","// web/src/components/print/utils/default-config.ts\nimport type { TemplateData } from '../types'\n\nexport const PAPER_PRESETS: Record<string, { width: number; height: number }> = {\n A4: { width: 210, height: 297 },\n A3: { width: 297, height: 420 },\n A5: { width: 148, height: 210 },\n Letter: { width: 216, height: 279 },\n Legal: { width: 216, height: 356 },\n}\n\n/**\n * 获取纸张原始宽高(mm,未应用方向)\n * CUSTOM 时读取 customWidth/customHeight,缺省回退 A4\n */\nexport function getPaperDimensions(t: Pick<TemplateData, 'paperSize' | 'orientation' | 'customWidth' | 'customHeight'>): { width: number; height: number } {\n let base: { width: number; height: number }\n if (t.paperSize === 'CUSTOM') {\n base = {\n width: t.customWidth ?? 210,\n height: t.customHeight ?? 297,\n }\n } else {\n base = PAPER_PRESETS[t.paperSize] || PAPER_PRESETS['A4']!\n }\n return t.orientation === 'landscape'\n ? { width: base.height, height: base.width }\n : base\n}\n","// web/src/components/print/utils/scale.ts\n// 缩放计算纯函数\n\n/** 计算适应窗口的缩放百分比,clamp 到 [50,200] */\nexport function computeFitScale(\n containerW: number,\n containerH: number,\n paperW: number,\n paperH: number,\n ratio = 0.9,\n): number {\n if (paperW <= 0 || paperH <= 0) return 100\n const fit = Math.min(containerW / paperW, containerH / paperH) * ratio\n const pct = Math.round(fit * 100)\n return Math.min(200, Math.max(50, pct))\n}\n","// web/src/components/print/utils/zone-layout.ts\n// 页眉/页脚/内容三区几何计算与归区逻辑(区域元素坐标相对区域左上角,mm)\nimport type { RuntimeElement, TemplateData, ElementZone } from '../types'\nimport { getPaperDimensions } from './default-config'\n\n/** 允许放入页眉/页脚的元素类型 */\nexport const ZONE_ALLOWED_TYPES = ['text', 'image', 'hline', 'vline', 'rect', 'oval', 'barcode', 'qrcode']\n\nexport interface ZoneRectPt {\n left: number\n top: number\n width: number\n height: number\n}\n\n/** 纸张宽高(mm,含方向;CUSTOM 读取 customWidth/customHeight,缺省回退 A4) */\nexport function getPaperSizeMM(t: TemplateData): { width: number; height: number } {\n return getPaperDimensions(t)\n}\n\n/** 三区在纸面坐标系中的矩形(mm),布局:上边距→页眉→内容→页脚→下边距 */\nexport function getZoneRects(t: TemplateData): Record<ElementZone, ZoneRectPt> {\n const paper = getPaperSizeMM(t)\n const m = t.margins\n const headerH = t.header.height\n const footerH = t.footer.height\n const contentW = paper.width - m.left - m.right\n const contentH = paper.height - m.top - m.bottom - headerH - footerH\n const rect = (l: number, tp: number, w: number, h: number): ZoneRectPt => ({\n left: l, top: tp, width: w, height: h,\n })\n return {\n header: rect(m.left, m.top, contentW, headerH),\n content: rect(m.left, m.top + headerH, contentW, contentH),\n footer: rect(m.left, paper.height - m.bottom - footerH, contentW, footerH),\n }\n}\n\n/** 纸面 mm 坐标 → 命中区域(高度为 0 的区域不参与命中) */\nexport function zoneFromPaperPoint(t: TemplateData, _x: number, y: number): ElementZone {\n const r = getZoneRects(t)\n if (r.footer.height > 0 && y >= r.footer.top) return 'footer'\n if (r.header.height > 0 && y < r.header.top + r.header.height) return 'header'\n return 'content'\n}\n\n/** 将元素局部坐标 clamp 到区域矩形内(原地修改) */\nexport function clampToZone(el: RuntimeElement, zone: ZoneRectPt): void {\n const o = el.options\n o.width = Math.min(o.width, zone.width)\n o.height = Math.min(o.height, zone.height)\n o.left = Math.min(Math.max(0, o.left), zone.width - o.width)\n o.top = Math.min(Math.max(0, o.top), zone.height - o.height)\n}\n\n/**\n * 拖拽/缩放结束后按元素中心点归区:\n * 跨区时换算坐标并改写 zone;页眉/页脚内 clamp;类型不允许时拒绝跨入并 clamp 回内容区。\n */\nexport function finalizeElementZone(\n el: RuntimeElement,\n t: TemplateData,\n): { rejected: boolean } {\n const rects = getZoneRects(t)\n const fromZone: ElementZone = el.zone || 'content'\n const from = rects[fromZone]\n const cx = from.left + el.options.left + el.options.width / 2\n const cy = from.top + el.options.top + el.options.height / 2\n let target = zoneFromPaperPoint(t, cx, cy)\n let rejected = false\n if (target !== 'content' && !ZONE_ALLOWED_TYPES.includes(el.printElementType.type)) {\n target = 'content'\n rejected = true\n }\n if (target !== fromZone) {\n const to = rects[target]\n el.options.left = from.left + el.options.left - to.left\n el.options.top = from.top + el.options.top - to.top\n el.zone = target\n }\n if (target !== 'content') {\n clampToZone(el, rects[target])\n } else if (rejected) {\n clampToZone(el, rects.content)\n }\n return { rejected }\n}\n","// web/src/components/print/composables/useSelection.ts\nimport { ref, computed, type InjectionKey, type Ref } from 'vue'\nimport type { RuntimeElement } from '../types'\n\n/** 通过 provide/inject 共享选中状态,每个 BaseElement 精确追踪自身是否被选中 */\nexport const SELECTED_IDS_KEY: InjectionKey<Ref<Set<string>>> = Symbol('selected-ids')\n/** 框选实时预选状态:拖拽过程中高亮即将选中的元素,提交后转为正式选中 */\nexport const PREVIEW_IDS_KEY: InjectionKey<Ref<Set<string>>> = Symbol('preview-ids')\n\nexport function useSelection(elements: { value: RuntimeElement[] }) {\n const selectedIds = ref<Set<string>>(new Set())\n // 框选预选:拖拽中实时计算,提交时拷贝进 selectedIds\n const previewIds = ref<Set<string>>(new Set())\n\n const selectedElements = computed(() =>\n elements.value.filter(e => selectedIds.value.has(e.id))\n )\n\n const hasSelection = computed(() => selectedIds.value.size > 0)\n\n function select(id: string, multiple = false) {\n if (multiple) {\n const s = new Set(selectedIds.value)\n if (s.has(id)) { s.delete(id) } else { s.add(id) }\n selectedIds.value = s\n } else {\n selectedIds.value = new Set([id])\n }\n }\n\n function clearSelection() {\n selectedIds.value = new Set()\n }\n\n function selectAll(allIds: string[]) {\n selectedIds.value = new Set(allIds)\n }\n\n /** 设置框选预选集合(拖拽中实时调用) */\n function setPreview(ids: string[]) {\n previewIds.value = new Set(ids)\n }\n /** 清除预选 */\n function clearPreview() {\n previewIds.value = new Set()\n }\n /** 提交预选:将预选集合转为正式选中,并清空预选 */\n function commitPreview() {\n selectedIds.value = new Set(previewIds.value)\n previewIds.value = new Set()\n }\n\n function getSelectionBounds(): { left: number; top: number; width: number; height: number } | null {\n const els = selectedElements.value\n if (els.length === 0) return null\n let minL = Infinity, minT = Infinity, maxR = -Infinity, maxB = -Infinity\n els.forEach(e => {\n minL = Math.min(minL, e.options.left)\n minT = Math.min(minT, e.options.top)\n maxR = Math.max(maxR, e.options.left + e.options.width)\n maxB = Math.max(maxB, e.options.top + e.options.height)\n })\n return { left: minL, top: minT, width: maxR - minL, height: maxB - minT }\n }\n\n return { selectedIds, selectedElements, hasSelection, select, clearSelection, selectAll, getSelectionBounds, previewIds, setPreview, clearPreview, commitPreview }\n}\n","// web/src/components/print/composables/useClipboard.ts\nimport { ref } from 'vue'\nimport type { RuntimeElement, PrintElementData } from '../types'\nimport { generateId } from '../utils/element-factory'\n\nexport function useClipboard() {\n const clipboard = ref<PrintElementData[] | null>(null)\n\n function copy(elements: RuntimeElement[]) {\n clipboard.value = elements.map(e => ({\n options: { ...e.options },\n printElementType: { ...e.printElementType },\n }))\n }\n\n function paste(offset = 10): RuntimeElement[] | null {\n if (!clipboard.value) return null\n return clipboard.value.map(item => ({\n id: generateId(),\n options: {\n ...item.options,\n left: item.options.left + offset,\n top: item.options.top + offset,\n },\n printElementType: { ...item.printElementType },\n }))\n }\n\n function hasData() { return clipboard.value !== null && clipboard.value.length > 0 }\n\n return { clipboard, copy, paste, hasData }\n}\n","// web/src/components/print/composables/useAlign.ts\nimport type { RuntimeElement } from '../types'\n\nexport type AlignMode = 'left' | 'right' | 'top' | 'bottom' | 'vertical' | 'horizontal' | 'distributeHor' | 'distributeVer'\n\nexport function useAlign() {\n function align(elements: RuntimeElement[], mode: AlignMode) {\n if (elements.length < 2) return\n\n const bounds = {\n minLeft: Math.min(...elements.map(e => e.options.left)),\n maxRight: Math.max(...elements.map(e => e.options.left + e.options.width)),\n minTop: Math.min(...elements.map(e => e.options.top)),\n maxBottom: Math.max(...elements.map(e => e.options.top + e.options.height)),\n }\n\n switch (mode) {\n case 'left':\n elements.forEach(e => { e.options.left = bounds.minLeft })\n break\n case 'right':\n elements.forEach(e => { e.options.left = bounds.maxRight - e.options.width })\n break\n case 'top':\n elements.forEach(e => { e.options.top = bounds.minTop })\n break\n case 'bottom':\n elements.forEach(e => { e.options.top = bounds.maxBottom - e.options.height })\n break\n case 'vertical': {\n const centerX = bounds.minLeft + (bounds.maxRight - bounds.minLeft) / 2\n elements.forEach(e => { e.options.left = centerX - e.options.width / 2 })\n break\n }\n case 'horizontal': {\n const centerY = bounds.minTop + (bounds.maxBottom - bounds.minTop) / 2\n elements.forEach(e => { e.options.top = centerY - e.options.height / 2 })\n break\n }\n case 'distributeHor': {\n const sorted = [...elements].sort((a, b) => a.options.left - b.options.left)\n const totalW = sorted.reduce((s, e) => s + e.options.width, 0)\n const gap = (bounds.maxRight - bounds.minLeft - totalW) / (sorted.length - 1)\n let x = bounds.minLeft\n sorted.forEach(e => { e.options.left = x; x += e.options.width + gap })\n break\n }\n case 'distributeVer': {\n const sorted = [...elements].sort((a, b) => a.options.top - b.options.top)\n const totalH = sorted.reduce((s, e) => s + e.options.height, 0)\n const gap = (bounds.maxBottom - bounds.minTop - totalH) / (sorted.length - 1)\n let y = bounds.minTop\n sorted.forEach(e => { e.options.top = y; y += e.options.height + gap })\n break\n }\n }\n }\n\n return { align }\n}\n","// web/src/components/print/composables/useGroup.ts\n// 元素编组/组合逻辑\nimport type { RuntimeElement } from '../types'\n\nexport function generateGroupId(): string {\n return `grp-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`\n}\n\nexport function useGroup() {\n function group(elements: RuntimeElement[], selectedIds: Set<string>): RuntimeElement[] {\n const selected = elements.filter(e => selectedIds.has(e.id))\n if (selected.length < 2) return elements\n\n const groupId = generateGroupId()\n return elements.map(e =>\n selectedIds.has(e.id) ? { ...e, options: { ...e.options, groupId } } : e\n )\n }\n\n function ungroup(elements: RuntimeElement[], selectedIds: Set<string>): RuntimeElement[] {\n const selected = elements.filter(e => selectedIds.has(e.id))\n // 收集选中元素中涉及的 groupId\n const groupIds = new Set(selected.map(e => e.options.groupId).filter(Boolean))\n\n return elements.map(e =>\n e.options.groupId && groupIds.has(e.options.groupId)\n ? { ...e, options: { ...e.options, groupId: undefined } }\n : e\n )\n }\n\n /** 获取与选中元素同组的所有元素 ID */\n function getGroupedIds(elements: RuntimeElement[], selectedId: string): Set<string> {\n const el = elements.find(e => e.id === selectedId)\n if (!el?.options.groupId) return new Set([selectedId])\n\n const ids = new Set<string>()\n for (const e of elements) {\n if (e.options.groupId === el.options.groupId) {\n ids.add(e.id)\n }\n }\n return ids\n }\n\n return { group, ungroup, getGroupedIds }\n}\n","// web/src/components/print/composables/useHistory.ts\nimport { ref } from 'vue'\nimport type { TemplateData } from '../types'\n\nexport interface HistoryState {\n elements: any[]\n templateData?: TemplateData\n}\n\nexport interface UseHistoryOptions {\n /** 历史记录上限,默认 50 步 */\n maxSteps?: number\n /** 是否启用增量快照(减少内存占用),默认 false */\n useIncremental?: boolean\n}\n\n/**\n * 撤销/重做历史管理(操作级快照粒度)。\n *\n * 语义说明:\n * - `push(state)` 记录一次操作后的快照(检查点),并清空 redo 栈。\n * - `undo(currentState?)` 弹出栈顶检查点(当前状态)压入 redo 栈,\n * 返回新的栈顶(即上一个待恢复状态);栈空时返回 null。\n * - `redo(currentState?)` 弹出 redo 栈顶(待重做状态)压回 undo 栈并返回。\n * - 所有快照均做 JSON 深拷贝,避免外部对象突变污染历史。\n *\n * 调用约定:若希望\"撤销到初始状态\",应在首次操作前先 `push(initialState)`。\n */\nexport function useHistory(options?: UseHistoryOptions) {\n const maxSteps = options?.maxSteps ?? 50\n const useIncremental = options?.useIncremental ?? false\n const undoStack = ref<HistoryState[]>([])\n const redoStack = ref<HistoryState[]>([])\n\n const canUndo = ref(false)\n const canRedo = ref(false)\n\n function updateFlags() {\n canUndo.value = undoStack.value.length > 0\n canRedo.value = redoStack.value.length > 0\n }\n\n /** 深拷贝快照,避免外部对象突变污染历史 */\n function clone(state: HistoryState | undefined): HistoryState {\n return {\n elements: JSON.parse(JSON.stringify(state?.elements ?? [])),\n templateData: JSON.parse(JSON.stringify(state?.templateData ?? {})),\n }\n }\n\n /** 增量快照:只记录元素变更,templateData 只记录非 elements 部分 */\n function cloneIncremental(state: HistoryState): HistoryState {\n const clonedElements = JSON.parse(JSON.stringify(state.elements))\n const td = state.templateData\n if (!td) return { elements: clonedElements }\n return {\n elements: clonedElements,\n templateData: {\n paperSize: td.paperSize,\n orientation: td.orientation,\n margins: { ...td.margins },\n header: { height: td.header.height, elements: [] },\n footer: { height: td.footer.height, elements: [] },\n firstPageOverlay: { height: td.firstPageOverlay.height, elements: [] },\n elements: [], // 元素已在顶层存储\n customWidth: td.customWidth,\n customHeight: td.customHeight,\n watermark: td.watermark ? { ...td.watermark } : undefined,\n guides: td.guides ? [...td.guides] : undefined,\n },\n }\n }\n\n function cloneState(state: HistoryState): HistoryState {\n return useIncremental ? cloneIncremental(state) : clone(state)\n }\n\n /** 记录操作后快照(深拷贝),并清空 redo 栈 */\n function push(state: HistoryState) {\n undoStack.value.push(cloneState(state))\n // 新操作清空 redo 栈\n redoStack.value = []\n // 超出上限丢弃最早\n if (undoStack.value.length > maxSteps) {\n undoStack.value.shift()\n }\n updateFlags()\n }\n\n /**\n * 撤销:弹出当前栈顶检查点(压入 redo 栈),返回上一个待恢复状态。\n * @param currentState 可选,若提供则用其替代弹出的检查点压入 redo 栈\n * (显式传入当前实时状态时使用)\n */\n function undo(currentState?: HistoryState): HistoryState | null {\n if (undoStack.value.length === 0) return null\n const popped = undoStack.value.pop()!\n redoStack.value.push(currentState ? cloneState(currentState) : clone(popped))\n updateFlags()\n // 返回新的栈顶(上一个待恢复状态);栈空表示无更早历史\n return undoStack.value.length > 0\n ? clone(undoStack.value[undoStack.value.length - 1])\n : null\n }\n\n /**\n * 重做:弹出 redo 栈顶(待重做状态)压回 undo 栈并返回。\n * @param currentState 可选,若提供则用其替代弹出的状态压回 undo 栈\n */\n function redo(currentState?: HistoryState): HistoryState | null {\n if (redoStack.value.length === 0) return null\n const popped = redoStack.value.pop()!\n undoStack.value.push(currentState ? cloneState(currentState) : clone(popped))\n updateFlags()\n return clone(popped)\n }\n\n /** 清空全部历史 */\n function clear() {\n undoStack.value = []\n redoStack.value = []\n updateFlags()\n }\n\n return { push, undo, redo, canUndo, canRedo, clear }\n}\n","// web/src/components/print/composables/useKeyboard.ts\n\nexport interface KeyboardHandlers {\n onMove?: (dx: number, dy: number) => void\n onDelete?: () => void\n onCopy?: () => void\n onPaste?: () => void\n onSelectAll?: () => void\n onUndo?: () => void\n onRedo?: () => void\n onDuplicate?: () => void\n onResetZoom?: () => void\n onAlignLeft?: () => void\n onAlignRight?: () => void\n onAlignCenterH?: () => void\n onAlignTop?: () => void\n onAlignBottom?: () => void\n onGroup?: () => void\n onUngroup?: () => void\n}\n\nconst STEP = 1 // mm\nconst STEP_LARGE = 10\nconst STEP_SMALL = 0.5\n\nexport function useKeyboard(handlers: KeyboardHandlers) {\n function onKeyDown(e: KeyboardEvent) {\n const tag = (e.target as HTMLElement).tagName\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return\n\n const ctrl = e.ctrlKey || e.metaKey\n\n // 方向键:Shift=大步,Ctrl=微步,默认标准步\n if (e.key.startsWith('Arrow')) {\n e.preventDefault()\n const step = e.shiftKey ? STEP_LARGE : e.ctrlKey ? STEP_SMALL : STEP\n const dx = e.key === 'ArrowLeft' ? -step : e.key === 'ArrowRight' ? step : 0\n const dy = e.key === 'ArrowUp' ? -step : e.key === 'ArrowDown' ? step : 0\n handlers.onMove?.(dx, dy)\n return\n }\n\n if (e.key === 'Delete' || e.key === 'Backspace') {\n e.preventDefault()\n handlers.onDelete?.()\n return\n }\n\n // Ctrl+0 适应窗口需容器尺寸,由 PrintDesigner 单独监听,此处不处理\n if (ctrl) {\n const k = e.key.toLowerCase()\n if (k === 'c') { e.preventDefault(); handlers.onCopy?.() }\n else if (k === 'v') { e.preventDefault(); handlers.onPaste?.() }\n else if (k === 'a') { e.preventDefault(); handlers.onSelectAll?.() }\n else if (k === 'd') { e.preventDefault(); handlers.onDuplicate?.() }\n else if (k === 'z') { e.preventDefault(); e.shiftKey ? handlers.onRedo?.() : handlers.onUndo?.() }\n else if (k === 'y') { e.preventDefault(); handlers.onRedo?.() }\n else if (k === '1') { e.preventDefault(); handlers.onResetZoom?.() }\n else if (k === 'l') { e.preventDefault(); handlers.onAlignLeft?.() }\n else if (k === 'r') { e.preventDefault(); handlers.onAlignRight?.() }\n else if (k === 'e') { e.preventDefault(); handlers.onAlignCenterH?.() }\n else if (k === 't') { e.preventDefault(); handlers.onAlignTop?.() }\n else if (k === 'b') { e.preventDefault(); handlers.onAlignBottom?.() }\n else if (k === 'g') { e.preventDefault(); e.shiftKey ? handlers.onUngroup?.() : handlers.onGroup?.() }\n }\n }\n\n function setup() { document.addEventListener('keydown', onKeyDown) }\n function cleanup() { document.removeEventListener('keydown', onKeyDown) }\n\n return { setup, cleanup }\n}\n","// web/src/components/print/composables/useDesignerState.ts\n// 设计器核心状态管理:模板数据/选择/历史/剪贴板/编组/键盘/序列化\nimport { ref, computed, onMounted, onUnmounted } from 'vue'\nimport type {\n RuntimeElement, ElementType, ElementZone, PrintBusinessField, TemplateData,\n TableSelection, PrintElementData,\n} from '../types'\nimport { createRuntimeElement, generateId } from '../utils/element-factory'\nimport { createFieldElement } from '../utils/binding'\nimport { normalizeTemplateUnits } from '../utils/migrate'\nimport { syncTableElementSize } from '../utils/table-matrix'\nimport { getPaperDimensions } from '../utils/default-config'\nimport { computeFitScale } from '../utils/scale'\nimport {\n getZoneRects, zoneFromPaperPoint, clampToZone, finalizeElementZone, ZONE_ALLOWED_TYPES,\n} from '../utils/zone-layout'\nimport { useSelection } from './useSelection'\nimport { useClipboard } from './useClipboard'\nimport { useAlign, type AlignMode } from './useAlign'\nimport { useGroup } from './useGroup'\nimport { useHistory, type HistoryState } from './useHistory'\nimport { useKeyboard } from './useKeyboard'\n\nexport interface DesignerStateOptions {\n initialTemplate?: TemplateData\n initialElements?: RuntimeElement[]\n initialFields?: PrintBusinessField[]\n}\n\n/** 创建默认模板数据 */\nexport function createDefaultTemplate(): TemplateData {\n return {\n paperSize: 'A4',\n orientation: 'portrait',\n unit: 'mm',\n margins: { top: 10, right: 10, bottom: 10, left: 10 },\n header: { height: 10, elements: [] },\n footer: { height: 10, elements: [] },\n firstPageOverlay: { height: 0, elements: [] },\n elements: [],\n watermark: {},\n }\n}\n\n/** 三区元素合并为统一运行时元素池(补建 id、打 zone 标) */\nexport function toRuntimePool(data: TemplateData): TemplateData {\n const mk = (els: PrintElementData[], zone: ElementZone): RuntimeElement[] =>\n (els ?? []).map(e => {\n const options = { ...e.options }\n // 表格尺寸恒由列宽/行高派生(mm),加载时重算以自愈历史污染数据\n if ((e.printElementType?.type ?? e.type) === 'table') {\n syncTableElementSize(options)\n }\n return {\n id: e.id || generateId(),\n zone,\n options,\n printElementType: { ...e.printElementType },\n }\n })\n return {\n ...data,\n margins: { ...data.margins },\n header: { height: data.header?.height ?? 10, elements: [] },\n footer: { height: data.footer?.height ?? 10, elements: [] },\n firstPageOverlay: {\n height: data.firstPageOverlay?.height ?? 0,\n elements: [...(data.firstPageOverlay?.elements ?? [])],\n },\n guides: [...(data.guides ?? [])],\n elements: [\n ...mk(data.elements ?? [], 'content'),\n ...mk(data.header?.elements ?? [], 'header'),\n ...mk(data.footer?.elements ?? [], 'footer'),\n ],\n }\n}\n\nexport function useDesignerState(options: DesignerStateOptions = {}) {\n const scale = ref(100)\n const showGrid = ref(true)\n const snapToGrid = ref(false)\n // 设计态下无边框表格单元格的虚拟虚线边框开关(默认开启)\n const showTableGhostBorder = ref(true)\n\n // 单一模板状态(三区元素归一化进运行时元素池)\n const templateData = ref<TemplateData>(\n toRuntimePool(options.initialTemplate || createDefaultTemplate())\n )\n\n // 内容区主体元素(快捷访问)\n // 优化:setter 直接修改 elements 属性,避免展开替换整个 templateData 触发全量通知\n const elements = computed({\n get: () => templateData.value.elements as RuntimeElement[],\n set: (els: RuntimeElement[]) => {\n templateData.value.elements = els\n },\n })\n\n const fields = ref<PrintBusinessField[]>(options.initialFields || [])\n\n const { selectedIds, selectedElements, select, clearSelection, selectAll: selectAllIds, previewIds, setPreview, clearPreview, commitPreview } = useSelection(elements)\n\n // 编组\n const { group: groupElements, ungroup: ungroupElements } = useGroup()\n\n // 复制粘贴 / 对齐 / 撤销重做\n const { copy: copyElements, paste: pasteElements, hasData: hasClipboardData } = useClipboard()\n const { align } = useAlign()\n const { push: pushHistory, undo: undoHistory, redo: redoHistory, canUndo, canRedo } = useHistory()\n\n const selectedElement = computed(() => {\n if (selectedIds.value.size === 0) return null\n const id = selectedIds.value.values().next().value\n return elements.value.find(e => e.id === id) || null\n })\n\n // 表格单元格选区(Excel 风格表格编辑)\n const tableSelection = ref<TableSelection | null>(null)\n function setTableSelection(s: TableSelection | null) {\n tableSelection.value = s\n }\n\n /** 当前设计器状态的深拷贝快照(用于历史记录) */\n function getHistoryState(): HistoryState {\n return {\n elements: elements.value.map(e => ({\n id: e.id,\n zone: e.zone,\n // JSON 深拷贝:tableRows 等嵌套结构若浅拷会在撤销时共享引用\n options: JSON.parse(JSON.stringify(e.options)),\n printElementType: { ...e.printElementType },\n })),\n templateData: {\n paperSize: templateData.value.paperSize,\n orientation: templateData.value.orientation,\n margins: { ...templateData.value.margins },\n header: { height: templateData.value.header.height, elements: [] },\n footer: { height: templateData.value.footer.height, elements: [] },\n firstPageOverlay: { height: templateData.value.firstPageOverlay.height, elements: [] },\n elements: [], // 元素已在顶层存储,避免重复\n customWidth: templateData.value.customWidth,\n customHeight: templateData.value.customHeight,\n watermark: templateData.value.watermark ? { ...templateData.value.watermark } : undefined,\n guides: [...(templateData.value.guides ?? [])],\n },\n }\n }\n\n function recordHistory() {\n pushHistory(getHistoryState())\n }\n\n function undo() {\n const state = undoHistory(getHistoryState())\n if (state?.templateData) {\n templateData.value = { ...state.templateData, elements: state.elements }\n }\n }\n\n function redo() {\n const state = redoHistory(getHistoryState())\n if (state?.templateData) {\n templateData.value = { ...state.templateData, elements: state.elements }\n }\n }\n\n function copy() {\n copyElements(selectedElements.value)\n }\n\n /** 剪切:复制到剪贴板后删除选中元素 */\n function cutSelected() {\n copyElements(selectedElements.value)\n deleteSelected()\n }\n\n function paste() {\n const pasted = pasteElements()\n if (pasted && pasted.length > 0) {\n elements.value.push(...pasted)\n recordHistory()\n }\n }\n\n /** Ctrl+D 原地复制:复用剪贴板克隆选中元素,叠加小幅偏移 */\n function duplicateSelected() {\n copyElements(selectedElements.value)\n const pasted = pasteElements()\n if (pasted && pasted.length > 0) {\n pasted.forEach(e => { e.options.left += 5; e.options.top += 5 })\n elements.value.push(...pasted)\n select(pasted[0]!.id, false)\n recordHistory()\n }\n }\n\n /** Ctrl+1 重置缩放至 100% */\n function resetZoom() {\n scale.value = 100\n }\n\n const hasClipboard = computed(() => hasClipboardData())\n\n let moveSessionActive = false\n let moveDebounceTimer: ReturnType<typeof setTimeout> | null = null\n const MOVE_SESSION_GAP_MS = 300\n\n function moveSelected(dx: number, dy: number) {\n const movable = selectedElements.value.filter(e => !e.options.locked)\n if (movable.length === 0) return\n movable.forEach(e => {\n e.options.left += dx\n e.options.top += dy\n })\n if (!moveSessionActive) {\n moveSessionActive = true\n recordHistory()\n }\n if (moveDebounceTimer) clearTimeout(moveDebounceTimer)\n moveDebounceTimer = setTimeout(() => {\n moveSessionActive = false\n moveDebounceTimer = null\n }, MOVE_SESSION_GAP_MS)\n }\n\n function selectAll() {\n selectAllIds(elements.value.map(e => e.id))\n }\n\n function alignSelected(mode: AlignMode) {\n align(selectedElements.value, mode)\n recordHistory()\n }\n\n function groupSelected() {\n elements.value = groupElements(elements.value, selectedIds.value)\n recordHistory()\n }\n\n function ungroupSelected() {\n elements.value = ungroupElements(elements.value, selectedIds.value)\n recordHistory()\n }\n\n function deleteSelected() {\n if (selectedIds.value.size === 0) return\n elements.value = elements.value.filter(e => !selectedIds.value.has(e.id))\n clearSelection()\n recordHistory()\n }\n\n // 键盘快捷键\n const { setup: setupKeyboard, cleanup: cleanupKeyboard } = useKeyboard({\n onMove: moveSelected,\n onDelete: deleteSelected,\n onCopy: copy,\n onPaste: paste,\n onSelectAll: selectAll,\n onUndo: undo,\n onRedo: redo,\n onDuplicate: duplicateSelected,\n onResetZoom: resetZoom,\n // 多选对齐快捷键:Ctrl+L 左对齐 / Ctrl+R 右对齐 / Ctrl+E 水平居中 / Ctrl+T 顶对齐 / Ctrl+B 底对齐\n onAlignLeft: () => alignSelected('left'),\n onAlignRight: () => alignSelected('right'),\n onAlignCenterH: () => alignSelected('vertical'),\n onAlignTop: () => alignSelected('top'),\n onAlignBottom: () => alignSelected('bottom'),\n // 编组快捷键:Ctrl+G 组合 / Ctrl+Shift+G 取消组合\n onGroup: groupSelected,\n onUngroup: ungroupSelected,\n })\n\n let draggingBeforeState: HistoryState | null = null\n\n function dragStart() {\n draggingBeforeState = getHistoryState()\n }\n\n function dragStop() {\n if (!draggingBeforeState) return\n // 拖拽/缩放结束:对位置或尺寸变化的元素做归区收尾(跨区换算 + 区域 clamp)\n const before = new Map(draggingBeforeState.elements.map(e => [e.id, e]))\n let rejected = false\n for (const el of elements.value) {\n const prev = before.get(el.id)\n if (!prev) continue\n const moved = prev.options.left !== el.options.left\n || prev.options.top !== el.options.top\n || prev.options.width !== el.options.width\n || prev.options.height !== el.options.height\n if (moved && finalizeElementZone(el, templateData.value).rejected) {\n rejected = true\n }\n }\n if (rejected) {\n alert('该元素类型不能放入页眉/页脚')\n }\n const sig = (e: RuntimeElement) =>\n `${e.id}:${e.zone || 'content'}:${e.options.left},${e.options.top},${e.options.width},${e.options.height}`\n const beforeIds = draggingBeforeState.elements.map(sig).join('|')\n const afterIds = getHistoryState().elements.map(sig).join('|')\n draggingBeforeState = null\n if (beforeIds !== afterIds) {\n recordHistory()\n }\n }\n\n /** 按落点将新元素放入对应区域;页眉/页脚不允许的类型拒绝并提示 */\n function placeAtDropPoint(el: RuntimeElement, dropPoint: { x: number; y: number }): boolean {\n // dropPoint 为 mm(由 CanvasArea.toPaperPoint 返回)\n const zone = zoneFromPaperPoint(templateData.value, dropPoint.x, dropPoint.y)\n if (zone !== 'content' && !ZONE_ALLOWED_TYPES.includes(el.printElementType.type)) {\n alert('该元素类型不能放入页眉/页脚')\n return false\n }\n const rect = getZoneRects(templateData.value)[zone] // mm\n el.zone = zone\n // 元素 options 以 mm 存储:落点相对区域左上角的偏移即 mm 坐标\n el.options.left = dropPoint.x - rect.left\n el.options.top = dropPoint.y - rect.top\n if (zone !== 'content') {\n clampToZone(el, rect)\n }\n return true\n }\n\n function addElement(type: string, dropPoint?: { x: number; y: number }) {\n const el = createRuntimeElement(type as ElementType)\n if (dropPoint && !placeAtDropPoint(el, dropPoint)) return\n elements.value.push(el)\n select(el.id, false)\n recordHistory()\n }\n\n function addFieldElement(field: { fieldKey: string; fieldLabel: string }, dropPoint?: { x: number; y: number }) {\n const el = createFieldElement(field)\n if (dropPoint && !placeAtDropPoint(el, dropPoint)) return\n elements.value.push(el)\n select(el.id, false)\n recordHistory()\n }\n\n function moveLayer(direction: string) {\n if (selectedIds.value.size === 0) return\n const id = selectedIds.value.values().next().value\n const el = elements.value.find(e => e.id === id)\n if (!el) return\n const currentZ = el.options.zIndex ?? 0\n const allZ = elements.value.map(e => e.options.zIndex ?? 0)\n const maxZ = Math.max(...allZ, 0)\n const minZ = Math.min(...allZ, 0)\n switch (direction) {\n case 'top': el.options.zIndex = maxZ + 1; break\n case 'bottom': el.options.zIndex = minZ - 1; break\n case 'up': el.options.zIndex = currentZ + 1; break\n case 'down': el.options.zIndex = currentZ - 1; break\n }\n recordHistory()\n }\n\n /** 适应窗口:根据容器尺寸(px)与纸张尺寸(mm->px)计算缩放 */\n function fitToWindow(containerW: number, containerH: number) {\n const { width, height } = getPaperDimensions(templateData.value)\n const MM_TO_PX = 96 / 25.4\n scale.value = computeFitScale(containerW, containerH, width * MM_TO_PX, height * MM_TO_PX)\n }\n\n function updateTemplateData(data: TemplateData) {\n templateData.value = { ...data }\n recordHistory()\n }\n\n /** 当前设计器状态序列化为模板 JSON(单一出口,按 zone 拆回三区,保留 id/type 供渲染服务使用) */\n function getTemplateJson(): TemplateData {\n const all = elements.value\n const ser = (zone: ElementZone) => all\n .filter(e => (e.zone || 'content') === zone)\n .map(e => ({\n id: e.id,\n type: e.printElementType.type,\n options: { ...e.options },\n printElementType: { ...e.printElementType },\n }))\n return {\n unit: 'mm' as const,\n ...templateData.value,\n header: { ...templateData.value.header, elements: ser('header') },\n footer: { ...templateData.value.footer, elements: ser('footer') },\n // 首页叠加层也需补 id/type\n firstPageOverlay: {\n ...templateData.value.firstPageOverlay,\n elements: templateData.value.firstPageOverlay.elements.map(e => ({\n id: e.id || generateId(),\n type: e.printElementType?.type || 'text',\n options: { ...e.options },\n printElementType: { ...e.printElementType },\n })),\n },\n elements: ser('content'),\n guides: [...(templateData.value.guides ?? [])],\n }\n }\n\n /** 加载模板数据(三区合并进运行时元素池;旧数据按 pt 迁移为 mm) */\n function loadTemplate(data: TemplateData, els?: RuntimeElement[]) {\n const migrated = normalizeTemplateUnits(data)\n templateData.value = toRuntimePool(migrated)\n if (els) {\n templateData.value = {\n ...templateData.value,\n elements: els.map(e => ({\n ...e,\n id: e.id || generateId(),\n zone: e.zone || 'content',\n options: { ...e.options },\n printElementType: { ...e.printElementType },\n })),\n }\n }\n pushHistory(getHistoryState())\n }\n\n // 记录设计器初始状态快照\n pushHistory(getHistoryState())\n\n onMounted(() => setupKeyboard())\n onUnmounted(() => {\n cleanupKeyboard()\n if (moveDebounceTimer) {\n clearTimeout(moveDebounceTimer)\n moveDebounceTimer = null\n }\n })\n\n return {\n scale, showGrid, snapToGrid, showTableGhostBorder,\n templateData, elements, fields,\n selectedIds, selectedElements, selectedElement, select, clearSelection, selectAll,\n previewIds, setPreview, clearPreview, commitPreview,\n hasClipboard, copy, paste, cutSelected,\n tableSelection, setTableSelection,\n canUndo, canRedo, undo, redo,\n recordHistory,\n alignSelected, groupSelected, ungroupSelected, deleteSelected,\n duplicateSelected, resetZoom,\n dragStart, dragStop,\n addElement, addFieldElement, moveLayer, fitToWindow, updateTemplateData,\n getTemplateJson, loadTemplate,\n }\n}\n","// web/src/components/print/composables/useGuides.ts\n// 手动参考线管理:增删改 + 吸附目标生成,增删改入历史栈\nimport { computed, type Ref } from 'vue'\nimport type { TemplateData, AlignLine } from '../types'\n\nlet guideSeq = 0\nfunction genId(): string {\n guideSeq += 1\n return `guide-${guideSeq}`\n}\n\nexport function useGuides(templateData: Ref<TemplateData>, recordHistory: () => void) {\n const guides = computed(() => templateData.value.guides ?? [])\n\n function mutate(fn: (list: AlignLine[]) => AlignLine[]) {\n templateData.value = {\n ...templateData.value,\n guides: fn([...(templateData.value.guides ?? [])]),\n }\n recordHistory()\n }\n\n function addGuide(type: 'vertical' | 'horizontal', position: number) {\n mutate(list => { list.push({ type, position, id: genId() }); return list })\n }\n function moveGuide(id: string, position: number) {\n mutate(list => list.map(g => g.id === id ? { ...g, position } : g))\n }\n function removeGuide(id: string) {\n mutate(list => list.filter(g => g.id !== id))\n }\n function getGuidePositions(): { vertical: number[]; horizontal: number[] } {\n const v: number[] = [], h: number[] = []\n for (const g of guides.value) {\n if (g.type === 'vertical') v.push(g.position)\n else h.push(g.position)\n }\n return { vertical: v, horizontal: h }\n }\n\n return { guides, addGuide, moveGuide, removeGuide, getGuidePositions }\n}\n","// 表格单元格选区跨组件共享契约:PrintDesigner provide,TableElement/PropertyPanel inject\nimport type { InjectionKey, Ref } from 'vue'\nimport type { TableSelection } from '../types'\n\nexport interface TableEditContext {\n tableSelection: Ref<TableSelection | null>\n setTableSelection: (s: TableSelection | null) => void\n recordHistory: () => void\n /** 页面打印范围宽度(mm)= 纸宽 - 左右边距,表格总列宽不得超过 */\n maxTableWidth: Ref<number>\n}\n\nexport const TABLE_EDIT_KEY: InjectionKey<TableEditContext> = Symbol('table-edit')\n","// 宿主能力注入键:开源核心不直接发请求、不内置业务字典,相关能力/数据由\n// PrintDesigner 经 props 接收后 provide,深层组件通过 inject 获取。\nimport type { ComputedRef, InjectionKey } from 'vue'\nimport type { UploadImageFn } from '../types'\n\n/** 图片上传适配器:PrintDesigner provide,ImageContentUpload inject */\nexport const UPLOAD_IMAGE_KEY: InjectionKey<ComputedRef<UploadImageFn | undefined>> =\n Symbol('print-upload-image')\n","<template>\n <div class=\"designer-toolbar\">\n <!-- 文件 -->\n <div class=\"tb-group\">\n <button class=\"tb-btn tb-icon\" title=\"返回\" @click=\"$emit('back')\">←</button>\n <span class=\"tb-mark\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"5\" y=\"3\" width=\"14\" height=\"18\" rx=\"2.5\" />\n <line x1=\"8.5\" y1=\"8.5\" x2=\"15.5\" y2=\"8.5\" />\n <line x1=\"8.5\" y1=\"12.5\" x2=\"15.5\" y2=\"12.5\" />\n <line x1=\"8.5\" y1=\"16.5\" x2=\"12.5\" y2=\"16.5\" />\n </svg>\n </span>\n <div class=\"tb-title\">\n <span class=\"tb-title-name\">{{ isEdit ? '编辑模板' : '新建模板' }}</span>\n <span class=\"tb-title-sub\">印刷工作台</span>\n </div>\n </div>\n <!-- 编辑 -->\n <div class=\"tb-group\">\n <button class=\"tb-btn tb-icon\" :disabled=\"!canUndo\" @click=\"$emit('undo')\" title=\"撤销\">↶</button>\n <button class=\"tb-btn tb-icon\" :disabled=\"!canRedo\" @click=\"$emit('redo')\" title=\"重做\">↷</button>\n </div>\n <!-- 对齐分布(多选) -->\n <div class=\"tb-group\" v-if=\"hasMultiSelection\">\n <button class=\"tb-btn tb-icon\" @click=\"$emit('align', 'left')\" title=\"左对齐\">⇤</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('align', 'right')\" title=\"右对齐\">⇥</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('align', 'top')\" title=\"顶对齐\">⇡</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('align', 'bottom')\" title=\"底对齐\">⇣</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('align', 'vertical')\" title=\"水平居中\">↔</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('align', 'horizontal')\" title=\"垂直居中\">↕</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('align', 'distributeHor')\" title=\"水平分布\">⇔</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('align', 'distributeVer')\" title=\"垂直分布\">⇕</button>\n </div>\n <!-- 组合 -->\n <div class=\"tb-group\" v-if=\"hasMultiSelection\">\n <button class=\"tb-btn\" @click=\"$emit('group')\" title=\"组合\">组合</button>\n </div>\n <div class=\"tb-group\" v-if=\"!hasMultiSelection && selectedElementHasGroup\">\n <button class=\"tb-btn\" @click=\"$emit('ungroup')\" title=\"取消组合\">取消组合</button>\n </div>\n <!-- 层级 -->\n <div class=\"tb-group\" v-if=\"hasSelection\">\n <button class=\"tb-btn tb-icon\" @click=\"$emit('move-layer', 'top')\" title=\"置顶\">⤒</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('move-layer', 'up')\" title=\"上移\">↑</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('move-layer', 'down')\" title=\"下移\">↓</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('move-layer', 'bottom')\" title=\"置底\">⤓</button>\n </div>\n <!-- 视图 -->\n <div class=\"tb-group\">\n <button class=\"tb-btn\" :class=\"{ on: showGrid }\" @click=\"$emit('toggle-grid')\">\n <span class=\"dot\" /> 网格\n </button>\n <button class=\"tb-btn\" :class=\"{ on: showTableGhostBorder }\" title=\"显示/隐藏无边框表格的虚拟虚线\" @click=\"$emit('toggle-table-ghost-border')\">\n <span class=\"dot\" /> 虚框\n </button>\n <button class=\"tb-btn\" :class=\"{ on: snapToGrid }\" @click=\"$emit('toggle-snap')\">\n <span class=\"dot\" /> 吸附\n </button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('fit-window')\" title=\"适应窗口\">⤢</button>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('zoom', -10)\" title=\"缩小\">−</button>\n <span class=\"tb-zoom\">{{ scale }}%</span>\n <button class=\"tb-btn tb-icon\" @click=\"$emit('zoom', 10)\" title=\"放大\">+</button>\n </div>\n <!-- 操作 -->\n <div class=\"tb-spacer\" />\n <div class=\"tb-group\">\n <button class=\"tb-btn\" @click=\"$emit('add-overlay-element')\">首页专属</button>\n <button class=\"tb-btn\" :class=\"{ warn: overlayVisible }\" @click=\"$emit('toggle-overlay')\">叠层对比</button>\n </div>\n <div class=\"tb-group\">\n <button v-if=\"showLoadDefault\" class=\"btn-secondary\" @click=\"$emit('load-default')\">加载默认布局</button>\n <button class=\"btn-secondary\" @click=\"$emit('preview')\">预览</button>\n <button class=\"btn-primary\" @click=\"$emit('save')\">保存</button>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nconst scale = defineModel<number>('scale', { default: 100 })\n\ndefineProps<{\n isEdit?: boolean\n canUndo?: boolean\n canRedo?: boolean\n hasMultiSelection?: boolean\n hasSelection?: boolean\n showGrid?: boolean\n snapToGrid?: boolean\n showTableGhostBorder?: boolean\n selectedElementHasGroup?: boolean\n overlayVisible?: boolean\n /** 是否展示「加载默认布局」按钮(宿主注入 loadDefaultTemplate 时由 PrintDesigner 开启) */\n showLoadDefault?: boolean\n}>()\n\ndefineEmits<{\n back: []\n preview: []\n save: []\n 'load-default': []\n undo: []\n redo: []\n align: [mode: string]\n 'move-layer': [direction: string]\n 'toggle-grid': []\n 'toggle-snap': []\n 'toggle-table-ghost-border': []\n 'toggle-overlay': []\n group: []\n ungroup: []\n 'add-overlay-element': []\n 'fit-window': []\n zoom: [delta: number]\n}>()\n</script>\n\n<style scoped>\n.designer-toolbar {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 0 12px;\n height: 50px;\n background: var(--pd-surface, #ffffff);\n border-bottom: 1px solid var(--pd-border-soft, #e9ecf2);\n box-shadow: 0 1px 2px rgba(23, 32, 60, .04), 0 6px 16px -12px rgba(23, 32, 60, .25);\n flex-shrink: 0;\n position: relative;\n z-index: 20;\n}\n.tb-group {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 0 8px;\n}\n.tb-group + .tb-group {\n border-left: 1px solid var(--pd-border-soft, #e9ecf2);\n}\n.tb-btn {\n height: 30px;\n min-width: 30px;\n padding: 0 8px;\n border-radius: 6px;\n border: 1px solid transparent;\n background: transparent;\n color: var(--pd-text-muted, #8b909c);\n font-size: 12px;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 5px;\n transition: background .14s ease, color .14s ease, border-color .14s ease, box-shadow .14s ease;\n}\n.tb-btn:hover {\n color: var(--pd-text, #2a2e37);\n background: var(--pd-sidebar-hover, #f0f3f9);\n}\n.tb-btn:active {\n background: var(--pd-border-soft, #e9ecf2);\n}\n.tb-btn:disabled {\n opacity: .32;\n cursor: default;\n background: transparent;\n color: var(--pd-text-faint, #b4b9c4);\n}\n.tb-btn.on {\n color: var(--pd-accent, #165DFF);\n background: var(--pd-accent-soft, rgba(22, 93, 255, .09));\n font-weight: 600;\n}\n.tb-btn.warn {\n color: var(--pd-accent-secondary, #f56c6c);\n background: var(--pd-danger-soft, rgba(245, 108, 108, .10));\n font-weight: 600;\n}\n.tb-btn .dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--pd-text-faint, #b4b9c4);\n display: inline-block;\n transition: background .14s ease, box-shadow .14s ease;\n}\n.tb-btn.on .dot {\n background: var(--pd-accent, #165DFF);\n box-shadow: 0 0 0 3px rgba(22, 93, 255, .12);\n}\n.tb-icon {\n font-size: 15px;\n line-height: 1;\n}\n.tb-mark {\n width: 28px;\n height: 28px;\n margin-right: 2px;\n border-radius: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: #fff;\n background: linear-gradient(150deg, var(--pd-accent-2, #3D7BFF), var(--pd-accent, #165DFF));\n box-shadow: 0 3px 8px rgba(22, 93, 255, .28), inset 0 1px 0 rgba(255, 255, 255, .22);\n flex-shrink: 0;\n}\n.tb-mark svg {\n width: 16px;\n height: 16px;\n}\n.tb-title {\n display: flex;\n flex-direction: column;\n line-height: 1.2;\n padding-left: 6px;\n}\n.tb-title-name {\n font-size: 13px;\n font-weight: 600;\n color: var(--pd-text, #2a2e37);\n letter-spacing: .2px;\n}\n.tb-title-sub {\n font-size: 10px;\n color: var(--pd-text-muted, #8b909c);\n letter-spacing: .8px;\n}\n.tb-zoom {\n font-size: 12px;\n color: var(--pd-text, #2a2e37);\n font-variant-numeric: tabular-nums;\n min-width: 46px;\n text-align: center;\n}\n.tb-spacer {\n flex: 1;\n}\n.btn-primary,\n.btn-secondary {\n height: 32px;\n padding: 0 16px;\n border-radius: 7px;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: filter .14s ease, background .14s ease, border-color .14s ease, box-shadow .14s ease;\n}\n.btn-secondary {\n background: var(--pd-field-bg, #f4f6fa);\n color: var(--pd-text-muted, #606266);\n border: 1px solid var(--pd-border, #d9dde6);\n}\n.btn-secondary:hover {\n border-color: var(--pd-accent, #165DFF);\n color: var(--pd-accent, #165DFF);\n background: var(--pd-accent-soft, rgba(22, 93, 255, .06));\n}\n.btn-primary {\n background: linear-gradient(180deg, var(--pd-accent-2, #3D7BFF), var(--pd-accent, #165DFF));\n color: #fff;\n border: none;\n box-shadow: 0 3px 10px rgba(22, 93, 255, .28), inset 0 1px 0 rgba(255, 255, 255, .18);\n}\n.btn-primary:hover {\n filter: brightness(1.07);\n box-shadow: 0 5px 14px rgba(22, 93, 255, .34), inset 0 1px 0 rgba(255, 255, 255, .18);\n}\n.btn-primary:active {\n filter: brightness(.97);\n}\n</style>\n","<template>\n <div class=\"layer-panel\">\n <div class=\"panel-title\">图层</div>\n <div\n v-for=\"layer in sortedLayers\"\n :key=\"layer.id\"\n class=\"layer-item\"\n :class=\"{ active: selectedIds.has(layer.id) }\"\n @click=\"$emit('select', layer.id, false)\"\n >\n <span class=\"layer-icon\">{{ layerIcon(layer) }}</span>\n <span class=\"layer-name\">{{ layerName(layer) }}</span>\n <span v-if=\"zoneTag(layer)\" class=\"layer-zone\">{{ zoneTag(layer) }}</span>\n <span class=\"layer-zindex\">z:{{ layer.options.zIndex ?? 0 }}</span>\n </div>\n <div class=\"layer-actions\" v-if=\"sortedLayers.length > 0\">\n <button type=\"button\" class=\"pd-button small\" @click=\"$emit('move-layer', 'top')\" title=\"置顶\">\n ⤒\n </button>\n <button type=\"button\" class=\"pd-button small\" @click=\"$emit('move-layer', 'up')\" title=\"上移\">\n ↑\n </button>\n <button type=\"button\" class=\"pd-button small\" @click=\"$emit('move-layer', 'down')\" title=\"下移\">\n ↓\n </button>\n <button type=\"button\" class=\"pd-button small\" @click=\"$emit('move-layer', 'bottom')\" title=\"置底\">\n ⤓\n </button>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { RuntimeElement } from '../types'\n\nconst props = defineProps<{\n elements: RuntimeElement[]\n selectedIds: Set<string>\n}>()\n\ndefineEmits<{\n select: [id: string, multiple: boolean]\n 'move-layer': [direction: string]\n}>()\n\nconst sortedLayers = computed(() =>\n [...props.elements].sort((a, b) => (b.options.zIndex ?? 0) - (a.options.zIndex ?? 0))\n)\n\nconst elementIconMap: Record<string, string> = {\n text: 'T',\n longText: '¶',\n table: '⊞',\n image: '🖼',\n barcode: '≡',\n qrcode: '▣',\n hline: '—',\n vline: '|',\n rect: '□',\n oval: '○',\n html: '<>',\n}\n\nfunction layerIcon(el: RuntimeElement): string {\n return elementIconMap[el.printElementType.type] || '?'\n}\n\nfunction layerName(el: RuntimeElement): string {\n return el.options.title || el.printElementType.title || el.printElementType.type\n}\n\nfunction zoneTag(el: RuntimeElement): string {\n if (el.zone === 'header') return '页眉'\n if (el.zone === 'footer') return '页脚'\n return ''\n}\n</script>\n\n<style scoped>\n.layer-panel {\n border-top: 1px solid var(--pd-border);\n padding: 8px 12px;\n height: 100%;\n box-sizing: border-box;\n overflow-y: auto;\n}\n.panel-title {\n font-size: 11px;\n color: var(--pd-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n}\n.layer-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 6px;\n margin-bottom: 2px;\n border-radius: 4px;\n cursor: pointer;\n font-size: 12px;\n transition: background 0.1s;\n}\n.layer-item:hover {\n background: var(--pd-sidebar-hover, #f0f2f5);\n}\n.layer-item.active {\n background: rgba(22, 93, 255, 0.10);\n color: var(--pd-accent, #165DFF);\n box-shadow: inset 2px 0 0 var(--pd-accent, #165DFF);\n}\n.layer-icon {\n width: 18px;\n text-align: center;\n font-size: 12px;\n color: var(--pd-text-muted, #909399);\n}\n.layer-name {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--pd-text, #303133);\n}\n.layer-zone {\n flex-shrink: 0;\n padding: 0 4px;\n font-size: 10px;\n line-height: 14px;\n color: var(--pd-ink-green, #67c23a);\n background: rgba(103, 194, 58, 0.1);\n border-radius: 3px;\n}\n.layer-zindex {\n font-size: 10px;\n color: var(--pd-text-muted, #909399);\n font-variant-numeric: tabular-nums;\n}\n.layer-actions {\n display: flex;\n gap: 4px;\n margin-top: 8px;\n}\n</style>\n","import type { PrintBusinessField } from '../types'\n\nexport interface FieldGroup {\n /** 分组键(fieldKey 首段);空串表示无分组的顶层字段 */\n key: string\n /** 分组显示名:取容器字段的 fieldLabel,缺省回退为 key */\n label: string\n /** 是否明细列表分组(容器字段 fieldType === 'list') */\n isList: boolean\n /** 分组下的叶子字段 */\n fields: PrintBusinessField[]\n}\n\n/**\n * 将宿主扁平字段按 fieldKey 首段分组:\n * - 带点路径(supplier.name、goods.spec)归入首段分组;\n * - 无点且作为其它字段前缀的记录视为分组容器(如 supplier/goods),\n * 容器提供分组名称,fieldType='list' 标识明细列表(表格数据源);\n * - 无点且无子字段的记录作为独立顶层字段。\n */\nexport function groupFields(fields: PrintBusinessField[]): FieldGroup[] {\n const sorted = [...fields].sort((a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0))\n const groupMap = new Map<string, FieldGroup>()\n const groupOrder: string[] = []\n\n for (const f of sorted) {\n const dot = f.fieldKey.indexOf('.')\n if (dot === -1) continue\n const key = f.fieldKey.slice(0, dot)\n let g = groupMap.get(key)\n if (!g) {\n g = { key, label: key, isList: false, fields: [] }\n groupMap.set(key, g)\n groupOrder.push(key)\n }\n g.fields.push(f)\n }\n\n const groups: FieldGroup[] = []\n const standalone: PrintBusinessField[] = []\n for (const f of sorted) {\n if (f.fieldKey.includes('.')) continue\n const g = groupMap.get(f.fieldKey)\n if (g) {\n // 容器记录:提供分组名称,列表容器(fieldType='list')用于表格数据源选择\n g.label = f.fieldLabel\n g.isList = f.fieldType === 'list'\n } else {\n standalone.push(f)\n }\n }\n if (standalone.length) groups.push({ key: '', label: '', isList: false, fields: standalone })\n for (const key of groupOrder) groups.push(groupMap.get(key)!)\n return groups\n}\n\n/** 按关键字过滤分组(匹配字段名/字段 key),无叶子的分组剔除 */\nexport function filterGroups(groups: FieldGroup[], keyword: string): FieldGroup[] {\n const kw = keyword.trim().toLowerCase()\n if (!kw) return groups\n return groups\n .map(g => ({\n ...g,\n fields: g.fields.filter(\n f => f.fieldLabel.toLowerCase().includes(kw) || f.fieldKey.toLowerCase().includes(kw),\n ),\n }))\n .filter(g => g.fields.length > 0)\n}\n","<template>\n <div class=\"field-tree-panel\">\n <div class=\"panel-title\">业务字段</div>\n <input v-model=\"searchText\" class=\"pd-input search-input\" type=\"search\" placeholder=\"搜索字段...\" aria-label=\"搜索字段\" />\n <div class=\"tree-container\">\n <template v-for=\"group in filteredGroups\" :key=\"group.key || '_top'\">\n <div\n v-if=\"group.key\"\n class=\"field-group-header\"\n :class=\"{ 'is-list': group.isList }\"\n @click=\"toggleGroup(group.key)\"\n >\n <span class=\"expand-icon\">{{ collapsedGroups.has(group.key) && !searching ? '▶' : '▼' }}</span>\n <span class=\"node-icon\">{{ group.isList ? '📋' : '📁' }}</span>\n <span class=\"group-label\">{{ group.label }}</span>\n </div>\n <div v-show=\"!group.key || searching || !collapsedGroups.has(group.key)\">\n <div\n v-for=\"field in group.fields\"\n :key=\"field.fieldKey\"\n class=\"field-row\"\n draggable=\"true\"\n :style=\"{ paddingLeft: (group.key ? 22 : 8) + 'px' }\"\n @dragstart=\"onDragStart($event, field)\"\n >\n <span class=\"node-icon\">📄</span>\n <span class=\"node-label\">{{ field.fieldLabel }}</span>\n <span class=\"node-key\">({{ field.fieldKey }})</span>\n </div>\n </div>\n </template>\n </div>\n <p v-if=\"filteredGroups.length === 0\" class=\"pd-empty\">暂无字段</p>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed } from 'vue'\nimport type { PrintBusinessField } from '../types'\nimport { groupFields, filterGroups } from '../utils/field-groups'\n\nconst props = defineProps<{\n fields: PrintBusinessField[]\n}>()\n\nconst emit = defineEmits<{\n 'field-drag': [field: PrintBusinessField]\n}>()\n\nconst searchText = ref('')\nconst collapsedGroups = ref<Set<string>>(new Set())\n\nconst searching = computed(() => !!searchText.value.trim())\nconst filteredGroups = computed(() =>\n filterGroups(groupFields(props.fields), searchText.value),\n)\n\nfunction toggleGroup(key: string) {\n const next = new Set(collapsedGroups.value)\n if (next.has(key)) next.delete(key)\n else next.add(key)\n collapsedGroups.value = next\n}\n\nfunction onDragStart(event: DragEvent, field: PrintBusinessField) {\n // 拖拽载荷为完整字段路径(如 goods.spec),与打印数据结构一致\n event.dataTransfer?.setData('fieldData', JSON.stringify({ fieldKey: field.fieldKey, fieldLabel: field.fieldLabel }))\n if (event.dataTransfer) event.dataTransfer.effectAllowed = 'copy'\n emit('field-drag', field)\n}\n</script>\n\n<style scoped>\n.field-tree-panel {\n padding: 0;\n}\n.panel-title {\n font-size: 11px;\n color: var(--pd-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n padding: 4px 0 8px;\n margin-bottom: 8px;\n border-bottom: 1px solid var(--pd-border);\n}\n.search-input {\n margin-bottom: 8px;\n}\n.tree-container {\n overflow-y: auto;\n min-height: 0;\n}\n.field-group-header {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 5px 8px;\n border-radius: 4px;\n font-size: 13px;\n color: var(--pd-text, #303133);\n cursor: pointer;\n user-select: none;\n transition: background 0.1s;\n}\n.field-group-header:hover {\n background: var(--pd-sidebar-hover, #f0f2f5);\n}\n.field-group-header.is-list {\n color: var(--pd-accent, #165DFF);\n font-weight: 500;\n}\n.expand-icon {\n width: 12px;\n font-size: 8px;\n flex-shrink: 0;\n color: var(--pd-text-muted, #909399);\n}\n.field-row {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 5px 8px;\n border-radius: 4px;\n font-size: 13px;\n color: var(--pd-text, #303133);\n cursor: grab;\n user-select: none;\n transition: background 0.1s;\n}\n.field-row:hover {\n background: var(--pd-sidebar-hover, #f0f2f5);\n}\n.node-icon {\n font-size: 14px;\n flex-shrink: 0;\n filter: saturate(.6);\n opacity: .9;\n}\n.node-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.node-key {\n font-size: 11px;\n color: var(--pd-text-muted, #909399);\n flex-shrink: 0;\n}\n.group-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n</style>\n","<template>\n <div class=\"left-panel\" :class=\"{ collapsed }\">\n <!-- 折叠态:竖排图标,点击即展开对应页签 -->\n <div v-if=\"collapsed\" class=\"left-collapsed\">\n <button class=\"lc-btn\" title=\"展开素材台\" @click=\"expandTab(activeTab)\">»</button>\n <button class=\"lc-btn\" :class=\"{ on: activeTab === 'elements' }\" title=\"元素\" @click=\"expandTab('elements')\">▦</button>\n <button class=\"lc-btn\" :class=\"{ on: activeTab === 'fields' }\" title=\"字段\" @click=\"expandTab('fields')\">⊛</button>\n <button class=\"lc-btn\" :class=\"{ on: activeTab === 'layers' }\" title=\"图层\" @click=\"expandTab('layers')\">≡</button>\n </div>\n <template v-else>\n <div class=\"left-head\">\n <span class=\"left-title\">素材台</span>\n <button class=\"collapse-btn\" title=\"收起素材台\" @click=\"$emit('toggle-collapse')\">«</button>\n </div>\n <div class=\"pd-tabs left-tabs\">\n <div class=\"pd-tab-bar\" role=\"tablist\">\n <button type=\"button\" class=\"pd-tab\" :class=\"{ active: activeTab === 'elements' }\" @click=\"activeTab = 'elements'\">元素</button>\n <button type=\"button\" class=\"pd-tab\" :class=\"{ active: activeTab === 'fields' }\" @click=\"activeTab = 'fields'\">字段</button>\n <button type=\"button\" class=\"pd-tab\" :class=\"{ active: activeTab === 'layers' }\" @click=\"activeTab = 'layers'\">图层</button>\n </div>\n <div v-show=\"activeTab === 'elements'\" class=\"pd-tab-pane\" role=\"tabpanel\">\n <div class=\"panel-title\">拖拽元素到画布</div>\n <div\n v-for=\"item in elementTypes\"\n :key=\"item.type\"\n class=\"material-card\"\n draggable=\"true\"\n @dragstart=\"onDragStart($event, item.type)\"\n >\n <span class=\"material-icon\">{{ item.icon }}</span>\n <span class=\"material-label\">{{ item.label }}</span>\n </div>\n </div>\n <div v-show=\"activeTab === 'fields'\" class=\"pd-tab-pane\" role=\"tabpanel\">\n <FieldTreePanel\n :fields=\"fields\"\n @field-drag=\"onFieldDrag\"\n />\n </div>\n <div v-show=\"activeTab === 'layers'\" class=\"pd-tab-pane\" role=\"tabpanel\">\n <LayerPanel\n :elements=\"elements\"\n :selected-ids=\"selectedIds\"\n @select=\"(id: string, m: boolean) => $emit('select', id, m)\"\n @move-layer=\"(d: string) => $emit('move-layer', d)\"\n @toggle-visible=\"(id: string) => $emit('toggle-visible', id)\"\n @toggle-locked=\"(id: string) => $emit('toggle-locked', id)\"\n />\n </div>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport type { ElementType, PrintBusinessField, RuntimeElement } from '../types'\nimport LayerPanel from './LayerPanel.vue'\nimport FieldTreePanel from './FieldTreePanel.vue'\n\ndefineProps<{\n fields: PrintBusinessField[]\n elements: RuntimeElement[]\n selectedIds: Set<string>\n collapsed: boolean\n}>()\n\nconst emit = defineEmits<{\n select: [id: string, multiple: boolean]\n 'move-layer': [direction: string]\n 'toggle-visible': [id: string]\n 'toggle-locked': [id: string]\n 'field-drag': [field: PrintBusinessField]\n 'toggle-collapse': []\n}>()\n\nconst activeTab = ref('elements')\n\nconst elementTypes: { type: ElementType; label: string; icon: string }[] = [\n { type: 'text', label: '文本', icon: 'T' },\n { type: 'barcode', label: '条形码', icon: '▍▍' },\n { type: 'qrcode', label: '二维码', icon: '▦' },\n { type: 'image', label: '图片', icon: '▧' },\n { type: 'table', label: '表格', icon: '⊞' },\n { type: 'longText', label: '长文', icon: '¶' },\n { type: 'hline', label: '横线', icon: '―' },\n { type: 'vline', label: '竖线', icon: '│' },\n { type: 'rect', label: '矩形', icon: '▭' },\n { type: 'oval', label: '椭圆', icon: '◯' },\n { type: 'html', label: 'HTML', icon: '<>' },\n]\n\nfunction onDragStart(event: DragEvent, type: string) {\n event.dataTransfer?.setData('elementType', type)\n}\n\nfunction onFieldDrag(field: PrintBusinessField) {\n emit('field-drag', field)\n}\n\nfunction expandTab(tab: string) {\n activeTab.value = tab\n emit('toggle-collapse')\n}\n</script>\n\n<style scoped>\n.left-panel {\n width: 224px;\n min-width: 224px;\n background: var(--pd-sidebar, #ffffff);\n border-right: 1px solid var(--pd-border-soft, #e9ecf2);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n transition: width .18s ease;\n}\n.left-panel.collapsed {\n width: 36px;\n min-width: 36px;\n border-right: 1px solid var(--pd-border-soft, #e9ecf2);\n}\n.left-collapsed {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding-top: 12px;\n flex: 1;\n}\n.lc-btn {\n width: 26px;\n height: 26px;\n border-radius: 6px;\n border: 1px solid transparent;\n background: transparent;\n color: var(--pd-text-muted, #8b909c);\n font-size: 12px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all .14s ease;\n}\n.lc-btn:hover {\n color: var(--pd-text, #2a2e37);\n background: var(--pd-sidebar-hover, #f0f3f9);\n}\n.lc-btn.on {\n color: var(--pd-accent, #165DFF);\n background: var(--pd-accent-soft, rgba(22, 93, 255, .09));\n}\n.left-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n height: 42px;\n padding: 0 12px;\n flex-shrink: 0;\n border-bottom: 1px solid var(--pd-border-soft, #e9ecf2);\n}\n.left-title {\n font-size: 12px;\n font-weight: 600;\n color: var(--pd-text, #2a2e37);\n letter-spacing: 1.2px;\n display: inline-flex;\n align-items: center;\n gap: 7px;\n}\n.left-title::before {\n content: \"\";\n width: 3px;\n height: 12px;\n border-radius: 2px;\n background: linear-gradient(180deg, var(--pd-accent-2, #3D7BFF), var(--pd-accent, #165DFF));\n}\n.collapse-btn {\n border: none;\n background: transparent;\n color: var(--pd-text-muted, #8b909c);\n font-size: 14px;\n cursor: pointer;\n width: 24px;\n height: 24px;\n border-radius: 5px;\n transition: all .14s ease;\n}\n.collapse-btn:hover {\n color: var(--pd-text, #2a2e37);\n background: var(--pd-sidebar-hover, #f0f3f9);\n}\n.left-tabs {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.left-tabs .pd-tab-pane {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 12px;\n}\n.panel-title {\n font-size: 11px;\n color: var(--pd-text-muted, #8b909c);\n letter-spacing: .6px;\n padding: 2px 2px 8px;\n margin-bottom: 10px;\n border-bottom: 1px solid var(--pd-border-soft, #e9ecf2);\n}\n.material-card {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 10px;\n margin-bottom: 7px;\n border: 1px solid var(--pd-border-soft, #e9ecf2);\n border-radius: 8px;\n background: var(--pd-field-bg, #f4f6fa);\n cursor: grab;\n user-select: none;\n transition: border-color .14s ease, background .14s ease, transform .14s ease, box-shadow .14s ease;\n}\n.material-card:hover {\n border-color: rgba(22, 93, 255, .45);\n background: var(--pd-surface, #ffffff);\n transform: translateY(-1px);\n box-shadow: var(--pd-shadow-sm, 0 1px 2px rgba(23, 32, 60, .05));\n}\n.material-card:active {\n cursor: grabbing;\n transform: translateY(0);\n}\n.material-icon {\n width: 30px;\n height: 24px;\n border: 1px dashed var(--pd-border, #d9dde6);\n border-radius: 5px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n color: var(--pd-accent, #165DFF);\n background: var(--pd-surface, #ffffff);\n flex-shrink: 0;\n transition: border-color .14s ease, background .14s ease;\n}\n.material-card:hover .material-icon {\n border-style: solid;\n border-color: var(--pd-accent, #165DFF);\n background: var(--pd-accent-soft, rgba(22, 93, 255, .09));\n}\n.material-label {\n font-size: 12.5px;\n color: var(--pd-text, #2a2e37);\n}\n</style>\n","// web/src/components/print/composables/useDrag.ts\nimport { ref } from 'vue'\nimport type { AdsorbResult } from '../types'\n\nexport interface DragOptions {\n axis?: 'x' | 'y'\n disabled?: boolean\n getScale?: () => number\n /** 拖拽过程中每帧回调,提供修正后的绝对坐标(调用方用 transform 做视觉跟随) */\n onDrag: (pos: { left: number; top: number }) => void\n /** 拖拽结束回调,提供最终坐标与修饰符信息(调用方一次性写入响应式数据) */\n onDragEnd?: (pos: { left: number; top: number }, info: { altKey: boolean }) => void\n onStart?: (info: { altKey: boolean }) => void\n onStop?: () => void\n onAdsorb?: (pos: { left: number; top: number; width: number; height: number }) => AdsorbResult\n}\n\nexport function useDrag(target: { value: HTMLElement | null }, options: DragOptions) {\n const isDragging = ref(false)\n /** 拖拽预览状态:半透明副本的绝对坐标与尺寸(pt),供上层渲染预览层 */\n const dragPreview = ref<{ left: number; top: number; width: number; height: number } | null>(null)\n\n let startX = 0, startY = 0\n let startLeft = 0, startTop = 0\n // 记录 mousedown 时的 altKey,供 onDragEnd 判定是否复制\n let downAltKey = false\n\n function onMouseDown(e: MouseEvent) {\n if (options.disabled) return\n // 忽略 resize 手柄点击\n const targetEl = e.target\n if (!(targetEl instanceof HTMLElement) || targetEl.classList.contains('resize-handle')) return\n\n isDragging.value = true\n downAltKey = e.altKey\n startX = e.clientX\n startY = e.clientY\n\n const el = target.value\n if (!el) return\n startLeft = parseFloat(el.style.left) || 0\n startTop = parseFloat(el.style.top) || 0\n // 初始化拖拽预览副本(记录起始位置与尺寸)\n dragPreview.value = {\n left: startLeft,\n top: startTop,\n width: parseFloat(el.style.width) || 0,\n height: parseFloat(el.style.height) || 0,\n }\n\n options.onStart?.({ altKey: downAltKey })\n\n document.addEventListener('mousemove', onMouseMove)\n document.addEventListener('mouseup', onMouseUp)\n e.preventDefault()\n }\n\n /** 由鼠标坐标计算吸附修正后的绝对坐标 */\n function computePos(e: MouseEvent) {\n const scale = options.getScale?.() ?? 1\n let newLeft = startLeft + (e.clientX - startX) / scale\n let newTop = startTop + (e.clientY - startY) / scale\n\n if (options.axis === 'x') newTop = startTop\n if (options.axis === 'y') newLeft = startLeft\n\n if (options.onAdsorb) {\n const el = target.value\n if (el) {\n const w = parseFloat(el.style.width) || 0\n const h = parseFloat(el.style.height) || 0\n const result = options.onAdsorb({ left: newLeft, top: newTop, width: w, height: h })\n newLeft = result.left\n newTop = result.top\n }\n }\n return { left: newLeft, top: newTop }\n }\n\n function onMouseMove(e: MouseEvent) {\n const pos = computePos(e)\n // 更新预览副本位置(响应式,供渲染层实时跟随)\n if (dragPreview.value) {\n dragPreview.value.left = pos.left\n dragPreview.value.top = pos.top\n }\n options.onDrag(pos)\n }\n\n function onMouseUp(e: MouseEvent) {\n isDragging.value = false\n const pos = computePos(e)\n // 一次性通知调用方最终坐标与修饰符,写入响应式数据\n options.onDragEnd?.(pos, { altKey: downAltKey })\n options.onStop?.()\n // 清空预览副本\n dragPreview.value = null\n\n document.removeEventListener('mousemove', onMouseMove)\n document.removeEventListener('mouseup', onMouseUp)\n }\n\n function cleanup() {\n const el = target.value\n if (el) {\n el.removeEventListener('mousedown', onMouseDown)\n }\n document.removeEventListener('mousemove', onMouseMove)\n document.removeEventListener('mouseup', onMouseUp)\n }\n\n function setup() {\n cleanup()\n const el = target.value\n if (el) {\n el.addEventListener('mousedown', onMouseDown)\n }\n }\n\n return { isDragging, dragPreview, setup, cleanup }\n}\n","// web/src/components/print/composables/useResize.ts\nimport type { ResizePoint } from '../types'\n\nexport interface ResizeRect {\n left: number\n top: number\n width: number\n height: number\n}\n\nexport interface ResizeOptions {\n minWidth?: number\n minHeight?: number\n getScale?: () => number\n /** 缩放起始时读取元素当前矩形(mm) */\n getRect: () => ResizeRect\n onResize: (rect: ResizeRect) => void\n onStart?: () => void\n onStop?: () => void\n}\n\n/** 8 方位缩放手柄,供模板 v-for 渲染 */\nexport const RESIZE_POINTS: ResizePoint[] = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w']\n\n/** 根据方位与位移计算缩放后矩形(纯函数) */\nexport function calcResizeRect(\n point: ResizePoint,\n startRect: ResizeRect,\n dx: number,\n dy: number,\n minW: number,\n minH: number,\n): ResizeRect {\n let { left, top, width, height } = startRect\n\n switch (point) {\n case 'e': width = Math.max(minW, startRect.width + dx); break\n case 'w': width = Math.max(minW, startRect.width - dx); left = startRect.left + startRect.width - width; break\n case 's': height = Math.max(minH, startRect.height + dy); break\n case 'n': height = Math.max(minH, startRect.height - dy); top = startRect.top + startRect.height - height; break\n case 'se': width = Math.max(minW, startRect.width + dx); height = Math.max(minH, startRect.height + dy); break\n case 'sw': width = Math.max(minW, startRect.width - dx); left = startRect.left + startRect.width - width; height = Math.max(minH, startRect.height + dy); break\n case 'ne': width = Math.max(minW, startRect.width + dx); height = Math.max(minH, startRect.height - dy); top = startRect.top + startRect.height - height; break\n case 'nw': width = Math.max(minW, startRect.width - dx); left = startRect.left + startRect.width - width; height = Math.max(minH, startRect.height - dy); top = startRect.top + startRect.height - height; break\n }\n\n return { left, top, width, height }\n}\n\n/** 缩放交互逻辑:手柄由组件模板渲染,mousedown 时调用 startResize */\nexport function useResize(options: ResizeOptions) {\n let startX = 0, startY = 0\n let startRect: ResizeRect = { left: 0, top: 0, width: 0, height: 0 }\n let activePoint: ResizePoint | null = null\n\n function startResize(point: ResizePoint, e: MouseEvent) {\n activePoint = point\n startX = e.clientX\n startY = e.clientY\n startRect = { ...options.getRect() }\n options.onStart?.()\n document.addEventListener('mousemove', onResizeMove)\n document.addEventListener('mouseup', onResizeEnd)\n e.preventDefault()\n }\n\n function onResizeMove(e: MouseEvent) {\n if (!activePoint) {\n return\n }\n const scale = options.getScale?.() || 1\n const dx = (e.clientX - startX) / scale\n const dy = (e.clientY - startY) / scale\n const minW = options.minWidth || 20\n const minH = options.minHeight || 20\n options.onResize(calcResizeRect(activePoint, startRect, dx, dy, minW, minH))\n }\n\n function onResizeEnd() {\n activePoint = null\n options.onStop?.()\n document.removeEventListener('mousemove', onResizeMove)\n document.removeEventListener('mouseup', onResizeEnd)\n }\n\n function cleanup() {\n document.removeEventListener('mousemove', onResizeMove)\n document.removeEventListener('mouseup', onResizeEnd)\n }\n\n return { startResize, cleanup }\n}\n","import { getDemoData } from '../utils/demo-data'\n\ninterface BindingDisplayState {\n status: 'unbound' | 'bound' | 'warning' | 'error'\n badge: string\n badgeColor: string\n demoPreview: string\n warning?: string\n}\n\nfunction getNestedValue(obj: any, path: string): any {\n return path.split('.').reduce((current, key) => current?.[key], obj)\n}\n\nexport function useBindingDisplay() {\n function getBindingDisplayState(element: any): BindingDisplayState {\n const formatter = element.options.formatter\n const title = element.options.title\n\n if (!formatter) {\n return {\n status: 'unbound',\n badge: title || '文本',\n badgeColor: '#909399',\n demoPreview: title || '文本',\n }\n }\n\n const demoData = getDemoData()\n // 简单预览:从 formatter 中提取字段名并查找 demo 数据\n const fieldMatch = formatter.match(/\\{([^}]+)\\}/)\n if (fieldMatch) {\n const fieldPath = fieldMatch[1]\n const demoValue = getNestedValue(demoData, fieldPath)\n return {\n status: 'bound',\n badge: `fx ${formatter}`,\n badgeColor: '#409EFF',\n demoPreview: demoValue != null ? String(demoValue) : formatter,\n }\n }\n\n return {\n status: 'bound',\n badge: `fx ${formatter}`,\n badgeColor: '#409EFF',\n demoPreview: formatter,\n }\n }\n\n return { getBindingDisplayState }\n}\n","<template>\n <div class=\"print-text\" :style=\"textStyle\">\n {{ displayText }}\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { RuntimeElement } from '../../types'\nimport { resolveTextBinding } from '../../utils/binding'\n\nconst props = defineProps<{\n element: RuntimeElement\n data?: Record<string, any>[]\n designMode?: boolean\n}>()\n\nconst V_ALIGN_FLEX: Record<string, string> = { top: 'flex-start', middle: 'center', bottom: 'flex-end' }\nconst H_ALIGN_FLEX: Record<string, string> = { left: 'flex-start', center: 'center', right: 'flex-end' }\n\nconst textStyle = computed(() => {\n const o = props.element.options\n return {\n fontSize: (o.fontSize || 12) + 'pt',\n fontWeight: o.fontWeight || 'normal',\n fontFamily: o.fontFamily || 'inherit',\n color: o.color || '#333',\n backgroundColor: o.backgroundColor || 'transparent',\n textAlign: o.textAlign || 'left',\n lineHeight: o.lineHeight ? o.lineHeight + 'pt' : 'normal',\n letterSpacing: o.letterSpacing ? o.letterSpacing + 'pt' : 'normal',\n textDecoration: o.textDecoration || 'none',\n padding: `${o.contentPaddingTop || 0}pt ${o.contentPaddingRight || 0}pt ${o.contentPaddingBottom || 0}pt ${o.contentPaddingLeft || 0}pt`,\n width: '100%',\n height: '100%',\n boxSizing: 'border-box' as const,\n overflow: 'hidden',\n ...(o.verticalAlign\n ? {\n display: 'flex',\n alignItems: V_ALIGN_FLEX[o.verticalAlign] ?? 'flex-start',\n justifyContent: H_ALIGN_FLEX[o.textAlign || 'left'] ?? 'flex-start',\n }\n : {}),\n }\n})\n\nconst displayText = computed(() => {\n if (props.designMode) {\n if (props.element.options.testData) {\n return props.element.options.testData\n }\n return props.element.options.formatter || '文本'\n }\n return resolveTextBinding(props.element.options, props.data)\n})\n</script>\n","<template>\n <div class=\"print-image\">\n <img v-if=\"imageSrc && !hasError\" :src=\"imageSrc\" :style=\"imgStyle\" @error=\"onError\" />\n <div v-else class=\"image-placeholder\">图片</div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport type { RuntimeElement } from '../../types'\nimport { evaluateTemplate } from '../../utils/expression-eval'\nimport { DEFAULT_DEMO_DATA } from '../../utils/demo-data'\n\nconst props = defineProps<{\n element: RuntimeElement\n data?: Record<string, any>[]\n designMode?: boolean\n}>()\n\nconst imageSrc = computed(() => {\n const raw = props.element.options.src || ''\n if (!raw) return ''\n // {字段} 表达式:设计态用 demo 数据求值,运行态用打印数据求值\n if (raw.includes('{')) {\n if (props.designMode) {\n return evaluateTemplate(raw, DEFAULT_DEMO_DATA)\n }\n return evaluateTemplate(raw, props.data?.[0] || {})\n }\n // 相对路径(如 /docfiles/...)经站点同源 + dev/prod 代理可直接访问;绝对 URL 原样使用\n return raw\n})\n\n// 加载失败兜底:显示占位,避免破图阻塞 PDF 就绪判定\nconst hasError = ref(false)\nfunction onError() {\n hasError.value = true\n}\n// src 变化时重置错误态\nwatch(imageSrc, () => {\n hasError.value = false\n})\n\nconst imgStyle = computed(() => ({\n objectFit: (props.element.options.fit || 'contain') as any,\n}))\n</script>\n\n<style scoped>\n.print-image { width: 100%; height: 100%; overflow: hidden; }\n.print-image img { width: 100%; height: 100%; display: block; }\n.image-placeholder {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #bbb;\n font-size: 12px;\n border: 1px dashed #ddd;\n box-sizing: border-box;\n}\n</style>\n","<template>\n <div class=\"print-longtext\" :style=\"textStyle\">\n {{ displayText }}\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { RuntimeElement } from '../../types'\nimport { resolveTextBinding } from '../../utils/binding'\n\nconst props = defineProps<{\n element: RuntimeElement\n data?: Record<string, any>[]\n designMode?: boolean\n}>()\n\nconst V_ALIGN_FLEX: Record<string, string> = { top: 'flex-start', middle: 'center', bottom: 'flex-end' }\nconst H_ALIGN_FLEX: Record<string, string> = { left: 'flex-start', center: 'center', right: 'flex-end' }\n\nconst textStyle = computed(() => {\n const o = props.element.options\n return {\n fontSize: (o.fontSize || 12) + 'pt',\n fontWeight: o.fontWeight || 'normal',\n fontFamily: o.fontFamily || 'inherit',\n color: o.color || '#333',\n backgroundColor: o.backgroundColor || 'transparent',\n textAlign: o.textAlign || 'left',\n lineHeight: o.lineHeight ? o.lineHeight + 'pt' : '1.5',\n letterSpacing: o.letterSpacing ? o.letterSpacing + 'pt' : 'normal',\n textIndent: o.longTextIndent ? o.longTextIndent + 'pt' : '0',\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n wordBreak: 'break-all' as const,\n boxSizing: 'border-box' as const,\n ...(o.verticalAlign\n ? {\n display: 'flex',\n alignItems: V_ALIGN_FLEX[o.verticalAlign] ?? 'flex-start',\n justifyContent: H_ALIGN_FLEX[o.textAlign || 'left'] ?? 'flex-start',\n }\n : {}),\n }\n})\n\nconst displayText = computed(() => {\n if (props.designMode) {\n if (props.element.options.formatter) return props.element.options.formatter\n return '长文本内容'\n }\n return resolveTextBinding(props.element.options, props.data)\n})\n</script>\n","<!-- 表格右键菜单:行列增删/合并拆分/行类型切换 -->\n<template>\n <Teleport to=\"body\">\n <div\n v-if=\"visible\"\n class=\"table-ctx-menu\"\n :style=\"{ left: x + 'px', top: y + 'px' }\"\n @mousedown.stop\n >\n <div class=\"menu-item\" @click=\"emitAction('insert-row-above')\">在上方插入行</div>\n <div class=\"menu-item\" @click=\"emitAction('insert-row-below')\">在下方插入行</div>\n <div\n class=\"menu-item\"\n :class=\"{ disabled: !canDeleteRow }\"\n @click=\"canDeleteRow && emitAction('delete-row')\"\n >\n 删除行\n </div>\n <div class=\"menu-divider\" />\n <div class=\"menu-item\" @click=\"emitAction('insert-col-left')\">在左侧插入列</div>\n <div class=\"menu-item\" @click=\"emitAction('insert-col-right')\">在右侧插入列</div>\n <div\n class=\"menu-item\"\n :class=\"{ disabled: !canDeleteCol }\"\n @click=\"canDeleteCol && emitAction('delete-col')\"\n >\n 删除列\n </div>\n <div class=\"menu-divider\" />\n <div\n class=\"menu-item\"\n :class=\"{ disabled: !!mergeDisabledReason }\"\n :title=\"mergeDisabledReason || ''\"\n @click=\"!mergeDisabledReason && emitAction('merge')\"\n >\n 合并单元格\n </div>\n <div\n class=\"menu-item\"\n :class=\"{ disabled: !canSplit }\"\n @click=\"canSplit && emitAction('split')\"\n >\n 拆分单元格\n </div>\n <div class=\"menu-divider\" />\n <div class=\"menu-group-title\">行类型</div>\n <div\n v-for=\"t in ROW_TYPES\"\n :key=\"t.value\"\n class=\"menu-item\"\n :class=\"{ disabled: !!rowTypeDisabledReason(t.value), active: currentRowType === t.value }\"\n :title=\"rowTypeDisabledReason(t.value) || ''\"\n @click=\"!rowTypeDisabledReason(t.value) && emitAction('set-row-type', t.value)\"\n >\n {{ t.label }}\n </div>\n </div>\n </Teleport>\n</template>\n\n<script setup lang=\"ts\">\nimport type { TableRowType } from '../../types'\n\nconst ROW_TYPES: { value: TableRowType; label: string }[] = [\n { value: 'header', label: '标题行' },\n { value: 'data', label: '数据行' },\n { value: 'subtotal', label: '小计行' },\n { value: 'summary', label: '汇总行' },\n]\n\ndefineProps<{\n visible: boolean\n x: number\n y: number\n canDeleteRow: boolean\n canDeleteCol: boolean\n mergeDisabledReason: string | null\n canSplit: boolean\n currentRowType: TableRowType | null\n rowTypeDisabledReason: (t: TableRowType) => string | null\n}>()\n\nconst emit = defineEmits<{ action: [name: string, payload?: string] }>()\n\nfunction emitAction(name: string, payload?: string) {\n emit('action', name, payload)\n}\n</script>\n\n<style scoped>\n.table-ctx-menu {\n position: fixed;\n z-index: 3000;\n min-width: 140px;\n padding: 4px 0;\n background: #fff;\n border: 1px solid #dcdfe6;\n border-radius: 4px;\n box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);\n font-size: 13px;\n}\n.menu-item {\n padding: 5px 14px;\n cursor: pointer;\n color: #333;\n}\n.menu-item:hover {\n background: #f5f7fa;\n}\n.menu-item.disabled {\n color: #c0c4cc;\n cursor: not-allowed;\n}\n.menu-item.active {\n color: #165DFF;\n}\n.menu-divider {\n height: 1px;\n margin: 4px 0;\n background: #ebeef5;\n}\n.menu-group-title {\n padding: 4px 14px;\n font-size: 12px;\n color: #909399;\n}\n</style>\n","<!-- 表格单元格内条形码/二维码渲染:设计态与预览态共用,按值生成图形 -->\n<template>\n <div class=\"cell-barcode\">\n <svg v-show=\"cellType === 'barcode' && svgOk\" ref=\"barcodeSvg\" preserveAspectRatio=\"xMidYMid meet\"></svg>\n <img v-if=\"cellType === 'qrcode' && dataUrl\" :src=\"dataUrl\" alt=\"qrcode\" />\n <span v-if=\"!svgOk && cellType === 'barcode'\" class=\"cell-barcode-fallback\">{{ value || '条码' }}</span>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, watch } from 'vue'\nimport JsBarcode from 'jsbarcode'\nimport QRCode from 'qrcode'\n\nconst props = defineProps<{\n cellType: 'barcode' | 'qrcode'\n value: string\n barcodeType?: string\n qrCodeLevel?: string\n showText?: boolean\n}>()\n\nconst barcodeSvg = ref<SVGSVGElement | null>(null)\nconst svgOk = ref(false)\nconst dataUrl = ref('')\n\nfunction renderBarcode() {\n svgOk.value = false\n if (!barcodeSvg.value) return\n try {\n JsBarcode(barcodeSvg.value, props.value, {\n format: (props.barcodeType || 'CODE128') as any,\n width: 1,\n height: 28,\n displayValue: props.showText !== false,\n fontSize: 9,\n margin: 0,\n })\n svgOk.value = true\n } catch { /* 码值不符合码制时回退文本占位 */ }\n}\n\nasync function renderQrcode() {\n if (!props.value) {\n dataUrl.value = ''\n return\n }\n try {\n dataUrl.value = await QRCode.toDataURL(props.value, {\n width: 96,\n margin: 1,\n errorCorrectionLevel: ((props.qrCodeLevel || 'M') as 'L' | 'M' | 'Q' | 'H'),\n })\n } catch {\n dataUrl.value = ''\n }\n}\n\nfunction render() {\n if (props.cellType === 'barcode') renderBarcode()\n else renderQrcode()\n}\n\nonMounted(render)\nwatch(() => [props.cellType, props.value, props.barcodeType, props.qrCodeLevel, props.showText], render)\n</script>\n\n<style scoped>\n.cell-barcode { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; overflow: hidden; }\n/* JsBarcode svg 自带 viewBox,100% + preserveAspectRatio 使条码按单元格等比缩放填满 */\n.cell-barcode svg { width: 100%; height: 100%; }\n.cell-barcode img { max-width: 100%; max-height: 100%; }\n.cell-barcode-fallback { font-style: italic; opacity: 0.6; }\n</style>\n","<!-- Excel 风格表格元素:单元格矩阵编辑器(选区/右键菜单/双击编辑) -->\n<template>\n <div class=\"print-table\" :class=\"{ 'design-mode': designMode }\" @contextmenu.prevent>\n <table ref=\"tableRef\" :style=\"{ fontSize: defaultFontSize + 'pt', color: defaultColor }\">\n <colgroup>\n <col v-for=\"(w, i) in colWidths\" :key=\"i\" :style=\"{ width: w + 'mm' }\" />\n </colgroup>\n <tbody>\n <tr v-for=\"(row, ri) in rows\" :key=\"row.id\" :style=\"{ height: row.height + 'mm' }\">\n <template v-for=\"(cell, ci) in row.cells\" :key=\"cell.id\">\n <td\n v-if=\"!cell.merged\"\n :rowspan=\"cell.rowspan || 1\"\n :colspan=\"cell.colspan || 1\"\n :class=\"cellClass(ri, ci)\"\n :style=\"cellStyle(row, cell)\"\n @mousedown.left=\"onCellMouseDown(ri, ci, $event)\"\n @mouseenter=\"onCellMouseEnter(ri, ci)\"\n @dblclick.stop=\"onCellDblClick(ri, ci)\"\n @contextmenu.prevent.stop=\"onCellContextMenu(ri, ci, $event)\"\n >\n <CellBarcode\n v-if=\"isCodeCell(cell)\"\n :cell-type=\"cell.cellType as 'barcode' | 'qrcode'\"\n :value=\"cellDisplay(row, cell)\"\n :barcode-type=\"cell.barcodeType\"\n :qr-code-level=\"cell.qrCodeLevel\"\n :show-text=\"cell.showBarcodeText\"\n />\n <span v-else-if=\"row.type === 'data'\" class=\"data-placeholder\">\n {{ cellDisplay(row, cell) }}\n </span>\n <template v-else>{{ cellDisplay(row, cell) }}</template>\n </td>\n </template>\n </tr>\n </tbody>\n </table>\n <!-- 行类型徽标(仅设计态且元素被选中) -->\n <div v-if=\"designMode && isSelected\" class=\"row-badges\">\n <span\n v-for=\"(row, ri) in rows\"\n :key=\"row.id\"\n class=\"row-badge\"\n :style=\"{ top: badgeTopMm(ri) + 'mm', height: badgeHeightMm(ri) + 'mm' }\"\n >\n {{ ROW_TYPE_BADGE[row.type] }}\n </span>\n </div>\n <TableContextMenu\n :visible=\"menu.visible\"\n :x=\"menu.x\"\n :y=\"menu.y\"\n :can-delete-row=\"rows.length > 1\"\n :can-delete-col=\"colWidths.length > 1\"\n :merge-disabled-reason=\"mergeReason\"\n :can-split=\"canSplit\"\n :current-row-type=\"selection ? rows[selection.r1]?.type ?? null : null\"\n :row-type-disabled-reason=\"rowTypeReason\"\n @action=\"onMenuAction\"\n />\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, inject, onMounted, reactive, ref, watch } from 'vue'\nimport type { RuntimeElement, TableRow, TableCell, TableRowType } from '../../types'\nimport {\n normalizeSelection, canMergeReason, mergeCells, splitCells,\n insertRow, deleteRow, insertCol, deleteCol, setRowType, syncTableElementSize,\n resolveCellBorderCss,\n} from '../../utils/table-matrix'\nimport { TABLE_EDIT_KEY, type TableEditContext } from '../../composables/useTableSelection'\nimport TableContextMenu from './TableContextMenu.vue'\nimport CellBarcode from './CellBarcode.vue'\nimport { resolveBarcodeDesignValue } from '../../utils/binding'\nimport { DEFAULT_DEMO_DATA } from '../../utils/demo-data'\n\nconst ROW_TYPE_BADGE: Record<TableRowType, string> = {\n header: '题', data: '数', subtotal: '小', summary: '汇',\n}\n\nconst props = defineProps<{\n element: RuntimeElement\n designMode?: boolean\n isSelected?: boolean\n /** 设计态下无边框单元格是否显示虚拟虚线(默认 true) */\n showTableGhostBorder?: boolean\n}>()\n\nconst emit = defineEmits<{\n 'dblclick-element': [id: string]\n 'dblclick-cell': [elementId: string, r: number, c: number]\n}>()\n\n// PrintDesigner 注入:选区共享 + 历史提交(非设计态如 PDF 预览无注入,提供空实现)\nconst editCtx = inject<TableEditContext>(TABLE_EDIT_KEY, {\n tableSelection: ref(null),\n setTableSelection: () => {},\n recordHistory: () => {},\n maxTableWidth: ref(Infinity),\n})\n\nconst rows = computed<TableRow[]>(() => props.element.options.tableRows ?? [])\nconst colWidths = computed<number[]>(() => props.element.options.tableColWidths ?? [])\nconst defaultFontSize = computed(() => props.element.options.tableDefaultFontSize ?? 10)\nconst defaultColor = computed(() => props.element.options.tableDefaultColor ?? '#333333')\n\n/** 当前元素的选区(全局选区属于本元素时才生效) */\nconst selection = computed(() => {\n const s = editCtx.tableSelection.value\n return s && s.elementId === props.element.id ? s : null\n})\n\nfunction rowTopMm(ri: number): number {\n let t = 0\n for (let i = 0; i < ri; i++) t += rows.value[i]!.height\n return t\n}\n\n// ─── 设计态实测尺寸自愈 ───\n// HTML 表格行高只是「最小高度」:单元格内容换行、大字号/大 padding 都会把行撑高,\n// 实际渲染高度可能大于行高和(打印端 overflow:visible 并按实测高度分页,行为一致)。\n// 设计框体(虚线选框/选中框/位置标签/吸附对齐)需跟随 <table> 实测高度,\n// 否则选中时示意虚线框与表格真实占用高度不一致。\nconst tableRef = ref<HTMLTableElement | null>(null)\n\n/** 96dpi 下 1mm ≈ 3.78px(与 render/browser-pagination 测量遍同一常量) */\nconst PX_PER_MM = 3.7795275591\n/** 实测高度与模型高度差小于该值(mm)时不回写,避免无意义抖动 */\nconst HEIGHT_EPSILON_MM = 0.1\n\n/** 各行实测布局(mm):行被内容撑高时,行类型徽标按实测位置/高度对齐 */\nconst rowLayoutMm = ref<{ top: number; height: number }[]>([])\n\nfunction measureTable() {\n if (!props.designMode) return\n const table = tableRef.value\n if (!table) return\n const tableHpx = table.offsetHeight\n if (tableHpx <= 0) return // 画布未挂载/隐藏(无布局)时跳过\n const o = props.element.options\n const tableHmm = tableHpx / PX_PER_MM\n if (Math.abs(tableHmm - (o.height ?? 0)) > HEIGHT_EPSILON_MM) {\n o.height = Math.round(tableHmm * 100) / 100\n }\n // tr.offsetTop 与 table.offsetTop 同属一个 offsetParent(.print-table 为 relative)\n const baseTop = table.offsetTop\n rowLayoutMm.value = Array.from(table.rows).map(tr => ({\n top: (tr.offsetTop - baseTop) / PX_PER_MM,\n height: tr.offsetHeight / PX_PER_MM,\n }))\n}\n\n/** 行徽标顶距:优先实测位置,未测量时回退行高累加 */\nfunction badgeTopMm(ri: number): number {\n return rowLayoutMm.value[ri]?.top ?? rowTopMm(ri)\n}\n\n/** 行徽标高:优先实测高度,未测量时回退配置行高 */\nfunction badgeHeightMm(ri: number): number {\n return rowLayoutMm.value[ri]?.height ?? rows.value[ri]?.height ?? 0\n}\n\n// 表格结构/内容/样式任意变化后,在 DOM 更新完毕时实测(post 钩子保证读到新布局)\nwatch(\n () => [props.element.options, props.designMode],\n () => measureTable(),\n { deep: true, flush: 'post' },\n)\n\nonMounted(() => {\n measureTable()\n // Web 字体加载完成后字宽可能变化导致换行变化,补测一次\n document.fonts?.ready.then(() => measureTable())\n})\n\n// ─── 单元格显示与样式 ───\n\n/** demo 数据中 data 行迭代用的列表(与服务端 resolveListSource 优先级一致) */\nconst demoList = computed<Record<string, any>[] | undefined>(() => {\n const ds = props.element.options.dataSource\n if (ds && Array.isArray(DEFAULT_DEMO_DATA[ds])) return DEFAULT_DEMO_DATA[ds]\n for (const v of Object.values(DEFAULT_DEMO_DATA)) {\n if (Array.isArray(v)) return v as Record<string, any>[]\n }\n return undefined\n})\n\nfunction isCodeCell(cell: TableCell): boolean {\n return cell.cellType === 'barcode' || cell.cellType === 'qrcode'\n}\n\nfunction cellDisplay(_row: TableRow, cell: TableCell): string {\n if (isCodeCell(cell)) {\n return resolveBarcodeDesignValue(cell.formatter, demoList.value)\n }\n return cell.formatter || ''\n}\n\nfunction cellStyle(_row: TableRow, cell: TableCell): Record<string, string> {\n const o = props.element.options\n // 设计态下无边框边补虚拟虚线(仅设计稿展示,预览/打印输出不受影响)\n const borderOpts = { designMode: props.designMode, showGhostBorder: props.showTableGhostBorder }\n return {\n fontFamily: cell.fontFamily || 'inherit',\n textAlign: cell.align ?? 'left',\n verticalAlign: cell.valign ?? 'middle',\n fontSize: (cell.fontSize ?? defaultFontSize.value) + 'pt',\n fontWeight: cell.fontWeight ?? 'normal',\n color: cell.color ?? defaultColor.value,\n backgroundColor: cell.backgroundColor ?? 'transparent',\n borderTop: resolveCellBorderCss(cell.borders?.top, borderOpts),\n borderRight: resolveCellBorderCss(cell.borders?.right, borderOpts),\n borderBottom: resolveCellBorderCss(cell.borders?.bottom, borderOpts),\n borderLeft: resolveCellBorderCss(cell.borders?.left, borderOpts),\n padding: (cell.padding ?? o.tableDefaultPadding ?? 1) + 'mm',\n whiteSpace: (cell.wordWrap ?? true) ? 'normal' : 'nowrap',\n overflow: (cell.wordWrap ?? true) ? 'visible' : 'hidden',\n }\n}\n\nfunction cellClass(ri: number, ci: number): Record<string, boolean> {\n const s = selection.value\n const inSel = !!s && ri >= s.r1 && ri <= s.r2 && ci >= s.c1 && ci <= s.c2\n return { 'cell-selected': inSel, 'row-data-bg': rows.value[ri]!.type === 'data' }\n}\n\n// ─── 选区交互 ───\n\nconst dragAnchor = ref<{ r: number; c: number } | null>(null)\n\nfunction applySelection(a: { r: number; c: number }, b: { r: number; c: number }) {\n const rect = normalizeSelection(rows.value, a, b)\n editCtx.setTableSelection({ elementId: props.element.id, ...rect })\n}\n\nfunction onCellMouseDown(r: number, c: number, e: MouseEvent) {\n if (!props.designMode || !props.isSelected) return\n e.stopPropagation() // 阻止画布拖拽元素\n if (e.shiftKey && selection.value) {\n applySelection({ r: selection.value.r1, c: selection.value.c1 }, { r, c })\n } else {\n dragAnchor.value = { r, c }\n applySelection({ r, c }, { r, c })\n }\n window.addEventListener('mouseup', () => { dragAnchor.value = null }, { once: true })\n}\n\nfunction onCellMouseEnter(r: number, c: number) {\n if (dragAnchor.value) applySelection(dragAnchor.value, { r, c })\n}\n\n// ─── 双击编辑 ───\n\nfunction onCellDblClick(r: number, c: number) {\n if (!props.designMode) return\n // 单元格双击:上报单元格坐标,由 PrintDesigner 打开该单元格的表达式编辑器\n emit('dblclick-cell', props.element.id, r, c)\n}\n\n// ─── 右键菜单 ───\n\nconst menu = reactive({ visible: false, x: 0, y: 0 })\n\nfunction onCellContextMenu(r: number, c: number, e: MouseEvent) {\n if (!props.designMode || !props.isSelected) return\n const s = selection.value\n const inSel = s && r >= s.r1 && r <= s.r2 && c >= s.c1 && c <= s.c2\n if (!inSel) applySelection({ r, c }, { r, c })\n menu.x = e.clientX\n menu.y = e.clientY\n menu.visible = true\n window.addEventListener('mousedown', () => { menu.visible = false }, { once: true })\n}\n\nconst mergeReason = computed(() => {\n const s = selection.value\n if (!s) return '未选择单元格'\n return canMergeReason(rows.value, s)\n})\n\nconst canSplit = computed(() => {\n const s = selection.value\n if (!s) return false\n for (let r = s.r1; r <= s.r2; r++) {\n for (let c = s.c1; c <= s.c2; c++) {\n const cell = rows.value[r]!.cells[c]!\n if (!cell.merged && ((cell.rowspan ?? 1) > 1 || (cell.colspan ?? 1) > 1)) return true\n }\n }\n return false\n})\n\nfunction rowTypeReason(t: TableRowType): string | null {\n const s = selection.value\n if (!s) return '未选择单元格'\n if (s.r1 !== s.r2) return '行类型仅支持单行设置'\n // 试算校验:在 JSON 深拷贝上执行(兼容 reactive Proxy)\n const cloned = JSON.parse(JSON.stringify(rows.value)) as TableRow[]\n return setRowType(cloned, s.r1, t)\n}\n\nfunction syncElementSize() {\n // 尺寸派生统一走共享函数:width/height 恒为列宽和/行高和(mm)\n syncTableElementSize(props.element.options)\n}\n\n/** 插入列前检查:新列复制相邻列宽,总列宽不得超过页面打印范围宽度 */\nfunction checkColWidthLimit(cw: number[], index: number): string | null {\n const maxW = editCtx.maxTableWidth.value\n const totalW = cw.reduce((s, w) => s + w, 0) + cw[index]!\n if (totalW > maxW) {\n return `插入后表格总宽 ${Math.round(totalW * 10) / 10}mm 超过打印范围宽度 ${maxW}mm,请先缩小列宽`\n }\n return null\n}\n\nfunction onMenuAction(name: string, payload?: string) {\n const s = selection.value\n if (!s) return\n menu.visible = false\n const o = props.element.options\n const rs = o.tableRows!\n const cw = o.tableColWidths!\n let err: string | null = null\n switch (name) {\n case 'insert-row-above': insertRow(rs, s.r1, 'above'); break\n case 'insert-row-below': insertRow(rs, s.r2, 'below'); break\n case 'delete-row': err = deleteRow(rs, s.r1); break\n case 'insert-col-left': err = checkColWidthLimit(cw, s.c1); if (!err) insertCol(rs, cw, s.c1, 'left'); break\n case 'insert-col-right': err = checkColWidthLimit(cw, s.c2); if (!err) insertCol(rs, cw, s.c2, 'right'); break\n case 'delete-col': err = deleteCol(rs, cw, s.c1); break\n case 'merge': mergeCells(rs, s); break\n case 'split': splitCells(rs, s); break\n case 'set-row-type':\n err = setRowType(rs, s.r1, payload as TableRowType)\n break\n }\n if (err) {\n alert(err)\n return\n }\n editCtx.setTableSelection(null) // 结构变化后选区坐标失效,清空\n syncElementSize()\n editCtx.recordHistory()\n}\n</script>\n\n<style scoped>\n.print-table {\n position: relative;\n width: 100%;\n height: 100%;\n}\n.print-table table {\n border-collapse: collapse;\n table-layout: fixed;\n width: 100%;\n}\n.print-table td {\n box-sizing: border-box;\n word-break: break-all;\n}\n.cell-selected {\n outline: 2px solid #165DFF;\n outline-offset: -2px;\n background-color: rgba(22, 93, 255, 0.08);\n}\n.row-data-bg {\n background-image: repeating-linear-gradient(\n 45deg,\n rgba(22, 93, 255, 0.04) 0 6px,\n transparent 6px 12px\n );\n}\n.data-placeholder {\n color: #909399;\n font-style: italic;\n}\n.cell-editor {\n width: 100%;\n border: none;\n outline: none;\n background: #fffbe6;\n font: inherit;\n}\n.row-badges {\n position: absolute;\n left: -16px;\n top: 0;\n width: 14px;\n}\n.row-badge {\n position: absolute;\n width: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n color: #909399;\n background: #f5f7fa;\n border-radius: 2px;\n}\n</style>\n","<template>\n <div class=\"print-line\" :style=\"lineStyle\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { RuntimeElement } from '../../types'\n\nconst props = defineProps<{\n element: RuntimeElement\n}>()\n\nconst isHline = computed(() => props.element.printElementType.type === 'hline')\n\nconst lineStyle = computed(() => {\n const o = props.element.options\n const bw = (o.borderWidth || 0.75) + 'pt'\n const bs = o.borderStyle || 'solid'\n const bc = o.borderColor || '#333'\n if (isHline.value) {\n return { width: '100%', height: '0', borderTop: `${bw} ${bs} ${bc}`, boxSizing: 'border-box' as const }\n }\n return { width: '0', height: '100%', borderLeft: `${bw} ${bs} ${bc}`, boxSizing: 'border-box' as const }\n})\n</script>","<template>\n <div class=\"print-shape\" :style=\"shapeStyle\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { RuntimeElement } from '../../types'\n\nconst props = defineProps<{\n element: RuntimeElement\n}>()\n\nconst isOval = computed(() => props.element.printElementType.type === 'oval')\n\nconst shapeStyle = computed(() => {\n const o = props.element.options\n return {\n width: '100%',\n height: '100%',\n borderWidth: (o.borderWidth || 1) + 'pt',\n borderStyle: (o.borderStyle || 'solid') as string,\n borderColor: o.borderColor || '#333',\n backgroundColor: o.backgroundColor || 'transparent',\n borderRadius: isOval.value ? '50%' : '0',\n boxSizing: 'border-box' as const,\n }\n})\n</script>\n","<template>\n <div class=\"print-barcode\" ref=\"containerRef\">\n <svg ref=\"svgRef\" preserveAspectRatio=\"xMidYMid meet\"></svg>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, watch } from 'vue'\nimport JsBarcode from 'jsbarcode'\nimport { resolveTextBinding } from '../../utils/binding'\nimport type { RuntimeElement } from '../../types'\n\nconst props = defineProps<{\n element: RuntimeElement\n data?: Record<string, any>[]\n designMode?: boolean\n}>()\n\nconst svgRef = ref<SVGSVGElement | null>(null)\n\n// 画布元素尺寸单位为 mm,浏览器 96dpi 下 1mm = 96/25.4 px\nconst MM_TO_PX = 96 / 25.4\n\nfunction render() {\n if (!svgRef.value) return\n const o = props.element.options\n const value = (props.designMode ? (o.testData || o.formatter) : resolveTextBinding(o, props.data)) || '条码'\n const showText = !o.hideTitle\n const fontSizePx = (o.fontSize || 12) * (96 / 72) // pt → px\n const totalPx = (o.height || 40) * MM_TO_PX // 元素高度 mm → px\n const textH = showText ? fontSizePx + 4 : 0 // 文本区预留\n const barH = Math.max(8, totalPx - textH) // 条码图形高度\n try {\n JsBarcode(svgRef.value, value, {\n format: (o.barcodeType || 'CODE128') as any,\n width: o.barWidth ? o.barWidth / 2 : 1,\n height: barH,\n displayValue: showText,\n fontSize: fontSizePx,\n margin: 2,\n })\n } catch { /* ignore render errors */ }\n}\n\nonMounted(render)\nwatch(\n () => [\n props.element.options.formatter,\n props.element.options.testData,\n props.element.options.barcodeType,\n props.element.options.width,\n props.element.options.height,\n props.element.options.barWidth,\n props.element.options.hideTitle,\n props.element.options.fontSize,\n ],\n render,\n)\n</script>\n\n<style scoped>\n.print-barcode { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; overflow: hidden; }\n/* JsBarcode 生成的 svg 自带 viewBox,width/height 100% 时等比缩放填满容器,随元素宽高变化 */\n.print-barcode svg { width: 100%; height: 100%; }\n</style>\n","<template>\n <div class=\"print-qrcode\">\n <img v-if=\"dataUrl\" :src=\"dataUrl\" alt=\"qrcode\" />\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, watch } from 'vue'\nimport QRCode from 'qrcode'\nimport { resolveTextBinding } from '../../utils/binding'\nimport type { RuntimeElement } from '../../types'\n\nconst props = defineProps<{\n element: RuntimeElement\n data?: Record<string, any>[]\n designMode?: boolean\n}>()\n\n// 改用 toDataURL 渲染为 <img>:纳入统一图片加载屏障,规避 canvas 在 PDF 中偶发空白\nconst dataUrl = ref('')\n\nasync function render() {\n const o = props.element.options\n const value = (props.designMode ? (o.testData || o.formatter) : resolveTextBinding(o, props.data)) || '二维码'\n const size = Math.min(o.width || 80, o.height || 80)\n try {\n dataUrl.value = await QRCode.toDataURL(value, {\n width: size,\n margin: 1,\n errorCorrectionLevel: (String(o.qrCodeLevel ?? 'M') as 'L' | 'M' | 'Q' | 'H'),\n })\n } catch {\n dataUrl.value = ''\n }\n}\n\nonMounted(render)\nwatch(() => [props.element.options.formatter, props.element.options.testData], render)\n</script>\n\n<style scoped>\n.print-qrcode { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; overflow: hidden; }\n.print-qrcode img { max-width: 100%; max-height: 100%; }\n</style>\n","<template>\n <div class=\"print-html\" v-html=\"htmlContent\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport DOMPurify from 'dompurify'\nimport type { RuntimeElement } from '../../types'\nimport { evaluateTemplate } from '../../utils/expression-eval'\n\nconst props = defineProps<{\n element: RuntimeElement\n data?: Record<string, any>[]\n designMode?: boolean\n}>()\n\nconst htmlContent = computed(() => {\n if (props.element.options.formatter) {\n const row = props.data && props.data.length > 0 ? props.data[0] : {}\n const result = evaluateTemplate(props.element.options.formatter, row ?? {})\n return result ? DOMPurify.sanitize(result) : ''\n }\n return '<div style=\"background:#e0e0e0;width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:10pt;color:#999\">HTML</div>'\n})\n</script>\n\n<style scoped>\n.print-html { width: 100%; height: 100%; overflow: hidden; }\n</style>\n","<template>\n <div class=\"page-number-element\" :style=\"textStyle\">\n {{ displayText }}\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { RuntimeElement } from '../../types'\n\nconst props = defineProps<{\n element: RuntimeElement\n data?: Record<string, any>[]\n designMode?: boolean\n}>()\n\nconst textStyle = computed(() => {\n const o = props.element.options\n return {\n fontSize: (o.fontSize || 12) + 'pt',\n fontWeight: o.fontWeight || 'normal',\n fontFamily: o.fontFamily || 'inherit',\n color: o.color || '#333',\n textAlign: (o.textAlign || 'left') as 'left' | 'center' | 'right',\n lineHeight: o.lineHeight ? o.lineHeight + 'pt' : 'normal',\n letterSpacing: o.letterSpacing ? o.letterSpacing + 'pt' : 'normal',\n }\n})\n\nconst displayText = computed(() => {\n if (props.designMode) {\n return props.element.options.title || '{pageIndex}/{totalPages}'\n }\n // 运行时由 print-render 渲染端按分页填充 {pageIndex}/{totalPages}\n return props.element.options.title || ''\n})\n</script>\n\n<style scoped>\n.page-number-element {\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n</style>\n","<template>\n <div\n ref=\"elRef\"\n class=\"print-element\"\n :class=\"{\n selected: isSelected,\n previewed: isPreviewed,\n 'design-mode': designMode,\n locked: element.options.locked,\n hidden: element.options.visible === false,\n 'drag-ghost': isDragging,\n [`type-${element.printElementType.type}`]: true,\n [`zone-${zone || 'content'}`]: true,\n }\"\n :style=\"elementStyle\"\n @mousedown.stop=\"onMouseDown\"\n @dblclick.stop=\"onDblClick\"\n @contextmenu.prevent.stop=\"$emit('contextmenu', element.id, $event)\"\n >\n <component\n :is=\"contentComponent\"\n :element=\"element\"\n :data=\"printData\"\n :design-mode=\"designMode\"\n :is-selected=\"isSelected\"\n v-bind=\"contentAttrs\"\n @dblclick-cell=\"onDblClickCell\"\n />\n\n <!-- 拖拽半透明预览副本 -->\n <div v-if=\"isDragging\" class=\"drag-preview\" />\n\n <div v-if=\"resizeEnabled\" class=\"resize-handles\">\n <div\n v-for=\"p in RESIZE_POINTS\"\n :key=\"p\"\n :class=\"['resize-handle', `handle-${p}`]\"\n @mousedown.stop=\"startResize(p, $event)\"\n />\n </div>\n\n <div v-if=\"isSelected && designMode\" class=\"selected-indicator\">\n <div class=\"position-label\">{{ posLabel }}</div>\n </div>\n <div v-if=\"designMode && bindingState\" class=\"binding-badge\" :style=\"{ color: bindingState.badgeColor }\">\n {{ bindingState.badge }}\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, inject, markRaw, reactive, ref, watchEffect, onMounted, onUnmounted } from 'vue'\nimport type { RuntimeElement, ElementRect, AdsorbResult } from '../../types'\nimport { useDrag } from '../../composables/useDrag'\nimport type { DragOptions } from '../../composables/useDrag'\nimport { generateId } from '../../utils/element-factory'\nimport { useResize, RESIZE_POINTS } from '../../composables/useResize'\nimport { useBindingDisplay } from '../../composables/useBindingDisplay'\nimport { SELECTED_IDS_KEY, PREVIEW_IDS_KEY } from '../../composables/useSelection'\nimport TextElement from './TextElement.vue'\nimport ImageElement from './ImageElement.vue'\nimport LongTextElement from './LongTextElement.vue'\nimport TableElement from './TableElement.vue'\nimport LineElement from './LineElement.vue'\nimport ShapeElement from './ShapeElement.vue'\nimport BarcodeElement from './BarcodeElement.vue'\nimport QrcodeElement from './QrcodeElement.vue'\nimport HtmlElement from './HtmlElement.vue'\nimport PageNumberElement from './PageNumberElement.vue'\n\nconst props = defineProps<{\n element: RuntimeElement\n /** @deprecated 通过 inject 获取,保留用于向后兼容 */\n isSelected?: boolean\n designMode?: boolean\n printData?: Record<string, any>[]\n scale?: number\n allElements?: RuntimeElement[]\n snapToGrid?: boolean\n /** 设计态下无边框表格单元格的虚拟虚线开关(透传给 TableElement) */\n showTableGhostBorder?: boolean\n /** 元素所在区域(影响设计态边框颜色) */\n zone?: 'content' | 'header' | 'footer' | 'overlay'\n /** 由 CanvasPaper 层吸附管理器提供:同步返回吸附修正结果并渲染引导线 */\n adsorbHandler?: (rect: ElementRect) => AdsorbResult\n clearAdsorbGuides?: () => void\n}>()\n\nconst emit = defineEmits<{\n select: [id: string, multiple: boolean]\n 'update:element': [element: RuntimeElement]\n 'drag-start': []\n 'drag-stop': []\n 'dblclick-element': [id: string]\n 'dblclick-cell': [elementId: string, r: number, c: number]\n 'contextmenu': [id: string, e: MouseEvent]\n 'clone-element': [element: RuntimeElement, position: { left: number; top: number }]\n}>()\n\nconst elRef = ref<HTMLElement | null>(null)\n\n// 通过 inject 精确追踪自身选中状态,避免父组件因 selectedIds 变化全量重渲染\nconst injectedSelectedIds = inject(SELECTED_IDS_KEY, null)\nconst isSelected = computed(() => {\n if (injectedSelectedIds?.value) {\n return injectedSelectedIds.value.has(props.element.id)\n }\n return props.isSelected ?? false\n})\n\n// 框选实时预选高亮(未提交前)\nconst injectedPreviewIds = inject(PREVIEW_IDS_KEY, null)\nconst isPreviewed = computed(() => injectedPreviewIds?.value.has(props.element.id) ?? false)\n\nconst componentMap: Record<string, any> = {\n text: markRaw(TextElement),\n image: markRaw(ImageElement),\n longText: markRaw(LongTextElement),\n table: markRaw(TableElement),\n hline: markRaw(LineElement),\n vline: markRaw(LineElement),\n rect: markRaw(ShapeElement),\n oval: markRaw(ShapeElement),\n barcode: markRaw(BarcodeElement),\n qrcode: markRaw(QrcodeElement),\n html: markRaw(HtmlElement),\n pageNumber: markRaw(PageNumberElement),\n}\n\nconst { getBindingDisplayState } = useBindingDisplay()\n\nconst bindingState = computed(() => {\n if (!props.designMode) return null\n return getBindingDisplayState(props.element)\n})\n\nconst contentComponent = computed(() => componentMap[props.element.printElementType.type])\n\n/** 仅表格元素需要虚拟虚线开关,避免其它元素根节点出现无关 attribute */\nconst contentAttrs = computed(() =>\n props.element.printElementType.type === 'table'\n ? { showTableGhostBorder: props.showTableGhostBorder }\n : {},\n)\n\nconst elementStyle = computed(() => {\n const o = props.element.options\n return {\n position: 'absolute' as const,\n left: o.left + 'mm',\n top: o.top + 'mm',\n width: o.width + 'mm',\n height: o.height + 'mm',\n zIndex: o.zIndex || 'auto',\n }\n})\n\nconst posLabel = computed(() => {\n const o = props.element.options\n return `x:${Math.round(o.left)} y:${Math.round(o.top)} ${Math.round(o.width)}×${Math.round(o.height)}mm`\n})\n\n// 吸附检测与引导线由 CanvasPaper 层的 useAdsorbManager 统一管理\n\n// 拖拽:拖拽期间用 CSS transform 做视觉跟随,不触发响应式更新;\n// mouseup 时通过 onDragEnd 一次性写入最终坐标。\nlet dragStartLeft = 0\nlet dragStartTop = 0\nconst dragConfig = reactive<DragOptions>({\n disabled: !props.designMode || !!props.element.options.locked,\n getScale: () => props.scale || 1,\n // 拖拽中:仅设置 style.transform,不修改响应式数据\n onDrag: (pos) => {\n const dx = pos.left - dragStartLeft\n const dy = pos.top - dragStartTop\n if (elRef.value) {\n elRef.value.style.transform = `translate(${dx}mm, ${dy}mm)`\n }\n // 同组元素拖拽跟随:拖拽期间不处理,mouseup 时通过 onDragEnd 一次性更新响应式坐标\n },\n // 拖拽结束:一次性写入最终坐标,清除 transform\n onDragEnd: (pos, info) => {\n // Alt+拖拽:在落点生成副本,原元素留在原位不动\n if (info.altKey) {\n const clone = JSON.parse(JSON.stringify(props.element)) as RuntimeElement\n clone.id = generateId()\n clone.options.left = pos.left\n clone.options.top = pos.top\n // 通过 emit 事件通知父组件处理克隆,而非直接操作 props\n emit('clone-element', clone, { left: pos.left, top: pos.top })\n if (elRef.value) {\n elRef.value.style.transform = ''\n }\n return\n }\n const finalDx = pos.left - dragStartLeft\n const finalDy = pos.top - dragStartTop\n // 写入主元素响应式坐标\n props.element.options.left = pos.left\n props.element.options.top = pos.top\n if (elRef.value) {\n elRef.value.style.transform = ''\n }\n // 同组元素一次性更新坐标(响应式写入,Vue 自动刷新 DOM)\n if (props.element.options.groupId && props.allElements) {\n for (const sibling of props.allElements) {\n if (sibling.id !== props.element.id && sibling.options.groupId === props.element.options.groupId) {\n sibling.options.left += finalDx\n sibling.options.top += finalDy\n }\n }\n }\n },\n onStart: () => {\n // 记录拖拽起始坐标(用于计算 transform 偏移量)\n dragStartLeft = props.element.options.left\n dragStartTop = props.element.options.top\n emit('select', props.element.id, false)\n emit('drag-start')\n },\n onStop: () => {\n props.clearAdsorbGuides?.()\n emit('drag-stop')\n },\n onAdsorb: (pos) => {\n // 网格吸附\n let left = pos.left\n let top = pos.top\n if (props.snapToGrid) {\n const grid = 5 // 5mm\n left = Math.round(pos.left / grid) * grid\n top = Math.round(pos.top / grid) * grid\n }\n\n // 元素间吸附交给 CanvasPaper 层管理器(含引导线渲染)\n if (props.adsorbHandler) {\n return props.adsorbHandler({\n id: props.element.id,\n left,\n top,\n width: props.element.options.width,\n height: props.element.options.height,\n })\n }\n return { left, top, lines: [] }\n },\n})\nconst { setup: setupDrag, cleanup: cleanupDrag, isDragging } = useDrag(elRef, dragConfig)\n\n// 锁定/设计态变化时自动同步拖拽禁用标志(useDrag.onMouseDown 实时读取 dragConfig.disabled)\nwatchEffect(() => {\n dragConfig.disabled = !props.designMode || !!props.element.options.locked\n})\n\n// 缩放:手柄由模板渲染,resizeEnabled 控制显隐;table 尺寸由列宽/行高派生,禁用缩放\nconst resizeEnabled = computed(\n () =>\n isSelected.value &&\n !!props.designMode &&\n !props.element.options.locked &&\n props.element.printElementType.type !== 'table',\n)\n\nconst { startResize, cleanup: cleanupResize } = useResize({\n minWidth: 3.5,\n minHeight: 3.5,\n getScale: () => props.scale || 1,\n getRect: () => ({\n left: props.element.options.left,\n top: props.element.options.top,\n width: props.element.options.width,\n height: props.element.options.height,\n }),\n onResize: (rect) => {\n props.element.options.left = rect.left\n props.element.options.top = rect.top\n props.element.options.width = rect.width\n props.element.options.height = rect.height\n },\n // 复用 drag-start/drag-stop 事件链记录历史:onStart 记录缩放前快照,\n // onStop 触发 PrintDesigner.onDragStop 的前后对比(含 width/height)入栈。\n onStart: () => {\n emit('drag-start')\n },\n onStop: () => {\n emit('drag-stop')\n },\n})\n\nfunction onMouseDown(e: MouseEvent) {\n if (!props.designMode) return\n emit('select', props.element.id, e.ctrlKey || e.metaKey)\n}\n\nfunction onDblClick() {\n if (!props.designMode) return\n emit('dblclick-element', props.element.id)\n}\n\n/** 表格单元格双击转发(仅表格元素的 TableElement 会触发) */\nfunction onDblClickCell(elementId: string, r: number, c: number) {\n if (!props.designMode) return\n emit('dblclick-cell', elementId, r, c)\n}\n\nonMounted(() => {\n // 始终挂载拖拽监听:useDrag.onMouseDown 在事件触发时实时读取 dragConfig.disabled,\n // 即使元素加载时 locked:true 也能正确门控;解锁后 locked watcher 更新 disabled 即生效。\n if (props.designMode) {\n setupDrag()\n }\n})\n\nfunction cleanup() {\n cleanupDrag()\n cleanupResize()\n props.clearAdsorbGuides?.()\n}\n\nonUnmounted(() => {\n cleanup()\n})\n</script>\n\n<style scoped>\n.print-element {\n box-sizing: border-box;\n cursor: pointer;\n user-select: none;\n}\n/* 设计态下所有元素显示浅灰虚线边框,标示占位空间大小 */\n.print-element.design-mode {\n outline: 1px dashed #C3C9D6;\n}\n/* 页眉/页脚区域元素:油墨绿虚线 */\n.print-element.design-mode.zone-header,\n.print-element.design-mode.zone-footer {\n outline: 1px dashed var(--pd-ink-green, #67c23a);\n}\n/* 首页叠加区域元素:青色虚线 */\n.print-element.design-mode.zone-overlay {\n outline: 1px dashed #06B6D4;\n}\n.print-element.selected {\n outline: 1.5px solid var(--pd-accent, #165DFF);\n background: rgba(22, 93, 255, 0.04);\n}\n/* 框选实时预选:墨蓝高亮(未提交) */\n.print-element.previewed {\n outline: 1.5px solid rgba(22, 93, 255, 0.5);\n background: rgba(22, 93, 255, 0.1);\n}\n.print-element.design-mode:hover {\n outline: 1px dashed var(--pd-accent, #165DFF);\n}\n.print-element.locked {\n cursor: not-allowed;\n}\n.print-element.locked:not(.selected) {\n outline: 1.5px dashed #999;\n}\n.print-element.hidden {\n opacity: 0.3;\n pointer-events: none;\n}\n/* 拖拽半透明预览:拖拽中元素变淡,叠加虚线副本框 */\n.print-element.drag-ghost {\n opacity: 0.4;\n}\n.drag-preview {\n position: absolute;\n inset: 0;\n border: 2px dashed var(--pd-accent, #165DFF);\n pointer-events: none;\n z-index: 1000;\n box-sizing: border-box;\n}\n.selected-indicator {\n position: absolute;\n top: -18px;\n left: 0;\n font-size: 10px;\n white-space: nowrap;\n pointer-events: none;\n z-index: 20;\n}\n.position-label {\n background: var(--pd-accent, #165DFF);\n color: #fff;\n padding: 1px 6px;\n border-radius: 3px;\n font-family: ui-monospace, 'SF Mono', Menlo, monospace;\n font-size: 10px;\n font-variant-numeric: tabular-nums;\n letter-spacing: 0;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);\n}\n.binding-badge {\n position: absolute;\n top: -1px;\n left: -1px;\n font-size: 9px;\n font-family: monospace;\n padding: 1px 4px;\n background: rgba(255, 255, 255, 0.92);\n border: 1px solid currentColor;\n border-radius: 2px;\n line-height: 1.4;\n max-width: calc(100% - 4px);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n pointer-events: none;\n z-index: 1;\n}\n.resize-handles {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n.resize-handle {\n position: absolute;\n width: 7px;\n height: 7px;\n background: var(--pd-handle, #165DFF);\n border: 1.5px solid #fff;\n border-radius: 2px;\n box-sizing: border-box;\n transform: translate(-50%, -50%);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18);\n z-index: 10;\n pointer-events: auto;\n}\n.handle-nw { top: 0; left: 0; cursor: nw-resize; }\n.handle-n { top: 0; left: 50%; cursor: n-resize; }\n.handle-ne { top: 0; left: 100%; cursor: ne-resize; }\n.handle-e { top: 50%; left: 100%; cursor: e-resize; }\n.handle-se { top: 100%; left: 100%; cursor: se-resize; }\n.handle-s { top: 100%; left: 50%; cursor: s-resize; }\n.handle-sw { top: 100%; left: 0; cursor: sw-resize; }\n.handle-w { top: 50%; left: 0; cursor: w-resize; }\n</style>\n","export interface RulerTick {\n mm: number\n major: boolean\n label?: string\n}\n\n/** 生成标尺刻度:5mm 小刻度,10mm 大刻度 + 数字标签 */\nexport function buildRulerTicks(lengthMM: number): RulerTick[] {\n const ticks: RulerTick[] = []\n for (let mm = 0; mm <= lengthMM + 1e-9; mm += 5) {\n const rounded = Math.round(mm * 100) / 100\n const major = rounded % 10 === 0\n if (major) {\n ticks.push({ mm: rounded, major, label: String(rounded) })\n } else {\n ticks.push({ mm: rounded, major })\n }\n }\n return ticks\n}\n","<template>\n <canvas ref=\"canvasRef\" class=\"pd-ruler\" :style=\"cssSize\" @mousedown=\"onDown\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, onMounted } from 'vue'\nimport { buildRulerTicks } from '../utils/ruler'\n\nconst MM_TO_PX = 96 / 25.4\nconst THICKNESS = 16\n\nconst props = defineProps<{\n orientation: 'horizontal' | 'vertical'\n lengthMM: number\n scale?: number\n}>()\nconst emit = defineEmits<{ 'add-guide': [type: 'vertical' | 'horizontal', positionMm: number] }>()\n\nconst canvasRef = ref<HTMLCanvasElement | null>(null)\n\nconst cssSize = computed(() => {\n if (props.orientation === 'horizontal') {\n return { width: props.lengthMM + 'mm', height: THICKNESS + 'px' }\n }\n return { width: THICKNESS + 'px', height: props.lengthMM + 'mm' }\n})\n\nfunction draw() {\n const canvas = canvasRef.value\n if (!canvas) return\n const dpr = window.devicePixelRatio || 1\n const lengthPx = props.lengthMM * MM_TO_PX\n const horizontal = props.orientation === 'horizontal'\n canvas.width = (horizontal ? lengthPx : THICKNESS) * dpr\n canvas.height = (horizontal ? THICKNESS : lengthPx) * dpr\n const ctx = canvas.getContext('2d')\n if (!ctx) return\n ctx.scale(dpr, dpr)\n\n const style = getComputedStyle(canvas)\n const bg = style.getPropertyValue('--pd-ruler-bg').trim() || '#FFFFFF'\n const fg = style.getPropertyValue('--pd-ruler').trim() || '#9CA3AF'\n\n ctx.fillStyle = bg\n ctx.fillRect(0, 0, horizontal ? lengthPx : THICKNESS, horizontal ? THICKNESS : lengthPx)\n\n ctx.strokeStyle = fg\n ctx.fillStyle = fg\n ctx.lineWidth = 1\n ctx.font = '8px ui-monospace, Menlo, monospace'\n\n for (const tick of buildRulerTicks(props.lengthMM)) {\n const pos = Math.round(tick.mm * MM_TO_PX) + 0.5\n const len = tick.major ? 8 : 4\n ctx.beginPath()\n if (horizontal) {\n ctx.moveTo(pos, 0)\n ctx.lineTo(pos, len)\n } else {\n ctx.moveTo(0, pos)\n ctx.lineTo(len, pos)\n }\n ctx.stroke()\n if (tick.major && tick.label) {\n if (horizontal) {\n ctx.fillText(tick.label, pos + 2, 14)\n } else {\n ctx.save()\n ctx.translate(12, pos + 2)\n ctx.rotate(-Math.PI / 2)\n ctx.fillText(tick.label, -ctx.measureText(tick.label).width, 0)\n ctx.restore()\n }\n }\n }\n}\n\nwatch(() => [props.lengthMM, props.orientation], draw)\nonMounted(draw)\n\n// ─── 拖出生成参考线 ───\nlet dragging = false\nfunction onDown(e: MouseEvent) {\n dragging = true\n e.preventDefault()\n window.addEventListener('mousemove', onMove)\n window.addEventListener('mouseup', onUp)\n}\nfunction onMove() {\n // 拖动中不显示预览,mouseup 时生成\n}\nfunction onUp(e: MouseEvent) {\n if (!dragging) return\n dragging = false\n window.removeEventListener('mousemove', onMove)\n window.removeEventListener('mouseup', onUp)\n const canvas = canvasRef.value\n if (!canvas) return\n const rect = canvas.getBoundingClientRect()\n const s = props.scale ?? 1\n const offset = props.orientation === 'horizontal'\n ? (e.clientX - rect.left) / s\n : (e.clientY - rect.top) / s\n const posMM = offset / MM_TO_PX\n if (posMM > 0 && posMM < props.lengthMM) {\n emit('add-guide', props.orientation === 'horizontal' ? 'horizontal' : 'vertical', posMM)\n }\n}\n</script>\n\n<style scoped>\n.pd-ruler {\n position: absolute;\n top: 0;\n left: 0;\n pointer-events: auto;\n cursor: crosshair;\n z-index: 5;\n display: block;\n}\n/* 横尺压下沿、竖尺压右沿,构成 L 型制图尺框 */\n.pd-ruler:nth-of-type(1) {\n box-shadow: 0 1px 0 var(--pd-border-soft, #e9ecf2);\n}\n.pd-ruler:nth-of-type(2) {\n box-shadow: 1px 0 0 var(--pd-border-soft, #e9ecf2);\n}\n</style>\n","// web/src/components/print/composables/useAdsorb.ts\nimport { ref, type Ref } from 'vue'\nimport type { ElementRect, AlignLine, AdsorbResult } from '../types'\n\nexport interface AdsorbConfig {\n adsorbMin?: number\n adsorbLineMin?: number\n showAdsorbLine?: boolean\n}\n\nexport function useAdsorb(config: AdsorbConfig = {}) {\n const adsorbMin = config.adsorbMin ?? 1\n const adsorbLineMin = config.adsorbLineMin ?? 2\n const showAdsorbLine = config.showAdsorbLine ?? true\n\n /** 引导线响应式数据,由模板 v-for 渲染 */\n const guideLines: Ref<AlignLine[]> = ref([])\n\n /** 纸张尺寸(mm),用于引导线贯穿整页 */\n const paperSize = ref({ width: 0, height: 0 })\n\n /** 对齐类型颜色:左/顶端蓝,居中绿,右/底橘 */\n const SNAP_COLORS: Record<'left' | 'center' | 'right' | 'top' | 'middle' | 'bottom', string> = {\n left: '#3b82f6',\n center: '#10b981',\n right: '#f59e0b',\n top: '#3b82f6',\n middle: '#10b981',\n bottom: '#f59e0b',\n }\n\n /** 根据移动元素对齐点(mk)返回引导线颜色 */\n function snapColor(mk: string): string {\n if (mk === 'vCenter') return SNAP_COLORS.center\n if (mk === 'hCenter') return SNAP_COLORS.middle\n return SNAP_COLORS[mk as keyof typeof SNAP_COLORS] ?? SNAP_COLORS.left\n }\n\n function check(\n movingRect: ElementRect,\n others: ElementRect[],\n guideLines?: { vertical: number[]; horizontal: number[] },\n ): AdsorbResult {\n let left = movingRect.left\n let top = movingRect.top\n const lines: AlignLine[] = []\n\n const m = {\n left: movingRect.left,\n right: movingRect.left + movingRect.width,\n vCenter: movingRect.left + movingRect.width / 2,\n top: movingRect.top,\n bottom: movingRect.top + movingRect.height,\n hCenter: movingRect.top + movingRect.height / 2,\n }\n\n let minDist = Infinity\n\n for (const other of others) {\n if (other.id === movingRect.id) continue\n const o = {\n left: other.left,\n right: other.left + other.width,\n vCenter: other.left + other.width / 2,\n top: other.top,\n bottom: other.top + other.height,\n hCenter: other.top + other.height / 2,\n }\n\n const hPairs: [keyof typeof m, keyof typeof o][] = [\n ['left', 'left'], ['left', 'vCenter'], ['left', 'right'],\n ['vCenter', 'left'], ['vCenter', 'vCenter'], ['vCenter', 'right'],\n ['right', 'left'], ['right', 'vCenter'], ['right', 'right'],\n ]\n const vPairs: [keyof typeof m, keyof typeof o][] = [\n ['top', 'top'], ['top', 'hCenter'], ['top', 'bottom'],\n ['hCenter', 'top'], ['hCenter', 'hCenter'], ['hCenter', 'bottom'],\n ['bottom', 'top'], ['bottom', 'hCenter'], ['bottom', 'bottom'],\n ]\n\n for (const [mk, ok] of hPairs) {\n const dist = Math.abs(m[mk] - o[ok])\n if (dist <= adsorbMin && dist < minDist) {\n minDist = dist\n left = movingRect.left + (o[ok] - m[mk])\n }\n }\n for (const [mk, ok] of vPairs) {\n const dist = Math.abs(m[mk] - o[ok])\n if (dist <= adsorbMin && dist < minDist) {\n minDist = dist\n top = movingRect.top + (o[ok] - m[mk])\n }\n }\n }\n\n // 手动参考线吸附:垂直参考线(position=X)参与水平方向,水平参考线参与垂直方向\n if (guideLines) {\n const m2 = {\n left, right: left + movingRect.width, vCenter: left + movingRect.width / 2,\n top, bottom: top + movingRect.height, hCenter: top + movingRect.height / 2,\n }\n const hKeys: (keyof typeof m2)[] = ['left', 'vCenter', 'right']\n for (const pos of guideLines.vertical) {\n for (const k of hKeys) {\n const d = Math.abs(m2[k] - pos)\n if (d <= adsorbMin && d < minDist) { minDist = d; left = movingRect.left + (pos - m2[k]) }\n }\n }\n const vKeys: (keyof typeof m2)[] = ['top', 'hCenter', 'bottom']\n for (const pos of guideLines.horizontal) {\n for (const k of vKeys) {\n const d = Math.abs(m2[k] - pos)\n if (d <= adsorbMin && d < minDist) { minDist = d; top = movingRect.top + (pos - m2[k]) }\n }\n }\n }\n\n const adjustedM = {\n left, right: left + movingRect.width,\n vCenter: left + movingRect.width / 2,\n top, bottom: top + movingRect.height,\n hCenter: top + movingRect.height / 2,\n }\n\n if (showAdsorbLine) {\n const seen = new Set<string>()\n for (const other of others) {\n if (other.id === movingRect.id) continue\n const o = {\n left: other.left,\n right: other.left + other.width,\n vCenter: other.left + other.width / 2,\n top: other.top,\n bottom: other.top + other.height,\n hCenter: other.top + other.height / 2,\n }\n\n const hPairs: [keyof typeof adjustedM, keyof typeof o][] = [\n ['left', 'left'], ['left', 'vCenter'], ['left', 'right'],\n ['vCenter', 'left'], ['vCenter', 'vCenter'], ['vCenter', 'right'],\n ['right', 'left'], ['right', 'vCenter'], ['right', 'right'],\n ]\n const vPairs: [keyof typeof adjustedM, keyof typeof o][] = [\n ['top', 'top'], ['top', 'hCenter'], ['top', 'bottom'],\n ['hCenter', 'top'], ['hCenter', 'hCenter'], ['hCenter', 'bottom'],\n ['bottom', 'top'], ['bottom', 'hCenter'], ['bottom', 'bottom'],\n ]\n\n for (const [mk, ok] of hPairs) {\n const dist = Math.abs(adjustedM[mk] - o[ok])\n // 吸附(dist <= adsorbMin)或近距(adsorbMin < dist <= adsorbLineMin)均绘制竖直引导线\n if (dist <= adsorbLineMin) {\n const key = `v:${o[ok]}`\n if (!seen.has(key)) {\n seen.add(key)\n lines.push({ type: 'vertical', position: o[ok], id: other.id, color: snapColor(mk) })\n }\n }\n }\n for (const [mk, ok] of vPairs) {\n const dist = Math.abs(adjustedM[mk] - o[ok])\n if (dist <= adsorbLineMin) {\n const key = `h:${o[ok]}`\n if (!seen.has(key)) {\n seen.add(key)\n lines.push({ type: 'horizontal', position: o[ok], id: other.id, color: snapColor(mk) })\n }\n }\n }\n }\n }\n\n if (guideLines) {\n for (const pos of guideLines.vertical) {\n if (!lines.some(l => l.type === 'vertical' && l.position === pos)) {\n lines.push({ type: 'vertical', position: pos })\n }\n }\n for (const pos of guideLines.horizontal) {\n if (!lines.some(l => l.type === 'horizontal' && l.position === pos)) {\n lines.push({ type: 'horizontal', position: pos })\n }\n }\n }\n\n return { left, top, lines }\n }\n\n /** 更新引导线(Vue 响应式,不再直接操作 DOM) */\n function renderLines(lines: AlignLine[], paperW: number, paperH: number) {\n guideLines.value = lines\n paperSize.value = { width: paperW, height: paperH }\n }\n\n /** 清除引导线 */\n function clearLines() {\n guideLines.value = []\n }\n\n return { check, renderLines, clearLines, guideLines, paperSize }\n}\n","// web/src/components/print/composables/useAdsorbManager.ts\n// 吸附管理器:在 CanvasPaper 层创建单例,统一处理吸附检测与引导线渲染\n// BaseElement 拖拽时通过函数 props 调用 requestAdsorb / clearGuides\nimport type { RuntimeElement, ElementRect, AdsorbResult } from '../types'\nimport { useAdsorb, type AdsorbConfig } from './useAdsorb'\n\nexport interface AdsorbManagerOptions {\n getElements: () => RuntimeElement[]\n /** 纸张尺寸(mm),用于引导线贯穿整页 */\n getPaperSize: () => { width: number; height: number }\n /** 手动参考线位置(mm),参与吸附 */\n getGuides?: () => { vertical: number[]; horizontal: number[] }\n config?: AdsorbConfig\n}\n\nexport function useAdsorbManager(options: AdsorbManagerOptions) {\n const { check, renderLines, clearLines, guideLines, paperSize } = useAdsorb(\n options.config ?? { adsorbMin: 1, adsorbLineMin: 2, showAdsorbLine: true }\n )\n\n function requestAdsorb(movingRect: ElementRect): AdsorbResult {\n const others = options.getElements()\n .filter(e => e.id !== movingRect.id)\n .map(e => ({\n id: e.id,\n left: e.options.left,\n top: e.options.top,\n width: e.options.width,\n height: e.options.height,\n } as ElementRect))\n const result = check(movingRect, others, options.getGuides?.())\n const paper = options.getPaperSize()\n renderLines(result.lines, paper.width, paper.height)\n return result\n }\n\n function clearGuides() {\n clearLines()\n }\n\n return { requestAdsorb, clearGuides, guideLines, paperSize }\n}\n","<template>\n <div\n class=\"hiprint-printPaper\"\n :style=\"paperStyle\"\n >\n <div\n class=\"hiprint-printPaper-content\"\n ref=\"contentRef\"\n :style=\"contentStyle\"\n >\n <!-- 刻度标尺 -->\n <template v-if=\"showRulerComputed\">\n <Ruler orientation=\"horizontal\" :length-m-m=\"paperWidthMM\" :scale=\"scale\" @add-guide=\"(t: 'vertical' | 'horizontal', p: number) => emit('add-guide', t, p)\" />\n <Ruler orientation=\"vertical\" :length-m-m=\"paperHeightMM\" :scale=\"scale\" @add-guide=\"(t: 'vertical' | 'horizontal', p: number) => emit('add-guide', t, p)\" />\n </template>\n <!-- 网格背景 -->\n <div\n v-if=\"showGrid && designMode\"\n class=\"grid-bg\"\n :style=\"gridBgStyle\"\n />\n <!-- 吸附高亮指示点(吸附发生时闪烁) -->\n <div\n v-if=\"snapIndicator\"\n :key=\"snapIndicator.key\"\n class=\"snap-indicator\"\n :style=\"{\n left: snapIndicator.left + 'mm',\n top: snapIndicator.top + 'mm',\n }\"\n />\n\n <!-- 水印渲染层(在所有元素之下) -->\n <div\n v-if=\"watermarkVisible\"\n class=\"watermark-layer\"\n :style=\"watermarkStyle\"\n />\n\n <!-- ─── 三段式区域层:上边距→页眉→内容→页脚→下边距 ─── -->\n <!-- 页眉层 -->\n <div\n class=\"zone-layer zone-header\"\n :class=\"{ 'design-mode': designMode }\"\n :style=\"layerStyle(zoneRectsMM.header)\"\n >\n <span v-if=\"designMode\" class=\"zone-label\">页眉</span>\n <BaseElement\n v-for=\"el in headerElements\"\n :key=\"el.id\"\n :element=\"el\"\n :design-mode=\"designMode\"\n :print-data=\"printData\"\n :scale=\"scale\"\n :all-elements=\"headerElements\"\n :snap-to-grid=\"snapToGrid\"\n :show-table-ghost-border=\"showTableGhostBorder\"\n zone=\"header\"\n :adsorb-handler=\"requestAdsorb\"\n :clear-adsorb-guides=\"clearGuides\"\n @select=\"onSelectElement\"\n @drag-start=\"$emit('drag-start')\"\n @drag-stop=\"$emit('drag-stop')\"\n @dblclick-element=\"(id: string) => $emit('dblclick-element', id)\"\n @dblclick-cell=\"(id: string, r: number, c: number) => $emit('dblclick-cell', id, r, c)\"\n @contextmenu=\"(id: string, e: MouseEvent) => $emit('contextmenu', id, e)\"\n @clone-element=\"(el, pos) => $emit('clone-element', el, pos)\"\n />\n <div\n v-if=\"designMode\"\n class=\"zone-resize-handle handle-bottom\"\n @mousedown.prevent.stop=\"startZoneResize('header', $event)\"\n >\n <div v-if=\"zoneResizing?.zone === 'header'\" class=\"zone-height-tip\">\n {{ templateData.header.height.toFixed(1) }}mm\n </div>\n </div>\n </div>\n\n <!-- 内容层 -->\n <div\n class=\"zone-layer zone-content\"\n :class=\"{ 'design-mode': designMode }\"\n :style=\"layerStyle(zoneRectsMM.content)\"\n >\n <!-- 首页叠加占位(本次不可编辑) -->\n <div\n v-if=\"designMode && templateData.firstPageOverlay.height > 0\"\n class=\"zone-overlay\"\n :style=\"{ height: templateData.firstPageOverlay.height + 'mm' }\"\n >\n <span class=\"zone-label\">首页叠加</span>\n </div>\n <BaseElement\n v-for=\"el in contentElements\"\n :key=\"el.id\"\n :element=\"el\"\n :design-mode=\"designMode\"\n :print-data=\"printData\"\n :scale=\"scale\"\n :all-elements=\"contentElements\"\n :snap-to-grid=\"snapToGrid\"\n :show-table-ghost-border=\"showTableGhostBorder\"\n zone=\"content\"\n :adsorb-handler=\"requestAdsorb\"\n :clear-adsorb-guides=\"clearGuides\"\n @select=\"onSelectElement\"\n @drag-start=\"$emit('drag-start')\"\n @drag-stop=\"$emit('drag-stop')\"\n @dblclick-element=\"(id: string) => $emit('dblclick-element', id)\"\n @dblclick-cell=\"(id: string, r: number, c: number) => $emit('dblclick-cell', id, r, c)\"\n @contextmenu=\"(id: string, e: MouseEvent) => $emit('contextmenu', id, e)\"\n @clone-element=\"(el, pos) => $emit('clone-element', el, pos)\"\n />\n </div>\n\n <!-- 页脚层 -->\n <div\n class=\"zone-layer zone-footer\"\n :class=\"{ 'design-mode': designMode }\"\n :style=\"layerStyle(zoneRectsMM.footer)\"\n >\n <span v-if=\"designMode\" class=\"zone-label\">页脚</span>\n <BaseElement\n v-for=\"el in footerElements\"\n :key=\"el.id\"\n :element=\"el\"\n :design-mode=\"designMode\"\n :print-data=\"printData\"\n :scale=\"scale\"\n :all-elements=\"footerElements\"\n :snap-to-grid=\"snapToGrid\"\n :show-table-ghost-border=\"showTableGhostBorder\"\n zone=\"footer\"\n :adsorb-handler=\"requestAdsorb\"\n :clear-adsorb-guides=\"clearGuides\"\n @select=\"onSelectElement\"\n @drag-start=\"$emit('drag-start')\"\n @drag-stop=\"$emit('drag-stop')\"\n @dblclick-element=\"(id: string) => $emit('dblclick-element', id)\"\n @dblclick-cell=\"(id: string, r: number, c: number) => $emit('dblclick-cell', id, r, c)\"\n @contextmenu=\"(id: string, e: MouseEvent) => $emit('contextmenu', id, e)\"\n @clone-element=\"(el, pos) => $emit('clone-element', el, pos)\"\n />\n <div\n v-if=\"designMode\"\n class=\"zone-resize-handle handle-top\"\n @mousedown.prevent.stop=\"startZoneResize('footer', $event)\"\n >\n <div v-if=\"zoneResizing?.zone === 'footer'\" class=\"zone-height-tip\">\n {{ templateData.footer.height.toFixed(1) }}mm\n </div>\n </div>\n </div>\n\n <!-- 吸附引导线(v-for 渲染,拖拽结束后自动清除) -->\n <div\n v-for=\"(line, idx) in guideLines\"\n :key=\"idx\"\n class=\"adsorb-guide\"\n :class=\"[`guide-${line.type}`]\"\n :style=\"line.type === 'vertical'\n ? { left: line.position + 'mm', top: '0', height: guidePaperSize.height + 'mm', borderLeftColor: line.color || 'var(--pd-accent-secondary, #f56c6c)' }\n : { top: line.position + 'mm', left: '0', width: guidePaperSize.width + 'mm', borderTopColor: line.color || 'var(--pd-accent-secondary, #f56c6c)' }\"\n />\n <!-- 手动参考线(常驻,可拖动/双击删除) -->\n <div\n v-for=\"g in guides\"\n :key=\"'mg-' + g.id\"\n class=\"manual-guide\"\n :class=\"[`guide-${g.type}`]\"\n :style=\"g.type === 'vertical'\n ? { left: g.position + 'mm', top: '0', height: paperHeightMM + 'mm' }\n : { top: g.position + 'mm', left: '0', width: paperWidthMM + 'mm' }\"\n @mousedown.prevent.stop=\"onGuideDown($event, g)\"\n @dblclick.prevent.stop=\"g.id && emit('guide-remove', g.id)\"\n />\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, onUnmounted } from 'vue'\nimport type { RuntimeElement, TemplateData, ElementRect, ElementZone, AlignLine } from '../types'\nimport { getPaperDimensions } from '../utils/default-config'\nimport BaseElement from './elements/BaseElement.vue'\nimport Ruler from './Ruler.vue'\nimport { useAdsorbManager } from '../composables/useAdsorbManager'\n\nconst props = defineProps<{\n templateData: TemplateData\n runtimeElements: RuntimeElement[]\n designMode?: boolean\n printData?: Record<string, any>[]\n scale?: number\n showRuler?: boolean\n showGrid?: boolean\n snapToGrid?: boolean\n showTableGhostBorder?: boolean\n guides?: AlignLine[]\n}>()\n\nconst emit = defineEmits<{\n select: [id: string, multiple: boolean]\n 'drag-start': []\n 'drag-stop': []\n 'dblclick-element': [id: string]\n 'dblclick-cell': [elementId: string, r: number, c: number]\n 'contextmenu': [id: string, e: MouseEvent]\n 'zone-height-change': [zone: 'header' | 'footer', height: number]\n 'zone-height-commit': [zone: 'header' | 'footer']\n 'add-guide': [type: 'vertical' | 'horizontal', positionMm: number]\n 'guide-move': [id: string, positionMm: number]\n 'guide-remove': [id: string]\n 'clone-element': [element: RuntimeElement, position: { left: number; top: number }]\n}>()\n\nconst contentRef = ref<HTMLElement | null>(null)\n\n/** 根据纸张尺寸和方向计算宽高(mm) */\nconst paperWidthMM = computed(() => {\n return getPaperDimensions(props.templateData).width\n})\nconst paperHeightMM = computed(() => {\n return getPaperDimensions(props.templateData).height\n})\n\n/** 三区矩形(mm,纸面坐标系):上边距→页眉→内容→页脚→下边距 */\nconst zoneRectsMM = computed(() => {\n const m = props.templateData.margins\n const headerH = props.templateData.header.height\n const footerH = props.templateData.footer.height\n const contentW = paperWidthMM.value - m.left - m.right\n return {\n header: { left: m.left, top: m.top, width: contentW, height: headerH },\n content: {\n left: m.left,\n top: m.top + headerH,\n width: contentW,\n height: paperHeightMM.value - m.top - m.bottom - headerH - footerH,\n },\n footer: {\n left: m.left,\n top: paperHeightMM.value - m.bottom - footerH,\n width: contentW,\n height: footerH,\n },\n }\n})\n\nfunction layerStyle(r: { left: number; top: number; width: number; height: number }) {\n return {\n position: 'absolute' as const,\n left: r.left + 'mm',\n top: r.top + 'mm',\n width: r.width + 'mm',\n height: r.height + 'mm',\n }\n}\n\n// 优化:一次遍历完成三区分类,避免三次全量 filter\nconst zoneElements = computed(() => {\n const result = { header: [] as RuntimeElement[], footer: [] as RuntimeElement[], content: [] as RuntimeElement[] }\n for (const el of props.runtimeElements) {\n if (el.zone === 'header') result.header.push(el)\n else if (el.zone === 'footer') result.footer.push(el)\n else result.content.push(el)\n }\n return result\n})\nconst headerElements = computed(() => zoneElements.value.header)\nconst footerElements = computed(() => zoneElements.value.footer)\nconst contentElements = computed(() => zoneElements.value.content)\n\n// 吸附管理器:仅同区元素间吸附,引导线通过 Vue 响应式渲染\nlet currentDragZone: ElementZone = 'content'\n\nconst { requestAdsorb: rawRequestAdsorb, clearGuides, guideLines, paperSize: guidePaperSize } = useAdsorbManager({\n // 优化:直接使用预计算的 zoneElements,避免每次拖拽都 filter\n getElements: () => zoneElements.value[currentDragZone],\n getPaperSize: () => {\n const r = zoneRectsMM.value[currentDragZone]\n return { width: r.width, height: r.height }\n },\n getGuides: () => {\n const v: number[] = [], h: number[] = []\n for (const g of props.guides ?? []) {\n if (g.type === 'vertical') v.push(g.position)\n else h.push(g.position)\n }\n return { vertical: v, horizontal: h }\n },\n})\n\nfunction requestAdsorb(rect: ElementRect): ReturnType<typeof rawRequestAdsorb> {\n const el = props.runtimeElements.find(e => e.id === rect.id)\n currentDragZone = el?.zone || 'content'\n const result = rawRequestAdsorb(rect)\n // 位置被修正即发生吸附,在元素中心闪烁网格高亮点\n if (result.left !== rect.left || result.top !== rect.top) {\n showSnapIndicator(result.left + rect.width / 2, result.top + rect.height / 2)\n }\n return result\n}\n\n/** 拖动手动参考线 */\nfunction onGuideDown(e: MouseEvent, g: AlignLine) {\n const startPt = g.position\n const startX = e.clientX, startY = e.clientY\n const s = props.scale ?? 1\n const MM_PER_PX = 25.4 / 96\n const onMove = (ev: MouseEvent) => {\n const delta = (g.type === 'vertical' ? (ev.clientX - startX) : (ev.clientY - startY)) / s * MM_PER_PX\n emit('guide-move', g.id!, startPt + delta)\n }\n const onUp = () => {\n window.removeEventListener('mousemove', onMove)\n window.removeEventListener('mouseup', onUp)\n }\n window.addEventListener('mousemove', onMove)\n window.addEventListener('mouseup', onUp)\n}\n\nconst paperStyle = computed(() => ({\n width: paperWidthMM.value + 'mm',\n minHeight: paperHeightMM.value + 'mm',\n background: 'var(--pd-paper, #fff)',\n boxShadow: 'var(--pd-shadow-paper, 0 1px 2px rgba(0,0,0,.12), 0 8px 24px rgba(0,0,0,.08))',\n margin: '0 auto',\n overflow: 'hidden',\n position: 'relative' as const,\n transform: props.scale ? `scale(${props.scale})` : undefined,\n transformOrigin: '0 0',\n}))\n\nconst contentStyle = computed(() => {\n const m = props.templateData.margins\n return {\n padding: `${m.top}mm ${m.right}mm ${m.bottom}mm ${m.left}mm`,\n position: 'relative' as const,\n minHeight: paperHeightMM.value + 'mm',\n }\n})\n\nconst showRulerComputed = computed(() => props.showRuler !== false && !!props.designMode)\n\nconst gridBgStyle = computed(() => {\n const size = 5 // mm\n // 虚线网格:SVG 平铺图案,颜色调淡避免干扰元素视觉\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"><path d=\"M0 .5H20M.5 0V20\" fill=\"none\" stroke=\"rgba(0,0,0,0.08)\" stroke-width=\"1\" stroke-dasharray=\"4 4\"/></svg>`\n return {\n backgroundImage: `url(\"data:image/svg+xml,${encodeURIComponent(svg)}\")`,\n backgroundSize: `${size}mm ${size}mm`,\n backgroundPosition: '0 0',\n }\n})\n\n// ─── 吸附高亮指示 ───\nlet snapSeq = 0\nlet snapTimer: ReturnType<typeof setTimeout> | null = null\nconst snapIndicator = ref<{ left: number; top: number; key: number } | null>(null)\n\n/** 在吸附对齐位置闪烁一个高亮点 */\nfunction showSnapIndicator(left: number, top: number) {\n snapSeq += 1\n snapIndicator.value = { left, top, key: snapSeq }\n if (snapTimer) clearTimeout(snapTimer)\n snapTimer = setTimeout(() => {\n snapIndicator.value = null\n }, 300)\n}\n\n// ─── 水印渲染 ───\nconst watermarkVisible = computed(() => {\n const w = props.templateData.watermark\n if (!w) return false\n // 向后兼容:如果没有 mode 字段,使用 content\n if (!w.mode || w.mode === 'fixed') {\n return !!w.content && w.content.trim().length > 0\n }\n // 绑定字段模式\n return !!w.binding\n})\n\nconst watermarkStyle = computed(() => {\n const w = props.templateData.watermark || {}\n const color = w.color || '#cccccc'\n const opacity = w.opacity ?? 0.15\n const rotate = w.rotate ?? -30\n // 获取水印文本\n let text = getWatermarkText(w)\n if (w.timestamp) {\n const now = new Date()\n const ts = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`\n text = text ? `${text} ${ts}` : ts\n }\n return {\n position: 'absolute' as const,\n top: '0',\n left: '0',\n width: '100%',\n height: '100%',\n pointerEvents: 'none' as const,\n zIndex: '0',\n overflow: 'hidden',\n opacity: String(opacity),\n backgroundImage: buildWatermarkSvg(text, color, rotate),\n backgroundRepeat: 'repeat',\n }\n})\n\n/** 获取水印文本(支持绑定字段) */\nfunction getWatermarkText(w: { mode?: 'fixed' | 'binding'; content?: string; binding?: string; testData?: string }): string {\n // 向后兼容:如果没有 mode 字段,使用 content\n if (!w.mode || w.mode === 'fixed') {\n return w.content || ''\n }\n // 绑定字段模式\n if (w.binding) {\n // 从打印数据中取值\n const printData = props.printData?.[0]\n if (printData && printData[w.binding] !== undefined && printData[w.binding] !== null) {\n return String(printData[w.binding])\n }\n // 回退到测试值\n return w.testData || `[${w.binding}]`\n }\n return ''\n}\n\n/** 用内联 SVG 生成水印背景图案 */\nfunction buildWatermarkSvg(text: string, color: string, rotate: number): string {\n const escaped = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"260\" height=\"180\">\n <text x=\"130\" y=\"90\" font-size=\"16\" fill=\"${color}\" text-anchor=\"middle\" dominant-baseline=\"middle\" transform=\"rotate(${rotate},130,90)\">${escaped}</text>\n </svg>`\n return `url(\"data:image/svg+xml,${encodeURIComponent(svg)}\")`\n}\n\n// ─── 页眉/页脚高度拖拽 ───\nconst zoneResizing = ref<{ zone: 'header' | 'footer'; startY: number; startH: number } | null>(null)\n\nfunction startZoneResize(zone: 'header' | 'footer', e: MouseEvent) {\n // 防止重复绑定:先清理再绑定\n cleanupZoneResize()\n zoneResizing.value = { zone, startY: e.clientY, startH: props.templateData[zone].height }\n window.addEventListener('mousemove', onZoneResizeMove)\n window.addEventListener('mouseup', onZoneResizeUp)\n}\n\nfunction onZoneResizeMove(e: MouseEvent) {\n if (!zoneResizing.value) return\n const { zone, startY, startH } = zoneResizing.value\n const dyPx = (e.clientY - startY) / (props.scale || 1)\n const dyMM = dyPx * 25.4 / 96\n const delta = zone === 'header' ? dyMM : -dyMM\n // 0.1mm 步进;上限 100mm 与属性面板一致,且保证内容区至少 10mm\n const maxH = Math.min(\n 100,\n paperHeightMM.value - props.templateData.margins.top - props.templateData.margins.bottom\n - (zone === 'header' ? props.templateData.footer.height : props.templateData.header.height)\n - 10,\n )\n const h = Math.min(maxH, Math.max(0, Math.round((startH + delta) * 10) / 10))\n emit('zone-height-change', zone, h)\n}\n\nfunction onZoneResizeUp() {\n if (!zoneResizing.value) return\n const zone = zoneResizing.value.zone\n zoneResizing.value = null\n window.removeEventListener('mousemove', onZoneResizeMove)\n window.removeEventListener('mouseup', onZoneResizeUp)\n emit('zone-height-commit', zone)\n}\n\n/** 清理区域拖拽事件监听器 */\nfunction cleanupZoneResize() {\n window.removeEventListener('mousemove', onZoneResizeMove)\n window.removeEventListener('mouseup', onZoneResizeUp)\n zoneResizing.value = null\n}\n\nonUnmounted(() => {\n cleanupZoneResize()\n if (snapTimer) clearTimeout(snapTimer)\n})\n\nfunction onSelectElement(id: string, multiple: boolean) {\n emit('select', id, multiple)\n}\n\ndefineExpose({ contentRef })\n</script>\n\n<style scoped>\n/* 纸张缩放平滑过渡(配合鼠标位置缩放中心) */\n.hiprint-printPaper {\n transition: transform 0.15s ease-out;\n}\n/* ─── 三段式区域层 ─── */\n.zone-layer {\n box-sizing: border-box;\n}\n.zone-layer.zone-header.design-mode,\n.zone-layer.zone-footer.design-mode {\n outline: 1px dashed var(--pd-ink-green, #67c23a);\n background: rgba(103, 194, 58, 0.04);\n}\n.zone-layer.zone-content.design-mode {\n outline: 1px dashed #C3C9D6;\n}\n.zone-overlay {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n outline: 1px dashed #06B6D4;\n background: rgba(6, 182, 212, 0.04);\n box-sizing: border-box;\n pointer-events: none;\n z-index: 1;\n}\n.zone-label {\n position: absolute;\n top: 2px;\n right: 4px;\n font-size: 9px;\n color: #909399;\n pointer-events: none;\n user-select: none;\n}\n/* 区域高度拖拽手柄 */\n.zone-resize-handle {\n position: absolute;\n left: 0;\n width: 100%;\n height: 6px;\n cursor: ns-resize;\n z-index: 5;\n}\n.zone-resize-handle.handle-bottom {\n bottom: -3px;\n}\n.zone-resize-handle.handle-top {\n top: -3px;\n}\n.zone-resize-handle:hover {\n background: rgba(16, 185, 129, 0.25);\n}\n.zone-height-tip {\n position: absolute;\n right: 4px;\n top: -22px;\n padding: 1px 6px;\n font-size: 11px;\n color: #fff;\n background: #10B981;\n border-radius: 3px;\n white-space: nowrap;\n pointer-events: none;\n}\n/* 刻度标尺由 Ruler.vue Canvas 绘制 */\n.grid-bg {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n z-index: 0;\n}\n/* 吸附高亮指示点 */\n.snap-indicator {\n position: absolute;\n width: 6px;\n height: 6px;\n background: var(--pd-accent, #165DFF);\n border-radius: 50%;\n transform: translate(-50%, -50%);\n pointer-events: none;\n z-index: 10;\n animation: snap-pulse 0.3s ease-out;\n}\n@keyframes snap-pulse {\n from { transform: translate(-50%, -50%) scale(2); opacity: 0.5; }\n to { transform: translate(-50%, -50%) scale(1); opacity: 0; }\n}\n/* 水印层 */\n.watermark-layer {\n pointer-events: none;\n}\n/* 吸附引导线 */\n.adsorb-guide {\n position: absolute;\n pointer-events: none;\n z-index: 9999;\n}\n.adsorb-guide.guide-vertical {\n border-left: 1px dashed var(--pd-accent-secondary, #f56c6c);\n}\n.adsorb-guide.guide-horizontal {\n border-top: 1px dashed var(--pd-accent-secondary, #f56c6c);\n}\n/* 手动参考线 */\n.manual-guide { position: absolute; pointer-events: auto; z-index: 9998; cursor: move; }\n.manual-guide.guide-vertical { border-left: 1px solid #3B82F6; width: 0; }\n.manual-guide.guide-horizontal { border-top: 1px solid #3B82F6; height: 0; }\n.manual-guide:hover { border-color: #EF4444 !important; }\n</style>\n","<template>\n <div\n ref=\"rootRef\"\n class=\"canvas-area\"\n @dragover.prevent\n @drop=\"onDrop\"\n @mousedown=\"onCanvasMouseDown\"\n @mousemove=\"onMouseMove\"\n @mouseleave=\"onMouseLeave\"\n @wheel=\"onWheel\"\n @contextmenu.prevent=\"onContextMenu\"\n >\n <div class=\"canvas-scroll\">\n <CanvasPaper\n :template-data=\"templateData\"\n :runtime-elements=\"elements\"\n :design-mode=\"true\"\n :print-data=\"[]\"\n :scale=\"scale\"\n :show-grid=\"showGrid\"\n :snap-to-grid=\"snapToGrid\"\n :show-table-ghost-border=\"showTableGhostBorder\"\n :guides=\"guides\"\n @select=\"onSelectElement\"\n @add-guide=\"(t: 'vertical' | 'horizontal', p: number) => $emit('add-guide', t, p)\"\n @guide-move=\"(id: string, p: number) => $emit('guide-move', id, p)\"\n @guide-remove=\"(id: string) => $emit('guide-remove', id)\"\n @drag-start=\"$emit('drag-start')\"\n @drag-stop=\"$emit('drag-stop')\"\n @dblclick-element=\"(id: string) => $emit('dblclick-element', id)\"\n @dblclick-cell=\"(id: string, r: number, c: number) => $emit('dblclick-cell', id, r, c)\"\n @contextmenu=\"(id: string, e: MouseEvent) => onContextMenu(e, id)\"\n @zone-height-change=\"(zone: 'header' | 'footer', h: number) => $emit('zone-height-change', zone, h)\"\n @zone-height-commit=\"(zone: 'header' | 'footer') => $emit('zone-height-commit', zone)\"\n @clone-element=\"(el, pos) => $emit('clone-element', el, pos)\"\n />\n <!-- 叠层对比截图 -->\n <div v-if=\"overlayVisible && screenshotUrl\" class=\"overlay-layer\">\n <img :src=\"screenshotUrl\" class=\"overlay-image\" :style=\"{ opacity: overlayOpacity ?? 0.5 }\" />\n </div>\n </div>\n\n <!-- 框选选框 -->\n <div\n v-if=\"marquee.visible\"\n class=\"marquee-selection\"\n :style=\"{\n left: marquee.x + 'px',\n top: marquee.y + 'px',\n width: marquee.w + 'px',\n height: marquee.h + 'px',\n }\"\n />\n\n <!-- 右键菜单 -->\n <div\n v-if=\"contextMenu.visible\"\n class=\"context-menu\"\n :style=\"{ left: contextMenu.x + 'px', top: contextMenu.y + 'px' }\"\n >\n <template v-if=\"contextMenu.targetId\">\n <div class=\"context-menu-item\" @click=\"emitAction('copy')\">复制</div>\n <div class=\"context-menu-item\" @click=\"emitAction('cut')\">剪切</div>\n <div class=\"context-menu-item\" :class=\"{ disabled: !hasClipboard }\" @click=\"emitAction('paste')\">粘贴</div>\n <div class=\"context-menu-item\" @click=\"emitAction('delete')\">删除</div>\n <div class=\"context-menu-sep\" />\n <div class=\"context-menu-item\" @click=\"emitAction('move-layer', 'top')\">置顶</div>\n <div class=\"context-menu-item\" @click=\"emitAction('move-layer', 'up')\">上移</div>\n <div class=\"context-menu-item\" @click=\"emitAction('move-layer', 'down')\">下移</div>\n <div class=\"context-menu-item\" @click=\"emitAction('move-layer', 'bottom')\">置底</div>\n <div class=\"context-menu-sep\" />\n <div class=\"context-menu-item\" @click=\"emitAction('group')\">编组 Ctrl+G</div>\n <div class=\"context-menu-item\" :class=\"{ disabled: !selectedElementHasGroup }\" @click=\"emitAction('ungroup')\">取消编组 Ctrl+Shift+G</div>\n </template>\n <template v-else>\n <div class=\"context-menu-item\" :class=\"{ disabled: !hasClipboard }\" @click=\"handlePaste\">粘贴</div>\n <div class=\"context-menu-item\" @click=\"handleSelectAll\">全选</div>\n <div class=\"context-menu-item\" @click=\"handleClearSelection\">取消选择</div>\n </template>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, reactive, onBeforeUnmount } from 'vue'\nimport type { RuntimeElement, TemplateData, AlignLine } from '../types'\nimport { pxToMm } from '../utils/units'\nimport CanvasPaper from './CanvasPaper.vue'\n\nconst props = defineProps<{\n templateData: TemplateData\n elements: RuntimeElement[]\n scale: number\n showGrid?: boolean\n snapToGrid?: boolean\n showTableGhostBorder?: boolean\n hasClipboard?: boolean\n guides?: AlignLine[]\n overlayVisible?: boolean\n screenshotUrl?: string\n overlayOpacity?: number\n selectedElementHasGroup?: boolean\n}>()\n\nconst emit = defineEmits<{\n select: [id: string, multiple: boolean]\n 'drop-element': [type: string, dropPoint?: { x: number; y: number }]\n 'drop-field': [field: { fieldKey: string; fieldLabel: string }, dropPoint?: { x: number; y: number }]\n 'drag-start': []\n 'drag-stop': []\n 'dblclick-element': [id: string]\n 'dblclick-cell': [elementId: string, r: number, c: number]\n 'zone-height-change': [zone: 'header' | 'footer', height: number]\n 'zone-height-commit': [zone: 'header' | 'footer']\n 'select-all': []\n 'clear-selection': []\n 'preview': [ids: string[]]\n 'commit-preview': []\n 'paste': []\n 'copy': []\n 'cut': []\n 'delete': []\n 'move-layer': [direction: string]\n group: []\n ungroup: []\n 'coordinate': [pos: { x: number; y: number } | null]\n 'add-guide': [type: 'vertical' | 'horizontal', positionMm: number]\n 'guide-move': [id: string, positionMm: number]\n 'guide-remove': [id: string]\n 'zoom': [delta: number]\n 'clone-element': [element: RuntimeElement, position: { left: number; top: number }]\n}>()\n\nfunction onSelectElement(id: string, multiple: boolean) {\n emit('select', id, multiple)\n}\n\nconst rootRef = ref<HTMLElement | null>(null)\n\n/** 客户端坐标 → 纸面 mm 坐标;纸张未挂载或落点在纸外时返回 undefined(走默认落位) */\nfunction toPaperPoint(e: DragEvent): { x: number; y: number } | undefined {\n const paper = rootRef.value?.querySelector('.hiprint-printPaper') as HTMLElement | null\n if (!paper) return undefined\n const rect = paper.getBoundingClientRect()\n const scale = props.scale || 1\n const x = pxToMm((e.clientX - rect.left) / scale)\n const y = pxToMm((e.clientY - rect.top) / scale)\n if (x < 0 || y < 0) return undefined\n return { x, y }\n}\n\nfunction onDrop(e: DragEvent) {\n const dropPoint = toPaperPoint(e)\n const fieldData = e.dataTransfer?.getData('fieldData')\n if (fieldData) {\n try {\n const field = JSON.parse(fieldData) as { fieldKey: string; fieldLabel: string }\n emit('drop-field', field, dropPoint)\n return\n } catch {\n // 解析失败,忽略\n }\n }\n const elementType = e.dataTransfer?.getData('elementType')\n if (elementType) {\n emit('drop-element', elementType, dropPoint)\n }\n}\n\n// ─── 鼠标框选 ───\nconst marquee = reactive({ visible: false, x: 0, y: 0, w: 0, h: 0 })\nlet marqueeStart = { x: 0, y: 0 }\n\n/** 判断点击目标是否为画布空白区域(非元素) */\nfunction isCanvasBackground(target: EventTarget | null): boolean {\n if (!target || !(target instanceof HTMLElement)) return false\n // 点击在画布容器、滚动层、纸张本身上视为空白区域\n if (target === rootRef.value) return true\n if (target.classList.contains('canvas-scroll')) return true\n if (target.classList.contains('hiprint-printPaper')) return true\n if (target.classList.contains('hiprint-printPaper-content')) return true\n if (target.classList.contains('zone-layer')) return true\n if (target.classList.contains('grid-bg')) return true\n if (target.classList.contains('watermark-layer')) return true\n return false\n}\n\nconst MM_TO_PX = 96 / 25.4\nfunction onMouseMove(e: MouseEvent) {\n const paper = rootRef.value?.querySelector('.hiprint-printPaper') as HTMLElement | null\n if (!paper) return\n const rect = paper.getBoundingClientRect()\n const s = props.scale || 1\n const xMm = pxToMm((e.clientX - rect.left) / s)\n const yMm = pxToMm((e.clientY - rect.top) / s)\n if (xMm < 0 || yMm < 0) { emit('coordinate', null); return }\n emit('coordinate', { x: xMm, y: yMm })\n}\nfunction onMouseLeave() { emit('coordinate', null) }\n\n/** Ctrl/Cmd+滚轮缩放:以鼠标位置为缩放中心,缩放前后保持鼠标下的内容点不动 */\nfunction onWheel(e: WheelEvent) {\n if (!(e.ctrlKey || e.metaKey)) return\n e.preventDefault()\n const oldScale = props.scale\n const newScale = Math.max(0.25, Math.min(3, oldScale + (e.deltaY > 0 ? -0.1 : 0.1)))\n if (newScale === oldScale) return\n\n // 缩放中心换算:scroll' = (scroll + mouse) * ratio - mouse\n const container = rootRef.value\n if (container) {\n const rect = container.getBoundingClientRect()\n const mouseX = e.clientX - rect.left\n const mouseY = e.clientY - rect.top\n const ratio = newScale / oldScale\n container.scrollLeft = (container.scrollLeft + mouseX) * ratio - mouseX\n container.scrollTop = (container.scrollTop + mouseY) * ratio - mouseY\n }\n\n // 以百分比增量上报(父级 scale 为百分比)\n emit('zoom', (newScale - oldScale) * 100)\n}\n\nfunction onCanvasMouseDown(e: MouseEvent) {\n // 右键由 contextmenu 处理\n if (e.button === 2) return\n if (!isCanvasBackground(e.target)) return\n\n // 点击空白区域取消选择\n emit('clear-selection')\n\n // 启动框选\n marqueeStart = { x: e.clientX, y: e.clientY }\n marquee.visible = true\n marquee.x = e.clientX\n marquee.y = e.clientY\n marquee.w = 0\n marquee.h = 0\n\n window.addEventListener('mousemove', onMarqueeMove)\n window.addEventListener('mouseup', onMarqueeUp)\n}\n\n/** 框选命中测试:左->右拖=交集,右->左拖=包含;返回命中元素 id */\nfunction hitTestIds(): string[] {\n if (marquee.w < 3 || marquee.h < 3) return []\n const paper = rootRef.value?.querySelector('.hiprint-printPaper') as HTMLElement | null\n if (!paper) return []\n const paperRect = paper.getBoundingClientRect()\n const s = props.scale || 1\n // marquee.x 是选框左边缘;小于起点 x 表示从右向左拖(包含模式)\n const containMode = marquee.x < marqueeStart.x\n const ids: string[] = []\n for (const el of props.elements) {\n if (el.options.visible === false || el.options.locked) continue\n const elLeft = paperRect.left + el.options.left * MM_TO_PX * s\n const elTop = paperRect.top + el.options.top * MM_TO_PX * s\n const elRight = elLeft + el.options.width * MM_TO_PX * s\n const elBottom = elTop + el.options.height * MM_TO_PX * s\n const inter = elLeft < marquee.x + marquee.w && elRight > marquee.x\n && elTop < marquee.y + marquee.h && elBottom > marquee.y\n const contained = elLeft >= marquee.x && elRight <= marquee.x + marquee.w\n && elTop >= marquee.y && elBottom <= marquee.y + marquee.h\n if (containMode ? contained : inter) ids.push(el.id)\n }\n return ids\n}\n\nfunction onMarqueeMove(e: MouseEvent) {\n const dx = e.clientX - marqueeStart.x\n const dy = e.clientY - marqueeStart.y\n marquee.x = dx >= 0 ? marqueeStart.x : e.clientX\n marquee.y = dy >= 0 ? marqueeStart.y : e.clientY\n marquee.w = Math.abs(dx)\n marquee.h = Math.abs(dy)\n // 实时预选高亮\n emit('preview', hitTestIds())\n}\n\nfunction onMarqueeUp() {\n window.removeEventListener('mousemove', onMarqueeMove)\n window.removeEventListener('mouseup', onMarqueeUp)\n\n const ids = hitTestIds()\n emit('preview', ids) // 确保预选为最终状态\n if (ids.length > 0) emit('commit-preview')\n else emit('clear-selection')\n emit('preview', []) // 清除预选高亮\n\n marquee.visible = false\n}\n\n// ─── 右键菜单 ───\nconst contextMenu = reactive({ visible: false, x: 0, y: 0, targetId: null as string | null })\n\nfunction onContextMenu(e: MouseEvent, elId?: string) {\n // 元素右键:由 BaseElement 上抛(已 stop);空白右键:无 elId,仅背景区域弹菜单\n if (!elId && !isCanvasBackground(e.target)) return\n const containerRect = rootRef.value?.getBoundingClientRect()\n if (!containerRect) return\n contextMenu.x = e.clientX - containerRect.left\n contextMenu.y = e.clientY - containerRect.top\n contextMenu.targetId = elId ?? null\n contextMenu.visible = true\n\n // 点击其他区域关闭:先清理旧监听器防止重复绑定\n window.removeEventListener('mousedown', closeContextMenu)\n setTimeout(() => {\n window.addEventListener('mousedown', closeContextMenu, { once: true })\n }, 0)\n}\n\nfunction closeContextMenu() {\n contextMenu.visible = false\n window.removeEventListener('mousedown', closeContextMenu)\n}\n\nfunction handlePaste() {\n contextMenu.visible = false\n if (props.hasClipboard) emit('paste')\n}\n\nfunction handleSelectAll() {\n contextMenu.visible = false\n emit('select-all')\n}\n\nfunction handleClearSelection() {\n contextMenu.visible = false\n emit('clear-selection')\n}\n\n/** 元素右键菜单动作派发 */\nfunction emitAction(action: string, arg?: string) {\n contextMenu.visible = false\n if (action === 'copy') emit('copy')\n else if (action === 'cut') emit('cut')\n else if (action === 'paste') emit('paste')\n else if (action === 'delete') emit('delete')\n else if (action === 'move-layer') emit('move-layer', arg!)\n else if (action === 'group') emit('group')\n else if (action === 'ungroup' && props.selectedElementHasGroup) emit('ungroup')\n}\n\nonBeforeUnmount(() => {\n window.removeEventListener('mousemove', onMarqueeMove)\n window.removeEventListener('mouseup', onMarqueeUp)\n})\n</script>\n\n<style scoped>\n.canvas-area {\n flex: 1;\n overflow: auto;\n /* 制图垫:略深冷灰 + 极淡点阵,让白纸浮起 */\n background-color: var(--pd-canvas-bg, #e6e9f0);\n background-image: radial-gradient(circle, rgba(23, 32, 60, .13) 1px, transparent 1.2px);\n background-size: 20px 20px;\n background-position: center;\n display: flex;\n justify-content: center;\n padding: 44px 28px 32px 44px;\n position: relative;\n}\n.canvas-scroll {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 20px;\n position: relative;\n}\n/* 叠层对比 */\n.overlay-layer {\n position: absolute;\n top: 0;\n left: 0;\n pointer-events: none;\n z-index: 100;\n}\n.overlay-image {\n width: 100%;\n display: block;\n}\n/* 框选选框 */\n.marquee-selection {\n position: fixed;\n border: 1.5px solid rgba(22, 93, 255, 0.7);\n background: rgba(22, 93, 255, 0.08);\n border-radius: 2px;\n pointer-events: none;\n z-index: 10000;\n}\n/* 右键菜单 */\n.context-menu {\n position: absolute;\n background: var(--pd-surface, #ffffff);\n border: 1px solid var(--pd-border-soft, #e9ecf2);\n border-radius: 8px;\n box-shadow: var(--pd-shadow-md, 0 10px 28px rgba(23, 32, 60, .12));\n padding: 5px;\n z-index: 10001;\n min-width: 132px;\n}\n.context-menu-item {\n padding: 7px 12px;\n border-radius: 5px;\n font-size: 12.5px;\n cursor: pointer;\n color: var(--pd-text, #2a2e37);\n user-select: none;\n transition: background .12s ease, color .12s ease;\n}\n.context-menu-item:hover {\n background: var(--pd-accent-soft, rgba(22, 93, 255, .09));\n color: var(--pd-accent, #165DFF);\n}\n.context-menu-item.disabled {\n color: var(--pd-text-faint, #b4b9c4);\n cursor: not-allowed;\n}\n.context-menu-item.disabled:hover {\n background: transparent;\n color: var(--pd-text-faint, #b4b9c4);\n}\n.context-menu-sep {\n height: 1px;\n background: var(--pd-border-soft, #e9ecf2);\n margin: 5px 8px;\n}\n</style>\n","/** 属性面板搜索注册表:分组 → 表单项 → 关键词 */\nexport interface PropertyItem {\n key: string\n keywords: string[]\n}\n\nexport interface PropertyGroupDef {\n group: string\n groupLabel: string\n items: PropertyItem[]\n}\n\nexport const PROPERTY_REGISTRY: PropertyGroupDef[] = [\n {\n group: 'position-size',\n groupLabel: '位置与尺寸',\n items: [\n { key: 'ps-left', keywords: ['X', '横坐标', 'left', '位置'] },\n { key: 'ps-top', keywords: ['Y', '纵坐标', 'top', '位置'] },\n { key: 'ps-width', keywords: ['W', '宽度', 'width', '尺寸'] },\n { key: 'ps-height', keywords: ['H', '高度', 'height', '尺寸'] },\n ],\n },\n {\n group: 'appearance',\n groupLabel: '外观',\n items: [\n { key: 'ap-font-size', keywords: ['字体大小', 'fontsize', '字号'] },\n { key: 'ap-font-weight', keywords: ['字体粗细', '粗体', 'bold'] },\n { key: 'ap-align', keywords: ['对齐', 'align'] },\n { key: 'ap-vertical-align', keywords: ['垂直对齐', 'verticalalign', '顶对齐', '底对齐'] },\n { key: 'ap-color', keywords: ['颜色', 'color'] },\n { key: 'ap-bg-color', keywords: ['背景色', 'background'] },\n { key: 'ap-line-height', keywords: ['行高', 'lineheight'] },\n { key: 'ap-letter-spacing', keywords: ['字间距', 'letterspacing'] },\n ],\n },\n {\n group: 'content',\n groupLabel: '内容',\n items: [\n { key: 'ct-title', keywords: ['内容', '文本', 'title'] },\n { key: 'ct-formatter', keywords: ['格式化', '表达式', 'formatter'] },\n { key: 'ct-table-mode', keywords: ['数据模式', '静态布局', '动态数据'] },\n { key: 'ct-table-source', keywords: ['数据源', '列表字段'] },\n { key: 'ct-table-font', keywords: ['默认字号', '默认颜色', '默认内边距'] },\n { key: 'ct-table-cols', keywords: ['列宽', '表格列'] },\n ],\n },\n {\n group: 'border-bg',\n groupLabel: '边框与背景',\n items: [\n { key: 'bb-border-width', keywords: ['边框宽度', 'border'] },\n { key: 'bb-border-color', keywords: ['边框颜色'] },\n { key: 'bb-bg-color', keywords: ['背景色', 'background'] },\n ],\n },\n {\n group: 'binding',\n groupLabel: '字段绑定',\n items: [\n { key: 'bd-formatter', keywords: ['格式化', '表达式', 'formatter', 'fx', '字段', '绑定', 'field'] },\n { key: 'bd-content', keywords: ['内容', '表达式', '文本', '变量'] },\n ],\n },\n {\n group: 'pagination',\n groupLabel: '分页',\n items: [\n { key: 'pg-enabled', keywords: ['分页', 'pagination', '启用分页'] },\n { key: 'pg-pageable', keywords: ['参与分页', 'pageable'] },\n { key: 'pg-keep-with-next', keywords: ['同页', 'keepWithNext'] },\n ],\n },\n {\n group: 'advanced',\n groupLabel: '高级',\n items: [\n { key: 'ad-locked', keywords: ['锁定', 'lock'] },\n { key: 'ad-fixed', keywords: ['每页重复', 'repeat'] },\n { key: 'ad-z-index', keywords: ['层级', 'zindex'] },\n { key: 'ad-delete', keywords: ['删除'] },\n ],\n },\n]\n\n/** 正向包含匹配:任一关键词包含搜索词即命中;空搜索恒命中 */\nexport function matchKeywords(search: string, keywords: string[]): boolean {\n const s = search.trim().toLowerCase()\n if (!s) {\n return true\n }\n return keywords.some(k => k.toLowerCase().includes(s))\n}\n\n/** 计算命中的分组与表单项 key 集合 */\nexport function searchProperties(search: string): { groups: string[]; itemKeys: Set<string> } {\n const groups: string[] = []\n const itemKeys = new Set<string>()\n for (const g of PROPERTY_REGISTRY) {\n const matched = g.items.filter(item => matchKeywords(search, [...item.keywords, g.groupLabel]))\n if (matched.length > 0) {\n groups.push(g.group)\n for (const item of matched) {\n itemKeys.add(item.key)\n }\n }\n }\n return { groups, itemKeys }\n}\n","<template>\n <div class=\"property-search\">\n <input\n v-model=\"searchText\"\n class=\"pd-input\"\n type=\"search\"\n placeholder=\"搜索属性...\"\n aria-label=\"搜索属性\"\n @input=\"onSearch\"\n >\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue'\n\nconst searchText = ref('')\nconst emit = defineEmits<{ search: [text: string] }>()\n\nfunction onSearch() {\n emit('search', searchText.value)\n}\n</script>\n\n<style scoped>\n.property-search {\n padding: 0 0 10px;\n background: transparent;\n}\n</style>\n","<template>\n <div class=\"property-group\" :class=\"{ 'is-expanded': isExpanded }\">\n <div class=\"group-header\" @click=\"toggle\">\n <span class=\"group-icon\">{{ iconChar }}</span>\n <span class=\"group-title\">{{ title }}</span>\n <span class=\"expand-icon\">{{ isExpanded ? '▾' : '▸' }}</span>\n </div>\n <div v-show=\"isExpanded\" class=\"group-content\">\n <slot />\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted } from 'vue'\n\nconst props = defineProps<{\n title: string\n icon: string\n defaultExpanded?: boolean\n groupKey: string\n}>()\n\nconst isExpanded = ref(props.defaultExpanded ?? true)\n\nconst iconMap: Record<string, string> = {\n Document: '≡',\n Brush: '◧',\n Setting: '⚙',\n}\nconst iconChar = iconMap[props.icon] || '•'\n\nfunction toggle() {\n isExpanded.value = !isExpanded.value\n saveState()\n}\n\nfunction saveState() {\n const key = `property-group-${props.groupKey}`\n try {\n localStorage.setItem(key, String(isExpanded.value))\n } catch {\n // 隐私模式或存储满,忽略持久化失败\n }\n}\n\nfunction loadState() {\n const key = `property-group-${props.groupKey}`\n try {\n const saved = localStorage.getItem(key)\n if (saved !== null) {\n isExpanded.value = saved === 'true'\n }\n } catch {\n // 读取失败保持默认展开状态\n }\n}\n\nonMounted(() => {\n loadState()\n})\n</script>\n\n<style scoped>\n.property-group {\n border: 1px solid var(--pd-border-soft, #e9ecf2);\n border-radius: 8px;\n margin-bottom: 10px;\n background: var(--pd-surface, #ffffff);\n overflow: hidden;\n transition: border-color .14s ease, box-shadow .14s ease;\n}\n.property-group:last-child {\n margin-bottom: 2px;\n}\n.property-group.is-expanded {\n border-color: var(--pd-border-soft, #e9ecf2);\n}\n.group-header {\n display: flex;\n align-items: center;\n padding: 9px 12px;\n cursor: pointer;\n user-select: none;\n background: var(--pd-field-bg, #f4f6fa);\n transition: background .14s ease;\n}\n.group-header:hover {\n background: var(--pd-sidebar-hover, #f0f3f9);\n}\n.property-group.is-expanded .group-header {\n border-bottom: 1px solid var(--pd-border-soft, #e9ecf2);\n}\n.group-icon {\n margin-right: 8px;\n color: var(--pd-accent, #165DFF);\n}\n.group-title {\n flex: 1;\n font-size: 12px;\n font-weight: 600;\n color: var(--pd-text, #2a2e37);\n letter-spacing: .3px;\n}\n.expand-icon {\n color: var(--pd-text-muted, #8b909c);\n font-size: 10px;\n}\n.group-content {\n padding: 10px 12px 12px;\n background: var(--pd-surface, #ffffff);\n}\n</style>","<template>\n <PropertyGroup title=\"位置与尺寸\" icon=\"Location\" default-expanded group-key=\"position-size\">\n <form class=\"pd-form\" @submit.prevent>\n <div class=\"position-grid\">\n <div class=\"pd-field\" v-show=\"showItem('ps-left')\"><span class=\"pd-label\">X</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.left\"\n :min=\"0\"\n :step=\"0.01\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ps-top')\"><span class=\"pd-label\">Y</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.top\"\n :min=\"0\"\n :step=\"0.01\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ps-width')\"><span class=\"pd-label\">W</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.width\"\n :min=\"3.5\"\n :step=\"0.01\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ps-height')\"><span class=\"pd-label\">H</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.height\"\n :min=\"3.5\"\n :step=\"0.01\" />\n </div>\n </div>\n </form>\n </PropertyGroup>\n</template>\n\n<script setup lang=\"ts\">\nimport type { RuntimeElement } from '../../types'\nimport PropertyGroup from './PropertyGroup.vue'\n\nconst props = defineProps<{\n element: RuntimeElement\n matchedKeys?: Set<string>\n searching?: boolean\n}>()\n\nfunction showItem(key: string): boolean {\n if (!props.searching) {\n return true\n }\n return props.matchedKeys?.has(key) ?? true\n}\n</script>\n\n<style scoped>\n.position-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px;\n}\n</style>\n","/** 打印设计器常见预设颜色(12 色) */\nexport const PRESET_COLORS = [\n '#000000',\n '#333333',\n '#666666',\n '#999999',\n '#cccccc',\n '#ffffff',\n '#e53935',\n '#fb8c00',\n '#1e88e5',\n '#43a047',\n '#8d6e63',\n '#00acc1',\n] as const\n","<template>\n <button\n ref=\"triggerRef\"\n type=\"button\"\n class=\"preset-color-trigger\"\n :aria-expanded=\"visible\"\n aria-haspopup=\"dialog\"\n :title=\"modelValue || '自动'\"\n @click=\"toggle\"\n >\n <span class=\"preset-color-swatch\" :style=\"{ background: normalizedValue }\"></span>\n </button>\n\n <Teleport to=\"body\">\n <div\n v-if=\"visible\"\n ref=\"panelRef\"\n class=\"preset-color-panel\"\n role=\"dialog\"\n aria-label=\"颜色选择\"\n :style=\"panelStyle\"\n @pointerdown.stop\n >\n <div class=\"picker-preview\">\n <span class=\"picker-current\" :style=\"{ background: activeColor }\"></span>\n <input\n v-model=\"hexInput\"\n class=\"picker-hex\"\n type=\"text\"\n maxlength=\"7\"\n spellcheck=\"false\"\n aria-label=\"颜色值\"\n @input=\"onHexInput\"\n />\n </div>\n\n <div\n ref=\"areaRef\"\n class=\"picker-area\"\n :style=\"{ '--picker-hue': `${Math.round(hue)}deg` }\"\n aria-label=\"自定义颜色\"\n tabindex=\"0\"\n @pointerdown=\"startAreaDrag\"\n @pointermove=\"moveAreaDrag\"\n @pointerup=\"endAreaDrag\"\n @pointercancel=\"endAreaDrag\"\n @keydown=\"onAreaKeydown\"\n >\n <span class=\"picker-handle\" :style=\"{ left: `${saturation * 100}%`, top: `${(1 - value) * 100}%`, background: activeColor }\"></span>\n </div>\n\n <input\n v-model.number=\"hueModel\"\n class=\"picker-hue\"\n type=\"range\"\n min=\"0\"\n max=\"360\"\n step=\"1\"\n aria-label=\"色相\"\n />\n\n <div class=\"picker-heading\">常用颜色</div>\n <div class=\"preset-color-grid\">\n <button\n v-for=\"color in PRESET_COLORS\"\n :key=\"color\"\n type=\"button\"\n class=\"preset-color-item\"\n :class=\"{ active: color.toLowerCase() === activeColor.toLowerCase() }\"\n :style=\"{ background: color }\"\n :title=\"color\"\n :aria-label=\"color\"\n @click=\"select(color)\"\n ></button>\n </div>\n </div>\n </Teleport>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { PRESET_COLORS } from '../utils/preset-colors'\n\nconst props = defineProps<{\n modelValue?: string\n}>()\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string]\n}>()\n\nconst visible = ref(false)\nconst triggerRef = ref<HTMLElement>()\nconst panelRef = ref<HTMLElement>()\nconst areaRef = ref<HTMLElement>()\nconst panelStyle = ref<Record<string, string>>({})\n\nconst hue = ref(0)\nconst saturation = ref(0)\nconst value = ref(0)\nconst hexInput = ref('#000000')\nconst areaDragging = ref(false)\n\nconst normalizedValue = computed({\n get: () => props.modelValue || '#000000',\n set: (color: string) => emit('update:modelValue', color),\n})\n\nconst activeColor = computed(() => {\n return rgbToHex(hsvToRgb(hue.value, saturation.value, value.value))\n})\n\nconst hueModel = computed({\n get: () => Math.round(hue.value),\n set: (degree: number) => setHsv(clampDegree(degree), saturation.value, value.value),\n})\n\nwatch(normalizedValue, syncFromColor, { immediate: true })\n\nfunction select(color: string) {\n hexInput.value = color.toUpperCase()\n syncFromColor(color)\n emit('update:modelValue', color)\n}\n\nfunction onHexInput(event: Event) {\n const input = event.target as HTMLInputElement\n const color = input.value.trim()\n if (!parseHex(color)) return\n syncFromColor(color)\n emit('update:modelValue', normalizeHex(color))\n}\n\nfunction syncFromColor(color: string) {\n const rgb = parseHex(color)\n if (!rgb) return\n const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b)\n hue.value = hsv.h\n saturation.value = hsv.s\n value.value = hsv.v\n hexInput.value = normalizeHex(color).toUpperCase()\n}\n\nfunction setHsv(h: number, s: number, v: number) {\n hue.value = clampDegree(h)\n saturation.value = clamp01(s)\n value.value = clamp01(v)\n hexInput.value = activeColor.value.toUpperCase()\n emit('update:modelValue', activeColor.value)\n}\n\nfunction startAreaDrag(event: PointerEvent) {\n const area = event.currentTarget as HTMLElement\n area.setPointerCapture(event.pointerId)\n areaDragging.value = true\n setAreaFromEvent(event)\n}\n\nfunction moveAreaDrag(event: PointerEvent) {\n if (!areaDragging.value) return\n setAreaFromEvent(event)\n}\n\nfunction endAreaDrag(event: PointerEvent) {\n areaDragging.value = false\n const area = event.currentTarget as HTMLElement\n if (area.hasPointerCapture(event.pointerId)) {\n area.releasePointerCapture(event.pointerId)\n }\n}\n\nfunction setAreaFromEvent(event: PointerEvent) {\n const area = areaRef.value\n if (!area) return\n const rect = area.getBoundingClientRect()\n const s = clamp01((event.clientX - rect.left) / rect.width)\n const v = clamp01(1 - (event.clientY - rect.top) / rect.height)\n setHsv(hue.value, s, v)\n}\n\nfunction onAreaKeydown(event: KeyboardEvent) {\n const step = event.shiftKey ? 0.1 : 0.02\n let handled = true\n if (event.key === 'ArrowLeft') setHsv(hue.value, saturation.value - step, value.value)\n else if (event.key === 'ArrowRight') setHsv(hue.value, saturation.value + step, value.value)\n else if (event.key === 'ArrowUp') setHsv(hue.value, saturation.value, value.value + step)\n else if (event.key === 'ArrowDown') setHsv(hue.value, saturation.value, value.value - step)\n else handled = false\n if (handled) event.preventDefault()\n}\n\nfunction toggle() {\n visible.value ? close() : open()\n}\n\nasync function open() {\n const trigger = triggerRef.value\n if (!trigger) return\n syncFromColor(normalizedValue.value)\n visible.value = true\n await nextTick()\n const rect = trigger.getBoundingClientRect()\n const panelWidth = 190\n const panelHeight = panelRef.value?.offsetHeight ?? 216\n const margin = 8\n const left = Math.min(rect.left, window.innerWidth - panelWidth - margin)\n const below = rect.bottom + 6\n const top = below + panelHeight > window.innerHeight - margin\n ? Math.max(margin, rect.top - panelHeight - 6)\n : below\n\n panelStyle.value = {\n left: `${Math.max(margin, left)}px`,\n top: `${top}px`,\n }\n}\n\nfunction close() {\n visible.value = false\n}\n\nfunction onDocumentPointerDown(event: PointerEvent) {\n const target = event.target as Node\n if (triggerRef.value?.contains(target) || panelRef.value?.contains(target)) return\n close()\n}\n\nfunction onWindowCloseEvents() {\n if (visible.value) close()\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape' && visible.value) close()\n}\n\nfunction parseHex(color: string): { r: number; g: number; b: number } | null {\n const match = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(color.trim())\n if (!match) return null\n const hex = match[1]!\n const full = hex.length === 3\n ? hex.split('').map(char => char + char).join('')\n : hex\n return {\n r: Number.parseInt(full.slice(0, 2), 16),\n g: Number.parseInt(full.slice(2, 4), 16),\n b: Number.parseInt(full.slice(4, 6), 16),\n }\n}\n\nfunction normalizeHex(color: string): string {\n const rgb = parseHex(color)\n return rgb ? rgbToHex(rgb) : '#000000'\n}\n\nfunction rgbToHex({ r, g, b }: { r: number; g: number; b: number }): string {\n return `#${[r, g, b].map(part => Math.round(clamp01(part / 255) * 255).toString(16).padStart(2, '0')).join('')}`\n}\n\nfunction rgbToHsv(r: number, g: number, b: number): { h: number; s: number; v: number } {\n const red = r / 255\n const green = g / 255\n const blue = b / 255\n const max = Math.max(red, green, blue)\n const min = Math.min(red, green, blue)\n const delta = max - min\n let h = 0\n if (delta !== 0) {\n if (max === red) h = ((green - blue) / delta) % 6\n else if (max === green) h = (blue - red) / delta + 2\n else h = (red - green) / delta + 4\n h *= 60\n if (h < 0) h += 360\n }\n return { h, s: max === 0 ? 0 : delta / max, v: max }\n}\n\nfunction hsvToRgb(h: number, s: number, v: number): { r: number; g: number; b: number } {\n const c = v * s\n const hh = (((h % 360) + 360) % 360) / 60\n const x = c * (1 - Math.abs((hh % 2) - 1))\n const [r1, g1, b1] = hh < 1 ? [c, x, 0]\n : hh < 2 ? [x, c, 0]\n : hh < 3 ? [0, c, x]\n : hh < 4 ? [0, x, c]\n : hh < 5 ? [x, 0, c]\n : [c, 0, x]\n const m = v - c\n return { r: (r1 + m) * 255, g: (g1 + m) * 255, b: (b1 + m) * 255 }\n}\n\nfunction clampDegree(degree: number): number {\n return (((Number.isFinite(degree) ? degree : 0) % 360) + 360) % 360\n}\n\nfunction clamp01(number: number): number {\n return Math.min(1, Math.max(0, Number.isFinite(number) ? number : 0))\n}\n\nonMounted(() => {\n document.addEventListener('pointerdown', onDocumentPointerDown, true)\n window.addEventListener('scroll', onWindowCloseEvents, true)\n window.addEventListener('resize', onWindowCloseEvents)\n document.addEventListener('keydown', onKeydown)\n})\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown, true)\n window.removeEventListener('scroll', onWindowCloseEvents, true)\n window.removeEventListener('resize', onWindowCloseEvents)\n document.removeEventListener('keydown', onKeydown)\n})\n</script>\n\n<style scoped>\n.preset-color-trigger {\n display: flex;\n align-items: center;\n width: 100%;\n min-height: 26px;\n padding: 1px;\n border: 1px solid var(--pd-border, #d9dde6);\n border-radius: 6px;\n background: #fff;\n cursor: pointer;\n transition: border-color .14s ease, box-shadow .14s ease;\n}\n\n.preset-color-trigger:hover,\n.preset-color-trigger[aria-expanded=\"true\"] {\n border-color: var(--pd-accent, #165DFF);\n}\n\n.preset-color-trigger:focus-visible {\n outline: none;\n border-color: var(--pd-accent, #165DFF);\n box-shadow: 0 0 0 2px rgb(22 93 255 / 12%);\n}\n\n.preset-color-swatch {\n width: 100%;\n height: 22px;\n border-radius: 4px;\n background-image: linear-gradient(45deg, #e9ecef 25%, transparent 25%, transparent 75%, #e9ecef 75%);\n background-size: 8px 8px;\n background-position: 0 0, 4px 4px;\n}\n\n.preset-color-panel {\n position: fixed;\n z-index: 3000;\n width: 190px;\n padding: 10px;\n border: 1px solid var(--pd-border, #d9dde6);\n border-radius: 8px;\n background: #fff;\n box-shadow: 0 8px 24px rgb(23 32 60 / 16%);\n}\n\n.picker-preview {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 8px;\n}\n\n.picker-current {\n flex: 0 0 26px;\n height: 24px;\n border: 1px solid rgb(0 0 0 / 12%);\n border-radius: 5px;\n}\n\n.picker-hex {\n flex: 1;\n min-width: 0;\n height: 24px;\n padding: 0 6px;\n border: 1px solid var(--pd-border, #d9dde6);\n border-radius: 5px;\n color: var(--pd-text, #303133);\n font: inherit;\n font-size: 11px;\n text-transform: uppercase;\n}\n\n.picker-hex:focus {\n outline: none;\n border-color: var(--pd-accent, #165DFF);\n box-shadow: 0 0 0 2px rgb(22 93 255 / 12%);\n}\n\n.picker-area {\n position: relative;\n height: 100px;\n border: 1px solid rgb(0 0 0 / 12%);\n border-radius: 6px;\n overflow: hidden;\n cursor: crosshair;\n touch-action: none;\n background:\n linear-gradient(to top, #000, transparent),\n linear-gradient(to right, #fff, hsl(var(--picker-hue) 100% 50%));\n}\n\n.picker-handle {\n position: absolute;\n width: 12px;\n height: 12px;\n border: 2px solid #fff;\n border-radius: 50%;\n transform: translate(-50%, -50%);\n box-shadow: 0 0 3px rgb(0 0 0 / 45%);\n pointer-events: none;\n}\n\n.picker-hue {\n width: 100%;\n height: 14px;\n margin: 10px 0 0;\n appearance: none;\n border: 1px solid rgb(0 0 0 / 12%);\n border-radius: 999px;\n background: linear-gradient(to right, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00);\n cursor: pointer;\n}\n\n.picker-hue::-webkit-slider-thumb {\n appearance: none;\n width: 12px;\n height: 12px;\n border: 2px solid #fff;\n border-radius: 50%;\n background: transparent;\n box-shadow: 0 0 3px rgb(0 0 0 / 45%);\n}\n\n.picker-hue::-moz-range-thumb {\n width: 8px;\n height: 8px;\n border: 2px solid #fff;\n border-radius: 50%;\n background: transparent;\n box-shadow: 0 0 3px rgb(0 0 0 / 45%);\n}\n\n.picker-heading {\n margin-top: 10px;\n margin-bottom: 6px;\n font-size: 11px;\n color: var(--pd-text-muted, #909399);\n}\n\n.preset-color-grid {\n display: grid;\n grid-template-columns: repeat(6, 1fr);\n gap: 5px;\n}\n\n.preset-color-item {\n width: 22px;\n height: 22px;\n padding: 0;\n border: 1px solid rgb(0 0 0 / 12%);\n border-radius: 5px;\n cursor: pointer;\n}\n\n.preset-color-item.active {\n box-shadow: 0 0 0 2px #fff, 0 0 0 3px var(--pd-accent, #165DFF);\n}\n</style>\n","<template>\n <PropertyGroup title=\"外观\" icon=\"Brush\" default-expanded group-key=\"appearance\">\n <form class=\"pd-form\" @submit.prevent>\n <template v-if=\"isTextType\">\n <div class=\"pd-field\" v-show=\"showItem('ap-font-size')\"><span class=\"pd-label\">字体大小</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.fontSize\"\n :min=\"8\"\n :max=\"72\"\n style=\"width: 100%\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ap-font-weight')\"><span class=\"pd-label\">字体粗细</span>\n <select class=\"pd-select\" v-model=\"element.options.fontWeight\" style=\"width: 100%\">\n <option value=\"normal\">正常</option>\n <option value=\"bold\">粗体</option>\n <option value=\"bolder\">更粗</option>\n <option value=\"lighter\">细体</option>\n </select>\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ap-align')\"><span class=\"pd-label\">对齐</span>\n <div class=\"pd-radio-group\" role=\"radiogroup\">\n <label class=\"pd-radio\"><input type=\"radio\" v-model=\"element.options.textAlign\" value=\"left\"><span>左</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" v-model=\"element.options.textAlign\" value=\"center\"><span>中</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" v-model=\"element.options.textAlign\" value=\"right\"><span>右</span></label>\n </div>\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ap-vertical-align')\"><span class=\"pd-label\">垂直对齐</span>\n <div class=\"pd-radio-group\" role=\"radiogroup\">\n <label class=\"pd-radio\"><input type=\"radio\" v-model=\"element.options.verticalAlign\" value=\"top\"><span>顶</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" v-model=\"element.options.verticalAlign\" value=\"middle\"><span>中</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" v-model=\"element.options.verticalAlign\" value=\"bottom\"><span>底</span></label>\n </div>\n </div>\n <div class=\"color-row\">\n <div class=\"pd-field\" v-show=\"showItem('ap-color')\"><span class=\"pd-label\">颜色</span>\n <PresetColorPicker v-model=\"element.options.color\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ap-bg-color')\"><span class=\"pd-label\">背景色</span>\n <PresetColorPicker v-model=\"element.options.backgroundColor\" />\n </div>\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ap-line-height')\"><span class=\"pd-label\">行高</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.lineHeight\"\n :min=\"0\"\n :max=\"100\"\n style=\"width: 100%\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ap-letter-spacing')\"><span class=\"pd-label\">字间距</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.letterSpacing\"\n :min=\"0\"\n :max=\"20\"\n :step=\"0.5\"\n style=\"width: 100%\" />\n </div>\n </template>\n\n <p class=\"pd-empty\" v-if=\"!isTextType && !isTableType\">当前元素不支持外观设置</p>\n </form>\n </PropertyGroup>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { RuntimeElement } from '../../types'\nimport PresetColorPicker from '../PresetColorPicker.vue'\nimport PropertyGroup from './PropertyGroup.vue'\n\nconst props = defineProps<{\n element: RuntimeElement\n isTextType: boolean\n matchedKeys?: Set<string>\n searching?: boolean\n}>()\n\nfunction showItem(key: string): boolean {\n if (!props.searching) {\n return true\n }\n return props.matchedKeys?.has(key) ?? true\n}\n\nconst isTableType = computed(() => {\n return props.element.printElementType.type === 'table'\n})\n</script>\n\n<style scoped>\n.color-row {\n display: flex;\n gap: 16px;\n}</style>","<template>\n <div v-if=\"visible\" class=\"pd-dialog-overlay\" @keydown.esc=\"visible = false\">\n <section class=\"pd-dialog pd-dialog-large\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"expression-editor-title\">\n <header class=\"pd-dialog-header\">\n <strong id=\"expression-editor-title\">编辑表达式</strong>\n <button type=\"button\" class=\"pd-close\" aria-label=\"关闭\" @click=\"visible = false\">×</button>\n </header>\n <div class=\"expression-editor\">\n <!-- 左侧导航栏 -->\n <div class=\"ee-nav\">\n <div class=\"ee-nav-title\">类型</div>\n <div class=\"ee-nav-tabs\">\n <div\n class=\"ee-nav-tab\"\n :class=\"{ active: activeTab === 'field' }\"\n @click=\"activeTab = 'field'\"\n >\n 📁 字段\n </div>\n <div\n class=\"ee-nav-tab\"\n :class=\"{ active: activeTab === 'variable' }\"\n @click=\"activeTab = 'variable'\"\n >\n 🔧 变量\n </div>\n <div\n class=\"ee-nav-tab\"\n :class=\"{ active: activeTab === 'function' }\"\n @click=\"activeTab = 'function'\"\n >\n ⚡ 函数\n </div>\n </div>\n </div>\n\n <!-- 中间内容区 -->\n <div class=\"ee-content\">\n <div class=\"ee-content-search\">\n <input class=\"pd-input\" v-model=\"searchText\"\n :placeholder=\"searchPlaceholder\" />\n </div>\n <div class=\"ee-content-list\">\n <!-- 字段列表(按 fieldKey 首段分组:supplier.*/receiver.*/goods.* 等) -->\n <template v-if=\"activeTab === 'field'\">\n <template v-for=\"group in filteredGroups\" :key=\"group.key || '_top'\">\n <div v-if=\"group.key\" class=\"ee-field-group\" :class=\"{ 'is-list': group.isList }\">\n <span class=\"ee-field-group-icon\">{{ group.isList ? '📋' : '📁' }}</span>\n <span>{{ group.label }}</span>\n </div>\n <div\n v-for=\"field in group.fields\"\n :key=\"field.fieldKey\"\n class=\"ee-list-item ee-field-item\"\n :style=\"{ paddingLeft: group.key ? '22px' : '10px' }\"\n @dblclick=\"handleFieldDoubleClick(field)\"\n >\n <label class=\"ee-field-row\">\n <input\n type=\"checkbox\"\n class=\"pd-checkbox\"\n :checked=\"selectedFields.has(field.fieldKey)\"\n @change=\"toggleField(field)\"\n @click.stop\n />\n <span class=\"ee-item-label\">{{ field.fieldLabel }}</span>\n <span class=\"ee-item-key\">{{ field.fieldKey }}</span>\n </label>\n </div>\n </template>\n <p v-if=\"filteredGroups.length === 0\" class=\"pd-empty\">暂无字段</p>\n </template>\n\n <!-- 变量列表 -->\n <template v-if=\"activeTab === 'variable'\">\n <div\n v-for=\"sv in filteredSystemVars\"\n :key=\"sv.name\"\n class=\"ee-list-item\"\n @dblclick=\"handleItemDoubleClick(sv.template)\"\n >\n <div class=\"ee-item-label\">{{ sv.label }}</div>\n <div class=\"ee-item-key\">{{ sv.name }}</div>\n </div>\n </template>\n\n <!-- 函数列表 -->\n <template v-if=\"activeTab === 'function'\">\n <div class=\"ee-func-group\">\n <div class=\"ee-func-group-title\">聚合函数</div>\n <div\n v-for=\"fn in filteredAggregateFuncs\"\n :key=\"fn.name\"\n class=\"ee-list-item\"\n @dblclick=\"handleAggregateDoubleClick(fn)\"\n >\n <div class=\"ee-item-label\">{{ fn.label }}</div>\n <div class=\"ee-item-key\">{{ fn.name }}</div>\n </div>\n </div>\n <div class=\"ee-func-group\">\n <div class=\"ee-func-group-title\">格式化函数</div>\n <div\n v-for=\"fn in filteredFormatFuncs\"\n :key=\"fn.name\"\n class=\"ee-list-item\"\n @dblclick=\"handleItemDoubleClick(fn.template)\"\n >\n <div class=\"ee-item-label\">{{ fn.label }}</div>\n <div class=\"ee-item-key\">{{ fn.name }}</div>\n </div>\n </div>\n </template>\n </div>\n </div>\n\n <!-- 右侧编辑区 -->\n <div class=\"ee-editor\">\n <div class=\"ee-editor-section\">\n <div class=\"ee-editor-title\">表达式编辑</div>\n <textarea\n ref=\"textareaRef\"\n v-model=\"localExpression\"\n class=\"ee-textarea\"\n rows=\"6\"\n placeholder=\"双击左侧字段/函数插入表达式,如: {fieldKey} 或 SUM(amount)\"\n />\n </div>\n\n <div class=\"ee-editor-section\">\n <div class=\"ee-editor-title\">预览结果</div>\n <div class=\"ee-preview\" :class=\"{ 'ee-preview-error': previewResult === '(表达式错误)' }\">{{ previewResult }}</div>\n </div>\n\n <div class=\"ee-help-section\">\n <div class=\"ee-help-title\">帮助信息</div>\n <div class=\"ee-help-grid\">\n <div class=\"ee-help-card ee-help-field\">\n <div class=\"ee-help-card-title\">字段绑定</div>\n <div class=\"ee-help-card-content\">\n 使用 {字段名} 格式<br>\n 示例: {order.no}\n </div>\n </div>\n <div class=\"ee-help-card ee-help-function\">\n <div class=\"ee-help-card-title\">函数使用</div>\n <div class=\"ee-help-card-content\">\n SUM(字段) - 求和<br>\n AVG(字段) - 平均值<br>\n COUNT(字段) - 计数\n </div>\n </div>\n <div class=\"ee-help-card ee-help-variable\">\n <div class=\"ee-help-card-title\">系统变量</div>\n <div class=\"ee-help-card-content\">\n {page} - 当前页码<br>\n {total} - 总页数<br>\n {row} - 当前行号\n </div>\n </div>\n <div class=\"ee-help-card ee-help-conditional\">\n <div class=\"ee-help-card-title\">条件判断</div>\n <div class=\"ee-help-card-content\">\n IF(条件, 真值, 假值)<br>\n 示例: IF(amount>1000, \"大单\", \"小单\")\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <footer class=\"pd-dialog-footer\">\n <button type=\"button\" class=\"pd-button\" @click=\"visible = false\">取消</button>\n <button type=\"button\" class=\"pd-button primary\" @click=\"onConfirm\">确定</button>\n </footer>\n </section>\n</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, nextTick } from 'vue'\nimport type { PrintBusinessField } from '../types'\nimport { evaluateTemplate } from '../utils/expression-eval'\nimport { DEFAULT_DEMO_DATA } from '../utils/demo-data'\nimport { groupFields, filterGroups } from '../utils/field-groups'\n\nconst props = defineProps<{\n modelValue: boolean\n expression: string\n /** 宿主传入的业务字段(字段页数据源) */\n fields?: PrintBusinessField[]\n}>()\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: boolean]\n 'update:expression': [value: string]\n}>()\n\nconst visible = computed({\n get: () => props.modelValue,\n set: (val) => emit('update:modelValue', val),\n})\n\n// 新增状态\nconst activeTab = ref<'field' | 'variable' | 'function'>('field')\n\n// 搜索占位符\nconst searchPlaceholder = computed(() => {\n switch (activeTab.value) {\n case 'field': return '搜索字段...'\n case 'variable': return '搜索变量...'\n case 'function': return '搜索函数...'\n default: return '搜索...'\n }\n})\n\n// 字段列表(宿主注入的扁平业务字段,按 fieldKey 首段分组展示)\nconst searchText = ref('')\nconst filteredGroups = computed(() =>\n filterGroups(groupFields(props.fields ?? []), searchText.value),\n)\n\n// 字段多选模式\nconst selectedFields = ref<Set<string>>(new Set())\n\nfunction toggleField(field: PrintBusinessField) {\n const key = field.fieldKey\n const next = new Set(selectedFields.value)\n if (next.has(key)) {\n next.delete(key)\n } else {\n next.add(key)\n }\n selectedFields.value = next\n}\n\n// 当弹出框打开时,根据当前 expression 值尝试匹配已选字段\nwatch(visible, (val) => {\n if (val) {\n // 每次打开时重置为外部传入值,避免携带上次编辑残留\n localExpression.value = props.expression || ''\n const found = (props.fields ?? []).find(\n f => props.expression === f.fieldKey || props.expression === `{${f.fieldKey}}`,\n )\n if (found) {\n selectedFields.value = new Set([found.fieldKey])\n }\n } else {\n selectedFields.value = new Set()\n }\n})\n\n// 字段双击处理\nfunction handleFieldDoubleClick(field: PrintBusinessField) {\n insertAtCursor(`{${field.fieldKey}}`)\n}\n\n// 聚合函数双击 — 自动填充选中字段\nfunction handleAggregateDoubleClick(fn: { name: string; template: string }) {\n if (selectedFields.value.size > 0) {\n const fields = Array.from(selectedFields.value).join(', ')\n insertAtCursor(`${fn.name}(${fields})`)\n } else {\n insertAtCursor(fn.template)\n }\n}\n\n// 通用双击处理(变量和格式化函数)\nfunction handleItemDoubleClick(text: string) {\n insertAtCursor(text)\n}\n\n// 过滤后的系统变量\nconst filteredSystemVars = computed(() => {\n if (!searchText.value.trim()) return systemVars\n const keyword = searchText.value.trim().toLowerCase()\n return systemVars.filter(sv =>\n sv.label.toLowerCase().includes(keyword) ||\n sv.name.toLowerCase().includes(keyword)\n )\n})\n\n// 过滤后的聚合函数\nconst filteredAggregateFuncs = computed(() => {\n if (!searchText.value.trim()) return aggregateFunctions\n const keyword = searchText.value.trim().toLowerCase()\n return aggregateFunctions.filter(fn =>\n fn.label.toLowerCase().includes(keyword) || fn.name.toLowerCase().includes(keyword)\n )\n})\n\n// 过滤后的格式化函数\nconst filteredFormatFuncs = computed(() => {\n if (!searchText.value.trim()) return formatFunctions\n const keyword = searchText.value.trim().toLowerCase()\n return formatFunctions.filter(fn =>\n fn.label.toLowerCase().includes(keyword) || fn.name.toLowerCase().includes(keyword)\n )\n})\n\n// 表达式编辑模式\nconst localExpression = ref(props.expression || '')\nconst textareaRef = ref<HTMLTextAreaElement | null>(null)\n\nwatch(() => props.expression, (val) => {\n localExpression.value = val || ''\n})\n\nconst aggregateFunctions = [\n { name: 'SUM', label: '求和', template: 'SUM()' },\n { name: 'AVG', label: '平均值', template: 'AVG()' },\n { name: 'COUNT', label: '计数', template: 'COUNT()' },\n { name: 'MIN', label: '最小值', template: 'MIN()' },\n { name: 'MAX', label: '最大值', template: 'MAX()' },\n]\n\nconst formatFunctions = [\n { name: 'MONEY', label: '金额格式化', template: 'MONEY()' },\n { name: 'DATE', label: '日期格式化', template: 'DATE()' },\n { name: 'UPPER', label: '大写金额', template: 'UPPER()' },\n { name: 'IF', label: '条件判断', template: 'IF()' },\n]\n\nconst systemVars = [\n { name: 'pageIndex', label: '当前页码', template: '{pageIndex}' },\n { name: 'totalPages', label: '总页数', template: '{totalPages}' },\n { name: 'printDate', label: '打印日期', template: '{printDate}' },\n { name: 'printTime', label: '打印时间', template: '{printTime}' },\n]\n\nconst previewResult = computed(() => {\n if (!localExpression.value.trim()) return '(输入表达式后预览)'\n try {\n const ctx = {\n ...DEFAULT_DEMO_DATA,\n // 系统变量示例值,与渲染端一致(print-render 在生成 HTML 时替换)\n pageIndex: 1,\n totalPages: 1,\n printDate: new Date().toISOString().split('T')[0],\n printTime: Date.now(),\n }\n const result = evaluateTemplate(localExpression.value, ctx)\n if (result === undefined || result === null) return '(无法计算)'\n return String(result)\n } catch (e) {\n return '(表达式错误)'\n }\n})\n\nfunction insertAtCursor(text: string) {\n const ta = textareaRef.value\n if (!ta) {\n localExpression.value += text\n return\n }\n const start = ta.selectionStart\n const end = ta.selectionEnd\n const before = localExpression.value.substring(0, start)\n const after = localExpression.value.substring(end)\n localExpression.value = before + text + after\n nextTick(() => {\n ta.focus()\n ta.selectionStart = ta.selectionEnd = start + text.length\n })\n}\n\nfunction onConfirm() {\n emit('update:expression', localExpression.value)\n visible.value = false\n}\n</script>\n\n<style scoped>\n/* 主容器 */\n.expression-editor {\n display: flex;\n height: 450px;\n gap: 0;\n}\n\n/* 左侧导航 */\n.ee-nav {\n width: 100px;\n background: var(--pd-sidebar);\n border-right: 1px solid var(--pd-border);\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n}\n\n.ee-nav-title {\n padding: 10px;\n border-bottom: 1px solid var(--pd-border);\n font-weight: 600;\n font-size: 13px;\n color: var(--pd-text);\n text-align: center;\n}\n\n.ee-nav-tabs {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: 6px;\n gap: 4px;\n}\n\n.ee-nav-tab {\n padding: 8px 10px;\n border-radius: 6px;\n cursor: pointer;\n font-size: 12px;\n text-align: center;\n transition: all 0.2s;\n}\n\n.ee-nav-tab.active {\n background: var(--pd-accent);\n color: white;\n}\n\n.ee-nav-tab:not(.active) {\n background: white;\n border: 1px solid var(--pd-border);\n color: var(--pd-text);\n}\n\n.ee-nav-tab:hover:not(.active) {\n background: #ecf5ff;\n border-color: var(--pd-accent);\n}\n\n/* 中间内容区 */\n.ee-content {\n width: 300px;\n display: flex;\n flex-direction: column;\n border-right: 1px solid var(--pd-border);\n flex-shrink: 0;\n}\n\n.ee-content-search {\n padding: 10px;\n border-bottom: 1px solid var(--pd-border);\n}\n\n.ee-content-list {\n flex: 1;\n padding: 8px;\n overflow-y: auto;\n min-height: 0;\n}\n\n/* 函数分组 */\n.ee-func-group {\n margin-bottom: 12px;\n}\n\n.ee-func-group-title {\n font-size: 11px;\n font-weight: 600;\n color: var(--pd-text-muted);\n padding: 4px 10px 6px;\n border-bottom: 1px solid var(--pd-border);\n margin-bottom: 4px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* 字段分组标题 */\n.ee-field-group {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 6px 10px;\n font-size: 12px;\n font-weight: 600;\n color: var(--pd-text);\n}\n.ee-field-group.is-list {\n color: var(--pd-accent, #165DFF);\n}\n.ee-field-group-icon {\n font-size: 13px;\n filter: saturate(.6);\n}\n/* 列表项 */\n.ee-list-item {\n padding: 8px 10px;\n cursor: pointer;\n border-radius: 4px;\n margin-bottom: 4px;\n transition: all 0.2s;\n}\n.ee-field-row {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n.ee-field-row .ee-item-label {\n flex: 1;\n}\n\n.ee-list-item:hover {\n background: #ecf5ff;\n border-color: var(--pd-accent);\n}\n\n.ee-list-item .ee-item-label {\n font-size: 12px;\n color: var(--pd-text);\n}\n\n.ee-list-item .ee-item-key {\n font-size: 10px;\n color: var(--pd-text-muted);\n font-family: monospace;\n margin-top: 2px;\n}\n\n/* 右侧编辑区 */\n.ee-editor {\n flex: 1;\n display: flex;\n flex-direction: column;\n background: var(--pd-sidebar);\n min-width: 0;\n}\n\n.ee-editor-section {\n padding: 12px;\n border-bottom: 1px solid var(--pd-border);\n}\n\n.ee-editor-title {\n font-size: 11px;\n color: var(--pd-text-muted);\n margin-bottom: 6px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* 表达式编辑框 */\n.ee-textarea {\n width: 100%;\n border: 1px solid var(--pd-border);\n border-radius: 6px;\n padding: 10px;\n font-family: monospace;\n font-size: 13px;\n resize: vertical;\n box-sizing: border-box;\n min-height: 100px;\n}\n\n.ee-textarea:focus {\n outline: none;\n border-color: var(--pd-accent);\n}\n\n/* 预览结果 */\n.ee-preview {\n padding: 10px;\n background: var(--pd-bg);\n border: 1px solid var(--pd-border);\n border-radius: 6px;\n min-height: 30px;\n font-size: 13px;\n color: var(--pd-text);\n line-height: 1.6;\n}\n\n.ee-preview-error {\n color: #e53e3e;\n background: #fef2f2;\n border-color: #fecaca;\n}\n\n/* 帮助信息 */\n.ee-help-section {\n flex: 1;\n padding: 12px;\n overflow-y: auto;\n min-height: 0;\n}\n\n.ee-help-title {\n font-size: 11px;\n color: var(--pd-text-muted);\n margin-bottom: 8px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.ee-help-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px;\n}\n\n.ee-help-card {\n border-radius: 6px;\n padding: 10px;\n}\n\n.ee-help-card-title {\n font-size: 12px;\n font-weight: 600;\n margin-bottom: 4px;\n}\n\n.ee-help-card-content {\n font-size: 11px;\n line-height: 1.5;\n color: var(--pd-text);\n}\n\n.ee-help-field {\n background: #f0f9ff;\n border: 1px solid #bae6fd;\n}\n\n.ee-help-field .ee-help-card-title {\n color: #0369a1;\n}\n\n.ee-help-function {\n background: #f0fdf4;\n border: 1px solid #bbf7d0;\n}\n\n.ee-help-function .ee-help-card-title {\n color: #166534;\n}\n\n.ee-help-variable {\n background: #fefce8;\n border: 1px solid #fde68a;\n}\n\n.ee-help-variable .ee-help-card-title {\n color: #854d0e;\n}\n\n.ee-help-conditional {\n background: #fdf2f8;\n border: 1px solid #fbcfe8;\n}\n\n.ee-help-conditional .ee-help-card-title {\n color: #9d174d;\n}\n\n/* 弹窗内容区域 */\n.expression-editor {\n max-height: min(600px, 80vh);\n overflow-y: auto;\n padding: 16px;\n}\n</style>\n","<template>\n <div class=\"pd-field\"><span class=\"pd-label\">{{ descriptor.label }}</span>\n <input :value=\"modelValue\" class=\"pd-input\"\n :placeholder=\"descriptor.placeholder || '输入内容,支持 {字段} 表达式'\"\n @input=\"emit('update:modelValue', ($event.target as HTMLInputElement).value)\"\n @dblclick=\"openEditor\" />\n </div>\n <ExpressionEditor\n v-model=\"editorVisible\"\n :fields=\"fields\"\n :expression=\"modelValue\"\n @update:expression=\"(v: string) => emit('update:modelValue', v)\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport type { BindingDescriptor, PrintBusinessField } from '../../types'\nimport ExpressionEditor from '../ExpressionEditor.vue'\n\nconst props = defineProps<{\n descriptor: BindingDescriptor\n modelValue: string\n fields?: PrintBusinessField[]\n}>()\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n}>()\n\nconst editorVisible = ref(false)\n\nfunction openEditor() {\n editorVisible.value = true\n}\n</script>\n\n<style scoped>\n.binding-control {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n</style>","<template>\n <PropertyGroup title=\"表格设置\" icon=\"Grid\" default-expanded group-key=\"table-settings\">\n <form class=\"pd-form\" @submit.prevent>\n <div class=\"pd-field\"><span class=\"pd-label\">列表数据源字段</span>\n <select :value=\"element.options.dataSource\" class=\"pd-select\"\n style=\"width: 100%\" @change=\"onSourceChange(($event.target as HTMLSelectElement).value)\">\n <option v-for=\"f in listFieldOptions\" :key=\"f.value\" :value=\"f.value\">{{ f.label }}</option>\n </select>\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">默认字号 (pt)</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.tableDefaultFontSize\" :min=\"5\" :max=\"72\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">默认文字颜色</span>\n <PresetColorPicker v-model=\"element.options.tableDefaultColor\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">默认内边距 (mm)</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.tableDefaultPadding\" :min=\"0\" :max=\"10\" :step=\"0.5\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">列宽 (mm)</span>\n <div v-for=\"(w, i) in element.options.tableColWidths\" :key=\"i\" class=\"col-width-row\">\n <span style=\"width: 60px\">列{{ i + 1 }}</span>\n <input :value=\"w\" type=\"number\" class=\"pd-input\" :min=\"5\" :max=\"200\" :step=\"1\" @input=\"onColWidthChange(i, ($event.target as HTMLInputElement).valueAsNumber)\" />\n </div>\n </div>\n </form>\n </PropertyGroup>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, inject } from 'vue'\nimport PresetColorPicker from '../PresetColorPicker.vue'\nimport type { RuntimeElement, PrintBusinessField } from '../../types'\nimport { TABLE_EDIT_KEY } from '../../composables/useTableSelection'\nimport { syncTableElementSize } from '../../utils/table-matrix'\nimport PropertyGroup from './PropertyGroup.vue'\n\nconst props = defineProps<{\n element: RuntimeElement\n fields: PrintBusinessField[]\n}>()\n\nconst tableEditCtx = inject(TABLE_EDIT_KEY, null)\n\n/** 列表数据源选项:宿主以 fieldType='list' 声明明细列表字段 */\nconst listFieldOptions = computed(() => {\n return props.fields\n .filter(f => f.fieldType === 'list')\n .map(f => ({ label: f.fieldLabel, value: f.fieldKey }))\n})\n\nfunction onSourceChange(v: string) {\n props.element.options.dataSource = v || undefined\n tableEditCtx?.recordHistory()\n}\n\nfunction onColWidthChange(i: number, v: number | undefined) {\n if (v === undefined) return\n const widths = props.element.options.tableColWidths!\n const maxW = tableEditCtx?.maxTableWidth.value ?? Infinity\n const othersW = widths.reduce((s, w, idx) => idx === i ? s : s + w, 0)\n if (othersW + v > maxW) {\n const clamped = Math.max(5, Math.round((maxW - othersW) * 10) / 10)\n alert(`表格总宽不能超过打印范围宽度 ${maxW}mm,列${i + 1} 已调整为 ${clamped}mm`)\n widths[i] = clamped\n } else {\n widths[i] = v\n }\n syncTableElementSize(props.element.options)\n tableEditCtx?.recordHistory()\n}\n</script>\n\n<style scoped>\n.col-width-row {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 4px;\n width: 100%;\n}\n</style>","<template>\n <PropertyGroup title=\"边框与背景\" icon=\"Picture\" default-expanded group-key=\"border-bg\">\n <form class=\"pd-form\" @submit.prevent>\n <div class=\"border-row\">\n <div class=\"pd-field\" v-show=\"showItem('bb-border-width')\"><span class=\"pd-label\">边框宽度</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.borderWidth\"\n :min=\"0\"\n :max=\"20\"\n :step=\"0.25\"\n />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('bb-border-color')\"><span class=\"pd-label\">边框颜色</span>\n <PresetColorPicker v-model=\"element.options.borderColor\" />\n </div>\n </div>\n <div class=\"pd-field\" v-show=\"showItem('bb-bg-color')\"><span class=\"pd-label\">背景色</span>\n <PresetColorPicker v-model=\"element.options.backgroundColor\" />\n </div>\n </form>\n </PropertyGroup>\n</template>\n\n<script setup lang=\"ts\">\nimport type { RuntimeElement } from '../../types'\nimport PresetColorPicker from '../PresetColorPicker.vue'\nimport PropertyGroup from './PropertyGroup.vue'\n\nconst props = defineProps<{\n element: RuntimeElement\n matchedKeys?: Set<string>\n searching?: boolean\n}>()\n\nfunction showItem(key: string): boolean {\n if (!props.searching) {\n return true\n }\n return props.matchedKeys?.has(key) ?? true\n}\n</script>\n\n<style scoped>\n.border-row {\n display: flex;\n gap: 16px;\n}</style>","<template>\n <PropertyGroup title=\"高级设置\" icon=\"Setting\" group-key=\"advanced\">\n <form class=\"pd-form\" @submit.prevent>\n <div class=\"advanced-row\">\n <div class=\"pd-field\" v-show=\"showItem('ad-locked')\"><span class=\"pd-label\">锁定</span>\n <input type=\"checkbox\" class=\"pd-switch\" v-model=\"element.options.locked\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ad-fixed')\"><span class=\"pd-label\">每页重复</span>\n <input type=\"checkbox\" class=\"pd-switch\" v-model=\"element.options.fixed\" />\n </div>\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ad-z-index')\"><span class=\"pd-label\">层级</span>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"element.options.zIndex\"\n :min=\"0\"\n :max=\"999\"\n style=\"width: 100%\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('ad-delete')\">\n <button type=\"button\" class=\"pd-button danger\" @click=\"$emit('delete-element')\">\n 删除元素\n </button>\n </div>\n </form>\n </PropertyGroup>\n</template>\n\n<script setup lang=\"ts\">\nimport type { RuntimeElement } from '../../types'\nimport PropertyGroup from './PropertyGroup.vue'\n\nconst props = defineProps<{\n element: RuntimeElement\n matchedKeys?: Set<string>\n searching?: boolean\n}>()\n\nfunction showItem(key: string): boolean {\n if (!props.searching) {\n return true\n }\n return props.matchedKeys?.has(key) ?? true\n}\n\ndefineEmits<{\n 'delete-element': []\n}>()\n</script>\n\n<style scoped>\n.advanced-row {\n display: flex;\n gap: 16px;\n}\n</style>\n","<template>\n <PropertyGroup title=\"分页配置\" icon=\"Document\" group-key=\"pagination\">\n <form class=\"pd-form\" @submit.prevent>\n <!-- 表格元素分页配置 -->\n <template v-if=\"isTable\">\n <div class=\"pd-field\" v-show=\"showItem('pg-enabled')\"><span class=\"pd-label\">启用分页</span>\n <input type=\"checkbox\" class=\"pd-switch\" :checked=\"tablePaginationEnabled\" @change=\"onTablePaginationChange(($event.target as HTMLInputElement).checked)\" />\n </div>\n </template>\n <!-- 非表格元素分页配置 -->\n <template v-else>\n <div class=\"pd-field\" v-show=\"showItem('pg-pageable')\"><span class=\"pd-label\">参与分页</span>\n <input type=\"checkbox\" class=\"pd-switch\" :checked=\"paginationPageable\" @change=\"onPageableChange(($event.target as HTMLInputElement).checked)\" />\n </div>\n <div class=\"pd-field\" v-show=\"showItem('pg-keep-with-next')\"><span class=\"pd-label\">与下元素同页</span>\n <input type=\"checkbox\" class=\"pd-switch\" :checked=\"paginationKeepWithNext\" @change=\"onKeepWithNextChange(($event.target as HTMLInputElement).checked)\" />\n </div>\n </template>\n </form>\n </PropertyGroup>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { RuntimeElement } from '../../types'\nimport PropertyGroup from './PropertyGroup.vue'\n\nconst props = defineProps<{\n element: RuntimeElement\n matchedKeys?: Set<string>\n searching?: boolean\n}>()\n\nconst isTable = computed(() => props.element.printElementType.type === 'table')\n\n// 表格分页\nconst tablePaginationEnabled = computed({\n get: () => props.element.options.tablePagination?.enabled ?? true,\n set: () => { /* 由 change 处理 */ },\n})\n\nfunction onTablePaginationChange(checked: boolean) {\n props.element.options.tablePagination = {\n enabled: checked,\n }\n}\n\n// 非表格分页\nconst paginationPageable = computed({\n get: () => props.element.options.pagination?.pageable ?? true,\n set: () => { /* 由 change 处理 */ },\n})\n\nconst paginationKeepWithNext = computed({\n get: () => props.element.options.pagination?.keepWithNext ?? false,\n set: () => { /* 由 change 处理 */ },\n})\n\nfunction onPageableChange(checked: boolean) {\n props.element.options.pagination = {\n pageable: checked,\n keepWithNext: paginationKeepWithNext.value,\n }\n}\n\nfunction onKeepWithNextChange(checked: boolean) {\n props.element.options.pagination = {\n pageable: paginationPageable.value,\n keepWithNext: checked,\n }\n}\n\nfunction showItem(key: string): boolean {\n if (!props.searching) return true\n return props.matchedKeys?.has(key) ?? true\n}\n</script>\n","<template>\n <div class=\"image-content-upload\">\n <label class=\"pd-button small upload-label\" :class=\"{ disabled: uploadDisabled }\">\n <svg class=\"pd-icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M12 3l4 4h-3v7h-2V7H8zm-7 12h14v5H5Z\" /></svg>\n {{ uploading ? '上传中...' : '上传图片' }}\n <input\n class=\"visually-hidden\"\n type=\"file\"\n accept=\"image/*\"\n :disabled=\"uploadDisabled\"\n @change=\"handleFileChange\"\n >\n </label>\n <p class=\"upload-tip\">支持 jpg/png/gif/bmp/webp/svg 等图片,上传后填入相对路径</p>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, inject, computed } from 'vue'\nimport { UPLOAD_IMAGE_KEY } from '../../composables/useHostAdapter'\n\nconst props = defineProps<{ disabled?: boolean }>()\n\nconst emit = defineEmits<{ success: [url: string] }>()\n\nconst uploading = ref(false)\n// 宿主注入的图片上传适配器;未注入时上传不可用\nconst uploadImage = inject(UPLOAD_IMAGE_KEY, computed(() => undefined))\nconst uploadDisabled = computed(() => props.disabled || uploading.value || !uploadImage.value)\n\nasync function handleFileChange(event: Event) {\n const input = event.target as HTMLInputElement\n const file = input.files?.[0]\n if (!file) return\n if (!file.type.startsWith('image/')) {\n alert('仅支持上传图片文件')\n input.value = ''\n return\n }\n if (!uploadImage.value) {\n alert('图片上传能力未配置')\n input.value = ''\n return\n }\n uploading.value = true\n try {\n const url = await uploadImage.value(file)\n if (url) {\n emit('success', url)\n } else {\n alert('图片上传失败')\n }\n } catch (err) {\n alert(err instanceof Error ? err.message : '图片上传失败')\n } finally {\n uploading.value = false\n input.value = ''\n }\n}\n</script>\n\n<style scoped>\n.image-content-upload {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 4px;\n margin-top: 4px;\n}\n.upload-label {\n cursor: pointer;\n}\n.upload-label.disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n.upload-tip {\n margin: 0;\n font-size: 11px;\n color: var(--pd-text-muted, #909399);\n}\n.visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n}\n</style>\n","<!-- 表格行属性分组:行类型/行高/每页重复(小计行按页重复) -->\n<template>\n <PropertyGroup title=\"行属性\" icon=\"Grid\" default-expanded group-key=\"table-row\">\n <form class=\"pd-form\" @submit.prevent>\n <div class=\"pd-field\"><span class=\"pd-label\">行类型</span>\n <select :value=\"row.type\" class=\"pd-select\" style=\"width: 100%\" @change=\"onTypeChange(($event.target as HTMLSelectElement).value as TableRowType)\">\n <option value=\"header\">标题行</option>\n <option value=\"data\">数据行</option>\n <option value=\"subtotal\">小计行(每页小计)</option>\n <option value=\"summary\">汇总行</option>\n </select>\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">行高 (mm)</span>\n <input :value=\"row.height\" type=\"number\" class=\"pd-input\"\n :min=\"3\"\n :max=\"100\"\n :step=\"0.5\"\n style=\"width: 100%\" @input=\"onHeightChange(($event.target as HTMLInputElement).valueAsNumber)\" />\n </div>\n <div class=\"pd-field\" v-if=\"row.type === 'header'\"><span class=\"pd-label\">每页顶部重复</span>\n <input :checked=\"row.repeatOnPage ?? false\" type=\"checkbox\" class=\"pd-switch\" @input=\"onRepeatChange(!!($event.target as HTMLInputElement).checked)\" />\n </div>\n </form>\n </PropertyGroup>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, inject } from 'vue'\nimport type { RuntimeElement, TableSelection, TableRowType } from '../../types'\nimport { setRowType, syncTableElementSize } from '../../utils/table-matrix'\nimport { TABLE_EDIT_KEY } from '../../composables/useTableSelection'\nimport PropertyGroup from './PropertyGroup.vue'\n\nconst props = defineProps<{ element: RuntimeElement; selection: TableSelection }>()\nconst ctx = inject(TABLE_EDIT_KEY)!\n\nconst row = computed(() => props.element.options.tableRows![props.selection.r1]!)\n\nfunction onTypeChange(t: TableRowType) {\n const err = setRowType(\n props.element.options.tableRows!,\n props.selection.r1,\n t,\n )\n if (err) {\n alert(err)\n return\n }\n ctx.recordHistory()\n}\n\nfunction onHeightChange(v: number | undefined) {\n if (v === undefined) return\n row.value.height = v\n syncTableElementSize(props.element.options)\n ctx.recordHistory()\n}\n\nfunction onRepeatChange(v: boolean) {\n row.value.repeatOnPage = v\n ctx.recordHistory()\n}\n</script>\n","<!-- 表格单元格分组:格式化/样式/边框/合并拆分 -->\n<template>\n <PropertyGroup title=\"单元格\" icon=\"Menu\" default-expanded group-key=\"table-cell\">\n <form class=\"pd-form\" @submit.prevent>\n <div class=\"pd-field\"><span class=\"pd-label\">单元格类型</span>\n <div class=\"pd-radio-group\" role=\"radiogroup\">\n <label class=\"pd-radio\"><input type=\"radio\" value=\"text\" :checked=\"(mainCell.cellType || 'text') === 'text'\" @change=\"onCellTypeChange(($event.target as HTMLInputElement).value)\"><span>文本</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" value=\"barcode\" :checked=\"mainCell.cellType === 'barcode'\" @change=\"onCellTypeChange(($event.target as HTMLInputElement).value)\"><span>条形码</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" value=\"qrcode\" :checked=\"mainCell.cellType === 'qrcode'\" @change=\"onCellTypeChange(($event.target as HTMLInputElement).value)\"><span>二维码</span></label>\n </div>\n </div>\n\n <div class=\"pd-field\" v-if=\"isBarcodeCell\"><span class=\"pd-label\">码制</span>\n <select :value=\"mainCell.barcodeType || 'CODE128'\" class=\"pd-select\" @change=\"write(c => { c.barcodeType = ($event.target as HTMLSelectElement).value || undefined })\">\n <option value=\"CODE128\">CODE128(通用)</option>\n <option value=\"EAN13\">EAN13(商品码)</option>\n <option value=\"EAN8\">EAN8</option>\n <option value=\"UPC\">UPC</option>\n <option value=\"CODE39\">CODE39</option>\n <option value=\"ITF14\">ITF14</option>\n </select>\n </div>\n <div class=\"pd-field\" v-if=\"isBarcodeCell\"><span class=\"pd-label\">显示文本</span>\n <input :checked=\"mainCell.showBarcodeText !== false\" type=\"checkbox\" class=\"pd-switch\" @input=\"write(c => { c.showBarcodeText = !!($event.target as HTMLInputElement).checked })\" />\n </div>\n <div class=\"pd-field\" v-if=\"isQrcodeCell\"><span class=\"pd-label\">纠错级别</span>\n <select :value=\"mainCell.qrCodeLevel || 'M'\" class=\"pd-select\" @change=\"write(c => { c.qrCodeLevel = ($event.target as HTMLSelectElement).value || undefined })\">\n <option value=\"L\">L(最低,容量大)</option>\n <option value=\"M\">M(推荐)</option>\n <option value=\"Q\">Q</option>\n <option value=\"H\">H(最高)</option>\n </select>\n </div>\n\n <div class=\"pd-field\"><span class=\"pd-label\">内容</span>\n <input :value=\"mainCell.formatter || ''\" class=\"pd-input\"\n placeholder=\"输入内容,支持 {字段} 表达式\"\n @input=\"write(c => { c.formatter = ($event.target as HTMLInputElement).value || undefined })\"\n @dblclick=\"openFormatterEditor\" />\n </div>\n\n <div class=\"pd-field\"><span class=\"pd-label\">水平对齐</span>\n <div class=\"pd-radio-group\" role=\"radiogroup\">\n <label class=\"pd-radio\"><input type=\"radio\" value=\"left\" :checked=\"mainCell.align === 'left'\" @change=\"onAlignChange(($event.target as HTMLInputElement).value)\"><span>左</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" value=\"center\" :checked=\"mainCell.align === 'center'\" @change=\"onAlignChange(($event.target as HTMLInputElement).value)\"><span>中</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" value=\"right\" :checked=\"mainCell.align === 'right'\" @change=\"onAlignChange(($event.target as HTMLInputElement).value)\"><span>右</span></label>\n </div>\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">垂直对齐</span>\n <div class=\"pd-radio-group\" role=\"radiogroup\">\n <label class=\"pd-radio\"><input type=\"radio\" value=\"top\" :checked=\"mainCell.valign === 'top'\" @change=\"onValignChange(($event.target as HTMLInputElement).value)\"><span>上</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" value=\"middle\" :checked=\"mainCell.valign === 'middle'\" @change=\"onValignChange(($event.target as HTMLInputElement).value)\"><span>中</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" value=\"bottom\" :checked=\"mainCell.valign === 'bottom'\" @change=\"onValignChange(($event.target as HTMLInputElement).value)\"><span>下</span></label>\n </div>\n </div>\n <div class=\"cell-style-grid\">\n <div class=\"pd-field\"><span class=\"pd-label\">字体</span>\n <select :value=\"mainCell.fontFamily\" class=\"pd-select\"\n placeholder=\"继承默认\" @change=\"write(c => { c.fontFamily = ($event.target as HTMLSelectElement).value || undefined })\">\n <option value=\"SimSun\">宋体</option>\n <option value=\"SimHei\">黑体</option>\n <option value=\"Microsoft YaHei\">微软雅黑</option>\n <option value=\"KaiTi\">楷体</option>\n <option value=\"FangSong\">仿宋</option>\n <option value=\"Arial\">Arial</option>\n </select>\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">字号 (pt)</span>\n <input :value=\"mainCell.fontSize\" type=\"number\" class=\"pd-input\"\n :min=\"5\"\n :max=\"72\" @input=\"write(c => { c.fontSize = ($event.target as HTMLInputElement).valueAsNumber ?? undefined })\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">加粗</span>\n <input :checked=\"mainCell.fontWeight === 'bold'\" type=\"checkbox\" class=\"pd-switch\" @input=\"write(c => { c.fontWeight = ($event.target as HTMLInputElement).checked ? 'bold' : undefined })\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">文字颜色</span>\n <PresetColorPicker :model-value=\"mainCell.color\" @update:model-value=\"write(c => { c.color = $event })\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">背景色</span>\n <PresetColorPicker :model-value=\"mainCell.backgroundColor\" @update:model-value=\"write(c => { c.backgroundColor = $event })\" />\n </div>\n </div>\n\n <h3 class=\"pd-divider\">边框</h3>\n <div class=\"border-style-row\">\n <select class=\"pd-select\" v-model=\"borderStyle\" style=\"width: 90px\">\n <option value=\"solid\">实线</option>\n <option value=\"dashed\">虚线</option>\n <option value=\"dotted\">点线</option>\n <option value=\"double\">双线</option>\n </select>\n <input type=\"number\" class=\"pd-input\" v-model.number=\"borderWidth\"\n :min=\"0.25\"\n :max=\"5\"\n :step=\"0.25\"\n style=\"width: 90px\" />\n <PresetColorPicker v-model=\"borderColor\" />\n </div>\n <div class=\"pd-button-group border-presets\">\n <button type=\"button\" class=\"pd-button small\" @click=\"preset('all')\">全部</button>\n <button type=\"button\" class=\"pd-button small\" @click=\"preset('outer')\">外侧</button>\n <button type=\"button\" class=\"pd-button small\" @click=\"preset('inner')\">内部</button>\n <button type=\"button\" class=\"pd-button small\" @click=\"preset('none')\">无</button>\n </div>\n <div class=\"pd-checkbox-group\">\n <label class=\"pd-checkbox\"><input type=\"checkbox\" v-model=\"edgeChecks\" value=\"top\" @change=\"onEdgesChange($event)\"><span>上</span></label>\n <label class=\"pd-checkbox\"><input type=\"checkbox\" v-model=\"edgeChecks\" value=\"right\" @change=\"onEdgesChange($event)\"><span>右</span></label>\n <label class=\"pd-checkbox\"><input type=\"checkbox\" v-model=\"edgeChecks\" value=\"bottom\" @change=\"onEdgesChange($event)\"><span>下</span></label>\n <label class=\"pd-checkbox\"><input type=\"checkbox\" v-model=\"edgeChecks\" value=\"left\" @change=\"onEdgesChange($event)\"><span>左</span></label>\n </div>\n\n <div class=\"pd-field\"><span class=\"pd-label\">内边距 (mm)</span>\n <input :value=\"mainCell.padding\" type=\"number\" class=\"pd-input\"\n :min=\"0\"\n :max=\"10\"\n :step=\"0.5\" @input=\"write(c => { c.padding = ($event.target as HTMLInputElement).valueAsNumber ?? undefined })\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">自动换行</span>\n <input :checked=\"mainCell.wordWrap ?? true\" type=\"checkbox\" class=\"pd-switch\" @input=\"write(c => { c.wordWrap = !!($event.target as HTMLInputElement).checked })\" />\n </div>\n\n <div class=\"merge-btns\">\n <button type=\"button\" class=\"pd-button small\" :disabled=\"!!mergeReason\" :title=\"mergeReason || ''\" @click=\"doMerge\">\n 合并单元格\n </button>\n <button type=\"button\" class=\"pd-button small\" :disabled=\"!canSplit\" @click=\"doSplit\">拆分单元格</button>\n </div>\n </form>\n </PropertyGroup>\n\n <ExpressionEditor\n v-model=\"formatterEditorVisible\"\n :fields=\"fields\"\n :expression=\"pendingFormatterValue\"\n @update:expression=\"onFormatterEditorConfirm\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, inject, ref } from 'vue'\nimport type {\n RuntimeElement, TableSelection, TableCell, TableCellBorder, TableCellBorders, TableCellType, TextAlign,\n PrintBusinessField,\n} from '../../types'\nimport {\n canMergeReason, mergeCells, splitCells, applyBorderPreset, findMainCell, type BorderPreset,\n} from '../../utils/table-matrix'\nimport { TABLE_EDIT_KEY } from '../../composables/useTableSelection'\nimport PropertyGroup from './PropertyGroup.vue'\nimport ExpressionEditor from '../ExpressionEditor.vue'\nimport PresetColorPicker from '../PresetColorPicker.vue'\n\nconst props = defineProps<{\n element: RuntimeElement\n selection: TableSelection\n fields: PrintBusinessField[]\n}>()\nconst ctx = inject(TABLE_EDIT_KEY)!\n\nconst rows = computed(() => props.element.options.tableRows!)\n\nconst mainCell = computed<TableCell>(() => {\n const m = findMainCell(rows.value, props.selection.r1, props.selection.c1)\n return rows.value[m.r]!.cells[m.c]!\n})\n\nconst formatterEditorVisible = ref(false)\nconst pendingFormatterValue = ref('')\n\nconst isBarcodeCell = computed(() => mainCell.value.cellType === 'barcode')\nconst isQrcodeCell = computed(() => mainCell.value.cellType === 'qrcode')\n\nfunction onAlignChange(v: string) {\n write(c => { c.align = v as TextAlign })\n}\n\nfunction onValignChange(v: string) {\n write(c => { c.valign = v as TableCell['valign'] })\n}\n\nfunction onCellTypeChange(v: string) {\n write(c => {\n c.cellType = v === 'text' ? undefined : (v as TableCellType)\n if (v !== 'barcode') {\n c.barcodeType = undefined\n c.showBarcodeText = undefined\n }\n if (v !== 'qrcode') c.qrCodeLevel = undefined\n })\n}\n\nfunction openFormatterEditor() {\n pendingFormatterValue.value = mainCell.value.formatter || ''\n formatterEditorVisible.value = true\n}\n\nfunction onFormatterEditorConfirm(val: string) {\n write(c => { c.formatter = val || undefined })\n}\n\nfunction write(fn: (c: TableCell) => void) {\n const s = props.selection\n for (let r = s.r1; r <= s.r2; r++) {\n for (let c = s.c1; c <= s.c2; c++) {\n const cell = rows.value[r]!.cells[c]!\n if (!cell.merged) fn(cell)\n }\n }\n ctx.recordHistory()\n}\n\nconst borderStyle = ref<TableCellBorder['style']>('solid')\nconst borderWidth = ref(0.75)\nconst borderColor = ref('#333333')\nconst edgeChecks = ref<string[]>([])\n\nfunction currentBorder(): TableCellBorder {\n return { width: borderWidth.value, style: borderStyle.value, color: borderColor.value }\n}\n\nfunction preset(p: BorderPreset) {\n applyBorderPreset(rows.value, props.selection, p, currentBorder())\n ctx.recordHistory()\n}\n\nfunction onEdgesChange(event: Event) {\n const input = event.target as HTMLInputElement\n const edges = new Set(edgeChecks.value)\n if (input.checked) edges.add(input.value)\n else edges.delete(input.value)\n edgeChecks.value = [...edges]\n const b = currentBorder()\n write(c => {\n const nb = { ...(c.borders ?? {}) } as Record<string, TableCellBorder | undefined>\n for (const side of ['top', 'right', 'bottom', 'left']) {\n if (edges.has(side)) nb[side] = { ...b }\n else delete nb[side]\n }\n c.borders = nb as TableCellBorders\n })\n}\n\nconst mergeReason = computed(() => canMergeReason(rows.value, props.selection))\n\nconst canSplit = computed(() => {\n const s = props.selection\n for (let r = s.r1; r <= s.r2; r++) {\n for (let c = s.c1; c <= s.c2; c++) {\n const cell = rows.value[r]!.cells[c]!\n if (!cell.merged && ((cell.rowspan ?? 1) > 1 || (cell.colspan ?? 1) > 1)) return true\n }\n }\n return false\n})\n\nfunction doMerge() {\n mergeCells(rows.value, props.selection)\n ctx.recordHistory()\n}\n\nfunction doSplit() {\n splitCells(rows.value, props.selection)\n ctx.recordHistory()\n}\n\ndefineExpose({ openFormatterEditor })\n</script>\n\n<style scoped>\n.cell-style-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 0 8px;\n}\n.border-style-row {\n display: flex;\n gap: 6px;\n margin-bottom: 8px;\n}\n.border-presets {\n margin-bottom: 8px;\n}\n.merge-btns {\n margin-top: 8px;\n display: flex;\n gap: 8px;\n}\n.field-row {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n}\n</style>\n","import type { BindingDescriptor } from '../types'\n\n/**\n * 元素绑定声明注册表\n * 每个元素类型声明其支持的 formatter 绑定位置\n */\nexport const ELEMENT_BINDING_REGISTRY: Record<string, BindingDescriptor[]> = {\n text: [\n { targetPath: 'options.formatter', label: '内容', dataSource: 'main' },\n ],\n longText: [\n { targetPath: 'options.formatter', label: '内容', dataSource: 'main' },\n { targetPath: 'options.styler', label: '样式', dataSource: 'main' },\n ],\n barcode: [\n { targetPath: 'options.formatter', label: '内容', dataSource: 'main' },\n ],\n qrcode: [\n { targetPath: 'options.formatter', label: '内容', dataSource: 'main' },\n ],\n image: [\n { targetPath: 'options.src', label: '内容', dataSource: 'main', placeholder: '输入图片路径,支持 /docfiles/... 相对路径、绝对 URL 或 {字段} 表达式' },\n ],\n table: [],\n}\n\nexport function getTableCellBindings(\n rowType: string,\n rowIndex: number,\n cellIndex: number,\n listField?: string,\n): BindingDescriptor[] {\n if (rowType === 'data') {\n return [{\n targetPath: `options.tableRows[${rowIndex}].cells[${cellIndex}].formatter`,\n label: '内容',\n dataSource: 'list',\n listField,\n placeholder: '{name}',\n }]\n }\n if (rowType === 'subtotal') {\n return [{\n targetPath: `options.tableRows[${rowIndex}].cells[${cellIndex}].formatter`,\n label: '内容',\n dataSource: 'subtotal',\n placeholder: '{MONEY(SUM(amount))}',\n }]\n }\n if (rowType === 'summary') {\n return [{\n targetPath: `options.tableRows[${rowIndex}].cells[${cellIndex}].formatter`,\n label: '内容',\n dataSource: 'summary',\n placeholder: '{MONEY(SUM(amount))}',\n }]\n }\n return [{\n targetPath: `options.tableRows[${rowIndex}].cells[${cellIndex}].formatter`,\n label: '内容',\n dataSource: 'main',\n placeholder: '合计: {order.total}',\n }]\n}\n\nexport function getElementBindings(element: any): BindingDescriptor[] {\n const type = element.printElementType.type\n const staticBindings = ELEMENT_BINDING_REGISTRY[type] ?? []\n const dynamicBindings: BindingDescriptor[] = []\n\n if (type === 'table') {\n const listField = element.options.dataSource\n for (const [ri, row] of (element.options.tableRows ?? []).entries()) {\n for (const [ci, cell] of row.cells.entries()) {\n if (cell.merged) continue\n dynamicBindings.push(...getTableCellBindings(row.type, ri, ci, listField))\n }\n }\n }\n\n return [...staticBindings, ...dynamicBindings]\n}\n","<template>\n <div class=\"property-panel\" :class=\"{ collapsed }\">\n <!-- 折叠态:竖排图标,点击即展开对应页签 -->\n <div v-if=\"collapsed\" class=\"prop-collapsed\">\n <button class=\"pc-btn\" title=\"展开属性台\" @click=\"expandTab(currentTab)\">«</button>\n <button class=\"pc-btn\" :class=\"{ on: currentTab === 'element' }\" title=\"元素属性\" @click=\"expandTab('element')\">▦</button>\n <button class=\"pc-btn\" :class=\"{ on: currentTab === 'page' }\" title=\"页面属性\" @click=\"expandTab('page')\">▤</button>\n </div>\n <template v-else>\n <div class=\"prop-head\">\n <span class=\"prop-title\">属性台</span>\n <button class=\"collapse-btn\" title=\"收起属性台\" @click=\"$emit('toggle-collapse')\">»</button>\n </div>\n <div class=\"pd-tabs prop-tabs\">\n <div class=\"pd-tab-bar\" role=\"tablist\">\n <button type=\"button\" class=\"pd-tab\" :class=\"{ active: (activeTab || 'page') === 'element' }\" @click=\"$emit('update:activeTab', 'element')\">元素属性</button>\n <button type=\"button\" class=\"pd-tab\" :class=\"{ active: (activeTab || 'page') === 'page' }\" @click=\"$emit('update:activeTab', 'page')\">页面属性</button>\n </div>\n <div v-show=\"(activeTab || 'page') === 'element'\" class=\"pd-tab-pane\" role=\"tabpanel\">\n <template v-if=\"element\">\n <PropertySearch @search=\"onSearch\" />\n <div class=\"property-content\">\n <PositionSizeGroup v-if=\"filteredGroups.includes('position-size') && !isTableCellSelected\" :element=\"element\" :matched-keys=\"matchedKeys\" :searching=\"searching\" />\n <AppearanceGroup v-if=\"filteredGroups.includes('appearance')\" :element=\"element\" :is-text-type=\"isTextType\" :matched-keys=\"matchedKeys\" :searching=\"searching\" />\n <PropertyGroup v-if=\"filteredGroups.includes('binding')\" title=\"内容\" icon=\"Document\" default-expanded group-key=\"binding\">\n <BindingControl\n v-for=\"desc in bindingDescriptors\"\n :key=\"desc.targetPath\"\n :descriptor=\"desc\"\n :fields=\"fields\"\n :model-value=\"getBindingValue(desc.targetPath)\"\n @update:model-value=\"(v: string) => setBindingValue(desc.targetPath, v)\"\n />\n <ImageContentUpload\n v-if=\"isImageType\"\n @success=\"onImageUploadSuccess\"\n />\n </PropertyGroup>\n <!-- 表格行/单元格属性(需有选区) -->\n <template v-if=\"isTableType && tableSelection && tableSelection.elementId === element!.id\">\n <TableRowGroup :element=\"element!\" :selection=\"tableSelection\" />\n <TableCellGroup :element=\"element!\" :selection=\"tableSelection\" :fields=\"fields\" />\n </template>\n <!-- 表格设置(表格元素时显示) -->\n <TableSettingsGroup\n v-if=\"isTableType && filteredGroups.includes('content')\"\n :element=\"element!\"\n :fields=\"fields\"\n />\n <BorderBgGroup v-if=\"filteredGroups.includes('border-bg')\" :element=\"element\" :matched-keys=\"matchedKeys\" :searching=\"searching\" />\n <!-- 分页配置(表格元素) -->\n <PaginationGroup\n v-if=\"filteredGroups.includes('pagination') && isTableType\"\n :element=\"element\"\n :matched-keys=\"matchedKeys\"\n :searching=\"searching\"\n />\n <!-- 分页配置(非表格元素) -->\n <PaginationGroup\n v-if=\"filteredGroups.includes('pagination') && !isTableType\"\n :element=\"element\"\n :matched-keys=\"matchedKeys\"\n :searching=\"searching\"\n />\n <AdvancedGroup v-if=\"filteredGroups.includes('advanced')\" :element=\"element\" :matched-keys=\"matchedKeys\" :searching=\"searching\" @delete-element=\"$emit('delete-element')\" />\n </div>\n </template>\n <p class=\"pd-empty\" v-else>请在画布中选择一个元素</p>\n </div>\n\n <div v-show=\"(activeTab || 'page') === 'page'\" class=\"pd-tab-pane\" role=\"tabpanel\">\n <form class=\"pd-form\" @submit.prevent>\n <h3 class=\"pd-divider\">纸张设置</h3>\n\n <div class=\"pd-field\"><span class=\"pd-label\">纸张尺寸</span>\n <select :value=\"paperSizeModel\" class=\"pd-select\" @change=\"onPaperSizeChange(($event.target as HTMLSelectElement).value)\" style=\"width: 100%\">\n <option v-for=\"(_ps, key) in paperPresets\" :key=\"key\" :value=\"key\">{{ key }}</option>\n <option value=\"CUSTOM\">自定义</option>\n </select>\n </div>\n <div class=\"pd-field\" v-if=\"paperSizeModel === 'CUSTOM'\"><span class=\"pd-label\">自定义宽高 (mm)</span>\n <div class=\"custom-size-grid\">\n <input :value=\"customWidth\" type=\"number\" class=\"pd-input\"\n @input=\"onCustomWidthChange(($event.target as HTMLInputElement).valueAsNumber)\"\n :min=\"25\"\n :max=\"2000\"\n :step=\"1\"\n style=\"width: 100%\" />\n <span class=\"custom-size-x\">×</span>\n <input :value=\"customHeight\" type=\"number\" class=\"pd-input\"\n @input=\"onCustomHeightChange(($event.target as HTMLInputElement).valueAsNumber)\"\n :min=\"25\"\n :max=\"2000\"\n :step=\"1\"\n style=\"width: 100%\" />\n </div>\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">方向</span>\n <div class=\"pd-radio-group\" role=\"radiogroup\">\n <label class=\"pd-radio\"><input type=\"radio\" value=\"portrait\" :checked=\"orientationModel === 'portrait'\" @change=\"onOrientationChange(($event.target as HTMLInputElement).value)\"><span>纵向</span></label>\n <label class=\"pd-radio\"><input type=\"radio\" value=\"landscape\" :checked=\"orientationModel === 'landscape'\" @change=\"onOrientationChange(($event.target as HTMLInputElement).value)\"><span>横向</span></label>\n </div>\n </div>\n\n <h3 class=\"pd-divider\">页边距 (mm)</h3>\n <div class=\"margin-grid\">\n <div class=\"pd-field\"><span class=\"pd-label\">上</span>\n <input :value=\"marginTop\" type=\"number\" class=\"pd-input\" @input=\"onMarginTopChange(($event.target as HTMLInputElement).valueAsNumber)\" :min=\"0\" :max=\"50\" :step=\"1\" style=\"width: 100%\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">下</span>\n <input :value=\"marginBottom\" type=\"number\" class=\"pd-input\" @input=\"onMarginBottomChange(($event.target as HTMLInputElement).valueAsNumber)\" :min=\"0\" :max=\"50\" :step=\"1\" style=\"width: 100%\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">左</span>\n <input :value=\"marginLeft\" type=\"number\" class=\"pd-input\" @input=\"onMarginLeftChange(($event.target as HTMLInputElement).valueAsNumber)\" :min=\"0\" :max=\"50\" :step=\"1\" style=\"width: 100%\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">右</span>\n <input :value=\"marginRight\" type=\"number\" class=\"pd-input\" @input=\"onMarginRightChange(($event.target as HTMLInputElement).valueAsNumber)\" :min=\"0\" :max=\"50\" :step=\"1\" style=\"width: 100%\" />\n </div>\n </div>\n\n <h3 class=\"pd-divider\">三区高度 (mm)</h3>\n <div class=\"pd-field\"><span class=\"pd-label\">页眉高度</span>\n <input :value=\"headerHeight\" type=\"number\" class=\"pd-input\" @input=\"onHeaderHeightChange(($event.target as HTMLInputElement).valueAsNumber)\" :min=\"0\" :max=\"100\" :step=\"0.1\" style=\"width: 100%\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">页脚高度</span>\n <input :value=\"footerHeight\" type=\"number\" class=\"pd-input\" @input=\"onFooterHeightChange(($event.target as HTMLInputElement).valueAsNumber)\" :min=\"0\" :max=\"100\" :step=\"0.1\" style=\"width: 100%\" />\n </div>\n <div class=\"pd-field\"><span class=\"pd-label\">首页叠加高度</span>\n <input :value=\"overlayHeight\" type=\"number\" class=\"pd-input\" @input=\"onOverlayHeightChange(($event.target as HTMLInputElement).valueAsNumber)\" :min=\"0\" :max=\"200\" style=\"width: 100%\" />\n </div>\n </form>\n </div>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport type { RuntimeElement, PrintBusinessField, TemplateData, TableSelection } from '../types'\nimport { PAPER_PRESETS } from '../utils/default-config'\nimport { searchProperties } from '../utils/property-search'\nimport PropertySearch from './property/PropertySearch.vue'\nimport PositionSizeGroup from './property/PositionSizeGroup.vue'\nimport AppearanceGroup from './property/AppearanceGroup.vue'\nimport PropertyGroup from './property/PropertyGroup.vue'\nimport BindingControl from './property/BindingControl.vue'\nimport TableSettingsGroup from './property/TableSettingsGroup.vue'\nimport BorderBgGroup from './property/BorderBgGroup.vue'\nimport AdvancedGroup from './property/AdvancedGroup.vue'\nimport PaginationGroup from './property/PaginationGroup.vue'\nimport ImageContentUpload from './property/ImageContentUpload.vue'\nimport TableRowGroup from './property/TableRowGroup.vue'\nimport TableCellGroup from './property/TableCellGroup.vue'\nimport { getElementBindings, getTableCellBindings } from '../utils/binding-registry'\nimport type { BindingDescriptor } from '../types'\n\nconst props = defineProps<{\n element: RuntimeElement | null\n templateData?: TemplateData\n fields: PrintBusinessField[]\n activeTab?: 'element' | 'page'\n tableSelection?: TableSelection | null\n recordHistory?: () => void\n collapsed: boolean\n}>()\n\nconst emit = defineEmits<{\n 'delete-element': []\n 'update:templateData': [data: TemplateData]\n 'update:activeTab': [tab: 'element' | 'page']\n 'toggle-collapse': []\n}>()\n\nconst paperPresets = PAPER_PRESETS\nconst searchText = ref('')\n\nconst isTextType = computed(() => {\n if (!props.element) return false\n return ['text', 'longText'].includes(props.element.printElementType.type)\n})\n\nconst isImageType = computed(() => {\n if (!props.element) return false\n return props.element.printElementType.type === 'image'\n})\n\n/** 是否处于表格单元格选中态:单元格的位置与宽高由行高/列宽控制,隐藏「位置与尺寸」组 */\nconst isTableCellSelected = computed(() => {\n if (!props.element) return false\n if (props.element.printElementType.type !== 'table') return false\n return !!props.tableSelection && props.tableSelection.elementId === props.element.id\n})\n\nconst isTableType = computed(() => {\n if (!props.element) return false\n return props.element.printElementType.type === 'table'\n})\n\nconst searchResult = computed(() => searchProperties(searchText.value))\nconst filteredGroups = computed(() => searchResult.value.groups)\nconst matchedKeys = computed(() => searchResult.value.itemKeys)\nconst searching = computed(() => !!searchText.value.trim())\n\nconst bindingDescriptors = computed<BindingDescriptor[]>(() => {\n if (!props.element) return []\n\n // 当有表格选区时,只返回选中单元格的绑定描述符\n if (props.element.printElementType.type === 'table' && props.tableSelection) {\n const { r1, c1 } = props.tableSelection\n const rows = props.element.options.tableRows\n if (rows && rows[r1]) {\n const row = rows[r1]\n const listField = props.element.options.fields?.[0]?.dataSource\n return getTableCellBindings(row.type, r1, c1, listField)\n }\n }\n\n return getElementBindings(props.element)\n})\n\n/**\n * 统一解析带点分段与数组下标的 targetPath 为段/索引混排数组\n * 例:'options.formatter' → ['options','formatter']\n * 例:'options.tableRows[0].cells[1].formatter' → ['options','tableRows',0,'cells',1,'formatter']\n */\nfunction parsePath(targetPath: string): (string | number)[] {\n return targetPath.split('.').flatMap(segment => {\n const match = segment.match(/^([^\\[]+)((?:\\[\\d+\\])*)$/)\n if (!match) return [segment]\n const baseName = match[1]!\n const indices = [...match[2]!.matchAll(/\\[(\\d+)\\]/g)].map(m => Number(m[1]!))\n return [baseName, ...indices]\n })\n}\n\nfunction getBindingValue(targetPath: string): string {\n if (!props.element) return ''\n const segments = parsePath(targetPath)\n const result = segments.reduce((current, seg) => {\n if (current === null || current === undefined) return ''\n return current[seg as keyof typeof current]\n }, props.element as any)\n return result ?? ''\n}\n\nfunction setBindingValue(targetPath: string, value: string) {\n if (!props.element) return\n const segments = parsePath(targetPath)\n const lastKey = segments.pop()!\n const obj = segments.reduce((current, seg) => {\n if (current[seg] === undefined || current[seg] === null) current[seg] = {}\n return current[seg]\n }, props.element as any)\n obj[lastKey] = value || undefined\n props.recordHistory?.()\n}\n\nfunction onSearch(text: string) {\n searchText.value = text\n}\n\n/** 图片上传成功:将相对路径写入 options.src(内容输入框绑定路径) */\nfunction onImageUploadSuccess(url: string) {\n if (!props.element) return\n setBindingValue('options.src', url)\n}\n\n// ─── 页面属性模型(直接读写 templateData) ───\n\nconst paperSizeModel = computed(() => props.templateData?.paperSize || 'A4')\nconst orientationModel = computed(() => props.templateData?.orientation || 'portrait')\n\nconst marginTop = computed(() => props.templateData?.margins.top ?? 10)\nconst marginBottom = computed(() => props.templateData?.margins.bottom ?? 10)\nconst marginLeft = computed(() => props.templateData?.margins.left ?? 10)\nconst marginRight = computed(() => props.templateData?.margins.right ?? 10)\n\nconst headerHeight = computed(() => props.templateData?.header.height ?? 10)\nconst footerHeight = computed(() => props.templateData?.footer.height ?? 10)\nconst overlayHeight = computed(() => props.templateData?.firstPageOverlay.height ?? 0)\n\nconst customWidth = computed(() => props.templateData?.customWidth ?? 210)\nconst customHeight = computed(() => props.templateData?.customHeight ?? 297)\n\nfunction emitUpdate(partial: Partial<TemplateData>) {\n if (!props.templateData) return\n emit('update:templateData', { ...props.templateData, ...partial })\n}\n\nfunction onPaperSizeChange(size: string) {\n if (size === 'CUSTOM') {\n emitUpdate({ paperSize: 'CUSTOM' })\n return\n }\n if (!paperPresets[size]) return\n emitUpdate({ paperSize: size as TemplateData['paperSize'] })\n}\n\nfunction onOrientationChange(val: string | number | boolean | undefined) {\n emitUpdate({ orientation: String(val) as TemplateData['orientation'] })\n}\n\nfunction onCustomWidthChange(v: number | undefined) {\n if (v === undefined) return\n emitUpdate({ customWidth: v })\n}\n\nfunction onCustomHeightChange(v: number | undefined) {\n if (v === undefined) return\n emitUpdate({ customHeight: v })\n}\n\nfunction onMarginTopChange(v: number | undefined) {\n if (v === undefined) return\n emitUpdate({ margins: { ...props.templateData!.margins, top: v } })\n}\nfunction onMarginBottomChange(v: number | undefined) {\n if (v === undefined) return\n emitUpdate({ margins: { ...props.templateData!.margins, bottom: v } })\n}\nfunction onMarginLeftChange(v: number | undefined) {\n if (v === undefined) return\n emitUpdate({ margins: { ...props.templateData!.margins, left: v } })\n}\nfunction onMarginRightChange(v: number | undefined) {\n if (v === undefined) return\n emitUpdate({ margins: { ...props.templateData!.margins, right: v } })\n}\n\nfunction onHeaderHeightChange(v: number | undefined) {\n if (v === undefined) return\n emitUpdate({ header: { ...props.templateData!.header, height: v } })\n}\n\nfunction onFooterHeightChange(v: number | undefined) {\n if (v === undefined) return\n emitUpdate({ footer: { ...props.templateData!.footer, height: v } })\n}\n\nfunction onOverlayHeightChange(v: number | undefined) {\n if (v === undefined) return\n emitUpdate({\n firstPageOverlay: { ...props.templateData!.firstPageOverlay, height: v },\n })\n}\n\nconst currentTab = computed(() => props.activeTab || 'page')\n\nfunction expandTab(tab: 'element' | 'page') {\n emit('update:activeTab', tab)\n emit('toggle-collapse')\n}\n</script>\n\n<style scoped>\n.property-panel {\n width: 280px;\n min-width: 280px;\n background: var(--pd-sidebar, #ffffff);\n border-left: 1px solid var(--pd-border-soft, #e9ecf2);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n transition: width .18s ease;\n}\n.property-panel.collapsed {\n width: 36px;\n min-width: 36px;\n border-left: 1px solid var(--pd-border-soft, #e9ecf2);\n}\n.prop-collapsed {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding-top: 12px;\n flex: 1;\n}\n.pc-btn {\n width: 26px;\n height: 26px;\n border-radius: 6px;\n border: 1px solid transparent;\n background: transparent;\n color: var(--pd-text-muted, #8b909c);\n font-size: 12px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all .14s ease;\n}\n.pc-btn:hover {\n color: var(--pd-text, #2a2e37);\n background: var(--pd-sidebar-hover, #f0f3f9);\n}\n.pc-btn.on {\n color: var(--pd-accent, #165DFF);\n background: var(--pd-accent-soft, rgba(22, 93, 255, .09));\n}\n.prop-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n height: 42px;\n padding: 0 12px;\n flex-shrink: 0;\n border-bottom: 1px solid var(--pd-border-soft, #e9ecf2);\n}\n.prop-title {\n font-size: 12px;\n font-weight: 600;\n color: var(--pd-text, #2a2e37);\n letter-spacing: 1.2px;\n display: inline-flex;\n align-items: center;\n gap: 7px;\n}\n.prop-title::before {\n content: \"\";\n width: 3px;\n height: 12px;\n border-radius: 2px;\n background: linear-gradient(180deg, var(--pd-accent-2, #3D7BFF), var(--pd-accent, #165DFF));\n}\n.collapse-btn {\n border: none;\n background: transparent;\n color: var(--pd-text-muted, #8b909c);\n font-size: 14px;\n cursor: pointer;\n width: 24px;\n height: 24px;\n border-radius: 5px;\n transition: all .14s ease;\n}\n.collapse-btn:hover {\n color: var(--pd-text, #2a2e37);\n background: var(--pd-sidebar-hover, #f0f3f9);\n}\n.prop-tabs {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.prop-tabs .pd-tab-pane {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 12px;\n}\n.property-content {\n padding: 0;\n}\n.margin-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 0 12px;\n}\n.custom-size-grid {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n align-items: center;\n gap: 4px;\n width: 100%;\n}\n.custom-size-x {\n color: var(--pd-text-muted, #8b909c);\n font-size: 12px;\n}\n</style>\n","<template>\n <div class=\"status-bar\">\n <span class=\"status-item coord\" v-if=\"coordinate\">\n x:{{ coordinate.x.toFixed(1) }}&nbsp;y:{{ coordinate.y.toFixed(1) }}mm\n </span>\n <span class=\"status-item\">缩放 {{ scale }}%</span>\n <span class=\"status-item\">元素 {{ elementCount }}{{ selectedCount ? ` (选中 ${selectedCount})` : '' }}</span>\n <span class=\"status-dirty\" :class=\"{ on: dirty }\">\n <span class=\"dirty-dot\" />{{ dirty ? '未保存' : '已保存' }}\n </span>\n <span class=\"status-item status-paper\">{{ paper }}</span>\n </div>\n</template>\n\n<script setup lang=\"ts\">\ndefineProps<{\n coordinate: { x: number; y: number } | null\n scale: number\n elementCount: number\n selectedCount: number\n paper: string\n dirty: boolean\n}>()\n</script>\n\n<style scoped>\n.status-bar {\n display: flex;\n align-items: center;\n gap: 20px;\n height: 30px;\n padding: 0 16px;\n background: var(--pd-surface, #ffffff);\n border-top: 1px solid var(--pd-border-soft, #e9ecf2);\n box-shadow: 0 -1px 2px rgba(23, 32, 60, .03);\n font-size: 11.5px;\n color: var(--pd-text-muted, #8b909c);\n user-select: none;\n flex-shrink: 0;\n}\n.status-item {\n white-space: nowrap;\n font-variant-numeric: tabular-nums;\n display: inline-flex;\n align-items: center;\n}\n.coord {\n font-variant-numeric: tabular-nums;\n color: var(--pd-text, #2a2e37);\n}\n.status-paper {\n margin-left: auto;\n font-variant-numeric: tabular-nums;\n color: var(--pd-accent, #165DFF);\n font-weight: 600;\n}\n.status-dirty {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n white-space: nowrap;\n color: var(--pd-text-muted, #8b909c);\n}\n.status-dirty.on {\n color: var(--pd-accent-secondary, #f56c6c);\n}\n.dirty-dot {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--pd-ink-green, #67c23a);\n}\n.status-dirty.on .dirty-dot {\n background: var(--pd-accent-secondary, #f56c6c);\n box-shadow: 0 0 0 3px rgba(245, 108, 108, .14);\n animation: dirty-pulse 1.6s ease-in-out infinite;\n}\n@keyframes dirty-pulse {\n 0%, 100% { box-shadow: 0 0 0 2px rgba(245, 108, 108, .12); }\n 50% { box-shadow: 0 0 0 4px rgba(245, 108, 108, .05); }\n}\n@media (prefers-reduced-motion: reduce) {\n .status-dirty.on .dirty-dot { animation: none; }\n}\n</style>\n","import { ref, watch } from 'vue'\n\nconst LEFT_KEY = 'print-studio:left'\nconst RIGHT_KEY = 'print-studio:right'\n\nfunction readStored(key: string, fallback: boolean): boolean {\n try {\n const raw = localStorage.getItem(key)\n return raw === null ? fallback : raw === '1'\n } catch {\n return fallback\n }\n}\n\nexport function useStudioChrome() {\n const leftCollapsed = ref(readStored(LEFT_KEY, false))\n const rightCollapsed = ref(readStored(RIGHT_KEY, false))\n const dirty = ref(false)\n\n watch(leftCollapsed, v => { try { localStorage.setItem(LEFT_KEY, v ? '1' : '0') } catch { /* ignore */ } }, { flush: 'sync' })\n watch(rightCollapsed, v => { try { localStorage.setItem(RIGHT_KEY, v ? '1' : '0') } catch { /* ignore */ } }, { flush: 'sync' })\n\n function toggleLeft() { leftCollapsed.value = !leftCollapsed.value }\n function toggleRight() { rightCollapsed.value = !rightCollapsed.value }\n function markSaved() { dirty.value = false }\n\n return { leftCollapsed, rightCollapsed, toggleLeft, toggleRight, dirty, markSaved }\n}\n","<template>\n <div class=\"designer-container\">\n <DesignerToolbar\n :is-edit=\"isEdit\"\n :can-undo=\"canUndo\"\n :can-redo=\"canRedo\"\n :has-multi-selection=\"selectedIds.size >= 2\"\n :has-selection=\"selectedIds.size >= 1\"\n :show-grid=\"showGrid\"\n :snap-to-grid=\"snapToGrid\"\n :show-table-ghost-border=\"showTableGhostBorder\"\n :selected-element-has-group=\"selectedElement?.options.groupId ? true : false\"\n :overlay-visible=\"overlayVisible\"\n :show-load-default=\"!!loadDefaultTemplate\"\n v-model:scale=\"scale\"\n @back=\"$emit('back')\"\n @preview=\"$emit('preview')\"\n @save=\"handleSave\"\n @load-default=\"handleLoadDefault\"\n @undo=\"onUndo\"\n @redo=\"onRedo\"\n @align=\"(mode: string) => onAlign(mode as AlignMode)\"\n @move-layer=\"onMoveLayer\"\n @toggle-grid=\"showGrid = !showGrid\"\n @toggle-snap=\"snapToGrid = !snapToGrid\"\n @toggle-table-ghost-border=\"showTableGhostBorder = !showTableGhostBorder\"\n @toggle-overlay=\"toggleOverlay\"\n @group=\"onGroup\"\n @ungroup=\"onUngroup\"\n @add-overlay-element=\"onAddOverlayElement\"\n @fit-window=\"onFitWindow\"\n @zoom=\"onZoom\"\n />\n\n <!-- 三栏布局 -->\n <div class=\"designer-body\">\n <LeftPanel\n :fields=\"fields\"\n :elements=\"elements\"\n :selected-ids=\"selectedIds\"\n :collapsed=\"leftCollapsed\"\n @select=\"onSelectElement\"\n @move-layer=\"onMoveLayer\"\n @toggle-visible=\"onToggleVisible\"\n @toggle-locked=\"onToggleLocked\"\n @toggle-collapse=\"toggleLeft\"\n />\n <CanvasArea\n ref=\"canvasAreaRef\"\n :template-data=\"templateData\"\n :elements=\"elements\"\n :scale=\"scale / 100\"\n :show-grid=\"showGrid\"\n :snap-to-grid=\"snapToGrid\"\n :show-table-ghost-border=\"showTableGhostBorder\"\n :has-clipboard=\"hasClipboard\"\n :guides=\"guides\"\n :overlay-visible=\"overlayVisible\"\n :screenshot-url=\"screenshotUrl\"\n :overlay-opacity=\"overlayOpacity\"\n :selected-element-has-group=\"selectedElement?.options.groupId ? true : false\"\n @select=\"onSelectElement\"\n @drop-element=\"onDropElement\"\n @drop-field=\"onDropField\"\n @drag-start=\"onDragStart\"\n @drag-stop=\"onDragStop\"\n @dblclick-element=\"onDblClickElement\"\n @dblclick-cell=\"onDblClickCell\"\n @zone-height-change=\"onZoneHeightChange\"\n @zone-height-commit=\"onZoneHeightCommit\"\n @select-all=\"selectAll\"\n @clear-selection=\"clearSelection\"\n @preview=\"setPreview\"\n @commit-preview=\"commitPreview\"\n @paste=\"paste\"\n @copy=\"copy\"\n @cut=\"cutSelected\"\n @delete=\"onDeleteElement\"\n @move-layer=\"onMoveLayer\"\n @coordinate=\"onCoordinate\"\n @group=\"onGroup\"\n @ungroup=\"onUngroup\"\n @add-guide=\"addGuide\"\n @guide-move=\"moveGuide\"\n @guide-remove=\"removeGuide\"\n @zoom=\"onZoom\"\n @clone-element=\"onCloneElement\"\n />\n <PropertyPanel\n :element=\"selectedElement\"\n :template-data=\"templateData\"\n :fields=\"fields\"\n :table-selection=\"tableSelection\"\n :record-history=\"recordHistory\"\n :collapsed=\"rightCollapsed\"\n v-model:active-tab=\"activePropertyTab\"\n @delete-element=\"onDeleteElement\"\n @update:template-data=\"onTemplateDataChanged\"\n @toggle-collapse=\"toggleRight\"\n />\n </div>\n <StatusBar\n :coordinate=\"coordinate\"\n :scale=\"scale\"\n :element-count=\"elements.length\"\n :selected-count=\"selectedIds.size\"\n :paper=\"paperLabel\"\n :dirty=\"dirty\"\n />\n\n <!-- 设计稿双击元素/单元格打开的表达式编辑器 -->\n <ExpressionEditor\n v-model=\"dblEditorVisible\"\n :fields=\"fields\"\n :expression=\"dblEditorExpression\"\n @update:expression=\"onDblEditorConfirm\"\n />\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport '../styles/native-controls.css'\nimport { ref, watch, provide, computed, onMounted, onUnmounted } from 'vue'\nimport type { RuntimeElement, PrintBusinessField, TemplateData, TableCell, RequestScreenshotFn, UploadImageFn } from '../types'\nimport { useDesignerState } from '../composables/useDesignerState'\nimport { useGuides } from '../composables/useGuides'\nimport { TABLE_EDIT_KEY } from '../composables/useTableSelection'\nimport { SELECTED_IDS_KEY, PREVIEW_IDS_KEY } from '../composables/useSelection'\nimport { getZoneRects } from '../utils/zone-layout'\nimport { getPaperDimensions } from '../utils/default-config'\nimport { DEFAULT_DEMO_DATA } from '../utils/demo-data'\nimport { findMainCell } from '../utils/table-matrix'\nimport { UPLOAD_IMAGE_KEY } from '../composables/useHostAdapter'\nimport type { AlignMode } from '../composables/useAlign'\nimport DesignerToolbar from './DesignerToolbar.vue'\nimport LeftPanel from './LeftPanel.vue'\nimport CanvasArea from './CanvasArea.vue'\nimport PropertyPanel from './PropertyPanel.vue'\nimport StatusBar from './StatusBar.vue'\nimport ExpressionEditor from './ExpressionEditor.vue'\nimport { useStudioChrome } from '../composables/useStudioChrome'\n\nconst props = defineProps<{\n initialTemplate?: TemplateData\n initialElements?: RuntimeElement[]\n fields?: PrintBusinessField[]\n isEdit?: boolean\n /** 截图适配器(叠层对比):未注入时该功能不可用 */\n requestScreenshot?: RequestScreenshotFn\n /** 图片上传适配器:未注入时图片上传不可用 */\n uploadImage?: UploadImageFn\n /** 加载默认布局回调(宿主实现业务逻辑;未注入时工具栏不展示该按钮),返回 null/undefined 视为无默认布局 */\n loadDefaultTemplate?: () => TemplateData | Promise<TemplateData | null | undefined> | null | undefined\n}>()\n\nconst emit = defineEmits<{\n back: []\n preview: []\n save: [json: string]\n}>()\n\n// 装配层状态:面板折叠(localStorage 持久)+ 未保存 dirty\nconst { leftCollapsed, rightCollapsed, toggleLeft, toggleRight, dirty, markSaved } = useStudioChrome()\n\n// 设计器核心状态统一由 useDesignerState 管理\nconst {\n scale, showGrid, snapToGrid, showTableGhostBorder,\n templateData, elements, fields,\n selectedIds, selectedElement, select, clearSelection, selectAll,\n previewIds, setPreview, commitPreview,\n hasClipboard, copy, paste, cutSelected,\n canUndo, canRedo, undo: onUndo, redo: onRedo,\n alignSelected: onAlign,\n groupSelected: onGroup, ungroupSelected: onUngroup, deleteSelected: onDeleteElement,\n dragStart: onDragStart, dragStop: onDragStop,\n addElement: onDropElement, addFieldElement: onDropField,\n moveLayer: onMoveLayer, updateTemplateData, fitToWindow,\n getTemplateJson, loadTemplate,\n tableSelection, setTableSelection, recordHistory,\n} = useDesignerState({\n initialTemplate: props.initialTemplate,\n initialElements: props.initialElements,\n initialFields: props.fields,\n})\n\n// 未保存信号:任何元素/模板数据变化点亮\nwatch([elements, templateData], () => { dirty.value = true }, { deep: true })\n\nconst { guides, addGuide, moveGuide, removeGuide } = useGuides(templateData, recordHistory)\n\n// 表格单元格编辑上下文\nconst maxTableWidth = computed(() => {\n const t = templateData.value\n const { width: paperW } = getPaperDimensions(t)\n return paperW - t.margins.left - t.margins.right\n})\nprovide(TABLE_EDIT_KEY, { tableSelection, setTableSelection, recordHistory, maxTableWidth })\nprovide(SELECTED_IDS_KEY, selectedIds)\nprovide(PREVIEW_IDS_KEY, previewIds)\n\nprovide(UPLOAD_IMAGE_KEY, computed(() => props.uploadImage))\nwatch(selectedElement, el => {\n if (!el || el.printElementType.type !== 'table') setTableSelection(null)\n})\n\nconst canvasAreaRef = ref<InstanceType<typeof CanvasArea> | null>(null)\n\n// 叠层对比模式\nconst overlayVisible = ref(false)\nconst screenshotUrl = ref('')\nconst overlayOpacity = ref(0.5)\n\nasync function toggleOverlay() {\n if (overlayVisible.value) {\n overlayVisible.value = false\n return\n }\n const templateJson = getTemplateJson()\n if (!templateJson) {\n alert('模板数据为空')\n return\n }\n if (!props.requestScreenshot) {\n alert('截图服务未配置')\n return\n }\n try {\n const blob = await props.requestScreenshot({ templateJson, printData: DEFAULT_DEMO_DATA })\n if (screenshotUrl.value) URL.revokeObjectURL(screenshotUrl.value)\n screenshotUrl.value = URL.createObjectURL(blob)\n overlayVisible.value = true\n } catch {\n alert('截图生成失败')\n }\n}\n\n// 状态栏:鼠标坐标(纸面 mm)\nconst coordinate = ref<{ x: number; y: number } | null>(null)\nfunction onCoordinate(pos: { x: number; y: number } | null) { coordinate.value = pos }\n\nconst paperLabel = computed(() => {\n const t = templateData.value\n const dim = getPaperDimensions(t)\n const orient = t.orientation === 'landscape' ? '横向' : '纵向'\n return `${t.paperSize} ${orient} ${Math.round(dim.width)}×${Math.round(dim.height)}mm`\n})\n\nfunction onFitWindow() {\n const el = (canvasAreaRef.value as any)?.$el as HTMLElement | undefined\n if (el) fitToWindow(el.clientWidth, el.clientHeight)\n}\nfunction onZoom(delta: number) {\n scale.value = Math.min(200, Math.max(50, scale.value + delta))\n}\n\n// Ctrl+0 适应窗口:需容器尺寸,由本组件单独监听(useKeyboard 不处理)\nfunction onKeyFitWindow(e: KeyboardEvent) {\n const tag = (e.target as HTMLElement).tagName\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return\n if ((e.ctrlKey || e.metaKey) && e.key === '0') {\n e.preventDefault()\n onFitWindow()\n }\n}\nonMounted(() => document.addEventListener('keydown', onKeyFitWindow))\nonUnmounted(() => document.removeEventListener('keydown', onKeyFitWindow))\n\nfunction onTemplateDataChanged(data: TemplateData) {\n const prevHeader = templateData.value.header.height\n const prevFooter = templateData.value.footer.height\n updateTemplateData(data)\n if (data.header.height < prevHeader) warnZoneOverflow('header')\n if (data.footer.height < prevFooter) warnZoneOverflow('footer')\n}\n\nfunction onZoneHeightChange(zone: 'header' | 'footer', height: number) {\n templateData.value = {\n ...templateData.value,\n [zone]: { ...templateData.value[zone], height },\n }\n}\n\nfunction onZoneHeightCommit(zone: 'header' | 'footer') {\n updateTemplateData({ ...templateData.value })\n warnZoneOverflow(zone)\n}\n\nfunction warnZoneOverflow(zone: 'header' | 'footer') {\n const rect = getZoneRects(templateData.value)[zone]\n const overflow = elements.value.some(e => e.zone === zone\n && (e.options.top + e.options.height > rect.height\n || e.options.left + e.options.width > rect.width))\n if (overflow) {\n alert(`${zone === 'header' ? '页眉' : '页脚'}高度已小于区域内元素,请手动调整元素位置`)\n }\n}\n\nfunction onAddOverlayElement() {\n const overlay = templateData.value.firstPageOverlay\n const newEl = {\n options: { left: 0, top: 0, width: 50, height: 10, title: '首页叠加' },\n printElementType: { type: 'text' as const, title: '首页叠加' },\n }\n templateData.value = {\n ...templateData.value,\n firstPageOverlay: { ...overlay, elements: [...overlay.elements, newEl] },\n }\n}\n\nconst onSelectElement = select\n\nfunction onToggleVisible(id: string) {\n const el = elements.value.find(e => e.id === id)\n if (el) el.options.visible = el.options.visible === false ? true : false\n}\n\nfunction onToggleLocked(id: string) {\n const el = elements.value.find(e => e.id === id)\n if (el) el.options.locked = !el.options.locked\n}\n\nconst activePropertyTab = ref<'element' | 'page'>('page')\nwatch(selectedElement, (el) => {\n activePropertyTab.value = el ? 'element' : 'page'\n})\n\n/** 双击可打开表达式编辑器的元素类型 → 对应表达式字段(无内容表达式的类型不在此列) */\nconst DBL_EDITABLE_FIELD: Record<string, string> = {\n text: 'formatter',\n longText: 'formatter',\n barcode: 'formatter',\n qrcode: 'formatter',\n}\nconst dblEditorVisible = ref(false)\nconst dblEditTarget = ref<\n { kind: 'element'; element: RuntimeElement; field: string } | { kind: 'cell'; cell: TableCell } | null\n>(null)\nconst dblEditorExpression = ref('')\n\nfunction onDblClickElement(id: string) {\n const el = elements.value.find(e => e.id === id)\n if (!el) return\n select(id, false)\n activePropertyTab.value = 'element'\n // 锁定元素不弹编辑器(保持选中,避免绕过锁定护栏)\n if (el.options.locked) return\n const field = DBL_EDITABLE_FIELD[el.printElementType.type]\n if (!field) return\n dblEditTarget.value = { kind: 'element', element: el, field }\n dblEditorExpression.value = (el.options as any)[field] || ''\n dblEditorVisible.value = true\n}\n\nfunction onDblClickCell(elId: string, r: number, c: number) {\n const el = elements.value.find(e => e.id === elId)\n if (!el) return\n select(elId, false)\n activePropertyTab.value = 'element'\n if (el.options.locked) return\n const rows = el.options.tableRows ?? []\n const main = findMainCell(rows, r, c)\n const cell = rows[main.r]?.cells[main.c]\n if (!cell) return\n dblEditTarget.value = { kind: 'cell', cell }\n dblEditorExpression.value = cell.formatter || ''\n dblEditorVisible.value = true\n}\n\nfunction onDblEditorConfirm(value: string) {\n const t = dblEditTarget.value\n if (t?.kind === 'element') {\n ;(t.element.options as any)[t.field] = value || undefined\n } else if (t?.kind === 'cell') {\n t.cell.formatter = value || undefined\n }\n recordHistory()\n dblEditorVisible.value = false\n dblEditTarget.value = null\n}\n\n/** Alt+拖拽克隆元素:将克隆元素添加到元素池并选中 */\nfunction onCloneElement(el: RuntimeElement, _pos: { left: number; top: number }) {\n elements.value.push(el)\n select(el.id, false)\n recordHistory()\n}\n\nwatch(() => props.initialTemplate, (t) => {\n if (t) loadTemplate(t, props.initialElements)\n})\nwatch(() => props.initialElements, (els) => {\n if (els && !props.initialTemplate) {\n templateData.value = {\n ...templateData.value,\n elements: els.map(e => ({ ...e, options: { ...e.options }, printElementType: { ...e.printElementType } })),\n }\n }\n})\nwatch(() => props.fields, (f) => { fields.value = f || [] })\n\ndefineExpose({ getTemplateJson })\n\nasync function handleLoadDefault() {\n if (!props.loadDefaultTemplate) return\n if (!confirm('将覆盖当前画布内容,是否继续?')) return\n try {\n const tpl = await props.loadDefaultTemplate()\n if (!tpl) {\n alert('未获取到默认布局')\n return\n }\n loadTemplate(tpl)\n alert('默认布局已加载')\n } catch {\n alert('加载默认布局失败')\n }\n}\n\nfunction handleSave() {\n emit('save', JSON.stringify(getTemplateJson()))\n markSaved()\n}\n</script>\n\n<style scoped>\n.designer-container {\n /* ── 精工排版工作台令牌:冷灰底 + 白纸 + 蓝墨点缀 ── */\n --pd-bg: #f3f5f9; /* 应用底色 / 内嵌控件底 */\n --pd-surface: #ffffff; /* 工具栏、状态栏、面板表面 */\n --pd-field-bg: #f4f6fa; /* 卡片、内嵌输入槽 */\n --pd-sidebar: #ffffff;\n --pd-sidebar-hover: #f0f3f9;\n --pd-canvas-bg: #e6e9f0; /* 排版垫:略深,托起纸张 */\n --pd-paper: #FFFFFF;\n --pd-accent: #165DFF;\n --pd-accent-2: #3D7BFF;\n --pd-accent-soft: rgba(22, 93, 255, .09);\n --pd-accent-secondary: #f56c6c;\n --pd-danger-soft: rgba(245, 108, 108, .10);\n --pd-ink-green: #67c23a;\n --pd-text: #2a2e37;\n --pd-text-muted: #8b909c;\n --pd-text-faint: #b4b9c4;\n --pd-border: #d9dde6;\n --pd-border-soft: #e9ecf2;\n --pd-handle: #165DFF;\n --pd-ruler: #9aa1af;\n --pd-ruler-bg: #f8f9fc;\n --pd-ruler-cursor: #165DFF;\n --pd-radius: 6px;\n --pd-shadow-sm: 0 1px 2px rgba(23, 32, 60, .05);\n --pd-shadow-md: 0 2px 8px rgba(23, 32, 60, .06), 0 10px 28px rgba(23, 32, 60, .07);\n --pd-shadow-paper: 0 0 0 1px rgba(23, 32, 60, .05),\n 0 1px 2px rgba(23, 32, 60, .06),\n 0 8px 20px rgba(23, 32, 60, .08),\n 0 26px 60px rgba(23, 32, 60, .15);\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--pd-bg);\n}\n.designer-body {\n flex: 1;\n display: flex;\n overflow: hidden;\n}\n</style>\n","// print-canvas/src/render/browser-pagination.ts\n// 浏览器内两遍渲染:隐藏 iframe 写入测量 HTML → 读取元素实测高度 →\n// 复用 print-core 分页算法 → 生成最终多页 HTML(与 print-render 的 pdf-render 同款逻辑)。\n\nimport {\n bindData,\n generateHtml,\n paginate,\n getPaperDimensions,\n} from '@worm-vue3-print/core'\nimport type {\n PrintTemplateData,\n MeasuredElement,\n PageLayout,\n CodeRenderer,\n} from '@worm-vue3-print/core'\n\n/** 96dpi 下 1mm ≈ 3.78px(与服务端 page.evaluate 一致) */\nconst PX_PER_MM = 3.7795275591\n/** 字体/图片等待兜底超时 */\nconst READY_TIMEOUT_MS = 3000\n\nexport interface BrowserRenderResult {\n /** 最终多页 HTML 字符串 */\n html: string\n /** 总页数 */\n pageCount: number\n /** 分页布局(调试/高级用途) */\n pageLayouts: PageLayout[]\n}\n\n/**\n * 浏览器内完成「数据绑定 → 测量 → 分页 → 最终 HTML」全流程。\n * @param template 模板 JSON(设计器 TemplateData 结构兼容)\n * @param printData 业务数据\n * @param baseUrl 图片相对路径拼接前缀\n * @param codeRenderer 条码渲染器(browserCodeRenderer)\n */\nexport async function renderHtmlPages(\n template: PrintTemplateData,\n printData?: Record<string, any> | Record<string, any>[],\n baseUrl?: string,\n codeRenderer?: CodeRenderer,\n): Promise<BrowserRenderResult> {\n // Step 1: 数据绑定\n const boundTemplate = bindData(template, printData, baseUrl)\n\n // Step 2: 第一遍测量(隐藏 iframe)\n const measuredElements = await measureElements(boundTemplate, codeRenderer)\n\n // Step 3: 分页计算(与服务端同一套算法)\n const pageLayouts = paginate(boundTemplate, measuredElements)\n\n // Step 4: 最终多页 HTML\n const html = generateHtml(boundTemplate, pageLayouts, printData as Record<string, any>, {\n codeRenderer,\n })\n\n return { html, pageCount: pageLayouts.length, pageLayouts }\n}\n\n// ─── 隐藏 iframe 测量 ───\n\n/** 渲染测量模式 HTML 到离屏 iframe,读取每个元素的实际高度(mm) */\nasync function measureElements(\n template: PrintTemplateData,\n codeRenderer?: CodeRenderer,\n): Promise<Map<string, MeasuredElement>> {\n const paper = getPaperDimensions(template)\n const measureHtml = generateHtml(template, [], undefined, {\n isMeasurementPass: true,\n codeRenderer,\n })\n\n const iframe = document.createElement('iframe')\n iframe.setAttribute('aria-hidden', 'true')\n // 禁用 display:none(会导致 offsetHeight=0);移出视口 + 不可见即可\n iframe.style.cssText =\n `position:fixed;left:-10000px;top:0;width:${paper.width}mm;height:${paper.height}mm;` +\n 'border:0;visibility:hidden;pointer-events:none;'\n document.body.appendChild(iframe)\n\n try {\n const win = iframe.contentWindow\n const doc = iframe.contentDocument\n if (!win || !doc) throw new Error('无法创建测量 iframe')\n\n doc.open()\n doc.write(measureHtml)\n doc.close()\n\n await waitForRenderReady(win)\n\n const measurements = readMeasurements(doc)\n\n // 转换为 Map(表格元素补算重复表头段高度),与服务端 pdf-render 一致\n const measuredMap = new Map<string, MeasuredElement>()\n const elementIndex = new Map(template.elements.map(el => [el.id, el]))\n for (const m of measurements) {\n const el = elementIndex.get(m.id)\n const repeatCount: number = el?.options?._repeatHeaderCount ?? 0\n measuredMap.set(m.id, {\n id: m.id,\n measuredHeight: m.height,\n measuredRowHeights: m.rowHeights,\n repeatHeaderHeight: m.rowHeights && repeatCount > 0\n ? m.rowHeights.slice(0, repeatCount).reduce((s: number, h: number) => s + h, 0)\n : 0,\n })\n }\n return measuredMap\n } finally {\n iframe.remove()\n }\n}\n\n/** 等待 iframe 文档加载完成、字体就绪、图片解码完成(带超时兜底) */\nfunction waitForRenderReady(win: Window): Promise<void> {\n return new Promise(resolve => {\n let settled = false\n const finish = () => {\n if (!settled) {\n settled = true\n resolve()\n }\n }\n const timer = setTimeout(finish, READY_TIMEOUT_MS)\n\n const run = async () => {\n try {\n const fonts = (win.document as Document & { fonts?: FontFaceSet }).fonts\n if (fonts?.ready) {\n await Promise.race([fonts.ready, timeout(READY_TIMEOUT_MS)])\n }\n await Promise.race([waitForImages(win.document), timeout(READY_TIMEOUT_MS)])\n } catch {\n // 测量兜底:即使资源加载失败也继续\n } finally {\n clearTimeout(timer)\n finish()\n }\n }\n\n if (win.document.readyState === 'complete') {\n void run()\n } else {\n win.addEventListener('load', () => void run(), { once: true })\n // load 事件意外缺失时兜底\n setTimeout(finish, READY_TIMEOUT_MS)\n }\n })\n}\n\nfunction timeout(ms: number): Promise<never> {\n return new Promise((_resolve, reject) => setTimeout(() => reject(new Error('timeout')), ms))\n}\n\n/** 等待文档内全部图片完成(成功或失败均放行) */\nfunction waitForImages(doc: Document): Promise<void> {\n const imgs = Array.from(doc.images ?? [])\n return Promise.all(\n imgs.map(img =>\n img.complete\n ? Promise.resolve()\n : new Promise<void>(resolve => {\n img.addEventListener('load', () => resolve(), { once: true })\n img.addEventListener('error', () => resolve(), { once: true })\n }),\n ),\n ).then(() => undefined)\n}\n\n/** 读取 [data-measure-id] 元素高度与表格行高(逻辑同服务端 page.evaluate) */\nfunction readMeasurements(doc: Document): Array<{\n id: string\n height: number\n rowHeights?: number[]\n}> {\n const result: Array<{ id: string; height: number; rowHeights?: number[] }> = []\n const elements = doc.querySelectorAll('[data-measure-id]')\n for (const el of elements) {\n const htmlEl = el as HTMLElement\n const id = htmlEl.getAttribute('data-measure-id')\n if (!id) continue\n const heightPx = htmlEl.offsetHeight\n\n const table = htmlEl.querySelector('table.print-table')\n if (table) {\n const rowHeights: number[] = []\n const rows = table.querySelectorAll('tbody > tr[data-row-index]')\n for (const row of rows) {\n rowHeights.push((row as HTMLElement).offsetHeight / PX_PER_MM)\n }\n result.push({ id, height: heightPx / PX_PER_MM, rowHeights })\n } else {\n result.push({ id, height: heightPx / PX_PER_MM })\n }\n }\n return result\n}\n","// print-canvas/src/render/browser-code-renderer.ts\n// 浏览器侧 CodeRenderer:jsbarcode(条形码)+ qrcode(二维码矩阵拼 SVG),纯前端无服务依赖。\n\nimport JsBarcode from 'jsbarcode'\nimport QRCode from 'qrcode'\nimport type { CodeRenderer, CodeRenderOptions } from '@worm-vue3-print/core'\n\nconst SVG_NS = 'http://www.w3.org/2000/svg'\n\n/** 条形码:jsbarcode 渲染到离体 SVG 元素,取 outerHTML */\nfunction renderBarcodeSvg(value: string, opts: CodeRenderOptions): string {\n const svg = document.createElementNS(SVG_NS, 'svg') as SVGSVGElement\n JsBarcode(svg as unknown as SVGElement, value, {\n format: (opts.barcodeType || 'CODE128') as unknown as string,\n width: Math.max(1, (opts.barWidth ?? 2) / 2),\n height: 30,\n displayValue: opts.showText !== false,\n fontSize: opts.fontSize ?? 10,\n margin: 0,\n marginBottom: 2,\n })\n return svg.outerHTML\n}\n\n/** 二维码:QRCode.create 同步取模块矩阵,拼接 SVG(静态白边 4 模块) */\nfunction renderQrSvg(value: string, opts: CodeRenderOptions): string {\n const level = (opts.qrCodeLevel ?? 'M').toUpperCase()\n const qr = QRCode.create(value, {\n errorCorrectionLevel: (['L', 'M', 'Q', 'H'].includes(level) ? level : 'M') as 'L' | 'M' | 'Q' | 'H',\n })\n const modules = qr.modules\n const size = modules.size\n const dot = 4\n const quiet = 4 * dot\n const dim = size * dot + quiet * 2\n let rects = ''\n for (let y = 0; y < size; y++) {\n for (let x = 0; x < size; x++) {\n if (modules.get(x, y)) {\n rects += `<rect x=\"${quiet + x * dot}\" y=\"${quiet + y * dot}\" width=\"${dot}\" height=\"${dot}\" fill=\"#000\"/>`\n }\n }\n }\n return `<svg xmlns=\"${SVG_NS}\" viewBox=\"0 0 ${dim} ${dim}\" width=\"${dim}\" height=\"${dim}\" shape-rendering=\"crispEdges\">${rects}</svg>`\n}\n\n/** 浏览器条码/二维码渲染器;码值非法或为空时抛错,由渲染管线降级文本占位 */\nexport const browserCodeRenderer: CodeRenderer = {\n render(value: string, cellType: 'barcode' | 'qrcode', opts: CodeRenderOptions = {}): string {\n if (!value) throw new Error('empty barcode value')\n return cellType === 'qrcode' ? renderQrSvg(value, opts) : renderBarcodeSvg(value, opts)\n },\n}\n","<!--\n PrintHtmlPreview:浏览器端 HTML 打印预览(不依赖服务端 PDF)。\n 内部完成 数据绑定 → 隐藏 iframe 测量 → 分页 → 多页 HTML 渲染;\n 父组件通过 ref 调用 print() 触发浏览器原生打印(@page 控制纸张与分页)。\n-->\n<template>\n <div class=\"print-html-preview\">\n <div v-if=\"errorMsg\" class=\"print-html-preview-error\">\n <span>预览渲染失败:{{ errorMsg }}</span>\n </div>\n <div v-else-if=\"rendering\" class=\"print-html-preview-loading\">预览渲染中…</div>\n <iframe\n v-show=\"!rendering && !errorMsg\"\n ref=\"iframeRef\"\n class=\"print-html-preview-iframe\"\n title=\"打印预览\"\n />\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch, onBeforeUnmount } from 'vue'\nimport type { PrintTemplateData } from '@worm-vue3-print/core'\nimport { renderHtmlPages } from '../render/browser-pagination'\nimport { browserCodeRenderer } from '../render/browser-code-renderer'\n\nconst props = defineProps<{\n /** 模板 JSON(设计器 TemplateData 结构兼容) */\n templateJson?: Record<string, any> | null\n /** 业务打印数据 */\n printData?: Record<string, any> | Record<string, any>[]\n /** 图片相对路径拼接前缀(与服务端 baseUrl 同源) */\n baseUrl?: string\n}>()\n\nconst emit = defineEmits<{\n /** 渲染完成,回传总页数 */\n rendered: [pageCount: number]\n /** 渲染失败 */\n error: [message: string]\n}>()\n\nconst iframeRef = ref<HTMLIFrameElement>()\nconst rendering = ref(false)\nconst errorMsg = ref('')\n/** 渲染序列:过期的渲染结果丢弃,避免快速重渲染竞态 */\nlet renderSeq = 0\n\nasync function rerender() {\n if (!props.templateJson) {\n errorMsg.value = ''\n rendering.value = false\n return\n }\n const seq = ++renderSeq\n rendering.value = true\n errorMsg.value = ''\n try {\n const { html, pageCount } = await renderHtmlPages(\n props.templateJson as PrintTemplateData,\n props.printData,\n props.baseUrl,\n browserCodeRenderer,\n )\n if (seq !== renderSeq) return\n const doc = iframeRef.value?.contentWindow?.document\n if (doc) {\n doc.open()\n doc.write(html)\n doc.close()\n }\n emit('rendered', pageCount)\n } catch (e) {\n if (seq !== renderSeq) return\n errorMsg.value = e instanceof Error ? e.message : '未知错误'\n emit('error', errorMsg.value)\n } finally {\n if (seq === renderSeq) rendering.value = false\n }\n}\n\n/** 触发浏览器原生打印(iframe 内 @page 规则控制纸张尺寸与分页) */\nfunction print() {\n const win = iframeRef.value?.contentWindow\n if (!win) return\n win.focus()\n win.print()\n}\n\nwatch(\n () => [props.templateJson, props.printData, props.baseUrl],\n () => void rerender(),\n { immediate: true, deep: true },\n)\n\nonBeforeUnmount(() => {\n renderSeq++\n})\n\ndefineExpose({ print, rerender })\n</script>\n\n<style scoped>\n.print-html-preview {\n width: 100%;\n height: 100%;\n position: relative;\n background: #e9ebee;\n}\n.print-html-preview-iframe {\n width: 100%;\n height: 100%;\n border: 0;\n background: #fff;\n}\n.print-html-preview-loading,\n.print-html-preview-error {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #909399;\n font-size: 14px;\n}\n.print-html-preview-error {\n color: #f56c6c;\n}\n</style>\n"],"names":["createCellIdGenerator","seq","createRowIdGenerator","genCellId","genRowId","DEFAULT_BORDER","deepClone","v","createCell","partial","createDefaultTable","colWidths","mk","type","repeat","header","c","findMainCell","rows","r","ri","ci","cell","rs","cs","getSpanRect","main","normalizeSelection","a","b","rect","changed","span","merged","canMergeReason","types","norm","mergeCells","contents","splitCells","styleSrc","sr","sc","t","copyCellStyle","src","dst","insertRow","index","position","insertAt","ref","colCount","newRow","deleteRow","row","next","insertCol","newCell","deleteCol","setRowType","existing","i","dataIdx","applyBorderPreset","preset","border","atTop","atBottom","atLeft","atRight","GHOST_BORDER_CSS","resolveCellBorderCss","opts","syncTableElementSize","options","wMm","s","w","hMm","generateId","createDefaultOptions","base","totalW","totalH","createRuntimeElement","typeMetaMap","engine","TemplateEngine","getDemoData","DEFAULT_DEMO_DATA","EXTENDED_FUNCTIONS","formatMoney","args","ifFn","value","str","start","len","num","decimals","defaultVal","char","from","to","formatDate","toUpperCaseAmount","name","fn","aggregate","field","sum","avg","count","min","max","evaluateTemplate","text","ctx","processedText","_match","inner","expr","_m","arg","createFieldElement","resolveTextBinding","data","lookupDemoPath","path","cur","seg","resolveBarcodeDesignValue","formatter","listSource","first","_","key","ptToMm","pt","pxToMm","px","PT_KEYS","convertElement","el","round2","n","normalizeTemplateUnits","convert","els","PAPER_PRESETS","getPaperDimensions","computeFitScale","containerW","containerH","paperW","paperH","ratio","fit","pct","ZONE_ALLOWED_TYPES","getPaperSizeMM","getZoneRects","paper","m","headerH","footerH","contentW","contentH","l","tp","h","zoneFromPaperPoint","_x","y","clampToZone","zone","o","finalizeElementZone","rects","fromZone","cx","cy","target","rejected","SELECTED_IDS_KEY","PREVIEW_IDS_KEY","useSelection","elements","selectedIds","previewIds","selectedElements","computed","e","hasSelection","select","id","multiple","clearSelection","selectAll","allIds","setPreview","ids","clearPreview","commitPreview","getSelectionBounds","minL","minT","maxR","maxB","useClipboard","clipboard","copy","paste","offset","item","hasData","useAlign","align","mode","bounds","centerX","centerY","sorted","gap","x","generateGroupId","useGroup","group","groupId","ungroup","selected","groupIds","getGroupedIds","selectedId","useHistory","undoStack","redoStack","canUndo","canRedo","updateFlags","clone","state","cloneState","push","undo","currentState","popped","redo","clear","STEP","STEP_LARGE","STEP_SMALL","useKeyboard","handlers","onKeyDown","tag","ctrl","step","dx","dy","k","setup","cleanup","createDefaultTemplate","toRuntimePool","useDesignerState","scale","showGrid","snapToGrid","showTableGhostBorder","templateData","fields","selectAllIds","groupElements","ungroupElements","copyElements","pasteElements","hasClipboardData","pushHistory","undoHistory","redoHistory","selectedElement","tableSelection","setTableSelection","getHistoryState","recordHistory","cutSelected","deleteSelected","pasted","duplicateSelected","resetZoom","hasClipboard","moveSessionActive","moveDebounceTimer","MOVE_SESSION_GAP_MS","moveSelected","movable","alignSelected","groupSelected","ungroupSelected","setupKeyboard","cleanupKeyboard","draggingBeforeState","dragStart","dragStop","before","prev","sig","beforeIds","afterIds","placeAtDropPoint","dropPoint","addElement","addFieldElement","moveLayer","direction","currentZ","allZ","maxZ","minZ","fitToWindow","width","height","MM_TO_PX","updateTemplateData","getTemplateJson","all","ser","loadTemplate","migrated","onMounted","onUnmounted","guideSeq","genId","useGuides","guides","mutate","addGuide","list","moveGuide","g","removeGuide","getGuidePositions","TABLE_EDIT_KEY","UPLOAD_IMAGE_KEY","_useModel","__props","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","$emit","_hoisted_3","_hoisted_4","_toDisplayString","_cache","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_normalizeClass","_hoisted_13","_hoisted_14","_hoisted_15","props","sortedLayers","elementIconMap","layerIcon","layerName","zoneTag","_Fragment","_renderList","layer","$event","groupFields","groupMap","groupOrder","f","dot","groups","standalone","filterGroups","keyword","kw","emit","__emit","searchText","collapsedGroups","searching","filteredGroups","toggleGroup","onDragStart","event","_normalizeStyle","activeTab","elementTypes","onFieldDrag","expandTab","tab","_withDirectives","_createVNode","FieldTreePanel","LayerPanel","d","useDrag","isDragging","dragPreview","startX","startY","startLeft","startTop","downAltKey","onMouseDown","targetEl","onMouseMove","onMouseUp","computePos","newLeft","newTop","result","pos","RESIZE_POINTS","calcResizeRect","point","startRect","minW","minH","left","top","useResize","activePoint","startResize","onResizeMove","onResizeEnd","getNestedValue","obj","current","useBindingDisplay","getBindingDisplayState","element","title","demoData","fieldMatch","fieldPath","demoValue","V_ALIGN_FLEX","H_ALIGN_FLEX","textStyle","displayText","imageSrc","raw","hasError","onError","watch","imgStyle","ROW_TYPES","emitAction","payload","_createBlock","_Teleport","barcodeSvg","svgOk","dataUrl","renderBarcode","JsBarcode","renderQrcode","QRCode","render","_vShow","PX_PER_MM","HEIGHT_EPSILON_MM","ROW_TYPE_BADGE","editCtx","inject","defaultFontSize","defaultColor","selection","rowTopMm","tableRef","rowLayoutMm","measureTable","table","tableHpx","tableHmm","baseTop","tr","badgeTopMm","badgeHeightMm","demoList","ds","isCodeCell","cellDisplay","_row","cellStyle","borderOpts","cellClass","dragAnchor","applySelection","onCellMouseDown","onCellMouseEnter","onCellDblClick","menu","reactive","onCellContextMenu","mergeReason","canSplit","rowTypeReason","cloned","syncElementSize","checkColWidthLimit","cw","maxW","onMenuAction","err","_withModifiers","CellBarcode","TableContextMenu","isHline","lineStyle","bw","bs","bc","isOval","shapeStyle","svgRef","showText","fontSizePx","totalPx","textH","barH","size","htmlContent","DOMPurify","elRef","injectedSelectedIds","isSelected","injectedPreviewIds","isPreviewed","componentMap","markRaw","TextElement","ImageElement","LongTextElement","TableElement","LineElement","ShapeElement","BarcodeElement","QrcodeElement","HtmlElement","PageNumberElement","bindingState","contentComponent","contentAttrs","elementStyle","posLabel","dragStartLeft","dragStartTop","dragConfig","info","finalDx","finalDy","sibling","setupDrag","cleanupDrag","watchEffect","resizeEnabled","cleanupResize","onDblClick","onDblClickCell","elementId","_unref","_resolveDynamicComponent","_mergeProps","p","buildRulerTicks","lengthMM","ticks","mm","rounded","major","THICKNESS","canvasRef","cssSize","draw","canvas","dpr","lengthPx","horizontal","style","bg","fg","tick","dragging","onDown","onMove","onUp","posMM","useAdsorb","config","adsorbMin","adsorbLineMin","showAdsorbLine","guideLines","paperSize","SNAP_COLORS","snapColor","check","movingRect","others","lines","minDist","other","hPairs","vPairs","ok","dist","m2","hKeys","vKeys","adjustedM","seen","renderLines","clearLines","useAdsorbManager","requestAdsorb","clearGuides","contentRef","paperWidthMM","paperHeightMM","zoneRectsMM","layerStyle","zoneElements","headerElements","footerElements","contentElements","currentDragZone","rawRequestAdsorb","guidePaperSize","showSnapIndicator","onGuideDown","startPt","MM_PER_PX","ev","delta","paperStyle","contentStyle","showRulerComputed","gridBgStyle","snapSeq","snapTimer","snapIndicator","watermarkVisible","watermarkStyle","color","opacity","rotate","getWatermarkText","now","ts","buildWatermarkSvg","printData","escaped","svg","zoneResizing","startZoneResize","cleanupZoneResize","onZoneResizeMove","onZoneResizeUp","startH","dyMM","maxH","onSelectElement","__expose","Ruler","BaseElement","line","idx","rootRef","toPaperPoint","onDrop","fieldData","elementType","marquee","marqueeStart","isCanvasBackground","xMm","yMm","onMouseLeave","onWheel","oldScale","newScale","container","mouseX","mouseY","onCanvasMouseDown","onMarqueeMove","onMarqueeUp","hitTestIds","paperRect","containMode","elLeft","elTop","elRight","elBottom","inter","contained","contextMenu","onContextMenu","elId","containerRect","closeContextMenu","handlePaste","handleSelectAll","handleClearSelection","action","onBeforeUnmount","CanvasPaper","PROPERTY_REGISTRY","matchKeywords","search","keywords","searchProperties","itemKeys","matched","onSearch","isExpanded","iconChar","toggle","saveState","loadState","saved","_renderSlot","_ctx","showItem","PropertyGroup","PRESET_COLORS","visible","triggerRef","panelRef","areaRef","panelStyle","hue","saturation","hexInput","areaDragging","normalizedValue","activeColor","rgbToHex","hsvToRgb","hueModel","degree","setHsv","clampDegree","syncFromColor","onHexInput","parseHex","normalizeHex","rgb","hsv","rgbToHsv","clamp01","startAreaDrag","setAreaFromEvent","moveAreaDrag","endAreaDrag","area","onAreaKeydown","handled","close","open","trigger","nextTick","panelWidth","panelHeight","margin","below","onDocumentPointerDown","onWindowCloseEvents","onKeydown","match","hex","full","part","red","green","blue","hh","r1","g1","b1","number","isTableType","PresetColorPicker","_hoisted_16","_hoisted_17","_hoisted_18","val","searchPlaceholder","selectedFields","toggleField","localExpression","found","handleFieldDoubleClick","insertAtCursor","handleAggregateDoubleClick","handleItemDoubleClick","filteredSystemVars","systemVars","sv","filteredAggregateFuncs","aggregateFunctions","filteredFormatFuncs","formatFunctions","textareaRef","previewResult","ta","end","after","onConfirm","_hoisted_19","_hoisted_20","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_26","_hoisted_27","_hoisted_28","_hoisted_29","_hoisted_30","_hoisted_31","editorVisible","openEditor","ExpressionEditor","tableEditCtx","listFieldOptions","onSourceChange","onColWidthChange","widths","othersW","clamped","isTable","tablePaginationEnabled","onTablePaginationChange","checked","paginationPageable","paginationKeepWithNext","onPageableChange","onKeepWithNextChange","uploading","uploadImage","uploadDisabled","handleFileChange","input","file","url","onTypeChange","onHeightChange","onRepeatChange","mainCell","formatterEditorVisible","pendingFormatterValue","isBarcodeCell","isQrcodeCell","onAlignChange","write","onValignChange","onCellTypeChange","openFormatterEditor","onFormatterEditorConfirm","borderStyle","borderWidth","borderColor","edgeChecks","currentBorder","onEdgesChange","edges","nb","side","doMerge","doSplit","_hoisted_21","_hoisted_25","_hoisted_33","_hoisted_34","_hoisted_36","_hoisted_38","_hoisted_40","_hoisted_41","_hoisted_42","_hoisted_43","_hoisted_44","_hoisted_45","_hoisted_46","_hoisted_47","_hoisted_48","_hoisted_49","_hoisted_51","_hoisted_53","_hoisted_54","_hoisted_55","ELEMENT_BINDING_REGISTRY","getTableCellBindings","rowType","rowIndex","cellIndex","listField","getElementBindings","staticBindings","dynamicBindings","paperPresets","isTextType","isImageType","isTableCellSelected","searchResult","matchedKeys","bindingDescriptors","c1","parsePath","targetPath","segment","baseName","indices","getBindingValue","setBindingValue","segments","lastKey","onImageUploadSuccess","paperSizeModel","orientationModel","marginTop","marginBottom","marginLeft","marginRight","headerHeight","footerHeight","overlayHeight","customWidth","customHeight","emitUpdate","onPaperSizeChange","onOrientationChange","onCustomWidthChange","onCustomHeightChange","onMarginTopChange","onMarginBottomChange","onMarginLeftChange","onMarginRightChange","onHeaderHeightChange","onFooterHeightChange","onOverlayHeightChange","currentTab","PropertySearch","PositionSizeGroup","AppearanceGroup","desc","BindingControl","ImageContentUpload","TableRowGroup","TableCellGroup","TableSettingsGroup","BorderBgGroup","PaginationGroup","AdvancedGroup","_ps","_hoisted_35","LEFT_KEY","RIGHT_KEY","readStored","fallback","useStudioChrome","leftCollapsed","rightCollapsed","dirty","toggleLeft","toggleRight","markSaved","onUndo","onRedo","onAlign","onGroup","onUngroup","onDeleteElement","onDragStop","onDropElement","onDropField","onMoveLayer","maxTableWidth","provide","canvasAreaRef","overlayVisible","screenshotUrl","overlayOpacity","toggleOverlay","templateJson","blob","coordinate","onCoordinate","paperLabel","dim","orient","onFitWindow","onZoom","onKeyFitWindow","onTemplateDataChanged","prevHeader","prevFooter","onZoneHeightChange","onZoneHeightCommit","warnZoneOverflow","onAddOverlayElement","overlay","newEl","onToggleVisible","onToggleLocked","activePropertyTab","DBL_EDITABLE_FIELD","dblEditorVisible","dblEditTarget","dblEditorExpression","onDblClickElement","onDblEditorConfirm","onCloneElement","_pos","handleLoadDefault","tpl","handleSave","DesignerToolbar","LeftPanel","CanvasArea","PropertyPanel","StatusBar","READY_TIMEOUT_MS","renderHtmlPages","template","baseUrl","codeRenderer","boundTemplate","bindData","measuredElements","measureElements","pageLayouts","paginate","generateHtml","measureHtml","iframe","win","doc","waitForRenderReady","measurements","readMeasurements","measuredMap","elementIndex","repeatCount","resolve","settled","finish","timer","run","fonts","timeout","waitForImages","ms","_resolve","reject","imgs","img","htmlEl","heightPx","rowHeights","SVG_NS","renderBarcodeSvg","renderQrSvg","level","modules","quiet","browserCodeRenderer","cellType","iframeRef","rendering","errorMsg","renderSeq","rerender","html","pageCount","print"],"mappings":"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"}
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 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 clampScalePercent(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')\" 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: showRuler }\" title=\"显示/隐藏标尺\" @click=\"$emit('toggle-ruler')\">\n <span class=\"dot\" /> 标尺\n </button>\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 <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}>(), {\n showRuler: 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: 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","// 标尺刻度纯函数:步长选择与可见范围刻度生成\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 } 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\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\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 /* 制图垫:略深冷灰 + 极淡点阵,让白纸浮起 */\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 margin: 0 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.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 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 { clampScalePercent } 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}>()\n\nconst emit = defineEmits<{\n preview: []\n save: [json: string]\n}>()\n\n// 帮助文档状态\nconst helpVisible = ref(false)\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, 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 = clampScalePercent(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","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","removeGuide","g","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","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","onCanvasMouseDown","onMarqueeMove","onMarqueeUp","hitTestIds","paperRect","containMode","elLeft","elTop","elRight","elBottom","inter","contained","contextMenu","onContextMenu","elId","containerRect","closeContextMenu","handlePaste","handleSelectAll","handleClearSelection","action","CanvasPaper","p","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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"}