liyu-pc-base 1.0.554 → 1.0.560

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,465 +0,0 @@
1
- import { N as e, o as t } from "./init-plugin-1SOa4xzt.js";
2
- import { t as n } from "./_plugin-vue_export-helper-B3ysoDQm.js";
3
- import { t as r } from "./lodash-CC0qDxjV.js";
4
- import { getApiData as i } from "./api/api-model.js";
5
- import { Fragment as a, createBlock as o, createCommentVNode as s, createElementBlock as c, createElementVNode as l, createTextVNode as u, createVNode as d, defineComponent as f, onMounted as p, openBlock as m, reactive as h, ref as g, renderList as _, resolveComponent as v, toDisplayString as y, withCtx as b } from "vue";
6
- import { message as x } from "ant-design-vue";
7
- //#region src/components/lysync/syncDataSourceConfig.vue?vue&type=script&setup=true&lang.ts
8
- var S = r(), C = /*#__PURE__*/ n(/* @__PURE__ */ f({
9
- __name: "syncDataSourceConfig",
10
- props: {
11
- title: {},
12
- record: {}
13
- },
14
- emits: ["cancel", "ok"],
15
- setup(n, { emit: r }) {
16
- let f = n, C = r, w = g(null), T = g(!1), E = g(!0), D = g("create"), O = e().currentOrg, k = [{
17
- value: "db",
18
- label: "数据库"
19
- }, {
20
- value: "custom",
21
- label: "自定义"
22
- }], A = [{
23
- value: "mysql",
24
- label: "MySQL"
25
- }, {
26
- value: "tsql",
27
- label: "SQL Server"
28
- }], j = g([]), M = g(!1), N = async () => {
29
- M.value = !0;
30
- try {
31
- j.value = await i({ org_id: O?.id }, `${f.record.model_app}/get_collect_funcs`) || [];
32
- } catch {
33
- j.value = [];
34
- } finally {
35
- M.value = !1;
36
- }
37
- }, P = g({
38
- name: void 0,
39
- source_type: "db",
40
- db_type: "mysql",
41
- db_host: void 0,
42
- db_port: void 0,
43
- db_user: void 0,
44
- db_password: void 0,
45
- db_name: void 0,
46
- db_options_str: "",
47
- custom_func: void 0,
48
- custom_func_kwargs_str: ""
49
- }), F = h({
50
- name: [{
51
- required: !0,
52
- message: "请填写数据源名称"
53
- }],
54
- source_type: [{
55
- required: !0,
56
- message: "请选择数据源类型"
57
- }],
58
- db_type: [{
59
- required: !0,
60
- message: "请选择数据库类型"
61
- }],
62
- db_host: [{
63
- required: !0,
64
- message: "请填写数据库主机"
65
- }],
66
- db_port: [{
67
- required: !0,
68
- message: "请填写数据库端口"
69
- }],
70
- db_user: [{
71
- required: !0,
72
- message: "请填写数据库用户"
73
- }],
74
- db_name: [{
75
- required: !0,
76
- message: "请填写数据库名称"
77
- }],
78
- custom_func: [{
79
- required: !0,
80
- message: "请填写自定义采集函数名称"
81
- }]
82
- }), I = () => {
83
- P.value.source_type === "db" ? (P.value.custom_func = void 0, P.value.custom_func_kwargs_str = "") : (P.value.db_host = void 0, P.value.db_port = void 0, P.value.db_user = void 0, P.value.db_password = void 0, P.value.db_name = void 0, P.value.db_options_str = "");
84
- }, L = (e, t) => {
85
- if (e == null || String(e).trim() === "") return {};
86
- try {
87
- return JSON.parse(e);
88
- } catch (e) {
89
- throw Error(`${t} 不是合法 JSON: ${e.message}`);
90
- }
91
- }, R = (e) => e && typeof e == "object" && !Array.isArray(e) && e.data !== void 0 ? e.data : e, z = async (e) => R(await i({
92
- sync_data_source_id: e,
93
- org_id: O?.id
94
- }, `${f.record.model_app}/get_sync_data_source`)) || {}, B = () => {
95
- let e = (0, S.cloneDeep)(P.value);
96
- return e.update_field_list = [
97
- "name",
98
- "source_type",
99
- "db_type",
100
- "db_host",
101
- "db_port",
102
- "db_user",
103
- "db_password",
104
- "db_name",
105
- "db_options",
106
- "custom_func",
107
- "custom_func_kwargs"
108
- ], e.source_type === "db" ? (delete e.custom_func, delete e.custom_func_kwargs_str, e.custom_func_kwargs = {}, e.db_options = L(e.db_options_str, "数据库选项"), delete e.db_options_str, e.db_password || (delete e.db_password, D.value === "edit" && (e.update_field_list = e.update_field_list.filter((e) => e !== "db_password")))) : ([
109
- "db_type",
110
- "db_host",
111
- "db_port",
112
- "db_user",
113
- "db_password",
114
- "db_name",
115
- "db_options_str"
116
- ].forEach((t) => delete e[t]), e.db_options = {}, e.custom_func_kwargs = L(e.custom_func_kwargs_str, "自定义采集函数参数"), delete e.custom_func_kwargs_str), e;
117
- }, V = async () => {
118
- try {
119
- if (await w.value.validate(), P.value.source_type === "db") {
120
- if (!P.value.db_host) {
121
- x.error("请填写数据库主机");
122
- return;
123
- }
124
- if (P.value.db_port === void 0 || P.value.db_port === null) {
125
- x.error("请填写数据库端口");
126
- return;
127
- }
128
- if (!P.value.db_user) {
129
- x.error("请填写数据库用户");
130
- return;
131
- }
132
- if (!P.value.db_name) {
133
- x.error("请填写数据库名称");
134
- return;
135
- }
136
- if (D.value === "create" && !P.value.db_password) {
137
- x.error("请填写数据库密码");
138
- return;
139
- }
140
- if (P.value.db_options_str && P.value.db_options_str.trim() !== "") try {
141
- JSON.parse(P.value.db_options_str);
142
- } catch (e) {
143
- x.error(`数据库选项不是合法 JSON: ${e.message}`);
144
- return;
145
- }
146
- } else {
147
- if (!P.value.custom_func) {
148
- x.error("请填写自定义采集函数名称");
149
- return;
150
- }
151
- if (P.value.custom_func_kwargs_str && P.value.custom_func_kwargs_str.trim() !== "") try {
152
- JSON.parse(P.value.custom_func_kwargs_str);
153
- } catch (e) {
154
- x.error(`自定义采集函数参数不是合法 JSON: ${e.message}`);
155
- return;
156
- }
157
- }
158
- let e = B();
159
- e.sync_data_source_id = f.record.id;
160
- let n = D.value === "edit" ? `${f.record.model_app}/update_sync_data_source` : `${f.record.model_app}/create_sync_data_source`;
161
- D.value === "edit" && (e.id = f.record.id), T.value = !0, await i({
162
- ...e,
163
- org_id: O?.id
164
- }, n), x.success("操作成功"), t()?.emit("refresh"), C("ok");
165
- } catch {} finally {
166
- T.value = !1;
167
- }
168
- }, H = () => C("cancel"), U = async () => {
169
- let e = f.record?.id, t = (e == null ? f.record : await z(e)) || {}, n = t.db_options, r = t.custom_func_kwargs;
170
- P.value = {
171
- name: t.name || "",
172
- source_type: t.source_type || "db",
173
- db_type: t.db_type || "mysql",
174
- db_host: t.db_host || void 0,
175
- db_port: t.db_port ?? void 0,
176
- db_user: t.db_user || void 0,
177
- db_password: void 0,
178
- db_name: t.db_name || void 0,
179
- db_options_str: n && typeof n == "object" ? JSON.stringify(n, null, 2) : "",
180
- custom_func: t.custom_func || void 0,
181
- custom_func_kwargs_str: r && typeof r == "object" ? JSON.stringify(r, null, 2) : ""
182
- };
183
- let i = t.custom_func;
184
- i && !j.value.some((e) => e.value === i) && (j.value = [{
185
- value: i,
186
- label: i
187
- }, ...j.value]);
188
- };
189
- return p(async () => {
190
- f.record?.form_type && (D.value = f.record.form_type), await N(), D.value === "edit" && await U();
191
- }), (e, t) => {
192
- let n = v("a-divider"), r = v("a-input"), i = v("a-form-item"), f = v("a-col"), p = v("a-select-option"), h = v("a-select"), g = v("a-row"), x = v("a-input-number"), S = v("a-input-password"), C = v("a-textarea"), D = v("a-form"), O = v("a-modal");
193
- return m(), o(O, {
194
- title: e.title,
195
- width: "880px",
196
- open: E.value,
197
- bodyStyle: {
198
- maxHeight: "78vh",
199
- overflowY: "auto",
200
- padding: "0 24px"
201
- },
202
- "confirm-loading": T.value,
203
- "cancel-text": "取消",
204
- "ok-text": "确定",
205
- centered: "",
206
- "destroy-on-close": "",
207
- onCancel: H,
208
- onOk: V
209
- }, {
210
- default: b(() => [d(D, {
211
- ref_key: "formRef",
212
- ref: w,
213
- model: P.value,
214
- layout: "vertical",
215
- size: "small"
216
- }, {
217
- default: b(() => [
218
- d(n, { orientation: "left" }, {
219
- default: b(() => t[11] ||= [u("基本信息")]),
220
- _: 1
221
- }),
222
- d(g, { gutter: 16 }, {
223
- default: b(() => [
224
- d(f, { span: 12 }, {
225
- default: b(() => [d(i, {
226
- label: "数据源名称",
227
- name: "name",
228
- rules: F.name
229
- }, {
230
- default: b(() => [d(r, {
231
- value: P.value.name,
232
- "onUpdate:value": t[0] ||= (e) => P.value.name = e,
233
- placeholder: "请填写数据源名称",
234
- "allow-clear": ""
235
- }, null, 8, ["value"])]),
236
- _: 1
237
- }, 8, ["rules"])]),
238
- _: 1
239
- }),
240
- d(f, { span: 12 }, {
241
- default: b(() => [d(i, {
242
- label: "数据源类型",
243
- name: "source_type",
244
- rules: F.source_type
245
- }, {
246
- default: b(() => [d(h, {
247
- value: P.value.source_type,
248
- "onUpdate:value": t[1] ||= (e) => P.value.source_type = e,
249
- placeholder: "请选择",
250
- onChange: I
251
- }, {
252
- default: b(() => [(m(), c(a, null, _(k, (e) => d(p, {
253
- key: e.value,
254
- value: e.value
255
- }, {
256
- default: b(() => [u(y(e.label), 1)]),
257
- _: 2
258
- }, 1032, ["value"])), 64))]),
259
- _: 1
260
- }, 8, ["value"])]),
261
- _: 1
262
- }, 8, ["rules"])]),
263
- _: 1
264
- }),
265
- P.value.source_type === "db" ? (m(), o(f, {
266
- key: 0,
267
- span: 12
268
- }, {
269
- default: b(() => [d(i, {
270
- label: "数据库类型",
271
- name: "db_type",
272
- rules: F.db_type
273
- }, {
274
- default: b(() => [d(h, {
275
- value: P.value.db_type,
276
- "onUpdate:value": t[2] ||= (e) => P.value.db_type = e,
277
- placeholder: "请选择"
278
- }, {
279
- default: b(() => [(m(), c(a, null, _(A, (e) => d(p, {
280
- key: e.value,
281
- value: e.value
282
- }, {
283
- default: b(() => [u(y(e.label), 1)]),
284
- _: 2
285
- }, 1032, ["value"])), 64))]),
286
- _: 1
287
- }, 8, ["value"])]),
288
- _: 1
289
- }, 8, ["rules"])]),
290
- _: 1
291
- })) : s("", !0)
292
- ]),
293
- _: 1
294
- }),
295
- P.value.source_type === "db" ? (m(), c(a, { key: 0 }, [
296
- d(n, { orientation: "left" }, {
297
- default: b(() => t[12] ||= [u("数据库连接信息")]),
298
- _: 1
299
- }),
300
- d(g, { gutter: 16 }, {
301
- default: b(() => [
302
- d(f, { span: 12 }, {
303
- default: b(() => [d(i, {
304
- label: "数据库主机",
305
- name: "db_host",
306
- rules: F.db_host
307
- }, {
308
- default: b(() => [d(r, {
309
- value: P.value.db_host,
310
- "onUpdate:value": t[3] ||= (e) => P.value.db_host = e,
311
- placeholder: "如 127.0.0.1",
312
- "allow-clear": ""
313
- }, null, 8, ["value"])]),
314
- _: 1
315
- }, 8, ["rules"])]),
316
- _: 1
317
- }),
318
- d(f, { span: 12 }, {
319
- default: b(() => [d(i, {
320
- label: "数据库端口",
321
- name: "db_port",
322
- rules: F.db_port
323
- }, {
324
- default: b(() => [d(x, {
325
- value: P.value.db_port,
326
- "onUpdate:value": t[4] ||= (e) => P.value.db_port = e,
327
- style: { width: "100%" },
328
- min: 1,
329
- max: 65535,
330
- placeholder: "如 3306"
331
- }, null, 8, ["value"])]),
332
- _: 1
333
- }, 8, ["rules"])]),
334
- _: 1
335
- }),
336
- d(f, { span: 12 }, {
337
- default: b(() => [d(i, {
338
- label: "数据库用户",
339
- name: "db_user",
340
- rules: F.db_user
341
- }, {
342
- default: b(() => [d(r, {
343
- value: P.value.db_user,
344
- "onUpdate:value": t[5] ||= (e) => P.value.db_user = e,
345
- placeholder: "如 root",
346
- "allow-clear": ""
347
- }, null, 8, ["value"])]),
348
- _: 1
349
- }, 8, ["rules"])]),
350
- _: 1
351
- }),
352
- d(f, { span: 12 }, {
353
- default: b(() => [d(i, {
354
- label: "数据库密码",
355
- name: "db_password"
356
- }, {
357
- default: b(() => [d(S, {
358
- value: P.value.db_password,
359
- "onUpdate:value": t[6] ||= (e) => P.value.db_password = e,
360
- placeholder: "修改时留空则不修改密码",
361
- "allow-clear": "",
362
- autocomplete: "new-password"
363
- }, null, 8, ["value"])]),
364
- _: 1
365
- })]),
366
- _: 1
367
- }),
368
- d(f, { span: 12 }, {
369
- default: b(() => [d(i, {
370
- label: "数据库名称",
371
- name: "db_name",
372
- rules: F.db_name
373
- }, {
374
- default: b(() => [d(r, {
375
- value: P.value.db_name,
376
- "onUpdate:value": t[7] ||= (e) => P.value.db_name = e,
377
- placeholder: "如 my_db",
378
- "allow-clear": ""
379
- }, null, 8, ["value"])]),
380
- _: 1
381
- }, 8, ["rules"])]),
382
- _: 1
383
- })
384
- ]),
385
- _: 1
386
- }),
387
- d(i, {
388
- label: "数据库选项(JSON)",
389
- name: "db_options"
390
- }, {
391
- default: b(() => [d(C, {
392
- value: P.value.db_options_str,
393
- "onUpdate:value": t[8] ||= (e) => P.value.db_options_str = e,
394
- placeholder: "可选,JSON 对象,如 {\"charset\":\"utf8mb4\"}",
395
- "auto-size": {
396
- minRows: 2,
397
- maxRows: 6
398
- },
399
- "allow-clear": ""
400
- }, null, 8, ["value"]), t[13] ||= l("div", { class: "field-extra" }, "该字段仅在保存时解析为 JSON,留空则使用 {}。", -1)]),
401
- _: 1
402
- })
403
- ], 64)) : P.value.source_type === "custom" ? (m(), c(a, { key: 1 }, [
404
- d(n, { orientation: "left" }, {
405
- default: b(() => t[14] ||= [u("自定义采集")]),
406
- _: 1
407
- }),
408
- d(g, { gutter: 16 }, {
409
- default: b(() => [d(f, { span: 12 }, {
410
- default: b(() => [d(i, {
411
- label: "自定义采集函数名称",
412
- name: "custom_func",
413
- rules: F.custom_func
414
- }, {
415
- default: b(() => [d(h, {
416
- value: P.value.custom_func,
417
- "onUpdate:value": t[9] ||= (e) => P.value.custom_func = e,
418
- placeholder: "请选择采集函数",
419
- options: j.value,
420
- "option-filter-prop": "label",
421
- "show-search": "",
422
- "allow-clear": "",
423
- loading: M.value
424
- }, null, 8, [
425
- "value",
426
- "options",
427
- "loading"
428
- ])]),
429
- _: 1
430
- }, 8, ["rules"])]),
431
- _: 1
432
- })]),
433
- _: 1
434
- }),
435
- d(i, {
436
- label: "自定义采集函数参数(JSON)",
437
- name: "custom_func_kwargs"
438
- }, {
439
- default: b(() => [d(C, {
440
- value: P.value.custom_func_kwargs_str,
441
- "onUpdate:value": t[10] ||= (e) => P.value.custom_func_kwargs_str = e,
442
- placeholder: "可选,JSON 对象,如 {\"token\":\"xxx\"}",
443
- "auto-size": {
444
- minRows: 2,
445
- maxRows: 6
446
- },
447
- "allow-clear": ""
448
- }, null, 8, ["value"]), t[15] ||= l("div", { class: "field-extra" }, "该字段仅在保存时解析为 JSON,留空则使用 {}。", -1)]),
449
- _: 1
450
- })
451
- ], 64)) : s("", !0)
452
- ]),
453
- _: 1
454
- }, 8, ["model"])]),
455
- _: 1
456
- }, 8, [
457
- "title",
458
- "open",
459
- "confirm-loading"
460
- ]);
461
- };
462
- }
463
- }), [["__scopeId", "data-v-571da14c"]]);
464
- //#endregion
465
- export { C as default };
@@ -1 +0,0 @@
1
- {"version":3,"file":"syncDataSourceConfig-AlcjBERC.js","names":[],"sources":["../src/components/lysync/syncDataSourceConfig.vue","../src/components/lysync/syncDataSourceConfig.vue"],"sourcesContent":["<template>\n <a-modal\n :title=\"title\"\n width=\"880px\"\n :open=\"open\"\n :bodyStyle=\"{ maxHeight: '78vh', overflowY: 'auto', padding: '0 24px' }\"\n :confirm-loading=\"loading\"\n cancel-text=\"取消\"\n ok-text=\"确定\"\n centered\n destroy-on-close\n @cancel=\"handleCancel\"\n @ok=\"handleOk\"\n >\n <a-form\n ref=\"formRef\"\n :model=\"model\"\n layout=\"vertical\"\n size=\"small\"\n >\n <a-divider orientation=\"left\">基本信息</a-divider>\n <a-row :gutter=\"16\">\n <a-col :span=\"12\">\n <a-form-item\n label=\"数据源名称\"\n name=\"name\"\n :rules=\"rules.name\"\n >\n <a-input\n v-model:value=\"model.name\"\n placeholder=\"请填写数据源名称\"\n allow-clear\n />\n </a-form-item>\n </a-col>\n <a-col :span=\"12\">\n <a-form-item\n label=\"数据源类型\"\n name=\"source_type\"\n :rules=\"rules.source_type\"\n >\n <a-select\n v-model:value=\"model.source_type\"\n placeholder=\"请选择\"\n @change=\"onSourceTypeChange\"\n >\n <a-select-option\n v-for=\"opt in sourceTypeOptions\"\n :key=\"opt.value\"\n :value=\"opt.value\"\n >\n {{ opt.label }}\n </a-select-option>\n </a-select>\n </a-form-item>\n </a-col>\n <a-col\n v-if=\"model.source_type === 'db'\"\n :span=\"12\"\n >\n <a-form-item\n label=\"数据库类型\"\n name=\"db_type\"\n :rules=\"rules.db_type\"\n >\n <a-select\n v-model:value=\"model.db_type\"\n placeholder=\"请选择\"\n >\n <a-select-option\n v-for=\"opt in dbTypeOptions\"\n :key=\"opt.value\"\n :value=\"opt.value\"\n >\n {{ opt.label }}\n </a-select-option>\n </a-select>\n </a-form-item>\n </a-col>\n </a-row>\n\n <!-- 数据库类型:连接信息 -->\n <template v-if=\"model.source_type === 'db'\">\n <a-divider orientation=\"left\">数据库连接信息</a-divider>\n <a-row :gutter=\"16\">\n <a-col :span=\"12\">\n <a-form-item\n label=\"数据库主机\"\n name=\"db_host\"\n :rules=\"rules.db_host\"\n >\n <a-input\n v-model:value=\"model.db_host\"\n placeholder=\"如 127.0.0.1\"\n allow-clear\n />\n </a-form-item>\n </a-col>\n <a-col :span=\"12\">\n <a-form-item\n label=\"数据库端口\"\n name=\"db_port\"\n :rules=\"rules.db_port\"\n >\n <a-input-number\n v-model:value=\"model.db_port\"\n style=\"width: 100%\"\n :min=\"1\"\n :max=\"65535\"\n placeholder=\"如 3306\"\n />\n </a-form-item>\n </a-col>\n <a-col :span=\"12\">\n <a-form-item\n label=\"数据库用户\"\n name=\"db_user\"\n :rules=\"rules.db_user\"\n >\n <a-input\n v-model:value=\"model.db_user\"\n placeholder=\"如 root\"\n allow-clear\n />\n </a-form-item>\n </a-col>\n <a-col :span=\"12\">\n <a-form-item\n label=\"数据库密码\"\n name=\"db_password\"\n >\n <a-input-password\n v-model:value=\"model.db_password\"\n placeholder=\"修改时留空则不修改密码\"\n allow-clear\n autocomplete=\"new-password\"\n />\n </a-form-item>\n </a-col>\n <a-col :span=\"12\">\n <a-form-item\n label=\"数据库名称\"\n name=\"db_name\"\n :rules=\"rules.db_name\"\n >\n <a-input\n v-model:value=\"model.db_name\"\n placeholder=\"如 my_db\"\n allow-clear\n />\n </a-form-item>\n </a-col>\n </a-row>\n <a-form-item\n label=\"数据库选项(JSON)\"\n name=\"db_options\"\n >\n <a-textarea\n v-model:value=\"model.db_options_str\"\n placeholder='可选,JSON 对象,如 {\"charset\":\"utf8mb4\"}'\n :auto-size=\"{ minRows: 2, maxRows: 6 }\"\n allow-clear\n />\n <div class=\"field-extra\">该字段仅在保存时解析为 JSON,留空则使用 {}。</div>\n </a-form-item>\n </template>\n\n <!-- 自定义类型:采集函数 -->\n <template v-else-if=\"model.source_type === 'custom'\">\n <a-divider orientation=\"left\">自定义采集</a-divider>\n <a-row :gutter=\"16\">\n <a-col :span=\"12\">\n <a-form-item\n label=\"自定义采集函数名称\"\n name=\"custom_func\"\n :rules=\"rules.custom_func\"\n >\n <a-select\n v-model:value=\"model.custom_func\"\n placeholder=\"请选择采集函数\"\n :options=\"customFuncOptions\"\n option-filter-prop=\"label\"\n show-search\n allow-clear\n :loading=\"funcOptionsLoading\"\n />\n </a-form-item>\n </a-col>\n </a-row>\n <a-form-item\n label=\"自定义采集函数参数(JSON)\"\n name=\"custom_func_kwargs\"\n >\n <a-textarea\n v-model:value=\"model.custom_func_kwargs_str\"\n placeholder='可选,JSON 对象,如 {\"token\":\"xxx\"}'\n :auto-size=\"{ minRows: 2, maxRows: 6 }\"\n allow-clear\n />\n <div class=\"field-extra\">该字段仅在保存时解析为 JSON,留空则使用 {}。</div>\n </a-form-item>\n </template>\n </a-form>\n </a-modal>\n</template>\n\n<script setup lang=\"ts\">\nimport { cloneDeep } from 'lodash';\nimport { message } from 'ant-design-vue';\nimport { onMounted, reactive, ref } from 'vue';\nimport { event_obj } from 'liyu-pc-base/init-plugin';\nimport { getApiData } from 'liyu-pc-base/api/api-model';\nimport { useUserStore } from 'liyu-pc-base/init-plugin';\ninterface Props {\n title: string;\n record: any;\n}\nconst props = defineProps<Props>();\nconst emit = defineEmits(['cancel', 'ok']);\n\nconst formRef = ref<any>(null);\nconst loading = ref(false);\nconst open = ref(true);\nconst form_type = ref('create');\nconst userStore = useUserStore();\nconst current_org = userStore.currentOrg;\n\nconst sourceTypeOptions = [\n { value: 'db', label: '数据库' },\n { value: 'custom', label: '自定义' },\n];\nconst dbTypeOptions = [\n { value: 'mysql', label: 'MySQL' },\n { value: 'tsql', label: 'SQL Server' },\n];\n\n/* 自定义采集函数下拉选项(来自后端 get_collect_funcs) */\nconst customFuncOptions = ref<any[]>([]);\nconst funcOptionsLoading = ref(false);\nconst loadCustomFuncOptions = async () => {\n funcOptionsLoading.value = true;\n try {\n const res = await getApiData(\n { org_id: current_org?.id },\n `${props.record.model_app}/get_collect_funcs`,\n );\n customFuncOptions.value = res || [];\n } catch (e) {\n customFuncOptions.value = [];\n } finally {\n funcOptionsLoading.value = false;\n }\n};\n\nconst model = ref<any>({\n name: undefined,\n source_type: 'db',\n db_type: 'mysql',\n db_host: undefined,\n db_port: undefined,\n db_user: undefined,\n db_password: undefined,\n db_name: undefined,\n db_options_str: '',\n custom_func: undefined,\n custom_func_kwargs_str: '',\n});\n\nconst rules = reactive<any>({\n name: [{ required: true, message: '请填写数据源名称' }],\n source_type: [{ required: true, message: '请选择数据源类型' }],\n db_type: [{ required: true, message: '请选择数据库类型' }],\n db_host: [{ required: true, message: '请填写数据库主机' }],\n db_port: [{ required: true, message: '请填写数据库端口' }],\n db_user: [{ required: true, message: '请填写数据库用户' }],\n db_name: [{ required: true, message: '请填写数据库名称' }],\n custom_func: [{ required: true, message: '请填写自定义采集函数名称' }],\n});\n\n/* 切换数据源类型时,清空与另一类型无关的不必要校验残留 */\nconst onSourceTypeChange = () => {\n if (model.value.source_type === 'db') {\n model.value.custom_func = undefined;\n model.value.custom_func_kwargs_str = '';\n } else {\n model.value.db_host = undefined;\n model.value.db_port = undefined;\n model.value.db_user = undefined;\n model.value.db_password = undefined;\n model.value.db_name = undefined;\n model.value.db_options_str = '';\n }\n};\n\n/* 将 JSON 字符串解析为对象;空字符串返回 {};解析失败抛出错误 */\nconst parseJsonField = (str: string, fieldName: string): any => {\n if (str === undefined || str === null || String(str).trim() === '') return {};\n try {\n return JSON.parse(str);\n } catch (e) {\n throw new Error(`${fieldName} 不是合法 JSON: ${(e as Error).message}`);\n }\n};\n\n/* 兼容 getApiData 可能的返回结构(直接对象 或 {data:{...}}) */\nconst extractData = (res: any) => {\n if (res && typeof res === 'object' && !Array.isArray(res) && res.data !== undefined)\n return res.data;\n return res;\n};\n\n/* 编辑:调用公共项目提供的详情接口(<app_flag>/get_<model_name>,即 get_basemodel)\n 获取完整的 SyncDataSource 记录。不依赖列表行数据 props.record,因为它可能缺失\n 部分字段。get_basemodel 返回单条 dict(非列表),按 id 查询(参数名\n 为 <model_name>_id,即 sync_data_source_id)。 */\nconst loadDetail = async (id: any) => {\n const res = await getApiData(\n { sync_data_source_id: id, org_id: current_org?.id },\n `${props.record.model_app}/get_sync_data_source`,\n );\n return extractData(res) || {};\n};\n\n/* 构建提交数据:始终 cloneDeep(model.value),兜底默认值 */\nconst buildPayload = () => {\n const payload: any = cloneDeep(model.value);\n payload.update_field_list = [\n 'name',\n 'source_type',\n 'db_type',\n 'db_host',\n 'db_port',\n 'db_user',\n 'db_password',\n 'db_name',\n 'db_options',\n 'custom_func',\n 'custom_func_kwargs',\n ];\n const isDb = payload.source_type === 'db';\n\n // 仅保留当前类型相关字段,避免把另一类型的空值带给后端\n if (isDb) {\n delete payload.custom_func;\n delete payload.custom_func_kwargs_str;\n payload.custom_func_kwargs = {};\n payload.db_options = parseJsonField(payload.db_options_str, '数据库选项');\n delete payload.db_options_str;\n // 编辑时密码留空则不修改:删除字段值,并从 update_field_list 中剔除,避免后端更新\n if (!payload.db_password) {\n delete payload.db_password;\n if (form_type.value === 'edit') {\n payload.update_field_list = payload.update_field_list.filter(\n (k: string) => k !== 'db_password',\n );\n }\n }\n } else {\n [\n 'db_type',\n 'db_host',\n 'db_port',\n 'db_user',\n 'db_password',\n 'db_name',\n 'db_options_str',\n ].forEach(k => delete payload[k]);\n payload.db_options = {};\n payload.custom_func_kwargs = parseJsonField(\n payload.custom_func_kwargs_str,\n '自定义采集函数参数',\n );\n delete payload.custom_func_kwargs_str;\n }\n\n return payload;\n};\n\n/* 提交:URL 遵循 /{app_flag}/create_{model} 与 /{app_flag}/update_{model} */\nconst handleOk = async () => {\n try {\n await formRef.value.validate();\n const isDb = model.value.source_type === 'db';\n if (isDb) {\n if (!model.value.db_host) {\n message.error('请填写数据库主机');\n return;\n }\n if (model.value.db_port === undefined || model.value.db_port === null) {\n message.error('请填写数据库端口');\n return;\n }\n if (!model.value.db_user) {\n message.error('请填写数据库用户');\n return;\n }\n if (!model.value.db_name) {\n message.error('请填写数据库名称');\n return;\n }\n if (form_type.value === 'create' && !model.value.db_password) {\n message.error('请填写数据库密码');\n return;\n }\n if (model.value.db_options_str && model.value.db_options_str.trim() !== '') {\n try {\n JSON.parse(model.value.db_options_str);\n } catch (e: any) {\n message.error(`数据库选项不是合法 JSON: ${e.message}`);\n return;\n }\n }\n } else {\n if (!model.value.custom_func) {\n message.error('请填写自定义采集函数名称');\n return;\n }\n if (model.value.custom_func_kwargs_str && model.value.custom_func_kwargs_str.trim() !== '') {\n try {\n JSON.parse(model.value.custom_func_kwargs_str);\n } catch (e: any) {\n message.error(`自定义采集函数参数不是合法 JSON: ${e.message}`);\n return;\n }\n }\n }\n\n const payload = buildPayload();\n payload.sync_data_source_id = props.record.id;\n const url =\n form_type.value === 'edit'\n ? `${props.record.model_app}/update_sync_data_source`\n : `${props.record.model_app}/create_sync_data_source`;\n if (form_type.value === 'edit') payload.id = props.record.id;\n loading.value = true;\n await getApiData({ ...payload, org_id: current_org?.id }, url);\n message.success('操作成功');\n event_obj()?.emit('refresh');\n emit('ok');\n } catch (error) {\n // 校验失败或接口异常:保持弹窗打开\n } finally {\n loading.value = false;\n }\n};\nconst handleCancel = () => emit('cancel');\n\n/* 初始化编辑:先调详情接口拿完整记录,再填充;并把 JSON 字段格式化为字符串 */\nconst initForEdit = async () => {\n const id = props.record?.id;\n // 编辑时依赖详情接口而非列表行数据(列表行可能缺失字段)\n const record = (id != null ? await loadDetail(id) : props.record) || {};\n const rawDbOptions = record.db_options;\n const rawCustomKwargs = record.custom_func_kwargs;\n model.value = {\n name: record.name || '',\n source_type: record.source_type || 'db',\n db_type: record.db_type || 'mysql',\n db_host: record.db_host || undefined,\n db_port: record.db_port ?? undefined,\n db_user: record.db_user || undefined,\n db_password: undefined, // 密码不回显,留空表示不修改\n db_name: record.db_name || undefined,\n db_options_str:\n rawDbOptions && typeof rawDbOptions === 'object' ? JSON.stringify(rawDbOptions, null, 2) : '',\n custom_func: record.custom_func || undefined,\n custom_func_kwargs_str:\n rawCustomKwargs && typeof rawCustomKwargs === 'object'\n ? JSON.stringify(rawCustomKwargs, null, 2)\n : '',\n };\n // 编辑时若已保存的采集函数不在当前选项列表中,补充进下拉避免丢失显示\n const rawCustomFunc = record.custom_func;\n if (rawCustomFunc && !customFuncOptions.value.some(o => o.value === rawCustomFunc)) {\n customFuncOptions.value = [\n { value: rawCustomFunc, label: rawCustomFunc },\n ...customFuncOptions.value,\n ];\n }\n};\n\nonMounted(async () => {\n if (props.record?.form_type) form_type.value = props.record.form_type;\n await loadCustomFuncOptions();\n if (form_type.value === 'edit') await initForEdit();\n});\n</script>\n\n<style scoped lang=\"less\">\n.field-extra {\n color: #999;\n font-size: 12px;\n line-height: 1.4;\n margin-top: 2px;\n}\n</style>\n","<template>\n <a-modal\n :title=\"title\"\n width=\"880px\"\n :open=\"open\"\n :bodyStyle=\"{ maxHeight: '78vh', overflowY: 'auto', padding: '0 24px' }\"\n :confirm-loading=\"loading\"\n cancel-text=\"取消\"\n ok-text=\"确定\"\n centered\n destroy-on-close\n @cancel=\"handleCancel\"\n @ok=\"handleOk\"\n >\n <a-form\n ref=\"formRef\"\n :model=\"model\"\n layout=\"vertical\"\n size=\"small\"\n >\n <a-divider orientation=\"left\">基本信息</a-divider>\n <a-row :gutter=\"16\">\n <a-col :span=\"12\">\n <a-form-item\n label=\"数据源名称\"\n name=\"name\"\n :rules=\"rules.name\"\n >\n <a-input\n v-model:value=\"model.name\"\n placeholder=\"请填写数据源名称\"\n allow-clear\n />\n </a-form-item>\n </a-col>\n <a-col :span=\"12\">\n <a-form-item\n label=\"数据源类型\"\n name=\"source_type\"\n :rules=\"rules.source_type\"\n >\n <a-select\n v-model:value=\"model.source_type\"\n placeholder=\"请选择\"\n @change=\"onSourceTypeChange\"\n >\n <a-select-option\n v-for=\"opt in sourceTypeOptions\"\n :key=\"opt.value\"\n :value=\"opt.value\"\n >\n {{ opt.label }}\n </a-select-option>\n </a-select>\n </a-form-item>\n </a-col>\n <a-col\n v-if=\"model.source_type === 'db'\"\n :span=\"12\"\n >\n <a-form-item\n label=\"数据库类型\"\n name=\"db_type\"\n :rules=\"rules.db_type\"\n >\n <a-select\n v-model:value=\"model.db_type\"\n placeholder=\"请选择\"\n >\n <a-select-option\n v-for=\"opt in dbTypeOptions\"\n :key=\"opt.value\"\n :value=\"opt.value\"\n >\n {{ opt.label }}\n </a-select-option>\n </a-select>\n </a-form-item>\n </a-col>\n </a-row>\n\n <!-- 数据库类型:连接信息 -->\n <template v-if=\"model.source_type === 'db'\">\n <a-divider orientation=\"left\">数据库连接信息</a-divider>\n <a-row :gutter=\"16\">\n <a-col :span=\"12\">\n <a-form-item\n label=\"数据库主机\"\n name=\"db_host\"\n :rules=\"rules.db_host\"\n >\n <a-input\n v-model:value=\"model.db_host\"\n placeholder=\"如 127.0.0.1\"\n allow-clear\n />\n </a-form-item>\n </a-col>\n <a-col :span=\"12\">\n <a-form-item\n label=\"数据库端口\"\n name=\"db_port\"\n :rules=\"rules.db_port\"\n >\n <a-input-number\n v-model:value=\"model.db_port\"\n style=\"width: 100%\"\n :min=\"1\"\n :max=\"65535\"\n placeholder=\"如 3306\"\n />\n </a-form-item>\n </a-col>\n <a-col :span=\"12\">\n <a-form-item\n label=\"数据库用户\"\n name=\"db_user\"\n :rules=\"rules.db_user\"\n >\n <a-input\n v-model:value=\"model.db_user\"\n placeholder=\"如 root\"\n allow-clear\n />\n </a-form-item>\n </a-col>\n <a-col :span=\"12\">\n <a-form-item\n label=\"数据库密码\"\n name=\"db_password\"\n >\n <a-input-password\n v-model:value=\"model.db_password\"\n placeholder=\"修改时留空则不修改密码\"\n allow-clear\n autocomplete=\"new-password\"\n />\n </a-form-item>\n </a-col>\n <a-col :span=\"12\">\n <a-form-item\n label=\"数据库名称\"\n name=\"db_name\"\n :rules=\"rules.db_name\"\n >\n <a-input\n v-model:value=\"model.db_name\"\n placeholder=\"如 my_db\"\n allow-clear\n />\n </a-form-item>\n </a-col>\n </a-row>\n <a-form-item\n label=\"数据库选项(JSON)\"\n name=\"db_options\"\n >\n <a-textarea\n v-model:value=\"model.db_options_str\"\n placeholder='可选,JSON 对象,如 {\"charset\":\"utf8mb4\"}'\n :auto-size=\"{ minRows: 2, maxRows: 6 }\"\n allow-clear\n />\n <div class=\"field-extra\">该字段仅在保存时解析为 JSON,留空则使用 {}。</div>\n </a-form-item>\n </template>\n\n <!-- 自定义类型:采集函数 -->\n <template v-else-if=\"model.source_type === 'custom'\">\n <a-divider orientation=\"left\">自定义采集</a-divider>\n <a-row :gutter=\"16\">\n <a-col :span=\"12\">\n <a-form-item\n label=\"自定义采集函数名称\"\n name=\"custom_func\"\n :rules=\"rules.custom_func\"\n >\n <a-select\n v-model:value=\"model.custom_func\"\n placeholder=\"请选择采集函数\"\n :options=\"customFuncOptions\"\n option-filter-prop=\"label\"\n show-search\n allow-clear\n :loading=\"funcOptionsLoading\"\n />\n </a-form-item>\n </a-col>\n </a-row>\n <a-form-item\n label=\"自定义采集函数参数(JSON)\"\n name=\"custom_func_kwargs\"\n >\n <a-textarea\n v-model:value=\"model.custom_func_kwargs_str\"\n placeholder='可选,JSON 对象,如 {\"token\":\"xxx\"}'\n :auto-size=\"{ minRows: 2, maxRows: 6 }\"\n allow-clear\n />\n <div class=\"field-extra\">该字段仅在保存时解析为 JSON,留空则使用 {}。</div>\n </a-form-item>\n </template>\n </a-form>\n </a-modal>\n</template>\n\n<script setup lang=\"ts\">\nimport { cloneDeep } from 'lodash';\nimport { message } from 'ant-design-vue';\nimport { onMounted, reactive, ref } from 'vue';\nimport { event_obj } from 'liyu-pc-base/init-plugin';\nimport { getApiData } from 'liyu-pc-base/api/api-model';\nimport { useUserStore } from 'liyu-pc-base/init-plugin';\ninterface Props {\n title: string;\n record: any;\n}\nconst props = defineProps<Props>();\nconst emit = defineEmits(['cancel', 'ok']);\n\nconst formRef = ref<any>(null);\nconst loading = ref(false);\nconst open = ref(true);\nconst form_type = ref('create');\nconst userStore = useUserStore();\nconst current_org = userStore.currentOrg;\n\nconst sourceTypeOptions = [\n { value: 'db', label: '数据库' },\n { value: 'custom', label: '自定义' },\n];\nconst dbTypeOptions = [\n { value: 'mysql', label: 'MySQL' },\n { value: 'tsql', label: 'SQL Server' },\n];\n\n/* 自定义采集函数下拉选项(来自后端 get_collect_funcs) */\nconst customFuncOptions = ref<any[]>([]);\nconst funcOptionsLoading = ref(false);\nconst loadCustomFuncOptions = async () => {\n funcOptionsLoading.value = true;\n try {\n const res = await getApiData(\n { org_id: current_org?.id },\n `${props.record.model_app}/get_collect_funcs`,\n );\n customFuncOptions.value = res || [];\n } catch (e) {\n customFuncOptions.value = [];\n } finally {\n funcOptionsLoading.value = false;\n }\n};\n\nconst model = ref<any>({\n name: undefined,\n source_type: 'db',\n db_type: 'mysql',\n db_host: undefined,\n db_port: undefined,\n db_user: undefined,\n db_password: undefined,\n db_name: undefined,\n db_options_str: '',\n custom_func: undefined,\n custom_func_kwargs_str: '',\n});\n\nconst rules = reactive<any>({\n name: [{ required: true, message: '请填写数据源名称' }],\n source_type: [{ required: true, message: '请选择数据源类型' }],\n db_type: [{ required: true, message: '请选择数据库类型' }],\n db_host: [{ required: true, message: '请填写数据库主机' }],\n db_port: [{ required: true, message: '请填写数据库端口' }],\n db_user: [{ required: true, message: '请填写数据库用户' }],\n db_name: [{ required: true, message: '请填写数据库名称' }],\n custom_func: [{ required: true, message: '请填写自定义采集函数名称' }],\n});\n\n/* 切换数据源类型时,清空与另一类型无关的不必要校验残留 */\nconst onSourceTypeChange = () => {\n if (model.value.source_type === 'db') {\n model.value.custom_func = undefined;\n model.value.custom_func_kwargs_str = '';\n } else {\n model.value.db_host = undefined;\n model.value.db_port = undefined;\n model.value.db_user = undefined;\n model.value.db_password = undefined;\n model.value.db_name = undefined;\n model.value.db_options_str = '';\n }\n};\n\n/* 将 JSON 字符串解析为对象;空字符串返回 {};解析失败抛出错误 */\nconst parseJsonField = (str: string, fieldName: string): any => {\n if (str === undefined || str === null || String(str).trim() === '') return {};\n try {\n return JSON.parse(str);\n } catch (e) {\n throw new Error(`${fieldName} 不是合法 JSON: ${(e as Error).message}`);\n }\n};\n\n/* 兼容 getApiData 可能的返回结构(直接对象 或 {data:{...}}) */\nconst extractData = (res: any) => {\n if (res && typeof res === 'object' && !Array.isArray(res) && res.data !== undefined)\n return res.data;\n return res;\n};\n\n/* 编辑:调用公共项目提供的详情接口(<app_flag>/get_<model_name>,即 get_basemodel)\n 获取完整的 SyncDataSource 记录。不依赖列表行数据 props.record,因为它可能缺失\n 部分字段。get_basemodel 返回单条 dict(非列表),按 id 查询(参数名\n 为 <model_name>_id,即 sync_data_source_id)。 */\nconst loadDetail = async (id: any) => {\n const res = await getApiData(\n { sync_data_source_id: id, org_id: current_org?.id },\n `${props.record.model_app}/get_sync_data_source`,\n );\n return extractData(res) || {};\n};\n\n/* 构建提交数据:始终 cloneDeep(model.value),兜底默认值 */\nconst buildPayload = () => {\n const payload: any = cloneDeep(model.value);\n payload.update_field_list = [\n 'name',\n 'source_type',\n 'db_type',\n 'db_host',\n 'db_port',\n 'db_user',\n 'db_password',\n 'db_name',\n 'db_options',\n 'custom_func',\n 'custom_func_kwargs',\n ];\n const isDb = payload.source_type === 'db';\n\n // 仅保留当前类型相关字段,避免把另一类型的空值带给后端\n if (isDb) {\n delete payload.custom_func;\n delete payload.custom_func_kwargs_str;\n payload.custom_func_kwargs = {};\n payload.db_options = parseJsonField(payload.db_options_str, '数据库选项');\n delete payload.db_options_str;\n // 编辑时密码留空则不修改:删除字段值,并从 update_field_list 中剔除,避免后端更新\n if (!payload.db_password) {\n delete payload.db_password;\n if (form_type.value === 'edit') {\n payload.update_field_list = payload.update_field_list.filter(\n (k: string) => k !== 'db_password',\n );\n }\n }\n } else {\n [\n 'db_type',\n 'db_host',\n 'db_port',\n 'db_user',\n 'db_password',\n 'db_name',\n 'db_options_str',\n ].forEach(k => delete payload[k]);\n payload.db_options = {};\n payload.custom_func_kwargs = parseJsonField(\n payload.custom_func_kwargs_str,\n '自定义采集函数参数',\n );\n delete payload.custom_func_kwargs_str;\n }\n\n return payload;\n};\n\n/* 提交:URL 遵循 /{app_flag}/create_{model} 与 /{app_flag}/update_{model} */\nconst handleOk = async () => {\n try {\n await formRef.value.validate();\n const isDb = model.value.source_type === 'db';\n if (isDb) {\n if (!model.value.db_host) {\n message.error('请填写数据库主机');\n return;\n }\n if (model.value.db_port === undefined || model.value.db_port === null) {\n message.error('请填写数据库端口');\n return;\n }\n if (!model.value.db_user) {\n message.error('请填写数据库用户');\n return;\n }\n if (!model.value.db_name) {\n message.error('请填写数据库名称');\n return;\n }\n if (form_type.value === 'create' && !model.value.db_password) {\n message.error('请填写数据库密码');\n return;\n }\n if (model.value.db_options_str && model.value.db_options_str.trim() !== '') {\n try {\n JSON.parse(model.value.db_options_str);\n } catch (e: any) {\n message.error(`数据库选项不是合法 JSON: ${e.message}`);\n return;\n }\n }\n } else {\n if (!model.value.custom_func) {\n message.error('请填写自定义采集函数名称');\n return;\n }\n if (model.value.custom_func_kwargs_str && model.value.custom_func_kwargs_str.trim() !== '') {\n try {\n JSON.parse(model.value.custom_func_kwargs_str);\n } catch (e: any) {\n message.error(`自定义采集函数参数不是合法 JSON: ${e.message}`);\n return;\n }\n }\n }\n\n const payload = buildPayload();\n payload.sync_data_source_id = props.record.id;\n const url =\n form_type.value === 'edit'\n ? `${props.record.model_app}/update_sync_data_source`\n : `${props.record.model_app}/create_sync_data_source`;\n if (form_type.value === 'edit') payload.id = props.record.id;\n loading.value = true;\n await getApiData({ ...payload, org_id: current_org?.id }, url);\n message.success('操作成功');\n event_obj()?.emit('refresh');\n emit('ok');\n } catch (error) {\n // 校验失败或接口异常:保持弹窗打开\n } finally {\n loading.value = false;\n }\n};\nconst handleCancel = () => emit('cancel');\n\n/* 初始化编辑:先调详情接口拿完整记录,再填充;并把 JSON 字段格式化为字符串 */\nconst initForEdit = async () => {\n const id = props.record?.id;\n // 编辑时依赖详情接口而非列表行数据(列表行可能缺失字段)\n const record = (id != null ? await loadDetail(id) : props.record) || {};\n const rawDbOptions = record.db_options;\n const rawCustomKwargs = record.custom_func_kwargs;\n model.value = {\n name: record.name || '',\n source_type: record.source_type || 'db',\n db_type: record.db_type || 'mysql',\n db_host: record.db_host || undefined,\n db_port: record.db_port ?? undefined,\n db_user: record.db_user || undefined,\n db_password: undefined, // 密码不回显,留空表示不修改\n db_name: record.db_name || undefined,\n db_options_str:\n rawDbOptions && typeof rawDbOptions === 'object' ? JSON.stringify(rawDbOptions, null, 2) : '',\n custom_func: record.custom_func || undefined,\n custom_func_kwargs_str:\n rawCustomKwargs && typeof rawCustomKwargs === 'object'\n ? JSON.stringify(rawCustomKwargs, null, 2)\n : '',\n };\n // 编辑时若已保存的采集函数不在当前选项列表中,补充进下拉避免丢失显示\n const rawCustomFunc = record.custom_func;\n if (rawCustomFunc && !customFuncOptions.value.some(o => o.value === rawCustomFunc)) {\n customFuncOptions.value = [\n { value: rawCustomFunc, label: rawCustomFunc },\n ...customFuncOptions.value,\n ];\n }\n};\n\nonMounted(async () => {\n if (props.record?.form_type) form_type.value = props.record.form_type;\n await loadCustomFuncOptions();\n if (form_type.value === 'edit') await initForEdit();\n});\n</script>\n\n<style scoped lang=\"less\">\n.field-extra {\n color: #999;\n font-size: 12px;\n line-height: 1.4;\n margin-top: 2px;\n}\n</style>\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"syncExportRawData-dtLd_SL2.js","names":[],"sources":["../src/components/lysync/syncConditionGroup.vue","../src/components/lysync/syncConditionGroup.vue","../src/components/lysync/syncExportRawData.vue","../src/components/lysync/syncExportRawData.vue"],"sourcesContent":["<template>\n <div class=\"qb-group\">\n <div class=\"qb-group-head\">\n <a-select\n style=\"width: 110px\"\n :value=\"group.type || 'and'\"\n :options=\"[\n { label: '并且', value: 'and' },\n { label: '或者', value: 'or' },\n ]\"\n @update:value=\"(v:string) => (group.type = v)\"\n />\n <a-button\n size=\"small\"\n @click=\"addRule\"\n >\n 添加条件\n </a-button>\n <a-button\n size=\"small\"\n style=\"margin-left: 8px\"\n @click=\"addGroup\"\n >\n 添加分组\n </a-button>\n </div>\n\n <div class=\"qb-group-body\">\n <template\n v-for=\"(child, idx) in group.conditions\"\n :key=\"idx\"\n >\n <!-- 分组 -->\n <div\n v-if=\"child && typeof child === 'object' && 'type' in child\"\n class=\"qb-subgroup\"\n >\n <ConditionGroup\n :group=\"child\"\n :columns=\"columns\"\n />\n <a-button\n danger\n size=\"small\"\n style=\"margin: 4px 0\"\n @click=\"removeAt(idx)\"\n >\n 删除分组\n </a-button>\n </div>\n <!-- 规则 -->\n <div\n v-else\n class=\"qb-rule\"\n >\n <a-select\n :value=\"child.field\"\n style=\"min-width: 200px\"\n placeholder=\"选择字段\"\n :options=\"fieldOptions\"\n @update:value=\"(v:string)=> (child.field = v)\"\n />\n <a-select\n :value=\"child.op\"\n style=\"width: 200px\"\n :options=\"operators\"\n @update:value=\"(v:string)=> (child.op = v)\"\n />\n\n <!-- 值输入区域 -->\n <template v-if=\"child.op === 'in'\">\n <a-select\n mode=\"tags\"\n style=\"min-width: 220px\"\n :value=\"Array.isArray(child.value) ? child.value : []\"\n placeholder=\"输入多个值后回车\"\n @update:value=\"(v:any)=> (child.value = v)\"\n />\n </template>\n <template v-else-if=\"child.op === 'between'\">\n <a-space :size=\"4\">\n <a-input\n style=\"width: 120px\"\n :value=\"Array.isArray(child.value) ? child.value?.[0] : undefined\"\n placeholder=\"起始值\"\n @update:value=\"(v:any)=> updateBetween(child, 0, v)\"\n />\n <span style=\"padding: 0 4px; color: #999\">~</span>\n <a-input\n style=\"width: 120px\"\n :value=\"Array.isArray(child.value) ? child.value?.[1] : undefined\"\n placeholder=\"结束值\"\n @update:value=\"(v:any)=> updateBetween(child, 1, v)\"\n />\n </a-space>\n </template>\n <template v-else-if=\"child.op === 'is'\">\n <a-select\n style=\"min-width: 160px\"\n :value=\"child.value\"\n placeholder=\"选择 NULL/TRUE/FALSE\"\n @update:value=\"(v:any)=> (child.value = v)\"\n >\n <a-select-option :value=\"null\">NULL</a-select-option>\n <a-select-option :value=\"true\">TRUE</a-select-option>\n <a-select-option :value=\"false\">FALSE</a-select-option>\n </a-select>\n </template>\n <template v-else>\n <a-input\n style=\"min-width: 220px\"\n :value=\"child.value\"\n placeholder=\"输入值\"\n @update:value=\"(v:any)=> (child.value = v)\"\n />\n </template>\n\n <a-button\n danger\n size=\"small\"\n @click=\"removeAt(idx)\"\n >\n 删除\n </a-button>\n </div>\n </template>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, computed } from 'vue';\n\nexport default defineComponent({\n name: 'ConditionGroup',\n props: {\n group: { type: Object as any, required: true },\n columns: { type: Array as any, required: true },\n isRoot: { type: Boolean, default: false },\n },\n setup(props) {\n const operators = [\n { label: '等于', value: '=' },\n { label: '不等于', value: '!=' },\n { label: '大于', value: '>' },\n { label: '大于或等于', value: '>=' },\n { label: '小于', value: '<' },\n { label: '小于或等于', value: '<=' },\n { label: '包含', value: 'in' },\n { label: '模糊匹配', value: 'like' },\n { label: '介于', value: 'between' },\n ];\n\n const fieldOptions = computed(() =>\n (props.columns as any[]).map((c: any) => ({ label: c.title, value: c.dataIndex })),\n );\n\n const addRule = () => {\n (props.group as any).conditions.push({ field: '', op: '=', value: '' });\n };\n const addGroup = () => {\n (props.group as any).conditions.push({ type: 'and', conditions: [] });\n };\n const removeAt = (idx: number) => {\n (props.group as any).conditions.splice(idx, 1);\n };\n const updateBetween = (rule: any, pos: number, v: any) => {\n const arr = Array.isArray(rule.value) ? rule.value : [undefined, undefined];\n arr[pos] = v;\n rule.value = arr;\n };\n\n return {\n operators,\n fieldOptions,\n addRule,\n addGroup,\n removeAt,\n updateBetween,\n };\n },\n});\n</script>\n\n<style lang=\"less\" scoped>\n.qb-group {\n border-left: 2px solid #f0f0f0;\n padding-left: 8px;\n}\n.qb-group-head {\n display: flex;\n gap: 8px;\n margin-bottom: 8px;\n}\n.qb-group-body {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.qb-rule {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.qb-subgroup {\n padding: 6px 0 6px 8px;\n border-left: 2px dashed #f0f0f0;\n}\n</style>\n","<template>\n <div class=\"qb-group\">\n <div class=\"qb-group-head\">\n <a-select\n style=\"width: 110px\"\n :value=\"group.type || 'and'\"\n :options=\"[\n { label: '并且', value: 'and' },\n { label: '或者', value: 'or' },\n ]\"\n @update:value=\"(v:string) => (group.type = v)\"\n />\n <a-button\n size=\"small\"\n @click=\"addRule\"\n >\n 添加条件\n </a-button>\n <a-button\n size=\"small\"\n style=\"margin-left: 8px\"\n @click=\"addGroup\"\n >\n 添加分组\n </a-button>\n </div>\n\n <div class=\"qb-group-body\">\n <template\n v-for=\"(child, idx) in group.conditions\"\n :key=\"idx\"\n >\n <!-- 分组 -->\n <div\n v-if=\"child && typeof child === 'object' && 'type' in child\"\n class=\"qb-subgroup\"\n >\n <ConditionGroup\n :group=\"child\"\n :columns=\"columns\"\n />\n <a-button\n danger\n size=\"small\"\n style=\"margin: 4px 0\"\n @click=\"removeAt(idx)\"\n >\n 删除分组\n </a-button>\n </div>\n <!-- 规则 -->\n <div\n v-else\n class=\"qb-rule\"\n >\n <a-select\n :value=\"child.field\"\n style=\"min-width: 200px\"\n placeholder=\"选择字段\"\n :options=\"fieldOptions\"\n @update:value=\"(v:string)=> (child.field = v)\"\n />\n <a-select\n :value=\"child.op\"\n style=\"width: 200px\"\n :options=\"operators\"\n @update:value=\"(v:string)=> (child.op = v)\"\n />\n\n <!-- 值输入区域 -->\n <template v-if=\"child.op === 'in'\">\n <a-select\n mode=\"tags\"\n style=\"min-width: 220px\"\n :value=\"Array.isArray(child.value) ? child.value : []\"\n placeholder=\"输入多个值后回车\"\n @update:value=\"(v:any)=> (child.value = v)\"\n />\n </template>\n <template v-else-if=\"child.op === 'between'\">\n <a-space :size=\"4\">\n <a-input\n style=\"width: 120px\"\n :value=\"Array.isArray(child.value) ? child.value?.[0] : undefined\"\n placeholder=\"起始值\"\n @update:value=\"(v:any)=> updateBetween(child, 0, v)\"\n />\n <span style=\"padding: 0 4px; color: #999\">~</span>\n <a-input\n style=\"width: 120px\"\n :value=\"Array.isArray(child.value) ? child.value?.[1] : undefined\"\n placeholder=\"结束值\"\n @update:value=\"(v:any)=> updateBetween(child, 1, v)\"\n />\n </a-space>\n </template>\n <template v-else-if=\"child.op === 'is'\">\n <a-select\n style=\"min-width: 160px\"\n :value=\"child.value\"\n placeholder=\"选择 NULL/TRUE/FALSE\"\n @update:value=\"(v:any)=> (child.value = v)\"\n >\n <a-select-option :value=\"null\">NULL</a-select-option>\n <a-select-option :value=\"true\">TRUE</a-select-option>\n <a-select-option :value=\"false\">FALSE</a-select-option>\n </a-select>\n </template>\n <template v-else>\n <a-input\n style=\"min-width: 220px\"\n :value=\"child.value\"\n placeholder=\"输入值\"\n @update:value=\"(v:any)=> (child.value = v)\"\n />\n </template>\n\n <a-button\n danger\n size=\"small\"\n @click=\"removeAt(idx)\"\n >\n 删除\n </a-button>\n </div>\n </template>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, computed } from 'vue';\n\nexport default defineComponent({\n name: 'ConditionGroup',\n props: {\n group: { type: Object as any, required: true },\n columns: { type: Array as any, required: true },\n isRoot: { type: Boolean, default: false },\n },\n setup(props) {\n const operators = [\n { label: '等于', value: '=' },\n { label: '不等于', value: '!=' },\n { label: '大于', value: '>' },\n { label: '大于或等于', value: '>=' },\n { label: '小于', value: '<' },\n { label: '小于或等于', value: '<=' },\n { label: '包含', value: 'in' },\n { label: '模糊匹配', value: 'like' },\n { label: '介于', value: 'between' },\n ];\n\n const fieldOptions = computed(() =>\n (props.columns as any[]).map((c: any) => ({ label: c.title, value: c.dataIndex })),\n );\n\n const addRule = () => {\n (props.group as any).conditions.push({ field: '', op: '=', value: '' });\n };\n const addGroup = () => {\n (props.group as any).conditions.push({ type: 'and', conditions: [] });\n };\n const removeAt = (idx: number) => {\n (props.group as any).conditions.splice(idx, 1);\n };\n const updateBetween = (rule: any, pos: number, v: any) => {\n const arr = Array.isArray(rule.value) ? rule.value : [undefined, undefined];\n arr[pos] = v;\n rule.value = arr;\n };\n\n return {\n operators,\n fieldOptions,\n addRule,\n addGroup,\n removeAt,\n updateBetween,\n };\n },\n});\n</script>\n\n<style lang=\"less\" scoped>\n.qb-group {\n border-left: 2px solid #f0f0f0;\n padding-left: 8px;\n}\n.qb-group-head {\n display: flex;\n gap: 8px;\n margin-bottom: 8px;\n}\n.qb-group-body {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.qb-rule {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.qb-subgroup {\n padding: 6px 0 6px 8px;\n border-left: 2px dashed #f0f0f0;\n}\n</style>\n","<template>\n <a-modal\n title=\"原始数据\"\n width=\"1300px\"\n v-model:open=\"open\"\n :maskClosable=\"false\"\n centered\n @cancel=\"handleCancel\"\n >\n <div>\n <a-card\n size=\"small\"\n :bordered=\"false\"\n style=\"margin-bottom: 12px\"\n >\n <a-space\n direction=\"vertical\"\n :size=\"8\"\n style=\"width: 100%\"\n >\n <div style=\"display: flex; justify-content: space-between; align-items: center\">\n <div style=\"font-weight: 600\">查询条件</div>\n <div>\n <a-button\n size=\"small\"\n @click=\"resetConditions\"\n >\n 重置\n </a-button>\n <a-button\n type=\"primary\"\n size=\"small\"\n style=\"margin-left: 8px\"\n @click=\"applySearch\"\n >\n 查询\n </a-button>\n </div>\n </div>\n <div class=\"conditions-scroll\">\n <ConditionGroup\n :group=\"conditionsRoot\"\n :columns=\"column\"\n :is-root=\"true\"\n />\n </div>\n <div class=\"time-range-row\">\n <span class=\"field-label\">时间范围:</span>\n <a-range-picker\n v-model:value=\"timeRange\"\n :show-time=\"{ format: 'HH:mm:ss' }\"\n format=\"YYYY-MM-DD HH:mm:ss\"\n value-format=\"YYYY-MM-DD HH:mm:ss\"\n :placeholder=\"['开始时间', '结束时间']\"\n style=\"width: 440px\"\n />\n </div>\n </a-space>\n </a-card>\n <a-spin :spinning=\"loading\">\n <a-table\n :columns=\"column\"\n :dataSource=\"datasource\"\n rowKey=\"id\"\n :pagination=\"{\n current: current,\n pageSize: pageSize,\n total: total,\n onChange: handlePageChange,\n showSizeChanger: true,\n showQuickJumper: true,\n pageSizeOptions: pageOptions,\n }\"\n :scroll=\"{ y: height, x: width }\"\n @change=\"handleTableChange\"\n ></a-table>\n </a-spin>\n </div>\n <template #footer>\n <a-button\n key=\"back\"\n @click=\"handleCancel\"\n >\n 关闭\n </a-button>\n <a-button\n key=\"ok\"\n type=\"primary\"\n @click=\"handleCancel\"\n >\n 确定\n </a-button>\n </template>\n </a-modal>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, onUnmounted, ref, onMounted, computed } from 'vue';\nimport { debounce } from 'lodash';\nimport ConditionGroup from './syncConditionGroup.vue';\nimport { getApiData } from 'liyu-pc-base/api/api-model';\nimport dayjs from 'dayjs';\n\nexport default defineComponent({\n name: 'ExportRawData',\n components: { ConditionGroup },\n props: {\n title: {\n type: String,\n required: false,\n default: () => '',\n },\n record: {\n type: Object,\n required: false,\n default: () => ({}),\n },\n },\n setup(props, { emit }) {\n const height = ref(window.innerHeight - 550);\n const onresize: any = debounce(() => {\n height.value = window.innerHeight - 550;\n }, 200);\n const loading = ref(false);\n\n const datasource = ref<any[]>([]);\n const open = ref(true);\n const titleMap = ref({});\n\n const column = computed(() => {\n const res = [];\n if (datasource.value?.length) {\n for (const key of Object.keys(datasource.value[0])) {\n const title = titleMap.value[key] || key;\n res.push({\n title: title,\n dataIndex: key,\n key: key,\n });\n }\n }\n return res;\n });\n\n const get_column_config = async () => {\n const res: any = await getApiData(\n {\n export_task_id: (props as any).record?.id,\n },\n `${props.record.model_app}/query_sync_model_field_list`,\n );\n if (res?.data?.length) {\n for (const item of res.data) {\n titleMap.value[item.field_name] = item.name;\n }\n }\n };\n const current = ref<number>(1);\n const pageSize = ref<number>(10);\n const total = ref<number>(0);\n const width = computed(() => {\n let w = column.value.length * 200;\n return w < 1000 ? 1000 : w;\n });\n const pageOptions = ref<string[]>([\n '10',\n '20',\n '50',\n '100',\n '500',\n '1000',\n '2000',\n '5000',\n '10000',\n ]);\n\n // 条件构建器根\n const conditionsRoot = ref<any>({ type: 'and', conditions: [] });\n\n // 时间范围([start, end] 字符串,格式 YYYY-MM-DD HH:mm:ss;用于后端 start_time/end_time)\n const timeRange = ref<any>(null);\n\n // 排序状态 - 支持多字段排序\n const sortFields = ref<Array<{ field: string; order: string }>>([]);\n\n const handleCancel = () => {\n emit('cancel');\n };\n\n const get_datasource = async () => {\n loading.value = true;\n try {\n const params: any = {\n export_task_id: (props as any).record?.id,\n current: current.value,\n pageSize: pageSize.value,\n conditions: conditionsRoot.value,\n sort_fields: sortFields.value.length > 0 ? sortFields.value : undefined,\n };\n // 时间范围:前端传则带上(供后端作为 start_time/end_time 渲染 SQL),不传则回退默认区间\n if (\n timeRange.value &&\n timeRange.value.length === 2 &&\n timeRange.value[0] &&\n timeRange.value[1]\n ) {\n params.time_range = timeRange.value;\n }\n const res: any = await getApiData(params, `${props.record.model_app}/query_raw_data`);\n datasource.value = res?.data || [];\n current.value = res?.current ?? current.value;\n pageSize.value = res?.pageSize ?? pageSize.value;\n total.value = res?.total ?? 0;\n } finally {\n loading.value = false;\n }\n };\n\n const handlePageChange = (page: number, size?: number) => {\n current.value = page;\n if (size && size !== pageSize.value) pageSize.value = size;\n get_datasource();\n };\n\n const handleTableChange = (pagination: any, filters: any, sorter: any, { action }: any) => {\n if (action === 'sort') {\n if (sorter?.field) {\n const field = sorter.field;\n const order = sorter.order === 'ascend' ? 'asc' : 'desc';\n sortFields.value = [{ field: field, order: order }];\n } else {\n // 清除所有排序\n sortFields.value = [];\n }\n\n // 重置到第一页并重新查询\n current.value = 1;\n get_datasource();\n }\n };\n\n const resetConditions = () => {\n conditionsRoot.value = { type: 'and', conditions: [] };\n timeRange.value = null;\n };\n const applySearch = () => {\n current.value = 1;\n get_datasource();\n };\n\n onMounted(() => {\n window.addEventListener('resize', onresize);\n onresize();\n get_column_config();\n let start_time = '';\n if (props.record?.data_start_date) {\n start_time = props.record?.data_start_date + ' 00:00:00';\n } else {\n start_time = dayjs().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss');\n }\n timeRange.value = [start_time, dayjs().format('YYYY-MM-DD HH:mm:ss')];\n });\n onUnmounted(() => {\n window.removeEventListener('resize', onresize);\n });\n return {\n height,\n handleCancel,\n open,\n column,\n width,\n datasource,\n current,\n pageSize,\n total,\n handlePageChange,\n pageOptions,\n // 条件\n conditionsRoot,\n resetConditions,\n applySearch,\n loading,\n handleTableChange,\n // 时间范围\n timeRange,\n };\n },\n});\n</script>\n<style lang=\"less\" scoped>\n.qb-group {\n border-left: 2px solid #f0f0f0;\n padding-left: 8px;\n}\n.qb-group-head {\n display: flex;\n gap: 8px;\n margin-bottom: 8px;\n}\n.qb-group-body {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.qb-rule {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.qb-subgroup {\n padding: 6px 0 6px 8px;\n border-left: 2px dashed #f0f0f0;\n}\n.conditions-scroll {\n max-height: 200px;\n overflow-y: auto;\n padding-right: 8px;\n}\n.time-range-row {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n}\n.field-label {\n font-weight: 500;\n color: rgba(0, 0, 0, 0.85);\n}\n</style>\n","<template>\n <a-modal\n title=\"原始数据\"\n width=\"1300px\"\n v-model:open=\"open\"\n :maskClosable=\"false\"\n centered\n @cancel=\"handleCancel\"\n >\n <div>\n <a-card\n size=\"small\"\n :bordered=\"false\"\n style=\"margin-bottom: 12px\"\n >\n <a-space\n direction=\"vertical\"\n :size=\"8\"\n style=\"width: 100%\"\n >\n <div style=\"display: flex; justify-content: space-between; align-items: center\">\n <div style=\"font-weight: 600\">查询条件</div>\n <div>\n <a-button\n size=\"small\"\n @click=\"resetConditions\"\n >\n 重置\n </a-button>\n <a-button\n type=\"primary\"\n size=\"small\"\n style=\"margin-left: 8px\"\n @click=\"applySearch\"\n >\n 查询\n </a-button>\n </div>\n </div>\n <div class=\"conditions-scroll\">\n <ConditionGroup\n :group=\"conditionsRoot\"\n :columns=\"column\"\n :is-root=\"true\"\n />\n </div>\n <div class=\"time-range-row\">\n <span class=\"field-label\">时间范围:</span>\n <a-range-picker\n v-model:value=\"timeRange\"\n :show-time=\"{ format: 'HH:mm:ss' }\"\n format=\"YYYY-MM-DD HH:mm:ss\"\n value-format=\"YYYY-MM-DD HH:mm:ss\"\n :placeholder=\"['开始时间', '结束时间']\"\n style=\"width: 440px\"\n />\n </div>\n </a-space>\n </a-card>\n <a-spin :spinning=\"loading\">\n <a-table\n :columns=\"column\"\n :dataSource=\"datasource\"\n rowKey=\"id\"\n :pagination=\"{\n current: current,\n pageSize: pageSize,\n total: total,\n onChange: handlePageChange,\n showSizeChanger: true,\n showQuickJumper: true,\n pageSizeOptions: pageOptions,\n }\"\n :scroll=\"{ y: height, x: width }\"\n @change=\"handleTableChange\"\n ></a-table>\n </a-spin>\n </div>\n <template #footer>\n <a-button\n key=\"back\"\n @click=\"handleCancel\"\n >\n 关闭\n </a-button>\n <a-button\n key=\"ok\"\n type=\"primary\"\n @click=\"handleCancel\"\n >\n 确定\n </a-button>\n </template>\n </a-modal>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, onUnmounted, ref, onMounted, computed } from 'vue';\nimport { debounce } from 'lodash';\nimport ConditionGroup from './syncConditionGroup.vue';\nimport { getApiData } from 'liyu-pc-base/api/api-model';\nimport dayjs from 'dayjs';\n\nexport default defineComponent({\n name: 'ExportRawData',\n components: { ConditionGroup },\n props: {\n title: {\n type: String,\n required: false,\n default: () => '',\n },\n record: {\n type: Object,\n required: false,\n default: () => ({}),\n },\n },\n setup(props, { emit }) {\n const height = ref(window.innerHeight - 550);\n const onresize: any = debounce(() => {\n height.value = window.innerHeight - 550;\n }, 200);\n const loading = ref(false);\n\n const datasource = ref<any[]>([]);\n const open = ref(true);\n const titleMap = ref({});\n\n const column = computed(() => {\n const res = [];\n if (datasource.value?.length) {\n for (const key of Object.keys(datasource.value[0])) {\n const title = titleMap.value[key] || key;\n res.push({\n title: title,\n dataIndex: key,\n key: key,\n });\n }\n }\n return res;\n });\n\n const get_column_config = async () => {\n const res: any = await getApiData(\n {\n export_task_id: (props as any).record?.id,\n },\n `${props.record.model_app}/query_sync_model_field_list`,\n );\n if (res?.data?.length) {\n for (const item of res.data) {\n titleMap.value[item.field_name] = item.name;\n }\n }\n };\n const current = ref<number>(1);\n const pageSize = ref<number>(10);\n const total = ref<number>(0);\n const width = computed(() => {\n let w = column.value.length * 200;\n return w < 1000 ? 1000 : w;\n });\n const pageOptions = ref<string[]>([\n '10',\n '20',\n '50',\n '100',\n '500',\n '1000',\n '2000',\n '5000',\n '10000',\n ]);\n\n // 条件构建器根\n const conditionsRoot = ref<any>({ type: 'and', conditions: [] });\n\n // 时间范围([start, end] 字符串,格式 YYYY-MM-DD HH:mm:ss;用于后端 start_time/end_time)\n const timeRange = ref<any>(null);\n\n // 排序状态 - 支持多字段排序\n const sortFields = ref<Array<{ field: string; order: string }>>([]);\n\n const handleCancel = () => {\n emit('cancel');\n };\n\n const get_datasource = async () => {\n loading.value = true;\n try {\n const params: any = {\n export_task_id: (props as any).record?.id,\n current: current.value,\n pageSize: pageSize.value,\n conditions: conditionsRoot.value,\n sort_fields: sortFields.value.length > 0 ? sortFields.value : undefined,\n };\n // 时间范围:前端传则带上(供后端作为 start_time/end_time 渲染 SQL),不传则回退默认区间\n if (\n timeRange.value &&\n timeRange.value.length === 2 &&\n timeRange.value[0] &&\n timeRange.value[1]\n ) {\n params.time_range = timeRange.value;\n }\n const res: any = await getApiData(params, `${props.record.model_app}/query_raw_data`);\n datasource.value = res?.data || [];\n current.value = res?.current ?? current.value;\n pageSize.value = res?.pageSize ?? pageSize.value;\n total.value = res?.total ?? 0;\n } finally {\n loading.value = false;\n }\n };\n\n const handlePageChange = (page: number, size?: number) => {\n current.value = page;\n if (size && size !== pageSize.value) pageSize.value = size;\n get_datasource();\n };\n\n const handleTableChange = (pagination: any, filters: any, sorter: any, { action }: any) => {\n if (action === 'sort') {\n if (sorter?.field) {\n const field = sorter.field;\n const order = sorter.order === 'ascend' ? 'asc' : 'desc';\n sortFields.value = [{ field: field, order: order }];\n } else {\n // 清除所有排序\n sortFields.value = [];\n }\n\n // 重置到第一页并重新查询\n current.value = 1;\n get_datasource();\n }\n };\n\n const resetConditions = () => {\n conditionsRoot.value = { type: 'and', conditions: [] };\n timeRange.value = null;\n };\n const applySearch = () => {\n current.value = 1;\n get_datasource();\n };\n\n onMounted(() => {\n window.addEventListener('resize', onresize);\n onresize();\n get_column_config();\n let start_time = '';\n if (props.record?.data_start_date) {\n start_time = props.record?.data_start_date + ' 00:00:00';\n } else {\n start_time = dayjs().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss');\n }\n timeRange.value = [start_time, dayjs().format('YYYY-MM-DD HH:mm:ss')];\n });\n onUnmounted(() => {\n window.removeEventListener('resize', onresize);\n });\n return {\n height,\n handleCancel,\n open,\n column,\n width,\n datasource,\n current,\n pageSize,\n total,\n handlePageChange,\n pageOptions,\n // 条件\n conditionsRoot,\n resetConditions,\n applySearch,\n loading,\n handleTableChange,\n // 时间范围\n timeRange,\n };\n },\n});\n</script>\n<style lang=\"less\" scoped>\n.qb-group {\n border-left: 2px solid #f0f0f0;\n padding-left: 8px;\n}\n.qb-group-head {\n display: flex;\n gap: 8px;\n margin-bottom: 8px;\n}\n.qb-group-body {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.qb-rule {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.qb-subgroup {\n padding: 6px 0 6px 8px;\n border-left: 2px dashed #f0f0f0;\n}\n.conditions-scroll {\n max-height: 200px;\n overflow-y: auto;\n padding-right: 8px;\n}\n.time-range-row {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n}\n.field-label {\n font-weight: 500;\n color: rgba(0, 0, 0, 0.85);\n}\n</style>\n"],"mappings":";;;;;;aAqIA,IAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDA,CAAA,SCpLO,OAAM,WAAU,SACd,OAAM,gBAAe,SAyBrB,OAAM,gBAAe;CA3B9B,KAAA;CAmCU,OAAM;;CAnChB,KAAA;CAqDU,OAAM;;;;aApDd,EA8HM,OA9HN,GA8HM,CA7HJ,EAuBM,OAvBN,GAuBM;EAtBJ,EAQE,GAAA;GAPA,OAAA,EAAA,OAAA,QAAA;GACC,OAAO,EAAA,MAAM,QAAI;GACjB,SAAS,CAAA;;;;;;;GAIT,kBAAY,AAAA,EAAA,QAAG,MAAc,EAAA,MAAM,OAAO;;EAE7C,EAKW,GAAA;GAJT,MAAK;GACJ,SAAO,EAAA;;GAdhB,SAAA,QAiBM,AAAA,EAAA,OAAA,CAjBN,EAeO,QAED,CAAA,CAAA;GAjBN,GAAA;;EAkBM,EAMW,GAAA;GALT,MAAK;GACL,OAAA,EAAA,eAAA,MAAA;GACC,SAAO,EAAA;;GArBhB,SAAA,QAwBM,AAAA,EAAA,OAAA,CAxBN,EAsBO,QAED,CAAA,CAAA;GAxBN,GAAA;;KA2BI,EAmGM,OAnGN,GAmGM,EAAA,EAAA,EAAA,GAlGJ,EAiGW,GAAA,MA7HjB,EA6B+B,EAAA,MAAM,aAArB,GAAO,YA7BvB,EAAA,GAAA,EAAA,KA8Bc,EAAG,GAAA,CAID,KAAK,OAAW,KAAK,YAAA,UAA2B,KAAA,EAAA,GADxD,EAgBM,OAhBN,GAgBM,CAZJ,EAGE,GAAA;EAFC,OAAO;EACP,SAAS,EAAA;oCAEZ,EAOW,GAAA;EANT,QAAA;EACA,MAAK;EACL,OAAA,EAAA,QAAA,QAAA;EACC,UAAK,MAAE,EAAA,SAAS,CAAG;;EA7ChC,SAAA,QAgDU,AAAA,EAAA,OAAA,CAhDV,EA8CW,QAED,CAAA,CAAA;EAhDV,GAAA;kCAmDQ,EAyEM,OAzEN,GAyEM;EArEJ,EAME,GAAA;GALC,OAAO,EAAM;GACd,OAAA,EAAA,aAAA,QAAA;GACA,aAAY;GACX,SAAS,EAAA;GACT,mBAAe,MAAa,EAAM,QAAQ;;;;;;EAE7C,EAKE,GAAA;GAJC,OAAO,EAAM;GACd,OAAA,EAAA,OAAA,QAAA;GACC,SAAS,EAAA;GACT,mBAAe,MAAa,EAAM,KAAK;;;;;;EAI1B,EAAM,OAAE,QAAA,EAAA,GACtB,EAME,GAAA;GA7Ed,KAAA;GAwEc,MAAK;GACL,OAAA,EAAA,aAAA,QAAA;GACC,OAAO,MAAM,QAAQ,EAAM,KAAK,IAAI,EAAM,QAAK,CAAA;GAChD,aAAY;GACX,mBAAe,MAAU,EAAM,QAAQ;8CAGvB,EAAM,OAAE,aAAA,EAAA,GAC3B,EAcU,GAAA;GA9FtB,KAAA;GAgFsB,MAAM;;GAhF5B,SAAA,QAsFgB;IALF,EAKE,GAAA;KAJA,OAAA,EAAA,OAAA,QAAA;KACC,OAAO,MAAM,QAAQ,EAAM,KAAK,IAAI,EAAM,QAAK,KAAQ,KAAA;KACxD,aAAY;KACX,mBAAe,MAAS,EAAA,cAAc,GAAK,GAAK,CAAC;;aAEpD,EAAkD,QAAA,EAA5C,OAAA;KAAA,SAAA;KAAA,OAAA;IAAA,EAAmC,GAAC,KAAC,EAAA;IAC3C,EAKE,GAAA;KAJA,OAAA,EAAA,OAAA,QAAA;KACC,OAAO,MAAM,QAAQ,EAAM,KAAK,IAAI,EAAM,QAAK,KAAQ,KAAA;KACxD,aAAY;KACX,mBAAe,MAAS,EAAA,cAAc,GAAK,GAAK,CAAC;;;GA5FlE,GAAA;cAgG+B,EAAM,OAAE,QAAA,EAAA,GAC3B,EASW,GAAA;GA1GvB,KAAA;GAkGc,OAAA,EAAA,aAAA,QAAA;GACC,OAAO,EAAM;GACd,aAAY;GACX,mBAAe,MAAU,EAAM,QAAQ;;GArGtD,SAAA,QAuGmE;IAArD,EAAqD,GAAA,EAAnC,OAAO,KAAI,GAAA;KAvG3C,SAAA,QAuGiD,AAAA,EAAA,OAAA,CAvGjD,EAuG6C,MAAI,CAAA,CAAA;KAvGjD,GAAA;;IAwGc,EAAqD,GAAA,EAAnC,OAAO,GAAI,GAAA;KAxG3C,SAAA,QAwGiD,AAAA,EAAA,OAAA,CAxGjD,EAwG6C,MAAI,CAAA,CAAA;KAxGjD,GAAA;;IAyGc,EAAuD,GAAA,EAArC,OAAO,GAAK,GAAA;KAzG5C,SAAA,QAyGmD,AAAA,EAAA,OAAA,CAzGnD,EAyG8C,OAAK,CAAA,CAAA;KAzGnD,GAAA;;;GAAA,GAAA;iDA6GY,EAKE,GAAA;GAlHd,KAAA;GA8Gc,OAAA,EAAA,aAAA,QAAA;GACC,OAAO,EAAM;GACd,aAAY;GACX,mBAAe,MAAU,EAAM,QAAQ;;EAI5C,EAMW,GAAA;GALT,QAAA;GACA,MAAK;GACJ,UAAK,MAAE,EAAA,SAAS,CAAG;;GAxHhC,SAAA,QA2HU,AAAA,EAAA,OAAA,CA3HV,EAyHW,MAED,CAAA,CAAA;GA3HV,GAAA;;;;;;ACuGA,IAAA,IAAe,EAAgB;CAC7B,MAAM;CACN,YAAY,EAAE,gBAAA,sEAAA,EAAe;CAC7B,OAAO;EACL,OAAO;GACL,MAAM;GACN,UAAU;GACV,eAAe;EACjB;EACA,QAAQ;GACN,MAAM;GACN,UAAU;GACV,gBAAgB,CAAC;EACnB;CACF;CACA,MAAM,GAAO,EAAE,WAAQ;EACrB,IAAM,IAAS,EAAI,OAAO,cAAc,GAAG,GACrC,KAAA,GAAA,EAAA,SAAA,OAA+B;GACnC,EAAO,QAAQ,OAAO,cAAc;EACtC,GAAG,GAAG,GACA,IAAU,EAAI,EAAK,GAEnB,IAAa,EAAW,CAAC,CAAC,GAC1B,IAAO,EAAI,EAAI,GACf,IAAW,EAAI,CAAC,CAAC,GAEjB,IAAS,QAAe;GAC5B,IAAM,IAAM,CAAC;GACb,IAAI,EAAW,OAAO,QACpB,KAAK,IAAM,KAAO,OAAO,KAAK,EAAW,MAAM,EAAE,GAAG;IAClD,IAAM,IAAQ,EAAS,MAAM,MAAQ;IACrC,EAAI,KAAK;KACA;KACP,WAAW;KACN;IACP,CAAC;GACH;GAEF,OAAO;EACT,CAAC,GAEK,IAAoB,YAAY;GACpC,IAAM,IAAW,MAAM,EACrB,EACE,gBAAiB,EAAc,QAAQ,GACzC,GACA,GAAG,EAAM,OAAO,UAAU,6BAC5B;GACA,IAAI,GAAK,MAAM,QACb,KAAK,IAAM,KAAQ,EAAI,MACrB,EAAS,MAAM,EAAK,cAAc,EAAK;EAG7C,GACM,IAAU,EAAY,CAAC,GACvB,IAAW,EAAY,EAAE,GACzB,IAAQ,EAAY,CAAC,GACrB,IAAQ,QAAe;GAC3B,IAAI,IAAI,EAAO,MAAM,SAAS;GAC9B,OAAO,IAAI,MAAO,MAAO;EAC3B,CAAC,GACK,IAAc,EAAc;GAChC;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF,CAAC,GAGK,IAAiB,EAAS;GAAE,MAAM;GAAO,YAAY,CAAC;EAAE,CAAC,GAGzD,IAAY,EAAS,IAAI,GAGzB,IAAa,EAA6C,CAAC,CAAC,GAE5D,UAAqB;GACzB,EAAK,QAAQ;EACf,GAEM,IAAiB,YAAY;GACjC,EAAQ,QAAQ;GAChB,IAAI;IACF,IAAM,IAAc;KAClB,gBAAiB,EAAc,QAAQ;KACvC,SAAS,EAAQ;KACjB,UAAU,EAAS;KACnB,YAAY,EAAe;KAC3B,aAAa,EAAW,MAAM,SAAS,IAAI,EAAW,QAAQ,KAAA;IAChE;IAEA,AACE,EAAU,SACV,EAAU,MAAM,WAAW,KAC3B,EAAU,MAAM,MAChB,EAAU,MAAM,OAEhB,EAAO,aAAa,EAAU;IAEhC,IAAM,IAAW,MAAM,EAAW,GAAQ,GAAG,EAAM,OAAO,UAAU,gBAAgB;IAIpF,AAHA,EAAW,QAAQ,GAAK,QAAQ,CAAC,GACjC,EAAQ,QAAQ,GAAK,WAAW,EAAQ,OACxC,EAAS,QAAQ,GAAK,YAAY,EAAS,OAC3C,EAAM,QAAQ,GAAK,SAAS;GAC9B,UAAU;IACR,EAAQ,QAAQ;GAClB;EACF;EAiDA,OAfA,QAAgB;GAGd,AAFA,OAAO,iBAAiB,UAAU,CAAQ,GAC1C,EAAS,GACT,EAAkB;GAClB,IAAI,IAAa;GAMjB,AALA,AAGE,IAHE,EAAM,QAAQ,kBACH,EAAM,QAAQ,kBAAkB,cAEhC,EAAM,CAAC,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC,OAAO,qBAAqB,GAEtE,EAAU,QAAQ,CAAC,GAAY,EAAM,CAAC,CAAC,OAAO,qBAAqB,CAAC;EACtE,CAAC,GACD,QAAkB;GAChB,OAAO,oBAAoB,UAAU,CAAQ;EAC/C,CAAC,GACM;GACL;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA,mBAzDwB,GAAc,MAAkB;IAGxD,AAFA,EAAQ,QAAQ,GACZ,KAAQ,MAAS,EAAS,UAAO,EAAS,QAAQ,IACtD,EAAe;GACjB;GAsDE;GAEA;GACA,uBAtC4B;IAE5B,AADA,EAAe,QAAQ;KAAE,MAAM;KAAO,YAAY,CAAC;IAAE,GACrD,EAAU,QAAQ;GACpB;GAoCE,mBAnCwB;IAExB,AADA,EAAQ,QAAQ,GAChB,EAAe;GACjB;GAiCE;GACA,oBA1DyB,GAAiB,GAAc,GAAa,EAAE,gBAAkB;IACzF,AAAI,MAAW,WACT,GAAQ,QAGV,EAAW,QAAQ,CAAC;KAAS,OAFf,EAAO;KAEsB,OAD7B,EAAO,UAAU,WAAW,QAAQ;IACD,CAAC,IAGlD,EAAW,QAAQ,CAAC,GAItB,EAAQ,QAAQ,GAChB,EAAe;GAEnB;GA6CE;EACF;CACF;AACF,CAAC,SC3Qc,OAAA;CAAA,SAAA;CAAA,mBAAA;CAAA,eAAA;AAAA,EAA0E,SAmB1E,OAAM,oBAAmB,SAOzB,OAAM,iBAAgB;;;aA7CnC,EA4FU,GAAA;EA3FR,OAAM;EACN,OAAM;EACE,MAAM,EAAA;EAJlB,iBAAA,AAAA,EAAA,QAAA,MAAA,EAIkB,OAAI;EACjB,cAAc;EACf,UAAA;EACC,UAAQ,EAAA;;EAuEE,QAAM,QAMJ,CALX,EAKW,GAAA;GAJT,KAAI;GACH,SAAO,EAAA;;GAjFhB,SAAA,QAoFM,AAAA,EAAA,OAAA,CApFN,EAkFO,MAED,CAAA,CAAA;GApFN,GAAA;sBAqFM,EAMW,GAAA;GALT,KAAI;GACJ,MAAK;GACJ,SAAO,EAAA;;GAxFhB,SAAA,QA2FM,AAAA,EAAA,OAAA,CA3FN,EAyFO,MAED,CAAA,CAAA;GA3FN,GAAA;;EAAA,SAAA,QA6EU,CApEN,EAoEM,OAAA,MAAA,CAnEJ,EAgDS,GAAA;GA/CP,MAAK;GACJ,UAAU;GACX,OAAA,EAAA,iBAAA,OAAA;;GAbR,SAAA,QAyDkB,CA1CV,EA0CU,GAAA;IAzCR,WAAU;IACT,MAAM;IACP,OAAA,EAAA,OAAA,OAAA;;IAlBV,SAAA,QAsCgB;KAlBN,EAkBM,OAlBN,GAkBM,CAAA,AAAA,EAAA,OAjBJ,EAAwC,OAAA,EAAnC,OAAA,EAAA,eAAA,MAAA,EAAwB,GAAC,QAAI,EAAA,GAClC,EAeM,OAAA,MAAA,CAdJ,EAKW,GAAA;MAJT,MAAK;MACJ,SAAO,EAAA;;MAzBxB,SAAA,QA4Bc,AAAA,EAAA,OAAA,CA5Bd,EA0Be,MAED,CAAA,CAAA;MA5Bd,GAAA;yBA6Bc,EAOW,GAAA;MANT,MAAK;MACL,MAAK;MACL,OAAA,EAAA,eAAA,MAAA;MACC,SAAO,EAAA;;MAjCxB,SAAA,QAoCc,AAAA,EAAA,OAAA,CApCd,EAkCe,MAED,CAAA,CAAA;MApCd,GAAA;;KAuCU,EAMM,OANN,GAMM,CALJ,EAIE,GAAA;MAHC,OAAO,EAAA;MACP,SAAS,EAAA;MACT,WAAS;;KAGd,EAUM,OAVN,GAUM,CAAA,AAAA,EAAA,OATJ,EAAsC,QAAA,EAAhC,OAAM,cAAa,GAAC,SAAK,EAAA,GAC/B,EAOE,GAAA;MANQ,OAAO,EAAA;MAjD7B,kBAAA,AAAA,EAAA,QAAA,MAAA,EAiD6B,YAAS;MACvB,aAAW,EAAA,QAAA,WAAA;MACZ,QAAO;MACP,gBAAa;MACZ,aAAa,CAAA,QAAA,MAAA;MACd,OAAA,EAAA,OAAA,QAAA;;;IAtDd,GAAA;;GAAA,GAAA;MA2DM,EAiBS,GAAA,EAjBA,UAAU,EAAA,QAAO,GAAA;GA3DhC,SAAA,QA2EmB,CAfX,EAeW,GAAA;IAdR,SAAS,EAAA;IACT,YAAY,EAAA;IACb,QAAO;IACN,YAAU;cAAyB,EAAA;eAA+B,EAAA;YAA6B,EAAA;eAA6B,EAAA;;;sBAAqH,EAAA;;IASjP,QAAM;KAAA,GAAO,EAAA;KAAM,GAAK,EAAA;IAAK;IAC7B,UAAQ,EAAA;;;;;;;;GA1EnB,GAAA;;EAAA,GAAA"}