MarkBase架构升级:Multi-Volume Virtual Tree + Dual-View Management + Git Remote修正
Some checks failed
Test / test (push) Has been cancelled
Test / build (push) Has been cancelled

核心功能:
-  Categories/Series双视图管理(category_view.rs + import_markdown.rs)
-  FUSE Multi-Volume支持(tree_type参数)
-  SSH/SFTP/SCP/rsync协议完整实现(4042行)
-  NFS/SMB Module Phase 1-3完成
-  Archive Module Phase 1-4完成(2916行)
-  Download Center API完整实现
-  S3兼容API实现(560行)

Git配置修正:
-  删除错误origin(gitea.momentry.ddns.net)
-  删除m5max128(指向机器名)
-  设置origin = m5max128gitea.momentry.ddns.net/admin/markbase
-  设置m4minigitea = m4minigitea.momentry.ddns.net/warren/markbase

数据清理:
-  删除38个临时SQLite(保留accusys.sqlite、demo.sqlite)
-  删除.bak、test_*.bin、调试脚本等临时文件
-  删除临时目录(build/、download files/、raid_test/等)
-  更新.gitignore排除临时文件

架构优化:
- 52个文件修改,2434行新增,4739行删除
- Workspace成员整合(16个crate)
- 数据库状态:accusys.sqlite保留(主demo测试)

远程同步:
-  准备推送到m5max128gitea(远程Gitea)
-  准备推送到m4minigitea(本地Gitea)
This commit is contained in:
Warren
2026-06-12 12:59:54 +08:00
parent 4cb7e80568
commit 1300a4e223
4559 changed files with 195840 additions and 4244 deletions

View File

@@ -0,0 +1,213 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Uploaded Files - AccuSys Download Service</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f7;
}
h1 {
color: #1d1d1f;
font-size: 32px;
margin-bottom: 20px;
}
.stats {
display: flex;
gap: 20px;
margin-bottom: 30px;
}
.stat-box {
background: white;
padding: 20px;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.stat-number {
font-size: 28px;
font-weight: bold;
color: #0071e3;
}
.stat-label {
font-size: 14px;
color: #86868b;
margin-top: 5px;
}
.file-table {
background: white;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
overflow: hidden;
}
table {
width: 100%;
border-collapse: collapse;
}
th {
background: #f5f5f7;
padding: 15px;
text-align: left;
font-weight: 600;
color: #1d1d1f;
}
td {
padding: 15px;
border-top: 1px solid #d2d2d7;
}
.filename {
color: #0071e3;
font-weight: 500;
}
.hash {
font-family: "Courier New", monospace;
font-size: 12px;
color: #86868b;
}
.size {
color: #1d1d1f;
}
.path {
font-size: 12px;
color: #86868b;
}
.refresh-btn {
background: #0071e3;
color: white;
border: none;
padding: 12px 24px;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
margin-bottom: 20px;
}
.refresh-btn:hover {
background: #0077ed;
}
.loading {
text-align: center;
padding: 40px;
color: #86868b;
}
.empty-dir {
text-align: center;
padding: 40px;
color: #86868b;
font-size: 16px;
}
</style>
</head>
<body>
<h1>Uploaded Files</h1>
<button class="refresh-btn" onclick="loadFiles()">Refresh List</button>
<div class="stats" id="stats">
<div class="stat-box">
<div class="stat-number" id="total-files">-</div>
<div class="stat-label">Total Files</div>
</div>
<div class="stat-box">
<div class="stat-number" id="total-size">-</div>
<div class="stat-label">Total Size</div>
</div>
<div class="stat-box">
<div class="stat-number" id="user-id">-</div>
<div class="stat-label">User ID</div>
</div>
</div>
<div id="file-list">
<div class="loading">Loading file list...</div>
</div>
<script>
const userId = 'accusys';
const apiBase = window.location.protocol + '//' + window.location.host;
function formatSize(bytes) {
if (bytes === 0) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];
}
function formatDate(dateStr) {
const date = new Date(dateStr);
return date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
}
async function loadFiles() {
try {
const response = await fetch(`${apiBase}/api/v2/files/${userId}`);
const data = await response.json();
// Update stats
document.getElementById('total-files').textContent = data.total_files;
document.getElementById('total-size').textContent = formatSize(data.total_size);
document.getElementById('user-id').textContent = data.user_id;
// Update file list
const fileListDiv = document.getElementById('file-list');
if (data.total_files === 0) {
fileListDiv.innerHTML = '<div class="empty-dir">No files uploaded yet</div>';
return;
}
let tableHtml = '<div class="file-table"><table>';
tableHtml += '<thead><tr>';
tableHtml += '<th>Filename</th>';
tableHtml += '<th>Size</th>';
tableHtml += '<th>SHA256 Hash</th>';
tableHtml += '<th>Path</th>';
tableHtml += '<th>Upload Time</th>';
tableHtml += '</tr></thead><tbody>';
data.files.forEach(file => {
tableHtml += '<tr>';
tableHtml += `<td class="filename">${file.filename}</td>`;
tableHtml += `<td class="size">${formatSize(file.file_size)}</td>`;
tableHtml += `<td class="hash">${file.file_hash.substring(0, 16)}...</td>`;
tableHtml += `<td class="path">${file.relative_path}</td>`;
tableHtml += `<td>${formatDate(file.upload_time)}</td>`;
tableHtml += '</tr>';
});
tableHtml += '</tbody></table></div>';
fileListDiv.innerHTML = tableHtml;
} catch (error) {
console.error('Error loading files:', error);
document.getElementById('file-list').innerHTML =
'<div class="empty-dir">Error loading file list. Please refresh.</div>';
}
}
// Auto-load on page load
loadFiles();
</script>
</body>
</html>