2025-12-2genxin
This commit is contained in:
@@ -7,6 +7,22 @@
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<!-- 头部导航 -->
|
||||
<header class="top-navbar" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 15px 0; box-shadow: 0 2px 10px rgba(0,0,0,0.1); position: sticky; top: 0; z-index: 100;">
|
||||
<div class="navbar-content" style="max-width: 1200px; margin: 0 auto; padding: 0 20px; display: flex; align-items: center; justify-content: space-between;">
|
||||
<a href="frontend.html" class="logo" style="font-size: 24px; font-weight: bold; text-decoration: none; color: white;">🔍 易搜高</a>
|
||||
<nav class="nav-menu" style="display: flex; gap: 15px; align-items: center;">
|
||||
<a href="frontend.html" class="nav-link" style="color: white; text-decoration: none; font-size: 14px; font-weight: 500; padding: 8px 16px; border-radius: 6px; transition: all 0.3s; background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2);" onmouseover="this.style.background='rgba(255, 255, 255, 0.2)'" onmouseout="this.style.background='rgba(255, 255, 255, 0.1)'">首页</a>
|
||||
<a href="#" class="nav-link" style="color: white; text-decoration: none; font-size: 14px; font-weight: 500; padding: 8px 16px; border-radius: 6px; transition: all 0.3s; background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2);" onmouseover="this.style.background='rgba(255, 255, 255, 0.2)'" onmouseout="this.style.background='rgba(255, 255, 255, 0.1)'">监控中心</a>
|
||||
<a href="#" class="nav-link" style="color: white; text-decoration: none; font-size: 14px; font-weight: 500; padding: 8px 16px; border-radius: 6px; transition: all 0.3s; background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2);" onmouseover="this.style.background='rgba(255, 255, 255, 0.2)'" onmouseout="this.style.background='rgba(255, 255, 255, 0.1)'">数据分析</a>
|
||||
<a href="#" class="nav-link" style="color: white; text-decoration: none; font-size: 14px; font-weight: 500; padding: 8px 16px; border-radius: 6px; transition: all 0.3s; background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2);" onmouseover="this.style.background='rgba(255, 255, 255, 0.2)'" onmouseout="this.style.background='rgba(255, 255, 255, 0.1)'">帮助文档</a>
|
||||
<a href="user-center.html" class="nav-link" id="userCenterLink" style="color: white; text-decoration: none; font-size: 14px; font-weight: 500; padding: 8px 16px; border-radius: 6px; transition: all 0.3s; background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2);" onmouseover="this.style.background='rgba(255, 255, 255, 0.2)'" onmouseout="this.style.background='rgba(255, 255, 255, 0.1)'">👤 用户中心</a>
|
||||
<a href="login.html" class="nav-link" id="loginLink" style="color: white; text-decoration: none; font-size: 14px; font-weight: 500; padding: 8px 16px; border-radius: 6px; transition: all 0.3s; background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2);" onmouseover="this.style.background='rgba(255, 255, 255, 0.2)'" onmouseout="this.style.background='rgba(255, 255, 255, 0.1)'">🔐 登录</a>
|
||||
<div id="userMenu" class="user-info" style="display: flex; align-items: center; gap: 10px;"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="container">
|
||||
<header class="header">
|
||||
<h1>🚀 微信公众号文章爬虫系统</h1>
|
||||
@@ -23,13 +39,6 @@
|
||||
<button class="btn btn-primary" onclick="showSection('homepage')">进入</button>
|
||||
</div>
|
||||
|
||||
<div class="card" id="card-single">
|
||||
<div class="card-icon">📄</div>
|
||||
<h3>下载单篇文章</h3>
|
||||
<p>根据链接下载单篇文章</p>
|
||||
<button class="btn btn-primary" onclick="showSection('single')">进入</button>
|
||||
</div>
|
||||
|
||||
<div class="card" id="card-list">
|
||||
<div class="card-icon">📋</div>
|
||||
<h3>获取文章列表</h3>
|
||||
@@ -44,11 +53,11 @@
|
||||
<button class="btn btn-primary" onclick="showSection('batch')">进入</button>
|
||||
</div>
|
||||
|
||||
<div class="card" id="card-data">
|
||||
<div class="card" id="card-detail">
|
||||
<div class="card-icon">📊</div>
|
||||
<h3>数据管理</h3>
|
||||
<p>查看已下载的文章数据</p>
|
||||
<button class="btn btn-primary" onclick="showSection('data')">进入</button>
|
||||
<h3>获取文章详情</h3>
|
||||
<p>获取文章阅读量、点赞数、评论等详细信息</p>
|
||||
<button class="btn btn-primary" onclick="showSection('detail')">进入</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -70,30 +79,6 @@
|
||||
<div class="result" id="homepage-result"></div>
|
||||
</div>
|
||||
|
||||
<!-- 下载单篇文章区域 -->
|
||||
<div class="section" id="section-single" style="display:none;">
|
||||
<div class="section-header">
|
||||
<h2>📄 下载单篇文章</h2>
|
||||
<button class="btn btn-secondary" onclick="showSection('home')">返回</button>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>文章链接:</label>
|
||||
<input type="text" id="article-url" placeholder="请输入微信文章链接...">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="checkbox-label">
|
||||
<input type="checkbox" id="save-image" checked> 保存图片
|
||||
</label>
|
||||
<label class="checkbox-label">
|
||||
<input type="checkbox" id="save-content" checked> 保存内容
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button class="btn btn-success" onclick="downloadSingleArticle()">开始下载</button>
|
||||
</div>
|
||||
<div class="result" id="single-result"></div>
|
||||
</div>
|
||||
|
||||
<!-- 获取文章列表区域 -->
|
||||
<div class="section" id="section-list" style="display:none;">
|
||||
<div class="section-header">
|
||||
@@ -140,20 +125,43 @@
|
||||
<div class="result" id="batch-result"></div>
|
||||
</div>
|
||||
|
||||
<!-- 数据管理区域 -->
|
||||
<div class="section" id="section-data" style="display:none;">
|
||||
<!-- 获取文章详情区域 -->
|
||||
<div class="section" id="section-detail" style="display:none;">
|
||||
<div class="section-header">
|
||||
<h2>📊 数据管理</h2>
|
||||
<h2>📊 获取文章详情</h2>
|
||||
<button class="btn btn-secondary" onclick="showSection('home')">返回</button>
|
||||
</div>
|
||||
<div class="help-text">
|
||||
<p><strong>💡 功能说明:</strong></p>
|
||||
<ul>
|
||||
<li>📈 自动获取公众号所有文章列表</li>
|
||||
<li>📊 下载每篇文章的阅读量、点赞数、分享数等统计数据</li>
|
||||
<li>💬 获取文章评论信息(如果有)</li>
|
||||
<li>📁 保存为TXT格式,便于查看和分析</li>
|
||||
</ul>
|
||||
<p><strong>⚠️ 注意事项:</strong></p>
|
||||
<ul>
|
||||
<li>需要提供有效的Access Token URL(包含登录凭证)</li>
|
||||
<li>处理时间较长,请耐心等待</li>
|
||||
<li>数据将保存在 data/公众号名称/文章详细 目录下</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Access Token URL:</label>
|
||||
<textarea id="detail-access-token" placeholder="请粘贴从Fiddler获取的完整URL...\n\n步骤:\n1. 在浏览器中登录微信公众号平台\n2. 访问目标公众号主页\n3. 向下滚动加载文章列表\n4. 在Fiddler中找到profile_ext?action=getmsg请求\n5. 复制完整的URL(包含__biz、uin、key、pass_ticket等参数)" rows="6"></textarea>
|
||||
<small>示例:https://mp.weixin.qq.com/mp/profile_ext?action=getmsg&__biz=...&uin=...&key=...&pass_ticket=...</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>获取页数:</label>
|
||||
<input type="number" id="detail-pages" value="0" min="0" max="999" placeholder="留空或0表示获取全部">
|
||||
<small>每页约10篇文章,留空或输入0表示获取全部文章</small>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button class="btn btn-info" onclick="loadDataList()">刷新列表</button>
|
||||
<button class="btn btn-warning" onclick="openDataFolder()">打开数据文件夹</button>
|
||||
<button class="btn btn-success" onclick="getArticleDetail()">开始获取</button>
|
||||
<button class="btn btn-info" onclick="loadDetailExample()">查看示例</button>
|
||||
</div>
|
||||
<div class="data-list" id="data-list">
|
||||
<p class="text-center">点击"刷新列表"加载数据...</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="result" id="detail-result"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
@@ -163,5 +171,116 @@
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script src="js/app.js"></script>
|
||||
<script>
|
||||
// 登录状态管理
|
||||
function checkLoginStatus() {
|
||||
// 检查认证数据
|
||||
const authData = localStorage.getItem('authData') || sessionStorage.getItem('authData');
|
||||
|
||||
if (authData) {
|
||||
try {
|
||||
const auth = JSON.parse(authData);
|
||||
const username = auth.user_info && auth.user_info.username ? auth.user_info.username : '用户';
|
||||
showLoggedInState(username);
|
||||
} catch (e) {
|
||||
console.error('解析登录数据失败:', e);
|
||||
showLoggedOutState();
|
||||
}
|
||||
} else {
|
||||
showLoggedOutState();
|
||||
}
|
||||
}
|
||||
|
||||
// 显示已登录状态
|
||||
function showLoggedInState(username) {
|
||||
const loginLink = document.getElementById('loginLink');
|
||||
const userMenu = document.getElementById('userMenu');
|
||||
|
||||
if (loginLink) loginLink.style.display = 'none';
|
||||
if (userMenu) {
|
||||
userMenu.innerHTML = `
|
||||
<span style="margin-right: 10px;">👋 ${username}</span>
|
||||
<button onclick="logout()" style="
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
color: white;
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
padding: 6px 12px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
transition: all 0.3s;
|
||||
" onmouseover="this.style.background='rgba(255, 255, 255, 0.3)'"
|
||||
onmouseout="this.style.background='rgba(255, 255, 255, 0.2)'">
|
||||
退出登录
|
||||
</button>
|
||||
`;
|
||||
userMenu.style.display = 'flex';
|
||||
}
|
||||
}
|
||||
|
||||
// 显示未登录状态
|
||||
function showLoggedOutState() {
|
||||
const loginLink = document.getElementById('loginLink');
|
||||
const userMenu = document.getElementById('userMenu');
|
||||
|
||||
if (loginLink) loginLink.style.display = 'inline';
|
||||
if (userMenu) userMenu.innerHTML = '';
|
||||
}
|
||||
|
||||
// 登出功能
|
||||
function logout() {
|
||||
if (confirm('确定要退出登录吗?')) {
|
||||
// 获取认证数据
|
||||
const authData = localStorage.getItem('authData') || sessionStorage.getItem('authData');
|
||||
let token = '';
|
||||
|
||||
if (authData) {
|
||||
try {
|
||||
const auth = JSON.parse(authData);
|
||||
token = auth.token || '';
|
||||
} catch (e) {
|
||||
console.error('解析token失败:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// 调用后端登出API
|
||||
fetch('http://localhost:8080/api/user/logout', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': token ? `Bearer ${token}` : ''
|
||||
}
|
||||
}).then(response => {
|
||||
// 无论API调用成功与否,都清除本地数据
|
||||
localStorage.removeItem('authData');
|
||||
localStorage.removeItem('isLoggedIn');
|
||||
localStorage.removeItem('username');
|
||||
localStorage.removeItem('token');
|
||||
sessionStorage.removeItem('authData');
|
||||
sessionStorage.removeItem('userSession');
|
||||
|
||||
alert('已成功退出登录!');
|
||||
window.location.href = 'login.html';
|
||||
}).catch(error => {
|
||||
console.error('登出请求失败:', error);
|
||||
// 即使API调用失败,也清除本地数据
|
||||
localStorage.removeItem('authData');
|
||||
localStorage.removeItem('isLoggedIn');
|
||||
localStorage.removeItem('username');
|
||||
localStorage.removeItem('token');
|
||||
sessionStorage.removeItem('authData');
|
||||
sessionStorage.removeItem('userSession');
|
||||
|
||||
alert('已成功退出登录!');
|
||||
window.location.href = 'login.html';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 页面加载时检查登录状态
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
checkLoginStatus();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user