You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

444 lines
16 KiB

{% extends 'base.html' %}
{% block title %}ZFSAFE{% endblock %}
<!-- 在此处可添加样式文件 -->
{% block style_link %}
<link href="{{ url_for('main.static', filename='css/node_tree.css') }}" rel="stylesheet">
{% endblock %}
<!-- 页面样式块 -->
{% block style %}
/* 搜索条件区域居中 */
.search-area {
text-align: center;
margin-bottom: 15px;
}
/* 表格样式 */
.table thead th {
text-align: center; /* 表头居中 */
vertical-align: middle;
}
.table tbody td {
vertical-align: middle;
padding: 0.3rem 0.5rem; /* 缩小单元格上下内边距 */
line-height: 1.5;
}
/* 序号列宽度较小 */
.table thead th.seq-col,
.table tbody td.seq-col {
width: 50px;
text-align: center;
}
/* 分页控件右对齐 */
.pagination {
justify-content: end;
}
/* 左侧任务列表整体样式 */
.task-list {
height: calc(100vh - 210px);
overflow-y: auto;
background-color: #fff;
padding: 5px;
border-right: 1px solid #ddd;
}
/* 每个任务项样式 */
.task-item {
padding: 5px;
margin-bottom: 5px;
background-color: #f9f9f9;
border: 1px solid #eee;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s ease, box-shadow 0.3s ease;
}
/* 任务项选中状态样式 */
.task-item.selected {
background-color: #e6f7ff;
border: 1px solid #1890ff;
box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.2);
}
.task-item:hover {
background-color: #e6f7ff;
}
.task-item.selected {
border-color: #1890ff;
background-color: #bae7ff;
}
/* 任务目标样式,第一行 */
.task-target {
font-weight: bold;
}
/* 任务状态,第二行,有缩进 */
.task-status {
margin-left: 10px;
color: #666;
font-size: 0.8rem;
}
/* 定义一个全高容器,与左侧任务列表高度保持一致 */
.full-height {
height: calc(100vh - 210px);
}
/* 右侧区域采用 flex 布局,垂直排列 */
.right-container {
display: flex;
flex-direction: column;
}
/* 基本信息区域,保持固定高度 */
.basic-info {
/* 根据需要设定高度,或保持内容自适应 */
flex: 0 0 auto;
}
/* Tab 内容区域占满剩余空间 */
.tab-wrapper {
flex: 1 1 auto;
display: flex;
flex-direction: column;
overflow: hidden; /* 防止内部溢出 */
}
/* 导航部分根据内容高度 */
#myTab {
flex: 0 0 auto;
}
.tab-content{
flex: 1 1 auto;
overflow-y: auto;
}
.disabled-btn {
/* 禁用状态样式 */
background-color: #cccccc; /* 灰色背景 */
color: #666666; /* 文字颜色变浅 */
cursor: not-allowed; /* 鼠标显示禁用图标 */
opacity: 0.7; /* 可选:降低透明度 */
/* 禁用点击事件(通过 disabled 属性已实现,此样式仅增强视觉效果) */
pointer-events: none; /* 可选:彻底阻止鼠标事件 */
}
{% endblock %}
{% block modal %}
{% include 'task_manager_modal.html' %}
{% endblock %}
<!-- 页面内容块 -->
{% block content %}
<div class="container mt-4">
<div class="container-fluid">
<div class="row">
<!-- 左侧:任务列表 -->
<div class="col-2 task-list" id="taskList">
<!-- 动态生成的任务项将插入此处 -->
<p>加载中...</p>
</div>
<!-- 右侧:任务详情 -->
<div class="col-10 full-height right-container">
<!-- 上方:基本信息 -->
<div class="row basic-info">
<div class="col-9">
<div class="mb-2">
<label class="fw-bold">测试目标: </label>
<span id="detailTestTarget">192.168.1.110</span>
</div>
<div class="row">
<div class="col-3">
<label class="fw-bold">工作状态: </label>
<span id="detailTestStatus">执行中</span>
</div>
<div class="col-3">
<label class="fw-bold">安全情况: </label>
<span id="detailSafeStatus">安全</span>
</div>
<div class="col-6">
<label class="fw-bold">测试模式: </label>
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
name="testMode"
id="autoMode"
value="auto"
checked
/>
<label class="form-check-label" for="autoMode"
>自动执行</label
>
</div>
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
name="testMode"
id="manualMode"
value="manual"
/>
<label class="form-check-label" for="manualMode"
>人工确认</label
>
</div>
</div>
</div>
</div>
<!-- <div class="col-2" style="display: flex; justify-content: center; align-items: center"> -->
<div class="col-3 d-flex justify-content-center align-items-center">
<!-- 按钮 (联动测试状态示例: 执行中->暂停, 暂停中->继续, 已结束->重启) -->
<button class="btn btn-primary btn-block" id="actionButton">暂停</button>
<button class="btn btn-primary btn-block m-2" id="one_step">单步</button>
<button class="btn btn-danger btn-block m-2" id="btnTaskOver">结束</button>
</div>
</div>
<!-- 下方:Tab 页 -->
<div class="tab-wrapper">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
<button
class="nav-link active"
id="nodeTreeTab"
data-bs-toggle="tab"
data-bs-target="#nodeTree"
type="button"
role="tab"
aria-controls="nodeTree"
aria-selected="true"
>
节点树
</button>
</li>
<li class="nav-item" role="presentation">
<button
class="nav-link"
id="testInstructionsTab"
data-bs-toggle="tab"
data-bs-target="#testInstructions"
type="button"
role="tab"
aria-controls="testInstructions"
aria-selected="false"
>
测试指令
</button>
</li>
<li class="nav-item" role="presentation">
<button
class="nav-link"
id="vulnerabilitiesTab"
data-bs-toggle="tab"
data-bs-target="#vulnerabilities"
type="button"
role="tab"
aria-controls="vulnerabilities"
aria-selected="false"
>
漏洞数据
</button>
</li>
</ul>
<div class="tab-content " id="myTabContent">
<!-- 节点树 -->
<div
class="tab-pane fade show active p-3 h-100"
id="nodeTree"
role="tabpanel"
aria-labelledby="nodeTreeTab"
>
<div class="row h-100">
<!-- 左侧:节点树区域 -->
<div class="col-8 h-100">
<div class="node-tree-area" id="nodeTreeContainer">
<!-- 顶部刷新按钮 -->
<div class="refresh-container">
<button class="tree-refresh" id="btnRefresh" title="刷新节点树">
&#x21bb;
</button>
</div>
<!-- 节点树内容区域 -->
<div id="treeContent" class="tree-content">
<p id="treeLoadingMsg" style="text-align:center;">加载中...</p>
</div>
</div>
</div>
<!-- 右侧:节点信息与操作 -->
<div class="col-4 h-100">
<div class="node-info-area mb-3">
<h5>节点信息</h5>
<p><strong>节点名称:</strong> <span id="nodeName">-</span></p>
<p><strong>测试状态:</strong> <span id="testStatus">-</span></p>
<p><strong>漏洞类型:</strong> <span id="node_vulType">-</span></p>
<p><strong>漏洞级别:</strong> <span id="node_vulLevel">-</span></p>
<p><strong>工作状态:</strong> <span id="node_bwork">-</span></p>
<p><strong>执行状态:</strong> <span id="node_workstatus">-</span></p>
</div>
<div class="node-actions">
<div class="row">
<div class="col-6"><button class="btn btn-primary w-100" id="btnToggleStatus">暂停</button></div>
<div class="col-6"><button class="btn btn-primary w-100" id="btnNodeStep">单步</button></div>
</div>
<div class="row">
<div class="col-6"><button class="btn btn-primary w-100" id="btnViewInstr">查看指令</button></div>
<div class="col-6"><button class="btn btn-primary w-100" id="btnViewMsg">查看MSG</button></div>
</div>
<div class="row">
<div class="col-6"><button class="btn btn-primary w-100" id="btnAddInfo">添加信息</button></div>
<div class="col-6"><button class="btn btn-primary w-100" id="btnAddChild">添加子节点</button></div>
</div>
</div>
</div>
</div>
</div>
<!-- 测试指令 -->
<div
class="tab-pane fade p-3"
id="testInstructions"
role="tabpanel"
aria-labelledby="testInstructionsTab"
>
<!-- 搜索区域 -->
<div class="row search-area">
<div class="col-4">
<input
type="text"
class="form-control"
id="instrNodeName"
placeholder="节点名称"
/>
</div>
<div class="col-2">
<button class="btn btn-primary" id="instrSearchBtn">
查询
</button>
<button class="btn btn-primary" id="instrExportBtn">
导出
</button>
</div>
</div>
<table class="table table-bordered table-hover" id="instrTable" style="width: 100%; table-layout: fixed;">
<colgroup>
<!-- 第一列:序号,固定宽度或百分比 -->
<col style="width: 5%;">
<!-- 第二列:节点路径,例如 25% -->
<col style="width: 15%;">
<!-- 第三列:指令序号,固定宽度 -->
<col style="width: 5%;">
<!-- 第四列:执行指令,设置为固定宽度或者百分比 -->
<col style="width: 30%;" class="wrap-cell">
<!-- 第五列:执行结果,占用剩余所有宽度 -->
<col style="width: auto;">
</colgroup>
<thead>
<tr>
<th>序号</th>
<th>节点路径</th>
<th>指序</th>
<th>执行指令</th>
<th>执行结果</th>
</tr>
</thead>
<tbody>
<!-- 默认显示 10 行(后续用 JS 渲染数据,补空行) -->
</tbody>
</table>
<!-- 分页控件 -->
<nav>
<ul class="pagination" id="instrPagination">
<li class="page-item">
<a class="page-link" href="#" id="instrPrev">上一页</a>
</li>
<li class="page-item">
<a class="page-link" href="#" id="instrNext">下一页</a>
</li>
</ul>
</nav>
</div>
<!-- 漏洞数据 -->
<div
class="tab-pane fade p-3"
id="vulnerabilities"
role="tabpanel"
aria-labelledby="vulnerabilitiesTab"
>
<!-- 搜索区域 -->
<div class="row search-area">
<div class="col-3">
<input
type="text"
class="form-control"
id="vulNodeName"
placeholder="节点名称"
/>
</div>
<div class="col-3">
<input
type="text"
class="form-control"
id="vulType"
placeholder="漏洞类型"
/>
</div>
<div class="col-3">
<select class="form-select" id="vulLevel">
<option value="">漏洞级别</option>
<option value="低危"></option>
<option value="中危"></option>
<option value="高危"></option>
</select>
</div>
<div class="col-2">
<button class="btn btn-primary" id="vulSearchBtn">
查询
</button>
<button class="btn btn-primary" id="vulExportBtn">
导出
</button>
</div>
</div>
<table class="table table-bordered table-hover" id="vulTable">
<thead>
<tr>
<th class="seq-col">序号</th>
<th>节点路径</th>
<th>漏洞类型</th>
<th>漏洞级别</th>
<th>漏洞说明</th>
</tr>
</thead>
<tbody>
<!-- 默认显示 10 行 -->
</tbody>
</table>
<!-- 分页控件 -->
<nav>
<ul class="pagination" id="vulPagination">
<li class="page-item">
<a class="page-link" href="#" id="vulPrev">上一页</a>
</li>
<li class="page-item">
<a class="page-link" href="#" id="vulNext">下一页</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
<!-- 页面脚本块 -->
{% block script %}
<!-- 在此处可添加与后端交互的脚本 -->
<script src="{{ url_for('main.static', filename='scripts/my_web_socket.js') }}"></script>
<script src="{{ url_for('main.static', filename='scripts/task_manager.js') }}"></script>
<script src="{{ url_for('main.static', filename='scripts/node_tree.js') }}"></script>
<script src="{{ url_for('main.static', filename='scripts/jquery-3.2.1.slim.min.js') }}"></script>
{% endblock %}