merge update...

This commit is contained in:
yumaojun
2015-11-14 23:07:08 +08:00
71 changed files with 11586 additions and 1228 deletions

View File

@@ -24,6 +24,7 @@
<!-- highcharts -->
<script src="/static/js/highcharts/highcharts.js"></script>
<script src="/static/js/dropzone/dropzone.js"></script>
<!-- active menu -->
<script>

View File

@@ -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>

View File

@@ -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 %}

View File

@@ -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>

View File

@@ -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
View 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>

View 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 %}

View 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 %}

View 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>

View File

@@ -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 %}

View File

@@ -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")
});
}

File diff suppressed because one or more lines are too long

View 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
View 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>

View File

@@ -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 %}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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
View 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>