Kamixitong/app/web/templates/log/list.html

280 lines
11 KiB
HTML
Raw Normal View History

2025-11-15 23:57:24 +08:00
{% extends "base.html" %}
{% block title %}操作日志{% endblock %}
{% block content %}
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">操作日志</h3>
</div>
<div class="card-body">
<!-- 筛选表单 -->
<form id="logFilterForm" class="mb-3">
<div class="row">
<div class="col-md-3">
<label for="action" class="form-label">操作类型</label>
<select class="form-select" id="action" name="action">
<option value="">全部</option>
</select>
</div>
<div class="col-md-3">
<label for="target_type" class="form-label">目标类型</label>
<select class="form-select" id="target_type" name="target_type">
<option value="">全部</option>
<option value="ADMIN">管理员</option>
<option value="PRODUCT">产品</option>
<option value="VERSION">版本</option>
<option value="LICENSE">卡密</option>
<option value="DEVICE">设备</option>
<option value="TICKET">工单</option>
</select>
</div>
<div class="col-md-3">
<label for="start_date" class="form-label">开始日期</label>
<input type="date" class="form-control" id="start_date" name="start_date">
</div>
<div class="col-md-3">
<label for="end_date" class="form-label">结束日期</label>
<input type="date" class="form-control" id="end_date" name="end_date">
</div>
</div>
<div class="row mt-2">
<div class="col-md-12">
<button type="submit" class="btn btn-primary">筛选</button>
<button type="button" class="btn btn-secondary" id="resetFilter">重置</button>
</div>
</div>
</form>
<!-- 日志表格 -->
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>ID</th>
<th>操作员</th>
<th>操作类型</th>
<th>目标类型</th>
<th>目标ID</th>
<th>详情</th>
<th>IP地址</th>
<th>时间</th>
</tr>
</thead>
<tbody id="logTableBody">
<!-- 日志数据将通过AJAX加载 -->
</tbody>
</table>
</div>
<!-- 分页 -->
<div id="pagination" class="d-flex justify-content-center">
<!-- 分页控件将通过JavaScript生成 -->
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 系统日志模态框 -->
<div class="modal fade" id="systemLogModal" tabindex="-1" aria-labelledby="systemLogModalLabel" aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="systemLogModalLabel">系统日志</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<pre id="systemLogContent" style="max-height: 500px; overflow-y: auto;"></pre>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
// 全局变量
let currentPage = 1;
const perPage = 20;
// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', function() {
// 加载操作类型列表
loadActionList();
// 加载日志数据
loadLogs();
// 绑定筛选表单事件
document.getElementById('logFilterForm').addEventListener('submit', function(e) {
e.preventDefault();
currentPage = 1;
loadLogs();
});
// 绑定重置按钮事件
document.getElementById('resetFilter').addEventListener('click', function() {
document.getElementById('logFilterForm').reset();
currentPage = 1;
loadLogs();
});
});
// 加载操作类型列表
function loadActionList() {
2025-11-22 16:48:45 +08:00
apiRequest('/api/v1/logs/actions')
2025-11-15 23:57:24 +08:00
.then(data => {
if (data.success) {
const actionSelect = document.getElementById('action');
data.data.actions.forEach(action => {
const option = document.createElement('option');
option.value = action;
option.textContent = action;
actionSelect.appendChild(option);
});
}
})
.catch(error => {
console.error('加载操作类型列表失败:', error);
});
}
// 加载日志数据
function loadLogs(page = 1) {
currentPage = page;
// 构建查询参数
const params = new URLSearchParams();
params.append('page', currentPage);
params.append('per_page', perPage);
// 添加筛选条件
const action = document.getElementById('action').value;
const target_type = document.getElementById('target_type').value;
const start_date = document.getElementById('start_date').value;
const end_date = document.getElementById('end_date').value;
if (action) params.append('action', action);
if (target_type) params.append('target_type', target_type);
if (start_date) params.append('start_date', start_date);
if (end_date) params.append('end_date', end_date);
// 发送请求
2025-11-22 16:48:45 +08:00
apiRequest(`/api/v1/logs?${params.toString()}`)
2025-11-15 23:57:24 +08:00
.then(data => {
if (data.success) {
renderLogs(data.data.logs);
renderPagination(data.data.pagination);
} else {
alert('加载日志失败: ' + data.message);
}
})
.catch(error => {
console.error('加载日志失败:', error);
alert('加载日志失败,请稍后重试');
});
}
// 渲染日志数据
function renderLogs(logs) {
const tbody = document.getElementById('logTableBody');
tbody.innerHTML = '';
if (logs.length === 0) {
const tr = document.createElement('tr');
tr.innerHTML = '<td colspan="8" class="text-center">暂无日志数据</td>';
tbody.appendChild(tr);
return;
}
logs.forEach(log => {
const tr = document.createElement('tr');
tr.innerHTML = `
<td>${log.log_id}</td>
<td>${log.admin_username || '系统'}</td>
<td>${log.action}</td>
<td>${log.target_type}</td>
<td>${log.target_id || '-'}</td>
<td>
${log.details ? `<button class="btn btn-sm btn-info" onclick="showDetails('${log.details}')">查看详情</button>` : '-'}
</td>
<td>${log.ip_address || '-'}</td>
<td>${log.create_time}</td>
`;
tbody.appendChild(tr);
});
}
// 渲染分页控件
function renderPagination(pagination) {
const paginationDiv = document.getElementById('pagination');
paginationDiv.innerHTML = '';
if (pagination.pages <= 1) {
return;
}
// 上一页按钮
if (pagination.has_prev) {
const prevButton = document.createElement('button');
prevButton.className = 'btn btn-outline-primary me-1';
prevButton.textContent = '上一页';
prevButton.onclick = () => loadLogs(pagination.page - 1);
paginationDiv.appendChild(prevButton);
}
// 页码按钮
for (let i = 1; i <= pagination.pages; i++) {
const pageButton = document.createElement('button');
pageButton.className = `btn ${i === pagination.page ? 'btn-primary' : 'btn-outline-primary'} me-1`;
pageButton.textContent = i;
pageButton.onclick = () => loadLogs(i);
paginationDiv.appendChild(pageButton);
}
// 下一页按钮
if (pagination.has_next) {
const nextButton = document.createElement('button');
nextButton.className = 'btn btn-outline-primary ms-1';
nextButton.textContent = '下一页';
nextButton.onclick = () => loadLogs(pagination.page + 1);
paginationDiv.appendChild(nextButton);
}
}
// 显示详情
function showDetails(details) {
try {
const parsedDetails = JSON.parse(details);
alert(JSON.stringify(parsedDetails, null, 2));
} catch (e) {
alert(details);
}
}
// 查看系统日志
function viewSystemLogs() {
2025-11-22 16:48:45 +08:00
apiRequest('/api/v1/logs/file')
2025-11-15 23:57:24 +08:00
.then(data => {
if (data.success) {
document.getElementById('systemLogContent').textContent = data.data.content;
new bootstrap.Modal(document.getElementById('systemLogModal')).show();
} else {
alert('加载系统日志失败: ' + data.message);
}
})
.catch(error => {
console.error('加载系统日志失败:', error);
alert('加载系统日志失败,请稍后重试');
});
}
</script>
{% endblock %}