在管理中新增系统日志页面
This commit is contained in:
parent
59f4a25172
commit
9f393ce709
Binary file not shown.
BIN
XNSimHtml/assets/icons/png/file-text.png
Normal file
BIN
XNSimHtml/assets/icons/png/file-text.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.6 KiB |
BIN
XNSimHtml/assets/icons/png/file-text_b.png
Normal file
BIN
XNSimHtml/assets/icons/png/file-text_b.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.4 KiB |
@ -141,6 +141,9 @@ class ContentArea extends HTMLElement {
|
||||
case 'users':
|
||||
contentElement = document.createElement('user-management');
|
||||
break;
|
||||
case 'system-log':
|
||||
contentElement = document.createElement('system-log');
|
||||
break;
|
||||
default:
|
||||
contentElement = document.createElement('div');
|
||||
contentElement.textContent = '正在开发中...';
|
||||
|
@ -97,8 +97,8 @@ class MainToolbar extends HTMLElement {
|
||||
<span>监控</span>
|
||||
</div>
|
||||
<div class="tool-item" data-tool="system" id="systemManagement">
|
||||
<img src="assets/icons/png/cogs.png" alt="系统管理" class="icon">
|
||||
<span>系统管理</span>
|
||||
<img src="assets/icons/png/cogs.png" alt="管理" class="icon">
|
||||
<span>管理</span>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
@ -237,6 +237,10 @@ class SubToolbar extends HTMLElement {
|
||||
<img src="assets/icons/png/user.png" alt="个人中心" class="icon">
|
||||
个人中心
|
||||
</div>
|
||||
<div class="sub-item" data-icon="file-text">
|
||||
<img src="assets/icons/png/file-text.png" alt="系统日志" class="icon">
|
||||
系统日志
|
||||
</div>
|
||||
<div class="sub-item admin-only" data-icon="users">
|
||||
<img src="assets/icons/png/users.png" alt="用户管理" class="icon">
|
||||
用户管理
|
||||
@ -308,7 +312,7 @@ class SubToolbar extends HTMLElement {
|
||||
'config': { icon: 'sliders', text: '配置' },
|
||||
'run': { icon: 'play', text: '运行' },
|
||||
'monitor': { icon: 'chart', text: '监控' },
|
||||
'system': { icon: 'cogs', text: '系统管理' }
|
||||
'system': { icon: 'cogs', text: '管理' }
|
||||
};
|
||||
|
||||
const currentTool = toolIcons[this._currentTool] || toolIcons['home'];
|
||||
|
405
XNSimHtml/components/system-log.js
Normal file
405
XNSimHtml/components/system-log.js
Normal file
@ -0,0 +1,405 @@
|
||||
class SystemLog extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.attachShadow({ mode: 'open' });
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.render();
|
||||
this.addEventListeners();
|
||||
this.loadLogs();
|
||||
}
|
||||
|
||||
render() {
|
||||
this.shadowRoot.innerHTML = `
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.log-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
padding: 16px;
|
||||
background: #f5f7fa;
|
||||
border-radius: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.search-box input {
|
||||
width: 100%;
|
||||
padding: 8px 12px 8px 36px;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.search-box input:focus {
|
||||
border-color: #409eff;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.filter-group {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.filter-select {
|
||||
padding: 8px 12px;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.filter-select:focus {
|
||||
border-color: #409eff;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 8px 16px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: #409eff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: #66b1ff;
|
||||
}
|
||||
|
||||
.btn-default {
|
||||
background: #f4f4f5;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.btn-default:hover {
|
||||
background: #e9e9eb;
|
||||
}
|
||||
|
||||
.log-content {
|
||||
flex: 1;
|
||||
background: #fff;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.log-header {
|
||||
display: grid;
|
||||
grid-template-columns: 180px 120px 120px 1fr;
|
||||
padding: 12px 16px;
|
||||
background: #f5f7fa;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
font-weight: bold;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.log-list {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.log-item {
|
||||
display: grid;
|
||||
grid-template-columns: 180px 120px 120px 1fr;
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.log-item:hover {
|
||||
background: #f5f7fa;
|
||||
}
|
||||
|
||||
.log-level {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.level-info {
|
||||
background: #e1f3d8;
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
.level-warning {
|
||||
background: #fdf6ec;
|
||||
color: #e6a23c;
|
||||
}
|
||||
|
||||
.level-error {
|
||||
background: #fef0f0;
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
.level-debug {
|
||||
background: #f4f4f5;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 16px;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.page-btn {
|
||||
padding: 6px 12px;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
color: #606266;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.page-btn:hover {
|
||||
color: #409eff;
|
||||
border-color: #c6e2ff;
|
||||
}
|
||||
|
||||
.page-btn.active {
|
||||
background: #409eff;
|
||||
color: #fff;
|
||||
border-color: #409eff;
|
||||
}
|
||||
|
||||
.page-btn:disabled {
|
||||
background: #f5f7fa;
|
||||
color: #c0c4cc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
</style>
|
||||
<div class="log-container">
|
||||
<div class="toolbar">
|
||||
<div class="search-box">
|
||||
<img src="assets/icons/png/search_b.png" alt="搜索" class="search-icon">
|
||||
<input type="text" placeholder="搜索日志内容...">
|
||||
</div>
|
||||
<div class="filter-group">
|
||||
<select class="filter-select" id="levelFilter">
|
||||
<option value="">所有级别</option>
|
||||
<option value="info">信息</option>
|
||||
<option value="warning">警告</option>
|
||||
<option value="error">错误</option>
|
||||
<option value="debug">调试</option>
|
||||
</select>
|
||||
<select class="filter-select" id="timeFilter">
|
||||
<option value="1h">最近1小时</option>
|
||||
<option value="6h">最近6小时</option>
|
||||
<option value="24h">最近24小时</option>
|
||||
<option value="7d">最近7天</option>
|
||||
<option value="30d">最近30天</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="action-buttons">
|
||||
<button class="btn btn-default" id="refreshBtn">
|
||||
<img src="assets/icons/png/refresh.png" alt="刷新" class="icon-small">
|
||||
刷新
|
||||
</button>
|
||||
<button class="btn btn-primary" id="exportBtn">
|
||||
<img src="assets/icons/png/download.png" alt="导出" class="icon-small">
|
||||
导出
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="log-content">
|
||||
<div class="log-header">
|
||||
<div>时间</div>
|
||||
<div>级别</div>
|
||||
<div>来源</div>
|
||||
<div>内容</div>
|
||||
</div>
|
||||
<div class="log-list" id="logList">
|
||||
<!-- 日志内容将通过JavaScript动态添加 -->
|
||||
</div>
|
||||
<div class="pagination">
|
||||
<button class="page-btn" id="prevPage" disabled>上一页</button>
|
||||
<button class="page-btn active">1</button>
|
||||
<button class="page-btn">2</button>
|
||||
<button class="page-btn">3</button>
|
||||
<button class="page-btn" id="nextPage">下一页</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
addEventListeners() {
|
||||
// 搜索框事件
|
||||
const searchInput = this.shadowRoot.querySelector('.search-box input');
|
||||
searchInput.addEventListener('input', this.debounce(() => {
|
||||
this.filterLogs();
|
||||
}, 300));
|
||||
|
||||
// 级别筛选事件
|
||||
const levelFilter = this.shadowRoot.querySelector('#levelFilter');
|
||||
levelFilter.addEventListener('change', () => {
|
||||
this.filterLogs();
|
||||
});
|
||||
|
||||
// 时间筛选事件
|
||||
const timeFilter = this.shadowRoot.querySelector('#timeFilter');
|
||||
timeFilter.addEventListener('change', () => {
|
||||
this.filterLogs();
|
||||
});
|
||||
|
||||
// 刷新按钮事件
|
||||
const refreshBtn = this.shadowRoot.querySelector('#refreshBtn');
|
||||
refreshBtn.addEventListener('click', () => {
|
||||
this.loadLogs();
|
||||
});
|
||||
|
||||
// 导出按钮事件
|
||||
const exportBtn = this.shadowRoot.querySelector('#exportBtn');
|
||||
exportBtn.addEventListener('click', () => {
|
||||
this.exportLogs();
|
||||
});
|
||||
|
||||
// 分页按钮事件
|
||||
const prevPage = this.shadowRoot.querySelector('#prevPage');
|
||||
const nextPage = this.shadowRoot.querySelector('#nextPage');
|
||||
prevPage.addEventListener('click', () => {
|
||||
this.changePage(-1);
|
||||
});
|
||||
nextPage.addEventListener('click', () => {
|
||||
this.changePage(1);
|
||||
});
|
||||
}
|
||||
|
||||
async loadLogs() {
|
||||
try {
|
||||
// 这里应该调用后端API获取日志数据
|
||||
// 示例数据
|
||||
const logs = [
|
||||
{
|
||||
timestamp: '2024-03-20 10:00:00',
|
||||
level: 'info',
|
||||
source: '系统',
|
||||
content: '系统启动成功'
|
||||
},
|
||||
{
|
||||
timestamp: '2024-03-20 10:01:00',
|
||||
level: 'warning',
|
||||
source: '数据库',
|
||||
content: '数据库连接池接近最大连接数'
|
||||
},
|
||||
{
|
||||
timestamp: '2024-03-20 10:02:00',
|
||||
level: 'error',
|
||||
source: 'API',
|
||||
content: 'API请求超时'
|
||||
}
|
||||
];
|
||||
|
||||
this.renderLogs(logs);
|
||||
} catch (error) {
|
||||
console.error('加载日志失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
renderLogs(logs) {
|
||||
const logList = this.shadowRoot.querySelector('#logList');
|
||||
logList.innerHTML = logs.map(log => `
|
||||
<div class="log-item">
|
||||
<div>${log.timestamp}</div>
|
||||
<div><span class="log-level level-${log.level}">${this.getLevelText(log.level)}</span></div>
|
||||
<div>${log.source}</div>
|
||||
<div>${log.content}</div>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
getLevelText(level) {
|
||||
const levelMap = {
|
||||
'info': '信息',
|
||||
'warning': '警告',
|
||||
'error': '错误',
|
||||
'debug': '调试'
|
||||
};
|
||||
return levelMap[level] || level;
|
||||
}
|
||||
|
||||
filterLogs() {
|
||||
const searchText = this.shadowRoot.querySelector('.search-box input').value.toLowerCase();
|
||||
const levelFilter = this.shadowRoot.querySelector('#levelFilter').value;
|
||||
const timeFilter = this.shadowRoot.querySelector('#timeFilter').value;
|
||||
|
||||
// 这里应该根据筛选条件调用后端API获取过滤后的日志
|
||||
this.loadLogs();
|
||||
}
|
||||
|
||||
exportLogs() {
|
||||
// 实现日志导出功能
|
||||
console.log('导出日志');
|
||||
}
|
||||
|
||||
changePage(delta) {
|
||||
// 实现分页功能
|
||||
console.log('切换页面:', delta);
|
||||
}
|
||||
|
||||
debounce(func, wait) {
|
||||
let timeout;
|
||||
return function executedFunction(...args) {
|
||||
const later = () => {
|
||||
clearTimeout(timeout);
|
||||
func(...args);
|
||||
};
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('system-log', SystemLog);
|
@ -17,6 +17,7 @@
|
||||
<script src="components/run-log.js"></script>
|
||||
<script src="components/system-info.js"></script>
|
||||
<script src="components/help-component.js"></script>
|
||||
<script src="components/system-log.js"></script>
|
||||
<script src="components/run-env-config.js" type="module"></script>
|
||||
<script src="components/model-config.js" type="module"></script>
|
||||
<script src="components/service-config.js" type="module"></script>
|
||||
@ -323,6 +324,14 @@
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理系统日志标签页
|
||||
if (title === '系统日志') {
|
||||
const id = 'system-log';
|
||||
tabsContainer.createTab(id, title, icon, parentText, parentTool);
|
||||
contentArea.loadContent(id);
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理帮助标签页
|
||||
if (title === '帮助') {
|
||||
const id = 'help';
|
||||
|
Loading…
x
Reference in New Issue
Block a user