import type { FormRules } from 'element-plus'; import { computed, reactive, ref, watch } from 'vue'; import { mergeConfigJsonBySourceType, sourceConnectionDefaults, sourceTypeLabels, } from './datacenter-constants'; export function useSourceForm() { const lastGeneratedJdbcUrl = ref(''); const lastGeneratedDriverClassName = ref(''); const form = reactive>({ id: undefined, sourceName: '', sourceCode: '', sourceType: 'MYSQL', accessMode: 'READ_ONLY', driverClassName: '', jdbcUrl: '', host: '', port: undefined, databaseName: '', schemaName: '', username: '', password: '', builtinFlag: 0, configJson: {}, }); const rules: FormRules = { sourceName: [ { required: true, message: '请输入连接名称', trigger: 'blur' }, ], sourceType: [ { required: true, message: '请选择连接类型', trigger: 'change' }, ], databaseName: [ { trigger: ['blur', 'change'], validator: (_rule, value, callback) => { if (!sourceConnectionDefaults[form.sourceType]) { callback(); return; } if (String(value || '').trim()) { callback(); return; } callback(new Error('请输入库名')); }, }, ], }; const selectedTypeDefaults = computed( () => sourceConnectionDefaults[form.sourceType] || null, ); const supportsExternalConnection = computed(() => Boolean(selectedTypeDefaults.value), ); const connectionTypeLabel = computed(() => form.sourceType ? sourceTypeLabels[form.sourceType] || form.sourceType : '', ); const connectionHelpText = computed(() => { if (form.sourceType === 'EXCEL') { return 'Excel 连接只需要名称,文件导入后会自动生成表。'; } if (!supportsExternalConnection.value) { return '系统内置连接由平台自动维护,无需填写地址。'; } return `填写主机、库名和账号即可,端口与连接地址会按 ${connectionTypeLabel.value} 自动补全。`; }); function generateJdbcUrl(payload: Record) { return ( sourceConnectionDefaults[payload.sourceType]?.buildJdbcUrl(payload) || '' ); } function syncGeneratedJdbcUrl(force = false) { const generated = generateJdbcUrl(form); if (!generated) { if ( force || !form.jdbcUrl || form.jdbcUrl === lastGeneratedJdbcUrl.value ) { form.jdbcUrl = ''; } lastGeneratedJdbcUrl.value = ''; return; } if ( force || !form.jdbcUrl || form.jdbcUrl === lastGeneratedJdbcUrl.value ) { form.jdbcUrl = generated; lastGeneratedJdbcUrl.value = generated; } else if (form.jdbcUrl === generated) { lastGeneratedJdbcUrl.value = generated; } } function applySourceTypeDefaults(force = false) { const defaults = selectedTypeDefaults.value; form.configJson = mergeConfigJsonBySourceType( form.sourceType, form.configJson, ); if (!defaults) { if (force) { form.port = undefined; form.driverClassName = ''; form.jdbcUrl = ''; lastGeneratedDriverClassName.value = ''; lastGeneratedJdbcUrl.value = ''; } return; } if (force || !form.port) { form.port = defaults.defaultPort; } if ( force || !form.driverClassName || form.driverClassName === lastGeneratedDriverClassName.value ) { form.driverClassName = defaults.defaultDriver; lastGeneratedDriverClassName.value = defaults.defaultDriver; } syncGeneratedJdbcUrl(force); } function resetForm(row?: any) { form.id = row?.id; form.sourceName = row?.sourceName || ''; form.sourceCode = row?.sourceCode || ''; form.sourceType = row?.sourceType || 'MYSQL'; form.accessMode = row?.accessMode || 'READ_ONLY'; form.driverClassName = row?.driverClassName || ''; form.jdbcUrl = row?.jdbcUrl || ''; form.host = row?.host || ''; form.port = row?.port; form.databaseName = row?.databaseName || ''; form.schemaName = row?.schemaName || ''; form.username = row?.username || ''; form.password = ''; form.builtinFlag = row?.builtinFlag || 0; form.configJson = mergeConfigJsonBySourceType( form.sourceType, row?.configJson || {}, ); lastGeneratedDriverClassName.value = ''; lastGeneratedJdbcUrl.value = ''; applySourceTypeDefaults(false); } watch( () => form.sourceType, () => applySourceTypeDefaults(true), ); watch( () => [ form.host, form.port, form.databaseName, form.configJson?.informixServer, form.configJson?.serviceName, ], () => syncGeneratedJdbcUrl(false), ); return { form, rules, supportsExternalConnection, connectionHelpText, resetForm, }; }