426 lines
15 KiB
HTML
426 lines
15 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>File Explorer</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<link rel="stylesheet" href="/css/font.css">
|
|
<link rel="stylesheet" href="/css/xadmin.css">
|
|
<link rel="stylesheet" href="/css/win10ui.css">
|
|
<link rel="stylesheet" href="/lib/layui/css/layui.css">
|
|
<link rel="stylesheet" href="/T4/css/tools-icon-btn.css">
|
|
<script type="text/javascript" src="/lib/layui/layui.js" charset="utf-8"></script>
|
|
<script type="text/javascript" src="/js/xadmin.js"></script>
|
|
<script type="text/javascript" src="/T4/js/ansi_up/ansi_up.js"></script>
|
|
<script src="/assets/js/socket/Socket.IO.js"></script>
|
|
<script src="/assets/js/core/echarts.min.js"></script>
|
|
<script>window.breadcrumbs = [{name: "首页", url: ""},{name: "Termination4", url: ""},{name: "文件系统"}];</script>
|
|
<style>
|
|
/* 基础样式 */
|
|
body {
|
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
margin: 0;
|
|
padding: 20px;
|
|
background-color: #f5f5f5;
|
|
color: #333;
|
|
}
|
|
.layui-btn {
|
|
background-color: #1e88e5;
|
|
}
|
|
|
|
/* 主标题样式 */
|
|
h1 {
|
|
color: #333;
|
|
margin-bottom: 20px;
|
|
font-size: 24px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
/* 路径控制区域 */
|
|
#path-controls {
|
|
background-color: #fff;
|
|
padding: 15px;
|
|
border-radius: 4px;
|
|
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
|
margin-bottom: 15px;
|
|
display: flex;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
gap: 10px;
|
|
}
|
|
|
|
#current-path {
|
|
flex-grow: 1;
|
|
min-width: 200px;
|
|
background-color: #f9f9f9;
|
|
padding: 8px 12px;
|
|
border-radius: 4px;
|
|
border: 1px solid #ddd;
|
|
cursor: default;
|
|
}
|
|
|
|
#current-path span {
|
|
color: #1e88e5;
|
|
cursor: pointer;
|
|
padding: 2px 4px;
|
|
border-radius: 2px;
|
|
}
|
|
|
|
#current-path span:hover {
|
|
background-color: #e3f2fd;
|
|
}
|
|
|
|
#path-input {
|
|
flex-grow: 1;
|
|
min-width: 200px;
|
|
padding: 8px 12px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
transition: border-color 0.3s;
|
|
}
|
|
|
|
#path-input:focus {
|
|
border-color: #1e88e5;
|
|
outline: none;
|
|
}
|
|
|
|
#go-button {
|
|
padding: 8px 16px;
|
|
background-color: #1e88e5;
|
|
color: white;
|
|
border: none;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
transition: background-color 0.3s;
|
|
}
|
|
|
|
#go-button:hover {
|
|
background-color: #1565c0;
|
|
}
|
|
|
|
/* 错误消息样式 */
|
|
#error-message {
|
|
color: #d32f2f;
|
|
padding: 10px;
|
|
background-color: #fce4ec;
|
|
border-radius: 4px;
|
|
margin-bottom: 15px;
|
|
display: none;
|
|
}
|
|
|
|
/* 文件列表容器 */
|
|
#file-list-container {
|
|
position: relative;
|
|
background-color: #fff;
|
|
border-radius: 4px;
|
|
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* 加载遮罩层 */
|
|
#loading-overlay {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background-color: rgba(255, 255, 255, 0.8);
|
|
display: none;
|
|
justify-content: center;
|
|
align-items: center;
|
|
z-index: 100;
|
|
}
|
|
|
|
.loading-spinner {
|
|
border: 4px solid #f3f3f3;
|
|
border-top: 4px solid #1e88e5;
|
|
border-radius: 50%;
|
|
width: 40px;
|
|
height: 40px;
|
|
animation: spin 1s linear infinite;
|
|
}
|
|
|
|
@keyframes spin {
|
|
0% { transform: rotate(0deg); }
|
|
100% { transform: rotate(360deg); }
|
|
}
|
|
|
|
/* 文件列表表格样式 */
|
|
table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
table-layout: fixed;
|
|
}
|
|
|
|
th {
|
|
background-color: #f5f5f5;
|
|
padding: 12px 15px;
|
|
text-align: left;
|
|
font-weight: 500;
|
|
border-bottom: 1px solid #ddd;
|
|
}
|
|
|
|
td {
|
|
padding: 12px 15px;
|
|
border-bottom: 1px solid #eee;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
tr.file-item:hover {
|
|
background-color: #f9f9f9;
|
|
}
|
|
|
|
tr.file-item.selected {
|
|
background-color: #e3f2fd;
|
|
}
|
|
|
|
/* 响应式调整 */
|
|
@media (max-width: 768px) {
|
|
#path-controls {
|
|
flex-direction: column;
|
|
align-items: stretch;
|
|
}
|
|
|
|
#current-path, #path-input {
|
|
width: 100%;
|
|
margin-bottom: 10px;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<h1>文件浏览器</h1>
|
|
<div id="path-controls">
|
|
<span>当前路径: </span>
|
|
<div id="current-path"></div>
|
|
<input type="text" id="path-input" placeholder="输入路径">
|
|
<button id="go-button" onclick="navigateByInput()">跳转</button>
|
|
</div>
|
|
<div id="error-message"></div>
|
|
|
|
<div id="file-list-container">
|
|
<div id="loading-overlay">
|
|
<div class="loading-spinner"></div>
|
|
</div>
|
|
<div id="file-list"></div>
|
|
</div>
|
|
|
|
<script>
|
|
socket = io("/Termination4SocketIOSpace");
|
|
// 全局变量用于存储当前路径
|
|
let currentPath = '此电脑';
|
|
// 显示加载动画
|
|
function showLoading() {
|
|
document.getElementById('loading-overlay').style.display = 'flex';
|
|
}
|
|
// 隐藏加载动画
|
|
function hideLoading() {
|
|
document.getElementById('loading-overlay').style.display = 'none';
|
|
}
|
|
// 显示错误消息
|
|
function showError(message) {
|
|
const errorElement = document.getElementById('error-message');
|
|
errorElement.textContent = message;
|
|
errorElement.style.display = 'block';
|
|
}
|
|
// 隐藏错误消息
|
|
function hideError() {
|
|
document.getElementById('error-message').style.display = 'none';
|
|
}
|
|
// 页面加载完成后执行的函数
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
loadFiles(currentPath);
|
|
});
|
|
// 加载文件列表的函数
|
|
function loadFiles(path) {
|
|
hideError();
|
|
showLoading();
|
|
if (path === '此电脑') {
|
|
socket.emit('T4CMDCommand', {PCMachineGUID: PCMachineGUID, "work": "Drive"});
|
|
} else {
|
|
socket.emit('T4CMDCommand', {PCMachineGUID: PCMachineGUID, "work": "file", Command: path});
|
|
}
|
|
}
|
|
function updateCurrentPath(path) {
|
|
const currentPathElement = document.getElementById('current-path');
|
|
currentPathElement.innerHTML = '';
|
|
if (path === '此电脑') {
|
|
const span = document.createElement('span');
|
|
span.textContent = '此电脑';
|
|
span.onclick = () => navigateToPath('此电脑');
|
|
currentPathElement.appendChild(span);
|
|
} else {
|
|
const pathParts = path.split('\\').filter(part => part.trim() !== '');
|
|
let currentPathStr = '';
|
|
pathParts.forEach((part, index) => {
|
|
if (index > 0) {
|
|
currentPathElement.appendChild(document.createTextNode('\\'));
|
|
}
|
|
currentPathStr = index === 0 ? part : `${currentPathStr}\\${part}`;
|
|
const span = document.createElement('span');
|
|
span.textContent = part;
|
|
span.dataset.path = currentPathStr;
|
|
span.onclick = function() {
|
|
navigateToPath(this.dataset.path);
|
|
};
|
|
currentPathElement.appendChild(span);
|
|
});
|
|
}
|
|
}
|
|
// 点击当前路径跳转的函数
|
|
function navigateToPath(path) {
|
|
// 确保路径格式正确,特别是处理驱动器根目录(如 C:\)
|
|
if (path.length === 2 && path[1] === ':') {
|
|
path += '\\'; // 将 C: 转换为 C:\
|
|
}
|
|
currentPath = path;
|
|
loadFiles(currentPath);
|
|
// 不需要再调用 updateCurrentPath,因为 loadFiles 成功后会自动更新
|
|
}
|
|
// 通过输入框输入路径跳转的函数
|
|
function navigateByInput() {
|
|
const inputPath = document.getElementById('path-input').value.trim();
|
|
if (inputPath) {
|
|
currentPath = inputPath;
|
|
loadFiles(currentPath);
|
|
}
|
|
}
|
|
// 处理服务器返回的盘符列表
|
|
socket.on(PCMachineGUID+"CMDRDrives", (drives) => {
|
|
drives = drives["drivers"];
|
|
hideLoading();
|
|
const fileList = document.getElementById('file-list');
|
|
fileList.innerHTML = '';
|
|
// 创建表格
|
|
const table = document.createElement('table');
|
|
const thead = document.createElement('thead');
|
|
const tbody = document.createElement('tbody');
|
|
// 添加表头
|
|
const headerRow = document.createElement('tr');
|
|
['名称', '类型', '大小', '修改时间', '权限'].forEach(text => {
|
|
const th = document.createElement('th');
|
|
th.textContent = text;
|
|
headerRow.appendChild(th);
|
|
});
|
|
thead.appendChild(headerRow);
|
|
table.appendChild(thead);
|
|
// 添加盘符行
|
|
drives.forEach(drive => {
|
|
const row = document.createElement('tr');
|
|
row.classList.add('file-item');
|
|
// 名称列
|
|
const nameCell = document.createElement('td');
|
|
nameCell.textContent = drive;
|
|
row.appendChild(nameCell);
|
|
// 类型列
|
|
const typeCell = document.createElement('td');
|
|
typeCell.textContent = '驱动器';
|
|
row.appendChild(typeCell);
|
|
// 其他列留空
|
|
['', '', ''].forEach(text => {
|
|
const cell = document.createElement('td');
|
|
cell.textContent = text;
|
|
row.appendChild(cell);
|
|
});
|
|
// 添加点击事件
|
|
row.addEventListener('click', function() {
|
|
document.querySelectorAll('.file-item').forEach(i => i.classList.remove('selected'));
|
|
this.classList.add('selected');
|
|
});
|
|
// 添加双击事件
|
|
row.addEventListener('dblclick', function() {
|
|
currentPath = drive;
|
|
updateCurrentPath(currentPath);
|
|
loadFiles(currentPath);
|
|
});
|
|
tbody.appendChild(row);
|
|
});
|
|
table.appendChild(tbody);
|
|
fileList.appendChild(table);
|
|
updateCurrentPath('此电脑');
|
|
});
|
|
// 处理服务器返回的文件列表
|
|
socket.on(PCMachineGUID+"CMDRFiles", (files) => {
|
|
files = files["files"];
|
|
hideLoading();
|
|
const fileList = document.getElementById('file-list');
|
|
fileList.innerHTML = '';
|
|
const table = document.createElement('table');
|
|
const thead = document.createElement('thead');
|
|
const tbody = document.createElement('tbody');
|
|
// 添加表头(不变)
|
|
const headerRow = document.createElement('tr');
|
|
['名称', '类型', '大小', '修改时间', '权限'].forEach(text => {
|
|
const th = document.createElement('th');
|
|
th.textContent = text;
|
|
headerRow.appendChild(th);
|
|
});
|
|
thead.appendChild(headerRow);
|
|
table.appendChild(thead);
|
|
// 添加文件行
|
|
files.forEach(file => {
|
|
const row = document.createElement('tr');
|
|
row.classList.add('file-item');
|
|
// 各列创建(不变)
|
|
const nameCell = document.createElement('td');
|
|
nameCell.textContent = file.name;
|
|
row.appendChild(nameCell);
|
|
const typeCell = document.createElement('td');
|
|
typeCell.textContent = file.is_dir ? '文件夹' : '文件';
|
|
row.appendChild(typeCell);
|
|
const sizeCell = document.createElement('td');
|
|
sizeCell.textContent = file.size || '';
|
|
row.appendChild(sizeCell);
|
|
const modifiedCell = document.createElement('td');
|
|
modifiedCell.textContent = file.modified || '';
|
|
row.appendChild(modifiedCell);
|
|
const permissionCell = document.createElement('td');
|
|
permissionCell.textContent = file.permission || '';
|
|
row.appendChild(permissionCell);
|
|
// **移除原 click 事件中的输出代码**,仅保留选中逻辑
|
|
row.addEventListener('click', function() {
|
|
document.querySelectorAll('.file-item').forEach(i => i.classList.remove('selected'));
|
|
this.classList.add('selected');
|
|
});
|
|
// **将路径输出逻辑移至 dblclick 事件中**
|
|
row.addEventListener('dblclick', function() {
|
|
if (file.is_dir) {
|
|
// 文件夹双击:跳转路径(原有逻辑)
|
|
currentPath = file.path;
|
|
updateCurrentPath(currentPath);
|
|
loadFiles(currentPath);
|
|
} else {
|
|
console.log(file);
|
|
layer.open({
|
|
type: 2,
|
|
skin: 'class-layer-radio-ui-custom',
|
|
area: ['90%', '90%'],
|
|
title: 'Termination 文件下载 (File DownLoad)',
|
|
shade: 0,
|
|
maxmin: true,
|
|
anim: 0,
|
|
content: './download.html?PCMachineGUID='+PCMachineGUID+'&PCSID='+PCSID+"&Path="+file.path.replace(/\\/g, '/'),
|
|
});
|
|
}
|
|
});
|
|
|
|
tbody.appendChild(row);
|
|
});
|
|
|
|
table.appendChild(tbody);
|
|
fileList.appendChild(table);
|
|
updateCurrentPath(currentPath);
|
|
});
|
|
// 处理服务器返回的错误信息
|
|
socket.on('error', (data) => {
|
|
hideLoading();
|
|
showError(data.message);
|
|
});
|
|
</script>
|
|
</body>
|
|
|
|
</html> |