@worm-vue3-print/core 1.2.0 → 1.2.2
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/README.md +97 -0
- package/dist/browser/index.cjs +1920 -0
- package/dist/browser/index.d.cts +23 -0
- package/dist/browser/index.d.ts +23 -0
- package/dist/browser/index.js +170 -0
- package/dist/chunk-HLCZHPUF.js +31 -0
- package/dist/chunk-JZIVNXZ7.js +1777 -0
- package/dist/designer/index.cjs +2419 -0
- package/dist/designer/index.d.cts +652 -0
- package/dist/designer/index.d.ts +652 -0
- package/dist/designer/index.js +1620 -0
- package/dist/index.d.cts +4 -184
- package/dist/index.d.ts +4 -184
- package/dist/index.js +36 -1764
- package/dist/types-BGBAbQD5.d.cts +184 -0
- package/dist/types-BGBAbQD5.d.ts +184 -0
- package/package.json +21 -4
|
@@ -0,0 +1,652 @@
|
|
|
1
|
+
import { TemplateEngine, formatMoney, ifFn, formatDate, toUpperCaseAmount } from '../index.cjs';
|
|
2
|
+
import '../types-BGBAbQD5.cjs';
|
|
3
|
+
|
|
4
|
+
/** 纸张尺寸 */
|
|
5
|
+
type PaperSize = 'A4' | 'A3' | 'A5' | 'Letter' | 'Legal' | 'CUSTOM';
|
|
6
|
+
/** 元素所属区域(运行时标记,序列化时剥离;区域元素 left/top 相对所在区域左上角,单位 pt) */
|
|
7
|
+
type ElementZone = 'content' | 'header' | 'footer';
|
|
8
|
+
/** 元素分页属性(非表格元素) */
|
|
9
|
+
interface PaginationConfig {
|
|
10
|
+
pageable: boolean;
|
|
11
|
+
keepWithNext: boolean;
|
|
12
|
+
}
|
|
13
|
+
/** 表格分页配置 */
|
|
14
|
+
interface TablePaginationConfig {
|
|
15
|
+
enabled: boolean;
|
|
16
|
+
}
|
|
17
|
+
/** 新模板数据模型(替代旧 PrintPanel / PrintTemplateJson) */
|
|
18
|
+
interface TemplateData {
|
|
19
|
+
paperSize: PaperSize;
|
|
20
|
+
orientation: 'portrait' | 'landscape';
|
|
21
|
+
margins: {
|
|
22
|
+
top: number;
|
|
23
|
+
right: number;
|
|
24
|
+
bottom: number;
|
|
25
|
+
left: number;
|
|
26
|
+
};
|
|
27
|
+
header: {
|
|
28
|
+
height: number;
|
|
29
|
+
elements: TemplateElement[];
|
|
30
|
+
};
|
|
31
|
+
footer: {
|
|
32
|
+
height: number;
|
|
33
|
+
elements: TemplateElement[];
|
|
34
|
+
};
|
|
35
|
+
firstPageOverlay: {
|
|
36
|
+
height: number;
|
|
37
|
+
elements: TemplateElement[];
|
|
38
|
+
};
|
|
39
|
+
elements: TemplateElement[];
|
|
40
|
+
/** 元素坐标单位(新保存模板固定 'mm';旧数据无此字段按 pt 迁移) */
|
|
41
|
+
unit?: 'pt' | 'mm';
|
|
42
|
+
/** 自定义纸张宽度(mm),仅 paperSize='CUSTOM' 时有效 */
|
|
43
|
+
customWidth?: number;
|
|
44
|
+
/** 自定义纸张高度(mm),仅 paperSize='CUSTOM' 时有效 */
|
|
45
|
+
customHeight?: number;
|
|
46
|
+
/** 页面(纸张)背景色;未设置时默认白色 */
|
|
47
|
+
pageBackground?: string;
|
|
48
|
+
/** 水印配置 */
|
|
49
|
+
watermark?: WatermarkOptions;
|
|
50
|
+
/** 手动参考线(设计态辅助,序列化保留,渲染端忽略) */
|
|
51
|
+
guides?: AlignLine[];
|
|
52
|
+
}
|
|
53
|
+
/** 模板元素引用(用于 TemplateData 各区域) */
|
|
54
|
+
type TemplateElement = PrintElementData;
|
|
55
|
+
/** 元素类型 */
|
|
56
|
+
type ElementType = 'text' | 'image' | 'longText' | 'table' | 'hline' | 'vline' | 'rect' | 'oval' | 'barcode' | 'qrcode' | 'html' | 'pageNumber';
|
|
57
|
+
/** 对齐方式 */
|
|
58
|
+
type TextAlign = 'left' | 'center' | 'right';
|
|
59
|
+
/** 垂直对齐方式(文本类元素,未设置时按顶部处理,与打印端一致) */
|
|
60
|
+
type VerticalAlign = 'top' | 'middle' | 'bottom';
|
|
61
|
+
/** 缩放手柄方向 */
|
|
62
|
+
type ResizePoint = 'nw' | 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w';
|
|
63
|
+
/** 引导线 */
|
|
64
|
+
interface AlignLine {
|
|
65
|
+
type: 'vertical' | 'horizontal';
|
|
66
|
+
position: number;
|
|
67
|
+
id?: string;
|
|
68
|
+
/** 引导线颜色(区分左/中/右对齐类型) */
|
|
69
|
+
color?: string;
|
|
70
|
+
}
|
|
71
|
+
/** 吸附结果 */
|
|
72
|
+
interface AdsorbResult {
|
|
73
|
+
left: number;
|
|
74
|
+
top: number;
|
|
75
|
+
lines: AlignLine[];
|
|
76
|
+
}
|
|
77
|
+
/** 元素矩形(用于吸附检测) */
|
|
78
|
+
interface ElementRect {
|
|
79
|
+
id: string;
|
|
80
|
+
left: number;
|
|
81
|
+
top: number;
|
|
82
|
+
width: number;
|
|
83
|
+
height: number;
|
|
84
|
+
}
|
|
85
|
+
/** 表格行类型:header 标题 / data 数据(全表唯一) / subtotal 当前页小计(每页末尾) / summary 整表汇总 */
|
|
86
|
+
type TableRowType = 'header' | 'data' | 'subtotal' | 'summary';
|
|
87
|
+
/** 单边边框样式 */
|
|
88
|
+
interface TableCellBorder {
|
|
89
|
+
width: number;
|
|
90
|
+
style: 'solid' | 'dashed' | 'dotted' | 'double' | 'none';
|
|
91
|
+
color: string;
|
|
92
|
+
}
|
|
93
|
+
/** 四边边框 */
|
|
94
|
+
interface TableCellBorders {
|
|
95
|
+
top?: TableCellBorder;
|
|
96
|
+
right?: TableCellBorder;
|
|
97
|
+
bottom?: TableCellBorder;
|
|
98
|
+
left?: TableCellBorder;
|
|
99
|
+
}
|
|
100
|
+
/** 单元格内容类型 */
|
|
101
|
+
type TableCellType = 'text' | 'barcode' | 'qrcode' | 'image';
|
|
102
|
+
/** 单元格 */
|
|
103
|
+
interface TableCell {
|
|
104
|
+
id: string;
|
|
105
|
+
formatter?: string;
|
|
106
|
+
cellType?: TableCellType;
|
|
107
|
+
barcodeType?: string;
|
|
108
|
+
qrCodeLevel?: string;
|
|
109
|
+
showBarcodeText?: boolean;
|
|
110
|
+
rowspan?: number;
|
|
111
|
+
colspan?: number;
|
|
112
|
+
merged?: boolean;
|
|
113
|
+
align?: TextAlign;
|
|
114
|
+
valign?: 'top' | 'middle' | 'bottom';
|
|
115
|
+
fontFamily?: string;
|
|
116
|
+
fontSize?: number;
|
|
117
|
+
fontWeight?: string;
|
|
118
|
+
color?: string;
|
|
119
|
+
backgroundColor?: string;
|
|
120
|
+
borders?: TableCellBorders;
|
|
121
|
+
padding?: number;
|
|
122
|
+
wordWrap?: boolean;
|
|
123
|
+
fit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
|
|
124
|
+
maxWidth?: number;
|
|
125
|
+
maxHeight?: number;
|
|
126
|
+
}
|
|
127
|
+
/** 表格行 */
|
|
128
|
+
interface TableRow {
|
|
129
|
+
id: string;
|
|
130
|
+
type: TableRowType;
|
|
131
|
+
height: number;
|
|
132
|
+
repeatOnPage?: boolean;
|
|
133
|
+
cells: TableCell[];
|
|
134
|
+
}
|
|
135
|
+
/** 单元格选区(r/c 均为 0 基,闭区间) */
|
|
136
|
+
interface TableSelection {
|
|
137
|
+
elementId: string;
|
|
138
|
+
r1: number;
|
|
139
|
+
c1: number;
|
|
140
|
+
r2: number;
|
|
141
|
+
c2: number;
|
|
142
|
+
}
|
|
143
|
+
/** 表格历史字段绑定(兼容存量模板,实际取 fields[0].dataSource) */
|
|
144
|
+
interface ElementFieldBinding {
|
|
145
|
+
text?: string;
|
|
146
|
+
dataSource?: string;
|
|
147
|
+
}
|
|
148
|
+
/** 元素选项(序列化到 JSON) */
|
|
149
|
+
interface ElementOptions {
|
|
150
|
+
left: number;
|
|
151
|
+
top: number;
|
|
152
|
+
width: number;
|
|
153
|
+
height: number;
|
|
154
|
+
/** @deprecated 统一使用 formatter */
|
|
155
|
+
title?: string;
|
|
156
|
+
testData?: string;
|
|
157
|
+
fontSize?: number;
|
|
158
|
+
fontWeight?: string;
|
|
159
|
+
fontFamily?: string;
|
|
160
|
+
color?: string;
|
|
161
|
+
backgroundColor?: string;
|
|
162
|
+
textAlign?: TextAlign;
|
|
163
|
+
verticalAlign?: VerticalAlign;
|
|
164
|
+
lineHeight?: number;
|
|
165
|
+
letterSpacing?: number;
|
|
166
|
+
fixed?: boolean;
|
|
167
|
+
locked?: boolean;
|
|
168
|
+
/** 元素可见性(图层面板切换) */
|
|
169
|
+
visible?: boolean;
|
|
170
|
+
borderWidth?: number;
|
|
171
|
+
borderStyle?: string;
|
|
172
|
+
borderColor?: string;
|
|
173
|
+
contentPaddingLeft?: number;
|
|
174
|
+
contentPaddingTop?: number;
|
|
175
|
+
contentPaddingRight?: number;
|
|
176
|
+
contentPaddingBottom?: number;
|
|
177
|
+
textDecoration?: string;
|
|
178
|
+
textType?: 'barcode' | 'qrcode';
|
|
179
|
+
barcodeType?: string;
|
|
180
|
+
barWidth?: number;
|
|
181
|
+
barAutoWidth?: string;
|
|
182
|
+
qrCodeLevel?: string;
|
|
183
|
+
src?: string;
|
|
184
|
+
fit?: string;
|
|
185
|
+
hideTitle?: boolean;
|
|
186
|
+
draggable?: boolean;
|
|
187
|
+
axis?: string;
|
|
188
|
+
transform?: number;
|
|
189
|
+
zIndex?: number;
|
|
190
|
+
groupId?: string;
|
|
191
|
+
pagination?: PaginationConfig;
|
|
192
|
+
tablePagination?: TablePaginationConfig;
|
|
193
|
+
/** @deprecated 静态布局模式已移除,所有表格统一使用动态模式 */
|
|
194
|
+
tableMode?: 'dynamic' | 'static';
|
|
195
|
+
tableRows?: TableRow[];
|
|
196
|
+
tableColWidths?: number[];
|
|
197
|
+
tableDefaultFontSize?: number;
|
|
198
|
+
tableDefaultColor?: string;
|
|
199
|
+
tableDefaultPadding?: number;
|
|
200
|
+
/** 列表数据源路径(data 行迭代的数据数组) */
|
|
201
|
+
dataSource?: string;
|
|
202
|
+
/** @deprecated 兼容存量表格模型;列表数据源优先使用 dataSource */
|
|
203
|
+
fields?: ElementFieldBinding[];
|
|
204
|
+
formatter?: string;
|
|
205
|
+
styler?: string;
|
|
206
|
+
rowStyler?: string;
|
|
207
|
+
longTextIndent?: number;
|
|
208
|
+
leftSpaceRemoved?: boolean;
|
|
209
|
+
lHeight?: number;
|
|
210
|
+
}
|
|
211
|
+
/** 元素类型元数据 */
|
|
212
|
+
interface PrintElementTypeMeta {
|
|
213
|
+
title?: string;
|
|
214
|
+
type: ElementType;
|
|
215
|
+
editable?: boolean;
|
|
216
|
+
formatter?: string;
|
|
217
|
+
styler?: string;
|
|
218
|
+
}
|
|
219
|
+
/** 序列化元素数据 */
|
|
220
|
+
interface PrintElementData {
|
|
221
|
+
id?: string;
|
|
222
|
+
type?: ElementType;
|
|
223
|
+
options: ElementOptions;
|
|
224
|
+
printElementType: PrintElementTypeMeta;
|
|
225
|
+
}
|
|
226
|
+
/** 水印配置 */
|
|
227
|
+
interface WatermarkOptions {
|
|
228
|
+
/** 水印模式:fixed=固定文本,binding=绑定字段 */
|
|
229
|
+
mode?: 'fixed' | 'binding';
|
|
230
|
+
/** 固定文本(mode=fixed 时使用) */
|
|
231
|
+
content?: string;
|
|
232
|
+
/** 绑定字段(mode=binding 时使用) */
|
|
233
|
+
binding?: string;
|
|
234
|
+
/** 测试值(设计态预览使用) */
|
|
235
|
+
testData?: string;
|
|
236
|
+
/** 旋转角度 */
|
|
237
|
+
rotate?: number;
|
|
238
|
+
/** 颜色 */
|
|
239
|
+
color?: string;
|
|
240
|
+
/** 透明度 */
|
|
241
|
+
opacity?: number;
|
|
242
|
+
/** 显示时间戳 */
|
|
243
|
+
timestamp?: boolean;
|
|
244
|
+
/** 时间格式 */
|
|
245
|
+
format?: string;
|
|
246
|
+
}
|
|
247
|
+
/** 运行时元素(设计器中带状态) */
|
|
248
|
+
interface RuntimeElement {
|
|
249
|
+
id: string;
|
|
250
|
+
options: ElementOptions;
|
|
251
|
+
printElementType: PrintElementTypeMeta;
|
|
252
|
+
selected?: boolean;
|
|
253
|
+
/** 运行时所属区域,序列化时剥离,缺省视为 content */
|
|
254
|
+
zone?: ElementZone;
|
|
255
|
+
}
|
|
256
|
+
/** 业务字段(宿主查询后传入,核心不内置字段字典) */
|
|
257
|
+
interface PrintBusinessField {
|
|
258
|
+
id?: string;
|
|
259
|
+
fieldKey: string;
|
|
260
|
+
fieldLabel: string;
|
|
261
|
+
/** 字段类型;'list' 表示明细列表字段(用于表格数据源选择) */
|
|
262
|
+
fieldType: string;
|
|
263
|
+
sortOrder: number;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* 绑定位置描述(用于属性面板自动渲染绑定控件)
|
|
267
|
+
*/
|
|
268
|
+
interface BindingDescriptor {
|
|
269
|
+
/** 绑定的属性路径(如 'options.formatter'、'options.tableRows[0].cells[0].formatter') */
|
|
270
|
+
targetPath: string;
|
|
271
|
+
/** 显示名称 */
|
|
272
|
+
label: string;
|
|
273
|
+
/** 数据源上下文 */
|
|
274
|
+
dataSource: 'main' | 'list' | 'subtotal' | 'summary';
|
|
275
|
+
/** 绑定的列表字段(仅表格行需要) */
|
|
276
|
+
listField?: string;
|
|
277
|
+
/** 提示文本 */
|
|
278
|
+
placeholder?: string;
|
|
279
|
+
/** 是否允许清空 */
|
|
280
|
+
clearable?: boolean;
|
|
281
|
+
}
|
|
282
|
+
/** 截图请求载荷(设计器叠层对比用) */
|
|
283
|
+
interface ScreenshotRequest {
|
|
284
|
+
templateJson: TemplateData;
|
|
285
|
+
printData: Record<string, any>;
|
|
286
|
+
}
|
|
287
|
+
/** 截图适配器:宿主依据模板 + 数据返回 PNG Blob */
|
|
288
|
+
type RequestScreenshotFn = (req: ScreenshotRequest) => Promise<Blob>;
|
|
289
|
+
/** 图片上传适配器:宿主上传文件并返回可访问的图片 URL */
|
|
290
|
+
type UploadImageFn = (file: File) => Promise<string>;
|
|
291
|
+
|
|
292
|
+
/** pt 转 mm */
|
|
293
|
+
declare function ptToMm(pt: number): number;
|
|
294
|
+
/** px 转 mm(基于 96dpi 屏幕) */
|
|
295
|
+
declare function pxToMm(px: number): number;
|
|
296
|
+
/** mm 转 px(基于 96dpi 屏幕) */
|
|
297
|
+
declare function mmToPx(mm: number): number;
|
|
298
|
+
|
|
299
|
+
/** 最小缩放百分比,低于此值画布难以查看与操作;放大方向不设上限 */
|
|
300
|
+
declare const MIN_SCALE_PERCENT = 25;
|
|
301
|
+
/** 适应窗口时允许的最小缩放百分比(可低于交互缩放下限,保证超大纸张也能整版容纳) */
|
|
302
|
+
declare const FIT_SCALE_MIN_PERCENT = 5;
|
|
303
|
+
/** 将缩放百分比钳制到允许范围:仅保留下限,放大不设上限 */
|
|
304
|
+
declare function clampScalePercent(percent: number): number;
|
|
305
|
+
/**
|
|
306
|
+
* 滚轮缩放:乘性步进(默认 ×1.1 / ÷1.1),大倍数下仍保持平滑手感,
|
|
307
|
+
* 返回取整后的百分比,避免浮点累加产生脏显示(如 110.00000001)
|
|
308
|
+
* @param percent 当前缩放百分比
|
|
309
|
+
* @param direction 1 放大,-1 缩小
|
|
310
|
+
*/
|
|
311
|
+
declare function nextWheelScale(percent: number, direction: 1 | -1, factor?: number): number;
|
|
312
|
+
/** 计算适应窗口的缩放百分比,允许小于交互缩放下限,保证整版纸张可见 */
|
|
313
|
+
declare function computeFitScale(containerW: number, containerH: number, paperW: number, paperH: number, ratio?: number): number;
|
|
314
|
+
|
|
315
|
+
declare function normalizeTemplateUnits(data: TemplateData): TemplateData;
|
|
316
|
+
|
|
317
|
+
declare const PAPER_PRESETS: Record<string, {
|
|
318
|
+
width: number;
|
|
319
|
+
height: number;
|
|
320
|
+
}>;
|
|
321
|
+
/**
|
|
322
|
+
* 获取纸张原始宽高(mm,未应用方向)
|
|
323
|
+
* CUSTOM 时读取 customWidth/customHeight,缺省回退 A4
|
|
324
|
+
*/
|
|
325
|
+
declare function getPaperDimensions(t: Pick<TemplateData, 'paperSize' | 'orientation' | 'customWidth' | 'customHeight'>): {
|
|
326
|
+
width: number;
|
|
327
|
+
height: number;
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
interface CellRect {
|
|
331
|
+
r1: number;
|
|
332
|
+
c1: number;
|
|
333
|
+
r2: number;
|
|
334
|
+
c2: number;
|
|
335
|
+
}
|
|
336
|
+
declare function createCell(partial?: Partial<TableCell>): TableCell;
|
|
337
|
+
/** 默认新建表格:3 列 × 4 行(标题/数据/小计/汇总),列宽均分 50mm,表格组件默认显示当前页小计行 */
|
|
338
|
+
declare function createDefaultTable(): {
|
|
339
|
+
rows: TableRow[];
|
|
340
|
+
colWidths: number[];
|
|
341
|
+
};
|
|
342
|
+
/** 定位覆盖 (r,c) 的主格坐标(自身非 merged 即为主格) */
|
|
343
|
+
declare function findMainCell(rows: TableRow[], r: number, c: number): {
|
|
344
|
+
r: number;
|
|
345
|
+
c: number;
|
|
346
|
+
};
|
|
347
|
+
/** 主格覆盖矩形 */
|
|
348
|
+
declare function getSpanRect(rows: TableRow[], r: number, c: number): CellRect;
|
|
349
|
+
/** 由锚点/焦点推导矩形选区,并迭代扩展至完整包含所有跨越的合并格 */
|
|
350
|
+
declare function normalizeSelection(rows: TableRow[], a: {
|
|
351
|
+
r: number;
|
|
352
|
+
c: number;
|
|
353
|
+
}, b: {
|
|
354
|
+
r: number;
|
|
355
|
+
c: number;
|
|
356
|
+
}): CellRect;
|
|
357
|
+
/** 合并合法性校验,返回拒绝原因或 null */
|
|
358
|
+
declare function canMergeReason(rows: TableRow[], rect: CellRect): string | null;
|
|
359
|
+
/** 合并:左上为主格,非空内容空格拼接并入主格 */
|
|
360
|
+
declare function mergeCells(rows: TableRow[], rect: CellRect): void;
|
|
361
|
+
/** 拆分选区内所有合并格:占位格恢复并复制主格样式 */
|
|
362
|
+
declare function splitCells(rows: TableRow[], rect: CellRect): void;
|
|
363
|
+
/** 插入行。index 为参照行,position 决定插在其上方或下方 */
|
|
364
|
+
declare function insertRow(rows: TableRow[], index: number, position: 'above' | 'below'): void;
|
|
365
|
+
/** 删除行;主格在被删行时移交下一行 */
|
|
366
|
+
declare function deleteRow(rows: TableRow[], index: number): string | null;
|
|
367
|
+
/** 插入列 */
|
|
368
|
+
declare function insertCol(rows: TableRow[], colWidths: number[], index: number, position: 'left' | 'right'): void;
|
|
369
|
+
/** 删除列;主格在被删列时移交右侧列 */
|
|
370
|
+
declare function deleteCol(rows: TableRow[], colWidths: number[], index: number): string | null;
|
|
371
|
+
/** 行类型变更校验 + 写入。约束:header 顶部连续;data 唯一;subtotal/summary 在 data 之后;subtotal 在 summary 之前 */
|
|
372
|
+
declare function setRowType(rows: TableRow[], index: number, type: TableRowType): string | null;
|
|
373
|
+
type BorderPreset = 'all' | 'outer' | 'inner' | 'none';
|
|
374
|
+
/** 按预设批量写边框;none 时清空选区内所有格的 borders */
|
|
375
|
+
declare function applyBorderPreset(rows: TableRow[], rect: CellRect, preset: BorderPreset, border: TableCellBorder): void;
|
|
376
|
+
/** 设计态下无边框单元格的辅助虚线:与背景网格线同风格(浅灰虚线),略深保证可读 */
|
|
377
|
+
declare const GHOST_BORDER_CSS = "1px dashed rgba(0,0,0,0.18)";
|
|
378
|
+
/**
|
|
379
|
+
* 解析单元格某条边的最终 CSS border 值。
|
|
380
|
+
* - 有真实边框(style 非 none)→ 返回 `${width}pt ${style} ${color}`
|
|
381
|
+
* - 设计态且开关开启、且该边无边框 → 返回虚拟虚线(仅设计稿展示,不影响预览/打印)
|
|
382
|
+
* - 其余情况(预览态 / 开关关闭)→ 'none'
|
|
383
|
+
*/
|
|
384
|
+
declare function resolveCellBorderCss(b: TableCellBorder | undefined, opts?: {
|
|
385
|
+
designMode?: boolean;
|
|
386
|
+
showGhostBorder?: boolean;
|
|
387
|
+
}): string;
|
|
388
|
+
/** 表格元素尺寸派生:options.width/height 恒等于列宽和/行高和(mm),与渲染端一致 */
|
|
389
|
+
declare function syncTableElementSize(options: ElementOptions): void;
|
|
390
|
+
/** 列宽拖拽的最小列宽(mm),与属性面板列宽输入下限一致 */
|
|
391
|
+
declare const MIN_COL_WIDTH_MM = 5;
|
|
392
|
+
/**
|
|
393
|
+
* 列宽拖拽钳制(纯函数,不修改入参,调用方负责回写):
|
|
394
|
+
* 返回目标列宽在 [MIN_COL_WIDTH_MM, maxTableWidth - 其余列和] 范围内的钳制值,
|
|
395
|
+
* 结果保留 0.1mm 精度。maxTableWidth 为 Infinity 时不设总宽上限。
|
|
396
|
+
*/
|
|
397
|
+
declare function clampResizedColumnWidth(colWidths: number[], index: number, targetMm: number, maxTableWidth: number): number;
|
|
398
|
+
|
|
399
|
+
declare function generateId(): string;
|
|
400
|
+
declare function createDefaultOptions(type: ElementType): ElementOptions;
|
|
401
|
+
declare function createRuntimeElement(type: ElementType, options?: Partial<ElementOptions>): RuntimeElement;
|
|
402
|
+
|
|
403
|
+
/** 允许放入页眉/页脚的元素类型 */
|
|
404
|
+
declare const ZONE_ALLOWED_TYPES: string[];
|
|
405
|
+
interface ZoneRectPt {
|
|
406
|
+
left: number;
|
|
407
|
+
top: number;
|
|
408
|
+
width: number;
|
|
409
|
+
height: number;
|
|
410
|
+
}
|
|
411
|
+
/** 纸张宽高(mm,含方向;CUSTOM 读取 customWidth/customHeight,缺省回退 A4) */
|
|
412
|
+
declare function getPaperSizeMM(t: TemplateData): {
|
|
413
|
+
width: number;
|
|
414
|
+
height: number;
|
|
415
|
+
};
|
|
416
|
+
/** 三区在纸面坐标系中的矩形(mm),布局:上边距→页眉→内容→页脚→下边距 */
|
|
417
|
+
declare function getZoneRects(t: TemplateData): Record<ElementZone, ZoneRectPt>;
|
|
418
|
+
/** 纸面 mm 坐标 → 命中区域(高度为 0 的区域不参与命中) */
|
|
419
|
+
declare function zoneFromPaperPoint(t: TemplateData, _x: number, y: number): ElementZone;
|
|
420
|
+
/** 将元素局部坐标 clamp 到区域矩形内(原地修改) */
|
|
421
|
+
declare function clampToZone(el: RuntimeElement, zone: ZoneRectPt): void;
|
|
422
|
+
/**
|
|
423
|
+
* 拖拽/缩放结束后按元素中心点归区:
|
|
424
|
+
* 跨区时换算坐标并改写 zone;页眉/页脚内 clamp;类型不允许时拒绝跨入并 clamp 回内容区。
|
|
425
|
+
*/
|
|
426
|
+
declare function finalizeElementZone(el: RuntimeElement, t: TemplateData): {
|
|
427
|
+
rejected: boolean;
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
/** 视口固定尺条厚度(px),CanvasArea 布局与左上角块共用 */
|
|
431
|
+
declare const RULER_THICKNESS = 22;
|
|
432
|
+
interface RulerTick {
|
|
433
|
+
/** 刻度在纸面坐标系上的位置(mm,可为负,表示纸张原点之外) */
|
|
434
|
+
mm: number;
|
|
435
|
+
/** 是否为主刻度(带数字标签) */
|
|
436
|
+
major: boolean;
|
|
437
|
+
label?: string;
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* 按缩放选择主刻度步长(mm):取漂亮数序列中使屏幕间距
|
|
441
|
+
* 不小于 targetPx 的最小步长,保证任意缩放下标签不重叠
|
|
442
|
+
* @param scale 画布缩放比例(1 = 100%)
|
|
443
|
+
* @param targetPx 主刻度之间的目标屏幕间距(px)
|
|
444
|
+
*/
|
|
445
|
+
declare function chooseMajorStepMM(scale: number, targetPx?: number): number;
|
|
446
|
+
/**
|
|
447
|
+
* 次刻度步长:5 系(5/50/500…)五等分、2 系(2/20/200…)二等分、
|
|
448
|
+
* 10 的幂从 10mm 起五等分(10→2mm、100→20mm),1mm 时无次刻度
|
|
449
|
+
*/
|
|
450
|
+
declare function minorStepMM(majorStepMM: number): number | null;
|
|
451
|
+
/**
|
|
452
|
+
* 生成可见毫米范围内的全部刻度(升序):
|
|
453
|
+
* 从首个对齐的次刻度开始,主刻度带数字标签
|
|
454
|
+
* @param startMM 可见范围起点(纸面坐标,可为负)
|
|
455
|
+
* @param endMM 可见范围终点
|
|
456
|
+
* @param majorStepMM 主刻度步长(由 chooseMajorStepMM 选出)
|
|
457
|
+
*/
|
|
458
|
+
declare function buildRulerTicks(startMM: number, endMM: number, majorStepMM: number): RulerTick[];
|
|
459
|
+
|
|
460
|
+
/** 打印设计器常见预设颜色(12 色) */
|
|
461
|
+
declare const PRESET_COLORS: readonly ["#000000", "#333333", "#666666", "#999999", "#cccccc", "#ffffff", "#e53935", "#fb8c00", "#1e88e5", "#43a047", "#8d6e63", "#00acc1"];
|
|
462
|
+
|
|
463
|
+
/** 属性面板搜索注册表:分组 → 表单项 → 关键词 */
|
|
464
|
+
interface PropertyItem {
|
|
465
|
+
key: string;
|
|
466
|
+
keywords: string[];
|
|
467
|
+
}
|
|
468
|
+
interface PropertyGroupDef {
|
|
469
|
+
group: string;
|
|
470
|
+
groupLabel: string;
|
|
471
|
+
items: PropertyItem[];
|
|
472
|
+
}
|
|
473
|
+
declare const PROPERTY_REGISTRY: PropertyGroupDef[];
|
|
474
|
+
/** 正向包含匹配:任一关键词包含搜索词即命中;空搜索恒命中 */
|
|
475
|
+
declare function matchKeywords(search: string, keywords: string[]): boolean;
|
|
476
|
+
/** 计算命中的分组与表单项 key 集合 */
|
|
477
|
+
declare function searchProperties(search: string): {
|
|
478
|
+
groups: string[];
|
|
479
|
+
itemKeys: Set<string>;
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
interface FieldGroup {
|
|
483
|
+
/** 分组键(fieldKey 首段);空串表示无分组的顶层字段 */
|
|
484
|
+
key: string;
|
|
485
|
+
/** 分组显示名:取容器字段的 fieldLabel,缺省回退为 key */
|
|
486
|
+
label: string;
|
|
487
|
+
/** 是否明细列表分组(容器字段 fieldType === 'list') */
|
|
488
|
+
isList: boolean;
|
|
489
|
+
/** 分组下的叶子字段 */
|
|
490
|
+
fields: PrintBusinessField[];
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* 将宿主扁平字段按 fieldKey 首段分组:
|
|
494
|
+
* - 带点路径(supplier.name、goods.spec)归入首段分组;
|
|
495
|
+
* - 无点且作为其它字段前缀的记录视为分组容器(如 supplier/goods),
|
|
496
|
+
* 容器提供分组名称,fieldType='list' 标识明细列表(表格数据源);
|
|
497
|
+
* - 无点且无子字段的记录作为独立顶层字段。
|
|
498
|
+
*/
|
|
499
|
+
declare function groupFields(fields: PrintBusinessField[]): FieldGroup[];
|
|
500
|
+
/** 按关键字过滤分组(匹配字段名/字段 key),无叶子的分组剔除 */
|
|
501
|
+
declare function filterGroups(groups: FieldGroup[], keyword: string): FieldGroup[];
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* 元素绑定声明注册表
|
|
505
|
+
* 每个元素类型声明其支持的 formatter 绑定位置
|
|
506
|
+
*/
|
|
507
|
+
declare const ELEMENT_BINDING_REGISTRY: Record<string, BindingDescriptor[]>;
|
|
508
|
+
declare function getTableCellBindings(rowType: string, rowIndex: number, cellIndex: number, listField?: string): BindingDescriptor[];
|
|
509
|
+
declare function getElementBindings(element: any): BindingDescriptor[];
|
|
510
|
+
|
|
511
|
+
declare function getDemoData(): Record<string, any>;
|
|
512
|
+
declare const DEFAULT_DEMO_DATA: Record<string, any>;
|
|
513
|
+
|
|
514
|
+
declare const engine: TemplateEngine;
|
|
515
|
+
|
|
516
|
+
declare const EXTENDED_FUNCTIONS: {
|
|
517
|
+
MONEY: typeof formatMoney;
|
|
518
|
+
CONCAT: (...args: any[]) => string;
|
|
519
|
+
IF: typeof ifFn;
|
|
520
|
+
FORMAT: (value: any) => string;
|
|
521
|
+
SUBSTR: (str: string, start: number, len?: number) => string;
|
|
522
|
+
LEN: (str: string) => number;
|
|
523
|
+
ROUND: (num: number, decimals: number) => number;
|
|
524
|
+
NOW: () => string;
|
|
525
|
+
IFEMPTY: (value: any, defaultVal: string) => string;
|
|
526
|
+
PAD: (value: any, len: number, char: string) => string;
|
|
527
|
+
REPLACE: (str: string, from: string, to: string) => string;
|
|
528
|
+
JSON: (value: any) => string;
|
|
529
|
+
DATE: typeof formatDate;
|
|
530
|
+
UPPER: typeof toUpperCaseAmount;
|
|
531
|
+
};
|
|
532
|
+
/**
|
|
533
|
+
* 在受限沙箱内求值表达式
|
|
534
|
+
* @param expr 表达式字符串
|
|
535
|
+
* @param context 上下文变量
|
|
536
|
+
* @param _callableNames 保留参数,实际使用共享引擎
|
|
537
|
+
*/
|
|
538
|
+
declare function safeEval(expr: string, context: Record<string, any>, _callableNames?: string[]): any;
|
|
539
|
+
/**
|
|
540
|
+
* 模板字符串求值:{表达式} 内 safeEval 求值,外为字面文本。
|
|
541
|
+
* 聚合函数 SUM/AVG/COUNT/MIN/MAX(field) 预处理(需 ctx.rows)。
|
|
542
|
+
* 单个 {expr} 求值失败时保留原 {expr} 文本。
|
|
543
|
+
*/
|
|
544
|
+
declare function evaluateTemplate(text: string, ctx: Record<string, any>): string;
|
|
545
|
+
|
|
546
|
+
/** 从业务字段创建带 formatter 绑定的文本元素 */
|
|
547
|
+
declare function createFieldElement(field: {
|
|
548
|
+
fieldKey: string;
|
|
549
|
+
fieldLabel: string;
|
|
550
|
+
}): RuntimeElement;
|
|
551
|
+
/** 非设计态文本内容解析:用共享引擎渲染 formatter */
|
|
552
|
+
declare function resolveTextBinding(options: {
|
|
553
|
+
formatter?: string;
|
|
554
|
+
}, data?: Record<string, any>[]): string;
|
|
555
|
+
/**
|
|
556
|
+
* 设计态条码/二维码单元格取值:{field} 占位符替换为 demo 数据
|
|
557
|
+
* (列表字段取数据源首项,全局字段按路径取),无匹配回退通用示例码值
|
|
558
|
+
*/
|
|
559
|
+
declare function resolveBarcodeDesignValue(formatter: string | undefined, listSource?: Record<string, any>[]): string;
|
|
560
|
+
|
|
561
|
+
interface AdsorbConfig {
|
|
562
|
+
adsorbMin?: number;
|
|
563
|
+
adsorbLineMin?: number;
|
|
564
|
+
showAdsorbLine?: boolean;
|
|
565
|
+
}
|
|
566
|
+
/** 手动参考线(mm) */
|
|
567
|
+
interface ManualGuides {
|
|
568
|
+
vertical: number[];
|
|
569
|
+
horizontal: number[];
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* 计算拖动元素的吸附结果(新坐标 + 引导线)。
|
|
573
|
+
* @param movingRect 拖动元素矩形
|
|
574
|
+
* @param others 其他参与吸附的元素矩形
|
|
575
|
+
* @param manualGuides 手动参考线(可选)
|
|
576
|
+
* @param config 吸附阈值配置
|
|
577
|
+
*/
|
|
578
|
+
declare function computeAdsorb(movingRect: ElementRect, others: ElementRect[], manualGuides?: ManualGuides, config?: AdsorbConfig): AdsorbResult;
|
|
579
|
+
|
|
580
|
+
type AlignMode = 'left' | 'right' | 'top' | 'bottom' | 'vertical' | 'horizontal' | 'distributeHor' | 'distributeVer';
|
|
581
|
+
declare function useAlign(): {
|
|
582
|
+
align: (elements: RuntimeElement[], mode: AlignMode) => void;
|
|
583
|
+
};
|
|
584
|
+
|
|
585
|
+
declare function generateGroupId(): string;
|
|
586
|
+
declare function useGroup(): {
|
|
587
|
+
group: (elements: RuntimeElement[], selectedIds: Set<string>) => RuntimeElement[];
|
|
588
|
+
ungroup: (elements: RuntimeElement[], selectedIds: Set<string>) => RuntimeElement[];
|
|
589
|
+
getGroupedIds: (elements: RuntimeElement[], selectedId: string) => Set<string>;
|
|
590
|
+
};
|
|
591
|
+
|
|
592
|
+
interface KeyboardHandlers {
|
|
593
|
+
onMove?: (dx: number, dy: number) => void;
|
|
594
|
+
onDelete?: () => void;
|
|
595
|
+
onCopy?: () => void;
|
|
596
|
+
onPaste?: () => void;
|
|
597
|
+
onSelectAll?: () => void;
|
|
598
|
+
onUndo?: () => void;
|
|
599
|
+
onRedo?: () => void;
|
|
600
|
+
onDuplicate?: () => void;
|
|
601
|
+
onResetZoom?: () => void;
|
|
602
|
+
onAlignLeft?: () => void;
|
|
603
|
+
onAlignRight?: () => void;
|
|
604
|
+
onAlignCenterH?: () => void;
|
|
605
|
+
onAlignTop?: () => void;
|
|
606
|
+
onAlignBottom?: () => void;
|
|
607
|
+
onGroup?: () => void;
|
|
608
|
+
onUngroup?: () => void;
|
|
609
|
+
}
|
|
610
|
+
declare function useKeyboard(handlers: KeyboardHandlers): {
|
|
611
|
+
setup: () => void;
|
|
612
|
+
cleanup: () => void;
|
|
613
|
+
};
|
|
614
|
+
|
|
615
|
+
interface ResizeRect {
|
|
616
|
+
left: number;
|
|
617
|
+
top: number;
|
|
618
|
+
width: number;
|
|
619
|
+
height: number;
|
|
620
|
+
}
|
|
621
|
+
interface ResizeOptions {
|
|
622
|
+
minWidth?: number;
|
|
623
|
+
minHeight?: number;
|
|
624
|
+
getScale?: () => number;
|
|
625
|
+
/** 缩放起始时读取元素当前矩形(mm) */
|
|
626
|
+
getRect: () => ResizeRect;
|
|
627
|
+
onResize: (rect: ResizeRect) => void;
|
|
628
|
+
onStart?: () => void;
|
|
629
|
+
onStop?: () => void;
|
|
630
|
+
}
|
|
631
|
+
/** 8 方位缩放手柄,供模板 v-for 渲染 */
|
|
632
|
+
declare const RESIZE_POINTS: ResizePoint[];
|
|
633
|
+
/** 根据方位与位移计算缩放后矩形(纯函数) */
|
|
634
|
+
declare function calcResizeRect(point: ResizePoint, startRect: ResizeRect, dx: number, dy: number, minW: number, minH: number): ResizeRect;
|
|
635
|
+
/** 缩放交互逻辑:手柄由组件模板渲染,mousedown 时调用 startResize */
|
|
636
|
+
declare function useResize(options: ResizeOptions): {
|
|
637
|
+
startResize: (point: ResizePoint, e: MouseEvent) => void;
|
|
638
|
+
cleanup: () => void;
|
|
639
|
+
};
|
|
640
|
+
|
|
641
|
+
interface BindingDisplayState {
|
|
642
|
+
status: 'unbound' | 'bound' | 'warning' | 'error';
|
|
643
|
+
badge: string;
|
|
644
|
+
badgeColor: string;
|
|
645
|
+
demoPreview: string;
|
|
646
|
+
warning?: string;
|
|
647
|
+
}
|
|
648
|
+
declare function useBindingDisplay(): {
|
|
649
|
+
getBindingDisplayState: (element: any) => BindingDisplayState;
|
|
650
|
+
};
|
|
651
|
+
|
|
652
|
+
export { type AdsorbConfig, type AdsorbResult, type AlignLine, type AlignMode, type BindingDescriptor, type BorderPreset, type CellRect, DEFAULT_DEMO_DATA, ELEMENT_BINDING_REGISTRY, EXTENDED_FUNCTIONS, type ElementFieldBinding, type ElementOptions, type ElementRect, type ElementType, type ElementZone, FIT_SCALE_MIN_PERCENT, type FieldGroup, GHOST_BORDER_CSS, type KeyboardHandlers, MIN_COL_WIDTH_MM, MIN_SCALE_PERCENT, type ManualGuides, PAPER_PRESETS, PRESET_COLORS, PROPERTY_REGISTRY, type PaginationConfig, type PaperSize, type PrintBusinessField, type PrintElementData, type PrintElementTypeMeta, type PropertyGroupDef, type PropertyItem, RESIZE_POINTS, RULER_THICKNESS, type RequestScreenshotFn, type ResizeOptions, type ResizePoint, type ResizeRect, type RulerTick, type RuntimeElement, type ScreenshotRequest, type TableCell, type TableCellBorder, type TableCellBorders, type TableCellType, type TablePaginationConfig, type TableRow, type TableRowType, type TableSelection, type TemplateData, type TemplateElement, type TextAlign, type UploadImageFn, type VerticalAlign, type WatermarkOptions, ZONE_ALLOWED_TYPES, type ZoneRectPt, applyBorderPreset, buildRulerTicks, calcResizeRect, canMergeReason, chooseMajorStepMM, clampResizedColumnWidth, clampScalePercent, clampToZone, computeAdsorb, computeFitScale, createCell, createDefaultOptions, createDefaultTable, createFieldElement, createRuntimeElement, deleteCol, deleteRow, engine, evaluateTemplate, filterGroups, finalizeElementZone, findMainCell, generateGroupId, generateId, getDemoData, getElementBindings, getPaperDimensions, getPaperSizeMM, getSpanRect, getTableCellBindings, getZoneRects, groupFields, insertCol, insertRow, matchKeywords, mergeCells, minorStepMM, mmToPx, nextWheelScale, normalizeSelection, normalizeTemplateUnits, ptToMm, pxToMm, resolveBarcodeDesignValue, resolveCellBorderCss, resolveTextBinding, safeEval, searchProperties, setRowType, splitCells, syncTableElementSize, useAlign, useBindingDisplay, useGroup, useKeyboard, useResize, zoneFromPaperPoint };
|