@topdatasec/probe 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Topdatasec
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # @topdatasec/probe
2
+
3
+ 探针部署管理组件库
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ npm install @topdatasec/probe
9
+ # or
10
+ pnpm add @topdatasec/probe
11
+ ```
12
+
13
+ ## 使用
14
+
15
+ ```typescript
16
+ import { createApp } from 'vue'
17
+ import TProbeUI from '@topdatasec/probe'
18
+ import App from './App.vue'
19
+
20
+ const app = createApp(App)
21
+ app.use(TProbeUI, {
22
+ envURL: 'your-api-url',
23
+ prodType: 'your-prod-type'
24
+ })
25
+ app.mount('#app')
26
+ ```
27
+
28
+ ## 按需引入
29
+
30
+ ```typescript
31
+ import { TCProbe } from '@topdatasec/probe'
32
+ ```
33
+
34
+ ## 功能
35
+
36
+ - **安装包管理**: 上传和管理探针安装包
37
+ - **探针部署**: 配置和部署探针到服务器
38
+ - **部署历史**: 查看部署历史记录
package/lib/style.css ADDED
@@ -0,0 +1 @@
1
+ .ip-port-item[data-v-16fc9c64]{border-style:dashed}.el-tab-pane[data-v-7172e806]{height:100%}
@@ -0,0 +1,1198 @@
1
+ import { defineComponent as H, useModel as ne, resolveComponent as p, openBlock as y, createElementBlock as x, Fragment as A, renderList as K, createVNode as e, withCtx as E, unref as M, createCommentVNode as O, ref as w, reactive as j, createTextVNode as q, createElementVNode as v, toDisplayString as C, mergeProps as X, createBlock as W } from "vue";
2
+ import { CircleClose as re, UploadFilled as ae } from "@element-plus/icons-vue";
3
+ import { TdsTable as se, TdsForm as Y } from "topdatasec-ui";
4
+ import { ElMessage as Q } from "element-plus";
5
+ const ue = {
6
+ key: 0,
7
+ class: "absolute right--13px text-#f56c6c hover:cursor-pointer"
8
+ }, ie = /* @__PURE__ */ H({
9
+ __name: "IpPortList",
10
+ props: {
11
+ modelValue: { default: () => [{ ip: "", port: "" }] },
12
+ modelModifiers: {}
13
+ },
14
+ emits: ["update:modelValue"],
15
+ setup(t) {
16
+ const l = ne(t, "modelValue"), { $t: o } = window;
17
+ function s() {
18
+ l.value = [...l.value, { ip: "", port: "" }];
19
+ }
20
+ function c(m) {
21
+ const r = [...l.value];
22
+ r.splice(m, 1), l.value = r;
23
+ }
24
+ return (m, r) => {
25
+ const _ = p("el-input"), T = p("el-form-item"), b = p("el-icon"), a = p("el-button");
26
+ return y(), x("div", null, [
27
+ (y(!0), x(A, null, K(l.value, (u, S) => (y(), x("div", {
28
+ key: S,
29
+ class: "flex form-m0 w-100% mb-5px"
30
+ }, [
31
+ e(T, { class: "w-70%" }, {
32
+ default: E(() => [
33
+ e(_, {
34
+ modelValue: u.ip,
35
+ "onUpdate:modelValue": (L) => u.ip = L,
36
+ class: "min-w-300px w-100%",
37
+ placeholder: "IP"
38
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
39
+ ]),
40
+ _: 2
41
+ }, 1024),
42
+ e(T, { class: "ml-auto w-30%" }, {
43
+ default: E(() => [
44
+ e(_, {
45
+ modelValue: u.port,
46
+ "onUpdate:modelValue": (L) => u.port = L,
47
+ class: "ml-10",
48
+ placeholder: M(o)("global.port")
49
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "placeholder"])
50
+ ]),
51
+ _: 2
52
+ }, 1024),
53
+ l.value.length > 1 ? (y(), x("div", ue, [
54
+ e(b, {
55
+ onClick: (L) => c(S)
56
+ }, {
57
+ default: E(() => [
58
+ e(M(re))
59
+ ]),
60
+ _: 1
61
+ }, 8, ["onClick"])
62
+ ])) : O("", !0)
63
+ ]))), 128)),
64
+ e(a, {
65
+ class: "w-100% mt-10px border-dashed!",
66
+ icon: "Plus",
67
+ onClick: s
68
+ })
69
+ ]);
70
+ };
71
+ }
72
+ });
73
+ const ee = (t, l) => {
74
+ const o = t.__vccOpts || t;
75
+ for (const [s, c] of l)
76
+ o[s] = c;
77
+ return o;
78
+ }, V = /* @__PURE__ */ ee(ie, [["__scopeId", "data-v-16fc9c64"]]), I = 5 * 1024 * 1024;
79
+ function de(t, l) {
80
+ return new Promise((o, s) => {
81
+ const c = new (void 0)(), m = new FileReader(), r = Math.ceil(t.size / I);
82
+ let _ = 0;
83
+ m.onload = (b) => {
84
+ var a;
85
+ if (c.append((a = b.target) == null ? void 0 : a.result), _++, l) {
86
+ const u = Math.floor(_ / r * 100);
87
+ l(u);
88
+ }
89
+ if (_ < r)
90
+ T();
91
+ else {
92
+ const u = c.end();
93
+ o(u);
94
+ }
95
+ }, m.onerror = () => {
96
+ s(new Error("MD5计算失败"));
97
+ };
98
+ function T() {
99
+ const b = _ * I, a = Math.min(b + I, t.size);
100
+ m.readAsArrayBuffer(t.slice(b, a));
101
+ }
102
+ T();
103
+ });
104
+ }
105
+ async function pe(t, l, o, s, c, m = "/api/upload/chunk") {
106
+ const r = l * I, _ = Math.min(r + I, t.size), T = t.slice(r, _), b = _ - r, a = new FormData();
107
+ a.append("file", T, t.name), a.append("chunkIndex", String(l + 1)), a.append("totalChunkNum", String(o)), a.append("fileMd5", s), a.append("tds_token", c), a.append("fileName", t.name), a.append("fileSize", String(t.size)), a.append("fileExt", t.name.substring(t.name.lastIndexOf(".") + 1)), a.append("chunkSize", String(I)), a.append("currentChunkSize", String(b));
108
+ try {
109
+ const u = await fetch(m, {
110
+ method: "POST",
111
+ body: a
112
+ });
113
+ if (console.log(u, "upload response"), !u.ok)
114
+ throw new Error(`分片 ${l + 1} 上传失败,HTTP状态码: ${u.status}`);
115
+ const S = await u.json();
116
+ if (console.log(S, "upload result"), S.recode !== 0)
117
+ throw new Error(`上传失败: ${S.remsg || "未知错误"}`);
118
+ return !0;
119
+ } catch (u) {
120
+ throw console.error(`上传分片 ${l + 1} 时出错:`, u), u;
121
+ }
122
+ }
123
+ async function ce(t, l = "/api/upload/merge") {
124
+ try {
125
+ if (!(await fetch(l, {
126
+ method: "POST",
127
+ headers: {
128
+ "Content-Type": "application/json"
129
+ },
130
+ body: JSON.stringify(t)
131
+ })).ok)
132
+ throw new Error("文件合并失败");
133
+ return !0;
134
+ } catch (o) {
135
+ return console.error("合并分片时出错:", o), !1;
136
+ }
137
+ }
138
+ async function me(t) {
139
+ const { token: l, file: o, fileDesc: s = "", uploadUrl: c = "/api/upload/chunk", mergeUrl: m = "/api/upload/merge", onProgress: r, onSuccess: _, onError: T } = t;
140
+ try {
141
+ r == null || r({
142
+ progress: 0,
143
+ statusText: "正在计算文件MD5...",
144
+ status: "preparing"
145
+ });
146
+ const a = await de(o, (g) => {
147
+ r == null || r({
148
+ progress: Math.floor(g * 0.1),
149
+ // MD5计算占10%进度
150
+ statusText: `正在计算文件MD5... ${g}%`,
151
+ status: "preparing"
152
+ });
153
+ });
154
+ r == null || r({
155
+ progress: 10,
156
+ statusText: "MD5计算完成",
157
+ status: "preparing",
158
+ fileMd5: a
159
+ });
160
+ const u = Math.ceil(o.size / I);
161
+ r == null || r({
162
+ progress: 10,
163
+ statusText: `开始上传 (共${u}个分片)`,
164
+ status: "uploading",
165
+ fileMd5: a
166
+ });
167
+ for (let g = 0; g < u; g++) {
168
+ const P = Math.floor(g / u * 80);
169
+ r == null || r({
170
+ progress: 10 + P,
171
+ statusText: `正在上传分片 ${g + 1}/${u}`,
172
+ status: "uploading",
173
+ fileMd5: a
174
+ }), await pe(o, g, u, a, l, c);
175
+ }
176
+ r == null || r({
177
+ progress: 90,
178
+ statusText: "正在合并文件...",
179
+ status: "merging",
180
+ fileMd5: a
181
+ });
182
+ const S = o.name.substring(o.name.lastIndexOf(".") + 1), L = {
183
+ fileDesc: s,
184
+ fileExt: S,
185
+ fileMd5: a,
186
+ fileName: o.name,
187
+ fileSize: String(o.size),
188
+ tds_token: l,
189
+ totalChunkNum: String(u)
190
+ };
191
+ if (!await ce(L, m))
192
+ throw new Error("文件合并失败");
193
+ r == null || r({
194
+ progress: 100,
195
+ statusText: "上传成功",
196
+ status: "success",
197
+ fileMd5: a
198
+ }), Q.success(`${o.name} 上传成功`), _ == null || _(a);
199
+ } catch (b) {
200
+ r == null || r({
201
+ progress: 0,
202
+ statusText: b.message || "上传失败",
203
+ status: "error"
204
+ }), Q.error(`${o.name} 上传失败: ${b.message}`), T == null || T(b);
205
+ }
206
+ }
207
+ function _e(t) {
208
+ if (t === 0)
209
+ return "0 B";
210
+ const l = 1024, o = ["B", "KB", "MB", "GB", "TB"], s = Math.floor(Math.log(t) / Math.log(l));
211
+ return Math.round(t / Math.pow(l, s) * 100) / 100 + " " + o[s];
212
+ }
213
+ const U = {
214
+ get deployURL() {
215
+ return window.$probeURL || "";
216
+ }
217
+ }, te = (t = {}) => window.$http.request({
218
+ url: `${U.deployURL}/service_deploy/deployment/servers/get`,
219
+ method: "get",
220
+ params: t,
221
+ isError: !1
222
+ }), fe = (t) => window.$http.request({
223
+ url: `${U.deployURL}/service_deploy/deployment/servers/add`,
224
+ method: "post",
225
+ data: t
226
+ }), ve = (t) => window.$http.request({
227
+ url: `${U.deployURL}/service_deploy/deployment/servers/delete`,
228
+ method: "delete",
229
+ data: t
230
+ }), le = (t = {}) => window.$http.request({
231
+ url: `${U.deployURL}/service_deploy/deployment/packages/get`,
232
+ method: "get",
233
+ params: t,
234
+ isError: !1
235
+ }), ye = (t) => window.$http.request({
236
+ url: `${U.deployURL}/service_deploy/deployment/packages/delete`,
237
+ method: "delete",
238
+ data: t
239
+ }), ge = () => window.$http.request({
240
+ url: `${U.deployURL}/service_deploy/deployment/servers/arch_type`,
241
+ method: "get",
242
+ isError: !1
243
+ }), oe = (t) => window.$http.request({
244
+ url: `${U.deployURL}/service_deploy/deployment/deploy`,
245
+ method: "post",
246
+ data: t
247
+ }), he = (t) => window.$http.request({
248
+ url: `${U.deployURL}/service_deploy/deployment/servers/test_connectivity`,
249
+ method: "post",
250
+ data: t
251
+ }), be = (t) => window.$http.request({
252
+ url: `${U.deployURL}/service_deploy/deployment/servers/check_env`,
253
+ method: "post",
254
+ data: t
255
+ }), we = (t) => window.$http.request({
256
+ url: `${U.deployURL}/service_deploy/deployment/servers/install_env`,
257
+ method: "post",
258
+ data: t
259
+ }), xe = (t = {}) => window.$http.request({
260
+ url: `${U.deployURL}/service_deploy/deployment/history/get`,
261
+ method: "get",
262
+ params: t,
263
+ isError: !1
264
+ }), ke = {
265
+ class: "h-100%"
266
+ }, Te = {
267
+ key: 0,
268
+ class: "upload-progress-list"
269
+ }, $e = {
270
+ class: "file-info"
271
+ }, Ee = {
272
+ class: "file-name"
273
+ }, Se = {
274
+ class: "file-size"
275
+ }, Ue = {
276
+ class: "progress-text"
277
+ }, Le = {
278
+ class: "table-box h-[calc(100%-220px)]"
279
+ }, Ce = {
280
+ key: 0
281
+ }, Me = {
282
+ class: "flex flex-wrap gap-12px p-12px"
283
+ }, qe = {
284
+ class: "font-bold text-14px mb-8px text-[var(--el-text-color-primary)]"
285
+ }, Ae = {
286
+ class: "text-12px text-[var(--el-text-color-regular)] space-y-4px"
287
+ }, Fe = {
288
+ key: 1,
289
+ class: "font-bold text-center text-gray-500 py-20"
290
+ }, Be = /* @__PURE__ */ H({
291
+ __name: "index",
292
+ props: {
293
+ token: {
294
+ type: String,
295
+ default: ""
296
+ }
297
+ },
298
+ setup(t) {
299
+ const l = w(), o = w(), s = w("快速部署"), c = w({}), {
300
+ $t: m,
301
+ $messageBox: r
302
+ } = window;
303
+ function _(i) {
304
+ c.value = {
305
+ id: i.id
306
+ }, o.value.open();
307
+ }
308
+ const T = w([{
309
+ ip: "",
310
+ port: ""
311
+ }]), b = w([{
312
+ ip: "",
313
+ port: ""
314
+ }]), a = w([{
315
+ ip: "",
316
+ port: ""
317
+ }]), u = w([{
318
+ ip: "",
319
+ port: ""
320
+ }]);
321
+ async function S(i) {
322
+ const k = (n, d) => {
323
+ const f = Math.max(n.length, d.length);
324
+ return Array.from({
325
+ length: f
326
+ }, (h, $) => {
327
+ var F, N, z, R;
328
+ return {
329
+ src_ip: ((F = n[$]) == null ? void 0 : F.ip) || "",
330
+ src_port: Number((N = n[$]) == null ? void 0 : N.port) || 0,
331
+ dst_ip: ((z = d[$]) == null ? void 0 : z.ip) || "",
332
+ dst_port: Number((R = d[$]) == null ? void 0 : R.port) || 0
333
+ };
334
+ });
335
+ }, B = {
336
+ packages_id: [c.value.id],
337
+ server_id: i.server_id,
338
+ service_type: window.$prodType,
339
+ deploy_params: {
340
+ probe_name: i.probe_name || "",
341
+ collection_mode: i.collection_mode,
342
+ interface: i.interface || "",
343
+ engine_ip: i.engine_ip || "",
344
+ engine_port: i.engine_port || "",
345
+ filterWhitelist: k(T.value, b.value),
346
+ filterBlacklist: k(a.value, u.value)
347
+ }
348
+ };
349
+ await oe({
350
+ data: B
351
+ }), l.value.getTableList(), o.value.close();
352
+ }
353
+ async function L(i) {
354
+ r(i, "file_name", m("button.delete"), "error").then(async () => {
355
+ await ye({
356
+ data: [i.id]
357
+ }), l.value.getTableList();
358
+ });
359
+ }
360
+ const D = j([
361
+ // { type: 'selection', align: 'center', field: 'id', hide: true },
362
+ {
363
+ field: "server_id",
364
+ name: "选择服务器",
365
+ enum: te,
366
+ fieldNames: {
367
+ value: "id",
368
+ label: "server_name"
369
+ },
370
+ show: {
371
+ type: "select",
372
+ prop: {
373
+ multiple: !0
374
+ },
375
+ dataType: "any"
376
+ },
377
+ hide: !0,
378
+ rules: [{
379
+ required: !0
380
+ }]
381
+ },
382
+ {
383
+ field: "file_name",
384
+ name: "文件名称"
385
+ },
386
+ {
387
+ field: "version",
388
+ name: "版本"
389
+ },
390
+ {
391
+ field: "file_size",
392
+ name: "大小"
393
+ },
394
+ {
395
+ field: "upload_time",
396
+ name: "上传时间"
397
+ },
398
+ {
399
+ field: "deployment_server",
400
+ name: "已部署服务器数",
401
+ render: (i) => {
402
+ var k;
403
+ return ((k = i.row.deployment_server) == null ? void 0 : k.length) || 0;
404
+ }
405
+ },
406
+ {
407
+ field: "upload_status",
408
+ name: "状态",
409
+ tag: !0,
410
+ enum: [{
411
+ label: "上传失败",
412
+ value: 0,
413
+ tagType: "danger"
414
+ }, {
415
+ label: "上传中",
416
+ value: 1,
417
+ tagType: "warning"
418
+ }, {
419
+ label: "上传成功",
420
+ value: 2,
421
+ tagType: "success"
422
+ }]
423
+ },
424
+ {
425
+ field: "probe_name",
426
+ name: "探针名称",
427
+ show: {
428
+ type: "input"
429
+ },
430
+ hide: !0,
431
+ rules: [{
432
+ required: !0
433
+ }]
434
+ },
435
+ {
436
+ field: "collection_mode",
437
+ name: "采集模式",
438
+ show: {
439
+ type: "input",
440
+ value: "DPDK",
441
+ disabled: !0
442
+ },
443
+ hide: !0,
444
+ rules: [{
445
+ required: !0
446
+ }]
447
+ },
448
+ {
449
+ field: "interface",
450
+ name: "采集网卡",
451
+ show: {
452
+ type: "input"
453
+ },
454
+ hide: !0,
455
+ rules: [{
456
+ required: !0
457
+ }]
458
+ },
459
+ {
460
+ field: "engine_ip",
461
+ name: "流量接收引擎IP",
462
+ show: {
463
+ type: "input"
464
+ },
465
+ hide: !0
466
+ },
467
+ {
468
+ field: "engine_port",
469
+ name: "流量接收引擎端口",
470
+ show: {
471
+ type: "input",
472
+ dataType: "number"
473
+ },
474
+ hide: !0,
475
+ rules: [{
476
+ required: !0,
477
+ type: "any"
478
+ }]
479
+ },
480
+ {
481
+ field: "whitelist",
482
+ name: "探针过滤白名单",
483
+ show: {
484
+ type: "input",
485
+ tooltip: "白名单配置后,仅采集白名单内相关流量,如不填写,则采集所有流量",
486
+ render: () => e(A, null, [e("p", {
487
+ class: "color-[var(--el-text-color-regular)]"
488
+ }, [q("源ip端口:")]), e(V, {
489
+ modelValue: T.value,
490
+ "onUpdate:modelValue": (i) => T.value = i
491
+ }, null), e("p", {
492
+ class: "color-[var(--el-text-color-regular)]"
493
+ }, [q("目的ip端口:")]), e(V, {
494
+ modelValue: b.value,
495
+ "onUpdate:modelValue": (i) => b.value = i
496
+ }, null)])
497
+ },
498
+ hide: !0
499
+ },
500
+ {
501
+ field: "blacklist",
502
+ name: "探针过滤黑名单",
503
+ show: {
504
+ type: "input",
505
+ tooltip: "黑名单配置后,将不再采集黑名单内相关流量",
506
+ render: () => e(A, null, [e("p", {
507
+ class: "color-[var(--el-text-color-regular)]"
508
+ }, [q("源ip端口:")]), e(V, {
509
+ modelValue: a.value,
510
+ "onUpdate:modelValue": (i) => a.value = i
511
+ }, null), e("p", {
512
+ class: "color-[var(--el-text-color-regular)]"
513
+ }, [q("目的ip端口:")]), e(V, {
514
+ modelValue: u.value,
515
+ "onUpdate:modelValue": (i) => u.value = i
516
+ }, null)])
517
+ },
518
+ hide: !0
519
+ },
520
+ {
521
+ field: "operation",
522
+ name: window.$t("global.operate"),
523
+ width: 140,
524
+ fixed: "right",
525
+ render: (i) => e("div", null, [e(p("el-button"), {
526
+ link: !0,
527
+ type: "primary",
528
+ class: "custom-btn",
529
+ onClick: () => _(i.row)
530
+ }, {
531
+ icon: () => e(p("tds-svg-icon"), {
532
+ name: "deployed",
533
+ tip: "部署"
534
+ }, null)
535
+ }), e(p("el-button"), {
536
+ link: !0,
537
+ type: "danger",
538
+ icon: "Delete",
539
+ title: m("button.delete"),
540
+ onClick: () => L([i.row])
541
+ }, null)])
542
+ }
543
+ ]), g = w([]);
544
+ function P(i) {
545
+ const k = i.raw;
546
+ if (!k)
547
+ return;
548
+ const B = {
549
+ fileName: k.name,
550
+ fileSize: k.size,
551
+ progress: 0,
552
+ progressStatus: "",
553
+ statusText: "准备上传..."
554
+ };
555
+ g.value.push(B);
556
+ const n = g.value.length - 1;
557
+ me({
558
+ file: k,
559
+ fileDesc: "探针安装包",
560
+ // 替换为你实际的接口地址
561
+ uploadUrl: U.deployURL + "/service_deploy/deployment/packages/upload",
562
+ mergeUrl: U.deployURL + "/service_deploy/deployment/packages/upload_merge",
563
+ // 进度回调
564
+ onProgress: (d) => {
565
+ const f = g.value[n];
566
+ f && (f.progress = d.progress, f.statusText = d.statusText, d.fileMd5 && (f.fileMd5 = d.fileMd5), d.status === "error" ? f.progressStatus = "exception" : d.status === "success" ? f.progressStatus = "success" : f.progressStatus = "");
567
+ },
568
+ // 成功回调
569
+ onSuccess: () => {
570
+ var f;
571
+ const d = g.value[n];
572
+ d && (d.progress = 100, d.progressStatus = "success", d.statusText = "上传成功"), (f = l.value) == null || f.getTableList(), setTimeout(() => {
573
+ const h = g.value.findIndex(($) => $.fileName === k.name);
574
+ h !== -1 && g.value.splice(h, 1);
575
+ }, 3e3);
576
+ },
577
+ // 失败回调
578
+ onError: (d) => {
579
+ console.error("文件上传失败:", d);
580
+ const f = g.value[n];
581
+ f && (f.progressStatus = "exception", f.statusText = d.message || "上传失败");
582
+ }
583
+ });
584
+ }
585
+ return (i, k) => {
586
+ const B = p("el-icon"), n = p("el-upload"), d = p("el-progress"), f = p("el-table-column");
587
+ return y(), x("div", ke, [e(n, {
588
+ class: "upload-demo mt-10px",
589
+ drag: "",
590
+ action: "",
591
+ "auto-upload": !1,
592
+ accept: ".tar.gz,.tgz",
593
+ "on-change": P,
594
+ "show-file-list": !1,
595
+ multiple: ""
596
+ }, {
597
+ default: E(() => [e(B, {
598
+ class: "el-icon--upload"
599
+ }, {
600
+ default: E(() => [e(M(ae))]),
601
+ _: 1
602
+ }), k[0] || (k[0] = v("div", {
603
+ class: "el-upload__text"
604
+ }, [q(" 点击或拖拽文件到此处上传   "), v("br"), v("em", null, "支持的格式: tar.gz, tgz")], -1))]),
605
+ _: 1
606
+ }), g.value.length > 0 ? (y(), x("div", Te, [(y(!0), x(A, null, K(g.value, (h) => (y(), x("div", {
607
+ key: h.fileName,
608
+ class: "upload-progress-item"
609
+ }, [v("div", $e, [v("span", Ee, C(h.fileName), 1), v("span", Se, C(M(_e)(h.fileSize)), 1)]), e(d, {
610
+ percentage: h.progress,
611
+ status: h.progressStatus
612
+ }, null, 8, ["percentage", "status"]), v("div", Ue, C(h.statusText), 1)]))), 128))])) : O("", !0), v("div", Le, [e(M(se), {
613
+ ref_key: "refTdsTable",
614
+ ref: l,
615
+ columns: D,
616
+ "request-api": M(le),
617
+ options: i.$tableOptions()
618
+ }, {
619
+ default: E(() => [e(f, {
620
+ type: "expand"
621
+ }, {
622
+ default: E((h) => [h.row.deployment_server && h.row.deployment_server.length > 0 ? (y(), x("div", Ce, [k[1] || (k[1] = v("div", {
623
+ class: "font-bold text-14px mt-12px"
624
+ }, "已部署的服务器", -1)), v("div", Me, [(y(!0), x(A, null, K(h.row.deployment_server, ($) => (y(), x("div", {
625
+ key: $.id,
626
+ class: "w-30% px-20px py-10px rounded-8px bg-[var(--el-fill-color-light)] border border-solid border-[var(--el-border-color-lighter)] hover:shadow-md transition-shadow"
627
+ }, [v("div", qe, C($.server_name), 1), v("div", Ae, [v("p", null, "IP: " + C($.ip_address), 1), v("p", null, "部署时间: " + C($.deployment_time), 1)])]))), 128))])])) : (y(), x("div", Fe, "暂无部署服务器记录"))]),
628
+ _: 1
629
+ })]),
630
+ _: 1
631
+ }, 8, ["columns", "request-api", "options"])]), e(M(Y), X({
632
+ ref_key: "refTdsForm",
633
+ ref: o
634
+ }, i.$formBindProps({
635
+ title: s.value,
636
+ form: c.value,
637
+ columns: D
638
+ }), {
639
+ onSubmit: S
640
+ }), null, 16)]);
641
+ };
642
+ }
643
+ }), Ne = {
644
+ class: "table-box"
645
+ }, Ve = {
646
+ class: "flex items-center"
647
+ }, De = {
648
+ key: 0
649
+ }, ze = {
650
+ class: "flex flex-wrap gap-12px p-12px"
651
+ }, Ie = {
652
+ class: "font-bold text-14px mb-8px text-[var(--el-text-color-primary)]"
653
+ }, Pe = {
654
+ class: "text-12px text-[var(--el-text-color-regular)] space-y-4px"
655
+ }, Re = {
656
+ key: 1,
657
+ class: "font-bold text-center text-gray-500 py-20"
658
+ }, Oe = /* @__PURE__ */ H({
659
+ __name: "index",
660
+ setup(t) {
661
+ const {
662
+ $t: l,
663
+ $messageBox: o
664
+ } = window, s = w(), c = w(), m = w(""), r = w({}), _ = w("show");
665
+ function T() {
666
+ r.value = {}, _.value = "show", m.value = "添加服务器", c.value.open();
667
+ }
668
+ const b = (n) => {
669
+ o(n, "server_name", l("button.delete"), "error").then(async () => {
670
+ await ve({
671
+ data: n.map((d) => d.id)
672
+ }), s.value.getTableList();
673
+ });
674
+ };
675
+ function a(n) {
676
+ r.value = {
677
+ id: n.id
678
+ }, _.value = "deploy", m.value = "快速部署", c.value.open();
679
+ }
680
+ const u = w([{
681
+ ip: "",
682
+ port: ""
683
+ }]), S = w([{
684
+ ip: "",
685
+ port: ""
686
+ }]), L = w([{
687
+ ip: "",
688
+ port: ""
689
+ }]), D = w([{
690
+ ip: "",
691
+ port: ""
692
+ }]);
693
+ async function g(n) {
694
+ if (_.value === "show") {
695
+ await fe({
696
+ data: n
697
+ }), s.value.getTableList(), c.value.close();
698
+ return;
699
+ }
700
+ const d = (h, $) => {
701
+ const F = Math.max(h.length, $.length);
702
+ return Array.from({
703
+ length: F
704
+ }, (N, z) => {
705
+ var R, G, J, Z;
706
+ return {
707
+ src_ip: ((R = h[z]) == null ? void 0 : R.ip) || "",
708
+ src_port: Number((G = h[z]) == null ? void 0 : G.port) || 0,
709
+ dst_ip: ((J = $[z]) == null ? void 0 : J.ip) || "",
710
+ dst_port: Number((Z = $[z]) == null ? void 0 : Z.port) || 0
711
+ };
712
+ });
713
+ }, f = {
714
+ packages_id: [n.packages_id],
715
+ server_id: [r.value.id],
716
+ service_type: window.$prodType,
717
+ deploy_params: {
718
+ probe_name: n.probe_name || "",
719
+ collection_mode: n.collection_mode,
720
+ interface: n.interface || "",
721
+ engine_ip: n.engine_ip || "",
722
+ engine_port: n.engine_port || "",
723
+ filterWhitelist: d(u.value, S.value),
724
+ filterBlacklist: d(L.value, D.value)
725
+ }
726
+ };
727
+ await oe({
728
+ data: f
729
+ }), s.value.getTableList(), c.value.close();
730
+ }
731
+ function P(n) {
732
+ he({
733
+ data: [n.id]
734
+ }), s.value.getTableList();
735
+ }
736
+ function i(n) {
737
+ be({
738
+ data: [n.id]
739
+ }), s.value.getTableList();
740
+ }
741
+ function k(n) {
742
+ we({
743
+ data: [n.id]
744
+ }), s.value.getTableList();
745
+ }
746
+ const B = j([{
747
+ field: "server_name",
748
+ name: "服务器名称",
749
+ show: {
750
+ type: "input"
751
+ },
752
+ rules: [{
753
+ required: !0
754
+ }]
755
+ }, {
756
+ field: "ip_address",
757
+ name: "IP地址",
758
+ show: {
759
+ type: "input"
760
+ },
761
+ rules: [{
762
+ required: !0
763
+ }]
764
+ }, {
765
+ field: "ssh_port",
766
+ name: "端口",
767
+ show: {
768
+ type: "input",
769
+ dataType: "number"
770
+ },
771
+ rules: [{
772
+ required: !0,
773
+ type: "any"
774
+ }]
775
+ }, {
776
+ field: "ssh_username",
777
+ name: "SSH用户",
778
+ show: {
779
+ type: "input"
780
+ },
781
+ rules: [{
782
+ required: !0
783
+ }]
784
+ }, {
785
+ field: "ssh_password",
786
+ name: "SSH登录密码",
787
+ hide: !0,
788
+ show: {
789
+ type: "input",
790
+ prop: {
791
+ type: "password",
792
+ showPassword: !0
793
+ }
794
+ },
795
+ rules: [{
796
+ required: !0
797
+ }]
798
+ }, {
799
+ field: "arch",
800
+ name: "架构",
801
+ enum: ge,
802
+ show: {
803
+ type: "select"
804
+ },
805
+ rules: [{
806
+ required: !0
807
+ }]
808
+ }, {
809
+ field: "deployed_count",
810
+ name: "已部署探针数量",
811
+ render: (n) => e("span", null, [n.row.deployment_packages.length])
812
+ }, {
813
+ field: "status",
814
+ name: "状态",
815
+ tag: !0,
816
+ enum: [{
817
+ label: "在线",
818
+ value: 1,
819
+ tagType: "success"
820
+ }, {
821
+ label: "不在线",
822
+ value: 0,
823
+ tagType: "danger"
824
+ }]
825
+ }, {
826
+ field: "ssh_status",
827
+ name: "连通性检查",
828
+ tag: !0,
829
+ enum: [{
830
+ label: "成功",
831
+ value: 1,
832
+ tagType: "success"
833
+ }, {
834
+ label: "失败",
835
+ value: 0,
836
+ tagType: "danger"
837
+ }]
838
+ }, {
839
+ field: "check_env_ok",
840
+ name: "安装环境",
841
+ tag: !0,
842
+ enum: [{
843
+ label: "具备",
844
+ value: 1,
845
+ tagType: "success"
846
+ }, {
847
+ label: "不具备",
848
+ value: 0,
849
+ tagType: "danger"
850
+ }]
851
+ }, {
852
+ field: "packages_id",
853
+ name: "安装包",
854
+ enum: le,
855
+ fieldNames: {
856
+ value: "id",
857
+ label: "file_name"
858
+ },
859
+ deploy: {
860
+ type: "select"
861
+ },
862
+ hide: !0,
863
+ rules: [{
864
+ required: !0
865
+ }]
866
+ }, {
867
+ field: "probe_name",
868
+ name: "探针名称",
869
+ deploy: {
870
+ type: "input"
871
+ },
872
+ hide: !0,
873
+ rules: [{
874
+ required: !0
875
+ }]
876
+ }, {
877
+ field: "collection_mode",
878
+ name: "采集模式",
879
+ deploy: {
880
+ type: "input",
881
+ value: "DPDK",
882
+ disabled: !0
883
+ },
884
+ hide: !0,
885
+ rules: [{
886
+ required: !0
887
+ }]
888
+ }, {
889
+ field: "interface",
890
+ name: "采集网卡",
891
+ deploy: {
892
+ type: "input"
893
+ },
894
+ hide: !0,
895
+ rules: [{
896
+ required: !0
897
+ }]
898
+ }, {
899
+ field: "engine_ip",
900
+ name: "流量接收引擎IP",
901
+ deploy: {
902
+ type: "input"
903
+ },
904
+ rules: [{
905
+ required: !0,
906
+ type: "any"
907
+ }],
908
+ hide: !0
909
+ }, {
910
+ field: "engine_port",
911
+ name: "流量接收引擎端口",
912
+ deploy: {
913
+ type: "input",
914
+ dataType: "number"
915
+ },
916
+ hide: !0,
917
+ rules: [{
918
+ required: !0,
919
+ type: "any"
920
+ }]
921
+ }, {
922
+ field: "whitelist",
923
+ name: "探针过滤白名单",
924
+ deploy: {
925
+ type: "input",
926
+ tooltip: "白名单配置后,仅采集白名单内相关流量,如不填写,则采集所有流量",
927
+ render: () => e(A, null, [e("p", {
928
+ class: "color-[var(--el-text-color-regular)]"
929
+ }, [q("源ip端口:")]), e(V, {
930
+ modelValue: u.value,
931
+ "onUpdate:modelValue": (n) => u.value = n
932
+ }, null), e("p", {
933
+ class: "color-[var(--el-text-color-regular)]"
934
+ }, [q("目的ip端口:")]), e(V, {
935
+ modelValue: S.value,
936
+ "onUpdate:modelValue": (n) => S.value = n
937
+ }, null)])
938
+ },
939
+ hide: !0
940
+ }, {
941
+ field: "blacklist",
942
+ name: "探针过滤黑名单",
943
+ deploy: {
944
+ type: "input",
945
+ tooltip: "黑名单配置后,将不再采集黑名单内相关流量",
946
+ render: () => e(A, null, [e("p", {
947
+ class: "color-[var(--el-text-color-regular)]"
948
+ }, [q("源ip端口:")]), e(V, {
949
+ modelValue: L.value,
950
+ "onUpdate:modelValue": (n) => L.value = n
951
+ }, null), e("p", {
952
+ class: "color-[var(--el-text-color-regular)]"
953
+ }, [q("目的ip端口:")]), e(V, {
954
+ modelValue: D.value,
955
+ "onUpdate:modelValue": (n) => D.value = n
956
+ }, null)])
957
+ },
958
+ hide: !0
959
+ }, {
960
+ field: "operation",
961
+ name: window.$t("global.operate"),
962
+ width: 180,
963
+ fixed: "right",
964
+ render: (n) => e("div", null, [e(p("el-button"), {
965
+ link: !0,
966
+ type: "primary",
967
+ icon: "Connection",
968
+ title: "连通性检查",
969
+ class: "custom-btn",
970
+ onClick: () => P(n.row)
971
+ }, null), e(p("el-button"), {
972
+ link: !0,
973
+ type: "primary",
974
+ class: "custom-btn",
975
+ onClick: () => i(n.row)
976
+ }, {
977
+ icon: () => e(p("tds-svg-icon"), {
978
+ name: "install_env",
979
+ tip: "测试安装环境"
980
+ }, null)
981
+ }), e(p("el-button"), {
982
+ link: !0,
983
+ type: "primary",
984
+ class: "custom-btn",
985
+ onClick: () => k(n.row)
986
+ }, {
987
+ icon: () => e(p("tds-svg-icon"), {
988
+ name: "docker",
989
+ tip: "自动安装docker环境"
990
+ }, null)
991
+ }), e(p("el-button"), {
992
+ link: !0,
993
+ type: "primary",
994
+ class: "custom-btn",
995
+ onClick: () => a(n.row)
996
+ }, {
997
+ icon: () => e(p("tds-svg-icon"), {
998
+ name: "deployed",
999
+ tip: "部署"
1000
+ }, null)
1001
+ }), e(p("el-button"), {
1002
+ link: !0,
1003
+ type: "danger",
1004
+ icon: "Delete",
1005
+ title: l("button.delete"),
1006
+ onClick: () => b([n.row])
1007
+ }, null)])
1008
+ }]);
1009
+ return (n, d) => {
1010
+ const f = p("el-button"), h = p("el-table-column"), $ = p("TdsTable");
1011
+ return y(), x("div", Ne, [e($, {
1012
+ ref_key: "refTdsTable",
1013
+ ref: s,
1014
+ columns: B,
1015
+ "request-api": M(te),
1016
+ "search-col": 4,
1017
+ options: n.$tableOptions(),
1018
+ "reserve-selection": ""
1019
+ }, {
1020
+ tableHeader: E(() => [v("div", Ve, [e(f, {
1021
+ class: "custom-btn",
1022
+ type: "primary",
1023
+ icon: "Plus",
1024
+ plain: "",
1025
+ onClick: d[0] || (d[0] = (F) => T())
1026
+ }, {
1027
+ default: E(() => [q(C(M(l)("button.add")), 1)]),
1028
+ _: 1
1029
+ })])]),
1030
+ default: E(() => [e(h, {
1031
+ type: "expand"
1032
+ }, {
1033
+ default: E((F) => [F.row.deployment_packages && F.row.deployment_packages.length > 0 ? (y(), x("div", De, [d[1] || (d[1] = v("div", {
1034
+ class: "font-bold text-14px mt-12px"
1035
+ }, "已部署的探针包", -1)), v("div", ze, [(y(!0), x(A, null, K(F.row.deployment_packages, (N) => (y(), x("div", {
1036
+ key: N.id,
1037
+ class: "w-30% px-20px py-10px rounded-8px bg-[var(--el-fill-color-light)] border border-solid border-[var(--el-border-color-lighter)] hover:shadow-md transition-shadow"
1038
+ }, [v("div", Ie, C(N.file_name), 1), v("div", Pe, [v("p", null, "版本: " + C(N.version), 1), v("p", null, "部署时间: " + C(N.deployment_time), 1)])]))), 128))])])) : (y(), x("div", Re, "暂无部署服务器记录"))]),
1039
+ _: 1
1040
+ })]),
1041
+ _: 1
1042
+ }, 8, ["columns", "request-api", "options"]), e(M(Y), X({
1043
+ ref_key: "refTdsForm",
1044
+ ref: c
1045
+ }, n.$formBindProps({
1046
+ title: m.value,
1047
+ form: r.value,
1048
+ columns: B,
1049
+ formKey: _.value
1050
+ }), {
1051
+ onSubmit: g
1052
+ }), null, 16)]);
1053
+ };
1054
+ }
1055
+ }), He = {
1056
+ class: "table-box"
1057
+ }, Ke = {
1058
+ style: {
1059
+ padding: "0 50px"
1060
+ }
1061
+ }, We = /* @__PURE__ */ H({
1062
+ __name: "index",
1063
+ setup(t) {
1064
+ const l = j([{
1065
+ field: "packages_name",
1066
+ name: "探针包",
1067
+ render: (o) => e(A, null, [e("p", {
1068
+ class: "font-bold"
1069
+ }, [o.row.packages_name]), e("p", {
1070
+ class: "text-gray-400"
1071
+ }, [o.row.packages_version])])
1072
+ }, {
1073
+ field: "server_name",
1074
+ name: "服务器",
1075
+ render: (o) => e(A, null, [e("p", {
1076
+ class: "font-bold"
1077
+ }, [o.row.server_name]), e("p", {
1078
+ class: "text-gray-400"
1079
+ }, [o.row.ip_address])])
1080
+ }, {
1081
+ field: "deployment_time",
1082
+ name: "部署时间"
1083
+ }, {
1084
+ field: "deployment_status",
1085
+ name: "状态",
1086
+ tag: !0,
1087
+ enum: [{
1088
+ label: "部署失败",
1089
+ value: 0,
1090
+ tagType: "danger"
1091
+ }, {
1092
+ label: "部署中",
1093
+ value: 1,
1094
+ tagType: "warning"
1095
+ }, {
1096
+ label: "部署成功",
1097
+ value: 2,
1098
+ tagType: "success"
1099
+ }]
1100
+ }]);
1101
+ return (o, s) => {
1102
+ const c = p("el-table-column"), m = p("TdsTable");
1103
+ return y(), x("div", He, [e(m, {
1104
+ ref: "refTdsTable",
1105
+ columns: l,
1106
+ "search-col": 4,
1107
+ "request-api": M(xe),
1108
+ options: o.$tableOptions(),
1109
+ "reserve-selection": ""
1110
+ }, {
1111
+ default: E(() => [e(c, {
1112
+ type: "expand"
1113
+ }, {
1114
+ default: E((r) => [v("div", Ke, C(r.row.deployment_log), 1)]),
1115
+ _: 1
1116
+ })]),
1117
+ _: 1
1118
+ }, 8, ["columns", "request-api", "options"])]);
1119
+ };
1120
+ }
1121
+ }), je = { class: "main-wrapper" }, Ge = /* @__PURE__ */ H({
1122
+ name: "TCProbe",
1123
+ __name: "index",
1124
+ props: {
1125
+ token: {
1126
+ type: String,
1127
+ default: ""
1128
+ }
1129
+ },
1130
+ setup(t) {
1131
+ const l = t, o = w("package");
1132
+ return (s, c) => {
1133
+ const m = p("el-tab-pane"), r = p("el-tabs");
1134
+ return y(), x("div", je, [
1135
+ e(r, {
1136
+ modelValue: o.value,
1137
+ "onUpdate:modelValue": c[0] || (c[0] = (_) => o.value = _),
1138
+ class: "demo-tabs"
1139
+ }, {
1140
+ default: E(() => [
1141
+ e(m, {
1142
+ label: "安装包管理",
1143
+ name: "package"
1144
+ }, {
1145
+ default: E(() => [
1146
+ o.value === "package" ? (y(), W(Be, {
1147
+ key: 0,
1148
+ token: l.token
1149
+ }, null, 8, ["token"])) : O("", !0)
1150
+ ]),
1151
+ _: 1
1152
+ }),
1153
+ e(m, {
1154
+ label: "探针部署",
1155
+ name: "deploy"
1156
+ }, {
1157
+ default: E(() => [
1158
+ o.value === "deploy" ? (y(), W(Oe, { key: 0 })) : O("", !0)
1159
+ ]),
1160
+ _: 1
1161
+ }),
1162
+ e(m, {
1163
+ label: "部署历史",
1164
+ name: "history"
1165
+ }, {
1166
+ default: E(() => [
1167
+ o.value === "history" ? (y(), W(We, { key: 0 })) : O("", !0)
1168
+ ]),
1169
+ _: 1
1170
+ })
1171
+ ]),
1172
+ _: 1
1173
+ }, 8, ["modelValue"])
1174
+ ]);
1175
+ };
1176
+ }
1177
+ });
1178
+ const Je = /* @__PURE__ */ ee(Ge, [["__scopeId", "data-v-7172e806"]]), Ze = (t, l) => {
1179
+ if (t.install = (o) => {
1180
+ for (const s of [t, ...Object.values(l ?? {})])
1181
+ o.component(s.name, s);
1182
+ }, l)
1183
+ for (const [o, s] of Object.entries(l))
1184
+ t[o] = s;
1185
+ return t;
1186
+ }, Qe = Ze(Je), Xe = {
1187
+ TCProbe: Qe
1188
+ }, ot = {
1189
+ install(t, l) {
1190
+ Object.entries(Xe).forEach(([o, s]) => {
1191
+ t.component(o, s);
1192
+ }), l != null && l.prodType && (window.$prodType = l.prodType), l != null && l.envURL && (window.$probeURL = l.envURL);
1193
+ }
1194
+ };
1195
+ export {
1196
+ Qe as TCProbe,
1197
+ ot as default
1198
+ };
@@ -0,0 +1 @@
1
+ (function(N,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue"),require("@element-plus/icons-vue"),require("topdatasec-ui"),require("element-plus")):typeof define=="function"&&define.amd?define(["exports","vue","@element-plus/icons-vue","topdatasec-ui","element-plus"],e):(N=typeof globalThis<"u"?globalThis:N||self,e(N.TProbeUI={},N.Vue,N.IconsVue,N.TopdatasecUI,N.ElementPlus))})(this,function(N,e,U,F,D){"use strict";const K={key:0,class:"absolute right--13px text-#f56c6c hover:cursor-pointer"},W=e.defineComponent({__name:"IpPortList",props:{modelValue:{default:()=>[{ip:"",port:""}]},modelModifiers:{}},emits:["update:modelValue"],setup(t){const o=e.useModel(t,"modelValue"),{$t:l}=window;function s(){o.value=[...o.value,{ip:"",port:""}]}function p(u){const n=[...o.value];n.splice(u,1),o.value=n}return(u,n)=>{const m=e.resolveComponent("el-input"),w=e.resolveComponent("el-form-item"),g=e.resolveComponent("el-icon"),a=e.resolveComponent("el-button");return e.openBlock(),e.createElementBlock("div",null,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(o.value,(d,k)=>(e.openBlock(),e.createElementBlock("div",{key:k,class:"flex form-m0 w-100% mb-5px"},[e.createVNode(w,{class:"w-70%"},{default:e.withCtx(()=>[e.createVNode(m,{modelValue:d.ip,"onUpdate:modelValue":V=>d.ip=V,class:"min-w-300px w-100%",placeholder:"IP"},null,8,["modelValue","onUpdate:modelValue"])]),_:2},1024),e.createVNode(w,{class:"ml-auto w-30%"},{default:e.withCtx(()=>[e.createVNode(m,{modelValue:d.port,"onUpdate:modelValue":V=>d.port=V,class:"ml-10",placeholder:e.unref(l)("global.port")},null,8,["modelValue","onUpdate:modelValue","placeholder"])]),_:2},1024),o.value.length>1?(e.openBlock(),e.createElementBlock("div",K,[e.createVNode(g,{onClick:V=>p(k)},{default:e.withCtx(()=>[e.createVNode(e.unref(U.CircleClose))]),_:1},8,["onClick"])])):e.createCommentVNode("",!0)]))),128)),e.createVNode(a,{class:"w-100% mt-10px border-dashed!",icon:"Plus",onClick:s})])}}}),Fe="",A=(t,o)=>{const l=t.__vccOpts||t;for(const[s,p]of o)l[s]=p;return l},E=A(W,[["__scopeId","data-v-16fc9c64"]]),B=5*1024*1024;function G(t,o){return new Promise((l,s)=>{const p=new(void 0),u=new FileReader,n=Math.ceil(t.size/B);let m=0;u.onload=g=>{var a;if(p.append((a=g.target)==null?void 0:a.result),m++,o){const d=Math.floor(m/n*100);o(d)}if(m<n)w();else{const d=p.end();l(d)}},u.onerror=()=>{s(new Error("MD5计算失败"))};function w(){const g=m*B,a=Math.min(g+B,t.size);u.readAsArrayBuffer(t.slice(g,a))}w()})}async function J(t,o,l,s,p,u="/api/upload/chunk"){const n=o*B,m=Math.min(n+B,t.size),w=t.slice(n,m),g=m-n,a=new FormData;a.append("file",w,t.name),a.append("chunkIndex",String(o+1)),a.append("totalChunkNum",String(l)),a.append("fileMd5",s),a.append("tds_token",p),a.append("fileName",t.name),a.append("fileSize",String(t.size)),a.append("fileExt",t.name.substring(t.name.lastIndexOf(".")+1)),a.append("chunkSize",String(B)),a.append("currentChunkSize",String(g));try{const d=await fetch(u,{method:"POST",body:a});if(console.log(d,"upload response"),!d.ok)throw new Error(`分片 ${o+1} 上传失败,HTTP状态码: ${d.status}`);const k=await d.json();if(console.log(k,"upload result"),k.recode!==0)throw new Error(`上传失败: ${k.remsg||"未知错误"}`);return!0}catch(d){throw console.error(`上传分片 ${o+1} 时出错:`,d),d}}async function Z(t,o="/api/upload/merge"){try{if(!(await fetch(o,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})).ok)throw new Error("文件合并失败");return!0}catch(l){return console.error("合并分片时出错:",l),!1}}async function Q(t){const{token:o,file:l,fileDesc:s="",uploadUrl:p="/api/upload/chunk",mergeUrl:u="/api/upload/merge",onProgress:n,onSuccess:m,onError:w}=t;try{n==null||n({progress:0,statusText:"正在计算文件MD5...",status:"preparing"});const a=await G(l,f=>{n==null||n({progress:Math.floor(f*.1),statusText:`正在计算文件MD5... ${f}%`,status:"preparing"})});n==null||n({progress:10,statusText:"MD5计算完成",status:"preparing",fileMd5:a});const d=Math.ceil(l.size/B);n==null||n({progress:10,statusText:`开始上传 (共${d}个分片)`,status:"uploading",fileMd5:a});for(let f=0;f<d;f++){const q=Math.floor(f/d*80);n==null||n({progress:10+q,statusText:`正在上传分片 ${f+1}/${d}`,status:"uploading",fileMd5:a}),await J(l,f,d,a,o,p)}n==null||n({progress:90,statusText:"正在合并文件...",status:"merging",fileMd5:a});const k=l.name.substring(l.name.lastIndexOf(".")+1),V={fileDesc:s,fileExt:k,fileMd5:a,fileName:l.name,fileSize:String(l.size),tds_token:o,totalChunkNum:String(d)};if(!await Z(V,u))throw new Error("文件合并失败");n==null||n({progress:100,statusText:"上传成功",status:"success",fileMd5:a}),D.ElMessage.success(`${l.name} 上传成功`),m==null||m(a)}catch(g){n==null||n({progress:0,statusText:g.message||"上传失败",status:"error"}),D.ElMessage.error(`${l.name} 上传失败: ${g.message}`),w==null||w(g)}}function X(t){if(t===0)return"0 B";const o=1024,l=["B","KB","MB","GB","TB"],s=Math.floor(Math.log(t)/Math.log(o));return Math.round(t/Math.pow(o,s)*100)/100+" "+l[s]}const x={get deployURL(){return window.$probeURL||""}},I=(t={})=>window.$http.request({url:`${x.deployURL}/service_deploy/deployment/servers/get`,method:"get",params:t,isError:!1}),Y=t=>window.$http.request({url:`${x.deployURL}/service_deploy/deployment/servers/add`,method:"post",data:t}),v=t=>window.$http.request({url:`${x.deployURL}/service_deploy/deployment/servers/delete`,method:"delete",data:t}),P=(t={})=>window.$http.request({url:`${x.deployURL}/service_deploy/deployment/packages/get`,method:"get",params:t,isError:!1}),ee=t=>window.$http.request({url:`${x.deployURL}/service_deploy/deployment/packages/delete`,method:"delete",data:t}),te=()=>window.$http.request({url:`${x.deployURL}/service_deploy/deployment/servers/arch_type`,method:"get",isError:!1}),z=t=>window.$http.request({url:`${x.deployURL}/service_deploy/deployment/deploy`,method:"post",data:t}),oe=t=>window.$http.request({url:`${x.deployURL}/service_deploy/deployment/servers/test_connectivity`,method:"post",data:t}),le=t=>window.$http.request({url:`${x.deployURL}/service_deploy/deployment/servers/check_env`,method:"post",data:t}),re=t=>window.$http.request({url:`${x.deployURL}/service_deploy/deployment/servers/install_env`,method:"post",data:t}),ne=(t={})=>window.$http.request({url:`${x.deployURL}/service_deploy/deployment/history/get`,method:"get",params:t,isError:!1}),ae={class:"h-100%"},se={key:0,class:"upload-progress-list"},de={class:"file-info"},ie={class:"file-name"},ce={class:"file-size"},pe={class:"progress-text"},ue={class:"table-box h-[calc(100%-220px)]"},me={key:0},_e={class:"flex flex-wrap gap-12px p-12px"},fe={class:"font-bold text-14px mb-8px text-[var(--el-text-color-primary)]"},ye={class:"text-12px text-[var(--el-text-color-regular)] space-y-4px"},ge={key:1,class:"font-bold text-center text-gray-500 py-20"},he=e.defineComponent({__name:"index",props:{token:{type:String,default:""}},setup(t){const o=e.ref(),l=e.ref(),s=e.ref("快速部署"),p=e.ref({}),{$t:u,$messageBox:n}=window;function m(i){p.value={id:i.id},l.value.open()}const w=e.ref([{ip:"",port:""}]),g=e.ref([{ip:"",port:""}]),a=e.ref([{ip:"",port:""}]),d=e.ref([{ip:"",port:""}]);async function k(i){const h=(r,c)=>{const _=Math.max(r.length,c.length);return Array.from({length:_},(y,b)=>{var T,$,L,M;return{src_ip:((T=r[b])==null?void 0:T.ip)||"",src_port:Number(($=r[b])==null?void 0:$.port)||0,dst_ip:((L=c[b])==null?void 0:L.ip)||"",dst_port:Number((M=c[b])==null?void 0:M.port)||0}})},C={packages_id:[p.value.id],server_id:i.server_id,service_type:window.$prodType,deploy_params:{probe_name:i.probe_name||"",collection_mode:i.collection_mode,interface:i.interface||"",engine_ip:i.engine_ip||"",engine_port:i.engine_port||"",filterWhitelist:h(w.value,g.value),filterBlacklist:h(a.value,d.value)}};await z({data:C}),o.value.getTableList(),l.value.close()}async function V(i){n(i,"file_name",u("button.delete"),"error").then(async()=>{await ee({data:[i.id]}),o.value.getTableList()})}const S=e.reactive([{field:"server_id",name:"选择服务器",enum:I,fieldNames:{value:"id",label:"server_name"},show:{type:"select",prop:{multiple:!0},dataType:"any"},hide:!0,rules:[{required:!0}]},{field:"file_name",name:"文件名称"},{field:"version",name:"版本"},{field:"file_size",name:"大小"},{field:"upload_time",name:"上传时间"},{field:"deployment_server",name:"已部署服务器数",render:i=>{var h;return((h=i.row.deployment_server)==null?void 0:h.length)||0}},{field:"upload_status",name:"状态",tag:!0,enum:[{label:"上传失败",value:0,tagType:"danger"},{label:"上传中",value:1,tagType:"warning"},{label:"上传成功",value:2,tagType:"success"}]},{field:"probe_name",name:"探针名称",show:{type:"input"},hide:!0,rules:[{required:!0}]},{field:"collection_mode",name:"采集模式",show:{type:"input",value:"DPDK",disabled:!0},hide:!0,rules:[{required:!0}]},{field:"interface",name:"采集网卡",show:{type:"input"},hide:!0,rules:[{required:!0}]},{field:"engine_ip",name:"流量接收引擎IP",show:{type:"input"},hide:!0},{field:"engine_port",name:"流量接收引擎端口",show:{type:"input",dataType:"number"},hide:!0,rules:[{required:!0,type:"any"}]},{field:"whitelist",name:"探针过滤白名单",show:{type:"input",tooltip:"白名单配置后,仅采集白名单内相关流量,如不填写,则采集所有流量",render:()=>e.createVNode(e.Fragment,null,[e.createVNode("p",{class:"color-[var(--el-text-color-regular)]"},[e.createTextVNode("源ip端口:")]),e.createVNode(E,{modelValue:w.value,"onUpdate:modelValue":i=>w.value=i},null),e.createVNode("p",{class:"color-[var(--el-text-color-regular)]"},[e.createTextVNode("目的ip端口:")]),e.createVNode(E,{modelValue:g.value,"onUpdate:modelValue":i=>g.value=i},null)])},hide:!0},{field:"blacklist",name:"探针过滤黑名单",show:{type:"input",tooltip:"黑名单配置后,将不再采集黑名单内相关流量",render:()=>e.createVNode(e.Fragment,null,[e.createVNode("p",{class:"color-[var(--el-text-color-regular)]"},[e.createTextVNode("源ip端口:")]),e.createVNode(E,{modelValue:a.value,"onUpdate:modelValue":i=>a.value=i},null),e.createVNode("p",{class:"color-[var(--el-text-color-regular)]"},[e.createTextVNode("目的ip端口:")]),e.createVNode(E,{modelValue:d.value,"onUpdate:modelValue":i=>d.value=i},null)])},hide:!0},{field:"operation",name:window.$t("global.operate"),width:140,fixed:"right",render:i=>e.createVNode("div",null,[e.createVNode(e.resolveComponent("el-button"),{link:!0,type:"primary",class:"custom-btn",onClick:()=>m(i.row)},{icon:()=>e.createVNode(e.resolveComponent("tds-svg-icon"),{name:"deployed",tip:"部署"},null)}),e.createVNode(e.resolveComponent("el-button"),{link:!0,type:"danger",icon:"Delete",title:u("button.delete"),onClick:()=>V([i.row])},null)])}]),f=e.ref([]);function q(i){const h=i.raw;if(!h)return;const C={fileName:h.name,fileSize:h.size,progress:0,progressStatus:"",statusText:"准备上传..."};f.value.push(C);const r=f.value.length-1;Q({file:h,fileDesc:"探针安装包",uploadUrl:x.deployURL+"/service_deploy/deployment/packages/upload",mergeUrl:x.deployURL+"/service_deploy/deployment/packages/upload_merge",onProgress:c=>{const _=f.value[r];_&&(_.progress=c.progress,_.statusText=c.statusText,c.fileMd5&&(_.fileMd5=c.fileMd5),c.status==="error"?_.progressStatus="exception":c.status==="success"?_.progressStatus="success":_.progressStatus="")},onSuccess:()=>{var _;const c=f.value[r];c&&(c.progress=100,c.progressStatus="success",c.statusText="上传成功"),(_=o.value)==null||_.getTableList(),setTimeout(()=>{const y=f.value.findIndex(b=>b.fileName===h.name);y!==-1&&f.value.splice(y,1)},3e3)},onError:c=>{console.error("文件上传失败:",c);const _=f.value[r];_&&(_.progressStatus="exception",_.statusText=c.message||"上传失败")}})}return(i,h)=>{const C=e.resolveComponent("el-icon"),r=e.resolveComponent("el-upload"),c=e.resolveComponent("el-progress"),_=e.resolveComponent("el-table-column");return e.openBlock(),e.createElementBlock("div",ae,[e.createVNode(r,{class:"upload-demo mt-10px",drag:"",action:"","auto-upload":!1,accept:".tar.gz,.tgz","on-change":q,"show-file-list":!1,multiple:""},{default:e.withCtx(()=>[e.createVNode(C,{class:"el-icon--upload"},{default:e.withCtx(()=>[e.createVNode(e.unref(U.UploadFilled))]),_:1}),h[0]||(h[0]=e.createElementVNode("div",{class:"el-upload__text"},[e.createTextVNode(" 点击或拖拽文件到此处上传   "),e.createElementVNode("br"),e.createElementVNode("em",null,"支持的格式: tar.gz, tgz")],-1))]),_:1}),f.value.length>0?(e.openBlock(),e.createElementBlock("div",se,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(f.value,y=>(e.openBlock(),e.createElementBlock("div",{key:y.fileName,class:"upload-progress-item"},[e.createElementVNode("div",de,[e.createElementVNode("span",ie,e.toDisplayString(y.fileName),1),e.createElementVNode("span",ce,e.toDisplayString(e.unref(X)(y.fileSize)),1)]),e.createVNode(c,{percentage:y.progress,status:y.progressStatus},null,8,["percentage","status"]),e.createElementVNode("div",pe,e.toDisplayString(y.statusText),1)]))),128))])):e.createCommentVNode("",!0),e.createElementVNode("div",ue,[e.createVNode(e.unref(F.TdsTable),{ref_key:"refTdsTable",ref:o,columns:S,"request-api":e.unref(P),options:i.$tableOptions()},{default:e.withCtx(()=>[e.createVNode(_,{type:"expand"},{default:e.withCtx(y=>[y.row.deployment_server&&y.row.deployment_server.length>0?(e.openBlock(),e.createElementBlock("div",me,[h[1]||(h[1]=e.createElementVNode("div",{class:"font-bold text-14px mt-12px"},"已部署的服务器",-1)),e.createElementVNode("div",_e,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(y.row.deployment_server,b=>(e.openBlock(),e.createElementBlock("div",{key:b.id,class:"w-30% px-20px py-10px rounded-8px bg-[var(--el-fill-color-light)] border border-solid border-[var(--el-border-color-lighter)] hover:shadow-md transition-shadow"},[e.createElementVNode("div",fe,e.toDisplayString(b.server_name),1),e.createElementVNode("div",ye,[e.createElementVNode("p",null,"IP: "+e.toDisplayString(b.ip_address),1),e.createElementVNode("p",null,"部署时间: "+e.toDisplayString(b.deployment_time),1)])]))),128))])])):(e.openBlock(),e.createElementBlock("div",ge,"暂无部署服务器记录"))]),_:1})]),_:1},8,["columns","request-api","options"])]),e.createVNode(e.unref(F.TdsForm),e.mergeProps({ref_key:"refTdsForm",ref:l},i.$formBindProps({title:s.value,form:p.value,columns:S}),{onSubmit:k}),null,16)])}}}),we={class:"table-box"},be={class:"flex items-center"},ke={key:0},xe={class:"flex flex-wrap gap-12px p-12px"},Ve={class:"font-bold text-14px mb-8px text-[var(--el-text-color-primary)]"},Ne={class:"text-12px text-[var(--el-text-color-regular)] space-y-4px"},Te={key:1,class:"font-bold text-center text-gray-500 py-20"},Ee=e.defineComponent({__name:"index",setup(t){const{$t:o,$messageBox:l}=window,s=e.ref(),p=e.ref(),u=e.ref(""),n=e.ref({}),m=e.ref("show");function w(){n.value={},m.value="show",u.value="添加服务器",p.value.open()}const g=r=>{l(r,"server_name",o("button.delete"),"error").then(async()=>{await v({data:r.map(c=>c.id)}),s.value.getTableList()})};function a(r){n.value={id:r.id},m.value="deploy",u.value="快速部署",p.value.open()}const d=e.ref([{ip:"",port:""}]),k=e.ref([{ip:"",port:""}]),V=e.ref([{ip:"",port:""}]),S=e.ref([{ip:"",port:""}]);async function f(r){if(m.value==="show"){await Y({data:r}),s.value.getTableList(),p.value.close();return}const c=(y,b)=>{const T=Math.max(y.length,b.length);return Array.from({length:T},($,L)=>{var M,O,j,H;return{src_ip:((M=y[L])==null?void 0:M.ip)||"",src_port:Number((O=y[L])==null?void 0:O.port)||0,dst_ip:((j=b[L])==null?void 0:j.ip)||"",dst_port:Number((H=b[L])==null?void 0:H.port)||0}})},_={packages_id:[r.packages_id],server_id:[n.value.id],service_type:window.$prodType,deploy_params:{probe_name:r.probe_name||"",collection_mode:r.collection_mode,interface:r.interface||"",engine_ip:r.engine_ip||"",engine_port:r.engine_port||"",filterWhitelist:c(d.value,k.value),filterBlacklist:c(V.value,S.value)}};await z({data:_}),s.value.getTableList(),p.value.close()}function q(r){oe({data:[r.id]}),s.value.getTableList()}function i(r){le({data:[r.id]}),s.value.getTableList()}function h(r){re({data:[r.id]}),s.value.getTableList()}const C=e.reactive([{field:"server_name",name:"服务器名称",show:{type:"input"},rules:[{required:!0}]},{field:"ip_address",name:"IP地址",show:{type:"input"},rules:[{required:!0}]},{field:"ssh_port",name:"端口",show:{type:"input",dataType:"number"},rules:[{required:!0,type:"any"}]},{field:"ssh_username",name:"SSH用户",show:{type:"input"},rules:[{required:!0}]},{field:"ssh_password",name:"SSH登录密码",hide:!0,show:{type:"input",prop:{type:"password",showPassword:!0}},rules:[{required:!0}]},{field:"arch",name:"架构",enum:te,show:{type:"select"},rules:[{required:!0}]},{field:"deployed_count",name:"已部署探针数量",render:r=>e.createVNode("span",null,[r.row.deployment_packages.length])},{field:"status",name:"状态",tag:!0,enum:[{label:"在线",value:1,tagType:"success"},{label:"不在线",value:0,tagType:"danger"}]},{field:"ssh_status",name:"连通性检查",tag:!0,enum:[{label:"成功",value:1,tagType:"success"},{label:"失败",value:0,tagType:"danger"}]},{field:"check_env_ok",name:"安装环境",tag:!0,enum:[{label:"具备",value:1,tagType:"success"},{label:"不具备",value:0,tagType:"danger"}]},{field:"packages_id",name:"安装包",enum:P,fieldNames:{value:"id",label:"file_name"},deploy:{type:"select"},hide:!0,rules:[{required:!0}]},{field:"probe_name",name:"探针名称",deploy:{type:"input"},hide:!0,rules:[{required:!0}]},{field:"collection_mode",name:"采集模式",deploy:{type:"input",value:"DPDK",disabled:!0},hide:!0,rules:[{required:!0}]},{field:"interface",name:"采集网卡",deploy:{type:"input"},hide:!0,rules:[{required:!0}]},{field:"engine_ip",name:"流量接收引擎IP",deploy:{type:"input"},rules:[{required:!0,type:"any"}],hide:!0},{field:"engine_port",name:"流量接收引擎端口",deploy:{type:"input",dataType:"number"},hide:!0,rules:[{required:!0,type:"any"}]},{field:"whitelist",name:"探针过滤白名单",deploy:{type:"input",tooltip:"白名单配置后,仅采集白名单内相关流量,如不填写,则采集所有流量",render:()=>e.createVNode(e.Fragment,null,[e.createVNode("p",{class:"color-[var(--el-text-color-regular)]"},[e.createTextVNode("源ip端口:")]),e.createVNode(E,{modelValue:d.value,"onUpdate:modelValue":r=>d.value=r},null),e.createVNode("p",{class:"color-[var(--el-text-color-regular)]"},[e.createTextVNode("目的ip端口:")]),e.createVNode(E,{modelValue:k.value,"onUpdate:modelValue":r=>k.value=r},null)])},hide:!0},{field:"blacklist",name:"探针过滤黑名单",deploy:{type:"input",tooltip:"黑名单配置后,将不再采集黑名单内相关流量",render:()=>e.createVNode(e.Fragment,null,[e.createVNode("p",{class:"color-[var(--el-text-color-regular)]"},[e.createTextVNode("源ip端口:")]),e.createVNode(E,{modelValue:V.value,"onUpdate:modelValue":r=>V.value=r},null),e.createVNode("p",{class:"color-[var(--el-text-color-regular)]"},[e.createTextVNode("目的ip端口:")]),e.createVNode(E,{modelValue:S.value,"onUpdate:modelValue":r=>S.value=r},null)])},hide:!0},{field:"operation",name:window.$t("global.operate"),width:180,fixed:"right",render:r=>e.createVNode("div",null,[e.createVNode(e.resolveComponent("el-button"),{link:!0,type:"primary",icon:"Connection",title:"连通性检查",class:"custom-btn",onClick:()=>q(r.row)},null),e.createVNode(e.resolveComponent("el-button"),{link:!0,type:"primary",class:"custom-btn",onClick:()=>i(r.row)},{icon:()=>e.createVNode(e.resolveComponent("tds-svg-icon"),{name:"install_env",tip:"测试安装环境"},null)}),e.createVNode(e.resolveComponent("el-button"),{link:!0,type:"primary",class:"custom-btn",onClick:()=>h(r.row)},{icon:()=>e.createVNode(e.resolveComponent("tds-svg-icon"),{name:"docker",tip:"自动安装docker环境"},null)}),e.createVNode(e.resolveComponent("el-button"),{link:!0,type:"primary",class:"custom-btn",onClick:()=>a(r.row)},{icon:()=>e.createVNode(e.resolveComponent("tds-svg-icon"),{name:"deployed",tip:"部署"},null)}),e.createVNode(e.resolveComponent("el-button"),{link:!0,type:"danger",icon:"Delete",title:o("button.delete"),onClick:()=>g([r.row])},null)])}]);return(r,c)=>{const _=e.resolveComponent("el-button"),y=e.resolveComponent("el-table-column"),b=e.resolveComponent("TdsTable");return e.openBlock(),e.createElementBlock("div",we,[e.createVNode(b,{ref_key:"refTdsTable",ref:s,columns:C,"request-api":e.unref(I),"search-col":4,options:r.$tableOptions(),"reserve-selection":""},{tableHeader:e.withCtx(()=>[e.createElementVNode("div",be,[e.createVNode(_,{class:"custom-btn",type:"primary",icon:"Plus",plain:"",onClick:c[0]||(c[0]=T=>w())},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(e.unref(o)("button.add")),1)]),_:1})])]),default:e.withCtx(()=>[e.createVNode(y,{type:"expand"},{default:e.withCtx(T=>[T.row.deployment_packages&&T.row.deployment_packages.length>0?(e.openBlock(),e.createElementBlock("div",ke,[c[1]||(c[1]=e.createElementVNode("div",{class:"font-bold text-14px mt-12px"},"已部署的探针包",-1)),e.createElementVNode("div",xe,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(T.row.deployment_packages,$=>(e.openBlock(),e.createElementBlock("div",{key:$.id,class:"w-30% px-20px py-10px rounded-8px bg-[var(--el-fill-color-light)] border border-solid border-[var(--el-border-color-lighter)] hover:shadow-md transition-shadow"},[e.createElementVNode("div",Ve,e.toDisplayString($.file_name),1),e.createElementVNode("div",Ne,[e.createElementVNode("p",null,"版本: "+e.toDisplayString($.version),1),e.createElementVNode("p",null,"部署时间: "+e.toDisplayString($.deployment_time),1)])]))),128))])])):(e.openBlock(),e.createElementBlock("div",Te,"暂无部署服务器记录"))]),_:1})]),_:1},8,["columns","request-api","options"]),e.createVNode(e.unref(F.TdsForm),e.mergeProps({ref_key:"refTdsForm",ref:p},r.$formBindProps({title:u.value,form:n.value,columns:C,formKey:m.value}),{onSubmit:f}),null,16)])}}}),Ce={class:"table-box"},$e={style:{padding:"0 50px"}},Be=e.defineComponent({__name:"index",setup(t){const o=e.reactive([{field:"packages_name",name:"探针包",render:l=>e.createVNode(e.Fragment,null,[e.createVNode("p",{class:"font-bold"},[l.row.packages_name]),e.createVNode("p",{class:"text-gray-400"},[l.row.packages_version])])},{field:"server_name",name:"服务器",render:l=>e.createVNode(e.Fragment,null,[e.createVNode("p",{class:"font-bold"},[l.row.server_name]),e.createVNode("p",{class:"text-gray-400"},[l.row.ip_address])])},{field:"deployment_time",name:"部署时间"},{field:"deployment_status",name:"状态",tag:!0,enum:[{label:"部署失败",value:0,tagType:"danger"},{label:"部署中",value:1,tagType:"warning"},{label:"部署成功",value:2,tagType:"success"}]}]);return(l,s)=>{const p=e.resolveComponent("el-table-column"),u=e.resolveComponent("TdsTable");return e.openBlock(),e.createElementBlock("div",Ce,[e.createVNode(u,{ref:"refTdsTable",columns:o,"search-col":4,"request-api":e.unref(ne),options:l.$tableOptions(),"reserve-selection":""},{default:e.withCtx(()=>[e.createVNode(p,{type:"expand"},{default:e.withCtx(n=>[e.createElementVNode("div",$e,e.toDisplayString(n.row.deployment_log),1)]),_:1})]),_:1},8,["columns","request-api","options"])])}}}),Se={class:"main-wrapper"},Le=e.defineComponent({name:"TCProbe",__name:"index",props:{token:{type:String,default:""}},setup(t){const o=t,l=e.ref("package");return(s,p)=>{const u=e.resolveComponent("el-tab-pane"),n=e.resolveComponent("el-tabs");return e.openBlock(),e.createElementBlock("div",Se,[e.createVNode(n,{modelValue:l.value,"onUpdate:modelValue":p[0]||(p[0]=m=>l.value=m),class:"demo-tabs"},{default:e.withCtx(()=>[e.createVNode(u,{label:"安装包管理",name:"package"},{default:e.withCtx(()=>[l.value==="package"?(e.openBlock(),e.createBlock(he,{key:0,token:o.token},null,8,["token"])):e.createCommentVNode("",!0)]),_:1}),e.createVNode(u,{label:"探针部署",name:"deploy"},{default:e.withCtx(()=>[l.value==="deploy"?(e.openBlock(),e.createBlock(Ee,{key:0})):e.createCommentVNode("",!0)]),_:1}),e.createVNode(u,{label:"部署历史",name:"history"},{default:e.withCtx(()=>[l.value==="history"?(e.openBlock(),e.createBlock(Be,{key:0})):e.createCommentVNode("",!0)]),_:1})]),_:1},8,["modelValue"])])}}}),Ue="",R=((t,o)=>{if(t.install=l=>{for(const s of[t,...Object.values(o??{})])l.component(s.name,s)},o)for(const[l,s]of Object.entries(o))t[l]=s;return t})(A(Le,[["__scopeId","data-v-7172e806"]])),qe={TCProbe:R},Me={install(t,o){Object.entries(qe).forEach(([l,s])=>{t.component(l,s)}),o!=null&&o.prodType&&(window.$prodType=o.prodType),o!=null&&o.envURL&&(window.$probeURL=o.envURL)}};N.TCProbe=R,N.default=Me,Object.defineProperties(N,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@topdatasec/probe",
3
+ "version": "1.0.0",
4
+ "description": "探针部署管理组件",
5
+ "author": "wangguiwang",
6
+ "license": "MIT",
7
+ "private": false,
8
+ "main": "lib/t-probe-ui.es.js",
9
+ "module": "lib/t-probe-ui.es.js",
10
+ "types": "lib/index.d.ts",
11
+ "type": "module",
12
+ "files": [
13
+ "package.json",
14
+ "README.md",
15
+ "LICENSE",
16
+ "lib"
17
+ ],
18
+ "scripts": {
19
+ "lib": "node -e \"const fs=require('fs');fs.rmSync('lib',{recursive:true,force:true})\" && vite build",
20
+ "pub": "npm publish --access public --registry=https://registry.npmjs.org/",
21
+ "prettier": "prettier --write \"packages/**/*.{js,ts,json,tsx,css,less,scss,vue,html,md}\""
22
+ },
23
+ "devDependencies": {
24
+ "@rollup/plugin-commonjs": "^28.0.3",
25
+ "@topdatasec/eslint-rc": "^1.0.4",
26
+ "@typescript-eslint/eslint-plugin": "^6.7.0",
27
+ "@typescript-eslint/parser": "^6.7.0",
28
+ "@vitejs/plugin-vue": "^5.0.4",
29
+ "@vitejs/plugin-vue-jsx": "^3.0.2",
30
+ "eslint": "^8.49.0",
31
+ "eslint-config-prettier": "^9.0.0",
32
+ "eslint-plugin-prettier": "^5.0.0",
33
+ "eslint-plugin-vue": "^9.17.0",
34
+ "lint-staged": "^14.0.1",
35
+ "postcss": "^8.4.29",
36
+ "postcss-html": "^1.5.0",
37
+ "prettier": "^3.0.3",
38
+ "rollup-plugin-visualizer": "^5.9.2",
39
+ "sass": "~1.77.8",
40
+ "standard-version": "^9.5.0",
41
+ "typescript": "^5.2.2",
42
+ "unplugin-auto-import": "^0.16.6",
43
+ "unplugin-vue-components": "^0.25.2",
44
+ "unplugin-vue-setup-extend-plus": "^1.0.0",
45
+ "vite": "^4.4.9",
46
+ "vite-plugin-dts": "^4.5.3",
47
+ "vite-plugin-eslint": "^1.8.1",
48
+ "vue-tsc": "~1.8.27",
49
+ "spark-md5": "^3.0.2"
50
+ },
51
+ "peerDependencies": {
52
+ "@element-plus/icons-vue": "^2.3.1",
53
+ "element-plus": "^2.9.0",
54
+ "pinia": "^2.1.6",
55
+ "topdatasec-ui": "^1.6.1",
56
+ "vue": "^3.4.35"
57
+ },
58
+ "repository": {
59
+ "type": "git"
60
+ },
61
+ "keywords": [
62
+ "vue",
63
+ "vue3",
64
+ "probe",
65
+ "components"
66
+ ]
67
+ }