Add files via upload

This commit is contained in:
公明
2026-03-25 19:49:14 +08:00
committed by GitHub
parent 80de8cf748
commit cce64e213f
3 changed files with 149 additions and 43 deletions
+74 -25
View File
@@ -10359,54 +10359,93 @@ header {
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
} }
.webshell-db-profile-modal-content {
max-width: 840px;
border-radius: 12px;
border: 1px solid rgba(15, 23, 42, 0.1);
box-shadow: 0 10px 30px rgba(2, 6, 23, 0.18);
}
#webshell-db-profile-modal .modal-header {
padding: 14px 18px;
border-bottom: 1px solid rgba(15, 23, 42, 0.08);
background: #fff;
box-shadow: none;
}
#webshell-db-profile-modal .modal-header h2 {
font-size: 1.08rem;
font-weight: 600;
background: none;
-webkit-text-fill-color: currentColor;
color: #0f172a;
}
#webshell-db-profile-modal .modal-body {
padding: 14px 18px 10px;
}
#webshell-db-profile-modal .modal-footer {
padding: 10px 18px 14px;
border-top: 1px solid rgba(15, 23, 42, 0.08);
background: #fff;
}
#webshell-db-profile-modal .modal-footer .btn-secondary,
#webshell-db-profile-modal .modal-footer .btn-primary {
min-width: 78px;
height: 36px;
border-radius: 8px;
}
.webshell-db-toolbar { .webshell-db-toolbar {
display: grid; display: grid;
grid-template-columns: repeat(4, minmax(160px, 1fr)); grid-template-columns: repeat(4, minmax(130px, 1fr));
gap: 12px; gap: 10px;
padding: 14px; padding: 12px;
border: 1px solid rgba(15, 23, 42, 0.08); border: 1px solid rgba(15, 23, 42, 0.08);
border-radius: 12px; border-radius: 10px;
background: linear-gradient(180deg, rgba(255, 255, 255, 0.98) 0%, rgba(248, 250, 252, 0.96) 100%); background: #f8fafc;
box-shadow: 0 6px 20px rgba(15, 23, 42, 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.9); box-shadow: none;
} }
.webshell-db-toolbar label { .webshell-db-toolbar label {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 6px; gap: 5px;
min-width: 0; min-width: 0;
padding: 8px 10px; padding: 7px 9px;
border-radius: 10px; border-radius: 8px;
background: rgba(255, 255, 255, 0.82); background: #fff;
border: 1px solid rgba(15, 23, 42, 0.08); border: 1px solid rgba(15, 23, 42, 0.08);
transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease; transition: border-color 0.2s ease, box-shadow 0.2s ease;
} }
.webshell-db-toolbar label:focus-within { .webshell-db-toolbar label:focus-within {
border-color: rgba(0, 102, 255, 0.38); border-color: rgba(0, 102, 255, 0.32);
box-shadow: 0 0 0 2px rgba(0, 102, 255, 0.12); box-shadow: 0 0 0 2px rgba(0, 102, 255, 0.1);
transform: translateY(-1px);
} }
.webshell-db-toolbar label span { .webshell-db-toolbar label span {
font-size: 0.75rem; font-size: 0.72rem;
color: var(--text-secondary); color: #64748b;
font-weight: 600; font-weight: 600;
letter-spacing: 0.03em; letter-spacing: 0.01em;
text-transform: uppercase; text-transform: none;
} }
.webshell-db-toolbar .form-control { .webshell-db-toolbar .form-control {
height: 36px; height: 34px;
border-radius: 8px; border-radius: 7px;
border: 1px solid rgba(15, 23, 42, 0.16); border: 1px solid rgba(15, 23, 42, 0.14);
background: #fff; background: #fff;
font-size: 0.9rem; font-size: 0.88rem;
padding-left: 10px; padding-left: 10px;
padding-right: 10px; padding-right: 10px;
transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease; transition: border-color 0.2s ease, box-shadow 0.2s ease;
} }
.webshell-db-toolbar .form-control:focus { .webshell-db-toolbar .form-control:focus {
border-color: var(--accent-color); border-color: var(--accent-color);
box-shadow: 0 0 0 2px rgba(0, 102, 255, 0.1); box-shadow: 0 0 0 2px rgba(0, 102, 255, 0.1);
background: #fff; background: #fff;
} }
.webshell-db-toolbar select.form-control {
appearance: auto;
-webkit-appearance: menulist;
-moz-appearance: menulist;
padding-right: 8px;
background-image: none;
}
#webshell-db-sqlite-row { #webshell-db-sqlite-row {
grid-column: 1 / -1; grid-column: 1 / -1;
} }
@@ -10522,7 +10561,7 @@ header {
grid-template-columns: 240px minmax(0, 1fr); grid-template-columns: 240px minmax(0, 1fr);
} }
.webshell-db-toolbar { .webshell-db-toolbar {
grid-template-columns: repeat(3, minmax(140px, 1fr)); grid-template-columns: repeat(3, minmax(120px, 1fr));
} }
} }
@media (max-width: 980px) { @media (max-width: 980px) {
@@ -10533,13 +10572,23 @@ header {
min-height: 200px; min-height: 200px;
} }
.webshell-db-toolbar { .webshell-db-toolbar {
grid-template-columns: repeat(2, minmax(140px, 1fr)); grid-template-columns: repeat(2, minmax(120px, 1fr));
} }
} }
@media (max-width: 700px) { @media (max-width: 700px) {
.webshell-db-toolbar { .webshell-db-toolbar {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
#webshell-db-profile-modal .modal-content {
width: calc(100% - 24px);
margin: 32px auto;
}
#webshell-db-profile-modal .modal-header,
#webshell-db-profile-modal .modal-body,
#webshell-db-profile-modal .modal-footer {
padding-left: 14px;
padding-right: 14px;
}
} }
/* 仪表盘页面样式(最佳实践布局 + 视觉增强) */ /* 仪表盘页面样式(最佳实践布局 + 视觉增强) */
+1
View File
@@ -407,6 +407,7 @@
"dbDeleteProfile": "删除连接", "dbDeleteProfile": "删除连接",
"dbDeleteProfileConfirm": "确定删除该数据库连接配置吗?", "dbDeleteProfileConfirm": "确定删除该数据库连接配置吗?",
"dbProfileNamePrompt": "请输入连接名称", "dbProfileNamePrompt": "请输入连接名称",
"dbProfileName": "连接名称",
"dbProfiles": "数据库连接", "dbProfiles": "数据库连接",
"aiSystemReadyMessage": "系统已就绪。请输入您的测试需求,系统将自动执行相应的安全测试。", "aiSystemReadyMessage": "系统已就绪。请输入您的测试需求,系统将自动执行相应的安全测试。",
"aiNewConversation": "新对话", "aiNewConversation": "新对话",
+74 -18
View File
@@ -132,6 +132,7 @@ function wsT(key) {
'webshell.dbDeleteProfile': '删除连接', 'webshell.dbDeleteProfile': '删除连接',
'webshell.dbDeleteProfileConfirm': '确定删除该数据库连接配置吗?', 'webshell.dbDeleteProfileConfirm': '确定删除该数据库连接配置吗?',
'webshell.dbProfileNamePrompt': '请输入连接名称', 'webshell.dbProfileNamePrompt': '请输入连接名称',
'webshell.dbProfileName': '连接名称',
'webshell.dbProfiles': '数据库连接', 'webshell.dbProfiles': '数据库连接',
'webshell.aiSystemReadyMessage': '系统已就绪。请输入您的测试需求,系统将自动执行相应的安全测试。', 'webshell.aiSystemReadyMessage': '系统已就绪。请输入您的测试需求,系统将自动执行相应的安全测试。',
'webshell.aiPlaceholder': '例如:列出当前目录下的文件', 'webshell.aiPlaceholder': '例如:列出当前目录下的文件',
@@ -864,14 +865,17 @@ function webshellDbGetFieldValue(id) {
} }
function webshellDbCollectConfig(conn) { function webshellDbCollectConfig(conn) {
var curr = getWebshellDbConfig(conn) || {};
var nameVal = webshellDbGetFieldValue('webshell-db-profile-name');
var cfg = { var cfg = {
name: nameVal || curr.name || 'DB-1',
type: webshellDbGetFieldValue('webshell-db-type') || 'mysql', type: webshellDbGetFieldValue('webshell-db-type') || 'mysql',
host: webshellDbGetFieldValue('webshell-db-host') || '127.0.0.1', host: webshellDbGetFieldValue('webshell-db-host') || '127.0.0.1',
port: webshellDbGetFieldValue('webshell-db-port') || '', port: webshellDbGetFieldValue('webshell-db-port') || '',
username: webshellDbGetFieldValue('webshell-db-user') || '', username: webshellDbGetFieldValue('webshell-db-user') || '',
password: (document.getElementById('webshell-db-pass') || {}).value || '', password: (document.getElementById('webshell-db-pass') || {}).value || '',
database: webshellDbGetFieldValue('webshell-db-name') || '', database: webshellDbGetFieldValue('webshell-db-name') || '',
selectedDatabase: getWebshellDbConfig(conn).selectedDatabase || '', selectedDatabase: curr.selectedDatabase || '',
sqlitePath: webshellDbGetFieldValue('webshell-db-sqlite-path') || '/tmp/test.db', sqlitePath: webshellDbGetFieldValue('webshell-db-sqlite-path') || '/tmp/test.db',
sql: (document.getElementById('webshell-db-sql') || {}).value || '' sql: (document.getElementById('webshell-db-sql') || {}).value || ''
}; };
@@ -1574,7 +1578,19 @@ function selectWebshell(id, stateReady) {
'<div class="webshell-db-sidebar-hint">' + (wsT('webshell.dbSelectTableHint') || '点击表名可生成查询 SQL') + '</div>' + '<div class="webshell-db-sidebar-hint">' + (wsT('webshell.dbSelectTableHint') || '点击表名可生成查询 SQL') + '</div>' +
'</aside>' + '</aside>' +
'<section class="webshell-db-main">' + '<section class="webshell-db-main">' +
'<div class="webshell-db-sql-tools"><button type="button" class="btn-ghost btn-sm" id="webshell-db-template-btn">' + (wsT('webshell.dbTemplateSql') || '示例 SQL') + '</button><button type="button" class="btn-ghost btn-sm" id="webshell-db-clear-btn">' + (wsT('webshell.dbClearSql') || '清空 SQL') + '</button></div>' +
'<textarea id="webshell-db-sql" class="webshell-db-sql form-control" rows="8" placeholder="' + (wsT('webshell.dbSqlPlaceholder') || '输入 SQL,例如:SELECT version();') + '"></textarea>' +
'<div class="webshell-db-actions">' +
'<button type="button" class="btn-ghost" id="webshell-db-test-btn">' + (wsT('webshell.dbTest') || '测试连接') + '</button>' +
'<button type="button" class="btn-primary" id="webshell-db-run-btn">' + (wsT('webshell.dbRunSql') || '执行 SQL') + '</button>' +
'</div>' +
'<div class="webshell-db-output-wrap"><div class="webshell-db-output-title">' + (wsT('webshell.dbOutput') || '执行输出') + '</div><div id="webshell-db-result-table" class="webshell-db-result-table"></div><pre id="webshell-db-output" class="webshell-db-output"></pre><div class="webshell-db-hint">' + (wsT('webshell.dbCliHint') || '如果提示命令不存在,请先在目标主机安装对应客户端(mysql/psql/sqlite3/sqlcmd') + '</div></div>' +
'<div id="webshell-db-profile-modal" class="modal">' +
'<div class="modal-content webshell-db-profile-modal-content">' +
'<div class="modal-header"><h2 id="webshell-db-profile-modal-title">' + (wsT('webshell.editConnectionTitle') || '编辑连接') + '</h2><span class="modal-close" id="webshell-db-profile-modal-close">&times;</span></div>' +
'<div class="modal-body">' +
'<div class="webshell-db-toolbar">' + '<div class="webshell-db-toolbar">' +
'<label><span>' + (wsT('webshell.dbProfileName') || '连接名称') + '</span><input id="webshell-db-profile-name" class="form-control" type="text" maxlength="30" /></label>' +
'<label><span>' + (wsT('webshell.dbType') || '数据库类型') + '</span><select id="webshell-db-type" class="form-control"><option value="mysql">MySQL</option><option value="pgsql">PostgreSQL</option><option value="sqlite">SQLite</option><option value="mssql">SQL Server</option></select></label>' + '<label><span>' + (wsT('webshell.dbType') || '数据库类型') + '</span><select id="webshell-db-type" class="form-control"><option value="mysql">MySQL</option><option value="pgsql">PostgreSQL</option><option value="sqlite">SQLite</option><option value="mssql">SQL Server</option></select></label>' +
'<label class="webshell-db-common-field"><span>' + (wsT('webshell.dbHost') || '主机') + '</span><input id="webshell-db-host" class="form-control" type="text" value="127.0.0.1" /></label>' + '<label class="webshell-db-common-field"><span>' + (wsT('webshell.dbHost') || '主机') + '</span><input id="webshell-db-host" class="form-control" type="text" value="127.0.0.1" /></label>' +
'<label class="webshell-db-common-field"><span>' + (wsT('webshell.dbPort') || '端口') + '</span><input id="webshell-db-port" class="form-control" type="text" /></label>' + '<label class="webshell-db-common-field"><span>' + (wsT('webshell.dbPort') || '端口') + '</span><input id="webshell-db-port" class="form-control" type="text" /></label>' +
@@ -1583,13 +1599,10 @@ function selectWebshell(id, stateReady) {
'<label class="webshell-db-common-field"><span>' + (wsT('webshell.dbName') || '数据库名') + '</span><input id="webshell-db-name" class="form-control" type="text" /></label>' + '<label class="webshell-db-common-field"><span>' + (wsT('webshell.dbName') || '数据库名') + '</span><input id="webshell-db-name" class="form-control" type="text" /></label>' +
'<label id="webshell-db-sqlite-row"><span>' + (wsT('webshell.dbSqlitePath') || 'SQLite 文件路径') + '</span><input id="webshell-db-sqlite-path" class="form-control" type="text" value="/tmp/test.db" /></label>' + '<label id="webshell-db-sqlite-row"><span>' + (wsT('webshell.dbSqlitePath') || 'SQLite 文件路径') + '</span><input id="webshell-db-sqlite-path" class="form-control" type="text" value="/tmp/test.db" /></label>' +
'</div>' + '</div>' +
'<div class="webshell-db-sql-tools"><button type="button" class="btn-ghost btn-sm" id="webshell-db-template-btn">' + (wsT('webshell.dbTemplateSql') || '示例 SQL') + '</button><button type="button" class="btn-ghost btn-sm" id="webshell-db-clear-btn">' + (wsT('webshell.dbClearSql') || '清空 SQL') + '</button></div>' +
'<textarea id="webshell-db-sql" class="webshell-db-sql form-control" rows="8" placeholder="' + (wsT('webshell.dbSqlPlaceholder') || '输入 SQL,例如:SELECT version();') + '"></textarea>' +
'<div class="webshell-db-actions">' +
'<button type="button" class="btn-ghost" id="webshell-db-test-btn">' + (wsT('webshell.dbTest') || '测试连接') + '</button>' +
'<button type="button" class="btn-primary" id="webshell-db-run-btn">' + (wsT('webshell.dbRunSql') || '执行 SQL') + '</button>' +
'</div>' + '</div>' +
'<div class="webshell-db-output-wrap"><div class="webshell-db-output-title">' + (wsT('webshell.dbOutput') || '执行输出') + '</div><div id="webshell-db-result-table" class="webshell-db-result-table"></div><pre id="webshell-db-output" class="webshell-db-output"></pre><div class="webshell-db-hint">' + (wsT('webshell.dbCliHint') || '如果提示命令不存在,请先在目标主机安装对应客户端(mysql/psql/sqlite3/sqlcmd') + '</div></div>' + '<div class="modal-footer"><button type="button" class="btn-secondary" id="webshell-db-profile-cancel-btn">取消</button><button type="button" class="btn-primary" id="webshell-db-profile-save-btn">保存</button></div>' +
'</div>' +
'</div>' +
'</section>' + '</section>' +
'</div>' + '</div>' +
'</div>'; '</div>';
@@ -1770,6 +1783,12 @@ function selectWebshell(id, stateReady) {
var dbSchemaTreeEl = document.getElementById('webshell-db-schema-tree'); var dbSchemaTreeEl = document.getElementById('webshell-db-schema-tree');
var dbProfilesEl = document.getElementById('webshell-db-profiles'); var dbProfilesEl = document.getElementById('webshell-db-profiles');
var dbAddProfileBtn = document.getElementById('webshell-db-add-profile-btn'); var dbAddProfileBtn = document.getElementById('webshell-db-add-profile-btn');
var dbProfileModalEl = document.getElementById('webshell-db-profile-modal');
var dbProfileModalTitleEl = document.getElementById('webshell-db-profile-modal-title');
var dbProfileModalCloseBtn = document.getElementById('webshell-db-profile-modal-close');
var dbProfileModalCancelBtn = document.getElementById('webshell-db-profile-cancel-btn');
var dbProfileModalSaveBtn = document.getElementById('webshell-db-profile-save-btn');
var dbProfileNameEl = document.getElementById('webshell-db-profile-name');
var dbHostEl = document.getElementById('webshell-db-host'); var dbHostEl = document.getElementById('webshell-db-host');
var dbPortEl = document.getElementById('webshell-db-port'); var dbPortEl = document.getElementById('webshell-db-port');
var dbUserEl = document.getElementById('webshell-db-user'); var dbUserEl = document.getElementById('webshell-db-user');
@@ -1793,9 +1812,19 @@ function selectWebshell(id, stateReady) {
if (dbAddProfileBtn) dbAddProfileBtn.disabled = disabled; if (dbAddProfileBtn) dbAddProfileBtn.disabled = disabled;
} }
function setDbProfileModalVisible(visible, mode) {
if (!dbProfileModalEl) return;
dbProfileModalEl.style.display = visible ? 'block' : 'none';
if (dbProfileModalTitleEl) {
if (mode === 'add') dbProfileModalTitleEl.textContent = wsT('webshell.dbAddProfile') || '新增连接';
else dbProfileModalTitleEl.textContent = wsT('webshell.editConnectionTitle') || '编辑连接';
}
}
function applyActiveDbProfileToForm() { function applyActiveDbProfileToForm() {
var dbCfg = getWebshellDbConfig(conn); var dbCfg = getWebshellDbConfig(conn);
if (!dbCfg) return; if (!dbCfg) return;
if (dbProfileNameEl) dbProfileNameEl.value = dbCfg.name || 'DB-1';
if (dbTypeEl) dbTypeEl.value = dbCfg.type || 'mysql'; if (dbTypeEl) dbTypeEl.value = dbCfg.type || 'mysql';
if (dbHostEl) dbHostEl.value = dbCfg.host || '127.0.0.1'; if (dbHostEl) dbHostEl.value = dbCfg.host || '127.0.0.1';
if (dbPortEl) dbPortEl.value = dbCfg.port || ''; if (dbPortEl) dbPortEl.value = dbCfg.port || '';
@@ -1817,7 +1846,7 @@ function selectWebshell(id, stateReady) {
var active = p.id === state.activeProfileId; var active = p.id === state.activeProfileId;
html += '<div class="webshell-db-profile-tab' + (active ? ' active' : '') + '" data-id="' + escapeHtml(p.id) + '">' + html += '<div class="webshell-db-profile-tab' + (active ? ' active' : '') + '" data-id="' + escapeHtml(p.id) + '">' +
'<button type="button" class="webshell-db-profile-main" data-action="switch" data-id="' + escapeHtml(p.id) + '">' + escapeHtml(p.name || 'DB') + '</button>' + '<button type="button" class="webshell-db-profile-main" data-action="switch" data-id="' + escapeHtml(p.id) + '">' + escapeHtml(p.name || 'DB') + '</button>' +
'<button type="button" class="webshell-db-profile-menu" data-action="rename" data-id="' + escapeHtml(p.id) + '" title="' + escapeHtml(wsT('webshell.dbRenameProfile') || '重命名') + '"></button>' + '<button type="button" class="webshell-db-profile-menu" data-action="edit" data-id="' + escapeHtml(p.id) + '" title="' + escapeHtml(wsT('webshell.editConnection') || '编辑') + '"></button>' +
'<button type="button" class="webshell-db-profile-menu" data-action="delete" data-id="' + escapeHtml(p.id) + '" title="' + escapeHtml(wsT('webshell.dbDeleteProfile') || '删除连接') + '">×</button>' + '<button type="button" class="webshell-db-profile-menu" data-action="delete" data-id="' + escapeHtml(p.id) + '" title="' + escapeHtml(wsT('webshell.dbDeleteProfile') || '删除连接') + '">×</button>' +
'</div>'; '</div>';
}); });
@@ -1839,15 +1868,12 @@ function selectWebshell(id, stateReady) {
renderDbSchemaTree(); renderDbSchemaTree();
return; return;
} }
if (action === 'rename') { if (action === 'edit') {
var curr = state.profiles[idx].name || ''; state.activeProfileId = id;
var next = prompt(wsT('webshell.dbProfileNamePrompt') || '请输入连接名称', curr);
if (next == null) return;
next = String(next || '').trim();
if (!next) return;
state.profiles[idx].name = next.slice(0, 30);
saveWebshellDbState(conn, state); saveWebshellDbState(conn, state);
applyActiveDbProfileToForm();
renderDbProfileTabs(); renderDbProfileTabs();
setDbProfileModalVisible(true, 'edit');
return; return;
} }
if (action === 'delete') { if (action === 'delete') {
@@ -2179,11 +2205,12 @@ function selectWebshell(id, stateReady) {
resetDbColumnLoadCache(); resetDbColumnLoadCache();
renderDbSchemaTree(); renderDbSchemaTree();
}); });
['webshell-db-host', 'webshell-db-port', 'webshell-db-user', 'webshell-db-pass', 'webshell-db-name', 'webshell-db-sqlite-path'].forEach(function (id) { ['webshell-db-profile-name', 'webshell-db-host', 'webshell-db-port', 'webshell-db-user', 'webshell-db-pass', 'webshell-db-name', 'webshell-db-sqlite-path'].forEach(function (id) {
var el = document.getElementById(id); var el = document.getElementById(id);
if (el) el.addEventListener('change', function () { if (el) el.addEventListener('change', function () {
webshellDbCollectConfig(conn); webshellDbCollectConfig(conn);
resetDbColumnLoadCache(); resetDbColumnLoadCache();
renderDbProfileTabs();
}); });
}); });
if (dbSqlEl) dbSqlEl.addEventListener('change', function () { webshellDbCollectConfig(conn); }); if (dbSqlEl) dbSqlEl.addEventListener('change', function () { webshellDbCollectConfig(conn); });
@@ -2203,6 +2230,25 @@ function selectWebshell(id, stateReady) {
if (dbSqlEl) dbSqlEl.value = ''; if (dbSqlEl) dbSqlEl.value = '';
webshellDbCollectConfig(conn); webshellDbCollectConfig(conn);
}); });
if (dbProfileModalCloseBtn) dbProfileModalCloseBtn.addEventListener('click', function () {
setDbProfileModalVisible(false);
});
if (dbProfileModalCancelBtn) dbProfileModalCancelBtn.addEventListener('click', function () {
applyActiveDbProfileToForm();
setDbProfileModalVisible(false);
});
if (dbProfileModalSaveBtn) dbProfileModalSaveBtn.addEventListener('click', function () {
webshellDbCollectConfig(conn);
renderDbProfileTabs();
resetDbColumnLoadCache();
setDbProfileModalVisible(false);
});
if (dbProfileModalEl) dbProfileModalEl.addEventListener('click', function (evt) {
if (evt.target === dbProfileModalEl) {
applyActiveDbProfileToForm();
setDbProfileModalVisible(false);
}
});
if (dbAddProfileBtn) dbAddProfileBtn.addEventListener('click', function () { if (dbAddProfileBtn) dbAddProfileBtn.addEventListener('click', function () {
var state = getWebshellDbState(conn); var state = getWebshellDbState(conn);
var name = 'DB-' + (state.profiles.length + 1); var name = 'DB-' + (state.profiles.length + 1);
@@ -2213,10 +2259,12 @@ function selectWebshell(id, stateReady) {
applyActiveDbProfileToForm(); applyActiveDbProfileToForm();
renderDbProfileTabs(); renderDbProfileTabs();
renderDbSchemaTree(); renderDbSchemaTree();
setDbProfileModalVisible(true, 'add');
}); });
renderDbProfileTabs(); renderDbProfileTabs();
applyActiveDbProfileToForm(); applyActiveDbProfileToForm();
renderDbSchemaTree(); renderDbSchemaTree();
setDbProfileModalVisible(false);
initWebshellTerminal(conn); initWebshellTerminal(conn);
} }
@@ -3699,6 +3747,8 @@ function refreshWebshellUIOnLanguageChange() {
} }
var dbTypeLabel = document.querySelector('#webshell-db-type') ? document.querySelector('#webshell-db-type').closest('label') : null; var dbTypeLabel = document.querySelector('#webshell-db-type') ? document.querySelector('#webshell-db-type').closest('label') : null;
if (dbTypeLabel && dbTypeLabel.querySelector('span')) dbTypeLabel.querySelector('span').textContent = wsT('webshell.dbType') || '数据库类型'; if (dbTypeLabel && dbTypeLabel.querySelector('span')) dbTypeLabel.querySelector('span').textContent = wsT('webshell.dbType') || '数据库类型';
var dbProfileNameLabel = document.querySelector('#webshell-db-profile-name') ? document.querySelector('#webshell-db-profile-name').closest('label') : null;
if (dbProfileNameLabel && dbProfileNameLabel.querySelector('span')) dbProfileNameLabel.querySelector('span').textContent = wsT('webshell.dbProfileName') || '连接名称';
var dbHostLabel = document.querySelector('#webshell-db-host') ? document.querySelector('#webshell-db-host').closest('label') : null; var dbHostLabel = document.querySelector('#webshell-db-host') ? document.querySelector('#webshell-db-host').closest('label') : null;
if (dbHostLabel && dbHostLabel.querySelector('span')) dbHostLabel.querySelector('span').textContent = wsT('webshell.dbHost') || '主机'; if (dbHostLabel && dbHostLabel.querySelector('span')) dbHostLabel.querySelector('span').textContent = wsT('webshell.dbHost') || '主机';
var dbPortLabel = document.querySelector('#webshell-db-port') ? document.querySelector('#webshell-db-port').closest('label') : null; var dbPortLabel = document.querySelector('#webshell-db-port') ? document.querySelector('#webshell-db-port').closest('label') : null;
@@ -3733,8 +3783,14 @@ function refreshWebshellUIOnLanguageChange() {
if (dbTreeHint) dbTreeHint.textContent = wsT('webshell.dbSelectTableHint') || '点击表名可生成查询 SQL'; if (dbTreeHint) dbTreeHint.textContent = wsT('webshell.dbSelectTableHint') || '点击表名可生成查询 SQL';
var dbAddProfileBtn = document.getElementById('webshell-db-add-profile-btn'); var dbAddProfileBtn = document.getElementById('webshell-db-add-profile-btn');
if (dbAddProfileBtn) dbAddProfileBtn.textContent = '+ ' + (wsT('webshell.dbAddProfile') || '新增连接'); if (dbAddProfileBtn) dbAddProfileBtn.textContent = '+ ' + (wsT('webshell.dbAddProfile') || '新增连接');
document.querySelectorAll('.webshell-db-profile-menu[data-action="rename"]').forEach(function (el) { var dbProfileModalTitle = document.getElementById('webshell-db-profile-modal-title');
el.title = wsT('webshell.dbRenameProfile') || '重命名'; if (dbProfileModalTitle) dbProfileModalTitle.textContent = wsT('webshell.editConnectionTitle') || '编辑连接';
var dbProfileCancelBtn = document.getElementById('webshell-db-profile-cancel-btn');
if (dbProfileCancelBtn) dbProfileCancelBtn.textContent = '取消';
var dbProfileSaveBtn = document.getElementById('webshell-db-profile-save-btn');
if (dbProfileSaveBtn) dbProfileSaveBtn.textContent = '保存';
document.querySelectorAll('.webshell-db-profile-menu[data-action="edit"]').forEach(function (el) {
el.title = wsT('webshell.editConnection') || '编辑';
}); });
document.querySelectorAll('.webshell-db-profile-menu[data-action="delete"]').forEach(function (el) { document.querySelectorAll('.webshell-db-profile-menu[data-action="delete"]').forEach(function (el) {
el.title = wsT('webshell.dbDeleteProfile') || '删除连接'; el.title = wsT('webshell.dbDeleteProfile') || '删除连接';