@qy_better_lib/hooks 0.1.10 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DOCUMENTATION.md +704 -0
- package/__tests__/use-chart/index.test.ts +287 -0
- package/__tests__/use-emit/index.test.ts +248 -0
- package/__tests__/use-fullscreen/index.test.ts +162 -0
- package/__tests__/use-image/index.test.ts +230 -0
- package/__tests__/use-layout-flow/index.test.ts +382 -0
- package/__tests__/use-mqtt/index.test.ts +392 -0
- package/__tests__/use-print/index.test.ts +378 -0
- package/__tests__/use-watermark/index.test.ts +277 -0
- package/__tests__/use-websocket/index.test.ts +402 -0
- package/dist/hooks.min.js +76 -0
- package/lib/index.d.ts +5 -2
- package/lib/index.js +20 -31
- package/lib/use-chart/config.d.ts +2 -3
- package/lib/use-chart/config.js +78 -0
- package/lib/use-chart/index.d.ts +5 -13
- package/lib/use-chart/index.js +196 -0
- package/lib/use-chart/type.d.ts +92 -4
- package/lib/use-emit/extend.d.ts +2 -1
- package/lib/use-emit/extend.js +34 -15
- package/lib/use-emit/index.d.ts +2 -13
- package/lib/use-emit/index.js +22 -17
- package/lib/use-emit/type.d.ts +16 -0
- package/lib/use-fullscreen/index.d.ts +23 -0
- package/lib/use-fullscreen/index.js +51 -0
- package/lib/use-image/index.d.ts +18 -52
- package/lib/use-image/index.js +187 -67
- package/lib/use-image/type.d.ts +8 -10
- package/lib/use-image/type.js +7 -6
- package/lib/use-layout-flow/index.d.ts +14 -40
- package/lib/use-layout-flow/index.js +284 -0
- package/lib/use-layout-flow/type.d.ts +46 -0
- package/lib/use-mqtt/index.d.ts +9 -18
- package/lib/use-mqtt/index.js +179 -0
- package/lib/use-mqtt/type.d.ts +78 -0
- package/lib/use-print/index.d.ts +5 -9
- package/lib/use-print/index.js +274 -40
- package/lib/use-print/type.d.ts +58 -0
- package/lib/use-watermark/index.d.ts +7 -0
- package/lib/use-watermark/index.js +131 -0
- package/lib/use-watermark/type.d.ts +55 -0
- package/lib/use-websocket/index.d.ts +6 -13
- package/lib/use-websocket/index.js +190 -39
- package/lib/use-websocket/type.d.ts +54 -0
- package/package.json +6 -3
- package/dist/@qy_better_lib/hooks.min.js +0 -15
- package/lib/use-chart/utils.d.ts +0 -0
- package/lib/use-file/index.d.ts +0 -14
- package/lib/use-file/index.js +0 -26
- package/lib/use-image/canvastoDataURL.d.ts +0 -11
- package/lib/use-image/canvastoDataURL.js +0 -7
- package/lib/use-image/canvastoFile.d.ts +0 -11
- package/lib/use-image/canvastoFile.js +0 -9
- package/lib/use-image/dataURLtoFile.d.ts +0 -10
- package/lib/use-image/dataURLtoFile.js +0 -16
- package/lib/use-image/dataURLtoImage.d.ts +0 -7
- package/lib/use-image/dataURLtoImage.js +0 -9
- package/lib/use-image/downloadFile.d.ts +0 -7
- package/lib/use-image/downloadFile.js +0 -9
- package/lib/use-image/filetoDataURL.d.ts +0 -7
- package/lib/use-image/filetoDataURL.js +0 -9
- package/lib/use-image/imagetoCanvas.d.ts +0 -26
- package/lib/use-image/imagetoCanvas.js +0 -41
- package/lib/use-image/urltoBlob.d.ts +0 -8
- package/lib/use-image/urltoBlob.js +0 -6
- package/lib/use-image/urltoImage.d.ts +0 -7
- package/lib/use-image/urltoImage.js +0 -13
- package/lib/use-utils/index.d.ts +0 -1
- package/lib/use-utils/use-fullscreen.d.ts +0 -9
- package/lib/use-waterMark/index.d.ts +0 -17
- package/lib/use-waterMark/index.js +0 -29
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { use_web_socket } from '../../src/use-websocket';
|
|
3
|
+
|
|
4
|
+
// 模拟WebSocket对象
|
|
5
|
+
class MockWebSocket {
|
|
6
|
+
readyState: number;
|
|
7
|
+
url: string;
|
|
8
|
+
onopen: ((event: Event) => void) | null;
|
|
9
|
+
onerror: ((event: Event) => void) | null;
|
|
10
|
+
onclose: ((event: CloseEvent) => void) | null;
|
|
11
|
+
onmessage: ((event: MessageEvent) => void) | null;
|
|
12
|
+
|
|
13
|
+
constructor(url: string) {
|
|
14
|
+
this.url = url;
|
|
15
|
+
this.readyState = WebSocket.CONNECTING;
|
|
16
|
+
this.onopen = null;
|
|
17
|
+
this.onerror = null;
|
|
18
|
+
this.onclose = null;
|
|
19
|
+
this.onmessage = null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
send(data: string) {
|
|
23
|
+
// 模拟发送消息
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
close() {
|
|
27
|
+
this.readyState = WebSocket.CLOSED;
|
|
28
|
+
if (this.onclose) {
|
|
29
|
+
const closeEvent = new CloseEvent('close', { code: 1000, reason: 'Normal closure' });
|
|
30
|
+
this.onclose(closeEvent);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 模拟连接成功
|
|
35
|
+
simulateOpen() {
|
|
36
|
+
this.readyState = WebSocket.OPEN;
|
|
37
|
+
if (this.onopen) {
|
|
38
|
+
this.onopen(new Event('open'));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 模拟连接错误
|
|
43
|
+
simulateError() {
|
|
44
|
+
if (this.onerror) {
|
|
45
|
+
this.onerror(new Event('error'));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 模拟接收消息
|
|
50
|
+
simulateMessage(data: any) {
|
|
51
|
+
if (this.onmessage) {
|
|
52
|
+
const messageEvent = new MessageEvent('message', { data });
|
|
53
|
+
this.onmessage(messageEvent);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// 模拟WebSocket构造函数
|
|
59
|
+
const mockWebSocketClass = vi.fn().mockImplementation((url: string) => new MockWebSocket(url));
|
|
60
|
+
|
|
61
|
+
// 模拟全局对象
|
|
62
|
+
beforeEach(() => {
|
|
63
|
+
vi.clearAllMocks();
|
|
64
|
+
global.WebSocket = mockWebSocketClass as any;
|
|
65
|
+
// 模拟setTimeout和clearTimeout
|
|
66
|
+
vi.useFakeTimers();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
afterEach(() => {
|
|
70
|
+
vi.resetModules();
|
|
71
|
+
vi.useRealTimers();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
describe('use_web_socket', () => {
|
|
75
|
+
it('should initialize with default values', () => {
|
|
76
|
+
const mockReceive = vi.fn();
|
|
77
|
+
const { ws, create, close, send_message, get_status, reconnect, start_heartbeat, stop_heartbeat } = use_web_socket({
|
|
78
|
+
server: 'ws://localhost:8080',
|
|
79
|
+
receive: mockReceive,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
expect(ws).toBeUndefined();
|
|
83
|
+
expect(typeof create).toBe('function');
|
|
84
|
+
expect(typeof close).toBe('function');
|
|
85
|
+
expect(typeof send_message).toBe('function');
|
|
86
|
+
expect(typeof get_status).toBe('function');
|
|
87
|
+
expect(typeof reconnect).toBe('function');
|
|
88
|
+
expect(typeof start_heartbeat).toBe('function');
|
|
89
|
+
expect(typeof stop_heartbeat).toBe('function');
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should create and connect WebSocket successfully', () => {
|
|
93
|
+
const mockReceive = vi.fn();
|
|
94
|
+
const mockOnOpen = vi.fn();
|
|
95
|
+
|
|
96
|
+
const { create, get_status } = use_web_socket({
|
|
97
|
+
server: 'ws://localhost:8080',
|
|
98
|
+
receive: mockReceive,
|
|
99
|
+
on_open: mockOnOpen,
|
|
100
|
+
auto_connect: false,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// 创建连接
|
|
104
|
+
create();
|
|
105
|
+
|
|
106
|
+
expect(mockWebSocketClass).toHaveBeenCalledWith('ws://localhost:8080');
|
|
107
|
+
|
|
108
|
+
// 模拟连接成功
|
|
109
|
+
const wsInstance = (global.WebSocket as any).mock.instances[0];
|
|
110
|
+
if (wsInstance) {
|
|
111
|
+
wsInstance.simulateOpen();
|
|
112
|
+
expect(mockOnOpen).toHaveBeenCalled();
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('should handle WebSocket error', () => {
|
|
117
|
+
const mockReceive = vi.fn();
|
|
118
|
+
const mockOnError = vi.fn();
|
|
119
|
+
|
|
120
|
+
const { create } = use_web_socket({
|
|
121
|
+
server: 'ws://localhost:8080',
|
|
122
|
+
receive: mockReceive,
|
|
123
|
+
on_error: mockOnError,
|
|
124
|
+
auto_connect: false,
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// 创建连接
|
|
128
|
+
create();
|
|
129
|
+
|
|
130
|
+
// 模拟连接错误
|
|
131
|
+
const wsInstance = (global.WebSocket as any).mock.instances[0];
|
|
132
|
+
if (wsInstance) {
|
|
133
|
+
wsInstance.simulateError();
|
|
134
|
+
expect(mockOnError).toHaveBeenCalled();
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('should handle WebSocket close', () => {
|
|
139
|
+
const mockReceive = vi.fn();
|
|
140
|
+
const mockOnClose = vi.fn();
|
|
141
|
+
|
|
142
|
+
const { create } = use_web_socket({
|
|
143
|
+
server: 'ws://localhost:8080',
|
|
144
|
+
receive: mockReceive,
|
|
145
|
+
on_close: mockOnClose,
|
|
146
|
+
auto_connect: false,
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// 创建连接
|
|
150
|
+
create();
|
|
151
|
+
|
|
152
|
+
// 模拟连接成功
|
|
153
|
+
const wsInstance = (global.WebSocket as any).mock.instances[0];
|
|
154
|
+
if (wsInstance) {
|
|
155
|
+
wsInstance.simulateOpen();
|
|
156
|
+
|
|
157
|
+
// 关闭连接
|
|
158
|
+
wsInstance.close();
|
|
159
|
+
|
|
160
|
+
expect(mockOnClose).toHaveBeenCalled();
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('should send message successfully', () => {
|
|
165
|
+
const mockReceive = vi.fn();
|
|
166
|
+
|
|
167
|
+
const { create, send_message } = use_web_socket({
|
|
168
|
+
server: 'ws://localhost:8080',
|
|
169
|
+
receive: mockReceive,
|
|
170
|
+
auto_connect: false,
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// 创建连接
|
|
174
|
+
create();
|
|
175
|
+
|
|
176
|
+
// 模拟连接成功
|
|
177
|
+
const wsInstance = (global.WebSocket as any).mock.instances[0];
|
|
178
|
+
if (wsInstance) {
|
|
179
|
+
wsInstance.simulateOpen();
|
|
180
|
+
|
|
181
|
+
// 发送消息
|
|
182
|
+
const sendSpy = vi.spyOn(wsInstance, 'send');
|
|
183
|
+
const result = send_message('test message');
|
|
184
|
+
|
|
185
|
+
expect(result).toBe(true);
|
|
186
|
+
expect(sendSpy).toHaveBeenCalledWith('test message');
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('should handle send message when not connected', () => {
|
|
191
|
+
const mockReceive = vi.fn();
|
|
192
|
+
|
|
193
|
+
const { send_message } = use_web_socket({
|
|
194
|
+
server: 'ws://localhost:8080',
|
|
195
|
+
receive: mockReceive,
|
|
196
|
+
auto_connect: false,
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
// 未连接时发送消息
|
|
200
|
+
const result = send_message('test message');
|
|
201
|
+
|
|
202
|
+
expect(result).toBe(false);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it('should receive message', () => {
|
|
206
|
+
const mockReceive = vi.fn();
|
|
207
|
+
|
|
208
|
+
const { create } = use_web_socket({
|
|
209
|
+
server: 'ws://localhost:8080',
|
|
210
|
+
receive: mockReceive,
|
|
211
|
+
auto_connect: false,
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
// 创建连接
|
|
215
|
+
create();
|
|
216
|
+
|
|
217
|
+
// 模拟连接成功
|
|
218
|
+
const wsInstance = (global.WebSocket as any).mock.instances[0];
|
|
219
|
+
if (wsInstance) {
|
|
220
|
+
wsInstance.simulateOpen();
|
|
221
|
+
|
|
222
|
+
// 模拟接收消息
|
|
223
|
+
wsInstance.simulateMessage('test message');
|
|
224
|
+
|
|
225
|
+
expect(mockReceive).toHaveBeenCalled();
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it('should reconnect automatically', () => {
|
|
230
|
+
const mockReceive = vi.fn();
|
|
231
|
+
|
|
232
|
+
const { create } = use_web_socket({
|
|
233
|
+
server: 'ws://localhost:8080',
|
|
234
|
+
receive: mockReceive,
|
|
235
|
+
auto_reconnect: true,
|
|
236
|
+
reconnect_interval: 1000,
|
|
237
|
+
auto_connect: false,
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// 创建连接
|
|
241
|
+
create();
|
|
242
|
+
expect(mockWebSocketClass).toHaveBeenCalledTimes(1);
|
|
243
|
+
|
|
244
|
+
// 模拟连接成功
|
|
245
|
+
const wsInstance1 = (global.WebSocket as any).mock.instances[0];
|
|
246
|
+
if (wsInstance1) {
|
|
247
|
+
wsInstance1.simulateOpen();
|
|
248
|
+
|
|
249
|
+
// 关闭连接(非干净关闭)
|
|
250
|
+
wsInstance1.close();
|
|
251
|
+
|
|
252
|
+
// 快进时间,触发重连
|
|
253
|
+
vi.advanceTimersByTime(1000);
|
|
254
|
+
|
|
255
|
+
expect(mockWebSocketClass).toHaveBeenCalledTimes(2);
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it('should start and stop heartbeat', () => {
|
|
260
|
+
const mockReceive = vi.fn();
|
|
261
|
+
|
|
262
|
+
const { create, start_heartbeat, stop_heartbeat } = use_web_socket({
|
|
263
|
+
server: 'ws://localhost:8080',
|
|
264
|
+
receive: mockReceive,
|
|
265
|
+
heartbeat_interval: 5000,
|
|
266
|
+
auto_connect: false,
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
// 创建连接
|
|
270
|
+
create();
|
|
271
|
+
|
|
272
|
+
// 模拟连接成功
|
|
273
|
+
const wsInstance = (global.WebSocket as any).mock.instances[0];
|
|
274
|
+
if (wsInstance) {
|
|
275
|
+
wsInstance.simulateOpen();
|
|
276
|
+
|
|
277
|
+
// 启动心跳
|
|
278
|
+
start_heartbeat();
|
|
279
|
+
|
|
280
|
+
// 快进时间,触发心跳
|
|
281
|
+
const sendSpy = vi.spyOn(wsInstance, 'send');
|
|
282
|
+
vi.advanceTimersByTime(5000);
|
|
283
|
+
|
|
284
|
+
expect(sendSpy).toHaveBeenCalledWith('ping');
|
|
285
|
+
|
|
286
|
+
// 停止心跳
|
|
287
|
+
stop_heartbeat();
|
|
288
|
+
|
|
289
|
+
// 快进时间,不应再触发心跳
|
|
290
|
+
sendSpy.mockClear();
|
|
291
|
+
vi.advanceTimersByTime(5000);
|
|
292
|
+
|
|
293
|
+
expect(sendSpy).not.toHaveBeenCalled();
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
it('should get correct connection status', () => {
|
|
298
|
+
const mockReceive = vi.fn();
|
|
299
|
+
|
|
300
|
+
const { create, get_status, close } = use_web_socket({
|
|
301
|
+
server: 'ws://localhost:8080',
|
|
302
|
+
receive: mockReceive,
|
|
303
|
+
auto_connect: false,
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
// 初始状态
|
|
307
|
+
expect(get_status()).toBe('CLOSED');
|
|
308
|
+
|
|
309
|
+
// 创建连接
|
|
310
|
+
create();
|
|
311
|
+
|
|
312
|
+
// 模拟连接成功
|
|
313
|
+
const wsInstance = (global.WebSocket as any).mock.instances[0];
|
|
314
|
+
if (wsInstance) {
|
|
315
|
+
wsInstance.simulateOpen();
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// 关闭连接
|
|
319
|
+
close();
|
|
320
|
+
expect(get_status()).toBe('CLOSED');
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
it('should handle connection with auto_connect', () => {
|
|
324
|
+
const mockReceive = vi.fn();
|
|
325
|
+
|
|
326
|
+
use_web_socket({
|
|
327
|
+
server: 'ws://localhost:8080',
|
|
328
|
+
receive: mockReceive,
|
|
329
|
+
auto_connect: true,
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
expect(mockWebSocketClass).toHaveBeenCalledWith('ws://localhost:8080');
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
it('should handle connection error with auto_reconnect', () => {
|
|
336
|
+
const mockReceive = vi.fn();
|
|
337
|
+
|
|
338
|
+
use_web_socket({
|
|
339
|
+
server: 'ws://localhost:8080',
|
|
340
|
+
receive: mockReceive,
|
|
341
|
+
auto_reconnect: true,
|
|
342
|
+
reconnect_interval: 1000,
|
|
343
|
+
auto_connect: true,
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
expect(mockWebSocketClass).toHaveBeenCalledTimes(1);
|
|
347
|
+
|
|
348
|
+
// 模拟连接错误
|
|
349
|
+
const wsInstance = (global.WebSocket as any).mock.instances[0];
|
|
350
|
+
if (wsInstance) {
|
|
351
|
+
wsInstance.simulateError();
|
|
352
|
+
|
|
353
|
+
// 快进时间,触发重连
|
|
354
|
+
vi.advanceTimersByTime(1000);
|
|
355
|
+
|
|
356
|
+
expect(mockWebSocketClass).toHaveBeenCalledTimes(2);
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
it('should handle message queue when not connected', () => {
|
|
361
|
+
const mockReceive = vi.fn();
|
|
362
|
+
|
|
363
|
+
const { send_message, create } = use_web_socket({
|
|
364
|
+
server: 'ws://localhost:8080',
|
|
365
|
+
receive: mockReceive,
|
|
366
|
+
auto_connect: false,
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
// 未连接时发送消息
|
|
370
|
+
send_message('message 1');
|
|
371
|
+
send_message('message 2');
|
|
372
|
+
|
|
373
|
+
// 创建连接
|
|
374
|
+
create();
|
|
375
|
+
|
|
376
|
+
// 模拟连接成功
|
|
377
|
+
const wsInstance = (global.WebSocket as any).mock.instances[0];
|
|
378
|
+
if (wsInstance) {
|
|
379
|
+
const sendSpy = vi.spyOn(wsInstance, 'send');
|
|
380
|
+
wsInstance.simulateOpen();
|
|
381
|
+
|
|
382
|
+
// 验证队列中的消息是否被发送
|
|
383
|
+
expect(sendSpy).toHaveBeenCalledTimes(2);
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
it('should limit message queue size', () => {
|
|
388
|
+
const mockReceive = vi.fn();
|
|
389
|
+
|
|
390
|
+
const { send_message } = use_web_socket({
|
|
391
|
+
server: 'ws://localhost:8080',
|
|
392
|
+
receive: mockReceive,
|
|
393
|
+
auto_connect: false,
|
|
394
|
+
max_message_queue_size: 2,
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
// 未连接时发送多条消息
|
|
398
|
+
send_message('message 1');
|
|
399
|
+
send_message('message 2');
|
|
400
|
+
send_message('message 3'); // 这应该替换最旧的消息
|
|
401
|
+
});
|
|
402
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
(function(R,Y){typeof exports=="object"&&typeof module<"u"?Y(exports,require("mitt"),require("vue")):typeof define=="function"&&define.amd?define(["exports","mitt","vue"],Y):(R=typeof globalThis<"u"?globalThis:R||self,Y(R.QyBetterLibHooks={},R.mitt,R.Vue))})(this,(function(R,Y,J){"use strict";function me(){if(typeof Y>"u")return{};const e=Y();return e.emitAsync=async function(n,...i){const a=this.all?.get(n);if(!a||a.length===0)return[];const _=a.map(m=>{try{const x=m(...i);return x instanceof Promise?x:Promise.resolve(x)}catch(x){return Promise.reject(x)}});return Promise.all(_)},e.emit,e.emit=function(n,...i){const a=this.all?.get(n);if(!a||a.length===0)return;let _;return a.forEach(m=>{try{_=m(...i)}catch(x){console.error(`Error in event handler for ${n}:`,x)}}),_},e}const ce=me();function _e(e){return typeof Y>"u"?{emitter:{}}:(J.onMounted(()=>{if(e&&e.length>0)for(const n of e)ce.on(n.key,n.value)}),J.onUnmounted(()=>{if(e&&e.length>0)for(const n of e)ce.off(n.key,n.value)}),{emitter:ce})}function ge(){let e=null,n=!1;function i(o,r){const t=r?.page_size||"A4",u=r?.page_orientation||"portrait",d=r?.margin||"1cm",p=r?.print_background?"true":"false",s=`#print-container {
|
|
2
|
+
display: none;
|
|
3
|
+
}
|
|
4
|
+
#preview-container {
|
|
5
|
+
position: fixed;
|
|
6
|
+
top: 0;
|
|
7
|
+
left: 0;
|
|
8
|
+
width: 100%;
|
|
9
|
+
height: 100%;
|
|
10
|
+
background: rgba(0, 0, 0, 0.8);
|
|
11
|
+
display: flex;
|
|
12
|
+
justify-content: center;
|
|
13
|
+
align-items: center;
|
|
14
|
+
z-index: 9999;
|
|
15
|
+
overflow: auto;
|
|
16
|
+
}
|
|
17
|
+
#preview-content {
|
|
18
|
+
background: white;
|
|
19
|
+
width: 80%;
|
|
20
|
+
max-width: 800px;
|
|
21
|
+
padding: 20px;
|
|
22
|
+
box-shadow: 0 0 20px rgba(0, 0, 0, 0.3);
|
|
23
|
+
position: relative;
|
|
24
|
+
}
|
|
25
|
+
#preview-close {
|
|
26
|
+
position: absolute;
|
|
27
|
+
top: 10px;
|
|
28
|
+
right: 10px;
|
|
29
|
+
background: #333;
|
|
30
|
+
color: white;
|
|
31
|
+
border: none;
|
|
32
|
+
border-radius: 50%;
|
|
33
|
+
width: 30px;
|
|
34
|
+
height: 30px;
|
|
35
|
+
cursor: pointer;
|
|
36
|
+
font-size: 16px;
|
|
37
|
+
display: flex;
|
|
38
|
+
justify-content: center;
|
|
39
|
+
align-items: center;
|
|
40
|
+
}
|
|
41
|
+
#preview-print {
|
|
42
|
+
margin-top: 20px;
|
|
43
|
+
padding: 10px 20px;
|
|
44
|
+
background: #007bff;
|
|
45
|
+
color: white;
|
|
46
|
+
border: none;
|
|
47
|
+
border-radius: 4px;
|
|
48
|
+
cursor: pointer;
|
|
49
|
+
font-size: 16px;
|
|
50
|
+
}
|
|
51
|
+
@media print {
|
|
52
|
+
body > :not(#print-container) {
|
|
53
|
+
display: none;
|
|
54
|
+
}
|
|
55
|
+
html,
|
|
56
|
+
body {
|
|
57
|
+
display: block !important;
|
|
58
|
+
margin: 0;
|
|
59
|
+
padding: 0;
|
|
60
|
+
width: 100%;
|
|
61
|
+
height: 100%;
|
|
62
|
+
-webkit-print-color-adjust: ${p};
|
|
63
|
+
print-color-adjust: ${p};
|
|
64
|
+
}
|
|
65
|
+
#print-container {
|
|
66
|
+
display: block;
|
|
67
|
+
padding: 20px;
|
|
68
|
+
width: 100%;
|
|
69
|
+
height: 100%;
|
|
70
|
+
box-sizing: border-box;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
@page {
|
|
74
|
+
size: ${t} ${u};
|
|
75
|
+
margin: ${d};
|
|
76
|
+
}`,l=document.createElement("style");return l.innerHTML=o||s,l}function a(){const o=document.getElementById("print-container");if(o)try{document.body.removeChild(o)}catch(r){console.error("清理打印容器失败:",r)}}function _(){const o=document.getElementById("preview-container");if(o)try{document.body.removeChild(o),e=null}catch(r){console.error("清理预览容器失败:",r)}}function m(o){a();const r=document.createElement("div");return r.setAttribute("id","print-container"),r.innerHTML=o,r}function x(o){if(!o||typeof o.querySelectorAll!="function")return Promise.resolve();const r=o.querySelectorAll("img"),t=Array.from(r);if(t.length===0)return Promise.resolve();let u=0;return new Promise((d,p)=>{function s(){u++,u===t.length&&d()}t.forEach(l=>{l.complete?s():(l.addEventListener("load",s),l.addEventListener("error",s))}),setTimeout(()=>{p(new Error("图片加载超时"))},1e4)})}async function $(o,r){if(n){console.warn("打印已在进行中");return}try{n=!0;const t=i(r?.custom_style,r),u=m(o);document.body.appendChild(t),document.body.appendChild(u),await x(u),window.print(),setTimeout(()=>{try{t.parentNode&&t.parentNode.removeChild(t),u.parentNode&&u.parentNode.removeChild(u),n=!1,r?.on_complete?.()}catch(d){console.error("清理打印元素失败:",d),r?.on_error?.(d)}},100)}catch(t){console.error("打印失败:",t),n=!1,r?.on_error?.(t)}}async function z(o,r){try{_();const t=i(r?.custom_style,r),u=document.createElement("div");u.innerHTML=o,await x(u);const d=document.createElement("div");d.setAttribute("id","preview-container");const p=document.createElement("div");p.setAttribute("id","preview-content"),p.appendChild(u);const s=document.createElement("button");s.setAttribute("id","preview-close"),s.textContent="×",s.addEventListener("click",()=>{_(),r?.on_cancel?.()});const l=document.createElement("button");l.setAttribute("id","preview-print"),l.textContent="打印",l.addEventListener("click",()=>{_(),$(o,r)}),p.appendChild(s),p.appendChild(l),d.appendChild(p),document.body.appendChild(t),document.body.appendChild(d),e=d}catch(t){console.error("预览失败:",t),r?.on_error?.(t)}}async function C(o,r){try{const t=document.querySelector(o);if(t)r?.preview?await z(t.innerHTML,r):await $(t.innerHTML,r);else throw new Error(`未找到DOM节点: ${o}`)}catch(t){console.error("打印DOM元素失败:",t),r?.on_error?.(t)}}async function q(o,r){try{if(!o||o.length===0)throw new Error("元素数组为空");let t="";for(const u of o)t+=u.outerHTML;if(!t)throw new Error("元素内容为空");r?.preview?await z(t,r):await $(t,r)}catch(t){console.error("打印元素数组失败:",t),r?.on_error?.(t)}}function E(o,r){try{const t=document.querySelector(o);if(t)z(t.innerHTML,r);else throw new Error(`未找到DOM节点: ${o}`)}catch(t){console.error("预览DOM元素失败:",t),r?.on_error?.(t)}}function T(o,r){try{if(!o||o.length===0)throw new Error("元素数组为空");let t="";for(const u of o)t+=u.outerHTML;if(!t)throw new Error("元素内容为空");z(t,r)}catch(t){console.error("预览元素数组失败:",t),r?.on_error?.(t)}}function y(){_()}return{print_html:C,print_html_element:q,preview_html:E,preview_html_element:T,close_preview:y}}function ye(){const e=pe;return`${e()}${e()}-${e()}-${e()}-${e()}-${e()}${e()}${e()}`}function pe(){return Math.floor((1+Math.random())*65536).toString(16).substring(1)}function Z(e){return typeof e=="object"&&e!==null&&Object.prototype.toString.call(e)==="[object Object]"}const we=typeof window<"u";function te(e){const n=Object.prototype.toString;if(!e||typeof e!="object")return e;if(e.nodeType&&"cloneNode"in e)return e.cloneNode(!0);if(n.call(e)==="[object Date]")return new Date(e.getTime());if(n.call(e)==="[object RegExp]"){const a=[];return e.global&&a.push("g"),e.multiline&&a.push("m"),e.ignoreCase&&a.push("i"),new RegExp(e.source,a.join(""))}if(n.call(e)==="[object FormData]"){const a=new FormData;for(const[_,m]of e.entries())a.append(_,m);return a}if(n.call(e)==="[object Map]"){const a=new Map;for(const[_,m]of e.entries())a.set(_,te(m));return a}if(n.call(e)==="[object Set]"){const a=new Set;for(const _ of e.values())a.add(te(_));return a}const i=Array.isArray(e)?[]:e.constructor?new e.constructor:{};for(const a in e)Object.prototype.hasOwnProperty.call(e,a)&&(i[a]=te(e[a]));return i}function re(...e){let n=e.length,i=e[0];Z(i)||(i={});for(let a=1;a<n;a++){let _=e[a];if(Z(_))for(let m in _)m==="__proto__"||i===_[m]||(Z(_[m])?(Z(i[m])||(i[m]=Array.isArray(_[m])?[]:{}),i[m]=re(i[m],_[m])):i[m]=_[m])}return i}function ae(e,n=document){return n.querySelector(e)}function ue(e,n,i,a){e&&e.addEventListener(n,i,a)}function se(e,n,i,a){e&&e.removeEventListener(n,i,a)}function ve(){return{width:window.innerWidth||document.documentElement.clientWidth,height:window.innerHeight||document.documentElement.clientHeight}}function be({path:e,name:n}){const i=document.createElement("a");i.href=e,i.target="_blank",n&&i.setAttribute("download",n),document.body.appendChild(i),i.click(),document.body.removeChild(i)}async function xe(e){if(!e)return;const n=new FileReader;return n.readAsDataURL(e),new Promise((i,a)=>{n.onload=_=>i(_.target?.result),n.onerror=_=>a(void 0)})}async function $e(e,n=800,i=800,a=.8){if(e.type.startsWith("image/"))return new Promise(_=>{const m=document.createElement("canvas"),x=m.getContext("2d"),$=new Image;$.onload=()=>{let{width:z,height:C}=$;if(z>n||C>i){const q=Math.min(n/z,i/C);z*=q,C*=q}m.width=z,m.height=C,x?.drawImage($,0,0,z,C),m.toBlob(q=>{if(q){const E=new File([q],e.name,{type:e.type});_(E)}else _(void 0)},e.type,a)},$.src=URL.createObjectURL(e)})}var ne={exports:{}},Se=ne.exports,le;function Ee(){return le||(le=1,(function(e,n){(function(i,a){e.exports=a()})(Se,(function(){var i=1e3,a=6e4,_=36e5,m="millisecond",x="second",$="minute",z="hour",C="day",q="week",E="month",T="quarter",y="year",o="date",r="Invalid Date",t=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,u=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,d={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(v){var h=["th","st","nd","rd"],f=v%100;return"["+v+(h[(f-20)%10]||h[f]||h[0])+"]"}},p=function(v,h,f){var w=String(v);return!w||w.length>=h?v:""+Array(h+1-w.length).join(f)+v},s={s:p,z:function(v){var h=-v.utcOffset(),f=Math.abs(h),w=Math.floor(f/60),c=f%60;return(h<=0?"+":"-")+p(w,2,"0")+":"+p(c,2,"0")},m:function v(h,f){if(h.date()<f.date())return-v(f,h);var w=12*(f.year()-h.year())+(f.month()-h.month()),c=h.clone().add(w,E),b=f-c<0,D=h.clone().add(w+(b?-1:1),E);return+(-(w+(f-c)/(b?c-D:D-c))||0)},a:function(v){return v<0?Math.ceil(v)||0:Math.floor(v)},p:function(v){return{M:E,y,w:q,d:C,D:o,h:z,m:$,s:x,ms:m,Q:T}[v]||String(v||"").toLowerCase().replace(/s$/,"")},u:function(v){return v===void 0}},l="en",g={};g[l]=d;var S="$isDayjsObject",O=function(v){return v instanceof A||!(!v||!v[S])},L=function v(h,f,w){var c;if(!h)return l;if(typeof h=="string"){var b=h.toLowerCase();g[b]&&(c=b),f&&(g[b]=f,c=b);var D=h.split("-");if(!c&&D.length>1)return v(D[0])}else{var N=h.name;g[N]=h,c=N}return!w&&c&&(l=c),c||!w&&l},k=function(v,h){if(O(v))return v.clone();var f=typeof h=="object"?h:{};return f.date=v,f.args=arguments,new A(f)},M=s;M.l=L,M.i=O,M.w=function(v,h){return k(v,{locale:h.$L,utc:h.$u,x:h.$x,$offset:h.$offset})};var A=(function(){function v(f){this.$L=L(f.locale,null,!0),this.parse(f),this.$x=this.$x||f.x||{},this[S]=!0}var h=v.prototype;return h.parse=function(f){this.$d=(function(w){var c=w.date,b=w.utc;if(c===null)return new Date(NaN);if(M.u(c))return new Date;if(c instanceof Date)return new Date(c);if(typeof c=="string"&&!/Z$/i.test(c)){var D=c.match(t);if(D){var N=D[2]-1||0,B=(D[7]||"0").substring(0,3);return b?new Date(Date.UTC(D[1],N,D[3]||1,D[4]||0,D[5]||0,D[6]||0,B)):new Date(D[1],N,D[3]||1,D[4]||0,D[5]||0,D[6]||0,B)}}return new Date(c)})(f),this.init()},h.init=function(){var f=this.$d;this.$y=f.getFullYear(),this.$M=f.getMonth(),this.$D=f.getDate(),this.$W=f.getDay(),this.$H=f.getHours(),this.$m=f.getMinutes(),this.$s=f.getSeconds(),this.$ms=f.getMilliseconds()},h.$utils=function(){return M},h.isValid=function(){return this.$d.toString()!==r},h.isSame=function(f,w){var c=k(f);return this.startOf(w)<=c&&c<=this.endOf(w)},h.isAfter=function(f,w){return k(f)<this.startOf(w)},h.isBefore=function(f,w){return this.endOf(w)<k(f)},h.$g=function(f,w,c){return M.u(f)?this[w]:this.set(c,f)},h.unix=function(){return Math.floor(this.valueOf()/1e3)},h.valueOf=function(){return this.$d.getTime()},h.startOf=function(f,w){var c=this,b=!!M.u(w)||w,D=M.p(f),N=function(Q,F){var j=M.w(c.$u?Date.UTC(c.$y,F,Q):new Date(c.$y,F,Q),c);return b?j:j.endOf(C)},B=function(Q,F){return M.w(c.toDate()[Q].apply(c.toDate("s"),(b?[0,0,0,0]:[23,59,59,999]).slice(F)),c)},H=this.$W,I=this.$M,U=this.$D,K="set"+(this.$u?"UTC":"");switch(D){case y:return b?N(1,0):N(31,11);case E:return b?N(1,I):N(0,I+1);case q:var V=this.$locale().weekStart||0,X=(H<V?H+7:H)-V;return N(b?U-X:U+(6-X),I);case C:case o:return B(K+"Hours",0);case z:return B(K+"Minutes",1);case $:return B(K+"Seconds",2);case x:return B(K+"Milliseconds",3);default:return this.clone()}},h.endOf=function(f){return this.startOf(f,!1)},h.$set=function(f,w){var c,b=M.p(f),D="set"+(this.$u?"UTC":""),N=(c={},c[C]=D+"Date",c[o]=D+"Date",c[E]=D+"Month",c[y]=D+"FullYear",c[z]=D+"Hours",c[$]=D+"Minutes",c[x]=D+"Seconds",c[m]=D+"Milliseconds",c)[b],B=b===C?this.$D+(w-this.$W):w;if(b===E||b===y){var H=this.clone().set(o,1);H.$d[N](B),H.init(),this.$d=H.set(o,Math.min(this.$D,H.daysInMonth())).$d}else N&&this.$d[N](B);return this.init(),this},h.set=function(f,w){return this.clone().$set(f,w)},h.get=function(f){return this[M.p(f)]()},h.add=function(f,w){var c,b=this;f=Number(f);var D=M.p(w),N=function(I){var U=k(b);return M.w(U.date(U.date()+Math.round(I*f)),b)};if(D===E)return this.set(E,this.$M+f);if(D===y)return this.set(y,this.$y+f);if(D===C)return N(1);if(D===q)return N(7);var B=(c={},c[$]=a,c[z]=_,c[x]=i,c)[D]||1,H=this.$d.getTime()+f*B;return M.w(H,this)},h.subtract=function(f,w){return this.add(-1*f,w)},h.format=function(f){var w=this,c=this.$locale();if(!this.isValid())return c.invalidDate||r;var b=f||"YYYY-MM-DDTHH:mm:ssZ",D=M.z(this),N=this.$H,B=this.$m,H=this.$M,I=c.weekdays,U=c.months,K=c.meridiem,V=function(F,j,ee,ie){return F&&(F[j]||F(w,b))||ee[j].slice(0,ie)},X=function(F){return M.s(N%12||12,F,"0")},Q=K||function(F,j,ee){var ie=F<12?"AM":"PM";return ee?ie.toLowerCase():ie};return b.replace(u,(function(F,j){return j||(function(ee){switch(ee){case"YY":return String(w.$y).slice(-2);case"YYYY":return M.s(w.$y,4,"0");case"M":return H+1;case"MM":return M.s(H+1,2,"0");case"MMM":return V(c.monthsShort,H,U,3);case"MMMM":return V(U,H);case"D":return w.$D;case"DD":return M.s(w.$D,2,"0");case"d":return String(w.$W);case"dd":return V(c.weekdaysMin,w.$W,I,2);case"ddd":return V(c.weekdaysShort,w.$W,I,3);case"dddd":return I[w.$W];case"H":return String(N);case"HH":return M.s(N,2,"0");case"h":return X(1);case"hh":return X(2);case"a":return Q(N,B,!0);case"A":return Q(N,B,!1);case"m":return String(B);case"mm":return M.s(B,2,"0");case"s":return String(w.$s);case"ss":return M.s(w.$s,2,"0");case"SSS":return M.s(w.$ms,3,"0");case"Z":return D}return null})(F)||D.replace(":","")}))},h.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},h.diff=function(f,w,c){var b,D=this,N=M.p(w),B=k(f),H=(B.utcOffset()-this.utcOffset())*a,I=this-B,U=function(){return M.m(D,B)};switch(N){case y:b=U()/12;break;case E:b=U();break;case T:b=U()/3;break;case q:b=(I-H)/6048e5;break;case C:b=(I-H)/864e5;break;case z:b=I/_;break;case $:b=I/a;break;case x:b=I/i;break;default:b=I}return c?b:M.a(b)},h.daysInMonth=function(){return this.endOf(E).$D},h.$locale=function(){return g[this.$L]},h.locale=function(f,w){if(!f)return this.$L;var c=this.clone(),b=L(f,w,!0);return b&&(c.$L=b),c},h.clone=function(){return M.w(this.$d,this)},h.toDate=function(){return new Date(this.valueOf())},h.toJSON=function(){return this.isValid()?this.toISOString():null},h.toISOString=function(){return this.$d.toISOString()},h.toString=function(){return this.$d.toUTCString()},v})(),P=A.prototype;return k.prototype=P,[["$ms",m],["$s",x],["$m",$],["$H",z],["$W",C],["$M",E],["$y",y],["$D",o]].forEach((function(v){P[v[1]]=function(h){return this.$g(h,v[0],v[1])}})),k.extend=function(v,h){return v.$i||(v(h,A,k),v.$i=!0),k},k.locale=L,k.isDayjs=O,k.unix=function(v){return k(1e3*v)},k.en=g[l],k.Ls=g,k.p={},k}))})(ne)),ne.exports}Ee();function W(e,n=1920){let i=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;if(!i)return e;let a=i/n;return Number((e*a).toFixed(3))}function Me(e,n,i){return{type:"linear",x:0,y:0,x2:e==="v"?0:1,y2:e==="v"?1:0,colorStops:[{offset:0,color:n},{offset:1,color:i}]}}function ke(e,n,i="canvas",a){return(async()=>{try{let m;if(typeof window<"u"&&window.echarts)m=window.echarts;else{const z=await import("echarts");m=z.default||z}const x=typeof e=="string"?document.getElementById(e):e;if(!x)return console.error("ECharts DOM容器未找到"),null;const $=m.init(x,a,{renderer:i});return n&&$.setOption(n),$}catch(m){return console.error("加载 ECharts 失败:",m),null}})()}function fe(e){e&&typeof e.dispose=="function"&&e.dispose()}function De(e,n){e&&typeof e.setOption=="function"&&e.setOption(n)}function de(e){e&&typeof e.resize=="function"&&e.resize()}function Le(e,n=200){if(!e)return;let i;const a=()=>{clearTimeout(i),i=setTimeout(()=>{de(e)},n)};return window.addEventListener("resize",a),()=>{window.removeEventListener("resize",a),clearTimeout(i)}}function ze(e,n){const a=n||["#5470c6","#91cc75","#fac858","#ee6666","#73c0de","#3ba272","#fc8452","#9a60b4","#ea7ccc","#67c23a"],_=[];for(let m=0;m<e;m++)_.push(a[m%a.length]);return _}function Ce(e,n){return{...e,...n,series:n.series||e.series,xAxis:n.xAxis||e.xAxis,yAxis:n.yAxis||e.yAxis,legend:n.legend||e.legend,tooltip:n.tooltip||e.tooltip,title:n.title||e.title}}function Te(e,n,i){e&&typeof e.on=="function"&&e.on(n,i)}function qe(e,n,i){e&&typeof e.off=="function"&&e.off(n,i)}function Ne(e,n={}){if(!e||typeof e.getDataURL!="function")return null;const{type:i="png",pixel_ratio:a=2,background_color:_="#fff",exclude_components:m=[],file_name:x="echarts-image"}=n,$=e.getDataURL({type:i,pixelRatio:a,backgroundColor:_,excludeComponents:m}),z=document.createElement("a");return z.download=`${x}.${i}`,z.href=$,z.click(),$}const Oe=new Map;let oe=null;we&&(document.addEventListener("mousedown",e=>{oe=e}),document.addEventListener("mouseup",e=>{for(const n of Oe.values())for(const{document_handler:i}of n)oe&&i(e,oe);oe=null}));function Ae(){const e=ye();let n=null,i=null;function a(E){return E&&ae(E)||document.body}function _(E){const{text1:T,text2:y,font_size:o=16,font_family:r="Avenir,Helvetica,Arial,sans-serif",rotate:t=-15,text_color:u="#999",opacity:d=.1,size:p={width:250,height:150}}=E;try{const s=document.createElement("canvas");s.width=p.width,s.height=p.height;const l=s.getContext("2d");if(l&&(l.font=`${o}px ${r}`,l.fillStyle=u.replace(/\,\s(1|(0\.\d+)\))/,`, ${d}`),l.textAlign="left",l.textBaseline="middle",l.rotate(t*Math.PI/180),l.fillText(T,0,s.height/2),y)){const g=l.measureText(T).width;l.fillText(y,g+16,s.height/2)}return s}catch(s){console.error("创建水印画布失败:",s);const l=document.createElement("canvas");return l.width=0,l.height=0,l}}function m(E){const{wrapper:T,z_index:y=1e5,position:o="fixed",spacing:r=0,size:t={width:250,height:150}}=E,u=a(T),d=document.getElementById(e);if(d)try{u.removeChild(d)}catch(g){console.error("移除旧水印失败:",g)}const p=_(E),s=document.createElement("div");s.id=e,s.style.pointerEvents="none",s.style.top="0px",s.style.left="0px",s.style.position=o,s.style.zIndex=y.toString();const l=ve();s.style.width=l.width+"px",s.style.height=l.height+"px",s.style.background=`url(${p.toDataURL("image/png")}) left top repeat`,r>0&&(s.style.backgroundSize=`${t.width+r}px ${t.height+r}px`);try{u.appendChild(s)}catch(g){console.error("添加水印失败:",g)}}function x(){n&&m(n)}function $(E){n=E,m(E),E.responsive?i||(i=x,ue(window,"resize",i)):i&&(se(window,"resize",i),i=null)}function z(){const E=document.getElementById(e);if(E)try{const T=E.parentElement;T&&T.removeChild(E)}catch(T){console.error("移除水印失败:",T)}i&&(se(window,"resize",i),i=null),n=null}function C(E){if(n){const T={...n,...E};$(T)}else console.warn("水印未初始化,请先调用 create_water_mark")}function q(){return document.getElementById(e)!==null}return{create_water_mark:$,remove_water_mark:z,update_water_mark:C,has_water_mark:q}}function We(e){const{server:n,receive:i,max_reconnect_attempts:a=5,reconnect_interval:_=5e3,heartbeat_interval:m=3e4,heartbeat_message:x="ping",on_open:$,on_error:z,on_close:C,auto_reconnect:q=!0,auto_connect:E=!0,max_message_queue_size:T=100}=e;let y=0,o=!1,r,t=null,u=null,d=[],p=0;const s=m*1.5;typeof window<"u"&&(window.onbeforeunload=()=>{f()});function l(){try{console.log("正在连接WebSocket:",n),r=new WebSocket(n),g()}catch(c){console.error("WebSocket连接建立异常:",c),z?.(c),q&&S()}}function g(){r&&(r.onopen=()=>{console.log("WebSocket连接成功:",n),y=0,p=Date.now(),L(),h(),$?.()},r.onerror=c=>{console.error("WebSocket连接错误:",c),z?.(c)},r.onclose=c=>{console.log("WebSocket连接关闭:",new Date().toLocaleTimeString(),"原因:",c.code,c.reason),k(),C?.(),q&&!c.wasClean&&S()},r.onmessage=c=>{try{p=Date.now(),i(c)}catch(b){console.error("WebSocket消息处理错误:",b),console.log("原始消息:",c.data)}})}function S(){if(y>=a){console.error("WebSocket重连失败次数过多,停止重连"),f();return}o||(o=!0,console.log(`WebSocket尝试重连 ${y+1}/${a}...`),t=setTimeout(()=>{l(),y++,o=!1,O()},_))}function O(){t&&(clearTimeout(t),t=null)}function L(){k(),u=setInterval(()=>{M(),A()},m)}function k(){u&&(clearInterval(u),u=null)}function M(){if(r?.readyState===WebSocket.OPEN)try{const c=Z(x)?JSON.stringify(x):x;r.send(c)}catch(c){console.error("发送心跳消息失败:",c)}}function A(){Date.now()-p>s&&(console.error("WebSocket心跳超时,尝试重连"),S())}function P(c){if(r?.readyState===WebSocket.OPEN)try{const b=Z(c)?JSON.stringify(c):c;return r.send(b),!0}catch(b){return console.error("发送消息失败:",b),v(c),!1}else return console.warn("WebSocket未连接,消息已加入队列"),v(c),!1}function v(c){if(d.length>=T){const b=d.shift();console.warn("消息队列已满,移除最旧的消息:",b)}d.push(c),console.log(`消息已加入队列,当前队列大小: ${d.length}/${T}`)}function h(){if(r?.readyState===WebSocket.OPEN&&d.length>0)for(console.log(`发送队列中的 ${d.length} 条消息`);d.length>0;){const c=d.shift();P(c)}}function f(){if(k(),O(),r){try{r.close()}catch(c){console.error("关闭WebSocket失败:",c)}r=void 0}d=[]}function w(){if(!r)return"CLOSED";switch(r.readyState){case WebSocket.CONNECTING:return"CONNECTING";case WebSocket.OPEN:return"OPEN";case WebSocket.CLOSING:return"CLOSING";case WebSocket.CLOSED:return"CLOSED";default:return"UNKNOWN"}}return E&&l(),{ws:r,create:l,close:f,send_message:P,get_status:w,reconnect:S,start_heartbeat:L,stop_heartbeat:k}}var G=(e=>(e.PNG="image/png",e.JPEG="image/jpeg",e.GIF="image/gif",e))(G||{});function Pe(){function e(y){return Object.values(G).includes(y)}async function n(y,o=.92,r=G.JPEG){return e(r)||(r=G.JPEG),y.toDataURL(r,o)}async function i(y,o="image",r=.92,t=G.JPEG){const u=await n(y,r,t);return a(u,t,o)}async function a(y,o=G.JPEG,r="image"){e(o)||(o=G.JPEG);const t=y.split(","),u=t[0].match(/:(.*?);/)?.[1]||o,d=atob(t[1]);let p=d.length;const s=new Uint8Array(p);for(;p--;)s[p]=d.charCodeAt(p);const l=u.split("/")[1],g=`${r}.${l}`;return new File([s],g,{type:u})}async function _(y){return new Promise((o,r)=>{const t=new Image;t.onload=()=>o(t),t.onerror=r,t.src=y})}function m(y,o="download"){const r=URL.createObjectURL(y);be({path:r,name:o}),URL.revokeObjectURL(r)}async function x(y){const o=await xe(y);if(!o)throw new Error("转换文件为DataURL失败");return o}async function $(y,o={}){const r=document.createElement("canvas"),t=r.getContext("2d");if(!t)throw new Error("创建Canvas上下文失败");const u=o.width||y.width,d=o.height||y.height,p=o.scale||1;return r.width=u*p,r.height=d*p,t.scale(p,p),t.drawImage(y,0,0,u,d),r}async function z(y){const o=await fetch(y);if(!o.ok)throw new Error(`获取图片失败: ${o.statusText}`);return o.blob()}async function C(y){return new Promise((o,r)=>{const t=new Image;t.onload=()=>o(t),t.onerror=r,t.src=y})}async function q(y,o={}){if(!(y instanceof Blob))throw new Error("compress(): 第一个参数必须是Blob对象或File对象");const r=Math.max(0,Math.min(1,isNaN(Number(o.quality))?.92:Number(o.quality)));o.quality=r;const t=await x(y),u=t.split(",")[0].match(/:(.*?);/)?.[1];let d=G.JPEG;e(o.type)&&(d=o.type);const p=await _(t),s=await $(p,o),l=await n(s,o.quality,d),g=await a(l,u||d);return g.size>y.size?y:g}async function E(y,o={}){if(!(y instanceof Blob))throw new Error("compressAccurately(): 第一个参数必须是Blob对象或File对象");const r=Math.max(0,isNaN(Number(o.size))?0:Number(o.size));o.size=r;const t=Math.max(.8,Math.min(.99,isNaN(Number(o.accuracy))?.95:Number(o.accuracy)));if(o.accuracy=t,isNaN(o.size)||o.size*1024>y.size)return y;(!o.accuracy||o.accuracy<.8||o.accuracy>.99)&&(o.accuracy=.95);const u={max:o.size*(2-o.accuracy)*1024,accurate:o.size*1024,min:o.size*o.accuracy*1024},d=await x(y),p=d.split(",")[0].match(/:(.*?);/)?.[1];let s=G.JPEG;e(o.type)&&(s=o.type);const l=await _(d),g=await $(l,o),S=.75;let O=1,L="";const k=[];for(let A=1;A<=7;A++){L=await n(g,O,s);const P=L.length*S;if(A===7){(u.max<P||u.min>P)&&(L=[L,...k].filter(Boolean).sort((v,h)=>Math.abs(v.length*S-u.accurate)-Math.abs(h.length*S-u.accurate))[0]);break}if(u.max<P)k[1]=L,O-=.5**(A+1);else if(u.min>P)k[0]=L,O+=.5**(A+1);else break}const M=await a(L,p||s);return M.size>y.size?y:M}async function T(y,o=800,r=800,t=.8){return $e(y,o,r,t)}return{compress:q,compress_accurately:E,compress_image:T,canvas_to_data_url:n,canvas_to_file:i,data_url_to_file:a,data_url_to_image:_,file_to_data_url:x,image_to_canvas:$,url_to_blob:z,url_to_image:C,download_file:m}}function Be(e){const n=J.ref(!1),i=J.shallowRef(null);function a(){n.value=document.fullscreenElement===i.value}J.onMounted(()=>{i.value=ae(e),i.value&&ue(i.value,"fullscreenchange",a)}),J.onUnmounted(()=>{i.value&&se(i.value,"fullscreenchange",a)});function _(){!n.value&&i.value?.requestFullscreen&&i.value.requestFullscreen().catch($=>{console.error("进入全屏失败:",$)})}function m(){document.exitFullscreen&&document.exitFullscreen().catch($=>{console.error("退出全屏失败:",$)})}function x(){n.value?m():_()}return{container:i,full:n,toggle_fullscreen:x,enter_fullscreen:_,exit_fullscreen:m}}const he={textStyle:{fontSize:W(12),fontFamily:"Helvetica Neue, Arial, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, sans-serif"},color:[],title:{textStyle:{fontSize:W(14)}},legend:{icon:"rect",itemHeight:W(12),itemWidth:W(12),textStyle:{color:"#606266",fontSize:W(12)},itemStyle:{shadowColor:"rgba(161, 163, 170, 0.25)",shadowBlur:W(4),shadowOffsetX:W(4),shadowOffsetY:W(4)}},tooltip:{trigger:"axis",axisPointer:{lineStyle:{color:"#D4D9E2",width:W(1)}},backgroundColor:"rgba(0,0,0,0.6)",textStyle:{color:"#fff",fontWeight:400,width:W(10),height:W(10),fontSize:W(12)},borderWidth:0,padding:[W(8),W(16)],formatter:"{a}<br/>{b}: {c}"},xAxis:{axisLine:{lineStyle:{color:"#D4D9E2",width:W(1)}},axisLabel:{color:"#606266",fontSize:W(12)},nameTextStyle:{color:"#606266",fontSize:W(12)},splitLine:{show:!1,lineStyle:{color:"#EBECEF",type:"dashed",width:W(1)}}},yAxis:{axisLine:{show:!1,lineStyle:{color:"#D4D9E2",width:W(1)}},axisLabel:{color:"#606266",fontSize:W(12)},nameTextStyle:{color:"#606266",fontSize:W(12)},splitLine:{lineStyle:{color:"#EBECEF",type:"dashed",width:W(1)}}}};function He(e){return{backgroundColor:"#1a1a1a",textStyle:{color:"#ccc"},title:{textStyle:{color:"#fff"}},legend:{textStyle:{color:"#ccc"}},xAxis:{axisLine:{lineStyle:{color:"#444"}},axisLabel:{color:"#ccc"},splitLine:{lineStyle:{color:"#333"}}},yAxis:{axisLine:{lineStyle:{color:"#444"}},axisLabel:{color:"#ccc"},splitLine:{lineStyle:{color:"#333"}}}}}function Re(e={}){const{default_theme:n="light",default_renderer:i="canvas",auto_responsive:a=!0,responsive_delay:_=200}=e,m=new Map,x=new Map;J.onUnmounted(()=>{T()});async function $(t,u,d){try{if(q(u),!document.querySelector(u))return console.error(`渲染图表失败:未找到DOM元素 ${u}`),null;const s=re(te(he),t),l=d?.default_theme||n;if(l==="dark"){const O=He("dark");re(s,O)}const g=d?.default_renderer||i,S=await ke(u,s,g,l==="dark"?"dark":void 0);if(S){if(m.set(u,S),d?.auto_responsive??a){const O=Le(S,d?.responsive_delay||_);O&&x.set(u,O)}return S}else return console.warn("渲染图表失败:ECharts 初始化失败。请确保已安装 echarts 依赖:npm install echarts 或 yarn add echarts"),null}catch(p){p.message?.includes("Cannot find module")?console.warn("渲染图表失败:未找到 echarts 模块。请安装 echarts 依赖:npm install echarts 或 yarn add echarts"):console.error("渲染图表失败:",p)}return null}function z(t){return m.get(t)}function C(t,u){try{const d=m.get(t);if(d){const p=Ce(he,u);return De(d,p),!0}}catch(d){console.error("更新图表失败:",d)}return!1}function q(t){try{const u=m.get(t);if(u){fe(u),m.delete(t);const d=x.get(t);return d&&(d(),x.delete(t)),!0}}catch(u){console.error("删除图表失败:",u)}return!1}function E(t){try{const u=m.get(t);if(u)return de(u),!0}catch(u){console.error("调整图表大小失败:",u)}return!1}function T(){m.forEach(t=>{fe(t)}),m.clear(),x.forEach(t=>{t()}),x.clear()}function y(t,u){const d=m.get(t);return d?Ne(d,u):null}function o(t,u,d){const p=m.get(t);p&&Te(p,u,d)}function r(t,u,d){const p=m.get(t);p&&qe(p,u,d)}return{render_chart:$,get_chart:z,update_chart:C,remove_chart:q,resize_chart:E,destroy_all_charts:T,generate_chart_colors:ze,get_chart_gradient_color:Me,export_chart_image:y,add_chart_listener:o,remove_chart_listener:r,auto_size:W}}function Ie(e){let n,i,a;async function _(){try{if(!i||!a){i=(await import("@antv/x6")).Graph;const l=await import("dagre");a=l.default||l}return!0}catch(s){return console.error("加载依赖失败:",s),console.error("请安装必要的依赖: npm install @antv/x6 dagre"),!1}}const m={panning:!0,interacting:!1,mousewheel:{enabled:!0},scaling:{min:.1,max:10}};async function x(s){if(!s)throw new Error("init(): 容器元素不能为空");if(!await _())return!1;const l=re(m,e);try{return n=new i({container:s,...l}),!0}catch(g){return console.error("初始化画布失败:",g),!1}}function $(){return n?!0:(console.error("错误:画布未初始化,请先调用 init() 方法"),!1)}function z(s){if($()){if(!Array.isArray(s)){console.error("错误:elements 参数必须是数组");return}n.resetCells(s)}}function C(s,l,g,S){const{node_w:O,node_h:L,nodesep:k,ranksep:M}=g,A=new a.graphlib.Graph;A.setGraph({rankdir:S,nodesep:k,ranksep:M}),A.setDefaultEdgeLabel(()=>({}));const P=O,v=L;return s.forEach(h=>{A.setNode(h.id,{width:P,height:v})}),l.forEach(h=>{const f=h.getSource(),w=h.getTarget();f&&w&&f.cell&&w.cell&&A.setEdge(f.cell,w.cell)}),A}function q(s){s.nodes().forEach(l=>{const g=n.getCellById(l);if(g){const S=s.node(l);g.position(S.x,S.y)}})}function E(s,l){s.forEach(g=>{try{const S=g.getSourceNode(),O=g.getTargetNode();if(!S||!O)return;const L=S.getBBox(),k=O.getBBox();if((l==="LR"||l==="RL")&&L.y!==k.y){const M=l==="LR"?k.x-L.x-L.width:-L.x+k.x+k.width,A=l==="LR"?L.width:0,P=L.x+A+M/2;g.setVertices([{x:P,y:L.center.y},{x:P,y:k.center.y}])}else if((l==="TB"||l==="BT")&&L.x!==k.x){const M=l==="TB"?k.y-L.y-L.height:-L.y+k.y+k.height,A=l==="TB"?L.height:0,P=L.y+A+M/2;g.setVertices([{x:L.center.x,y:P},{x:k.center.x,y:P}])}else g.setVertices([])}catch(S){console.error("处理边布局时出错:",S)}})}async function T(s,l="LR"){if(!$())return!1;if(!s)return console.error("错误:布局配置不能为空"),!1;if(!await _())return!1;const{node_w:g,node_h:S,nodesep:O,ranksep:L}=s;if(typeof g!="number"||g<=0||typeof S!="number"||S<=0||typeof O!="number"||O<0||typeof L!="number"||L<0)return console.error("错误:布局配置参数必须为正数"),!1;if(!["LR","RL","TB","BT"].includes(l))return console.error("错误:无效的布局方向,支持的方向:LR, RL, TB, BT"),!1;try{const M=n.getNodes(),A=n.getEdges(),P=C(M,A,s,l);return a.layout(P),q(P),E(A,l),!0}catch(M){return console.error("执行布局时出错:",M),!1}}function y(s){if($()){if(typeof s!="number"||s<0){console.error("错误:padding 参数必须为非负数");return}n.zoomToFit({padding:s,maxScale:1.2}),n.centerContent()}}function o(s){if(!$())return[];if(!Array.isArray(s))return console.error("错误:node_options 参数必须是数组"),[];const l=[];return s.forEach(g=>{if(g)try{const S=n.createNode(g);l.push(S)}catch(S){console.error("创建节点时出错:",S)}}),l}function r(s){if(!$())return[];if(!Array.isArray(s))return console.error("错误:edge_options 参数必须是数组"),[];const l=[];return s.forEach(g=>{if(g&&g.source_id&&g.target_id)try{const S=n.createEdge({shape:g.shape,source:{cell:g.source_id},target:{cell:g.target_id}});l.push(S)}catch(S){console.error("创建边时出错:",S)}}),l}function t(s){if(!$())return;if(!s||typeof s!="object"){console.error("错误:event_options 参数必须是对象");return}Object.keys(s).forEach(g=>{const S=s[g];typeof S=="function"?(s[g]=l(S,"g",n),n.on(g,s[g])):console.error(`错误:事件 ${g} 的处理函数必须是函数`)});function l(g,S,O){return function(...L){return L[0][S]=O,g.apply(this,L)}}}async function u(s){return!s||typeof s!="object"?(console.error("错误:el_options 参数必须是对象"),!1):await _()?(s.nodes&&typeof s.nodes=="object"&&Object.keys(s.nodes).forEach(l=>{const g=s.nodes[l];if(g)try{i.registerNode(l,g,!0)}catch(S){console.error(`注册自定义节点 ${l} 时出错:`,S)}}),s.edges&&typeof s.edges=="object"&&Object.keys(s.edges).forEach(l=>{const g=s.edges[l];if(g)try{i.registerEdge(l,g,!0)}catch(S){console.error(`注册自定义边 ${l} 时出错:`,S)}}),!0):!1}function d(){return $()?n.getNodes():[]}function p(){n&&n.clearCells()}return{init:x,add_graph_elements:z,layout:T,center_content:y,create_nodes:o,create_edges:r,register_event:t,register_custom_elements:u,get_nodes:d,clear:p}}function Fe(e,n={}){let i,a,_="disconnected",m;function x(){e||(console.error("mqtt:连接地址不能为空!"),_="error")}async function $(){try{if(!i){const r=await import("mqtt");i=r.default||r}return i}catch(r){console.error("mqtt:加载MQTT库失败,请确保已安装mqtt包:",r);return}}async function z({success:r,error:t,receive:u}){if(!e){console.error("mqtt:连接地址不能为空"),_="error",t(new Error("连接地址不能为空"));return}try{_="connecting";const d=await $();if(!d){_="error",t(new Error("MQTT库加载失败"));return}a=d.connect(e,n),a?(a.on("connect",()=>{console.log("mqtt:连接成功!"),_="connected",r()}),a.on("error",p=>{console.error("mqtt:连接错误-",p),_="error",t(p)}),a.on("close",()=>{console.log("mqtt:连接关闭"),_="disconnected",y()}),a.on("message",u),a.on("reconnect",()=>{console.log("mqtt:正在重连..."),_="connecting"})):(console.error("mqtt:创建客户端失败"),_="error",t(new Error("创建MQTT客户端失败")))}catch(d){console.error("mqtt:连接异常!",d),_="error",t(d)}}function C(r){o(),a?a.end(!1,void 0,()=>{console.log("mqtt:连接关闭"),_="disconnected",a=void 0,r?.()}):(_="disconnected",r?.())}function q(r,t,u){if(!a){console.error("mqtt:客户端未连接"),u?.(new Error("客户端未连接"),[]);return}if(!r){console.error("mqtt:订阅主题不能为空"),u?.(new Error("订阅主题不能为空"),[]);return}a.subscribe(r,t,(d,p)=>{d?console.error(`mqtt:订阅主题失败-${r}`,d):console.log(`mqtt:成功订阅主题-${r}`),u?.(d,p)})}function E(r,t){if(!a){console.error("mqtt:客户端未连接"),t?.(new Error("客户端未连接"));return}if(!r){console.error("mqtt:取消订阅主题不能为空"),t?.(new Error("取消订阅主题不能为空"));return}a.unsubscribe(r,u=>{u?console.error(`mqtt:取消订阅失败-${r}`,u):console.log(`mqtt:成功取消订阅主题-${r}`),t?.(u)})}function T(r,t,u,d){if(!a){console.error("mqtt:客户端未连接"),d?.(new Error("客户端未连接"));return}if(!r){console.error("mqtt:发布主题不能为空"),d?.(new Error("发布主题不能为空"));return}if(!t){console.error("mqtt:发布消息不能为空"),d?.(new Error("发布消息不能为空"));return}a.publish(r,t,u,p=>{p?console.error(`mqtt:发布消息失败-${r}`,p):console.log(`mqtt:成功发布消息到主题-${r}`),d?.(p)})}function y(){o(),n.reconnectPeriod&&n.reconnectPeriod>0&&(m=setTimeout(()=>{console.log("mqtt:尝试重连...")},n.reconnectPeriod))}function o(){m&&(clearTimeout(m),m=void 0)}return x(),{get status(){return _},connect:z,close:C,subscribe:q,unsubscribe:E,publish:T}}R.EImageType=G,R.use_chart=Re,R.use_emit=_e,R.use_fullscreen=Be,R.use_image=Pe,R.use_layout_flow=Ie,R.use_mqtt=Fe,R.use_print=ge,R.use_water_mark=Ae,R.use_web_socket=We,Object.defineProperty(R,Symbol.toStringTag,{value:"Module"})}));
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export * from './use-emit';
|
|
2
|
-
export * from './use-file';
|
|
3
2
|
export * from './use-print';
|
|
4
|
-
export * from './use-
|
|
3
|
+
export * from './use-watermark';
|
|
5
4
|
export * from './use-websocket';
|
|
6
5
|
export * from './use-image';
|
|
6
|
+
export * from './use-fullscreen';
|
|
7
|
+
export * from './use-chart';
|
|
8
|
+
export * from './use-layout-flow';
|
|
9
|
+
export * from './use-mqtt';
|
package/lib/index.js
CHANGED
|
@@ -1,33 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { default as k } from "./use-image/downloadFile.js";
|
|
12
|
-
import { default as I } from "./use-image/filetoDataURL.js";
|
|
13
|
-
import { default as w } from "./use-image/imagetoCanvas.js";
|
|
14
|
-
import { default as A } from "./use-image/urltoBlob.js";
|
|
15
|
-
import { default as C } from "./use-image/urltoImage.js";
|
|
1
|
+
import { use_emit } from "./use-emit/index.js";
|
|
2
|
+
import { use_print } from "./use-print/index.js";
|
|
3
|
+
import { use_water_mark } from "./use-watermark/index.js";
|
|
4
|
+
import { use_web_socket } from "./use-websocket/index.js";
|
|
5
|
+
import { use_image } from "./use-image/index.js";
|
|
6
|
+
import { use_fullscreen } from "./use-fullscreen/index.js";
|
|
7
|
+
import { use_chart } from "./use-chart/index.js";
|
|
8
|
+
import { use_layout_flow } from "./use-layout-flow/index.js";
|
|
9
|
+
import { use_mqtt } from "./use-mqtt/index.js";
|
|
10
|
+
import { EImageType } from "./use-image/type.js";
|
|
16
11
|
export {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
C as urltoImage,
|
|
28
|
-
t as useEmits,
|
|
29
|
-
r as useFile,
|
|
30
|
-
m as usePrintHtml,
|
|
31
|
-
l as useWaterMark,
|
|
32
|
-
u as useWebSocket
|
|
12
|
+
EImageType,
|
|
13
|
+
use_chart,
|
|
14
|
+
use_emit,
|
|
15
|
+
use_fullscreen,
|
|
16
|
+
use_image,
|
|
17
|
+
use_layout_flow,
|
|
18
|
+
use_mqtt,
|
|
19
|
+
use_print,
|
|
20
|
+
use_water_mark,
|
|
21
|
+
use_web_socket
|
|
33
22
|
};
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export default _default;
|
|
1
|
+
declare const options: Record<string, any>;
|
|
2
|
+
export default options;
|