mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-10-22 08:19:04 +00:00
merge update...
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
<!-- highcharts -->
|
||||
<script src="/static/js/highcharts/highcharts.js"></script>
|
||||
|
||||
|
||||
<script src="/static/js/dropzone/dropzone.js"></script>
|
||||
<!-- active menu -->
|
||||
<script>
|
||||
|
@@ -8,4 +8,5 @@
|
||||
<!-- validator js -->
|
||||
<script src="/static/js/validator/jquery.validator.js"></script>
|
||||
<script src="/static/js/validator/zh_CN.js"></script>
|
||||
<script src="/static/js/datapicker/bootstrap-datepicker.js"></script>
|
||||
|
||||
|
@@ -14,7 +14,7 @@
|
||||
</div>
|
||||
<div class="ibox-content">
|
||||
<h1 class="no-margins"><a href="/juser/user_list/">{{ users.count}}</a></h1>
|
||||
<div class="stat-percent font-bold text-success">{{ percent_user }} <i class="fa fa-bolt"></i></div>
|
||||
{# <div class="stat-percent font-bold text-success">{{ percent_user }} <i class="fa fa-bolt"></i></div>#}
|
||||
<small>All user</small>
|
||||
</div>
|
||||
</div>
|
||||
@@ -27,7 +27,7 @@
|
||||
</div>
|
||||
<div class="ibox-content">
|
||||
<h1 class="no-margins"><a href="/jasset/host_list/">{{ hosts.count }}</a></h1>
|
||||
<div class="stat-percent font-bold text-info">{{ percent_host }} <i class="fa fa-level-up"></i></div>
|
||||
{# <div class="stat-percent font-bold text-info">{{ percent_host }} <i class="fa fa-level-up"></i></div>#}
|
||||
<small>All host</small>
|
||||
</div>
|
||||
</div>
|
||||
@@ -40,8 +40,8 @@
|
||||
<h5>实时在线用户</h5>
|
||||
</div>
|
||||
<div class="ibox-content">
|
||||
<h1 class="no-margins"><a href="/jlog/log_list/online/"> <span id="online_users"></span></a></h1>
|
||||
<div class="stat-percent font-bold text-navy">{{ percent_online_user }} <i class="fa fa-level-up"></i></div>
|
||||
<h1 class="no-margins"><a href="/jlog/log_list/online/"> <span id="online_users">{{ online_user | length }}</span></a></h1>
|
||||
{# <div class="stat-percent font-bold text-navy">{{ percent_online_user }} <i class="fa fa-level-up"></i></div>#}
|
||||
<small>Online user</small>
|
||||
</div>
|
||||
</div>
|
||||
@@ -54,15 +54,15 @@
|
||||
<h5>已连接服务器</h5>
|
||||
</div>
|
||||
<div class="ibox-content">
|
||||
<h1 class="no-margins"><a href="/jlog/log_list/online/"> <span id="online_hosts"></span></a></h1>
|
||||
<div class="stat-percent font-bold text-danger">{{ percent_online_host }} <i class="fa fa-level-down"></i></div>
|
||||
<h1 class="no-margins"><a href="/jlog/log_list/online/"> <span id="online_hosts">{{ online_host | length }}</span></a></h1>
|
||||
{# <div class="stat-percent font-bold text-danger">{{ percent_online_host }} <i class="fa fa-level-down"></i></div>#}
|
||||
<small>Connected host</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-3 border-bottom white-bg dashboard-header" style="margin-left:15px;height: 346px">
|
||||
<div class="col-sm-2 border-bottom white-bg dashboard-header" style="margin-left:15px;height: 346px">
|
||||
<h2>活跃用户TOP5</h2>
|
||||
<small>过去一周共有<span class="text-info">{{ week_users }}</span>位用户登录<span class="text-success">{{ week_hosts }}</span>次服务器.</small>
|
||||
<ul class="list-group clear-list m-t">
|
||||
@@ -76,7 +76,32 @@
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-lg-9" id="top10" style="margin-left: -15px;height: 345px"></div>
|
||||
<div class="col-sm-7" id="top10" style="margin-left: -15px;height: 346px;padding: 15px 0 15px 0;"></div>
|
||||
<div class="col-lg-3 white-bg" id="top1" style="margin-left: -15px;height: 346px">
|
||||
<div class="statistic-box">
|
||||
<h4>
|
||||
活跃用户资产占比
|
||||
</h4>
|
||||
<p>
|
||||
以下图形分别描述一个月活跃用户和资产占所有用户主机的百分比
|
||||
</p>
|
||||
<div class="row text-center">
|
||||
<div class="col-lg-6">
|
||||
<div id="activeUser" style="width: 140px; height: 140px;">
|
||||
|
||||
</div>
|
||||
<h5>用户</h5>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div id="activeAsset" style="width: 140px; height: 140px;"></div>
|
||||
<h5>主机</h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-t">
|
||||
<small></small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
@@ -126,6 +151,51 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<h5>一周Top10资产</h5>
|
||||
<div class="ibox-tools">
|
||||
<a class="collapse-link">
|
||||
<i class="fa fa-chevron-up"></i>
|
||||
</a>
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-user"></ul>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ibox-content ibox-heading">
|
||||
<h3><i class="fa fa-user"></i> 一周Top10资产 </h3>
|
||||
<small><i class="fa fa-map-marker"></i> 登录次数及最近一次登录记录. </small>
|
||||
</div>
|
||||
<div class="ibox-content inspinia-timeline">
|
||||
{% if host_top_ten %}
|
||||
{% for data in host_top_ten %}
|
||||
<div class="timeline-item">
|
||||
<div class="row">
|
||||
<div class="col-xs-5 date">
|
||||
<i class="fa fa-info-circle"></i>
|
||||
<strong>{{ data.host }}</strong>
|
||||
<br/>
|
||||
<small class="text-navy">{{ data.times }}次</small>
|
||||
</div>
|
||||
<div class="col-xs-7 content no-top-border">
|
||||
<p class="m-b-xs">最近一次登录用户</p>
|
||||
<p>{{ data.last.user }}</p>
|
||||
<p>于{{ data.last.start_time |date:"Y-m-d H:i:s" }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<p class="text-center">(暂无)</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="ibox float-e-margins">
|
||||
@@ -137,7 +207,7 @@
|
||||
</div>
|
||||
<div class="ibox-content ibox-heading">
|
||||
<h3><i class="fa fa-paper-plane-o"></i> 登录记录 </h3>
|
||||
<small<i class="fa fa-map-marker"></i> 最近十次登录记录. </small>
|
||||
<small><i class="fa fa-map-marker"></i> 最近十次登录记录. </small>
|
||||
</div>
|
||||
<div class="ibox-content">
|
||||
<div>
|
||||
@@ -212,7 +282,7 @@
|
||||
</div>
|
||||
<div class="ibox-content ibox-heading">
|
||||
<h3><i class="fa fa-user"></i> 一周Top10用户 </h3>
|
||||
<small><i class="fa fa-map-marker"></i> 一周Top10用户登录次数及最近一次登录记录. </small>
|
||||
<small><i class="fa fa-map-marker"></i> 用户登录次数及最近一次登录记录. </small>
|
||||
</div>
|
||||
<div class="ibox-content inspinia-timeline">
|
||||
{% if user_top_ten %}
|
||||
@@ -226,7 +296,7 @@
|
||||
<small class="text-navy">{{ data.times }}次</small>
|
||||
</div>
|
||||
<div class="col-xs-7 content no-top-border">
|
||||
<p class="m-b-xs">最近一次登录</p>
|
||||
<p class="m-b-xs">最近一次登录主机</p>
|
||||
<p>{{ data.last.host }}</p>
|
||||
<p>于{{ data.last.start_time |date:"Y-m-d H:i:s" }}</p>
|
||||
</div>
|
||||
@@ -247,162 +317,257 @@
|
||||
<!--<div class="col-lg-6" id="hosttop10" style="width:50%;height:400px; margin-top: 20px"></div>-->
|
||||
<!--</div>-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block self_footer_js %}
|
||||
<script src="/static/js/echarts/echarts.js"></script>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
$('#show').click(function(){
|
||||
$('#show').css('display', 'none');
|
||||
$('#more').css('display', 'block');
|
||||
})
|
||||
})
|
||||
var cate = {{ li_str|safe }};
|
||||
$(function () {
|
||||
$('#top10').highcharts({
|
||||
// chart: {
|
||||
// type: 'column'
|
||||
// },
|
||||
title: {
|
||||
text: '一周数据总览',
|
||||
x: -20 //center
|
||||
},
|
||||
subtitle: {
|
||||
text: 'Source: JumpServer',
|
||||
x: -20
|
||||
},
|
||||
rangeSelector: {
|
||||
allButtonsEnabled: true,
|
||||
selected: 2
|
||||
},
|
||||
xAxis: {
|
||||
type: 'datetime',
|
||||
categories: cate
|
||||
},
|
||||
yAxis:{
|
||||
min: 0,
|
||||
title: {
|
||||
text: ''
|
||||
},
|
||||
plotLines: [{
|
||||
value: 0,
|
||||
width: 1,
|
||||
color: '#808080'
|
||||
}]
|
||||
},
|
||||
tooltip: {
|
||||
valueSuffix: '次'
|
||||
},
|
||||
navigation: {
|
||||
buttonOptions: {
|
||||
align: 'right'
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{% for k,v in top_dic.items %}
|
||||
{
|
||||
name: '{{ k }}',
|
||||
data: {{ v }}
|
||||
},
|
||||
{% endfor %}
|
||||
]
|
||||
});
|
||||
|
||||
$('#usertop10').highcharts({
|
||||
title: {
|
||||
text: '一周用户登录TOP10',
|
||||
x: -20 //center
|
||||
},
|
||||
subtitle: {
|
||||
text: 'Source: JumpServer',
|
||||
x: -20
|
||||
},
|
||||
xAxis: {
|
||||
type: 'datetime',
|
||||
categories: cate
|
||||
},
|
||||
yAxis:{
|
||||
min: 0,
|
||||
title: {
|
||||
text: '登录次数'
|
||||
},
|
||||
plotLines: [{
|
||||
value: 0,
|
||||
width: 1,
|
||||
color: '#808080'
|
||||
}]
|
||||
},
|
||||
tooltip: {
|
||||
valueSuffix: '次'
|
||||
},
|
||||
series: [
|
||||
{% for k,v in user_dic.items %}
|
||||
{
|
||||
name: '{{ k }}',
|
||||
data: {{ v }}
|
||||
},
|
||||
{% endfor %}
|
||||
]
|
||||
});
|
||||
|
||||
$('#hosttop10').highcharts({
|
||||
title: {
|
||||
text: '一周主机登录TOP10',
|
||||
x: -20 //center
|
||||
},
|
||||
subtitle: {
|
||||
text: 'Source: JumpServer',
|
||||
x: -20
|
||||
},
|
||||
xAxis: {
|
||||
type: 'datetime',
|
||||
categories: cate
|
||||
},
|
||||
yAxis:{
|
||||
min: 0,
|
||||
title: {
|
||||
text: '登录次数'
|
||||
},
|
||||
plotLines: [{
|
||||
value: 0,
|
||||
width: 1,
|
||||
color: '#808080'
|
||||
}]
|
||||
},
|
||||
tooltip: {
|
||||
valueSuffix: '次'
|
||||
},
|
||||
series: [
|
||||
{% for k,v in host_dic.items %}
|
||||
{
|
||||
name: '{{ k }}',
|
||||
data: {{ v }}
|
||||
},
|
||||
{% endfor %}
|
||||
]
|
||||
});
|
||||
|
||||
function magic_number(value, id) {
|
||||
var num = $("#"+id);
|
||||
num.animate({count: value}, {
|
||||
duration: 500,
|
||||
step: function() {
|
||||
num.text(String(parseInt(this.count)));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function update() {
|
||||
$.getJSON('api/user/', function(data) {
|
||||
var users = data.users;
|
||||
var hosts = data.hosts;
|
||||
magic_number(users, 'online_users');
|
||||
magic_number(hosts, 'online_hosts')
|
||||
});
|
||||
};
|
||||
|
||||
setInterval(update, 5000); //5秒钟执行一次
|
||||
update();
|
||||
|
||||
});
|
||||
|
||||
require.config({
|
||||
paths: {
|
||||
'echarts': '/static/js/echarts/chart',
|
||||
'echarts/chart/line': '/static/js/echarts/chart/line',
|
||||
'echarts/chart/pie': '/static/js/echarts/chart/pie'
|
||||
}
|
||||
});
|
||||
require(
|
||||
[
|
||||
'echarts',
|
||||
'echarts/chart/line'
|
||||
],
|
||||
function (ec) {
|
||||
var top10Chart = ec.init(document.getElementById('top10'));
|
||||
var option = {
|
||||
title : {
|
||||
text: '月数据总览',
|
||||
subtext: '一个月内历史汇总',
|
||||
x: 'center'
|
||||
},
|
||||
tooltip : {
|
||||
trigger: 'axis'
|
||||
},
|
||||
backgroundColor: '#fff',
|
||||
legend: {
|
||||
data:['登陆次数', '活跃用户','活跃资产'],
|
||||
y: 'bottom'
|
||||
},
|
||||
toolbox: {
|
||||
show : false,
|
||||
feature : {
|
||||
{# mark : {show: true},#}
|
||||
{# dataView : {show: true, readOnly: false},#}
|
||||
magicType : {show: true, type: ['line', 'bar']}
|
||||
}
|
||||
},
|
||||
calculable : true,
|
||||
xAxis : [
|
||||
{
|
||||
type : 'category',
|
||||
boundaryGap : false,
|
||||
data : {{ date_month | safe}}
|
||||
}
|
||||
],
|
||||
yAxis : [
|
||||
{
|
||||
type : 'value'
|
||||
}
|
||||
],
|
||||
series : [
|
||||
{
|
||||
name:'登陆次数',
|
||||
type:'line',
|
||||
smooth:true,
|
||||
itemStyle: {normal: {areaStyle: {type: 'default'}}},
|
||||
data: {{ active_login_per_month | safe }}
|
||||
},
|
||||
{
|
||||
name:'活跃用户',
|
||||
type:'line',
|
||||
smooth:true,
|
||||
itemStyle: {normal: {areaStyle: {type: 'default'}}},
|
||||
data: {{ active_user_per_month | safe }}
|
||||
},
|
||||
{
|
||||
name:'活跃资产',
|
||||
type:'line',
|
||||
smooth:true,
|
||||
itemStyle: {normal: {areaStyle: {type: 'default'}}},
|
||||
data: {{ active_asset_per_month | safe }}
|
||||
}
|
||||
|
||||
]
|
||||
};
|
||||
|
||||
top10Chart.setOption(option);
|
||||
}
|
||||
);
|
||||
|
||||
require(
|
||||
[
|
||||
'echarts',
|
||||
'echarts/chart/pie'
|
||||
],
|
||||
function (ec) {
|
||||
var auChart = ec.init(document.getElementById('activeUser'));
|
||||
var option = {
|
||||
tooltip : {
|
||||
trigger: 'item',
|
||||
formatter: "{b} <br> {c} ({d}%)"
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
orient : 'vertical',
|
||||
x : 'left',
|
||||
data:['月活跃用户','禁用用户','月未登陆用户']
|
||||
},
|
||||
toolbox: {
|
||||
show : false,
|
||||
feature : {
|
||||
mark : {show: true},
|
||||
dataView : {show: true, readOnly: false},
|
||||
magicType : {
|
||||
show: true,
|
||||
type: ['pie', 'funnel'],
|
||||
option: {
|
||||
funnel: {
|
||||
x: '25%',
|
||||
width: '50%',
|
||||
funnelAlign: 'center',
|
||||
max: 1548
|
||||
}
|
||||
}
|
||||
},
|
||||
restore : {show: true},
|
||||
saveAsImage : {show: true}
|
||||
}
|
||||
},
|
||||
calculable : true,
|
||||
series : [
|
||||
{
|
||||
name:'访问来源',
|
||||
type:'pie',
|
||||
radius : ['50%', '70%'],
|
||||
itemStyle : {
|
||||
normal : {
|
||||
label : {
|
||||
show : false
|
||||
},
|
||||
labelLine : {
|
||||
show : false
|
||||
}
|
||||
},
|
||||
emphasis : {
|
||||
label : {
|
||||
show : true,
|
||||
position : 'center',
|
||||
textStyle : {
|
||||
fontSize : '5',
|
||||
fontWeight : 'bold'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data:[
|
||||
{value:{{ active_user_month }}, name:'月活跃用户'},
|
||||
{value:{{ disabled_user_count }}, name:'禁用用户'},
|
||||
{value:{{ inactive_user_month }}, name:'月未登陆用户'}
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
auChart.setOption(option);
|
||||
}
|
||||
);
|
||||
|
||||
require(
|
||||
[
|
||||
'echarts',
|
||||
'echarts/chart/pie'
|
||||
],
|
||||
function (ec) {
|
||||
var aaChart = ec.init(document.getElementById('activeAsset'));
|
||||
var option = {
|
||||
tooltip : {
|
||||
trigger: 'item',
|
||||
formatter: "{b} <br> {c} ({d}%)"
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
orient : 'vertical',
|
||||
x : 'left',
|
||||
data:['月被登陆主机','禁用主机','月未登陆主机']
|
||||
},
|
||||
toolbox: {
|
||||
show : false,
|
||||
feature : {
|
||||
mark : {show: true},
|
||||
dataView : {show: true, readOnly: false},
|
||||
magicType : {
|
||||
show: true,
|
||||
type: ['pie', 'funnel'],
|
||||
option: {
|
||||
funnel: {
|
||||
x: '25%',
|
||||
width: '50%',
|
||||
funnelAlign: 'center',
|
||||
max: 1548
|
||||
}
|
||||
}
|
||||
},
|
||||
restore : {show: true},
|
||||
saveAsImage : {show: true}
|
||||
}
|
||||
},
|
||||
calculable : true,
|
||||
series : [
|
||||
{
|
||||
name:'访问来源',
|
||||
type:'pie',
|
||||
radius : ['50%', '70%'],
|
||||
itemStyle : {
|
||||
normal : {
|
||||
label : {
|
||||
show : false
|
||||
},
|
||||
labelLine : {
|
||||
show : false
|
||||
}
|
||||
},
|
||||
emphasis : {
|
||||
label : {
|
||||
show : true,
|
||||
position : 'center',
|
||||
textStyle : {
|
||||
fontSize : '5',
|
||||
fontWeight : 'bold'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data:[
|
||||
{value:{{ active_asset_month }}, name:'月被登陆主机'},
|
||||
{value:{{ disabled_asset_count }}, name:'禁用主机'},
|
||||
{value:{{ inactive_asset_month }}, name:'月未登陆主机'}
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
aaChart.setOption(option);
|
||||
}
|
||||
);
|
||||
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
@@ -72,7 +72,7 @@
|
||||
<div class="col-lg-4">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<span class="label label-primary"><b>{{ user.name }}</b></span>
|
||||
<span class="label label-primary"><b>{{ user.username }}</b></span>
|
||||
<div class="ibox-tools">
|
||||
<a class="collapse-link">
|
||||
<i class="fa fa-chevron-up"></i>
|
||||
@@ -109,7 +109,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">角色</td>
|
||||
<td>{{ user.id | get_role }}</td>
|
||||
<td>{{ user.role }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">Email</td>
|
||||
|
@@ -24,7 +24,9 @@
|
||||
|
||||
<div class="ibox-content">
|
||||
<div>
|
||||
{% if session_role_id > 0 %}
|
||||
<a target="_blank" href="/jasset/asset_add/" class="btn btn-sm btn-primary "> 添加 </a>
|
||||
{% endif %}
|
||||
<form id="search_form" method="get" action="" class="pull-right mail-search">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control input-sm" id="search_input" name="keyword" placeholder="Search">
|
||||
|
111
templates/jlog/base.jinja2
Normal file
111
templates/jlog/base.jinja2
Normal file
@@ -0,0 +1,111 @@
|
||||
<html>
|
||||
<head>{% block head %}{% endblock %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<input type="button" value="Play/Pause" onclick="pause(false);" />
|
||||
<input type="button" value="Restart" onclick="restart(1);" />
|
||||
<span id="beforeScrubberText"></span>
|
||||
<input id="scrubber" type="range" value="0" min=0 max=100
|
||||
onmousedown="pause(true);" onmouseup="scrub();" />
|
||||
<span id="afterScrubberText"></span>
|
||||
-5x <input id="speed" type="range" value="0" min=-5 max=5
|
||||
onmouseup="setSpeed();" /> +5x
|
||||
<script>
|
||||
var data = {{ json }};
|
||||
var toggle = true;
|
||||
var totalTime = 0;
|
||||
var TICK = 33;
|
||||
var TIMESTEP = 33;
|
||||
var time = 33;
|
||||
var pos = 0;
|
||||
var timer;
|
||||
|
||||
// Thanks http://stackoverflow.com/a/2998822
|
||||
function zeroPad(num, size) {
|
||||
var s = "0" + num;
|
||||
return s.substr(s.length-size);
|
||||
}
|
||||
|
||||
function scrub() {
|
||||
setPercent = document.getElementById('scrubber').value;
|
||||
time = (setPercent / 100) * totalTime;
|
||||
restart(time);
|
||||
}
|
||||
|
||||
function buildTimeString(millis) {
|
||||
hours = zeroPad(Math.floor(millis / (1000 * 60 * 60)), 2);
|
||||
millis -= hours * (1000 * 60 * 60)
|
||||
minutes = zeroPad(Math.floor(millis / (1000 * 60)), 2);
|
||||
millis -= minutes * (1000 * 60);
|
||||
seconds = zeroPad(Math.floor(millis / 1000), 2);
|
||||
return hours + ':' + minutes + ':' + seconds;
|
||||
}
|
||||
|
||||
function advance() {
|
||||
document.getElementById('scrubber').value =
|
||||
Math.ceil((time / totalTime) * 100);
|
||||
timestr = buildTimeString(time);
|
||||
document.getElementById("beforeScrubberText").innerHTML =
|
||||
timestr;
|
||||
for (; pos < data.length; pos++) {
|
||||
if (data[pos][1] <= time) {
|
||||
term.write(eval(data[pos][0]));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos >= data.length) {
|
||||
clearInterval(timer);
|
||||
}
|
||||
|
||||
time += TIMESTEP;
|
||||
}
|
||||
|
||||
function pause(test) {
|
||||
if (!toggle && test) {
|
||||
return;
|
||||
}
|
||||
if (toggle) {
|
||||
clearInterval(timer);
|
||||
toggle = !toggle;
|
||||
} else {
|
||||
timer = setInterval(advance, TICK);
|
||||
toggle = !toggle;
|
||||
}
|
||||
}
|
||||
|
||||
function setSpeed() {
|
||||
speed = document.getElementById('speed').value;
|
||||
if (speed == 0) {
|
||||
TIMESTEP = TICK;
|
||||
} else if (speed < 0) {
|
||||
TIMESTEP = TICK / -speed;
|
||||
} else {
|
||||
TIMESTEP = TICK * speed;
|
||||
}
|
||||
}
|
||||
|
||||
function restart(millis) {
|
||||
clearInterval(timer);
|
||||
term.reset();
|
||||
time = millis;
|
||||
pos = 0;
|
||||
toggle = true;
|
||||
timer = setInterval(advance, TICK);
|
||||
}
|
||||
|
||||
var term = new Terminal({
|
||||
cols: {{ dimensions[1] }},
|
||||
rows: {{ dimensions[0] }},
|
||||
screenKeys: true
|
||||
});
|
||||
totalTime = data[data.length - 1][1];
|
||||
timestr = buildTimeString(totalTime);
|
||||
document.getElementById("afterScrubberText").innerHTML = timestr;
|
||||
term.open(document.body);
|
||||
timer = setInterval(advance, TICK);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
11
templates/jlog/dynamic.jinja2
Normal file
11
templates/jlog/dynamic.jinja2
Normal file
@@ -0,0 +1,11 @@
|
||||
{% extends "base.jinja2" %}
|
||||
{% block head %}
|
||||
<script src='term.js'></script>
|
||||
<link href='http://fonts.googleapis.com/css?family=Ubuntu+Mono' rel='stylesheet' type='text/css'>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Ubuntu Mono', Courier, monospace;
|
||||
font-size: 14pt;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
139
templates/jlog/log_filter.html
Normal file
139
templates/jlog/log_filter.html
Normal file
@@ -0,0 +1,139 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block self_head_css_js %}
|
||||
<link href="/static/css/plugins/datapicker/datepicker3.css" rel="stylesheet">
|
||||
<link href="/static/css/plugins/chosen/chosen.css" rel="stylesheet">
|
||||
<script src="/static/js/plugins/chosen/chosen.jquery.js"></script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
{% include 'nav_cat_bar.html' %}
|
||||
|
||||
<div class="wrapper wrapper-content animated fadeInRight">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="ibox float-e-margins">
|
||||
<div id="ibox-content" class="ibox-title">
|
||||
<h5> 用户日志详细信息列表 </h5>
|
||||
<div class="ibox-tools">
|
||||
<a class="collapse-link">
|
||||
<i class="fa fa-chevron-up"></i>
|
||||
</a>
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ibox-content">
|
||||
<div class="panel-options">
|
||||
<ul class="nav nav-tabs">
|
||||
<li><a href="/jlog/log_list/online/" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
|
||||
<li><a href="/jlog/log_list/offline/" class="text-center"><i class="fa fa-bar-chart-o"></i> 历史记录 </a></li>
|
||||
<li class="active"><a href="/jlog/search/" class="text-center"><i class="fa fa-bar-chart-o"></i> 详细搜索 </a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="tab-content">
|
||||
<form method="get" action="" role="form" class="form-inline">
|
||||
<p>
|
||||
选择相应条件进行搜索
|
||||
</p>
|
||||
<div class="form-group" id="data_5">
|
||||
<div class="input-daterange input-group" id="datepicker">
|
||||
<input type="text" class="input-sm form-control" style="width: 100px;" name="start" value="{{ date_seven_day }}">
|
||||
<span class="input-group-addon">to</span>
|
||||
<input type="text" class="input-sm form-control" style="width: 100px;" name="end" value="{{ date_now_str }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<select name="single" data-placeholder="用户名" class="chosen-select" multiple style="width:300px;" tabindex="2">
|
||||
<option value="用户">用户名</option>
|
||||
<option value="Bolivia, Plurinational State of">hongweiguang</option>
|
||||
<option value="Bonaire, Sint Eustatius and Saba">wangyong</option>
|
||||
<option value="Bosnia and Herzegovina">hehe</option>
|
||||
<option value="Botswana">wangyong</option>
|
||||
<option value="Bouvet Island">wangyongd</option>
|
||||
<option value="Romania">Romania</option>
|
||||
<option value="Zambia">Zambia</option>
|
||||
<option value="Zimbabwe">Zimbabwe</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<select name="multi" data-placeholder="主机" class="chosen-select" multiple style="width:200px;" tabindex="4">
|
||||
<option value="主机">主机</option>
|
||||
<option value="United States">172.16.1.1</option>
|
||||
<option value="Afghanistan">172.16.1.1</option>
|
||||
<option value="Aland Islands">172.16.1.1</option>
|
||||
<option value="Albania">172.16.1.1</option>
|
||||
<option value="Algeria">172.16.1.1</option>
|
||||
<option value="American Samoa">172.16.1.1</option>
|
||||
<option value="Andorra">172.16.1.1</option>
|
||||
<option value="Angola">172.16.1.1</option>
|
||||
<option value="Anguilla">172.16.1.1</option>
|
||||
<option value="Antarctica">172.16.1.1</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input id="cmd" name="cmd" placeholder="命令" type="text" class="form-control" style="width: 200px;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button id="submit_button" class="btn btn-primary" type="submit">搜索</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
</div>
|
||||
{% include 'paginator.html' %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function log_search(){
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "/jlog/search/?env=offline",
|
||||
data: $("#search_form").serialize(),
|
||||
success: function (data) {
|
||||
$(".tab-content").html(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
$('#data_5 .input-daterange').datepicker({
|
||||
dateFormat: 'yy-mm-dd',
|
||||
keyboardNavigation: false,
|
||||
forceParse: false,
|
||||
autoclose: true
|
||||
});
|
||||
});
|
||||
|
||||
var config = {
|
||||
'.chosen-select' : {},
|
||||
'.chosen-select-deselect' : {allow_single_deselect:true},
|
||||
'.chosen-select-no-single' : {disable_search_threshold:10},
|
||||
'.chosen-select-no-results': {no_results_text:'Oops, nothing found!'},
|
||||
'.chosen-select-width' : {width:"95%"}
|
||||
};
|
||||
for (var selector in config) {
|
||||
$(selector).chosen(config[selector]);
|
||||
}
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block self_footer_js %}
|
||||
<script src="/static/js/cropper/cropper.min.js"></script>
|
||||
<script src="/static/js/datapicker/bootstrap-datepicker.js"></script>
|
||||
<script src="/static/js/plugins/chosen/chosen.jquery.js"></script>
|
||||
{% endblock %}
|
56
templates/jlog/log_monitor.html
Normal file
56
templates/jlog/log_monitor.html
Normal file
@@ -0,0 +1,56 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>Jumpserver | 开源跳板机系统</title>
|
||||
|
||||
<link rel="shortcut icon" href="/static/img/facio.ico" type="image/x-icon">
|
||||
{% include 'link_css.html' %}
|
||||
{% include 'head_script.html' %}
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div class="col-lg-12">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<h5> 实时监控 </h5>
|
||||
</div>
|
||||
|
||||
<div class="ibox-content blank-panel" id="content" style="background-color: #0b0b0b; color: #006621; height: 500px; padding: 20px;">
|
||||
你好<br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
{% block self_footer_js %}
|
||||
<script>
|
||||
function monitor(){
|
||||
var wsUri = 'ws://j:8080/send';
|
||||
var ws = new WebSocket(wsUri);
|
||||
ws.onopen = function(evt){
|
||||
$('#content').append('Connect websocket success' + '<br />');
|
||||
ws.send('Start')
|
||||
};
|
||||
|
||||
ws.onmessage = function(evt){
|
||||
console.log(evt.data);
|
||||
$('#content').append(evt.data.replace(/\n|\r|(\r\n)|(\u0085)|(\u2028)|(\u2029)/g, '<br>'));
|
||||
};
|
||||
|
||||
ws.onclose = function(evt){
|
||||
$('#content').append('Disconnect with websocket')
|
||||
}
|
||||
}
|
||||
|
||||
monitor();
|
||||
</script>
|
||||
{% endblock %}
|
||||
</html>
|
@@ -1,12 +1,18 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block self_head_css_js %}
|
||||
<link href="/static/css/plugins/datapicker/datepicker3.css" rel="stylesheet">
|
||||
<link href="/static/css/plugins/chosen/chosen.css" rel="stylesheet">
|
||||
<script src="/static/js/plugins/chosen/chosen.jquery.js"></script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
{% include 'nav_cat_bar.html' %}
|
||||
|
||||
<style>
|
||||
.bootstrap-dialog-body {
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
.bootstrap-dialog-message {
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
color: #00FF00;
|
||||
}
|
||||
.modal-content {
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
@@ -21,9 +27,7 @@
|
||||
.modal-header {
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
.bootstrap-dialog-message {
|
||||
color: #00FF00;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="wrapper wrapper-content animated fadeInRight">
|
||||
@@ -39,12 +43,6 @@
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-user">
|
||||
<li><a href="#">未启用 1</a>
|
||||
</li>
|
||||
<li><a href="#">未启用 2</a>
|
||||
</li>
|
||||
</ul>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
</a>
|
||||
@@ -56,48 +54,73 @@
|
||||
<ul class="nav nav-tabs">
|
||||
<li><a href="/jlog/log_list/online/" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
|
||||
<li class="active"><a href="/jlog/log_list/offline/" class="text-center"><i class="fa fa-bar-chart-o"></i> 历史记录 </a></li>
|
||||
<li style="float: right">
|
||||
<form id="search_form" method="get" action="" class="pull-right mail-search">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control input-sm" id="search_input" name="keyword" placeholder="Search">
|
||||
<input type="text" style="display: none">
|
||||
<div class="input-group-btn">
|
||||
<button id='search_btn' type="button" class="btn btn-sm btn-primary" onclick="log_search()">
|
||||
Search
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</li>
|
||||
{# <li><a href="/jlog/search/" class="text-center"><i class="fa fa-bar-chart-o"></i> 详细搜索 </a></li>#}
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<br/>
|
||||
<form class="form-inline" action="" method="get">
|
||||
<div class="form-group" id="data_5">
|
||||
<div class="form-group" id="data_5">
|
||||
<div class="input-daterange input-group" id="datepicker">
|
||||
<input type="text" class="input-sm form-control" style="width: 100px;" name="start" value="{{ date_seven_day }}">
|
||||
<span class="input-group-addon">to</span>
|
||||
<input type="text" class="input-sm form-control" style="width: 100px;" name="end" value="{{ date_now_str }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<select name="username" data-placeholder="用户名" class="chosen-select" multiple style="width:200px;" tabindex="2">
|
||||
{% for username in username_all %}
|
||||
<option value="{{ username }}"{% if username in username_list %}selected{% endif %}>{{ username }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<select name="host" data-placeholder="主机" class="chosen-select" multiple style="width:200px;" tabindex="4">
|
||||
{% for ip in ip_all %}
|
||||
<option value="{{ ip }}" {% if ip in host_list %}selected{% endif %}>{{ ip }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input id="cmd" name="cmd" placeholder="命令" type="text" class="form-control" value="{{ cmd }}" style="width: 200px;">
|
||||
</div>
|
||||
</div>
|
||||
<button id='search_btn' type="submit" class="btn btn-sm btn-primary">
|
||||
Search
|
||||
</button>
|
||||
</form>
|
||||
<div class="tab-content">
|
||||
<table class="table table-striped table-bordered table-hover ">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center"> 用户名 </th>
|
||||
<th class="text-center"> 所属部门 </th>
|
||||
<th class="text-center"> 登录主机 </th>
|
||||
<th class="text-center"> 来源IP </th>
|
||||
{% ifnotequal session_role_id 0 %}
|
||||
<th class="text-center"> 命令统计 </th>
|
||||
{% endifnotequal %}
|
||||
<th class="text-center"> 回放录像 </th>
|
||||
<th class="text-center"> 登录时间 </th>
|
||||
<th class="text-center"> 结束时间 </th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{% for post in contacts.object_list %}
|
||||
<tr class="gradeX">
|
||||
<td class="text-center" id="username"> {{ post.user }} </td>
|
||||
<td class="text-center" id="dept"> {{ post.dept_name }} </td>
|
||||
<td class="text-center" id="ip"> {{ post.host }} </td>
|
||||
<td class="text-center" id="remote_ip"> {{ post.remote_ip }} </td>
|
||||
{% ifnotequal session_role_id 0 %}
|
||||
<td class="text-center"><a href="/jlog/history/?id={{ post.id }}" class="log_command"> 命令统计 </td>
|
||||
<td class="text-center"><a href="/jlog/history/?id={{ post.id }}" class="log_command"> 命令统计 </a></td>
|
||||
{% endifnotequal %}
|
||||
<td class="text-center"><a value="/jlog/record/?id={{ post.id }}" class="log_record"> 回放 </a></td>
|
||||
<td class="text-center" id="start_time"> {{ post.start_time|date:"Y-m-d H:i:s"}} </td>
|
||||
<td class="text-center" id="end_time"> {{ post.end_time|date:"Y-m-d H:i:s" }} </td>
|
||||
</tr>
|
||||
@@ -116,10 +139,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{#<script src="http://{{ web_socket_host }}/socket.io/socket.io.js"></script>#}
|
||||
<script>
|
||||
$('.log_command').on('click',function(){
|
||||
$('.log_record').click(function(){
|
||||
var url = $(this).attr('value');
|
||||
window.open(url, '播放', 'height=500, width=910, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no');
|
||||
return false;
|
||||
});
|
||||
|
||||
$('.log_command').on('click',function(){
|
||||
var url = $(this).attr('href');
|
||||
var username = $('#username')[0].innerText;
|
||||
var ip = $('#ip')[0].innerText;
|
||||
@@ -127,17 +154,15 @@
|
||||
var end_time = $('#end_time')[0].innerText;
|
||||
var div_username = ' 用户名: '+'<span class="text-info">'+username+'' + '</span>';
|
||||
var div_ip = ' 主机: '+'<span class="text-info">' + ip + '</span>';
|
||||
var div_time = ' 开始时间: ' + '<span class="text-info">'+start_time +'</span>' + ' 结束时间: ' +'<span class="text-info">' + end_time + '</span'
|
||||
var div_time = ' 开始时间: ' + '<span class="text-info">'+start_time +'</span>' + ' 结束时间: ' +'<span class="text-info">' + end_time + '</span>';
|
||||
var title = 'JumpServer命令统计 '+ div_username + div_ip + div_time;
|
||||
$.ajax({url:url,success:function(data){
|
||||
var tag = $('<div style="height: 500px;overflow: auto;background-color: rgba(0, 0, 0, 0);"></div>').html(data.replace(/\n/g,"<br />"));
|
||||
BootstrapDialog.show({title: title, message:tag[0]});
|
||||
$.ajax({url:url,
|
||||
success:function(data){
|
||||
var tag = $('<div style="height: 500px;overflow: auto;background-color: rgba(0, 0, 0, 0);"></div>').html(data.replace(/\n/g,"<br />"));
|
||||
BootstrapDialog.show({title: title, message:tag[0]});
|
||||
}});
|
||||
return false;
|
||||
});
|
||||
globalConfig = {
|
||||
SOCKET_HOST: "{{ web_socket_host }}"
|
||||
};
|
||||
|
||||
function log_search(){
|
||||
$.ajax({
|
||||
@@ -150,11 +175,33 @@
|
||||
});
|
||||
}
|
||||
|
||||
$("#search_input").keydown(function(e){
|
||||
if(e.keyCode==13){
|
||||
log_search()
|
||||
}
|
||||
})
|
||||
{# $("#search_input").keydown(function(e){#}
|
||||
{# if(e.keyCode==13){#}
|
||||
{# log_search()#}
|
||||
{# }#}
|
||||
{# });#}
|
||||
|
||||
$('#data_5 .input-daterange').datepicker({
|
||||
dateFormat: 'yy-mm-dd',
|
||||
keyboardNavigation: false,
|
||||
forceParse: false,
|
||||
autoclose: true
|
||||
});
|
||||
|
||||
var config = {
|
||||
'.chosen-select' : {},
|
||||
'.chosen-select-deselect' : {allow_single_deselect:true},
|
||||
'.chosen-select-no-single' : {disable_search_threshold:10},
|
||||
'.chosen-select-no-results': {no_results_text:'Oops, nothing found!'},
|
||||
'.chosen-select-width' : {width:"95%"}
|
||||
};
|
||||
for (var selector in config) {
|
||||
$(selector).chosen(config[selector]);
|
||||
}
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block self_footer_js %}
|
||||
<script src="/static/js/cropper/cropper.min.js"></script>
|
||||
<script src="/static/js/datapicker/bootstrap-datepicker.js"></script>
|
||||
{% endblock %}
|
@@ -1,18 +1,32 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block content %}
|
||||
{% include 'nav_cat_bar.html' %}
|
||||
<style>
|
||||
{% block self_head_css_js %}
|
||||
<style>
|
||||
.terminal {
|
||||
border: #000 solid 5px;
|
||||
font-family: "Monaco", "DejaVu Sans Mono", "Liberation Mono", monospace;
|
||||
font-size: 11px;
|
||||
color: #f0f0f0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
width: 600px;
|
||||
box-shadow: rgba(0, 0, 0, 0.6) 2px 2px 20px;
|
||||
}
|
||||
|
||||
.reverse-video {
|
||||
color: #000;
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
.bootstrap-dialog-body {
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
.bootstrap-dialog-message {
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
color: #00FF00;
|
||||
}
|
||||
.pre-class {
|
||||
background-color: rgba(0, 0, 0, 1);
|
||||
}
|
||||
.modal-content {
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
background-color: #000;
|
||||
}
|
||||
.modal-dialog {
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
@@ -24,14 +38,19 @@
|
||||
.modal-header {
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
<script src="/static/js/term.js"></script>
|
||||
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
{% include 'nav_cat_bar.html' %}
|
||||
|
||||
<div class="wrapper wrapper-content animated fadeInRight">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="ibox float-e-margins">
|
||||
<div id="ibox-content" class="ibox-title">
|
||||
<h5> 用户日志详细信息列表 </h5>
|
||||
<h5> 用户日志详细信息列表 <input type="button" id="test_connect" class="btn btn-primary" value="测试连接 web terminal" /> </h5>
|
||||
<div class="ibox-tools">
|
||||
<a class="collapse-link">
|
||||
<i class="fa fa-chevron-up"></i>
|
||||
@@ -39,12 +58,6 @@
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-user">
|
||||
<li><a href="#">未启用 1</a>
|
||||
</li>
|
||||
<li><a href="#">未启用 2</a>
|
||||
</li>
|
||||
</ul>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
</a>
|
||||
@@ -56,19 +69,6 @@
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a href="/jlog/log_list/online/" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
|
||||
<li><a href="/jlog/log_list/offline/" class="text-center"><i class="fa fa-bar-chart-o"></i> 历史记录 </a></li>
|
||||
<li style="float: right">
|
||||
<form id="search_form" method="get" action="" class="pull-right mail-search">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control input-sm" id="search_input" name="keyword" placeholder="Search">
|
||||
<input type="text" style="display: none">
|
||||
<div class="input-group-btn">
|
||||
<button id='search_btn' type="button" class="btn btn-sm btn-primary" onclick="log_search()">
|
||||
Search
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br/>
|
||||
@@ -77,10 +77,10 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center"> 用户名 </th>
|
||||
<th class="text-center"> 所属部门 </th>
|
||||
<th class="text-center"> 登录主机 </th>
|
||||
<th class="text-center"> 来源IP </th>
|
||||
{% ifnotequal session_role_id 0 %}
|
||||
<th class="text-center"> 统计命令 </th>
|
||||
<th class="text-center"> 实时监控 </th>
|
||||
<th class="text-center"> 阻断 </th>
|
||||
{% endifnotequal %}
|
||||
@@ -92,14 +92,14 @@
|
||||
{% for post in contacts.object_list %}
|
||||
<tr class="gradeX">
|
||||
<td id="username" class="text-center"> {{ post.user }} </td>
|
||||
<td id="deptname" class="text-center"> {{ post.dept_name }} </td>
|
||||
<td id="ip" class="text-center"> {{ post.host }} </td>
|
||||
<td id="remote_ip" class="text-center"> {{ post.remote_ip }} </td>
|
||||
{% ifnotequal session_role_id 0 %}
|
||||
<td class="text-center"><a class="monitor" filename="{{ post.log_path }}"> 监控 </a></td>
|
||||
<td class="text-center"><input type="button" id="cut" class="btn btn-danger btn-xs" name="cut" value="阻断" onclick='cut("{{ post.pid }}")' /></td>
|
||||
<td class="text-center"><a href="/jlog/history/?id={{ post.id }}" class="log_command"> 命令统计 </a></td>
|
||||
<td class="text-center"><a class="monitor" file_path="{{ post.log_path }}"> 监控 </a></td>
|
||||
<td class="text-center"><input type="button" id="cut" class="btn btn-danger btn-xs" name="cut" value="阻断" onclick='cut("{{ post.pid }}", "{{ post.remote_ip }}")' /></td>
|
||||
{% endifnotequal %}
|
||||
<td class="text-center"> {{ post.start_time|date:"Y-m-d H:i:s" }} </td>
|
||||
<td class="text-center" id="start_time"> {{ post.start_time|date:"Y-m-d H:i:s" }} </td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
@@ -116,115 +116,108 @@
|
||||
</div>
|
||||
|
||||
|
||||
<script src="http://{{ web_socket_host }}/socket.io/socket.io.js"></script>
|
||||
{#<script src="http://{{ web_socket_host }}/socket.io/socket.io.js"></script>#}
|
||||
<script>
|
||||
$.fn.webSocket = function(opt){
|
||||
var st = {};
|
||||
st = $.extend(st,opt);
|
||||
var message = {};
|
||||
var $this = $(this);
|
||||
var genUid = function(){
|
||||
return new Date().getTime()+""+Math.floor(Math.random()*899+100);
|
||||
};
|
||||
var init = function(e){
|
||||
var socket = io.connect('ws://'+globalConfig.SOCKET_HOST);
|
||||
var node = $(e.target);
|
||||
message.id = genUid();
|
||||
message.filename = node.attr('filename');
|
||||
var username = $('#username')[0].innerText;
|
||||
var ip = $('#ip')[0].innerText;
|
||||
BootstrapDialog.show({message:function(){
|
||||
var option, exsit_message;
|
||||
var escapeString = function (html){
|
||||
var elem = document.createElement('div');
|
||||
var txt = document.createTextNode(html);
|
||||
elem.appendChild(txt);
|
||||
return elem.innerHTML;
|
||||
};
|
||||
var tag = $('<div id="log" style="height: 500px;overflow: auto;background-color: rgba(0, 0, 0, 0);"></div>');
|
||||
{# $(document).ready(function(){#}
|
||||
{# $('.monitor').click(function(){#}
|
||||
{# window.open('/jlog/monitor/', '监控', 'height=500, width=910, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no');#}
|
||||
{# })#}
|
||||
{# });#}
|
||||
function init(obj){
|
||||
var file_path = obj.attr('file_path');
|
||||
var wsUri = '{{ web_monitor_uri }}';
|
||||
var socket = new WebSocket(wsUri + '?file_path=' + file_path);
|
||||
|
||||
var username = "";
|
||||
var seed = "";
|
||||
document.cookie.split('; ').forEach(function(obj){
|
||||
var info = obj.split('=');
|
||||
if(info.length == 2 ){
|
||||
if(info[0] == 'username'){
|
||||
username = info[1];
|
||||
}else if(info[0] == 'seed'){
|
||||
seed = info[1];
|
||||
}
|
||||
}
|
||||
})
|
||||
var term = new Terminal({
|
||||
cols: 80,
|
||||
rows: 24,
|
||||
screenKeys: false
|
||||
});
|
||||
|
||||
var tag = $('<div id="term" style="height:500px; overflow: auto;background-color: rgba(0, 0, 0, 0);border: none"></div>');
|
||||
term.open();
|
||||
term.resize(80, 24);
|
||||
|
||||
socket.onopen = function(evt){
|
||||
socket.send('hello');
|
||||
term.write('~.~ Connect WebSocket Success.~.~ \r\n');
|
||||
};
|
||||
|
||||
window.onbeforeunload = function(){
|
||||
socket.close()
|
||||
};
|
||||
|
||||
var username = obj.closest('tr').find('#username').text();
|
||||
var ip = obj.closest('tr').find('#ip').text();
|
||||
|
||||
BootstrapDialog.show({message: function(){
|
||||
//服务器端认证
|
||||
{# socket.send('login', {userid:message.id, filename:message.filename,username:username,seed:seed});#}
|
||||
window.setTimeout(function(){
|
||||
$('.terminal').detach().appendTo('#term');
|
||||
socket.onmessage = function(evt){
|
||||
term.write(evt.data);
|
||||
}}, 1000);
|
||||
|
||||
//告诉服务器端有用户登录
|
||||
socket.emit('login', {userid:message.id, filename:message.filename,username:username,seed:seed});
|
||||
socket.on('message',function(obj){
|
||||
option = obj.option;
|
||||
console.log(option+'so')
|
||||
exsit_message = obj.content;
|
||||
console.log(obj.content)
|
||||
//去除log中的颜色控制字符
|
||||
var regx = /\x1B\[([0-9]{1,3}((;[0-9]{1,3})*)?)?[m|K]/g;
|
||||
// tag.append('<p>'+escapeString(obj.content.replace(regx,''))+'</p>');
|
||||
if (option == 'new') {
|
||||
// tag.append('<p style="margin: 2px">' + escapeString(obj.content) + '</p>');
|
||||
tag.append('<p style="margin: 2px">'+escapeString(obj.content.replace(regx,' '))+'</p>');
|
||||
} else if (option == 'exist') {
|
||||
tag.append('<pre>' + exsit_message + '</pre>');
|
||||
}
|
||||
tag.animate({ scrollTop: tag[0].scrollHeight}, 1);
|
||||
});
|
||||
tag[0].style.color = "#00FF00";
|
||||
return tag[0];
|
||||
|
||||
} ,
|
||||
title:'Jumpserver实时监控 '+' 登录用户名: '+'<span class="text-info">'+username+'</span>'+' 登录主机: '+'<span class="text-info">'+ip,
|
||||
onhide:function(){
|
||||
socket.emit('disconnect');
|
||||
socket.close();
|
||||
}});
|
||||
}
|
||||
$this.on("click",function(e){
|
||||
init(e);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
$('.log_command').on('click',function(){
|
||||
var url = $(this).attr('href');
|
||||
$.ajax({url:url,success:function(data){
|
||||
BootstrapDialog.show({title:'命令统计',message:data});
|
||||
}});
|
||||
return false;
|
||||
})
|
||||
globalConfig = {
|
||||
SOCKET_HOST: "{{ web_socket_host }}"
|
||||
}
|
||||
$(".monitor").webSocket()
|
||||
|
||||
|
||||
function log_search(){
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "/jlog/search/?env=online",
|
||||
data: $("#search_form").serialize(),
|
||||
success: function (data) {
|
||||
$(".tab-content").html(data);
|
||||
}
|
||||
$(document).ready(function(){
|
||||
$('.monitor').click(function(){
|
||||
init($(this));
|
||||
});
|
||||
}
|
||||
|
||||
$("#search_input").keydown(function(e){
|
||||
if(e.keyCode==13){
|
||||
log_search()
|
||||
}
|
||||
})
|
||||
$('.log_command').on('click',function(){
|
||||
var url = $(this).attr('href');
|
||||
var username = $(this).closest('tr').find('#username').text();
|
||||
var ip = $(this).closest('tr').find('#ip').text();
|
||||
var start_time = $(this).closest('tr').find('#start_time').text();
|
||||
var div_username = ' 用户名: '+'<span class="text-info">'+username+'' + '</span>';
|
||||
var div_ip = ' 主机: '+'<span class="text-info">' + ip + '</span>';
|
||||
var div_time = ' 开始时间: ' + '<span class="text-info">'+start_time +'</span>' + '</span>';
|
||||
var title = 'JumpServer命令统计 '+ div_username + div_ip + div_time;
|
||||
$.ajax({url:url,
|
||||
success:function(data){
|
||||
var tag = $('<div style="height: 500px;overflow: auto;background-color: rgba(0, 0, 0, 0);"></div>').html(data.replace(/\n/g,"<br />"));
|
||||
BootstrapDialog.show({title: title, message:tag[0]});
|
||||
}});
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#test_connect').click(function(){
|
||||
window.open('/jlog/web_terminal/?asset_name="hello', '播放', 'height=400, width=600, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no');
|
||||
});
|
||||
});
|
||||
|
||||
{# function log_search(){#}
|
||||
{# $.ajax({#}
|
||||
{# type: "GET",#}
|
||||
{# url: "/jlog/search/?env=online",#}
|
||||
{# data: $("#search_form").serialize(),#}
|
||||
{# success: function (data) {#}
|
||||
{# $(".tab-content").html(data);#}
|
||||
{# }#}
|
||||
{# });#}
|
||||
{# }#}
|
||||
|
||||
|
||||
function cut(num, host){
|
||||
console.log(host);
|
||||
if (host=='Web'){
|
||||
var g_url = '{{ web_kill_uri }}' + '?id=' + num;
|
||||
} else {
|
||||
g_url = "/jlog/log_kill/?id=" + num;
|
||||
}
|
||||
|
||||
function cut(num){
|
||||
var g_url = "/jlog/log_kill/?id="+num;
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: g_url,
|
||||
success: window.open("/jlog/log_list/online/", "_self")
|
||||
// error: window.open(g_url, "_self")
|
||||
});
|
||||
|
||||
}
|
||||
|
18
templates/jlog/static.jinja2
Normal file
18
templates/jlog/static.jinja2
Normal file
File diff suppressed because one or more lines are too long
117
templates/jlog/web_terminal.html
Normal file
117
templates/jlog/web_terminal.html
Normal file
@@ -0,0 +1,117 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Jumpserver web terminal</title>
|
||||
|
||||
<style>
|
||||
body {
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
.terminal {
|
||||
border: #000 solid 5px;
|
||||
font-family: "Monaco", "DejaVu Sans Mono", "Liberation Mono", monospace;
|
||||
font-size: 11px;
|
||||
color: #f0f0f0;
|
||||
background: #000;
|
||||
width: 600px;
|
||||
box-shadow: rgba(0, 0, 0, 0.8) 2px 2px 20px;
|
||||
}
|
||||
|
||||
.reverse-video {
|
||||
color: #000;
|
||||
background: #f0f0f0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<div id="term">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="application/javascript" src="/static/js/jquery-2.1.1.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="/static/js/term.js">
|
||||
</script>
|
||||
<script type="application/javascript">
|
||||
function WSSHClient() {
|
||||
}
|
||||
|
||||
WSSHClient.prototype.connect = function(options) {
|
||||
var endpoint = '{{ web_terminal_uri }}';
|
||||
|
||||
if (window.WebSocket) {
|
||||
this._connection = new WebSocket(endpoint);
|
||||
}
|
||||
else if (window.MozWebSocket) {
|
||||
this._connection = MozWebSocket(endpoint);
|
||||
}
|
||||
else {
|
||||
options.onError('WebSocket Not Supported');
|
||||
return ;
|
||||
}
|
||||
|
||||
this._connection.onopen = function() {
|
||||
options.onConnect();
|
||||
};
|
||||
|
||||
this._connection.onmessage = function (evt) {
|
||||
var data = JSON.parse(evt.data.toString());
|
||||
if (data.error !== undefined) {
|
||||
options.onError(data.error);
|
||||
}
|
||||
else {
|
||||
options.onData(data.data);
|
||||
}
|
||||
};
|
||||
|
||||
this._connection.onclose = function(evt) {
|
||||
options.onClose();
|
||||
};
|
||||
};
|
||||
|
||||
WSSHClient.prototype.send = function(data) {
|
||||
this._connection.send(JSON.stringify({'data': data}));
|
||||
};
|
||||
|
||||
function openTerminal(options) {
|
||||
var client = new WSSHClient();
|
||||
var term = new Terminal(80, 24, function(key) {
|
||||
client.send(key);
|
||||
});
|
||||
term.open();
|
||||
$('.terminal').detach().appendTo('#term');
|
||||
term.resize(80, 24);
|
||||
term.write('Connecting...');
|
||||
client.connect($.extend(options, {
|
||||
onError: function(error) {
|
||||
term.write('Error: ' + error + '\r\n');
|
||||
},
|
||||
onConnect: function() {
|
||||
// Erase our connecting message
|
||||
term.write('\r');
|
||||
},
|
||||
onClose: function() {
|
||||
term.write('Connection Reset By Peer');
|
||||
},
|
||||
onData: function(data) {
|
||||
term.write(data);
|
||||
}
|
||||
}));
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type='application/javascript'>
|
||||
$(document).ready(function() {
|
||||
var options = {
|
||||
};
|
||||
|
||||
$('#ssh').show();
|
||||
openTerminal(options);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
138
templates/log_watch.html
Normal file
138
templates/log_watch.html
Normal file
@@ -0,0 +1,138 @@
|
||||
<html>
|
||||
<head>
|
||||
<link href="http://cdn.bootcss.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="http://cdn.bootcss.com/bootstrap/3.2.0/css/bootstrap-theme.min.css" rel="stylesheet">
|
||||
<script src="http://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
|
||||
<script src="http://cdn.bootcss.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
|
||||
<script>
|
||||
var wsUri = "ws://j:8080/send";
|
||||
var ws;
|
||||
function connect(){
|
||||
ws = new WebSocket(wsUri);
|
||||
ws.onopen = function(evt){ console.log(evt.data) };
|
||||
ws.onclose = function(evt){ console.log(evt.data) };
|
||||
ws.onmessage = function(evt){ console.log(evt.data) };
|
||||
ws.onerror = function(evt){ console.log(evt.data) };
|
||||
|
||||
return ws;
|
||||
}
|
||||
|
||||
function send() {
|
||||
var data = {
|
||||
input:$("#input_data").val()
|
||||
};
|
||||
|
||||
console.log('hello');
|
||||
ws.send(JSON.stringify(data));
|
||||
|
||||
$("#message").empty();
|
||||
ws.onopen = function() {
|
||||
ws.send(JSON.stringify(data));
|
||||
};
|
||||
|
||||
$("#message").append('<div class="panel-body"><p>');
|
||||
ws.onmessage = function(event) {
|
||||
$("#message").append(JSON.parse(event.data).input + "<br>");
|
||||
};
|
||||
|
||||
ws.onclose = function(event) {
|
||||
$("#message").append('</p></div>');
|
||||
};
|
||||
}
|
||||
|
||||
{# function send() {#}
|
||||
{# var ws = new WebSocket("ws://j:8080/send");#}
|
||||
{##}
|
||||
{# var data = {#}
|
||||
{# input:$("#input_data").val(),#}
|
||||
{# };#}
|
||||
{##}
|
||||
{# $("#message").empty();#}
|
||||
{# ws.onopen = function() {#}
|
||||
{# ws.send(JSON.stringify(data));#}
|
||||
{# };#}
|
||||
{##}
|
||||
{# $("#message").append('<div class="panel-body"><p>');#}
|
||||
{# ws.onmessage = function(event) {#}
|
||||
{# $("#message").append(JSON.parse(event.data).input + "<br>");#}
|
||||
{# };#}
|
||||
{##}
|
||||
{# ws.onclose = function(event) {#}
|
||||
{# $("#message").append('</p></div>');#}
|
||||
{# };#}
|
||||
{# }#}
|
||||
|
||||
function disconnect(){
|
||||
ws.close();
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
{# <div id="test">#}
|
||||
{# <form class="form-horizontal" role="form">#}
|
||||
{# <div class="panel panel-default">#}
|
||||
{# <div class="panel-heading">#}
|
||||
{# <h5 class="panel-title">>>输入</h5>#}
|
||||
{# </div>#}
|
||||
{# <div class="panel-body">#}
|
||||
{# <div class="form-group">#}
|
||||
{# <div class="col-md-8">#}
|
||||
{# <input type="text" class="form-control" id="input_data" value="">#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# <div class="form-group">#}
|
||||
{# <div class="col-md-8">#}
|
||||
{# <input type="button" class="btn btn-success" id="input_1_btn" onclick="connect();" value="连接" />#}
|
||||
{# <input type="button" class="btn btn-success" id="input_btn" onclick="send();" value="查看" />#}
|
||||
{# <input type="button" class="btn btn-success" id="input_2_btn" onclick="close();" value="关闭" />#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# </form>#}
|
||||
{# <div class="panel panel-default">#}
|
||||
{# <div class="panel-heading">#}
|
||||
{# <h5 class="panel-title">>> 输出</h5>#}
|
||||
{# </div>#}
|
||||
{# <div class="panel-body">#}
|
||||
{# <div id="message"></div>#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
<div class="col-lg-12">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title" style="border: solid">
|
||||
<h5> 实时监控 </h5>
|
||||
<div class="ibox-tools">
|
||||
<a class="collapise-link">
|
||||
<i class="fa fa-chevron-up"></i>
|
||||
</a>
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ibox-content blank-panel" style="background-color: #0b0b0b; color: #006621; height: 500px; padding: 20px;">
|
||||
你好<br>
|
||||
你好<br>
|
||||
你好<br>
|
||||
你好你好你好<br>
|
||||
你好<br>
|
||||
你好<br>
|
||||
你好<br>
|
||||
你好<br>
|
||||
你好<br>
|
||||
你好<br>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
@@ -1,4 +1,4 @@
|
||||
{% ifequal session_role_id 2 %}
|
||||
{% if request.session.role_id == 2 %}
|
||||
<nav class="navbar-default navbar-static-side" role="navigation">
|
||||
<div class="sidebar-collapse">
|
||||
<ul class="nav" id="side-menu">
|
||||
@@ -51,8 +51,8 @@
|
||||
|
||||
</div>
|
||||
</nav>
|
||||
{% endifequal %}
|
||||
{% ifequal session_role_id 1 %}
|
||||
{% endif %}
|
||||
{% if request.session.role_id == 1 %}
|
||||
<nav class="navbar-default navbar-static-side" role="navigation">
|
||||
<div class="sidebar-collapse">
|
||||
<ul class="nav" id="side-menu">
|
||||
@@ -73,8 +73,8 @@
|
||||
<li id="jasset">
|
||||
<a><i class="fa fa-cube"></i> <span class="nav-label">资产管理</span><span class="fa arrow"></span></a>
|
||||
<ul class="nav nav-second-level">
|
||||
<li class="host_add host_add_multi"><a href="/jasset/host_add/">添加资产</a></li>
|
||||
<li class="host_list host_detail host_edit"><a href="/jasset/host_list/">查看资产<span class="label label-info pull-right">{{ host_active_num }}/{{ host_total_num}}</span></a></li>
|
||||
{# <li class="host_add host_add_multi"><a href="/jasset/host_add/">添加资产</a></li>#}
|
||||
<li class="host_list host_detail host_edit"><a href="/jasset/asset_list/">查看资产<span class="label label-info pull-right">{{ host_active_num }}/{{ host_total_num}}</span></a></li>
|
||||
<li class="idc_list idc_detail idc_edit"><a href="/jasset/idc_list/">查看IDC</a></li>
|
||||
<li class="group_add"><a href="/jasset/group_add/">添加主机组</a></li>
|
||||
<li class="group_list group_detail group_edit"><a href="/jasset/group_list/">查看主机组</a></li>
|
||||
@@ -103,9 +103,9 @@
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
{% endifequal %}
|
||||
{% endif %}
|
||||
|
||||
{% ifequal session_role_id 0 %}
|
||||
{% if request.session.role_id == 0 %}
|
||||
<nav class="navbar-default navbar-static-side" role="navigation">
|
||||
<div class="sidebar-collapse">
|
||||
<ul class="nav" id="side-menu">
|
||||
@@ -117,7 +117,7 @@
|
||||
<a href="/juser/user_detail/?id={{ session_user_id }}"><i class="fa fa-rebel"></i> <span class="nav-label">个人信息</span><span class="label label-info pull-right"></span></a>
|
||||
</li>
|
||||
<li id="jasset">
|
||||
<a href="/jasset/host_list/"><i class="fa fa-cube"></i> <span class="nav-label">查看主机</span><span class="label label-info pull-right"></span></a>
|
||||
<a href="/jasset/asset_list/"><i class="fa fa-cube"></i> <span class="nav-label">查看主机</span><span class="label label-info pull-right"></span></a>
|
||||
</li>
|
||||
<li id="jperm">
|
||||
<a><i class="fa fa-cube"></i> <span class="nav-label">权限申请</span><span class="fa arrow"></span></a>
|
||||
@@ -144,4 +144,4 @@
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
{% endifequal %}
|
||||
{% endif %}
|
@@ -17,8 +17,13 @@
|
||||
<ul class="dropdown-menu animated fadeInRight m-t-xs">
|
||||
<li><a value="/juser/profile/?id={{ session_user_id }}" class="iframe_user">个人信息</a></li>
|
||||
<li><a href="/juser/change_info/">修改信息</a></li>
|
||||
<li><a href="/juser/change_role/">切换角色</a></li>
|
||||
|
||||
{% if not user.role == 'CU' %}
|
||||
{% if request.session.role_id == 0 %}
|
||||
<li><a href="/juser/change_role/">系统后台</a></li>
|
||||
{% else %}
|
||||
<li><a href="/juser/change_role/">主机控制台</a></li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<li class="divider"></li>
|
||||
<li><a href="/logout/">注销</a></li>
|
||||
</ul>
|
||||
|
@@ -1,72 +1,56 @@
|
||||
<div class="col-sm-6">
|
||||
<div class="dataTables_paginate paging_simple_numbers" id="editable_paginate">
|
||||
<ul class="pagination" style="margin-top: 0; float: right">
|
||||
{% if keyword %}
|
||||
{% if contacts.has_previous %}
|
||||
<li class="paginate_button previous" aria-controls="editable" tabindex="0" id="editable_previous">
|
||||
<a href="?keyword={{ keyword }}&page={{ contacts.previous_page_number }}">Previous</a>
|
||||
<a class="page" href="?page={{ contacts.previous_page_number }}">Previous</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="paginate_button previous disabled" aria-controls="editable" tabindex="0" id="editable_previous">
|
||||
<a href="#">Previous</a>
|
||||
<a class="page" href="#">Previous</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% ifequal show_first 1 %}
|
||||
<li class="paginate_button" aria-controls="editable" tabindex="0"><a href="?keyword={{ keyword }}&page=1" title="第1页">1...</a></li>
|
||||
<li class="paginate_button" aria-controls="editable" tabindex="0"><a class="page" href="?page=1" title="第1页">1...</a></li>
|
||||
{% endifequal %}
|
||||
{% for page in page_range %}
|
||||
{% ifequal current_page page %}
|
||||
<li class="paginate_button active" aria-controls="editable" tabindex="0"><a href="?keyword={{ keyword }}&page={{ page }}" title="第{{ page }}页">{{ page }}</a></li>
|
||||
<li class="paginate_button active" aria-controls="editable" tabindex="0"><a class="page" href="?page={{ page }}" title="第{{ page }}页">{{ page }}</a></li>
|
||||
{% else %}
|
||||
<li class="paginate_button" aria-controls="editable" tabindex="0"><a href="?keyword={{ keyword }}&page={{ page }}" title="第{{ page }}页">{{ page }}</a></li>
|
||||
<li class="paginate_button" aria-controls="editable" tabindex="0"><a class="page" href="?page={{ page }}" title="第{{ page }}页">{{ page }}</a></li>
|
||||
{% endifequal %}
|
||||
{% endfor %}
|
||||
{% ifequal show_end 1 %}
|
||||
<li class="paginate_button" aria-controls="editable" tabindex="0"><a href="?keyword={{ keyword }}&page={{ p.num_pages }}" title="第{{ page }}页">...{{ p.num_pages }}</a></li>
|
||||
<li class="paginate_button" aria-controls="editable" tabindex="0"><a class="page" href="?page={{ p.num_pages }}" title="第{{ page }}页">...{{ p.num_pages }}</a></li>
|
||||
{% endifequal %}
|
||||
{% if contacts.has_next %}
|
||||
<li class="paginate_button next" aria-controls="editable" tabindex="0" id="editable_next">
|
||||
<a href="?keyword={{ keyword }}&page={{ contacts.next_page_number }}">Next</a>
|
||||
<a class="page" href="?page={{ contacts.next_page_number }}">Next</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="paginate_button next disabled" aria-controls="editable" tabindex="0" id="editable_next">
|
||||
<a href="#">Next</a>
|
||||
<a class="page" href="#">Next</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% else %}
|
||||
{% if contacts.has_previous %}
|
||||
<li class="paginate_button previous" aria-controls="editable" tabindex="0" id="editable_previous">
|
||||
<a href="?page={{ contacts.previous_page_number }}">Previous</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="paginate_button previous disabled" aria-controls="editable" tabindex="0" id="editable_previous">
|
||||
<a href="#">Previous</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% ifequal show_first 1 %}
|
||||
<li class="paginate_button" aria-controls="editable" tabindex="0"><a href="?page=1" title="第1页">1...</a></li>
|
||||
{% endifequal %}
|
||||
{% for page in page_range %}
|
||||
{% ifequal current_page page %}
|
||||
<li class="paginate_button active" aria-controls="editable" tabindex="0"><a href="?page={{ page }}" title="第{{ page }}页">{{ page }}</a></li>
|
||||
{% else %}
|
||||
<li class="paginate_button" aria-controls="editable" tabindex="0"><a href="?page={{ page }}" title="第{{ page }}页">{{ page }}</a></li>
|
||||
{% endifequal %}
|
||||
{% endfor %}
|
||||
{% ifequal show_end 1 %}
|
||||
<li class="paginate_button" aria-controls="editable" tabindex="0"><a href="?page={{ p.num_pages }}" title="第{{ page }}页">...{{ p.num_pages }}</a></li>
|
||||
{% endifequal %}
|
||||
{% if contacts.has_next %}
|
||||
<li class="paginate_button next" aria-controls="editable" tabindex="0" id="editable_next">
|
||||
<a href="?page={{ contacts.next_page_number }}">Next</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="paginate_button next disabled" aria-controls="editable" tabindex="0" id="editable_next">
|
||||
<a href="#">Next</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
$('.page').click(function(){
|
||||
var searchStr = location.search;
|
||||
var old_href = $(this).attr('href').replace('?', '');
|
||||
var searchArray = searchStr.split('&');
|
||||
|
||||
if (searchStr.indexOf('page')){
|
||||
searchArray.pop();
|
||||
}
|
||||
searchArray.push(old_href);
|
||||
|
||||
if (searchArray.length > 2){
|
||||
$(this).attr('href', searchArray.join('&'));
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
</script>
|
||||
|
@@ -46,20 +46,28 @@
|
||||
{% endif %}
|
||||
<div class="form-group">
|
||||
<label for="username" class="col-sm-2 control-label">默认用户名<span class="red-fonts">*</span></label>
|
||||
<input name="setting" value="default" style="display: none">
|
||||
<div class="col-sm-8">
|
||||
<input id="username" name="username" placeholder="Username" type="text" value="{{ setting_r.default_user }}" class="form-control">
|
||||
<input id="username" name="username" placeholder="Username" type="text" value="{{ setting_default.default_user }}" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="form-group">
|
||||
<label for="port" class="col-sm-2 control-label">默认ssh端口<span class="red-fonts">*</span></label>
|
||||
<div class="col-sm-8">
|
||||
<input id="port" name="port" placeholder="Port" type="text" value="{{ setting_r.default_port }}" class="form-control">
|
||||
<input id="port" name="port" placeholder="Port" type="text" value="{{ setting_default.default_port }}" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="form-group">
|
||||
<label for="key" class="col-sm-2 control-label">默认密钥<span class="red-fonts">*</span></label>
|
||||
<label for="key" class="col-sm-2 control-label">默认密码</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="password" name="password" placeholder="Password" type="password" value="{{ setting_default.default_password }}" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="form-group">
|
||||
<label for="key" class="col-sm-2 control-label">默认密钥</label>
|
||||
<div class="col-sm-8">
|
||||
<textarea class="form-control" name="key" placeholder="请复制粘贴私钥(原来的因为安全原因不被显示)" rows="10" style="font-size: 9px;"></textarea>
|
||||
</div>
|
||||
|
@@ -1,74 +0,0 @@
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf8'>
|
||||
<script src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script>
|
||||
<style type="text/css">
|
||||
|
||||
.blue
|
||||
{
|
||||
color: blue;
|
||||
}
|
||||
</style>
|
||||
{#<script>#}
|
||||
{#$('html').ajaxSend(function(event, xhr, settings) {#}
|
||||
{# function getCookie(name) {#}
|
||||
{# var cookieValue = null;#}
|
||||
{# if (document.cookie && document.cookie != '') {#}
|
||||
{# var cookies = document.cookie.split(';');#}
|
||||
{# for (var i = 0; i < cookies.length; i++) {#}
|
||||
{# var cookie = jQuery.trim(cookies[i]);#}
|
||||
{# // Does this cookie string begin with the name we want?#}
|
||||
{# if (cookie.substring(0, name.length + 1) == (name + '=')) {#}
|
||||
{# cookieValue = decodeURIComponent(cookie.substring(name.length + 1));#}
|
||||
{# break;#}
|
||||
{# }#}
|
||||
{# }#}
|
||||
{# }#}
|
||||
{# return cookieValue;#}
|
||||
{# }#}
|
||||
{# if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {#}
|
||||
{# // Only send the token to relative URLs i.e. locally.#}
|
||||
{# xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));#}
|
||||
{# }#}
|
||||
{#});#}
|
||||
{#</script>#}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
$("#btn1").click(function(){
|
||||
$("#test").text(function(i,origText){
|
||||
return "Old text: " + origText + "New text: Hllo" + i
|
||||
})
|
||||
});
|
||||
|
||||
$("#btn2").click(function(){
|
||||
$.post('/test_ajax/',
|
||||
{'name': 'join', 'age': 10},
|
||||
function(data, status){
|
||||
$('#btn1').text(data)
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
$("#btn3").click(function(){
|
||||
$("p").toggleClass('blue')
|
||||
// $("p").addClass('blue')
|
||||
// $("p").before("Some thine")
|
||||
});
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p id="test" class="blue">
|
||||
这是段落中的<b>粗体</b>文本。
|
||||
<p><span>hello</span></p>
|
||||
|
||||
</p>
|
||||
<!-- <input type="text" id="test2" name="nameaaaaaaaaaa" value="米老鼠"> -->
|
||||
<button id="btn1">显示文本</button>
|
||||
<button id="btn2">显示 HTML</button>
|
||||
<button id="btn3">显示 value</button>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
85
templates/test2.html
Normal file
85
templates/test2.html
Normal file
@@ -0,0 +1,85 @@
|
||||
<html>
|
||||
<body>
|
||||
<div id="main" style="height:400px;"></div>
|
||||
...
|
||||
<script src="/static/js/echarts/echarts.js"></script>
|
||||
<script type="text/javascript">
|
||||
require.config({
|
||||
paths: {
|
||||
'echarts': '/static/js/echarts/chart',
|
||||
'echarts/chart/line': '/static/js/echarts/chart/line'
|
||||
}
|
||||
});
|
||||
require(
|
||||
[
|
||||
'echarts',
|
||||
'echarts/chart/line'
|
||||
],
|
||||
function (ec) {
|
||||
var myChart = ec.init(document.getElementById('main'));
|
||||
var option = {
|
||||
title : {
|
||||
text: '某楼盘销售情况',
|
||||
subtext: '纯属虚构'
|
||||
},
|
||||
tooltip : {
|
||||
trigger: 'axis'
|
||||
},
|
||||
legend: {
|
||||
data:['意向','预购','成交']
|
||||
},
|
||||
toolbox: {
|
||||
show : true,
|
||||
feature : {
|
||||
mark : {show: true},
|
||||
dataView : {show: true, readOnly: false},
|
||||
magicType : {show: true, type: ['line', 'bar', 'stack', 'tiled']},
|
||||
restore : {show: true},
|
||||
saveAsImage : {show: true}
|
||||
}
|
||||
},
|
||||
calculable : true,
|
||||
xAxis : [
|
||||
{
|
||||
type : 'category',
|
||||
boundaryGap : false,
|
||||
data : ['周一','周二','周三','周四','周五','周六','周日']
|
||||
}
|
||||
],
|
||||
yAxis : [
|
||||
{
|
||||
type : 'value'
|
||||
}
|
||||
],
|
||||
series : [
|
||||
{
|
||||
name:'成交',
|
||||
type:'line',
|
||||
smooth:true,
|
||||
itemStyle: {normal: {areaStyle: {type: 'default'}}},
|
||||
data:[10, 12, 21, 54, 260, 830, 710]
|
||||
},
|
||||
{
|
||||
name:'预购',
|
||||
type:'line',
|
||||
smooth:true,
|
||||
itemStyle: {normal: {areaStyle: {type: 'default'}}},
|
||||
data:[30, 182, 434, 791, 390, 30, 10]
|
||||
},
|
||||
{
|
||||
name:'意向',
|
||||
type:'line',
|
||||
smooth:true,
|
||||
itemStyle: {normal: {areaStyle: {type: 'default'}}},
|
||||
data:[1320, 1132, 601, 234, 120, 90, 20]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
myChart.setOption(option);
|
||||
}
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user