Files
shengkao_pachong/view/admin/index.html
2026-01-21 11:44:35 +08:00

494 lines
18 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>系统管理 - 职位信息爬虫工具</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
background: #f5f5f5;
padding: 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
padding: 30px;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30px;
padding-bottom: 20px;
border-bottom: 2px solid #4CAF50;
}
h1 {
color: #333;
font-size: 24px;
}
.nav-links {
display: flex;
gap: 15px;
}
.nav-links a {
color: #2196F3;
text-decoration: none;
padding: 8px 15px;
border-radius: 4px;
transition: background 0.3s;
}
.nav-links a:hover {
background: #e3f2fd;
}
.form-section {
margin-bottom: 30px;
padding: 20px;
background: #f9f9f9;
border-radius: 6px;
border: 1px solid #e0e0e0;
}
.form-section h2 {
font-size: 18px;
color: #555;
margin-bottom: 15px;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
color: #333;
font-weight: 500;
}
.form-group input {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
.btn {
padding: 10px 20px;
background: #4CAF50;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: background 0.3s;
}
.btn:hover {
background: #45a049;
}
.btn-danger {
background: #f44336;
}
.btn-danger:hover {
background: #da190b;
}
.message {
padding: 12px;
border-radius: 4px;
margin-bottom: 15px;
}
.message.success {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.message.error {
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
table {
width: 100%;
border-collapse: collapse;
background: #fff;
}
table th,
table td {
padding: 12px;
text-align: left;
border: 1px solid #ddd;
}
table th {
background: #4CAF50;
color: #fff;
font-weight: 600;
}
table tr:nth-child(even) {
background: #f9f9f9;
}
table tr:hover {
background: #f0f0f0;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>系统管理</h1>
<div class="nav-links">
<a href="/crawler">爬虫工具</a>
<a href="/auth/logout">退出登录</a>
</div>
</div>
<!-- BASE_URL配置 -->
<div class="form-section">
<h2>BASE_URL配置</h2>
<div id="baseurl-message"></div>
<div class="form-group">
<label for="base-url">BASE_URL域名和端口</label>
<input type="text" id="base-url" placeholder="例如http://gzrsks.oumakspt.com:62">
<small style="color: #666; margin-top: 5px; display: block;">这是爬虫目标网站的基础URL不含路径</small>
</div>
<button class="btn" onclick="saveBaseUrl()">保存配置</button>
</div>
<!-- 账号列表 -->
<div class="form-section">
<div style="display: flex; justify-content: space-between; align-items: center;">
<h2 style="margin: 0;">账号列表</h2>
<button class="btn" style="background:#2196F3;" onclick="openAddUserModal()">添加账号</button>
</div>
<div id="list-message"></div>
<table id="users-table">
<thead>
<tr>
<th>用户名</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="users-tbody">
<tr>
<td colspan="3" style="text-align: center;">加载中...</td>
</tr>
</tbody>
</table>
</div>
</div>
<script>
const API_BASE_URL = '';
// 页面加载时获取配置和账号列表
window.onload = function() {
loadBaseUrl();
loadUsers();
};
// 加载BASE_URL配置
function loadBaseUrl() {
fetch(API_BASE_URL + '/admin/getBaseUrl', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
}
})
.then(response => response.json())
.then(data => {
if (data.code === 1) {
document.getElementById('base-url').value = data.data.base_url || '';
} else {
showMessage('baseurl-message', data.msg || '获取失败', 'error');
}
})
.catch(error => {
showMessage('baseurl-message', '请求失败: ' + error.message, 'error');
});
}
// 保存BASE_URL配置
function saveBaseUrl() {
const baseUrl = document.getElementById('base-url').value.trim();
if (!baseUrl) {
showMessage('baseurl-message', 'BASE_URL不能为空', 'error');
return;
}
fetch(API_BASE_URL + '/admin/setBaseUrl', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-Requested-With': 'XMLHttpRequest',
},
body: `base_url=${encodeURIComponent(baseUrl)}`
})
.then(response => response.json())
.then(data => {
if (data.code === 1) {
showMessage('baseurl-message', data.msg || '保存成功', 'success');
} else {
showMessage('baseurl-message', data.msg || '保存失败', 'error');
}
})
.catch(error => {
showMessage('baseurl-message', '请求失败: ' + error.message, 'error');
});
}
// 加载账号列表
function loadUsers() {
fetch(API_BASE_URL + '/admin/getUsers', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
}
})
.then(response => response.json())
.then(data => {
if (data.code === 1) {
displayUsers(data.data);
} else {
showMessage('list-message', data.msg || '获取失败', 'error');
}
})
.catch(error => {
showMessage('list-message', '请求失败: ' + error.message, 'error');
});
}
// 显示账号列表
function displayUsers(users) {
const tbody = document.getElementById('users-tbody');
tbody.innerHTML = '';
// 添加管理员账号(只显示,不能删除)
const adminRow = document.createElement('tr');
adminRow.innerHTML = `
<td>admin</td>
<td>-</td>
<td><span style="color: #999;">系统管理员</span></td>
`;
tbody.appendChild(adminRow);
// 添加普通用户
if (users.length === 0) {
const row = document.createElement('tr');
row.innerHTML = '<td colspan="3" style="text-align: center;">暂无账号</td>';
tbody.appendChild(row);
} else {
users.forEach(user => {
const row = document.createElement('tr');
row.innerHTML = `
<td>${user.username || ''}</td>
<td>${user.created_at || '-'}</td>
<td>
<button class="btn" style="background:#2196F3; margin-right:8px;" onclick="openUserModal('${user.username}')">修改</button>
<button class="btn btn-danger" onclick="deleteUser('${user.username}')">删除</button>
</td>
`;
tbody.appendChild(row);
});
}
}
// 打开添加账号弹窗
function openAddUserModal() {
document.getElementById('add-modal-username').value = '';
document.getElementById('add-modal-password').value = '';
document.getElementById('add-modal-message').innerHTML = '';
document.getElementById('add-user-modal').style.display = 'flex';
}
function closeAddUserModal() {
document.getElementById('add-user-modal').style.display = 'none';
}
function submitAddUserModal() {
const username = document.getElementById('add-modal-username').value.trim();
const password = document.getElementById('add-modal-password').value.trim();
if (!username || !password) {
showMessage('add-modal-message', '请输入用户名和密码', 'error');
return;
}
fetch(API_BASE_URL + '/admin/addUser', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-Requested-With': 'XMLHttpRequest',
},
body: `username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}`
})
.then(response => response.json())
.then(data => {
if (data.code === 1) {
showMessage('add-modal-message', data.msg || '添加成功', 'success');
setTimeout(() => {
closeAddUserModal();
loadUsers();
}, 600);
} else {
showMessage('add-modal-message', data.msg || '添加失败', 'error');
}
})
.catch(error => {
showMessage('add-modal-message', '请求失败: ' + error.message, 'error');
});
}
// 打开用户编辑弹窗(用户名+密码)
function openUserModal(username) {
document.getElementById('user-modal-username').value = username || '';
document.getElementById('user-modal-password').value = '';
document.getElementById('user-modal-message').innerHTML = '';
document.getElementById('user-modal').style.display = 'flex';
}
function closeUserModal() {
document.getElementById('user-modal').style.display = 'none';
}
function submitUserModal() {
const username = document.getElementById('user-modal-username').value.trim();
const password = document.getElementById('user-modal-password').value.trim();
if (!username || !password) {
showMessage('user-modal-message', '请输入用户名和新密码', 'error');
return;
}
fetch(API_BASE_URL + '/admin/resetUserPassword', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-Requested-With': 'XMLHttpRequest',
},
body: `username=${encodeURIComponent(username)}&new_password=${encodeURIComponent(password)}`
})
.then(response => response.json())
.then(data => {
if (data.code === 1) {
showMessage('user-modal-message', data.msg || '修改成功', 'success');
setTimeout(() => {
closeUserModal();
loadUsers();
}, 600);
} else {
showMessage('user-modal-message', data.msg || '修改失败', 'error');
}
})
.catch(error => {
showMessage('user-modal-message', '请求失败: ' + error.message, 'error');
});
}
// 删除账号
function deleteUser(username) {
if (!confirm('确定要删除账号 "' + username + '" 吗?')) {
return;
}
fetch(API_BASE_URL + '/admin/deleteUser', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-Requested-With': 'XMLHttpRequest',
},
body: `username=${encodeURIComponent(username)}`
})
.then(response => response.json())
.then(data => {
if (data.code === 1) {
showMessage('list-message', data.msg || '删除成功', 'success');
loadUsers();
} else {
showMessage('list-message', data.msg || '删除失败', 'error');
}
})
.catch(error => {
showMessage('list-message', '请求失败: ' + error.message, 'error');
});
}
// 显示消息
function showMessage(containerId, message, type) {
const container = document.getElementById(containerId);
container.innerHTML = `<div class="message ${type}">${message}</div>`;
}
</script>
<!-- 添加账号弹窗 -->
<div class="modal-overlay" id="add-user-modal" style="display:none; align-items:center; justify-content:center; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.45); z-index:999;">
<div class="modal" style="background:#fff; padding:20px; border-radius:8px; width:360px; max-width:90%; box-shadow:0 4px 12px rgba(0,0,0,0.2);">
<h3>添加账号</h3>
<div id="add-modal-message"></div>
<div class="form-group">
<label for="add-modal-username">用户名:</label>
<input type="text" id="add-modal-username" placeholder="请输入用户名">
</div>
<div class="form-group">
<label for="add-modal-password">密码:</label>
<input type="password" id="add-modal-password" placeholder="请输入密码">
</div>
<div class="modal-actions">
<button class="btn btn-secondary" style="background:#9e9e9e;" onclick="closeAddUserModal()">取消</button>
<button class="btn" onclick="submitAddUserModal()">保存</button>
</div>
</div>
</div>
<!-- 用户编辑弹窗(用户名+密码) -->
<div class="modal-overlay" id="user-modal" style="display:none; align-items:center; justify-content:center; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.45); z-index:999;">
<div class="modal" style="background:#fff; padding:20px; border-radius:8px; width:360px; max-width:90%; box-shadow:0 4px 12px rgba(0,0,0,0.2);">
<h3>修改用户</h3>
<div id="user-modal-message"></div>
<div class="form-group">
<label for="user-modal-username">用户名:</label>
<input type="text" id="user-modal-username" placeholder="请输入用户名">
</div>
<div class="form-group">
<label for="user-modal-password">新密码:</label>
<input type="password" id="user-modal-password" placeholder="请输入新密码">
</div>
<div class="modal-actions">
<button class="btn btn-secondary" style="background:#9e9e9e;" onclick="closeUserModal()">取消</button>
<button class="btn" onclick="submitUserModal()">保存</button>
</div>
</div>
</div>
</body>
</html>