x-print-designer 0.4.8 → 0.4.13

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.
@@ -1,170 +1,247 @@
1
- import type {
2
- DesignerExportRequest,
3
- DesignerPrintRequest,
4
- DesignerPrintDefaults,
5
- DesignerListContextMenuConfig,
6
- DesignerListContextMenuItem,
7
- DesignerTemplateTagResolver
8
- } from './web-component';
9
- import type {
10
- LocalPrinterInfo,
11
- RemotePrinterInfo,
12
- LocalPrinterCaps,
13
- RemoteClientInfo
14
- } from './composables/usePrintSettings';
15
- import type { Page } from './types';
16
- import type { LoopExpandContext } from './utils/loopExpand';
17
- import type { DefineComponent } from 'vue';
18
-
19
- export type EndpointConfig = string | {
20
- url: string;
21
- method?: string;
22
- data?: Record<string, any>;
23
- };
24
-
25
- export type CrudEndpoints = {
26
- baseUrl?: string;
27
- templates?: {
28
- list?: EndpointConfig;
29
- get?: EndpointConfig;
30
- upsert?: EndpointConfig;
31
- delete?: EndpointConfig;
32
- };
33
- customElements?: {
34
- list?: EndpointConfig;
35
- get?: EndpointConfig;
36
- upsert?: EndpointConfig;
37
- delete?: EndpointConfig;
38
- };
39
- };
40
- export type DesignerFieldDictionaryItem = {
41
- fieldKey?: string;
42
- key?: string;
43
- fieldType?: string;
44
- label?: string;
45
- labelCn?: string;
46
- labelEn?: string;
47
- moduleKey?: string;
48
- moduleName?: string;
49
- primaryKey?: boolean;
50
- };
51
-
52
- export type DesignerFieldDictionary = Record<string, DesignerFieldDictionaryItem | string | null | undefined>;
53
-
54
- export interface PrintDesignerElement extends HTMLElement {
55
- print(request?: DesignerPrintRequest): Promise<void>;
56
- export(request: DesignerExportRequest): Promise<void | Blob>;
57
- setPrintDefaults(payload?: DesignerPrintDefaults): void;
58
- fetchLocalPrinters(): Promise<LocalPrinterInfo[]>;
59
- fetchLocalPrinterCaps(printer: string): Promise<LocalPrinterCaps | undefined>;
60
- fetchRemotePrinters(clientId?: string): Promise<RemotePrinterInfo[]>;
61
- fetchRemoteClients(): Promise<RemoteClientInfo[]>;
62
-
63
- setBranding(payload?: { title?: string; logoUrl?: string; showTitle?: boolean; showLogo?: boolean }): void;
64
- setBrandVars(vars: Record<string, string>, options?: { persist?: boolean }): void;
65
- setTheme(theme: string): void;
66
- setDesignerFont(fontFamily: string, options?: { persist?: boolean }): void;
67
- setLanguage(lang: 'zh' | 'en'): void;
68
- getPrintQuality(): 'fast' | 'normal' | 'high' | 'ultra';
69
- setDataLoading(isLoading: boolean): void;
70
-
71
- // Save callback
72
- setOnSave(handler: ((payload: { id: string | null; name: string; data: Record<string, any>; isNew: boolean }) => void | Promise<void>) | null): void;
73
- setAutoSave(enabled: boolean, intervalMs?: number): void;
74
- setPrintQuality(quality: 'fast' | 'normal' | 'high' | 'ultra'): void;
75
-
76
- getTestData(): Record<string, any>;
77
- setTestData(data: Record<string, any>, options?: { merge?: boolean }): Promise<void>;
78
- setSampleData(data: Record<string, any>): void;
79
-
80
- getVariables(): Record<string, any>;
81
- setVariables(data: Record<string, any>, options?: { merge?: boolean }): Promise<void>;
82
- setTemplateVariables(data: Record<string, any>, options?: { merge?: boolean }): Promise<void>;
83
- setFieldDictionary(dictionary?: DesignerFieldDictionary | null): void;
84
-
85
- getTemplateVariables(): Record<string, any>;
86
-
87
- getTemplateData(): any;
88
- loadTemplateData(data: any): boolean;
89
-
90
- getTemplates(options?: { includeData?: boolean }): Array<{ id: string; name: string; updatedAt: number } | any>;
91
- refreshTemplates(options?: { includeData?: boolean }): Promise<Array<{ id: string; name: string; updatedAt: number } | any>>;
92
- getTemplate(id: string): any | null;
93
- upsertTemplate(template: { id?: string; name: string; data?: any; updatedAt?: number; [key: string]: any }, options?: { setCurrent?: boolean }): Promise<string | null>;
94
- /**
95
- * 写入模板列表并加载 currentTemplateId 对应模板。
96
- * 返回的 Promise 在 pages 填充完成后 resolve,调用方可据此消除时序竞态。
97
- */
98
- setTemplates(templates: Array<{ id: string; name: string; data?: any; updatedAt?: number; [key: string]: any }>, options?: { currentTemplateId?: string }): Promise<void>;
99
- deleteTemplate(id: string, options?: { confirm?: boolean }): Promise<void>;
100
- /**
101
- * 加载指定模板并填充画布。
102
- * @returns Promise<boolean>,resolve 时 pages 已填充;false 表示因前置条件未触发。
103
- */
104
- loadTemplate(id: string): Promise<boolean>;
105
-
106
- getCustomElements(options?: { includeElement?: boolean }): Array<{ id: string; name: string } | any>;
107
- refreshCustomElements(options?: { includeElement?: boolean }): Promise<Array<{ id: string; name: string } | any>>;
108
- upsertCustomElement(customElement: { id?: string; name: string; element: any; [key: string]: any }): Promise<string | null>;
109
- setCustomElements(customElements: Array<{ id: string; name: string; element: any; [key: string]: any }>): void;
110
- deleteCustomElement(id: string, options?: { confirm?: boolean }): Promise<void>;
111
- setTemplateContextMenu(config: DesignerListContextMenuConfig | DesignerListContextMenuItem[]): void;
112
- clearTemplateContextMenu(): void;
113
- setCustomElementContextMenu(config: DesignerListContextMenuConfig | DesignerListContextMenuItem[]): void;
114
- clearCustomElementContextMenu(): void;
115
- setTemplateTagResolver(resolver: DesignerTemplateTagResolver): void;
116
- clearTemplateTagResolver(): void;
117
-
118
- setCrudMode(mode: 'local' | 'remote', options?: { skipAutoLoad?: boolean }): void;
119
- setCrudEndpoints(endpoints: CrudEndpoints, options?: { baseUrl?: string; headers?: Record<string, string>; fetcher?: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response> }): void;
120
-
121
- /**
122
- * 循环页展开:按 page.loopDataVariable + ctx 数组数据,把 1 个模板页展开成 N 个渲染页。
123
- * 不传 ctx 时默认使用当前 store 的 testData/variables(按导出语义解析)。
124
- */
125
- expandLoopPages(pages: Page[], ctx?: LoopExpandContext): Page[];
126
- /** 判断页面数组中是否含循环页(任一 page 带 loopDataVariable) */
127
- hasLoopPage(pages: Page[] | undefined | null): boolean;
128
- /**
129
- * 折叠已展开的循环页,还原为带 loopDataVariable 的单个模板页。
130
- * 适用于报告模式保存前还原模板结构。
131
- */
132
- collapseLoopPages(currentPages: Page[], originalTemplatePages: Page[]): Page[];
133
- }
134
-
135
- declare global {
136
- interface HTMLElementTagNameMap {
137
- 'print-designer': PrintDesignerElement;
138
- }
139
- }
140
-
141
- // ============================================================
142
- // 独立命名导出(src/index.ts)
143
- // 允许宿主 `import { PreviewPage, expandLoopPages, ... } from 'x-print-designer'`
144
- // 作为普通 Vue 组件 / 纯函数使用,无需挂载完整 Web Component。
145
- // ============================================================
146
-
147
- /** 轻量预览组件:接收 pages + testData + variables,渲染只读预览(含循环页展开 + report 表格分页) */
148
- export const PreviewPage: DefineComponent<{
149
- autoRender?: boolean;
150
- pages?: any[];
151
- canvasSize?: { width: number; height: number };
152
- canvasBackground?: string;
153
- testData?: Record<string, any>;
154
- variables?: Record<string, any>;
155
- watermark?: any;
156
- autoRenderTrigger?: number;
157
- mode?: 'template' | 'report';
158
- headerHeight?: number;
159
- footerHeight?: number;
160
- showHeaderLine?: boolean;
161
- showFooterLine?: boolean;
162
- pageSpacingY?: number;
163
- }>;
164
-
165
- // 循环页展开 / 折叠纯函数
166
- export function expandLoopPages(pages: Page[], ctx: LoopExpandContext): Page[];
167
- export function collapseLoopPages(currentPages: Page[], originalTemplatePages: Page[]): Page[];
168
- export function hasLoopPage(pages: Page[] | undefined | null): boolean;
169
-
170
- export {};
1
+ export type DesignerMode = 'template' | 'report';
2
+ export type DesignerViewMode = 'edit' | 'preview';
3
+ export type DesignerPage = Record<string, any>;
4
+ export type PrintMode = 'browser' | 'local' | 'remote';
5
+
6
+ export interface PrintOptions {
7
+ printer: string;
8
+ jobName: string;
9
+ copies: number;
10
+ intervalMs: number;
11
+ timeout?: number;
12
+ pageRange: string;
13
+ pageSet: '' | 'odd' | 'even';
14
+ scale: '' | 'noscale' | 'shrink' | 'fit';
15
+ orientation: '' | 'portrait' | 'landscape';
16
+ colorMode: '' | 'color' | 'monochrome';
17
+ sidesMode: '' | 'simplex' | 'duplex' | 'duplexshort' | 'duplexlong';
18
+ paperSize: string;
19
+ trayBin: string;
20
+ }
21
+
22
+ export interface LocalConnectionSettings {
23
+ wsAddress: string;
24
+ secretKey: string;
25
+ }
26
+
27
+ export interface RemoteConnectionSettings {
28
+ wsAddress: string;
29
+ apiBaseUrl: string;
30
+ username: string;
31
+ password: string;
32
+ }
33
+
34
+ export interface LocalPrinterInfo {
35
+ name: string;
36
+ isDefault?: boolean;
37
+ }
38
+
39
+ export interface RemotePrinterInfo {
40
+ printer_name: string;
41
+ printer_type?: string;
42
+ paper_spec?: string;
43
+ is_ready?: boolean;
44
+ supported_format?: string;
45
+ capabilities?: Record<string, any>;
46
+ }
47
+
48
+ export interface RemoteClientInfo {
49
+ client_id: string;
50
+ client_name?: string;
51
+ online?: boolean;
52
+ last_heartbeat?: string;
53
+ }
54
+
55
+ export interface LocalPrinterCaps {
56
+ paperSizes?: string[];
57
+ printerPaperNames?: string[];
58
+ duplexSupported?: boolean;
59
+ colorSupported?: boolean;
60
+ }
61
+
62
+ export type DesignerExportRequest = {
63
+ type: 'pdf' | 'html' | 'images' | 'pdfBlob' | 'imageBlob';
64
+ filename?: string;
65
+ filenamePrefix?: string;
66
+ merged?: boolean;
67
+ };
68
+
69
+ export type DesignerPrintRequest = {
70
+ mode?: PrintMode;
71
+ options?: PrintOptions;
72
+ };
73
+
74
+ export type DesignerPrintDefaults = {
75
+ printMode?: PrintMode;
76
+ silentPrint?: boolean;
77
+ exportImageMerged?: boolean;
78
+ localSettings?: Partial<LocalConnectionSettings>;
79
+ remoteSettings?: Partial<RemoteConnectionSettings>;
80
+ localPrintOptions?: Partial<PrintOptions>;
81
+ remotePrintOptions?: Partial<PrintOptions>;
82
+ };
83
+
84
+ export type EndpointConfig = string | {
85
+ url: string;
86
+ method?: string;
87
+ data?: Record<string, any>;
88
+ };
89
+
90
+ export type CrudEndpoints = {
91
+ baseUrl?: string;
92
+ templates?: {
93
+ list?: EndpointConfig;
94
+ get?: EndpointConfig;
95
+ upsert?: EndpointConfig;
96
+ delete?: EndpointConfig;
97
+ };
98
+ customElements?: {
99
+ list?: EndpointConfig;
100
+ get?: EndpointConfig;
101
+ upsert?: EndpointConfig;
102
+ delete?: EndpointConfig;
103
+ };
104
+ };
105
+
106
+ export type DesignerFieldDictionaryItem = {
107
+ fieldKey?: string;
108
+ key?: string;
109
+ fieldType?: string;
110
+ label?: string;
111
+ labelCn?: string;
112
+ labelEn?: string;
113
+ moduleKey?: string;
114
+ moduleName?: string;
115
+ primaryKey?: boolean;
116
+ };
117
+
118
+ export type DesignerFieldDictionary = Record<string, DesignerFieldDictionaryItem | string | null | undefined>;
119
+
120
+ export interface DesignerListContextMenuItem {
121
+ key: string;
122
+ label: string;
123
+ [key: string]: any;
124
+ }
125
+
126
+ export interface DesignerListContextMenuConfig {
127
+ mode?: 'replace' | 'append';
128
+ items: DesignerListContextMenuItem[];
129
+ }
130
+
131
+ export type DesignerTemplateModalFormConfig = Record<string, any>;
132
+
133
+ export interface LoopExpandContext {
134
+ testData?: Record<string, any>;
135
+ variables?: Record<string, any>;
136
+ mode?: DesignerMode;
137
+ isExporting?: boolean;
138
+ showVariableNames?: boolean;
139
+ }
140
+
141
+ export interface DesignerPreviewModeOptions {
142
+ pages: DesignerPage[];
143
+ canvasSize: { width: number; height: number };
144
+ canvasBackground?: string;
145
+ testData?: Record<string, any>;
146
+ variables?: Record<string, any>;
147
+ watermark?: any;
148
+ mode?: DesignerMode;
149
+ headerHeight?: number;
150
+ footerHeight?: number;
151
+ showHeaderLine?: boolean;
152
+ showFooterLine?: boolean;
153
+ pageSpacingY?: number;
154
+ }
155
+
156
+ export interface PrintDesignerElement extends HTMLElement {
157
+ isReady: boolean;
158
+
159
+ setClientLink(url: string): void;
160
+ setCloudLink(url: string): void;
161
+ hideLinks(hide: boolean): void;
162
+ hideClientLink(hide: boolean): void;
163
+ hideCloudLink(hide: boolean): void;
164
+ setMode(mode: DesignerMode): void;
165
+ setViewMode(viewMode: DesignerViewMode): void;
166
+
167
+ print(request?: DesignerPrintRequest): Promise<void>;
168
+ getPreviewHtml(): Promise<string>;
169
+ export(request: DesignerExportRequest): Promise<void | Blob>;
170
+ setPrintDefaults(payload?: DesignerPrintDefaults): void;
171
+ fetchLocalPrinters(): Promise<LocalPrinterInfo[]>;
172
+ fetchLocalPrinterCaps(printer: string): Promise<LocalPrinterCaps | undefined>;
173
+ fetchRemotePrinters(clientId?: string): Promise<RemotePrinterInfo[]>;
174
+ fetchRemoteClients(): Promise<RemoteClientInfo[]>;
175
+
176
+ setBranding(payload?: { title?: string; logoUrl?: string; showTitle?: boolean; showLogo?: boolean }): void;
177
+ setBrandVars(vars: Record<string, string>, options?: { persist?: boolean }): void;
178
+ setTheme(theme: string): void;
179
+ setDesignerFont(fontFamily: string, options?: { persist?: boolean }): void;
180
+ setLanguage(lang: 'zh' | 'en'): void;
181
+ getPrintQuality(): 'fast' | 'normal' | 'high' | 'ultra';
182
+ setDataLoading(isLoading: boolean): void;
183
+
184
+ setOnSave(handler: ((payload: { id: string | null; name: string; data: Record<string, any>; isNew: boolean }) => void | Promise<void>) | null): void;
185
+ setAutoSave(enabled: boolean, intervalMs?: number): void;
186
+ setPrintQuality(quality: 'fast' | 'normal' | 'high' | 'ultra'): void;
187
+
188
+ setPreviewMode(options: DesignerPreviewModeOptions): void;
189
+ exitPreviewMode(): void;
190
+
191
+ getTestData(): Record<string, any>;
192
+ setTestData(data: Record<string, any>, options?: { merge?: boolean }): Promise<void>;
193
+ setSampleData(data: Record<string, any>): void;
194
+
195
+ getVariables(): Record<string, any>;
196
+ setVariables(data: Record<string, any>, options?: { merge?: boolean }): Promise<void>;
197
+ setTemplateVariables(data: Record<string, any>, options?: { merge?: boolean }): Promise<void>;
198
+ setFieldDictionary(dictionary?: DesignerFieldDictionary | null): void;
199
+ setAvailableVariables(variables: any[]): void;
200
+
201
+ getTemplateVariables(): Record<string, any>;
202
+
203
+ getTemplateData(): any;
204
+ loadTemplateData(data: any): boolean;
205
+
206
+ getTemplates(options?: { includeData?: boolean }): Array<{ id: string; name: string; updatedAt: number } | any>;
207
+ refreshTemplates(options?: { includeData?: boolean }): Promise<Array<{ id: string; name: string; updatedAt: number } | any>>;
208
+ getTemplate(id: string): any | null;
209
+ upsertTemplate(template: { id?: string; name: string; data?: any; updatedAt?: number; [key: string]: any }, options?: { setCurrent?: boolean }): Promise<string | null>;
210
+ setTemplates(templates: Array<{ id: string; name: string; data?: any; updatedAt?: number; [key: string]: any }>, options?: { currentTemplateId?: string }): Promise<void>;
211
+ deleteTemplate(id: string, options?: { confirm?: boolean }): Promise<void>;
212
+ loadTemplate(id: string): Promise<boolean>;
213
+
214
+ getCustomElements(options?: { includeElement?: boolean }): Array<{ id: string; name: string } | any>;
215
+ refreshCustomElements(options?: { includeElement?: boolean }): Promise<Array<{ id: string; name: string } | any>>;
216
+ getCustomElement(id: string): any | null;
217
+ upsertCustomElement(customElement: { id?: string; name: string; element: any; [key: string]: any }): Promise<string | null>;
218
+ setCustomElements(customElements: Array<{ id: string; name: string; element: any; [key: string]: any }>): void;
219
+ deleteCustomElement(id: string, options?: { confirm?: boolean }): Promise<void>;
220
+
221
+ setTemplateContextMenu(config: DesignerListContextMenuConfig | DesignerListContextMenuItem[]): void;
222
+ clearTemplateContextMenu(): void;
223
+ setCustomElementContextMenu(config: DesignerListContextMenuConfig | DesignerListContextMenuItem[]): void;
224
+ clearCustomElementContextMenu(): void;
225
+ setTemplateModalForm(config: DesignerTemplateModalFormConfig): void;
226
+ clearTemplateModalForm(): void;
227
+ setCustomElementModalForm(config: DesignerTemplateModalFormConfig): void;
228
+ clearCustomElementModalForm(): void;
229
+
230
+ setCrudMode(mode: 'local' | 'remote', options?: { skipAutoLoad?: boolean }): void;
231
+ setCrudEndpoints(endpoints: CrudEndpoints, options?: { baseUrl?: string; headers?: Record<string, string>; fetcher?: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response> }): void;
232
+
233
+ expandLoopPages(pages: DesignerPage[], ctx?: LoopExpandContext): DesignerPage[];
234
+ hasLoopPage(pages: DesignerPage[] | undefined | null): boolean;
235
+ collapseLoopPages(currentPages: DesignerPage[], originalTemplatePages: DesignerPage[]): DesignerPage[];
236
+ }
237
+
238
+ export const PrintDesignerElement: {
239
+ prototype: PrintDesignerElement;
240
+ new (): PrintDesignerElement;
241
+ };
242
+
243
+ declare global {
244
+ interface HTMLElementTagNameMap {
245
+ 'print-designer': PrintDesignerElement;
246
+ }
247
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "x-print-designer",
3
3
  "private": false,
4
- "version": "0.4.8",
4
+ "version": "0.4.13",
5
5
  "license": "AGPL-3.0-only",
6
6
  "type": "module",
7
7
  "main": "dist/print-designer.umd.js",
@@ -14,6 +14,11 @@
14
14
  "import": "./dist/print-designer.es.js",
15
15
  "require": "./dist/print-designer.umd.js"
16
16
  },
17
+ "./vue": {
18
+ "types": "./dist/vue.d.ts",
19
+ "import": "./dist/vue.es.js"
20
+ },
21
+ "./vue.css": "./dist/vue.css",
17
22
  "./style.css": "./dist/print-designer.css"
18
23
  },
19
24
  "files": [
@@ -29,7 +34,7 @@
29
34
  "dev": "vite",
30
35
  "dev:lib": "node ./scripts/generate-tailwind-css.mjs && vite build --config vite.config.wc.dev.ts --watch",
31
36
  "build": "node ./scripts/bump-version.mjs && node ./scripts/typecheck.mjs && vite build",
32
- "build:wc": "node ./scripts/bump-version.mjs && node ./scripts/typecheck.mjs && node ./scripts/generate-tailwind-css.mjs && vite build --config vite.config.wc.ts && node ./scripts/copy-wc-types.mjs",
37
+ "build:wc": "node ./scripts/bump-version.mjs && node ./scripts/typecheck.mjs && node ./scripts/generate-tailwind-css.mjs && vite build --config vite.config.wc.ts && vite build --config vite.config.vue.ts && node ./scripts/copy-wc-types.mjs",
33
38
  "link": "npm link",
34
39
  "build:watch": "vite build --watch",
35
40
  "unlink": "npm unlink -g",
@@ -44,11 +49,13 @@
44
49
  "jspdf": "4.2",
45
50
  "jszip": "^3.10.1",
46
51
  "lodash": "^4.17.21",
47
- "pinia": "^2.3.0",
48
52
  "qrcode": "^1.5.4",
49
- "uuid": "^11.0.3",
50
- "vue": "^3.5.13",
51
- "vue-i18n": "^11.2.8"
53
+ "uuid": "^11.0.3"
54
+ },
55
+ "peerDependencies": {
56
+ "pinia": ">=2.3.0",
57
+ "vue": ">=3.5.0",
58
+ "vue-i18n": ">=11.2.0"
52
59
  },
53
60
  "devDependencies": {
54
61
  "@iconify-json/material-symbols": "^1.2.53",
@@ -61,6 +68,7 @@
61
68
  "@vue/tsconfig": "^0.7.0",
62
69
  "autoprefixer": "^10.4.20",
63
70
  "postcss": "^8.4.49",
71
+ "pinia": "2.3.0",
64
72
  "rollup-plugin-visualizer": "^7.0.1",
65
73
  "sharp": "^0.34.5",
66
74
  "tailwindcss": "^3.4.17",
@@ -68,6 +76,8 @@
68
76
  "typescript": "~5.6.2",
69
77
  "unplugin-icons": "^23.0.1",
70
78
  "vite": "^6.0.1",
79
+ "vue": "3.5.13",
80
+ "vue-i18n": "11.2.8",
71
81
  "vue-tsc": "^2.1.10"
72
82
  }
73
83
  }