优化: Settings 前端(Provider 模型表格化手动标注 + 布局重构 + 连接密码字段)

This commit is contained in:
lxy
2026-08-08 14:19:49 +08:00
parent b408b2d7a1
commit 92903702e2
6 changed files with 424 additions and 75 deletions
+42 -13
View File
@@ -43,25 +43,32 @@
</div>
<div class="form-field">
<label class="form-label">{{ $t('settings.labelType') }}</label>
<select v-model="connForm.type" class="setting-select">
<select v-model="connForm.type" class="setting-select" @change="onTypeChange">
<option value="mysql">MySQL</option>
<option value="ssh">SSH</option>
<option value="redis">Redis</option>
<option value="mongo">MongoDB</option>
</select>
</div>
<div class="form-field">
<label class="form-label">{{ $t('settings.labelHost') }}</label>
<input v-model="connForm.host" class="setting-input" :placeholder="$t('settings.phHost')" />
</div>
<div class="form-field">
<label class="form-label">{{ $t('settings.labelPort') }}</label>
<input v-model.number="connForm.port" class="setting-input" type="number" min="1" max="65535" :placeholder="$t('settings.phPort')" />
<!-- host + port 同一行(端口跟在 host 后面,符合 host:port 地址习惯) -->
<div class="form-row">
<div class="form-field form-field--host">
<label class="form-label">{{ $t('settings.labelHost') }}</label>
<input v-model="connForm.host" class="setting-input" :placeholder="$t('settings.phHost')" />
</div>
<div class="form-field form-field--port">
<label class="form-label">{{ $t('settings.labelPort') }}</label>
<input v-model.number="connForm.port" class="setting-number" type="number" min="1" max="65535" :placeholder="$t('settings.phPort')" />
</div>
</div>
<div class="form-field">
<label class="form-label">{{ $t('settings.labelUser') }}</label>
<input v-model="connForm.user" class="setting-input" :placeholder="$t('settings.phUser')" />
</div>
<div class="form-field">
<label class="form-label">{{ $t('settings.labelPassword') }}</label>
<input v-model="connForm.password" class="setting-input" type="password" :placeholder="$t('settings.phPassword')" autocomplete="new-password" />
</div>
<div class="form-actions">
<button class="btn btn-primary" :disabled="submitting" @click="saveConn">{{ $t('common.save') }}</button>
</div>
@@ -96,18 +103,23 @@ interface ConnRecord {
host: string
port: number
user: string
password: string
}
const connections = ref<ConnRecord[]>([])
// 各类型连接的默认端口(用户切换类型时自动带入,单一来源)
const DEFAULT_PORTS: Record<string, number> = { mysql: 3306, ssh: 22, redis: 6379, mongo: 27017 }
const connForm = reactive({
visible: false,
editId: '' as string,
name: '',
type: 'mysql',
host: '',
port: 3306,
port: DEFAULT_PORTS.mysql,
user: '',
password: '',
})
// 异步操作禁用态(防双击重复提交):saveConn 保存连接期间禁用按钮
@@ -142,17 +154,25 @@ function openConnForm(conn?: ConnRecord) {
connForm.host = conn.host
connForm.port = conn.port
connForm.user = conn.user
connForm.password = conn.password ?? ''
} else {
connForm.editId = ''
connForm.name = ''
connForm.type = 'mysql'
connForm.host = ''
connForm.port = 3306
connForm.port = DEFAULT_PORTS[connForm.type] ?? 3306
connForm.user = ''
connForm.password = ''
}
connForm.visible = true
}
/** 用户手动切换连接类型时,端口自动重置为该类型默认端口。
* 用 @change(仅用户交互触发)而非 watch:避免编辑已有连接回填类型时误覆盖已存端口。 */
function onTypeChange(): void {
connForm.port = DEFAULT_PORTS[connForm.type] ?? 3306
}
function saveConn() {
if (!connForm.name || !connForm.host) {
emit('toast', t('settings.toastConnIncomplete'), 'warning')
@@ -173,6 +193,7 @@ function saveConn() {
host: connForm.host,
port: connForm.port,
user: connForm.user,
password: connForm.password,
}
if (connForm.editId) {
const idx = connections.value.findIndex(c => c.id === connForm.editId)
@@ -269,10 +290,18 @@ onMounted(loadConnections)
/* 表单(本面板特有输入控件样式;.setting-select 走全局) */
.form-grid { display: flex; flex-direction: column; gap: 14px; }
.form-field { display: flex; flex-direction: column; gap: 4px; }
.form-label { font-size: 12px; font-weight: 500; color: var(--df-text-secondary); }
.form-field { display: flex; flex-direction: row; align-items: center; gap: 10px; }
.form-label { flex: 0 0 44px; font-size: 12px; font-weight: 500; color: var(--df-text-secondary); text-align: right; }
.form-actions { display: flex; justify-content: flex-end; padding-top: 4px; }
.setting-input { padding: 6px 12px; background: var(--df-bg); border: 0.5px solid var(--df-border); border-radius: var(--df-radius-sm); color: var(--df-text); font-size: 13px; outline: none; min-width: 260px; }
.setting-input { flex: 1; min-width: 0; padding: 6px 12px; background: var(--df-bg); border: 0.5px solid var(--df-border); border-radius: var(--df-radius-sm); color: var(--df-text); font-size: 13px; outline: none; }
.setting-input:focus { border-color: var(--df-accent); }
.form-field .setting-select { flex: 1; min-width: 0; }
/* host+port 组合行(端口跟在 host 后;min-width:0 允许收缩防窄面板溢出,label 已缩窄控制距离) */
.form-row { display: flex; gap: 6px; }
.form-row .form-field { min-width: 0; }
.form-row .form-field--host { flex: 3; }
.form-row .form-field--port { flex: 2; }
/* port 数字框复用 .setting-number(隐藏原生箭头);在 form-row 内覆盖 flex 填满列宽 */
.form-row .setting-number { flex: 1; min-width: 0; }
</style>