mirror of
https://github.com/RobbieHan/sandboxMP.git
synced 2026-02-13 07:34:56 +08:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb10ffe9be |
@@ -14,4 +14,10 @@ urlpatterns = [
|
|||||||
path('portal/code/delete/', views_code.CodeDeleteView.as_view(), name='portal-code-delete'),
|
path('portal/code/delete/', views_code.CodeDeleteView.as_view(), name='portal-code-delete'),
|
||||||
|
|
||||||
path('portal/scan_config/', views_scan.ScanConfigView.as_view(), name='portal-scan_config'),
|
path('portal/scan_config/', views_scan.ScanConfigView.as_view(), name='portal-scan_config'),
|
||||||
|
path('portal/device_scan/', views_scan.DeviceScanView.as_view(), name='portal-device_scan'),
|
||||||
|
path('portal/device_scan/list/', views_scan.DeviceScanListView.as_view(), name='portal-device_scan-list'),
|
||||||
|
path('portal/device_scan/detail/', views_scan.DeviceScanDetailView.as_view(), name='portal-device_scan-detail'),
|
||||||
|
path('portal/device_scan/delete/', views_scan.DeviceScanDeleteView.as_view(), name='portal-device_scan-delete'),
|
||||||
|
path('portal/device_scan/exec/', views_scan.DeviceScanExecView.as_view(), name='portal-device_scan-exec'),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -6,15 +6,16 @@ import ast
|
|||||||
import logging
|
import logging
|
||||||
from ruamel import yaml
|
from ruamel import yaml
|
||||||
|
|
||||||
from django.views.generic import View
|
from django.views.generic import View, TemplateView
|
||||||
from django.http import JsonResponse
|
from django.http import JsonResponse
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render, get_object_or_404
|
||||||
|
|
||||||
|
|
||||||
from system.mixin import LoginRequiredMixin
|
from system.mixin import LoginRequiredMixin
|
||||||
from custom import BreadcrumbMixin
|
from custom import BreadcrumbMixin, SandboxListView, SandboxDeleteView
|
||||||
from utils.sandbox_utils import ConfigFileMixin
|
from utils.sandbox_utils import ConfigFileMixin
|
||||||
from system.models import Menu
|
from system.models import Menu
|
||||||
|
from .models import DeviceScanInfo
|
||||||
|
|
||||||
error_logger = logging.getLogger('sandbox_error')
|
error_logger = logging.getLogger('sandbox_error')
|
||||||
|
|
||||||
@@ -52,3 +53,78 @@ class ScanConfigView(LoginRequiredMixin, BreadcrumbMixin, ConfigFileMixin, View)
|
|||||||
error_logger.error(e)
|
error_logger.error(e)
|
||||||
|
|
||||||
return JsonResponse(ret)
|
return JsonResponse(ret)
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceScanView(LoginRequiredMixin, BreadcrumbMixin, TemplateView):
|
||||||
|
template_name = 'cmdb/device_scan.html'
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceScanListView(SandboxListView):
|
||||||
|
model = DeviceScanInfo
|
||||||
|
fields = ['id', 'sys_hostname', 'hostname', 'mac_address', 'auth_type', 'status', 'os_type', 'device_type']
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceScanDetailView(LoginRequiredMixin, View):
|
||||||
|
|
||||||
|
def get(self, request):
|
||||||
|
ret = Menu.get_menu_by_request_url(request.path_info)
|
||||||
|
if 'id' in request.GET and request.GET['id']:
|
||||||
|
device = get_object_or_404(DeviceScanInfo, pk=int(request.GET['id']))
|
||||||
|
ret['device'] = device
|
||||||
|
return render(request, 'cmdb/device_scan_detail.html', ret)
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceScanDeleteView(SandboxDeleteView):
|
||||||
|
model = DeviceScanInfo
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceScanExecView(LoginRequiredMixin, View):
|
||||||
|
|
||||||
|
def get(self, request):
|
||||||
|
import time
|
||||||
|
from utils.sandbox_utils import SandboxScan, LoginExecution
|
||||||
|
info_logger = logging.getLogger('sandbox_info')
|
||||||
|
ret = dict(result=False)
|
||||||
|
scan = SandboxScan()
|
||||||
|
execution = LoginExecution()
|
||||||
|
scan_type = execution.get_scan_type()
|
||||||
|
auth_type = execution.get_auth_type()
|
||||||
|
start_time = time.time()
|
||||||
|
if scan_type == 'basic_scan':
|
||||||
|
hosts = scan.basic_scan()
|
||||||
|
for host in hosts:
|
||||||
|
DeviceScanInfo.objects.update_or_create(
|
||||||
|
hostname=host,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
hosts = scan.os_scan()
|
||||||
|
login_hosts = [host for host in hosts if host['os'] in ['Linux', 'embedded']]
|
||||||
|
nologin_hosts = [host for host in hosts if host not in login_hosts]
|
||||||
|
for host in nologin_hosts:
|
||||||
|
DeviceScanInfo.objects.update_or_create(
|
||||||
|
hostname=host['host'],
|
||||||
|
defaults={
|
||||||
|
'os_type': host['os']
|
||||||
|
}
|
||||||
|
)
|
||||||
|
for host in login_hosts:
|
||||||
|
kwargs = {
|
||||||
|
'hostname': host['host'],
|
||||||
|
'username': execution.get_ssh_username(),
|
||||||
|
'port': execution.get_ssh_port(),
|
||||||
|
'password': execution.get_ssh_password(),
|
||||||
|
'private_key': execution.get_ssh_private_key()
|
||||||
|
}
|
||||||
|
defaults = execution.login_execution(auth_type=auth_type, **kwargs)
|
||||||
|
DeviceScanInfo.objects.update_or_create(
|
||||||
|
hostname=host['host'],
|
||||||
|
defaults=defaults
|
||||||
|
)
|
||||||
|
end_time = time.time()
|
||||||
|
msg = 'Scan task has been completed, execution time: %(time)s, %(num)s hosts are up.' % {
|
||||||
|
'time': end_time - start_time,
|
||||||
|
'num': len(hosts)
|
||||||
|
}
|
||||||
|
info_logger.info(msg)
|
||||||
|
ret['result'] = True
|
||||||
|
return JsonResponse(ret)
|
||||||
298
templates/cmdb/device_scan.html
Normal file
298
templates/cmdb/device_scan.html
Normal file
@@ -0,0 +1,298 @@
|
|||||||
|
{% extends "base-left.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
|
||||||
|
{% block css %}
|
||||||
|
<link rel="stylesheet" href="{% static 'plugins/datatables/jquery.dataTables.min.css' %}">
|
||||||
|
<link rel="stylesheet" href="{% static 'js/plugins/layer/skin/layer.css' %}">
|
||||||
|
<link rel="stylesheet" href="{% static 'plugins/select2/select2.min.css' %}">
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<!-- Main content -->
|
||||||
|
<section class="content">
|
||||||
|
<div id="devlist">
|
||||||
|
<div class="box box-primary" id="liebiao">
|
||||||
|
<div class="box-header">
|
||||||
|
<div class="btn-group pull-left">
|
||||||
|
<button type="button" id="btnRefresh" class="btn btn-default">
|
||||||
|
<i class="glyphicon glyphicon-repeat"></i> 刷新
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="btn-group pull-left"> </div>
|
||||||
|
<div class="btn-group pull-left">
|
||||||
|
<button type="button" id="btnScan" class="btn btn-default" onclick="doScan()">
|
||||||
|
<i class="glyphicon glyphicon-search"></i> 执行扫描
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="btn-group pull-left"> </div>
|
||||||
|
<div class="btn-group pull-left">
|
||||||
|
<button type="button" id="btnInbound" class="btn btn-default" onclick="doInbound()">
|
||||||
|
<i class="glyphicon glyphicon-floppy-disk"></i> 执行入库
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="btn-group pull-left"> </div>
|
||||||
|
<div class="btn-group pull-left">
|
||||||
|
<button type="button" id="btnDelete" class="btn btn-default">
|
||||||
|
<i class="glyphicon glyphicon-trash"></i> 删除
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="box-body">
|
||||||
|
<table id="dtbList" class="display" cellspacing="0" width="100%">
|
||||||
|
<thead>
|
||||||
|
<tr valign="middle">
|
||||||
|
<th><input type="checkbox" id="checkAll"></th>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>主机名</th>
|
||||||
|
<th>IP地址</th>
|
||||||
|
<th>MAC地址</th>
|
||||||
|
<th>认证类型</th>
|
||||||
|
<th>登陆状态</th>
|
||||||
|
<th>系统类型</th>
|
||||||
|
<th>设备类型</th>
|
||||||
|
<th>操作</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<br>
|
||||||
|
<small>点击【执行入库】可将扫描结果中,登陆状态为:成功(succeed)的设备数据导入正式设备管理数据库。</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- /.content -->
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block javascripts %}
|
||||||
|
|
||||||
|
<script src="{% static 'plugins/datatables/jquery.dataTables.min.js' %}"></script>
|
||||||
|
<script src="{% static 'plugins/datatables/dataTables.const-1.js' %}"></script>
|
||||||
|
<script src="{% static 'js/plugins/layer/layer.js' %}"></script>
|
||||||
|
<script src="{% static 'plugins/select2/select2.full.min.js' %}"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
// 菜单选中高亮
|
||||||
|
$(function () {
|
||||||
|
$('#CMDB-PORTAL').addClass('active');
|
||||||
|
$('#CDMB-PORTAL-DEVICE_SCAN').addClass('active');
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// datatables 初始化配置
|
||||||
|
var oDataTable = null;
|
||||||
|
$(function () {
|
||||||
|
oDataTable = initTable();
|
||||||
|
|
||||||
|
function initTable() {
|
||||||
|
var oTable = $('#dtbList').DataTable($.extend(true, {},
|
||||||
|
DATATABLES_CONSTANT.DATA_TABLES.SERVER_SIDE_OPTION,
|
||||||
|
|
||||||
|
{
|
||||||
|
ajax: {
|
||||||
|
"url": "{% url 'cmdb:portal-device_scan-list' %}",
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
columns: [
|
||||||
|
DATATABLES_CONSTANT.DATA_TABLES.COLUMN.CHECKBOX,
|
||||||
|
{
|
||||||
|
data: "id",
|
||||||
|
width: "5%",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: "sys_hostname",
|
||||||
|
//width : "20%",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: "hostname",
|
||||||
|
//width : "20%",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: "mac_address",
|
||||||
|
//width : "20%",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: "auth_type",
|
||||||
|
//width : "20%",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: "status",
|
||||||
|
render: function (data, type, row, meta) {
|
||||||
|
if (data == "succeed") {
|
||||||
|
var ret = "<button class='btn btn-info btn-xs'>成功</button>";
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (data == "failed") {
|
||||||
|
var ret = "<button class='btn btn-danger btn-xs'>失败</button>";
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var ret = "<button class='btn btn-default btn-xs'>未知</button>";
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: "os_type",
|
||||||
|
//width : "20%",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: "device_type",
|
||||||
|
//width : "20%",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: "id",
|
||||||
|
width: "10%",
|
||||||
|
bSortable: "false",
|
||||||
|
render: function (data, type, row, meta) {
|
||||||
|
var ret = "";
|
||||||
|
var ret = "<button title='详情' onclick='doDetail("
|
||||||
|
+ data + ")'><i class='glyphicon glyphicon-list-alt'></i></button>";
|
||||||
|
ret = ret + "<button title='删除' onclick='doDelete("
|
||||||
|
+ data + ")'><i class='glyphicon glyphicon-trash'></i></button>";
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
}));
|
||||||
|
return oTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// 刷新数据
|
||||||
|
$("#btnRefresh").click(function () {
|
||||||
|
oDataTable.ajax.reload();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function doDetail(id){
|
||||||
|
window.location.href="/cmdb/portal/device_scan/detail/?id="+id;
|
||||||
|
}
|
||||||
|
|
||||||
|
//checkbox全选
|
||||||
|
$("#checkAll").on("click", function () {
|
||||||
|
if ($(this).prop("checked") === true) {
|
||||||
|
$("input[name='checkList']").prop("checked", $(this).prop("checked"));
|
||||||
|
$('#example tbody tr').addClass('selected');
|
||||||
|
} else {
|
||||||
|
$("input[name='checkList']").prop("checked", false);
|
||||||
|
$('#example tbody tr').removeClass('selected');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//批量删除
|
||||||
|
$("#btnDelete").click(function () {
|
||||||
|
if ($("input[name='checkList']:checked").length == 0) {
|
||||||
|
layer.msg("请选择要删除的记录");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var arrId = new Array();
|
||||||
|
$("input[name='checkList']:checked").each(function () {
|
||||||
|
//alert($(this).val());
|
||||||
|
arrId.push($(this).val());
|
||||||
|
});
|
||||||
|
|
||||||
|
sId = arrId.join(',');
|
||||||
|
|
||||||
|
layer.alert('确定删除吗?', {
|
||||||
|
title: '提示'
|
||||||
|
, icon: 3 //0:感叹号 1:对号 2:差号 3:问号 4:小锁 5:哭脸 6:笑脸
|
||||||
|
, time: 0 //不自动关闭
|
||||||
|
, btn: ['YES', 'NO']
|
||||||
|
, yes: function (index) {
|
||||||
|
layer.close(index);
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "{% url 'cmdb:portal-device_scan-delete' %}",
|
||||||
|
data: {"id": sId, csrfmiddlewaretoken: '{{ csrf_token }}'},
|
||||||
|
cache: false,
|
||||||
|
success: function (msg) {
|
||||||
|
if (msg.result) {
|
||||||
|
layer.alert("操作成功", {icon: 1});
|
||||||
|
oDataTable.ajax.reload();
|
||||||
|
} else {
|
||||||
|
//alert(msg.message);
|
||||||
|
layer.alert("操作失败", {icon: 2});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//删除单个数据
|
||||||
|
function doDelete(id) {
|
||||||
|
layer.alert('确定删除吗?', {
|
||||||
|
title: '提示'
|
||||||
|
, icon: 3 //0:感叹号 1:对号 2:差号 3:问号 4:小锁 5:哭脸 6:笑脸
|
||||||
|
, time: 0 //不自动关闭
|
||||||
|
, btn: ['YES', 'NO']
|
||||||
|
, yes: function (index) {
|
||||||
|
layer.close(index);
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "{% url 'cmdb:portal-device_scan-delete' %}",
|
||||||
|
data: {"id": id, csrfmiddlewaretoken: '{{ csrf_token }}'},
|
||||||
|
cache: false,
|
||||||
|
success: function (msg) {
|
||||||
|
if (msg.result) {
|
||||||
|
layer.alert('删除成功', {icon: 1});
|
||||||
|
oDataTable.ajax.reload();
|
||||||
|
} else {
|
||||||
|
//alert(msg.message);
|
||||||
|
layer.alert('删除失败', {icon: 2});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//资产扫描
|
||||||
|
function doScan() {
|
||||||
|
layer.alert('确定开始扫描吗?', {
|
||||||
|
title: '提示'
|
||||||
|
, icon: 3 //0:感叹号 1:对号 2:差号 3:问号 4:小锁 5:哭脸 6:笑脸
|
||||||
|
, time: 0 //不自动关闭
|
||||||
|
, btn: ['YES', 'NO']
|
||||||
|
, yes: function (index) {
|
||||||
|
layer.close(index);
|
||||||
|
$.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: "{% url 'cmdb:portal-device_scan-exec' %}",
|
||||||
|
cache: false,
|
||||||
|
beforeSend:function(){
|
||||||
|
this.layerIndex = layer.load(2, {
|
||||||
|
shade: [0.1,'#fff']
|
||||||
|
});
|
||||||
|
},
|
||||||
|
success: function (msg) {
|
||||||
|
layer.closeAll('loading');
|
||||||
|
if (msg.result) {
|
||||||
|
layer.alert('扫描已完成', {icon: 1});
|
||||||
|
oDataTable.ajax.reload();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//alert(msg.message);
|
||||||
|
layer.alert('扫描失败', {icon: 2});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
113
templates/cmdb/device_scan_detail.html
Normal file
113
templates/cmdb/device_scan_detail.html
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
{% extends "base-left.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
|
||||||
|
{% block css %}
|
||||||
|
<link rel="stylesheet" href="{% static 'js/plugins/layer/skin/layer.css' %}">
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<!-- Main content -->
|
||||||
|
|
||||||
|
<section class="content">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="box box-primary">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">设备详情</h3>
|
||||||
|
|
||||||
|
<div class="box-tools">
|
||||||
|
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i
|
||||||
|
class="fa fa-minus"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box-body no-padding">
|
||||||
|
<div class="btn-group pull-right margin">
|
||||||
|
<button type="button" class="btn btn-primary btn-xs margin-r-5" title="返回" id="btnReturn">
|
||||||
|
<i class="fa fa-undo"> 返回</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-responsive mailbox-messages">
|
||||||
|
<table class="table" id="tbWorkList" style="white-space: nowrap;">
|
||||||
|
<tbody>
|
||||||
|
<tr class="info">
|
||||||
|
<td width="10%"><strong>主机名</strong></td>
|
||||||
|
<td class="text-left">{{ device.sys_hostname }}</td>
|
||||||
|
<td width="10%"><strong>SN编号</strong></td>
|
||||||
|
<td class="text-left">{{ device.sn_number }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>SSH用户名</strong></td>
|
||||||
|
<td>{{ device.username }}</td>
|
||||||
|
<td><strong>SSH端口</strong></td>
|
||||||
|
<td>{{ device.port }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="info">
|
||||||
|
<td><strong>认证类型</strong></td>
|
||||||
|
<td>{{ device.auth_type }}</td>
|
||||||
|
<td><strong>登陆状态</strong></td>
|
||||||
|
<td>{{ device.status }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>IP地址</strong></td>
|
||||||
|
<td>{{ device.hostname }}</td>
|
||||||
|
<td><strong>MAC地址</strong></td>
|
||||||
|
<td>{{ device.mac_address }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="info">
|
||||||
|
<td><strong>系统类型</strong></td>
|
||||||
|
<td>{{ device.os_type }}</td>
|
||||||
|
<td><strong>设备类型</strong></td>
|
||||||
|
<td>{{ device.device_type }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>入库时间</strong></td>
|
||||||
|
<td>{{ device.add_time }}</td>
|
||||||
|
<td><strong>变更时间</strong></td>
|
||||||
|
<td>{{ device.modify_time }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="info">
|
||||||
|
<td><strong>错误信息</strong></td>
|
||||||
|
<td colspan="3">{{ device.error_message }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="box-footer margin-b-10">
|
||||||
|
<small>该设备信息为自动扫描入库设备,不提供修改功能,可通过管理页面【执行入库】按钮将登陆状态为:成功(succeed)的设备迁移到正式设备管理库</small>
|
||||||
|
</div>
|
||||||
|
<!-- /.box-footer -->
|
||||||
|
</div>
|
||||||
|
<!-- /.box-body -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /.col -->
|
||||||
|
<!-- TO DO List -->
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- /.content -->
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block javascripts %}
|
||||||
|
<script src="{% static 'js/plugins/layer/layer.js' %}"></script>
|
||||||
|
<script src="{% static 'plugins/masonry/masonry.js' %}"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function () {
|
||||||
|
$('#CMDB-PORTAL').addClass('active');
|
||||||
|
$('#CDMB-PORTAL-DEVICE_SCAN').addClass('active');
|
||||||
|
|
||||||
|
});
|
||||||
|
//返回
|
||||||
|
$("#btnReturn").click(function () {
|
||||||
|
history.back();
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user