Files
gpt_from_scratch/website/index.html
T
2026-06-18 20:19:38 +08:00

198 lines
6.9 KiB
HTML

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>软件下载页面</title>
<style>
body{font-size:18px!important;line-height:2;font-family:sans-serif;margin:.5em 1.5em 2em}
h1{font-size:24px!important;margin-top:0;margin-bottom:.5em;border-bottom:2px solid #ccc;padding-bottom:.3em}
.breadcrumb{font-size:18px;margin-bottom:.75em}
.breadcrumb a{color:#0066cc;cursor:pointer}
.tools-nav{margin-bottom:.75em}
.tools-link{text-decoration:underline;font-style:italic}
.loading{font-size:20px;color:#666}
.error{color:#c00;font-size:18px}
.user-bar{margin-bottom:.4em;padding:.25em 0;display:flex;align-items:center;justify-content:flex-end;gap:1em}
.user-bar .logged-in{color:green}
.user-bar .logout-btn{padding:.3em .8em;font-size:16px;cursor:pointer;background:#0066cc;color:#fff;border:none;border-radius:4px}
.user-bar .logout-btn:hover{background:#0052a3}
.file-list{margin-top:.25em;overflow-x:auto}
.file-table{border-collapse:collapse;width:75%;table-layout:fixed}
.file-table th,.file-table td{padding:.45em .65em;border-bottom:1px solid #ddd;text-align:left;vertical-align:middle}
.file-table thead th{font-size:17px;font-weight:600;color:#333;background:#f5f5f5;border-bottom:2px solid #ccc}
.file-table .col-name{width:70%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.file-table .col-size{width:10%;white-space:nowrap;font-size:16px;color:#555}
.file-table .col-mtime{width:20%;white-space:nowrap;font-size:16px;color:#555}
.file-table a{font-size:19px!important;color:#0066cc;text-decoration:none}
.file-table a:hover{text-decoration:underline}
.file-table .dir{font-weight:bold;cursor:pointer}
.file-table .empty-msg{text-align:center;color:#666;padding:1em}
</style>
</head>
<body>
<div class="user-bar">
<span class="logged-in">当前已登录: <span id="username-display"></span></span>
<button class="logout-btn" id="logout-btn">注销</button>
</div>
<h1>文件列表 <span id="path-display"></span></h1>
<div class="breadcrumb" id="breadcrumb"></div>
<div id="content">
<div class="loading" id="loading">正在加载...</div>
<div class="file-list" id="file-list" style="display:none"></div>
<div class="error" id="error" style="display:none"></div>
</div>
<script>
(function(){
var authHeader=sessionStorage.getItem("auth");
var username=sessionStorage.getItem("username");
if(!authHeader){
window.location.href="/login.html?return="+encodeURIComponent(window.location.pathname);
return;
}
document.getElementById("username-display").textContent=username||"";
loadFileList(getPath());
function getPath(){
var p=window.location.pathname;
if(p==="/"||p==="")return"";
if(p.endsWith("/"))p=p.slice(0,-1);
return p.replace(/^\//,"");
}
function shouldHideFile(filename){
var hiddenPatterns=[/\.php$/i,/\.html$/i,/\.backup$/i,/^api$/i,/^auth_check/i,/^login/i,/^logout/i,/^index\./i];
return hiddenPatterns.some(function(pattern){return pattern.test(filename)});
}
function escapeHtml(s){
if(s==null||s==="")return"";
return String(s).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");
}
function formatSize(bytes){
if(!bytes)return"-";
if(bytes<1024)return bytes+" B";
if(bytes<1048576)return(bytes/1024).toFixed(1)+" K";
if(bytes<1073741824)return(bytes/1048576).toFixed(1)+" M";
return(bytes/1073741824).toFixed(1)+" G";
}
function formatMtime(mtime){
if(!mtime)return"";
try{
var d=new Date(mtime);
return isNaN(d)?mtime:d.toLocaleString();
}catch(e){
return mtime;
}
}
function normalizeName(name){
return (name||"").replace(/\/$/,"");
}
function isDirectory(item){
return item.type==="directory"||/\/$/.test(item.name||"");
}
function renderBreadcrumb(path){
var parts=path?path.split("/").filter(Boolean):[];
if(parts.length===0){
document.getElementById("breadcrumb").innerHTML="";
return;
}
var inTools=parts[0]==="tools";
var html='<a'+(inTools?' class="tools-link"':'')+' onclick="navigateTo(\'/\')">根目录</a>';
var acc="";
for(var i=0;i<parts.length;i++){
acc+=(acc?"/":"")+parts[i];
var linkClass=parts[i]==="tools"?' class="tools-link"':'';
html+=' / <a'+linkClass+' onclick="navigateTo(\'/'+acc+'/\')">'+escapeHtml(parts[i])+"</a>";
}
document.getElementById("breadcrumb").innerHTML=html;
}
function buildToolsNavHtml(path,items){
if(path)return "";
var hasTools=items.some(function(item){return isDirectory(item)&&normalizeName(item.name)==="tools"});
if(!hasTools)return "";
return '<div class="breadcrumb tools-nav"><a class="tools-link" onclick="navigateTo(\'/tools/\')">tools</a></div>';
}
window.navigateTo=function(path){
window.location.href=path;
};
function loadFileList(path){
var loadingEl=document.getElementById("loading");
var errorEl=document.getElementById("error");
var listEl=document.getElementById("file-list");
loadingEl.style.display="block";
errorEl.style.display="none";
listEl.style.display="none";
fetch("/list/"+(path?path+"/":""),{
headers:{Authorization:authHeader}
})
.then(function(r){
if(r.status===401){
sessionStorage.clear();
window.location.href="/login.html";
return;
}
if(!r.ok)throw new Error("加载失败");
return r.json();
})
.then(function(data){
if(!data)return;
loadingEl.style.display="none";
document.getElementById("path-display").textContent=path?"/"+path:"";
renderBreadcrumb(path);
var rows="";
var items=Array.isArray(data)?data:[];
var toolsHtml=buildToolsNavHtml(path,items);
items.forEach(function(item){
if(shouldHideFile(item.name))return;
var name=normalizeName(item.name);
if(!path&&isDirectory(item)&&name==="tools")return;
var fullPath=(path?path+"/":"")+name;
var isDir=isDirectory(item);
var size=formatSize(item.size);
var mtime=formatMtime(item.mtime);
var nameEsc=escapeHtml(name)+(isDir?"/":"");
if(isDir){
var navPath="/"+fullPath+"/";
rows+="<tr><td class=\"col-name\"><a onclick='navigateTo("+JSON.stringify(navPath)+")' class=\"dir\" href=\"javascript:void(0)\">"+nameEsc+"</a></td><td class=\"col-size\">"+escapeHtml(size)+"</td><td class=\"col-mtime\">"+escapeHtml(mtime)+"</td></tr>";
}else{
rows+="<tr><td class=\"col-name\"><a href=\"/"+fullPath+"?u="+encodeURIComponent(username)+"\" download>"+nameEsc+"</a></td><td class=\"col-size\">"+escapeHtml(size)+"</td><td class=\"col-mtime\">"+escapeHtml(mtime)+"</td></tr>";
}
});
var tableStart='<table class="file-table"><thead><tr><th class="col-name">文件名称</th><th class="col-size">文件大小</th><th class="col-mtime">上传时间</th></tr></thead><tbody>';
var tableEnd="</tbody></table>";
if(!rows){
listEl.innerHTML=toolsHtml+tableStart+'<tr><td class="empty-msg" colspan="3">目录为空</td></tr>'+tableEnd;
}else{
listEl.innerHTML=toolsHtml+tableStart+rows+tableEnd;
}
listEl.style.display="block";
})
.catch(function(err){
loadingEl.style.display="none";
errorEl.textContent="加载失败: "+(err.message||"未知错误");
errorEl.style.display="block";
});
}
document.getElementById("logout-btn").addEventListener("click",function(){
sessionStorage.clear();
window.location.href="/login.html";
});
})();
</script>
</body>
</html>