mirror of https://github.com/jumpserver/jumpserver
pull/6/head
parent
9348a0deb7
commit
fef224459c
|
@ -43,7 +43,8 @@ LOG_DIR = os.path.join(BASE_DIR, 'logs')
|
|||
SSH_KEY_DIR = os.path.join(BASE_DIR, 'keys')
|
||||
SERVER_KEY_DIR = os.path.join(SSH_KEY_DIR, 'server')
|
||||
KEY = CONF.get('web', 'key')
|
||||
LOGIN_NAME = getpass.getuser()
|
||||
#LOGIN_NAME = getpass.getuser()
|
||||
LOGIN_NAME = 'wy01'
|
||||
|
||||
|
||||
def color_print(msg, color='blue'):
|
||||
|
@ -103,6 +104,7 @@ def log_record(username, host):
|
|||
today_connect_log_dir = os.path.join(connect_log_dir, today)
|
||||
log_filename = '%s_%s_%s.log' % (username, host, time_now)
|
||||
log_file_path = os.path.join(today_connect_log_dir, log_filename)
|
||||
dept_name = User.objects.get(username=username).dept
|
||||
pid = os.getpid()
|
||||
ip_list = []
|
||||
remote_ip = os.popen("who |grep `ps aux |gawk '{if ($2==%s) print $1}'` |gawk '{print $5}'|tr -d '()'" % pid).readlines()
|
||||
|
@ -122,7 +124,7 @@ def log_record(username, host):
|
|||
except IOError:
|
||||
raise ServerError('Create logfile failed, Please modify %s permission.' % today_connect_log_dir)
|
||||
|
||||
log = Log(user=username, host=host, remote_ip=ip_list, log_path=log_file_path, start_time=datetime.now(), pid=pid)
|
||||
log = Log(user=username, host=host, remote_ip=ip_list, dept_name=dept_name, log_path=log_file_path, start_time=datetime.now(), pid=pid)
|
||||
log_file.write('Starttime is %s\n' % datetime.now())
|
||||
log.save()
|
||||
return log_file, log
|
||||
|
|
|
@ -13,7 +13,6 @@ django.setup()
|
|||
from juser.views import db_add_user, md5_crypt, CRYPTOR, db_add_group
|
||||
from jasset.models import Asset, IDC, BisGroup
|
||||
from juser.models import UserGroup, DEPT, User
|
||||
from jasset.views import jasset_group_add
|
||||
from jperm.models import CmdGroup
|
||||
from jlog.models import Log
|
||||
|
||||
|
@ -123,18 +122,18 @@ def test_add_log():
|
|||
end_time = datetime.datetime.now()
|
||||
log_path = '/var/log/jumpserver/test.log'
|
||||
host = '192.168.1.' + str(ip)
|
||||
Log.objects.create(user=user, host=host, log_path=log_path, pid=168, start_time=start_time,
|
||||
Log.objects.create(user=user, host=host, remote_ip='8.8.8.8', dept_name='运维部', log_path=log_path, pid=168, start_time=start_time,
|
||||
is_finished=1, log_finished=1, end_time=end_time)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
install()
|
||||
test_add_dept()
|
||||
test_add_group()
|
||||
test_add_user()
|
||||
test_add_idc()
|
||||
test_add_asset_group()
|
||||
test_add_asset()
|
||||
#install()
|
||||
#test_add_dept()
|
||||
#test_add_group()
|
||||
#test_add_user()
|
||||
#test_add_idc()
|
||||
#test_add_asset_group()
|
||||
#test_add_asset()
|
||||
test_add_log()
|
||||
|
||||
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
# coding:utf-8
|
||||
|
||||
import ast
|
||||
|
||||
from django.db.models import Q
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.template import RequestContext
|
||||
from django.shortcuts import render_to_response
|
||||
|
||||
from models import IDC, Asset, BisGroup
|
||||
from juser.models import UserGroup, DEPT, User
|
||||
from juser.models import UserGroup, DEPT
|
||||
from connect import PyCrypt, KEY
|
||||
from jlog.models import Log
|
||||
from jumpserver.views import jasset_host_edit, pages
|
||||
from jumpserver.api import asset_perm_api
|
||||
from jumpserver.api import user_perm_group_api, require_login, require_super_user, \
|
||||
require_admin, is_group_admin, is_super_user, get_user_dept
|
||||
require_admin, is_group_admin, is_super_user, is_common_user, get_user_dept
|
||||
|
||||
cryptor = PyCrypt(KEY)
|
||||
|
||||
|
@ -61,7 +63,7 @@ def add_host(request):
|
|||
eidc = IDC.objects.all()
|
||||
if is_super_user(request):
|
||||
edept = DEPT.objects.all()
|
||||
egroup = BisGroup.objects.all()
|
||||
egroup = BisGroup.objects.exclude(name='ALL')
|
||||
eusergroup = UserGroup.objects.all()
|
||||
elif is_group_admin(request):
|
||||
dept_id = get_user_dept(request)
|
||||
|
@ -93,21 +95,20 @@ def add_host(request):
|
|||
return render_to_response('jasset/host_add.html', locals(), context_instance=RequestContext(request))
|
||||
|
||||
|
||||
@require_admin
|
||||
def add_host_multi(request):
|
||||
header_title, path1, path2 = u'批量添加主机', u'资产管理', u'批量添加主机'
|
||||
login_types = {'LDAP': 'L', 'SSH_KEY': 'S', 'PASSWORD': 'P', 'MAP': 'M'}
|
||||
j_group = []
|
||||
login_types = {'LDAP': 'L', 'MAP': 'M'}
|
||||
dept_id = get_user_dept(request)
|
||||
if request.method == 'POST':
|
||||
multi_hosts = request.POST.get('j_multi').split('\n')
|
||||
for host in multi_hosts:
|
||||
if host == '':
|
||||
break
|
||||
j_ip, j_port, j_type, j_idc, j_groups, j_active, j_comment = host.split()
|
||||
j_ip, j_port, j_type, j_idc, j_groups, j_depts, j_active, j_comment = host.split()
|
||||
j_type = login_types[j_type]
|
||||
j_groups = j_groups.split(',')
|
||||
for group in j_groups:
|
||||
g = group.strip('[]').encode('utf-8').strip()
|
||||
j_group.append(g)
|
||||
j_group = ast.literal_eval(j_groups)
|
||||
j_dept = ast.literal_eval(j_depts)
|
||||
|
||||
if Asset.objects.filter(ip=str(j_ip)):
|
||||
emg = u'该IP %s 已存在!' % j_ip
|
||||
|
@ -117,9 +118,9 @@ def add_host_multi(request):
|
|||
if j_type == 'M':
|
||||
j_user = request.POST.get('j_user')
|
||||
j_password = cryptor.encrypt(request.POST.get('j_password'))
|
||||
f_add_host(j_ip, j_port, j_idc, j_type, j_group, j_active, j_comment, j_user, j_password)
|
||||
f_add_host(j_ip, j_port, j_idc, j_type, j_group, j_dept, j_active, j_comment, j_user, j_password)
|
||||
else:
|
||||
f_add_host(j_ip, j_port, j_idc, j_type, j_group, j_active, j_comment)
|
||||
f_add_host(j_ip, j_port, j_idc, j_type, j_group, j_dept, j_active, j_comment)
|
||||
|
||||
smg = u'批量添加添加成功'
|
||||
return HttpResponseRedirect('/jasset/host_list/')
|
||||
|
@ -127,6 +128,7 @@ def add_host_multi(request):
|
|||
return render_to_response('jasset/host_add_multi.html', locals(), context_instance=RequestContext(request))
|
||||
|
||||
|
||||
@require_admin
|
||||
def batch_host_edit(request):
|
||||
if request.method == 'POST':
|
||||
len_table = request.POST.get('len_table')
|
||||
|
@ -161,7 +163,8 @@ def batch_host_edit(request):
|
|||
|
||||
return render_to_response('jasset/host_list.html')
|
||||
|
||||
@require_admin
|
||||
|
||||
@require_login
|
||||
def list_host(request):
|
||||
header_title, path1, path2 = u'查看主机', u'资产管理', u'查看主机'
|
||||
login_types = {'L': 'LDAP', 'M': 'MAP'}
|
||||
|
@ -172,22 +175,23 @@ def list_host(request):
|
|||
if keyword:
|
||||
posts = Asset.objects.filter(Q(ip__contains=keyword) | Q(idc__name__contains=keyword) |
|
||||
Q(bis_group__name__contains=keyword) | Q(comment__contains=keyword)).distinct().order_by('ip')
|
||||
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
|
||||
|
||||
else:
|
||||
posts = Asset.objects.all().order_by('ip')
|
||||
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
|
||||
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
|
||||
elif is_group_admin(request):
|
||||
if keyword:
|
||||
posts = Asset.objects.filter(Q(ip__contains=keyword) | Q(idc__name__contains=keyword) |
|
||||
Q(bis_group__name__contains=keyword) | Q(comment__contains=keyword)).filter(dept=dept).distinct().order_by('ip')
|
||||
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
|
||||
else:
|
||||
posts = Asset.objects.all().filter(dept=dept).order_by('ip')
|
||||
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
|
||||
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
|
||||
|
||||
elif is_common_user(request):
|
||||
pass
|
||||
return render_to_response('jasset/host_list.html', locals(), context_instance=RequestContext(request))
|
||||
|
||||
|
||||
@require_admin
|
||||
def host_del(request, offset):
|
||||
if offset == 'multi':
|
||||
len_list = request.POST.get("len_list")
|
||||
|
@ -205,6 +209,7 @@ def host_del(request, offset):
|
|||
return HttpResponseRedirect('/jasset/host_list/')
|
||||
|
||||
|
||||
@require_admin
|
||||
def host_edit(request):
|
||||
actives = {1: u'激活', 0: u'禁用'}
|
||||
login_types = {'L': 'LDAP', 'M': 'MAP'}
|
||||
|
@ -271,6 +276,7 @@ def host_edit(request):
|
|||
return render_to_response('jasset/host_edit.html', locals(), context_instance=RequestContext(request))
|
||||
|
||||
|
||||
@require_login
|
||||
def jlist_ip(request, offset):
|
||||
header_title, path1, path2 = u'主机详细信息', u'资产管理', u'主机详情'
|
||||
login_types = {'L': 'LDAP', 'S': 'SSH_KEY', 'P': 'PASSWORD', 'M': 'MAP'}
|
||||
|
@ -280,6 +286,7 @@ def jlist_ip(request, offset):
|
|||
return render_to_response('jasset/jlist_ip.html', locals(), context_instance=RequestContext(request))
|
||||
|
||||
|
||||
@require_super_user
|
||||
def add_idc(request):
|
||||
header_title, path1, path2 = u'添加IDC', u'资产管理', u'添加IDC'
|
||||
if request.method == 'POST':
|
||||
|
@ -295,6 +302,7 @@ def add_idc(request):
|
|||
return render_to_response('jasset/idc_add.html', locals(), context_instance=RequestContext(request))
|
||||
|
||||
|
||||
@require_admin
|
||||
def list_idc(request):
|
||||
header_title, path1, path2 = u'查看IDC', u'资产管理', u'查看IDC'
|
||||
keyword = request.GET.get('keyword', '')
|
||||
|
@ -306,6 +314,7 @@ def list_idc(request):
|
|||
return render_to_response('jasset/idc_list.html', locals(), context_instance=RequestContext(request))
|
||||
|
||||
|
||||
@require_super_user
|
||||
def edit_idc(request):
|
||||
header_title, path1, path2 = u'编辑IDC', u'资产管理', u'编辑IDC'
|
||||
edit = 1
|
||||
|
@ -334,6 +343,7 @@ def edit_idc(request):
|
|||
return render_to_response('jasset/idc_add.html', locals(), context_instance=RequestContext(request))
|
||||
|
||||
|
||||
@require_super_user
|
||||
def del_idc(request, offset):
|
||||
if offset == 'multi':
|
||||
len_list = request.POST.get("len_list")
|
||||
|
@ -387,14 +397,14 @@ def list_group(request):
|
|||
keyword = request.GET.get('keyword', '')
|
||||
if is_super_user(request):
|
||||
if keyword:
|
||||
posts = BisGroup.objects.filter(Q(name__contains=keyword) | Q(comment__contains=keyword))
|
||||
posts = BisGroup.objects.exclude(name='ALL').filter(Q(name__contains=keyword) | Q(comment__contains=keyword))
|
||||
else:
|
||||
posts = BisGroup.objects.all().order_by('id')
|
||||
posts = BisGroup.objects.exclude(name='ALL').order_by('id')
|
||||
elif is_group_admin(request):
|
||||
if keyword:
|
||||
posts = BisGroup.objects.filter(Q(name__contains=keyword) | Q(comment__contains=keyword)).filter(dept=dept)
|
||||
else:
|
||||
posts = BisGroup.objects.all().filter(dept=dept).order_by('id')
|
||||
posts = BisGroup.objects.filter(dept=dept).order_by('id')
|
||||
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
|
||||
return render_to_response('jasset/group_list.html', locals(), context_instance=RequestContext(request))
|
||||
|
||||
|
@ -406,14 +416,17 @@ def edit_group(request):
|
|||
group = BisGroup.objects.get(id=group_id)
|
||||
all = Asset.objects.all()
|
||||
dept_id = get_user_dept(request)
|
||||
edept = DEPT.objects.get(id=dept_id)
|
||||
eposts = contact_list = Asset.objects.filter(bis_group=group).order_by('ip')
|
||||
|
||||
if is_super_user(request):
|
||||
edept = DEPT.objects.all()
|
||||
posts = [g for g in all if g not in eposts]
|
||||
|
||||
elif is_group_admin(request):
|
||||
dept = DEPT.objects.get(id=dept_id)
|
||||
all_dept = Asset.objects.filter(dept=dept)
|
||||
posts = [g for g in all_dept if g not in eposts]
|
||||
|
||||
if request.method == 'POST':
|
||||
j_group = request.POST.get('j_group')
|
||||
j_hosts = request.POST.getlist('j_hosts')
|
||||
|
@ -430,30 +443,43 @@ def edit_group(request):
|
|||
return render_to_response('jasset/group_add.html', locals(), context_instance=RequestContext(request))
|
||||
|
||||
|
||||
@require_admin
|
||||
def detail_group(request):
|
||||
header_title, path1, path2 = u'主机组详情', u'资产管理', u'主机组详情'
|
||||
login_types = {'L': 'LDAP', 'S': 'SSH_KEY', 'P': 'PASSWORD', 'M': 'MAP'}
|
||||
dept_id = get_user_dept(request)
|
||||
dept = DEPT.objects.get(id=dept_id)
|
||||
group_id = request.GET.get('id')
|
||||
group_name = BisGroup.objects.get(id=group_id).name
|
||||
b = BisGroup.objects.get(id=group_id)
|
||||
posts = Asset.objects.filter(bis_group=b).order_by('ip')
|
||||
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
|
||||
if is_super_user(request):
|
||||
posts = Asset.objects.filter(bis_group=b).order_by('ip')
|
||||
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
|
||||
|
||||
elif is_group_admin(request):
|
||||
posts = Asset.objects.filter(bis_group=b).filter(dept=dept).order_by('ip')
|
||||
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
|
||||
return render_to_response('jasset/group_detail.html', locals(), context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def detail_idc(request):
|
||||
header_title, path1, path2 = u'IDC详情', u'资产管理', u'IDC详情'
|
||||
login_types = {'L': 'LDAP', 'S': 'SSH_KEY', 'P': 'PASSWORD', 'M': 'MAP'}
|
||||
login_types = {'L': 'LDAP', 'M': 'MAP'}
|
||||
idc_id = request.GET.get('id')
|
||||
idc_name = IDC.objects.get(id=idc_id).name
|
||||
b = IDC.objects.get(id=idc_id)
|
||||
posts = Asset.objects.filter(idc=b).order_by('ip')
|
||||
dept_id = get_user_dept(request)
|
||||
dept = DEPT.objects.get(id=dept_id)
|
||||
if is_super_user(request):
|
||||
posts = Asset.objects.filter(idc=b).order_by('ip')
|
||||
elif is_group_admin(request):
|
||||
posts = Asset.objects.filter(idc=b).filter(dept=dept).order_by('ip')
|
||||
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
|
||||
|
||||
return render_to_response('jasset/idc_detail.html', locals(), context_instance=RequestContext(request))
|
||||
|
||||
|
||||
@require_admin
|
||||
def group_del_host(request, offset):
|
||||
if request.method == 'POST':
|
||||
group_name = request.POST.get('group_name')
|
||||
|
@ -475,6 +501,7 @@ def group_del_host(request, offset):
|
|||
return HttpResponseRedirect('/jasset/%s_detail/?id=%s' % (offset, group.id))
|
||||
|
||||
|
||||
@require_admin
|
||||
def group_del(request, offset):
|
||||
if offset == 'multi':
|
||||
len_list = request.POST.get("len_list")
|
||||
|
@ -490,10 +517,17 @@ def group_del(request, offset):
|
|||
|
||||
def host_search(request):
|
||||
keyword = request.GET.get('keyword')
|
||||
login_types = {'L': 'LDAP', 'S': 'SSH_KEY', 'P': 'PASSWORD', 'M': 'MAP'}
|
||||
posts = Asset.objects.filter(Q(ip__contains=keyword) | Q(idc__name__contains=keyword) |
|
||||
Q(bis_group__name__contains=keyword) | Q(
|
||||
comment__contains=keyword)).distinct().order_by('ip')
|
||||
login_types = {'L': 'LDAP', 'M': 'MAP'}
|
||||
dept_id = get_user_dept(request)
|
||||
dept = DEPT.objects.get(id=dept_id)
|
||||
if is_super_user(request):
|
||||
posts = Asset.objects.filter(Q(ip__contains=keyword) | Q(idc__name__contains=keyword) |
|
||||
Q(bis_group__name__contains=keyword) | Q(
|
||||
comment__contains=keyword)).distinct().order_by('ip')
|
||||
elif is_group_admin(request):
|
||||
posts = Asset.objects.filter(Q(ip__contains=keyword) | Q(idc__name__contains=keyword) |
|
||||
Q(bis_group__name__contains=keyword) | Q(
|
||||
comment__contains=keyword)).filter(dept=dept).distinct().order_by('ip')
|
||||
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
|
||||
|
||||
return render_to_response('jasset/host_search.html', locals(), context_instance=RequestContext(request))
|
||||
|
|
|
@ -5,6 +5,7 @@ class Log(models.Model):
|
|||
user = models.CharField(max_length=20, null=True)
|
||||
host = models.CharField(max_length=20, null=True)
|
||||
remote_ip = models.CharField(max_length=100)
|
||||
dept_name = models.CharField(max_length=20)
|
||||
log_path = models.CharField(max_length=100)
|
||||
start_time = models.DateTimeField(null=True)
|
||||
pid = models.IntegerField(max_length=10)
|
||||
|
|
|
@ -12,6 +12,8 @@ from django.shortcuts import render_to_response
|
|||
from connect import BASE_DIR
|
||||
from jlog.models import Log
|
||||
from jumpserver.views import pages
|
||||
from juser.models import User, DEPT
|
||||
from jumpserver.api import get_user_dept, is_super_user, is_group_admin, is_common_user
|
||||
|
||||
CONF = ConfigParser.ConfigParser()
|
||||
CONF.read('%s/jumpserver.conf' % BASE_DIR)
|
||||
|
@ -21,14 +23,30 @@ def log_list_online(request):
|
|||
header_title, path1, path2 = u'查看日志', u'查看日志', u'在线用户'
|
||||
keyword = request.GET.get('keyword')
|
||||
web_socket_host = CONF.get('websocket', 'web_socket_host')
|
||||
if keyword:
|
||||
posts = contact_list = Log.objects.filter(Q(user__contains=keyword) | Q(host__contains=keyword)) \
|
||||
.filter(is_finished=0).order_by('-start_time')
|
||||
dept_id = get_user_dept(request)
|
||||
dept_name = DEPT.objects.get(id=dept_id).name
|
||||
user_id = request.session.get('user_id')
|
||||
username = User.objects.get(id=user_id).username
|
||||
|
||||
if is_super_user(request):
|
||||
if keyword:
|
||||
posts = Log.objects.filter(Q(user__contains=keyword) | Q(host__contains=keyword)) \
|
||||
.filter(is_finished=0).order_by('-start_time')
|
||||
else:
|
||||
posts = Log.objects.filter(is_finished=0).order_by('-start_time')
|
||||
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
|
||||
else:
|
||||
posts = Log.objects.filter(is_finished=0).order_by('-start_time')
|
||||
|
||||
elif is_group_admin(request):
|
||||
if keyword:
|
||||
posts = Log.objects.filter(Q(user__contains=keyword) | Q(host__contains=keyword)) \
|
||||
.filter(is_finished=0).filter(dept_name=dept_name).order_by('-start_time')
|
||||
else:
|
||||
posts = Log.objects.filter(is_finished=0).filter(dept_name=dept_name).order_by('-start_time')
|
||||
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
|
||||
|
||||
elif is_common_user(request):
|
||||
posts = Log.objects.filter(is_finished=0).filter(user=username).order_by('-start_time')
|
||||
|
||||
return render_to_response('jlog/log_online.html', locals(), context_instance=RequestContext(request))
|
||||
|
||||
|
||||
|
@ -36,14 +54,29 @@ def log_list_offline(request):
|
|||
header_title, path1, path2 = u'查看日志', u'查看日志', u'历史记录'
|
||||
keyword = request.GET.get('keyword')
|
||||
web_socket_host = CONF.get('websocket', 'web_socket_host')
|
||||
if keyword:
|
||||
posts = contact_list = Log.objects.filter(Q(user__contains=keyword) | Q(host__contains=keyword)) \
|
||||
.filter(is_finished=1).order_by('-start_time')
|
||||
dept_id = get_user_dept(request)
|
||||
dept_name = DEPT.objects.get(id=dept_id).name
|
||||
user_id = request.session.get('user_id')
|
||||
username = User.objects.get(id=user_id).username
|
||||
if is_super_user(request):
|
||||
if keyword:
|
||||
posts = Log.objects.filter(Q(user__contains=keyword) | Q(host__contains=keyword)) \
|
||||
.filter(is_finished=1).order_by('-start_time')
|
||||
else:
|
||||
posts = Log.objects.filter(is_finished=1).order_by('-start_time')
|
||||
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
|
||||
else:
|
||||
posts = Log.objects.filter(is_finished=1).order_by('-start_time')
|
||||
|
||||
elif is_group_admin(request):
|
||||
if keyword:
|
||||
posts = Log.objects.filter(Q(user__contains=keyword) | Q(host__contains=keyword)) \
|
||||
.filter(is_finished=1).filter(dept_name=dept_name).order_by('-start_time')
|
||||
else:
|
||||
posts = Log.objects.filter(is_finished=1).filter(dept_name=dept_name).order_by('-start_time')
|
||||
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
|
||||
|
||||
elif is_common_user(request):
|
||||
posts = Log.objects.filter(is_finished=1).filter(user=username).order_by('-start_time')
|
||||
|
||||
return render_to_response('jlog/log_offline.html', locals(), context_instance=RequestContext(request))
|
||||
|
||||
|
||||
|
@ -70,13 +103,23 @@ def log_history(request):
|
|||
def log_search(request):
|
||||
keyword = request.GET.get('keyword')
|
||||
env = request.GET.get('env')
|
||||
if env == 'online':
|
||||
posts = contact_list = Log.objects.filter(Q(user__contains=keyword) | Q(host__contains=keyword)) \
|
||||
.filter(is_finished=0).order_by('-start_time')
|
||||
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
|
||||
elif env == 'offline':
|
||||
posts = contact_list = Log.objects.filter(Q(user__contains=keyword) | Q(host__contains=keyword)) \
|
||||
.filter(is_finished=1).order_by('-start_time')
|
||||
dept_id = get_user_dept(request)
|
||||
dept_name = DEPT.objects.get(id=dept_id).name
|
||||
if is_super_user(request):
|
||||
if env == 'online':
|
||||
posts = contact_list = Log.objects.filter(Q(user__contains=keyword) | Q(host__contains=keyword)) \
|
||||
.filter(is_finished=0).order_by('-start_time')
|
||||
elif env == 'offline':
|
||||
posts = contact_list = Log.objects.filter(Q(user__contains=keyword) | Q(host__contains=keyword)) \
|
||||
.filter(is_finished=1).order_by('-start_time')
|
||||
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
|
||||
|
||||
elif is_group_admin(request):
|
||||
if env == 'online':
|
||||
posts = contact_list = Log.objects.filter(Q(user__contains=keyword) | Q(host__contains=keyword)) \
|
||||
.filter(is_finished=0).filter(dept_name=dept_name).order_by('-start_time')
|
||||
elif env == 'offline':
|
||||
posts = contact_list = Log.objects.filter(Q(user__contains=keyword) | Q(host__contains=keyword)) \
|
||||
.filter(is_finished=1).filter(dept_name=dept_name).order_by('-start_time')
|
||||
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
|
||||
return render_to_response('jlog/log_search.html', locals(), context_instance=RequestContext(request))
|
||||
|
|
|
@ -94,6 +94,13 @@ def is_group_admin(request):
|
|||
return False
|
||||
|
||||
|
||||
def is_common_user(request):
|
||||
if request.session.get('role_id') == 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def get_user_dept(request):
|
||||
user_id = request.session.get('user_id')
|
||||
if user_id:
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from juser.models import User
|
||||
from jasset.models import Asset
|
||||
|
||||
|
||||
def name_proc(request):
|
||||
|
@ -6,8 +7,11 @@ def name_proc(request):
|
|||
role_id = request.session.get('role_id')
|
||||
user_total_num = User.objects.all().count()
|
||||
user_active_num = User.objects.filter(is_active=True).count()
|
||||
host_total_num = Asset.objects.all().count()
|
||||
host_active_num = Asset.objects.filter(is_active=True).count()
|
||||
request.session.set_expiry(3600)
|
||||
|
||||
return {'session_user_id': user_id, 'session_role_id': role_id,
|
||||
'user_total_num': user_total_num, 'user_active_num': user_active_num}
|
||||
'user_total_num': user_total_num, 'user_active_num': user_active_num,
|
||||
'host_total_num': host_total_num, 'host_active_num': host_active_num}
|
||||
|
||||
|
|
|
@ -159,22 +159,6 @@ def string_length(string, length):
|
|||
return '%s ...' % string[0:length]
|
||||
|
||||
|
||||
@register.filter(name='filter_private')
|
||||
def filter_private(group):
|
||||
agroup = []
|
||||
pattern = re.compile(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
|
||||
p = BisGroup.objects.get(name='ALL')
|
||||
for g in group:
|
||||
if not pattern.match(g.name):
|
||||
agroup.append(g)
|
||||
try:
|
||||
agroup.remove(p)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
return agroup
|
||||
|
||||
|
||||
@register.filter(name='to_name')
|
||||
def to_name(user_id):
|
||||
try:
|
||||
|
|
|
@ -0,0 +1,977 @@
|
|||
/*!
|
||||
* FullCalendar v2.2.0 Stylesheet
|
||||
* Docs & License: http://arshaw.com/fullcalendar/
|
||||
* (c) 2013 Adam Shaw
|
||||
*/
|
||||
|
||||
|
||||
.fc {
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.fc-rtl {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
body .fc { /* extra precedence to overcome jqui */
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
|
||||
/* Colors
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc-unthemed th,
|
||||
.fc-unthemed td,
|
||||
.fc-unthemed hr,
|
||||
.fc-unthemed thead,
|
||||
.fc-unthemed tbody,
|
||||
.fc-unthemed .fc-row,
|
||||
.fc-unthemed .fc-popover {
|
||||
border-color: #ddd;
|
||||
}
|
||||
|
||||
.fc-unthemed .fc-popover {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.fc-unthemed hr,
|
||||
.fc-unthemed .fc-popover .fc-header {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
.fc-unthemed .fc-popover .fc-header .fc-close {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.fc-unthemed .fc-today {
|
||||
background: #fcf8e3;
|
||||
}
|
||||
|
||||
.fc-highlight { /* when user is selecting cells */
|
||||
background: #bce8f1;
|
||||
opacity: .3;
|
||||
filter: alpha(opacity=30); /* for IE */
|
||||
}
|
||||
|
||||
.fc-bgevent { /* default look for background events */
|
||||
background: rgb(143, 223, 130);
|
||||
opacity: .3;
|
||||
filter: alpha(opacity=30); /* for IE */
|
||||
}
|
||||
|
||||
.fc-nonbusiness { /* default look for non-business-hours areas */
|
||||
/* will inherit .fc-bgevent's styles */
|
||||
background: #ccc;
|
||||
}
|
||||
|
||||
|
||||
/* Icons (inline elements with styled text that mock arrow icons)
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc-icon {
|
||||
display: inline-block;
|
||||
font-size: 2em;
|
||||
line-height: .5em;
|
||||
height: .5em; /* will make the total height 1em */
|
||||
font-family: "Courier New", Courier, monospace;
|
||||
}
|
||||
|
||||
.fc-icon-left-single-arrow:after {
|
||||
content: "\02039";
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.fc-icon-right-single-arrow:after {
|
||||
content: "\0203A";
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.fc-icon-left-double-arrow:after {
|
||||
content: "\000AB";
|
||||
}
|
||||
|
||||
.fc-icon-right-double-arrow:after {
|
||||
content: "\000BB";
|
||||
}
|
||||
|
||||
.fc-icon-x:after {
|
||||
content: "\000D7";
|
||||
}
|
||||
|
||||
|
||||
/* Buttons (styled <button> tags, normalized to work cross-browser)
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc button {
|
||||
/* force height to include the border and padding */
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
|
||||
/* dimensions */
|
||||
margin: 0;
|
||||
height: 2.1em;
|
||||
padding: 0 .6em;
|
||||
|
||||
/* text & cursor */
|
||||
font-size: 1em; /* normalize */
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Firefox has an annoying inner border */
|
||||
.fc button::-moz-focus-inner { margin: 0; padding: 0; }
|
||||
|
||||
.fc-state-default { /* non-theme */
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.fc-state-default.fc-corner-left { /* non-theme */
|
||||
border-top-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
|
||||
.fc-state-default.fc-corner-right { /* non-theme */
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
|
||||
/* icons in buttons */
|
||||
|
||||
.fc button .fc-icon { /* non-theme */
|
||||
position: relative;
|
||||
top: .05em; /* seems to be a good adjustment across browsers */
|
||||
margin: 0 .1em;
|
||||
}
|
||||
|
||||
/*
|
||||
button states
|
||||
borrowed from twitter bootstrap (http://twitter.github.com/bootstrap/)
|
||||
*/
|
||||
|
||||
.fc-state-default {
|
||||
background-color: #f5f5f5;
|
||||
background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));
|
||||
background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
|
||||
background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
|
||||
background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #e6e6e6 #e6e6e6 #bfbfbf;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
color: #333;
|
||||
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.fc-state-hover,
|
||||
.fc-state-down,
|
||||
.fc-state-active,
|
||||
.fc-state-disabled {
|
||||
color: #333333;
|
||||
background-color: #e6e6e6;
|
||||
}
|
||||
|
||||
.fc-state-hover {
|
||||
color: #333333;
|
||||
text-decoration: none;
|
||||
background-position: 0 -15px;
|
||||
-webkit-transition: background-position 0.1s linear;
|
||||
-moz-transition: background-position 0.1s linear;
|
||||
-o-transition: background-position 0.1s linear;
|
||||
transition: background-position 0.1s linear;
|
||||
}
|
||||
|
||||
.fc-state-down,
|
||||
.fc-state-active {
|
||||
background-color: #cccccc;
|
||||
background-image: none;
|
||||
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.fc-state-disabled {
|
||||
cursor: default;
|
||||
background-image: none;
|
||||
opacity: 0.65;
|
||||
filter: alpha(opacity=65);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
|
||||
/* Buttons Groups
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc-button-group {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/*
|
||||
every button that is not first in a button group should scootch over one pixel and cover the
|
||||
previous button's border...
|
||||
*/
|
||||
|
||||
.fc .fc-button-group > * { /* extra precedence b/c buttons have margin set to zero */
|
||||
float: left;
|
||||
margin: 0 0 0 -1px;
|
||||
}
|
||||
|
||||
.fc .fc-button-group > :first-child { /* same */
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
|
||||
/* Popover
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc-popover {
|
||||
position: absolute;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,.15);
|
||||
}
|
||||
|
||||
.fc-popover .fc-header {
|
||||
padding: 2px 4px;
|
||||
}
|
||||
|
||||
.fc-popover .fc-header .fc-title {
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
.fc-popover .fc-header .fc-close {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.fc-ltr .fc-popover .fc-header .fc-title,
|
||||
.fc-rtl .fc-popover .fc-header .fc-close {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.fc-rtl .fc-popover .fc-header .fc-title,
|
||||
.fc-ltr .fc-popover .fc-header .fc-close {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* unthemed */
|
||||
|
||||
.fc-unthemed .fc-popover {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.fc-unthemed .fc-popover .fc-header .fc-close {
|
||||
font-size: 25px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* jqui themed */
|
||||
|
||||
.fc-popover > .ui-widget-header + .ui-widget-content {
|
||||
border-top: 0; /* where they meet, let the header have the border */
|
||||
}
|
||||
|
||||
|
||||
/* Misc Reusable Components
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc hr {
|
||||
height: 0;
|
||||
margin: 0;
|
||||
padding: 0 0 2px; /* height is unreliable across browsers, so use padding */
|
||||
border-style: solid;
|
||||
border-width: 1px 0;
|
||||
}
|
||||
|
||||
.fc-clear {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.fc-bg,
|
||||
.fc-bgevent-skeleton,
|
||||
.fc-highlight-skeleton,
|
||||
.fc-helper-skeleton {
|
||||
/* these element should always cling to top-left/right corners */
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.fc-bg {
|
||||
bottom: 0; /* strech bg to bottom edge */
|
||||
}
|
||||
|
||||
.fc-bg table {
|
||||
height: 100%; /* strech bg to bottom edge */
|
||||
}
|
||||
|
||||
|
||||
/* Tables
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc table {
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
font-size: 1em; /* normalize cross-browser */
|
||||
}
|
||||
|
||||
.fc th {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.fc th,
|
||||
.fc td {
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
padding: 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.fc td.fc-today {
|
||||
border-style: double; /* overcome neighboring borders */
|
||||
}
|
||||
|
||||
|
||||
/* Fake Table Rows
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc .fc-row { /* extra precedence to overcome themes w/ .ui-widget-content forcing a 1px border */
|
||||
/* no visible border by default. but make available if need be (scrollbar width compensation) */
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.fc-row table {
|
||||
/* don't put left/right border on anything within a fake row.
|
||||
the outer tbody will worry about this */
|
||||
border-left: 0 hidden transparent;
|
||||
border-right: 0 hidden transparent;
|
||||
|
||||
/* no bottom borders on rows */
|
||||
border-bottom: 0 hidden transparent;
|
||||
}
|
||||
|
||||
.fc-row:first-child table {
|
||||
border-top: 0 hidden transparent; /* no top border on first row */
|
||||
}
|
||||
|
||||
|
||||
/* Day Row (used within the header and the DayGrid)
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc-row {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.fc-row .fc-bg {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* highlighting cells & background event skeleton */
|
||||
|
||||
.fc-row .fc-bgevent-skeleton,
|
||||
.fc-row .fc-highlight-skeleton {
|
||||
bottom: 0; /* stretch skeleton to bottom of row */
|
||||
}
|
||||
|
||||
.fc-row .fc-bgevent-skeleton table,
|
||||
.fc-row .fc-highlight-skeleton table {
|
||||
height: 100%; /* stretch skeleton to bottom of row */
|
||||
}
|
||||
|
||||
.fc-row .fc-highlight-skeleton td,
|
||||
.fc-row .fc-bgevent-skeleton td {
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.fc-row .fc-bgevent-skeleton {
|
||||
z-index: 2;
|
||||
|
||||
}
|
||||
|
||||
.fc-row .fc-highlight-skeleton {
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
/*
|
||||
row content (which contains day/week numbers and events) as well as "helper" (which contains
|
||||
temporary rendered events).
|
||||
*/
|
||||
|
||||
.fc-row .fc-content-skeleton {
|
||||
position: relative;
|
||||
z-index: 4;
|
||||
padding-bottom: 2px; /* matches the space above the events */
|
||||
}
|
||||
|
||||
.fc-row .fc-helper-skeleton {
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.fc-row .fc-content-skeleton td,
|
||||
.fc-row .fc-helper-skeleton td {
|
||||
/* see-through to the background below */
|
||||
background: none; /* in case <td>s are globally styled */
|
||||
border-color: transparent;
|
||||
|
||||
/* don't put a border between events and/or the day number */
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.fc-row .fc-content-skeleton tbody td, /* cells with events inside (so NOT the day number cell) */
|
||||
.fc-row .fc-helper-skeleton tbody td {
|
||||
/* don't put a border between event cells */
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
|
||||
/* Scrolling Container
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc-scroller { /* this class goes on elements for guaranteed vertical scrollbars */
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.fc-scroller > * { /* we expect an immediate inner element */
|
||||
position: relative; /* re-scope all positions */
|
||||
width: 100%; /* hack to force re-sizing this inner element when scrollbars appear/disappear */
|
||||
overflow: hidden; /* don't let negative margins or absolute positioning create further scroll */
|
||||
}
|
||||
|
||||
|
||||
/* Global Event Styles
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc-event {
|
||||
position: relative; /* for resize handle and other inner positioning */
|
||||
display: block; /* make the <a> tag block */
|
||||
font-size: .85em;
|
||||
line-height: 1.3;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #3a87ad; /* default BORDER color */
|
||||
background-color: #3a87ad; /* default BACKGROUND color */
|
||||
font-weight: normal; /* undo jqui's ui-widget-header bold */
|
||||
}
|
||||
|
||||
/* overpower some of bootstrap's and jqui's styles on <a> tags */
|
||||
.fc-event,
|
||||
.fc-event:hover,
|
||||
.ui-widget .fc-event {
|
||||
color: #fff; /* default TEXT color */
|
||||
text-decoration: none; /* if <a> has an href */
|
||||
}
|
||||
|
||||
.fc-event[href],
|
||||
.fc-event.fc-draggable {
|
||||
cursor: pointer; /* give events with links and draggable events a hand mouse pointer */
|
||||
}
|
||||
|
||||
.fc-not-allowed, /* causes a "warning" cursor. applied on body */
|
||||
.fc-not-allowed .fc-event { /* to override an event's custom cursor */
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
|
||||
/* DayGrid events
|
||||
----------------------------------------------------------------------------------------------------
|
||||
We use the full "fc-day-grid-event" class instead of using descendants because the event won't
|
||||
be a descendant of the grid when it is being dragged.
|
||||
*/
|
||||
|
||||
.fc-day-grid-event {
|
||||
margin: 1px 2px 0; /* spacing between events and edges */
|
||||
padding: 0 1px;
|
||||
}
|
||||
|
||||
/* events that are continuing to/from another week. kill rounded corners and butt up against edge */
|
||||
|
||||
.fc-ltr .fc-day-grid-event.fc-not-start,
|
||||
.fc-rtl .fc-day-grid-event.fc-not-end {
|
||||
margin-left: 0;
|
||||
border-left-width: 0;
|
||||
padding-left: 1px; /* replace the border with padding */
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.fc-ltr .fc-day-grid-event.fc-not-end,
|
||||
.fc-rtl .fc-day-grid-event.fc-not-start {
|
||||
margin-right: 0;
|
||||
border-right-width: 0;
|
||||
padding-right: 1px; /* replace the border with padding */
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.fc-day-grid-event > .fc-content { /* force events to be one-line tall */
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fc-day-grid-event .fc-time {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* resize handle (outside of fc-content, so can go outside of bounds) */
|
||||
|
||||
.fc-day-grid-event .fc-resizer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 7px;
|
||||
}
|
||||
|
||||
.fc-ltr .fc-day-grid-event .fc-resizer {
|
||||
right: -3px;
|
||||
cursor: e-resize;
|
||||
}
|
||||
|
||||
.fc-rtl .fc-day-grid-event .fc-resizer {
|
||||
left: -3px;
|
||||
cursor: w-resize;
|
||||
}
|
||||
|
||||
|
||||
/* Event Limiting
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* "more" link that represents hidden events */
|
||||
|
||||
a.fc-more {
|
||||
margin: 1px 3px;
|
||||
font-size: .85em;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a.fc-more:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.fc-limited { /* rows and cells that are hidden because of a "more" link */
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* popover that appears when "more" link is clicked */
|
||||
|
||||
.fc-day-grid .fc-row {
|
||||
z-index: 1; /* make the "more" popover one higher than this */
|
||||
}
|
||||
|
||||
.fc-more-popover {
|
||||
z-index: 2;
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.fc-more-popover .fc-event-container {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
/* Toolbar
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc-toolbar {
|
||||
text-align: center;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.fc-toolbar .fc-left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.fc-toolbar .fc-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.fc-toolbar .fc-center {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* the things within each left/right/center section */
|
||||
.fc .fc-toolbar > * > * { /* extra precedence to override button border margins */
|
||||
float: left;
|
||||
margin-left: .75em;
|
||||
}
|
||||
|
||||
/* the first thing within each left/center/right section */
|
||||
.fc .fc-toolbar > * > :first-child { /* extra precedence to override button border margins */
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
/* title text */
|
||||
|
||||
.fc-toolbar h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* button layering (for border precedence) */
|
||||
|
||||
.fc-toolbar button {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.fc-toolbar .fc-state-hover,
|
||||
.fc-toolbar .ui-state-hover {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.fc-toolbar .fc-state-down {
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.fc-toolbar .fc-state-active,
|
||||
.fc-toolbar .ui-state-active {
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.fc-toolbar button:focus {
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
|
||||
/* View Structure
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* undo twitter bootstrap's box-sizing rules. normalizes positioning techniques */
|
||||
/* don't do this for the toolbar because we'll want bootstrap to style those buttons as some pt */
|
||||
.fc-view-container *,
|
||||
.fc-view-container *:before,
|
||||
.fc-view-container *:after {
|
||||
-webkit-box-sizing: content-box;
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.fc-view, /* scope positioning and z-index's for everything within the view */
|
||||
.fc-view > table { /* so dragged elements can be above the view's main element */
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* BasicView
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* day row structure */
|
||||
|
||||
.fc-basicWeek-view .fc-content-skeleton,
|
||||
.fc-basicDay-view .fc-content-skeleton {
|
||||
/* we are sure there are no day numbers in these views, so... */
|
||||
padding-top: 1px; /* add a pixel to make sure there are 2px padding above events */
|
||||
padding-bottom: 1em; /* ensure a space at bottom of cell for user selecting/clicking */
|
||||
}
|
||||
|
||||
.fc-basic-view tbody .fc-row {
|
||||
min-height: 4em; /* ensure that all rows are at least this tall */
|
||||
}
|
||||
|
||||
/* a "rigid" row will take up a constant amount of height because content-skeleton is absolute */
|
||||
|
||||
.fc-row.fc-rigid {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fc-row.fc-rigid .fc-content-skeleton {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
/* week and day number styling */
|
||||
|
||||
.fc-basic-view .fc-week-number,
|
||||
.fc-basic-view .fc-day-number {
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
.fc-basic-view td.fc-week-number span,
|
||||
.fc-basic-view td.fc-day-number {
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.fc-basic-view .fc-week-number {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.fc-basic-view .fc-week-number span {
|
||||
/* work around the way we do column resizing and ensure a minimum width */
|
||||
display: inline-block;
|
||||
min-width: 1.25em;
|
||||
}
|
||||
|
||||
.fc-ltr .fc-basic-view .fc-day-number {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.fc-rtl .fc-basic-view .fc-day-number {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.fc-day-number.fc-other-month {
|
||||
opacity: 0.3;
|
||||
filter: alpha(opacity=30); /* for IE */
|
||||
/* opacity with small font can sometimes look too faded
|
||||
might want to set the 'color' property instead
|
||||
making day-numbers bold also fixes the problem */
|
||||
}
|
||||
|
||||
/* AgendaView all-day area
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc-agenda-view .fc-day-grid {
|
||||
position: relative;
|
||||
z-index: 2; /* so the "more.." popover will be over the time grid */
|
||||
}
|
||||
|
||||
.fc-agenda-view .fc-day-grid .fc-row {
|
||||
min-height: 3em; /* all-day section will never get shorter than this */
|
||||
}
|
||||
|
||||
.fc-agenda-view .fc-day-grid .fc-row .fc-content-skeleton {
|
||||
padding-top: 1px; /* add a pixel to make sure there are 2px padding above events */
|
||||
padding-bottom: 1em; /* give space underneath events for clicking/selecting days */
|
||||
}
|
||||
|
||||
|
||||
/* TimeGrid axis running down the side (for both the all-day area and the slot area)
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc .fc-axis { /* .fc to overcome default cell styles */
|
||||
vertical-align: middle;
|
||||
padding: 0 4px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.fc-ltr .fc-axis {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.fc-rtl .fc-axis {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.ui-widget td.fc-axis {
|
||||
font-weight: normal; /* overcome jqui theme making it bold */
|
||||
}
|
||||
|
||||
|
||||
/* TimeGrid Structure
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc-time-grid-container, /* so scroll container's z-index is below all-day */
|
||||
.fc-time-grid { /* so slats/bg/content/etc positions get scoped within here */
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.fc-time-grid {
|
||||
min-height: 100%; /* so if height setting is 'auto', .fc-bg stretches to fill height */
|
||||
}
|
||||
|
||||
.fc-time-grid table { /* don't put outer borders on slats/bg/content/etc */
|
||||
border: 0 hidden transparent;
|
||||
}
|
||||
|
||||
.fc-time-grid > .fc-bg {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.fc-time-grid .fc-slats,
|
||||
.fc-time-grid > hr { /* the <hr> AgendaView injects when grid is shorter than scroller */
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.fc-time-grid .fc-bgevent-skeleton,
|
||||
.fc-time-grid .fc-content-skeleton {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.fc-time-grid .fc-bgevent-skeleton {
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.fc-time-grid .fc-highlight-skeleton {
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.fc-time-grid .fc-content-skeleton {
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.fc-time-grid .fc-helper-skeleton {
|
||||
z-index: 6;
|
||||
}
|
||||
|
||||
|
||||
/* TimeGrid Slats (lines that run horizontally)
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc-slats td {
|
||||
height: 1.5em;
|
||||
border-bottom: 0; /* each cell is responsible for its top border */
|
||||
}
|
||||
|
||||
.fc-slats .fc-minor td {
|
||||
border-top-style: dotted;
|
||||
}
|
||||
|
||||
.fc-slats .ui-widget-content { /* for jqui theme */
|
||||
background: none; /* see through to fc-bg */
|
||||
}
|
||||
|
||||
|
||||
/* TimeGrid Highlighting Slots
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc-time-grid .fc-highlight-container { /* a div within a cell within the fc-highlight-skeleton */
|
||||
position: relative; /* scopes the left/right of the fc-highlight to be in the column */
|
||||
}
|
||||
|
||||
.fc-time-grid .fc-highlight {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
/* top and bottom will be in by JS */
|
||||
}
|
||||
|
||||
|
||||
/* TimeGrid Event Containment
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc-time-grid .fc-event-container, /* a div within a cell within the fc-content-skeleton */
|
||||
.fc-time-grid .fc-bgevent-container { /* a div within a cell within the fc-bgevent-skeleton */
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.fc-ltr .fc-time-grid .fc-event-container { /* space on the sides of events for LTR (default) */
|
||||
margin: 0 2.5% 0 2px;
|
||||
}
|
||||
|
||||
.fc-rtl .fc-time-grid .fc-event-container { /* space on the sides of events for RTL */
|
||||
margin: 0 2px 0 2.5%;
|
||||
}
|
||||
|
||||
.fc-time-grid .fc-event,
|
||||
.fc-time-grid .fc-bgevent {
|
||||
position: absolute;
|
||||
z-index: 1; /* scope inner z-index's */
|
||||
}
|
||||
|
||||
.fc-time-grid .fc-bgevent {
|
||||
/* background events always span full width */
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
|
||||
/* TimeGrid Event Styling
|
||||
----------------------------------------------------------------------------------------------------
|
||||
We use the full "fc-time-grid-event" class instead of using descendants because the event won't
|
||||
be a descendant of the grid when it is being dragged.
|
||||
*/
|
||||
|
||||
.fc-time-grid-event.fc-not-start { /* events that are continuing from another day */
|
||||
/* replace space made by the top border with padding */
|
||||
border-top-width: 0;
|
||||
padding-top: 1px;
|
||||
|
||||
/* remove top rounded corners */
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
.fc-time-grid-event.fc-not-end {
|
||||
/* replace space made by the top border with padding */
|
||||
border-bottom-width: 0;
|
||||
padding-bottom: 1px;
|
||||
|
||||
/* remove bottom rounded corners */
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.fc-time-grid-event {
|
||||
overflow: hidden; /* don't let the bg flow over rounded corners */
|
||||
}
|
||||
|
||||
.fc-time-grid-event > .fc-content { /* contains the time and title, but no bg and resizer */
|
||||
position: relative;
|
||||
z-index: 2; /* above the bg */
|
||||
}
|
||||
|
||||
.fc-time-grid-event .fc-time,
|
||||
.fc-time-grid-event .fc-title {
|
||||
padding: 0 1px;
|
||||
}
|
||||
|
||||
.fc-time-grid-event .fc-time {
|
||||
font-size: .85em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.fc-time-grid-event .fc-bg {
|
||||
z-index: 1;
|
||||
background: #fff;
|
||||
opacity: .25;
|
||||
filter: alpha(opacity=25); /* for IE */
|
||||
}
|
||||
|
||||
/* short mode, where time and title are on the same line */
|
||||
|
||||
.fc-time-grid-event.fc-short .fc-content {
|
||||
/* don't wrap to second line (now that contents will be inline) */
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.fc-time-grid-event.fc-short .fc-time,
|
||||
.fc-time-grid-event.fc-short .fc-title {
|
||||
/* put the time and title on the same line */
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.fc-time-grid-event.fc-short .fc-time span {
|
||||
display: none; /* don't display the full time text... */
|
||||
}
|
||||
|
||||
.fc-time-grid-event.fc-short .fc-time:before {
|
||||
content: attr(data-start); /* ...instead, display only the start time */
|
||||
}
|
||||
|
||||
.fc-time-grid-event.fc-short .fc-time:after {
|
||||
content: "\000A0-\000A0"; /* seperate with a dash, wrapped in nbsp's */
|
||||
}
|
||||
|
||||
.fc-time-grid-event.fc-short .fc-title {
|
||||
font-size: .85em; /* make the title text the same size as the time */
|
||||
padding: 0; /* undo padding from above */
|
||||
}
|
||||
|
||||
/* resizer */
|
||||
|
||||
.fc-time-grid-event .fc-resizer {
|
||||
position: absolute;
|
||||
z-index: 3; /* above content */
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 8px;
|
||||
overflow: hidden;
|
||||
line-height: 8px;
|
||||
font-size: 11px;
|
||||
font-family: monospace;
|
||||
text-align: center;
|
||||
cursor: s-resize;
|
||||
}
|
||||
|
||||
.fc-time-grid-event .fc-resizer:after {
|
||||
content: "=";
|
||||
}
|
|
@ -0,0 +1,202 @@
|
|||
/*!
|
||||
* FullCalendar v2.2.0 Print Stylesheet
|
||||
* Docs & License: http://arshaw.com/fullcalendar/
|
||||
* (c) 2013 Adam Shaw
|
||||
*/
|
||||
|
||||
/*
|
||||
* Include this stylesheet on your page to get a more printer-friendly calendar.
|
||||
* When including this stylesheet, use the media='print' attribute of the <link> tag.
|
||||
* Make sure to include this stylesheet IN ADDITION to the regular fullcalendar.css.
|
||||
*/
|
||||
|
||||
.fc {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
|
||||
/* Global Event Restyling
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc-event {
|
||||
background: #fff !important;
|
||||
color: #000 !important;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
.fc-event .fc-resizer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/* Table & Day-Row Restyling
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
th,
|
||||
td,
|
||||
hr,
|
||||
thead,
|
||||
tbody,
|
||||
.fc-row {
|
||||
border-color: #ccc !important;
|
||||
background: #fff !important;
|
||||
}
|
||||
|
||||
/* kill the overlaid, absolutely-positioned common components */
|
||||
.fc-bg,
|
||||
.fc-bgevent-skeleton,
|
||||
.fc-highlight-skeleton,
|
||||
.fc-helper-skeleton {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* don't force a min-height on rows (for DayGrid) */
|
||||
.fc tbody .fc-row {
|
||||
height: auto !important; /* undo height that JS set in distributeHeight */
|
||||
min-height: 0 !important; /* undo the min-height from each view's specific stylesheet */
|
||||
}
|
||||
|
||||
.fc tbody .fc-row .fc-content-skeleton {
|
||||
position: static; /* undo .fc-rigid */
|
||||
padding-bottom: 0 !important; /* use a more border-friendly method for this... */
|
||||
}
|
||||
|
||||
.fc tbody .fc-row .fc-content-skeleton tbody tr:last-child td { /* only works in newer browsers */
|
||||
padding-bottom: 1em; /* ...gives space within the skeleton. also ensures min height in a way */
|
||||
}
|
||||
|
||||
.fc tbody .fc-row .fc-content-skeleton table {
|
||||
/* provides a min-height for the row, but only effective for IE, which exaggerates this value,
|
||||
making it look more like 3em. for other browers, it will already be this tall */
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
|
||||
/* Undo month-view event limiting. Display all events and hide the "more" links
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc-more-cell,
|
||||
.fc-more {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.fc tr.fc-limited {
|
||||
display: table-row !important;
|
||||
}
|
||||
|
||||
.fc td.fc-limited {
|
||||
display: table-cell !important;
|
||||
}
|
||||
|
||||
.fc-popover {
|
||||
display: none; /* never display the "more.." popover in print mode */
|
||||
}
|
||||
|
||||
|
||||
/* TimeGrid Restyling
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* undo the min-height 100% trick used to fill the container's height */
|
||||
.fc-time-grid {
|
||||
min-height: 0 !important;
|
||||
}
|
||||
|
||||
/* don't display the side axis at all ("all-day" and time cells) */
|
||||
.fc-agenda-view .fc-axis {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* don't display the horizontal lines */
|
||||
.fc-slats,
|
||||
.fc-time-grid hr { /* this hr is used when height is underused and needs to be filled */
|
||||
display: none !important; /* important overrides inline declaration */
|
||||
}
|
||||
|
||||
/* let the container that holds the events be naturally positioned and create real height */
|
||||
.fc-time-grid .fc-content-skeleton {
|
||||
position: static;
|
||||
}
|
||||
|
||||
/* in case there are no events, we still want some height */
|
||||
.fc-time-grid .fc-content-skeleton table {
|
||||
height: 4em;
|
||||
}
|
||||
|
||||
/* kill the horizontal spacing made by the event container. event margins will be done below */
|
||||
.fc-time-grid .fc-event-container {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
|
||||
/* TimeGrid *Event* Restyling
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* naturally position events, vertically stacking them */
|
||||
.fc-time-grid .fc-event {
|
||||
position: static !important;
|
||||
margin: 3px 2px !important;
|
||||
}
|
||||
|
||||
/* for events that continue to a future day, give the bottom border back */
|
||||
.fc-time-grid .fc-event.fc-not-end {
|
||||
border-bottom-width: 1px !important;
|
||||
}
|
||||
|
||||
/* indicate the event continues via "..." text */
|
||||
.fc-time-grid .fc-event.fc-not-end:after {
|
||||
content: "...";
|
||||
}
|
||||
|
||||
/* for events that are continuations from previous days, give the top border back */
|
||||
.fc-time-grid .fc-event.fc-not-start {
|
||||
border-top-width: 1px !important;
|
||||
}
|
||||
|
||||
/* indicate the event is a continuation via "..." text */
|
||||
.fc-time-grid .fc-event.fc-not-start:before {
|
||||
content: "...";
|
||||
}
|
||||
|
||||
/* time */
|
||||
|
||||
/* undo a previous declaration and let the time text span to a second line */
|
||||
.fc-time-grid .fc-event .fc-time {
|
||||
white-space: normal !important;
|
||||
}
|
||||
|
||||
/* hide the the time that is normally displayed... */
|
||||
.fc-time-grid .fc-event .fc-time span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ...replace it with a more verbose version (includes AM/PM) stored in an html attribute */
|
||||
.fc-time-grid .fc-event .fc-time:after {
|
||||
content: attr(data-full);
|
||||
}
|
||||
|
||||
|
||||
/* Vertical Scroller & Containers
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* kill the scrollbars and allow natural height */
|
||||
.fc-scroller,
|
||||
.fc-day-grid-container, /* these divs might be assigned height, which we need to cleared */
|
||||
.fc-time-grid-container { /* */
|
||||
overflow: visible !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
/* kill the horizontal border/padding used to compensate for scrollbars */
|
||||
.fc-row {
|
||||
border: 0 !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
|
||||
/* Button Controls
|
||||
--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.fc-button-group,
|
||||
.fc button {
|
||||
display: none; /* don't display any button-related controls */
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -3,6 +3,8 @@
|
|||
<script src="/static/js/plugins/slimscroll/jquery.slimscroll.min.js"></script>
|
||||
<script src="/static/js/bootstrap-dialog.js"></script>
|
||||
<script src="/static/js/mindmup-editabletable.js"></script>
|
||||
<script src="/static/js/plugins/fullcalendar/moment.min.js"></script>
|
||||
<script src="/static/js/plugins/fullcalendar/fullcalendar.min.js"></script>
|
||||
|
||||
<!-- Custom and plugin javascript -->
|
||||
<script src="/static/js/inspinia.js"></script>
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
{% ifequal session_role_id 1 %}
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="form-group">
|
||||
<label for="j_dept" class="col-lg-2 control-label">所属部门<span class="red-fonts">*</span></label>
|
||||
<label for="j_dept" class="col-lg-2 control-label">所属部门<span class="red-fonts" style="">*</span></label>
|
||||
<div class="col-sm-8"><input type="text" name="j_dept" value="{{ edept.name }}" class="form-control" readonly="readonly"></div>
|
||||
</div>
|
||||
{% endifequal %}
|
||||
|
@ -54,9 +54,9 @@
|
|||
</select>
|
||||
</div>
|
||||
<div class="col-sm-1">
|
||||
<div class="btn-group" style="margin-top: 50px;">
|
||||
<button type="button" class="btn btn-white" onclick="move('groups', 'groups_selected')"><i class="fa fa-chevron-right"></i></button>
|
||||
<button type="button" class="btn btn-white" onclick="move_left('groups_selected', 'groups')"><i class="fa fa-chevron-left"></i> </button>
|
||||
<div class="fc-button-group" style="margin-top: 50px;">
|
||||
<button type="button" class="fc-button fc-state-default" onclick="move('groups', 'groups_selected')"><span class="fc-icon fc-icon-right-single-arrow"></span></button>
|
||||
<button type="button" class="fc-button fc-state-default" onclick="move_left('groups_selected', 'groups')"><span class="fc-icon fc-icon-left-single-arrow"></span></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
|
|
|
@ -118,16 +118,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!--<div class="hr-line-dashed"></div>-->
|
||||
<!--<div class="form-group">-->
|
||||
<!--<label for="j_group" class="col-sm-2 control-label"> 所属用户组<span class="red-fonts">*</span> </label>-->
|
||||
<!--<div class="col-sm-8">-->
|
||||
<!--{% for g in eusergroup %}-->
|
||||
<!--<label class="checkbox-inline"><input type="checkbox" id="j_usergroup" value="{{ g }}" name="j_usergroup"> {{ g }} </label>-->
|
||||
<!--{% endfor %}-->
|
||||
<!--</div>-->
|
||||
<!--</div>-->
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="form-group"><label class="col-sm-2 control-label"> 是否激活<span class="red-fonts">*</span> </label>
|
||||
<div class="col-sm-8">
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
{% endif %}
|
||||
<h4>按照文本框内主机信息格式填写, 多台主机回车换行</h4>
|
||||
<form id="assetMulti" method="post" class="form-horizontal">
|
||||
<div><textarea id="j_multi" name="j_multi" type="text" placeholder="192.168.1.1 22 LDAP 北京联通 [网站,数据库] 1 网站服务器" class="form-control" style="width:700px;height:500px"></textarea></div>
|
||||
<div><textarea id="j_multi" name="j_multi" type="text" placeholder="192.168.1.1 22 LDAP 北京联通 [网站,数据库] 运维部 1 网站服务器" class="form-control" style="width:700px;height:500px">192.168.1.1 22 LDAP 北京联通 ['网站','数据库'] ['运维部','测试部'] 1 网站服务器</textarea></div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-4 col-sm-offset-4">
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th class="text-center"> 用户名 </th>
|
||||
<th class="text-center"> 所属部门 </th>
|
||||
<th class="text-center"> 登录主机 </th>
|
||||
<th class="text-center"> 来源IP </th>
|
||||
<th class="text-center"> 命令统计 </th>
|
||||
|
@ -89,8 +90,9 @@
|
|||
{% 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="ip"> {{ post.remote_ip }} </td>
|
||||
<td class="text-center" id="remote_ip"> {{ post.remote_ip }} </td>
|
||||
<td class="text-center"><a href="/jlog/history/?id={{ post.id }}" class="log_command"> 命令统计 </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>
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th class="text-center"> 用户名 </th>
|
||||
<th class="text-center"> 所属部门 </th>
|
||||
<th class="text-center"> 登录主机 </th>
|
||||
<th class="text-center"> 来源IP </th>
|
||||
<th class="text-center"> 实时监控 </th>
|
||||
|
@ -89,6 +90,7 @@
|
|||
{% for post in contacts.object_list %}
|
||||
<tr class="gradeX">
|
||||
<td id="username" class="text-center"> {{ post.user }} </td>
|
||||
<td id="ip" class="text-center"> {{ post.dept_name }} </td>
|
||||
<td id="ip" class="text-center"> {{ post.host }} </td>
|
||||
<td id="ip" class="text-center"> {{ post.remote_ip }} </td>
|
||||
<td class="text-center"><a class="monitor" filename="{{ post.log_path }}"> 监控 </a></td>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th class="text-center"> 用户名 </th>
|
||||
<th class="text-center"> 所属部门 </th>
|
||||
<th class="text-center"> 登录主机 </th>
|
||||
<th class="text-center"> 来源IP </th>
|
||||
<th class="text-center"> 命令统计 </th>
|
||||
|
@ -15,6 +16,7 @@
|
|||
{% for post in contacts.object_list %}
|
||||
<tr class="gradeX">
|
||||
<td class="text-center" id="username"> {{ post.user }} </td>
|
||||
<td class="text-center" id="ip"> {{ post.dept_name }} </td>
|
||||
<td class="text-center" id="ip"> {{ post.host }} </td>
|
||||
<td class="text-center" id="ip"> {{ post.remote_ip }} </td>
|
||||
<td class="text-center"><a href="/jlog/history/?id={{ post.id }}" class="log_command"> 命令统计 </td>
|
||||
|
|
|
@ -6,3 +6,4 @@
|
|||
<link href="/static/css/colorbox.css" rel="stylesheet">
|
||||
<link href="/static/css/vaildator/jquery.validator.css" rel="stylesheet">
|
||||
<link href="/static/css/magnific/magnific-popup.css" rel="stylesheet">
|
||||
<link href="/static/css/plugins/fullcalendar/fullcalendar.css" rel="stylesheet">
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<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"><a href="/jasset/host_list/">查看资产  </span><span class="label label-info pull-right">16/18</span></a></li>
|
||||
<li class="host_list"><a href="/jasset/host_list/">查看资产  </span><span class="label label-info pull-right">{{ host_active_num }}/{{ host_total_num}}</span></a></li>
|
||||
<li class="jgroup_add"><a href="/jasset/jgroup_add/">添加主机组</a></li>
|
||||
<li class="jgroup_list group_detail"><a href="/jasset/jgroup_list/">查看主机组</a></li>
|
||||
<li class="idc_add"><a href="/jasset/idc_add/">添加IDC</a></li>
|
||||
|
@ -99,11 +99,11 @@
|
|||
<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 id="host_add"><a href="/jasset/host_add/">添加资产</a></li>
|
||||
<li id="host_list"><a href="/jasset/host_list/">查看资产  </span><span class="label label-info pull-right">16/18</span></a></li>
|
||||
<li id="jgroup_add"><a href="/jasset/jgroup_add/">添加主机组</a></li>
|
||||
<li id="jgroup_list"><a href="/jasset/jgroup_list/">查看主机组</a></li>
|
||||
<li id="idc_list"><a href="/jasset/idc_list/">查看IDC</a></li>
|
||||
<li class="host_add host_add_multi"><a href="/jasset/host_add/">添加资产</a></li>
|
||||
<li class="host_list"><a href="/jasset/host_list/">查看资产  </span><span class="label label-info pull-right">{{ host_active_num }}/{{ host_total_num}}</span></a></li>
|
||||
<li class="jgroup_add"><a href="/jasset/jgroup_add/">添加主机组</a></li>
|
||||
<li class="jgroup_list group_detail"><a href="/jasset/jgroup_list/">查看主机组</a></li>
|
||||
<li class="idc_list idc_detail"><a href="/jasset/idc_list/">查看IDC</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li id="jperm">
|
||||
|
@ -139,4 +139,49 @@
|
|||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
{% endifequal %}
|
||||
|
||||
{% ifequal session_role_id 0 %}
|
||||
<nav class="navbar-default navbar-static-side" role="navigation">
|
||||
<div class="sidebar-collapse">
|
||||
<ul class="nav" id="side-menu">
|
||||
{% include 'nav_li_profile.html' %}
|
||||
<li>
|
||||
<a href="/"><i class="fa fa-th-large"></i> <span class="nav-label">仪表盘</span><span class="label label-info pull-right"></span></a>
|
||||
</li>
|
||||
<li id="juser">
|
||||
<a href="#"><i class="fa fa-rebel"></i> <span class="nav-label">用户管理</span><span class="fa arrow"></span></a>
|
||||
<ul class="nav nav-second-level">
|
||||
<li id="user_list"><a href="/juser/user_list/">查看用户<span class="label {% ifequal user_active_num user_total_num %}label-primary {% else %}label-warning {% endifequal %}pull-right">{{ user_active_num }}/{{ user_total_num }}</span></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<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_list"><a href="/jasset/host_list/">查看资产  </span><span class="label label-info pull-right">16/18</span></a></li>
|
||||
<li class="jgroup_list group_detail"><a href="/jasset/jgroup_list/">查看主机组</a></li>
|
||||
<li class="idc_list idc_detail"><a href="/jasset/idc_list/">查看IDC</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li id="jlog">
|
||||
<a href="#"><i class="fa fa-files-o"></i> <span class="nav-label">日志审计</span><span class="fa arrow"></span></a>
|
||||
<ul class="nav nav-second-level">
|
||||
<li id="log_list"><a href="/jlog/log_list/online/">查看日志</a></li>
|
||||
<li id="log_detail"><a href="/jlog/log_detail/">日志分析</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#"><i class="fa fa-download"></i> <span class="nav-label">上传下载</span><span class="fa arrow"></span></a>
|
||||
<ul class="nav nav-second-level">
|
||||
<li><a href="/file/upload/">文件上传</a></li>
|
||||
<li><a href="/file/download/">文件下载</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="special_link">
|
||||
<a href="http://www.jumpserver.org" target="_blank"><i class="fa fa-database"></i> <span class="nav-label">访问官网</span></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
{% endifequal %}
|
Loading…
Reference in New Issue