liyu-pc-base 1.0.554 → 1.0.562
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/dist/{aiGenModel-CNwUTMNL.js → aiGenModel-C7SZpnoO.js} +506 -471
- package/dist/{aiGenModel-CNwUTMNL.js.map → aiGenModel-C7SZpnoO.js.map} +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/remotePages/index.js +1 -1
- package/dist/index.js +1 -1
- package/dist/liyu-pc-base.css +1 -1
- package/dist/{remotePages-CbLpjalw.js → remotePages-CiKzUQeL.js} +3 -3
- package/dist/remotePages-CiKzUQeL.js.map +1 -0
- package/dist/syncDataSourceConfig-BXAolK4f.js +443 -0
- package/dist/syncDataSourceConfig-BXAolK4f.js.map +1 -0
- package/dist/{syncExportRawData-dtLd_SL2.js → syncExportRawData-B8xySuut.js} +107 -102
- package/dist/syncExportRawData-B8xySuut.js.map +1 -0
- package/package.json +1 -1
- package/dist/remotePages-CbLpjalw.js.map +0 -1
- package/dist/syncDataSourceConfig-AlcjBERC.js +0 -465
- package/dist/syncDataSourceConfig-AlcjBERC.js.map +0 -1
- package/dist/syncExportRawData-dtLd_SL2.js.map +0 -1
|
@@ -0,0 +1,443 @@
|
|
|
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 { t as a } from "./JsonStr-Bx2WI6jK.js";
|
|
6
|
+
import { Fragment as o, computed as s, createBlock as c, createCommentVNode as l, createElementBlock as u, createTextVNode as d, createVNode as f, defineComponent as p, onMounted as m, openBlock as h, reactive as g, ref as _, renderList as v, resolveComponent as y, toDisplayString as b, withCtx as x } from "vue";
|
|
7
|
+
import { message as S } from "ant-design-vue";
|
|
8
|
+
//#region src/components/lysync/syncDataSourceConfig.vue?vue&type=script&setup=true&lang.ts
|
|
9
|
+
var C = r(), w = /*#__PURE__*/ n(/* @__PURE__ */ p({
|
|
10
|
+
__name: "syncDataSourceConfig",
|
|
11
|
+
props: {
|
|
12
|
+
title: {},
|
|
13
|
+
record: {}
|
|
14
|
+
},
|
|
15
|
+
emits: ["cancel", "ok"],
|
|
16
|
+
setup(n, { emit: r }) {
|
|
17
|
+
let p = n, w = r, T = _(null), E = _(!1), D = _(!0), O = _("create"), k = e().currentOrg, A = s(() => L.value.db_type === "oracle" ? "SID/服务名" : "数据库名称"), j = s({
|
|
18
|
+
get: () => L.value.db_options?.schema ? L.value.db_options?.schema : "",
|
|
19
|
+
set: (e) => {
|
|
20
|
+
typeof L.value.db_options == "object" ? e ? L.value.db_options.schema = e : delete L.value.db_options.schema : e && (L.value.db_options = { schema: e });
|
|
21
|
+
}
|
|
22
|
+
}), M = [{
|
|
23
|
+
value: "db",
|
|
24
|
+
label: "数据库"
|
|
25
|
+
}, {
|
|
26
|
+
value: "custom",
|
|
27
|
+
label: "自定义"
|
|
28
|
+
}], N = [
|
|
29
|
+
{
|
|
30
|
+
value: "mysql",
|
|
31
|
+
label: "MySQL"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
value: "tsql",
|
|
35
|
+
label: "SQL Server"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
value: "oracle",
|
|
39
|
+
label: "Oracle"
|
|
40
|
+
}
|
|
41
|
+
], P = _([]), F = _(!1), I = async () => {
|
|
42
|
+
F.value = !0;
|
|
43
|
+
try {
|
|
44
|
+
P.value = await i({ org_id: k?.id }, `${p.record.model_app}/get_collect_funcs`) || [];
|
|
45
|
+
} catch {
|
|
46
|
+
P.value = [];
|
|
47
|
+
} finally {
|
|
48
|
+
F.value = !1;
|
|
49
|
+
}
|
|
50
|
+
}, L = _({
|
|
51
|
+
name: void 0,
|
|
52
|
+
source_type: "db",
|
|
53
|
+
db_type: "mysql",
|
|
54
|
+
db_host: void 0,
|
|
55
|
+
db_port: void 0,
|
|
56
|
+
db_user: void 0,
|
|
57
|
+
db_password: void 0,
|
|
58
|
+
db_name: void 0,
|
|
59
|
+
db_options: {},
|
|
60
|
+
custom_func: void 0,
|
|
61
|
+
custom_func_kwargs: {}
|
|
62
|
+
}), R = g({
|
|
63
|
+
name: [{
|
|
64
|
+
required: !0,
|
|
65
|
+
message: "请填写数据源名称"
|
|
66
|
+
}],
|
|
67
|
+
source_type: [{
|
|
68
|
+
required: !0,
|
|
69
|
+
message: "请选择数据源类型"
|
|
70
|
+
}],
|
|
71
|
+
db_type: [{
|
|
72
|
+
required: !0,
|
|
73
|
+
message: "请选择数据库类型"
|
|
74
|
+
}],
|
|
75
|
+
db_host: [{
|
|
76
|
+
required: !0,
|
|
77
|
+
message: "请填写数据库主机"
|
|
78
|
+
}],
|
|
79
|
+
db_port: [{
|
|
80
|
+
required: !0,
|
|
81
|
+
message: "请填写数据库端口"
|
|
82
|
+
}],
|
|
83
|
+
db_user: [{
|
|
84
|
+
required: !0,
|
|
85
|
+
message: "请填写数据库用户"
|
|
86
|
+
}],
|
|
87
|
+
db_name: [{
|
|
88
|
+
required: !0,
|
|
89
|
+
message: "请填写数据库名称"
|
|
90
|
+
}],
|
|
91
|
+
custom_func: [{
|
|
92
|
+
required: !0,
|
|
93
|
+
message: "请填写自定义采集函数名称"
|
|
94
|
+
}]
|
|
95
|
+
}), z = () => {
|
|
96
|
+
L.value.source_type === "db" ? (L.value.custom_func = void 0, L.value.custom_func_kwargs = {}) : (L.value.db_host = void 0, L.value.db_port = void 0, L.value.db_user = void 0, L.value.db_password = void 0, L.value.db_name = void 0, L.value.db_options = {});
|
|
97
|
+
}, B = (e, t) => {
|
|
98
|
+
if (e == null || String(e).trim() === "") return {};
|
|
99
|
+
try {
|
|
100
|
+
return JSON.parse(e);
|
|
101
|
+
} catch (e) {
|
|
102
|
+
throw Error(`${t} 不是合法 JSON: ${e.message}`);
|
|
103
|
+
}
|
|
104
|
+
}, V = (e) => e && typeof e == "object" && !Array.isArray(e) && e.data !== void 0 ? e.data : e, H = async (e) => V(await i({
|
|
105
|
+
sync_data_source_id: e,
|
|
106
|
+
org_id: k?.id
|
|
107
|
+
}, `${p.record.model_app}/get_sync_data_source`)) || {}, U = () => {
|
|
108
|
+
let e = (0, C.cloneDeep)(L.value);
|
|
109
|
+
return e.update_field_list = [
|
|
110
|
+
"name",
|
|
111
|
+
"source_type",
|
|
112
|
+
"db_type",
|
|
113
|
+
"db_host",
|
|
114
|
+
"db_port",
|
|
115
|
+
"db_user",
|
|
116
|
+
"db_password",
|
|
117
|
+
"db_name",
|
|
118
|
+
"db_options",
|
|
119
|
+
"custom_func",
|
|
120
|
+
"custom_func_kwargs"
|
|
121
|
+
], e.source_type === "db" ? (delete e.custom_func, delete e.custom_func_kwargs, e.custom_func_kwargs = {}, e.db_password || (delete e.db_password, O.value === "edit" && (e.update_field_list = e.update_field_list.filter((e) => e !== "db_password")))) : ([
|
|
122
|
+
"db_type",
|
|
123
|
+
"db_host",
|
|
124
|
+
"db_port",
|
|
125
|
+
"db_user",
|
|
126
|
+
"db_password",
|
|
127
|
+
"db_name",
|
|
128
|
+
"db_options"
|
|
129
|
+
].forEach((t) => delete e[t]), e.db_options = {}, e.custom_func_kwargs = B(e.custom_func_kwargs, "自定义采集函数参数"), delete e.custom_func_kwargs), e;
|
|
130
|
+
}, W = async () => {
|
|
131
|
+
try {
|
|
132
|
+
await T.value.validate();
|
|
133
|
+
let e = U();
|
|
134
|
+
e.sync_data_source_id = p.record.id;
|
|
135
|
+
let n = O.value === "edit" ? `${p.record.model_app}/update_sync_data_source` : `${p.record.model_app}/create_sync_data_source`;
|
|
136
|
+
O.value === "edit" && (e.id = p.record.id), E.value = !0, await i({
|
|
137
|
+
...e,
|
|
138
|
+
org_id: k?.id
|
|
139
|
+
}, n), S.success("操作成功"), t()?.emit("refresh"), w("ok");
|
|
140
|
+
} catch {} finally {
|
|
141
|
+
E.value = !1;
|
|
142
|
+
}
|
|
143
|
+
}, G = () => w("cancel"), K = async () => {
|
|
144
|
+
let e = p.record?.id, t = (e == null ? p.record : await H(e)) || {};
|
|
145
|
+
L.value = {
|
|
146
|
+
name: t.name || "",
|
|
147
|
+
source_type: t.source_type || "db",
|
|
148
|
+
db_type: t.db_type || "mysql",
|
|
149
|
+
db_host: t.db_host || void 0,
|
|
150
|
+
db_port: t.db_port ?? void 0,
|
|
151
|
+
db_user: t.db_user || void 0,
|
|
152
|
+
db_password: void 0,
|
|
153
|
+
db_name: t.db_name || void 0,
|
|
154
|
+
db_options: t.db_options,
|
|
155
|
+
custom_func: t.custom_func || void 0,
|
|
156
|
+
custom_func_kwargs: t.custom_func_kwargs
|
|
157
|
+
};
|
|
158
|
+
let n = t.custom_func;
|
|
159
|
+
n && !P.value.some((e) => e.value === n) && (P.value = [{
|
|
160
|
+
value: n,
|
|
161
|
+
label: n
|
|
162
|
+
}, ...P.value]);
|
|
163
|
+
};
|
|
164
|
+
return m(async () => {
|
|
165
|
+
p.record?.form_type && (O.value = p.record.form_type), await I(), O.value === "edit" && await K();
|
|
166
|
+
}), (e, t) => {
|
|
167
|
+
let n = y("a-divider"), r = y("a-input"), i = y("a-form-item"), s = y("a-col"), p = y("a-select-option"), m = y("a-select"), g = y("a-row"), _ = y("a-input-number"), S = y("a-input-password"), C = y("a-form"), w = y("a-modal");
|
|
168
|
+
return h(), c(w, {
|
|
169
|
+
title: e.title,
|
|
170
|
+
width: "880px",
|
|
171
|
+
open: D.value,
|
|
172
|
+
bodyStyle: {
|
|
173
|
+
maxHeight: "78vh",
|
|
174
|
+
overflowY: "auto",
|
|
175
|
+
padding: "0 24px"
|
|
176
|
+
},
|
|
177
|
+
"confirm-loading": E.value,
|
|
178
|
+
"cancel-text": "取消",
|
|
179
|
+
"ok-text": "确定",
|
|
180
|
+
centered: "",
|
|
181
|
+
"destroy-on-close": "",
|
|
182
|
+
onCancel: G,
|
|
183
|
+
onOk: W
|
|
184
|
+
}, {
|
|
185
|
+
default: x(() => [f(C, {
|
|
186
|
+
ref_key: "formRef",
|
|
187
|
+
ref: T,
|
|
188
|
+
model: L.value,
|
|
189
|
+
layout: "vertical",
|
|
190
|
+
size: "small"
|
|
191
|
+
}, {
|
|
192
|
+
default: x(() => [
|
|
193
|
+
f(n, { orientation: "left" }, {
|
|
194
|
+
default: x(() => t[12] ||= [d("基本信息")]),
|
|
195
|
+
_: 1
|
|
196
|
+
}),
|
|
197
|
+
f(g, { gutter: 16 }, {
|
|
198
|
+
default: x(() => [
|
|
199
|
+
f(s, { span: 12 }, {
|
|
200
|
+
default: x(() => [f(i, {
|
|
201
|
+
label: "数据源名称",
|
|
202
|
+
name: "name",
|
|
203
|
+
rules: R.name
|
|
204
|
+
}, {
|
|
205
|
+
default: x(() => [f(r, {
|
|
206
|
+
value: L.value.name,
|
|
207
|
+
"onUpdate:value": t[0] ||= (e) => L.value.name = e,
|
|
208
|
+
placeholder: "请填写数据源名称",
|
|
209
|
+
"allow-clear": ""
|
|
210
|
+
}, null, 8, ["value"])]),
|
|
211
|
+
_: 1
|
|
212
|
+
}, 8, ["rules"])]),
|
|
213
|
+
_: 1
|
|
214
|
+
}),
|
|
215
|
+
f(s, { span: 12 }, {
|
|
216
|
+
default: x(() => [f(i, {
|
|
217
|
+
label: "数据源类型",
|
|
218
|
+
name: "source_type",
|
|
219
|
+
rules: R.source_type
|
|
220
|
+
}, {
|
|
221
|
+
default: x(() => [f(m, {
|
|
222
|
+
value: L.value.source_type,
|
|
223
|
+
"onUpdate:value": t[1] ||= (e) => L.value.source_type = e,
|
|
224
|
+
placeholder: "请选择",
|
|
225
|
+
onChange: z
|
|
226
|
+
}, {
|
|
227
|
+
default: x(() => [(h(), u(o, null, v(M, (e) => f(p, {
|
|
228
|
+
key: e.value,
|
|
229
|
+
value: e.value
|
|
230
|
+
}, {
|
|
231
|
+
default: x(() => [d(b(e.label), 1)]),
|
|
232
|
+
_: 2
|
|
233
|
+
}, 1032, ["value"])), 64))]),
|
|
234
|
+
_: 1
|
|
235
|
+
}, 8, ["value"])]),
|
|
236
|
+
_: 1
|
|
237
|
+
}, 8, ["rules"])]),
|
|
238
|
+
_: 1
|
|
239
|
+
}),
|
|
240
|
+
L.value.source_type === "db" ? (h(), c(s, {
|
|
241
|
+
key: 0,
|
|
242
|
+
span: 12
|
|
243
|
+
}, {
|
|
244
|
+
default: x(() => [f(i, {
|
|
245
|
+
label: "数据库类型",
|
|
246
|
+
name: "db_type",
|
|
247
|
+
rules: R.db_type
|
|
248
|
+
}, {
|
|
249
|
+
default: x(() => [f(m, {
|
|
250
|
+
value: L.value.db_type,
|
|
251
|
+
"onUpdate:value": t[2] ||= (e) => L.value.db_type = e,
|
|
252
|
+
placeholder: "请选择"
|
|
253
|
+
}, {
|
|
254
|
+
default: x(() => [(h(), u(o, null, v(N, (e) => f(p, {
|
|
255
|
+
key: e.value,
|
|
256
|
+
value: e.value
|
|
257
|
+
}, {
|
|
258
|
+
default: x(() => [d(b(e.label), 1)]),
|
|
259
|
+
_: 2
|
|
260
|
+
}, 1032, ["value"])), 64))]),
|
|
261
|
+
_: 1
|
|
262
|
+
}, 8, ["value"])]),
|
|
263
|
+
_: 1
|
|
264
|
+
}, 8, ["rules"])]),
|
|
265
|
+
_: 1
|
|
266
|
+
})) : l("", !0)
|
|
267
|
+
]),
|
|
268
|
+
_: 1
|
|
269
|
+
}),
|
|
270
|
+
L.value.source_type === "db" ? (h(), u(o, { key: 0 }, [
|
|
271
|
+
f(n, { orientation: "left" }, {
|
|
272
|
+
default: x(() => t[13] ||= [d("数据库连接信息")]),
|
|
273
|
+
_: 1
|
|
274
|
+
}),
|
|
275
|
+
f(g, { gutter: 16 }, {
|
|
276
|
+
default: x(() => [
|
|
277
|
+
f(s, { span: 12 }, {
|
|
278
|
+
default: x(() => [f(i, {
|
|
279
|
+
label: "数据库主机",
|
|
280
|
+
name: "db_host",
|
|
281
|
+
rules: R.db_host
|
|
282
|
+
}, {
|
|
283
|
+
default: x(() => [f(r, {
|
|
284
|
+
value: L.value.db_host,
|
|
285
|
+
"onUpdate:value": t[3] ||= (e) => L.value.db_host = e,
|
|
286
|
+
placeholder: "如 127.0.0.1",
|
|
287
|
+
"allow-clear": ""
|
|
288
|
+
}, null, 8, ["value"])]),
|
|
289
|
+
_: 1
|
|
290
|
+
}, 8, ["rules"])]),
|
|
291
|
+
_: 1
|
|
292
|
+
}),
|
|
293
|
+
f(s, { span: 12 }, {
|
|
294
|
+
default: x(() => [f(i, {
|
|
295
|
+
label: "数据库端口",
|
|
296
|
+
name: "db_port",
|
|
297
|
+
rules: R.db_port
|
|
298
|
+
}, {
|
|
299
|
+
default: x(() => [f(_, {
|
|
300
|
+
value: L.value.db_port,
|
|
301
|
+
"onUpdate:value": t[4] ||= (e) => L.value.db_port = e,
|
|
302
|
+
style: { width: "100%" },
|
|
303
|
+
min: 1,
|
|
304
|
+
max: 65535,
|
|
305
|
+
placeholder: "如 3306"
|
|
306
|
+
}, null, 8, ["value"])]),
|
|
307
|
+
_: 1
|
|
308
|
+
}, 8, ["rules"])]),
|
|
309
|
+
_: 1
|
|
310
|
+
}),
|
|
311
|
+
f(s, { span: 12 }, {
|
|
312
|
+
default: x(() => [f(i, {
|
|
313
|
+
label: "数据库用户",
|
|
314
|
+
name: "db_user",
|
|
315
|
+
rules: R.db_user
|
|
316
|
+
}, {
|
|
317
|
+
default: x(() => [f(r, {
|
|
318
|
+
value: L.value.db_user,
|
|
319
|
+
"onUpdate:value": t[5] ||= (e) => L.value.db_user = e,
|
|
320
|
+
placeholder: "如 root",
|
|
321
|
+
"allow-clear": ""
|
|
322
|
+
}, null, 8, ["value"])]),
|
|
323
|
+
_: 1
|
|
324
|
+
}, 8, ["rules"])]),
|
|
325
|
+
_: 1
|
|
326
|
+
}),
|
|
327
|
+
f(s, { span: 12 }, {
|
|
328
|
+
default: x(() => [f(i, {
|
|
329
|
+
label: "数据库密码",
|
|
330
|
+
name: "db_password"
|
|
331
|
+
}, {
|
|
332
|
+
default: x(() => [f(S, {
|
|
333
|
+
value: L.value.db_password,
|
|
334
|
+
"onUpdate:value": t[6] ||= (e) => L.value.db_password = e,
|
|
335
|
+
placeholder: "修改时留空则不修改密码",
|
|
336
|
+
"allow-clear": "",
|
|
337
|
+
autocomplete: "new-password"
|
|
338
|
+
}, null, 8, ["value"])]),
|
|
339
|
+
_: 1
|
|
340
|
+
})]),
|
|
341
|
+
_: 1
|
|
342
|
+
}),
|
|
343
|
+
f(s, { span: 12 }, {
|
|
344
|
+
default: x(() => [f(i, {
|
|
345
|
+
label: A.value,
|
|
346
|
+
name: "db_name",
|
|
347
|
+
rules: R.db_name
|
|
348
|
+
}, {
|
|
349
|
+
default: x(() => [f(r, {
|
|
350
|
+
value: L.value.db_name,
|
|
351
|
+
"onUpdate:value": t[7] ||= (e) => L.value.db_name = e,
|
|
352
|
+
placeholder: "如 my_db",
|
|
353
|
+
"allow-clear": ""
|
|
354
|
+
}, null, 8, ["value"])]),
|
|
355
|
+
_: 1
|
|
356
|
+
}, 8, ["label", "rules"])]),
|
|
357
|
+
_: 1
|
|
358
|
+
}),
|
|
359
|
+
L.value.db_type == "oracle" ? (h(), c(s, {
|
|
360
|
+
key: 0,
|
|
361
|
+
span: 12
|
|
362
|
+
}, {
|
|
363
|
+
default: x(() => [f(i, { label: "默认Schema" }, {
|
|
364
|
+
default: x(() => [f(r, {
|
|
365
|
+
value: j.value,
|
|
366
|
+
"onUpdate:value": t[8] ||= (e) => j.value = e,
|
|
367
|
+
"allow-clear": ""
|
|
368
|
+
}, null, 8, ["value"])]),
|
|
369
|
+
_: 1
|
|
370
|
+
})]),
|
|
371
|
+
_: 1
|
|
372
|
+
})) : l("", !0)
|
|
373
|
+
]),
|
|
374
|
+
_: 1
|
|
375
|
+
}),
|
|
376
|
+
f(i, {
|
|
377
|
+
label: "数据库选项",
|
|
378
|
+
name: "db_options"
|
|
379
|
+
}, {
|
|
380
|
+
default: x(() => [f(a, {
|
|
381
|
+
value: L.value.db_options,
|
|
382
|
+
"onUpdate:value": t[9] ||= (e) => L.value.db_options = e,
|
|
383
|
+
placeholder: "可选,JSON 对象,如 {\"charset\":\"utf8mb4\"}"
|
|
384
|
+
}, null, 8, ["value"])]),
|
|
385
|
+
_: 1
|
|
386
|
+
})
|
|
387
|
+
], 64)) : L.value.source_type === "custom" ? (h(), u(o, { key: 1 }, [
|
|
388
|
+
f(n, { orientation: "left" }, {
|
|
389
|
+
default: x(() => t[14] ||= [d("自定义采集")]),
|
|
390
|
+
_: 1
|
|
391
|
+
}),
|
|
392
|
+
f(g, { gutter: 16 }, {
|
|
393
|
+
default: x(() => [f(s, { span: 12 }, {
|
|
394
|
+
default: x(() => [f(i, {
|
|
395
|
+
label: "自定义采集函数名称",
|
|
396
|
+
name: "custom_func",
|
|
397
|
+
rules: R.custom_func
|
|
398
|
+
}, {
|
|
399
|
+
default: x(() => [f(m, {
|
|
400
|
+
value: L.value.custom_func,
|
|
401
|
+
"onUpdate:value": t[10] ||= (e) => L.value.custom_func = e,
|
|
402
|
+
placeholder: "请选择采集函数",
|
|
403
|
+
options: P.value,
|
|
404
|
+
"option-filter-prop": "label",
|
|
405
|
+
"show-search": "",
|
|
406
|
+
"allow-clear": "",
|
|
407
|
+
loading: F.value
|
|
408
|
+
}, null, 8, [
|
|
409
|
+
"value",
|
|
410
|
+
"options",
|
|
411
|
+
"loading"
|
|
412
|
+
])]),
|
|
413
|
+
_: 1
|
|
414
|
+
}, 8, ["rules"])]),
|
|
415
|
+
_: 1
|
|
416
|
+
})]),
|
|
417
|
+
_: 1
|
|
418
|
+
}),
|
|
419
|
+
f(i, {
|
|
420
|
+
label: "自定义采集函数参数(JSON)",
|
|
421
|
+
name: "custom_func_kwargs"
|
|
422
|
+
}, {
|
|
423
|
+
default: x(() => [f(a, {
|
|
424
|
+
value: L.value.custom_func_kwargs,
|
|
425
|
+
"onUpdate:value": t[11] ||= (e) => L.value.custom_func_kwargs = e
|
|
426
|
+
}, null, 8, ["value"])]),
|
|
427
|
+
_: 1
|
|
428
|
+
})
|
|
429
|
+
], 64)) : l("", !0)
|
|
430
|
+
]),
|
|
431
|
+
_: 1
|
|
432
|
+
}, 8, ["model"])]),
|
|
433
|
+
_: 1
|
|
434
|
+
}, 8, [
|
|
435
|
+
"title",
|
|
436
|
+
"open",
|
|
437
|
+
"confirm-loading"
|
|
438
|
+
]);
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
}), [["__scopeId", "data-v-02b9ac99"]]);
|
|
442
|
+
//#endregion
|
|
443
|
+
export { w as default };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syncDataSourceConfig-BXAolK4f.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=\"db_name_field_lable\"\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-col\n :span=\"12\"\n v-if=\"model.db_type == 'oracle'\"\n >\n <a-form-item label=\"默认Schema\">\n <a-input\n v-model:value=\"oracle_schema\"\n allow-clear\n />\n </a-form-item>\n </a-col>\n </a-row>\n <a-form-item\n label=\"数据库选项\"\n name=\"db_options\"\n >\n <JsonStr\n v-model:value=\"model.db_options\"\n placeholder='可选,JSON 对象,如 {\"charset\":\"utf8mb4\"}'\n />\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 <JsonStr v-model:value=\"model.custom_func_kwargs\" />\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 { computed, 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';\nimport JsonStr from 'liyu-pc-base/components/FormRender/JsonStr/index.vue';\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;\nconst db_name_field_lable = computed(() => {\n return model.value.db_type === 'oracle' ? 'SID/服务名' : '数据库名称';\n});\nconst oracle_schema = computed({\n get: () => {\n if (model.value.db_options?.schema) {\n return model.value.db_options?.schema;\n }\n return '';\n },\n set: val => {\n if (typeof model.value.db_options === 'object') {\n if (val) {\n model.value.db_options.schema = val;\n } else {\n delete model.value.db_options.schema;\n }\n } else {\n if (val) {\n model.value.db_options = { schema: val };\n }\n }\n },\n});\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 { value: 'oracle', label: 'Oracle' },\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: {},\n custom_func: undefined,\n custom_func_kwargs: {},\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 = {};\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 = {};\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;\n payload.custom_func_kwargs = {};\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 ['db_type', 'db_host', 'db_port', 'db_user', 'db_password', 'db_name', 'db_options'].forEach(\n k => delete payload[k],\n );\n payload.db_options = {};\n payload.custom_func_kwargs = parseJsonField(payload.custom_func_kwargs, '自定义采集函数参数');\n delete payload.custom_func_kwargs;\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 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 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: record.db_options,\n custom_func: record.custom_func || undefined,\n custom_func_kwargs: record.custom_func_kwargs,\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=\"db_name_field_lable\"\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-col\n :span=\"12\"\n v-if=\"model.db_type == 'oracle'\"\n >\n <a-form-item label=\"默认Schema\">\n <a-input\n v-model:value=\"oracle_schema\"\n allow-clear\n />\n </a-form-item>\n </a-col>\n </a-row>\n <a-form-item\n label=\"数据库选项\"\n name=\"db_options\"\n >\n <JsonStr\n v-model:value=\"model.db_options\"\n placeholder='可选,JSON 对象,如 {\"charset\":\"utf8mb4\"}'\n />\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 <JsonStr v-model:value=\"model.custom_func_kwargs\" />\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 { computed, 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';\nimport JsonStr from 'liyu-pc-base/components/FormRender/JsonStr/index.vue';\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;\nconst db_name_field_lable = computed(() => {\n return model.value.db_type === 'oracle' ? 'SID/服务名' : '数据库名称';\n});\nconst oracle_schema = computed({\n get: () => {\n if (model.value.db_options?.schema) {\n return model.value.db_options?.schema;\n }\n return '';\n },\n set: val => {\n if (typeof model.value.db_options === 'object') {\n if (val) {\n model.value.db_options.schema = val;\n } else {\n delete model.value.db_options.schema;\n }\n } else {\n if (val) {\n model.value.db_options = { schema: val };\n }\n }\n },\n});\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 { value: 'oracle', label: 'Oracle' },\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: {},\n custom_func: undefined,\n custom_func_kwargs: {},\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 = {};\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 = {};\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;\n payload.custom_func_kwargs = {};\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 ['db_type', 'db_host', 'db_port', 'db_user', 'db_password', 'db_name', 'db_options'].forEach(\n k => delete payload[k],\n );\n payload.db_options = {};\n payload.custom_func_kwargs = parseJsonField(payload.custom_func_kwargs, '自定义采集函数参数');\n delete payload.custom_func_kwargs;\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 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 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: record.db_options,\n custom_func: record.custom_func || undefined,\n custom_func_kwargs: record.custom_func_kwargs,\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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"}
|