初始化知识库网页系统

功能:
- 用户登录/退出
- 文档列表展示(支持子目录)
- 关键词搜索
- Markdown 文档在线查看
- 管理员添加用户脚本
This commit is contained in:
2026-02-14 00:04:12 +08:00
commit 608d05cf5e
10 changed files with 1042 additions and 0 deletions
+153
View File
@@ -0,0 +1,153 @@
<?php
require_once 'config.php';
checkLogin();
$user = getCurrentUser();
$username = $user['username'];
$docDir = getUserDocDir($username);
// 搜索关键词
$search = trim($_GET['q'] ?? '');
// 递归获取文档列表
$documents = [];
function scanDirectory($dir, $baseDir, $search) {
$docs = [];
if (!is_dir($dir)) return $docs;
$items = scandir($dir);
foreach ($items as $item) {
if ($item === '.' || $item === '..') continue;
$fullPath = $dir . '/' . $item;
$relativePath = str_replace($baseDir . '/', '', $fullPath);
if (is_dir($fullPath)) {
// 递归扫描子目录
$docs = array_merge($docs, scanDirectory($fullPath, $baseDir, $search));
} elseif (is_file($fullPath)) {
// 只处理 .md 和 .txt 文件
$ext = strtolower(pathinfo($item, PATHINFO_EXTENSION));
if (!in_array($ext, ['md', 'txt', 'markdown'])) continue;
$content = file_get_contents($fullPath);
// 搜索过滤
if ($search) {
$searchLower = mb_strtolower($search);
$titleLower = mb_strtolower($item);
$contentLower = mb_strtolower($content);
if (strpos($titleLower, $searchLower) === false &&
strpos($contentLower, $searchLower) === false) {
continue;
}
}
$docs[] = [
'name' => $item,
'path' => $relativePath,
'folder' => dirname($relativePath) === '.' ? '' : dirname($relativePath),
'size' => filesize($fullPath),
'mtime' => filemtime($fullPath),
'preview' => mb_substr(strip_tags($content), 0, 200)
];
}
}
return $docs;
}
$documents = scanDirectory($docDir, $docDir, $search);
// 按文件夹分组,然后按修改时间排序
usort($documents, function($a, $b) {
// 先按文件夹排序
if ($a['folder'] !== $b['folder']) {
return strcmp($a['folder'], $b['folder']);
}
// 同一文件夹按修改时间排序(新文件在前)
return $b['mtime'] - $a['mtime'];
});
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>知识库 - <?php echo htmlspecialchars($username); ?></title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="dashboard">
<header class="header">
<h1>📚 我的知识库</h1>
<div class="user-info">
<span><?php echo htmlspecialchars($username); ?></span>
<a href="logout.php" class="btn-logout">退出</a>
</div>
</header>
<div class="search-bar">
<form method="GET" action="">
<input type="text" name="q" placeholder="搜索文档..."
value="<?php echo htmlspecialchars($search); ?>">
<button type="submit">搜索</button>
<?php if ($search): ?>
<a href="dashboard.php" class="btn-clear">清除</a>
<?php endif; ?>
</form>
</div>
<div class="stats">
共 <?php echo count($documents); ?> 个文档
<?php if ($search): ?>
<span class="search-hint">(搜索: "<?php echo htmlspecialchars($search); ?>")</span>
<?php endif; ?>
</div>
<div class="document-list">
<?php if (empty($documents)): ?>
<div class="empty">
<?php if ($search): ?>
没有找到匹配的文档
<?php else: ?>
暂无文档
<?php endif; ?>
</div>
<?php else: ?>
<?php
$currentFolder = '';
foreach ($documents as $doc):
// 显示文件夹分隔
if ($doc['folder'] !== $currentFolder):
$currentFolder = $doc['folder'];
if ($currentFolder):
?>
<div class="folder-separator">
📁 <?php echo htmlspecialchars($currentFolder); ?>
</div>
<?php
endif;
endif;
?>
<a href="view.php?file=<?php echo urlencode($doc['path']); ?><?php echo $search ? '&q=' . urlencode($search) : ''; ?>"
class="document-card">
<div class="doc-icon">📄</div>
<div class="doc-info">
<div class="doc-name"><?php echo htmlspecialchars($doc['name']); ?></div>
<div class="doc-meta">
<?php echo round($doc['size'] / 1024, 1); ?> KB ·
<?php echo date('Y-m-d H:i', $doc['mtime']); ?>
<?php if ($doc['folder']): ?>
· 📁 <?php echo htmlspecialchars($doc['folder']); ?>
<?php endif; ?>
</div>
<div class="doc-preview"><?php echo htmlspecialchars($doc['preview']); ?>...</div>
</div>
</a>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
</body>
</html>