Skip to content

Commit 5e44c2d

Browse files
committed
🐛 修复数据源表单遗漏密码字段提交的问题
1 parent a10faa4 commit 5e44c2d

File tree

8 files changed

+420
-402
lines changed

8 files changed

+420
-402
lines changed

ballcat-codegen-frontend/components.d.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ declare module 'vue' {
4141
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
4242
AResult: typeof import('ant-design-vue/es')['Result']
4343
ARow: typeof import('ant-design-vue/es')['Row']
44-
ArrowsAltOutlined: typeof import('@ant-design/icons-vue')['ArrowsAltOutlined']
4544
ASelect: typeof import('ant-design-vue/es')['Select']
4645
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
4746
ASkeleton: typeof import('ant-design-vue/es')['Skeleton']
@@ -57,22 +56,14 @@ declare module 'vue' {
5756
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
5857
ATypographyText: typeof import('ant-design-vue/es')['TypographyText']
5958
AUpload: typeof import('ant-design-vue/es')['Upload']
60-
ClusterOutlined: typeof import('@ant-design/icons-vue')['ClusterOutlined']
6159
CropperModal: typeof import('./src/components/cropper-modal/index.vue')['default']
62-
FileTextOutlined: typeof import('@ant-design/icons-vue')['FileTextOutlined']
63-
FullscreenExitOutlined: typeof import('@ant-design/icons-vue')['FullscreenExitOutlined']
64-
FullscreenOutlined: typeof import('@ant-design/icons-vue')['FullscreenOutlined']
6560
Icon: typeof import('./src/components/Icon/index.vue')['default']
6661
ImportButton: typeof import('./src/components/button/ImportButton.vue')['default']
67-
LeftOutlined: typeof import('@ant-design/icons-vue')['LeftOutlined']
6862
MenuItemContent: typeof import('./src/components/menu/MenuItemContent.vue')['default']
6963
PageBreadcrumb: typeof import('./src/components/breadcrumb/PageBreadcrumb.vue')['default']
70-
PlusOutlined: typeof import('@ant-design/icons-vue')['PlusOutlined']
71-
RightOutlined: typeof import('@ant-design/icons-vue')['RightOutlined']
7264
RouterLink: typeof import('vue-router')['RouterLink']
7365
RouterMenu: typeof import('./src/components/menu/RouterMenu.vue')['default']
7466
RouterView: typeof import('vue-router')['RouterView']
75-
ShrinkOutlined: typeof import('@ant-design/icons-vue')['ShrinkOutlined']
7667
SubMenu: typeof import('./src/components/menu/SubMenu.vue')['default']
7768
}
7869
}

ballcat-codegen-frontend/src/api/gen/datasource-config/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ export interface DataSourceConfig {
2020
dsKey?: string
2121
// 用户名
2222
username?: string
23+
// 提交表单时的密码参数
24+
pass?: string
2325
// 密码
2426
password?: string
2527
// 数据源连接

ballcat-codegen-frontend/src/styles/components.less

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@
367367
box-shadow: @shadow-xs-05;
368368

369369
svg {
370-
margin-right: 4px;
370+
margin-right: 0px;
371371
width: 16px;
372372
height: 16px;
373373
}
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
// Reusable JDBC URL parser and helpers
2+
3+
export type JdbcVendor = 'MySQL' | 'PostgreSQL' | 'SQLServer' | 'Oracle' | 'SQLite' | 'H2' | 'Other'
4+
5+
export interface JdbcHost { host: string; port?: number }
6+
7+
export interface JdbcParsed {
8+
vendor: JdbcVendor
9+
hosts: JdbcHost[]
10+
database?: string
11+
params: Record<string, string>
12+
raw: string
13+
}
14+
15+
export function getDefaultPort(vendor: JdbcVendor): number | undefined {
16+
switch (vendor) {
17+
case 'MySQL': return 3306
18+
case 'PostgreSQL': return 5432
19+
case 'SQLServer': return 1433
20+
case 'Oracle': return 1521
21+
default: return undefined
22+
}
23+
}
24+
25+
function parseKv(str: string, sep: RegExp = /[&;]/): Record<string, string> {
26+
const out: Record<string, string> = {}
27+
if (!str) return out
28+
str.split(sep).forEach(pair => {
29+
if (!pair) return
30+
const i = pair.indexOf('=')
31+
if (i === -1) {
32+
const k = pair.trim()
33+
if (k) out[k] = ''
34+
return
35+
}
36+
const k = pair.slice(0, i).trim()
37+
const v = pair.slice(i + 1).trim()
38+
if (k) out[k] = v
39+
})
40+
return out
41+
}
42+
43+
function parseHostPort(token: string): JdbcHost {
44+
// IPv6: [fe80::1]:5432
45+
const ipv6 = token.match(/^\[([^\]]+)\](?::(\d+))?$/)
46+
if (ipv6) {
47+
return { host: `[${ipv6[1]}]`, port: ipv6[2] ? Number(ipv6[2]) : undefined }
48+
}
49+
const idx = token.lastIndexOf(':')
50+
if (idx > -1 && token.indexOf(':') === idx) {
51+
const host = token.slice(0, idx)
52+
const port = Number(token.slice(idx + 1))
53+
return isNaN(port) ? { host: token } : { host, port }
54+
}
55+
return { host: token }
56+
}
57+
58+
export function parseJdbcUrl(url?: string): JdbcParsed {
59+
const raw = url ?? ''
60+
if (!raw) return { vendor: 'Other', hosts: [], database: undefined, params: {}, raw }
61+
62+
// MySQL / PostgreSQL
63+
let m = raw.match(/^jdbc:(mysql|postgresql):\/\/([^\/]+)\/([^?;]+)(?:[?;](.*))?$/i)
64+
if (m) {
65+
const vendor: JdbcVendor = m[1].toLowerCase() === 'mysql' ? 'MySQL' : 'PostgreSQL'
66+
const hosts = m[2].split(',').map(h => parseHostPort(h.trim())).filter(Boolean)
67+
const database = decodeURIComponent(m[3])
68+
const params = parseKv(m[4] || '')
69+
const def = getDefaultPort(vendor)
70+
hosts.forEach(h => { if (!h.port && def) h.port = def })
71+
return { vendor, hosts, database, params, raw }
72+
}
73+
74+
// SQLServer
75+
m = raw.match(/^jdbc:sqlserver:\/\/([^;]+)(?:;(.*))?$/i)
76+
if (m) {
77+
const host = parseHostPort(m[1].trim())
78+
const params = parseKv(m[2] || '', /[;]+/)
79+
const database = params.databaseName || params['database'] || undefined
80+
if (!host.port) host.port = getDefaultPort('SQLServer')
81+
return { vendor: 'SQLServer', hosts: [host], database, params, raw }
82+
}
83+
84+
// Oracle Thin (SID)
85+
m = raw.match(/^jdbc:oracle:thin:@([^:\/]+)(?::(\d+))?:(.+)$/i)
86+
if (m) {
87+
const host = { host: m[1], port: m[2] ? Number(m[2]) : getDefaultPort('Oracle') }
88+
const database = m[3]
89+
return { vendor: 'Oracle', hosts: [host], database, params: {}, raw }
90+
}
91+
// Oracle Thin (Service)
92+
m = raw.match(/^jdbc:oracle:thin:@\/\/([^\/:]+)(?::(\d+))?\/(.+)$/i)
93+
if (m) {
94+
const host = { host: m[1], port: m[2] ? Number(m[2]) : getDefaultPort('Oracle') }
95+
const database = m[3]
96+
return { vendor: 'Oracle', hosts: [host], database, params: {}, raw }
97+
}
98+
99+
// SQLite
100+
m = raw.match(/^jdbc:sqlite:(.+)$/i)
101+
if (m) {
102+
return { vendor: 'SQLite', hosts: [], database: m[1], params: {}, raw }
103+
}
104+
105+
// H2
106+
m = raw.match(/^jdbc:h2:(mem|file):(.+)$/i)
107+
if (m) {
108+
return { vendor: 'H2', hosts: [], database: `${m[1]}:${m[2]}`, params: {}, raw }
109+
}
110+
111+
return { vendor: 'Other', hosts: [], database: undefined, params: {}, raw }
112+
}
113+
114+
export function getJdbcSummary(url?: string): string {
115+
const p = parseJdbcUrl(url)
116+
const v = p.vendor
117+
if (v === 'SQLite' || v === 'H2') {
118+
return p.database ? `${v} · ${p.database}` : v
119+
}
120+
if (p.hosts.length) {
121+
const first = p.hosts[0]
122+
const hostPort = `${first.host}${first.port ? `:${first.port}` : ''}`
123+
const multi = p.hosts.length > 1 ? ' 等' : ''
124+
const db = p.database ? ` · ${p.database}` : ''
125+
return `${v} · ${hostPort}${multi}${db}`
126+
}
127+
return p.raw || ''
128+
}
129+
130+
export function getJdbcTooltip(url?: string): string {
131+
const p = parseJdbcUrl(url)
132+
const parts: string[] = []
133+
parts.push(`类型:${p.vendor}`)
134+
if (p.hosts.length) {
135+
parts.push(`主机:${p.hosts.map(h => `${h.host}${h.port ? `:${h.port}` : ''}`).join(', ')}`)
136+
}
137+
if (p.database) parts.push(`库名:${p.database}`)
138+
const paramKeys = Object.keys(p.params || {})
139+
if (paramKeys.length) parts.push(`参数:${paramKeys.length} 项`)
140+
parts.push(`完整:${p.raw}`)
141+
return parts.join('\n')
142+
}
143+
144+
export function hasSsl(url?: string): boolean {
145+
const p = parseJdbcUrl(url)
146+
const lower: Record<string, string> = {}
147+
Object.keys(p.params).forEach(k => {
148+
lower[k.toLowerCase()] = (p.params[k] ?? '').toString().toLowerCase()
149+
})
150+
if ('usessl' in lower) return lower['usessl'] === 'true'
151+
if ('ssl' in lower) return lower['ssl'] === 'true'
152+
if ('sslmode' in lower) return !!lower['sslmode'] && lower['sslmode'] !== 'disable'
153+
if ('encrypt' in lower) return lower['encrypt'] === 'true'
154+
return false
155+
}

ballcat-codegen-frontend/src/views/gen/datasource-config/DataSourceConfigEditModal.vue

Lines changed: 0 additions & 161 deletions
This file was deleted.

0 commit comments

Comments
 (0)