Refactor error handling in FileController and enhance file rendering logic in app.js. Improved error messages and added checks for data structure integrity. Updated connection handling to maintain independent selections for SFTP connections across panels.
This commit is contained in:
@@ -55,7 +55,9 @@ public class FileController {
|
|||||||
|
|
||||||
return ApiResponse.success("查询成功", files);
|
return ApiResponse.success("查询成功", files);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return ApiResponse.error("列出文件失败: " + e.getMessage());
|
// SftpService 已抛出带「列出文件失败:」前缀的消息,此处不再重复拼接
|
||||||
|
String msg = e.getMessage();
|
||||||
|
return ApiResponse.error(msg != null ? msg : "列出文件失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -117,12 +117,16 @@ function loadFiles(panelId) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 渲染文件列表
|
// 渲染文件列表(仅当 data 为数组时渲染,避免错误数据结构被当成文件显示)
|
||||||
function renderFileList(panelId, files) {
|
function renderFileList(panelId, files) {
|
||||||
const fileList = $(`#${panelId}-file-list`);
|
const fileList = $(`#${panelId}-file-list`);
|
||||||
fileList.empty();
|
fileList.empty();
|
||||||
|
|
||||||
if (!files || files.length === 0) {
|
if (!Array.isArray(files)) {
|
||||||
|
fileList.html('<div class="text-center text-danger p-3">数据格式错误,请刷新重试</div>');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (files.length === 0) {
|
||||||
fileList.html('<div class="text-center text-muted p-3">文件夹为空</div>');
|
fileList.html('<div class="text-center text-muted p-3">文件夹为空</div>');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -439,7 +443,8 @@ function showConnectionStatus(panelId, sessionId) {
|
|||||||
statusDiv.show();
|
statusDiv.show();
|
||||||
if (sessionId && activeConnections[sessionId]) {
|
if (sessionId && activeConnections[sessionId]) {
|
||||||
const conn = activeConnections[sessionId];
|
const conn = activeConnections[sessionId];
|
||||||
updateConnectionStatus(panelId, 'connected', '已连接: ' + (conn.name || sessionId));
|
// 仅显示「已连接」,具体连接名由下拉框展示,避免与下拉框重复显示 IP/名称
|
||||||
|
updateConnectionStatus(panelId, 'connected', '已连接');
|
||||||
} else {
|
} else {
|
||||||
updateConnectionStatus(panelId, 'disconnected', '未连接');
|
updateConnectionStatus(panelId, 'disconnected', '未连接');
|
||||||
}
|
}
|
||||||
@@ -465,23 +470,53 @@ function loadActiveConnections() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新连接下拉框
|
// 更新连接下拉框(优先显示连接名或主机,避免暴露 sftp-uuid)
|
||||||
|
// 重建选项后会恢复当前面板的选中值,保证左右面板可独立选择不同 SFTP 连接
|
||||||
function updateConnectionSelect(panelId) {
|
function updateConnectionSelect(panelId) {
|
||||||
const select = $(`#${panelId}-connection`);
|
const select = $(`#${panelId}-connection`);
|
||||||
|
const currentSessionId = panelState[panelId] && panelState[panelId].sessionId;
|
||||||
|
|
||||||
select.empty().append('<option value="">选择连接</option>');
|
select.empty().append('<option value="">选择连接</option>');
|
||||||
|
|
||||||
$.each(activeConnections, function(sessionId, conn) {
|
$.each(activeConnections, function(sessionId, conn) {
|
||||||
const name = (conn && conn.name) ? conn.name : sessionId;
|
const name = (conn && (conn.name || conn.host)) ? (conn.name || conn.host) : ('会话 ' + (sessionId || '').substring(0, 13));
|
||||||
select.append('<option value="' + sessionId + '">' + $('<div>').text(name).html() + '</option>');
|
select.append('<option value="' + sessionId + '">' + $('<div>').text(name).html() + '</option>');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 恢复当前面板的选中连接,避免左右两侧被同步成同一个
|
||||||
|
if (currentSessionId && activeConnections[currentSessionId]) {
|
||||||
|
select.val(currentSessionId);
|
||||||
|
} else {
|
||||||
|
select.val('');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 刷新面板
|
// 刷新面板(先更新活跃连接,再加载左右面板文件,避免竞态和错误数据)
|
||||||
function refreshPanels() {
|
function refreshPanels() {
|
||||||
loadActiveConnections();
|
$.ajax({
|
||||||
loadFiles('left');
|
url: API_BASE + 'api/connection/active',
|
||||||
loadFiles('right');
|
method: 'GET',
|
||||||
updateStatus('已刷新');
|
success: function(response) {
|
||||||
|
if (response.success && response.data) {
|
||||||
|
activeConnections = response.data;
|
||||||
|
updateConnectionSelect('left');
|
||||||
|
updateConnectionSelect('right');
|
||||||
|
['left', 'right'].forEach(function(panelId) {
|
||||||
|
if (panelState[panelId].mode === 'sftp') {
|
||||||
|
showConnectionStatus(panelId, panelState[panelId].sessionId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
loadFiles('left');
|
||||||
|
loadFiles('right');
|
||||||
|
updateStatus('已刷新');
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
loadFiles('left');
|
||||||
|
loadFiles('right');
|
||||||
|
updateStatus('已刷新');
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 切换是否展示隐藏文件
|
// 切换是否展示隐藏文件
|
||||||
@@ -678,20 +713,16 @@ function updatePanelsAfterDisconnect(sessionId) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 连接成功后更新面板状态与下拉框
|
// 连接成功后只更新当前活动面板为新连接,另一侧保持原选择,便于左右选不同 SFTP
|
||||||
function updatePanelStateWithConnection(sessionId, conn) {
|
function updatePanelStateWithConnection(sessionId, conn) {
|
||||||
if (panelState.left.mode === 'sftp') {
|
const panelId = activePanelId;
|
||||||
panelState.left.sessionId = sessionId;
|
if (panelState[panelId].mode === 'sftp') {
|
||||||
$('#left-connection').val(sessionId);
|
panelState[panelId].sessionId = sessionId;
|
||||||
initPanelPath('left');
|
$('#' + panelId + '-connection').val(sessionId);
|
||||||
showConnectionStatus('left', sessionId);
|
initPanelPath(panelId);
|
||||||
}
|
showConnectionStatus(panelId, sessionId);
|
||||||
if (panelState.right.mode === 'sftp') {
|
|
||||||
panelState.right.sessionId = sessionId;
|
|
||||||
$('#right-connection').val(sessionId);
|
|
||||||
initPanelPath('right');
|
|
||||||
showConnectionStatus('right', sessionId);
|
|
||||||
}
|
}
|
||||||
|
// 另一侧保持原有连接选择不变
|
||||||
}
|
}
|
||||||
|
|
||||||
function showAddConnectionDialog() {
|
function showAddConnectionDialog() {
|
||||||
|
|||||||
Reference in New Issue
Block a user