7 Commits
v1.05 ... v1.14

Author SHA1 Message Date
RobbieHan
0f6bd53883 menu update 2018-11-12 22:05:32 +08:00
RobbieHan
8c3158b18e menu list 2018-11-10 19:36:12 +08:00
RobbieHan
1526767e87 menu create 2018-11-09 23:22:13 +08:00
RobbieHan
64a8fab611 user management 2018-11-06 12:42:31 +08:00
RobbieHan
45630bd451 structure2user 2018-10-23 19:10:55 +08:00
RobbieHan
b85d89642d structure update & delete 2018-10-21 16:46:38 +08:00
RobbieHan
832c55ab34 structure list 2018-10-20 14:32:30 +08:00
29 changed files with 2382 additions and 463 deletions

854
.idea/workspace.xml generated

File diff suppressed because it is too large Load Diff

Binary file not shown.

56
apps/custom.py Normal file
View File

@@ -0,0 +1,56 @@
# @Time : 2018/11/9 22:06
# @Author : RobbieHan
# @File : custom.py
import json
from django.views.generic import CreateView, UpdateView
from django.shortcuts import HttpResponse
from django.http import Http404
from system.mixin import LoginRequiredMixin
class SandboxGetObjectMixin:
def get_object(self, queryset=None):
if queryset is None:
queryset = self.get_queryset()
if 'id' in self.request.GET and self.request.GET['id']:
queryset = queryset.filter(id=int(self.request.GET['id']))
elif 'id' in self.request.POST and self.request.POST['id']:
queryset = queryset.filter(id=int(self.request.POST['id']))
else:
raise AttributeError("Generic detail view %s must be called with id. "
% self.__class__.__name__)
try:
obj = queryset.get()
except queryset.model.DoesNotExist:
raise Http404("No %(verbose_name)s found matching the query" %
{'verbose_name': queryset.model._meta.verbose_name})
return obj
class SandboxEditViewMixin:
def post(self, request, *args, **kwargs):
res = dict(result=False)
form = self.get_form()
if form.is_valid():
form.save()
res['result'] = True
return HttpResponse(json.dumps(res), content_type='application/json')
class SandboxCreateView(LoginRequiredMixin, SandboxEditViewMixin, CreateView):
""""
View for create an object, with a response rendered by a template.
Returns information with Json when the data is created successfully or fails.
"""
class SandboxUpdateView(LoginRequiredMixin, SandboxEditViewMixin, SandboxGetObjectMixin, UpdateView):
def post(self, request, *args, **kwargs):
self.object = self.get_object()
return super().post(request, *args, **kwargs)

Binary file not shown.

View File

@@ -2,8 +2,13 @@
# @Author : RobbieHan
# @File : forms.py
import re
from django import forms
from .models import Structure
from django.contrib.auth import get_user_model
from .models import Structure, Menu
User = get_user_model()
class LoginForm(forms.Form):
@@ -15,3 +20,108 @@ class StructureForm(forms.ModelForm):
class Meta:
model = Structure
fields = ['type', 'name', 'parent']
class UserCreateForm(forms.ModelForm):
password = forms.CharField(
required=True,
min_length=6,
max_length=20,
error_messages={
"required": "密码不能为空",
"min_length": "密码长度最少6位数",
}
)
confirm_password = forms.CharField(
required=True,
min_length=6,
max_length=20,
error_messages={
"required": "确认密码不能为空",
"min_length": "密码长度最少6位数",
}
)
class Meta:
model = User
fields = [
'name', 'gender', 'birthday', 'username', 'mobile', 'email',
'department', 'post', 'superior', 'is_active', 'roles', 'password'
]
error_messages = {
"name": {"required": "姓名不能为空"},
"username": {"required": "用户名不能为空"},
"email": {"required": "邮箱不能为空"},
"mobile": {
"required": "手机号码不能为空",
"max_length": "输入有效的手机号码",
"min_length": "输入有效的手机号码"
}
}
def clean(self):
cleaned_data = super(UserCreateForm, self).clean()
username = cleaned_data.get("username")
mobile = cleaned_data.get("mobile", "")
email = cleaned_data.get("email")
password = cleaned_data.get("password")
confirm_password = cleaned_data.get("confirm_password")
if User.objects.filter(username=username).count():
raise forms.ValidationError('用户名:{}已存在'.format(username))
if password != confirm_password:
raise forms.ValidationError("两次密码输入不一致")
if User.objects.filter(mobile=mobile).count():
raise forms.ValidationError('手机号码:{}已存在'.format(mobile))
REGEX_MOBILE = "^1[3578]\d{9}$|^147\d{8}$|^176\d{8}$"
if not re.match(REGEX_MOBILE, mobile):
raise forms.ValidationError("手机号码非法")
if User.objects.filter(email=email).count():
raise forms.ValidationError('邮箱:{}已存在'.format(email))
class UserUpdateForm(forms.ModelForm):
class Meta:
model = User
fields = [
'name', 'gender', 'birthday', 'username', 'mobile', 'email',
'department', 'post', 'superior', 'is_active', 'roles'
]
class PasswordChangeForm(forms.Form):
password = forms.CharField(
required=True,
min_length=6,
max_length=20,
error_messages={
"required": u"密码不能为空"
})
confirm_password = forms.CharField(
required=True,
min_length=6,
max_length=20,
error_messages={
"required": u"确认密码不能为空"
})
def clean(self):
cleaned_data = super(PasswordChangeForm, self).clean()
password = cleaned_data.get("password")
confirm_password = cleaned_data.get("confirm_password")
if password != confirm_password:
raise forms.ValidationError("两次密码输入不一致")
class MenuForm(forms.ModelForm):
class Meta:
model = Menu
fields = '__all__'

View File

@@ -1,3 +1,4 @@
from django.test import TestCase
# Create your tests here.

View File

@@ -1,7 +1,7 @@
from django.urls import path
from .views import SystemView
from . import views_structure
from . import views_structure, views_user, views_menu
app_name = 'system'
@@ -9,5 +9,22 @@ urlpatterns = [
path('', SystemView.as_view(), name='login'),
path('basic/structure/', views_structure.StructureView.as_view(), name='basic-structure'),
path('basic/structure/create/', views_structure.StructureCreateView.as_view(), name='basic-structure-create'),
]
path('basic/structure/list/', views_structure.StructureListView.as_view(), name='basic-structure-list'),
path('basic/structure/delete/', views_structure.StructureDeleteView.as_view(), name='basic-structure-delete'),
path('basic/structure/add_user/', views_structure.Structure2UserView.as_view(), name='basic-structure-add_user'),
path('basic/user/', views_user.UserView.as_view(), name='basic-user'),
path('basic/user/list/', views_user.UserListView.as_view(), name='basic-user-list'),
path('basic/user/create/', views_user.UserCreateView.as_view(), name='basic-user-create'),
path('basic/user/detail/', views_user.UserDetailView.as_view(), name='basic-user-detail'),
path('basic/user/update/', views_user.UserUpdateView.as_view(), name='basic-user-update'),
path('basic/user/password_change/', views_user.PasswordChangeView.as_view(), name='basic-user-password_change'),
path('basic/user/delete/', views_user.UserDeleteView.as_view(), name='basic-user-delete'),
path('basic/user/enable/', views_user.UserEnableView.as_view(), name='basic-user-enable'),
path('basic/user/disable/', views_user.UserDisableView.as_view(), name='basic-user-disable'),
path('rbac/menu/', views_menu.MenuListView.as_view(), name='rbac-menu'),
path('rbac/menu/create/', views_menu.MenuCreateView.as_view(), name='rbac-menu-create'),
path('rbac/menu/update/', views_menu.MenuUpdateView.as_view(), name='rbac-menu-update'),
]

23
apps/system/views_menu.py Normal file
View File

@@ -0,0 +1,23 @@
from django.views.generic import ListView
from .mixin import LoginRequiredMixin
from apps.custom import SandboxCreateView, SandboxUpdateView
from .models import Menu
class MenuCreateView(SandboxCreateView):
model = Menu
fields = '__all__'
extra_context = dict(menu_all=Menu.objects.all())
class MenuListView(LoginRequiredMixin, ListView):
model = Menu
context_object_name = 'menu_all'
class MenuUpdateView(SandboxUpdateView):
model = Menu
fields = '__all__'
template_name_suffix = '_update'
extra_context = dict(menu_all=Menu.objects.all())

View File

@@ -8,11 +8,15 @@ from django.views.generic.base import TemplateView
from django.views.generic.base import View
from django.shortcuts import render
from django.shortcuts import HttpResponse
from django.shortcuts import get_object_or_404
from django.contrib.auth import get_user_model
from .mixin import LoginRequiredMixin
from .models import Structure
from .forms import StructureForm
User = get_user_model()
class StructureView(LoginRequiredMixin, TemplateView):
@@ -23,13 +27,63 @@ class StructureCreateView(LoginRequiredMixin, View):
def get(self, request):
ret = dict(structure_all=Structure.objects.all())
if 'id' in request.GET and request.GET['id']:
structure = get_object_or_404(Structure, pk=request.GET['id'])
ret['structure'] = structure
return render(request, 'system/structure/structure_create.html', ret)
def post(self, request):
res = dict(result=False)
structure = Structure()
if 'id' in request.POST and request.POST['id']:
structure = get_object_or_404(Structure, pk=request.POST['id'])
else:
structure = Structure()
structure_form = StructureForm(request.POST, instance=structure)
if structure_form.is_valid():
structure_form.save()
res['result'] = True
return HttpResponse(json.dumps(res), content_type='application/json')
class StructureListView(LoginRequiredMixin, View):
def get(self, request):
fields = ['id', 'name', 'type', 'parent__name']
ret = dict(data=list(Structure.objects.values(*fields)))
return HttpResponse(json.dumps(ret), content_type='application/json')
class StructureDeleteView(LoginRequiredMixin, View):
def post(self, request):
ret = dict(result=False)
if 'id' in request.POST and request.POST['id']:
id_list = map(int, request.POST['id'].split(','))
Structure.objects.filter(id__in=id_list).delete()
ret['result'] = True
return HttpResponse(json.dumps(ret), content_type='application/json')
class Structure2UserView(LoginRequiredMixin, View):
def get(self, request):
if 'id' in request.GET and request.GET['id']:
structure = get_object_or_404(Structure, pk=int(request.GET['id']))
added_users = structure.userprofile_set.all()
all_users = User.objects.all()
un_add_users = set(all_users).difference(added_users)
ret = dict(structure=structure, added_users=added_users, un_add_users=list(un_add_users))
return render(request, 'system/structure/structure_user.html', ret)
def post(self, request):
res = dict(result=False)
id_list = None
structure = get_object_or_404(Structure, pk=int(request.POST['id']))
if 'to' in request.POST and request.POST.getlist('to', []):
id_list = map(int, request.POST.getlist('to', []))
structure.userprofile_set.clear()
if id_list:
for user in User.objects.filter(id__in=id_list):
structure.userprofile_set.add(user)
res['result'] = True
return HttpResponse(json.dumps(res), content_type='application/json')

View File

@@ -2,14 +2,23 @@
# @Author : RobbieHan
# @File : views_user.py
from django.shortcuts import render
from django.views.generic.base import View
from django.http import HttpResponseRedirect
from django.contrib.auth import authenticate, login, logout
from django.urls import reverse
import re
import json
from .forms import LoginForm
from django.shortcuts import render, HttpResponse
from django.views.generic.base import View, TemplateView
from django.http import HttpResponseRedirect
from django.contrib.auth import authenticate, login, logout, get_user_model
from django.urls import reverse
from django.contrib.auth.hashers import make_password
from django.shortcuts import get_object_or_404
from django.db.models import Q
from .forms import LoginForm, UserCreateForm, UserUpdateForm, PasswordChangeForm
from .mixin import LoginRequiredMixin
from .models import Structure, Role
User = get_user_model()
class IndexView(LoginRequiredMixin, View):
@@ -51,4 +60,159 @@ class LogoutView(View):
def get(self, request):
logout(request)
return HttpResponseRedirect(reverse('login'))
return HttpResponseRedirect(reverse('login'))
class UserView(LoginRequiredMixin, TemplateView):
template_name = 'system/users/user.html'
class UserListView(LoginRequiredMixin, View):
def get(self, request):
fields = ['id', 'name', 'gender', 'mobile', 'email', 'department__name', 'post', 'superior__name', 'is_active']
filters = dict()
if 'select' in request.GET and request.GET['select']:
filters['is_active'] = request.GET['select']
ret = dict(data=list(User.objects.filter(**filters).values(*fields)))
return HttpResponse(json.dumps(ret), content_type='application/json')
class UserCreateView(LoginRequiredMixin, View):
"""
添加用户
"""
def get(self, request):
users = User.objects.exclude(username='admin')
structures = Structure.objects.values()
roles = Role.objects.values()
ret = {
'users': users,
'structures': structures,
'roles': roles,
}
return render(request, 'system/users/user_create.html', ret)
def post(self, request):
user_create_form = UserCreateForm(request.POST)
if user_create_form.is_valid():
new_user = user_create_form.save(commit=False)
new_user.password = make_password(user_create_form.cleaned_data['password'])
new_user.save()
user_create_form.save_m2m()
ret = {'status': 'success'}
else:
pattern = '<li>.*?<ul class=.*?><li>(.*?)</li>'
errors = str(user_create_form.errors)
user_create_form_errors = re.findall(pattern, errors)
ret = {
'status': 'fail',
'user_create_form_errors': user_create_form_errors[0]
}
return HttpResponse(json.dumps(ret), content_type='application/json')
class UserDetailView(LoginRequiredMixin, View):
def get(self, request):
user = get_object_or_404(User, pk=int(request.GET['id']))
users = User.objects.exclude(Q(id=int(request.GET['id'])) | Q(username='admin'))
structures = Structure.objects.values()
roles = Role.objects.values()
user_roles = user.roles.values()
ret = {
'user': user,
'structures': structures,
'users': users,
'roles': roles,
'user_roles': user_roles
}
return render(request, 'system/users/user_detail.html', ret)
class UserUpdateView(LoginRequiredMixin, View):
def post(self, request):
if 'id' in request.POST and request.POST['id']:
user = get_object_or_404(User, pk=int(request.POST['id']))
else:
user = get_object_or_404(User, pk=int(request.user.id))
user_update_form = UserUpdateForm(request.POST, instance=user)
if user_update_form.is_valid():
user_update_form.save()
ret = {"status": "success"}
else:
ret = {"status": "fail", "message": user_update_form.errors}
return HttpResponse(json.dumps(ret), content_type="application/json")
class PasswordChangeView(LoginRequiredMixin, View):
def get(self, request):
ret = dict()
if 'id' in request.GET and request.GET['id']:
user = get_object_or_404(User, pk=int(request.GET.get('id')))
ret['user'] = user
return render(request, 'system/users/passwd_change.html', ret)
def post(self, request):
if 'id' in request.POST and request.POST['id']:
user = get_object_or_404(User, pk=int(request.POST['id']))
form = PasswordChangeForm(request.POST)
if form.is_valid():
new_password = request.POST['password']
user.set_password(new_password)
user.save()
ret = {'status': 'success'}
else:
pattern = '<li>.*?<ul class=.*?><li>(.*?)</li>'
errors = str(form.errors)
password_change_form_errors = re.findall(pattern, errors)
ret = {
'status': 'fail',
'password_change_form_errors': password_change_form_errors[0]
}
return HttpResponse(json.dumps(ret), content_type='application/json')
class UserDeleteView(LoginRequiredMixin, View):
"""
删除数据:支持删除单条记录和批量删除
"""
def post(self, request):
ret = dict(result=False)
if 'id' in request.POST and request.POST['id']:
id_list = map(int, request.POST['id'].split(','))
User.objects.filter(id__in=id_list).delete()
ret['result'] = True
return HttpResponse(json.dumps(ret), content_type='application/json')
class UserEnableView(LoginRequiredMixin, View):
"""
启用用户:单个或批量启用
"""
def post(self, request):
if 'id' in request.POST and request.POST['id']:
id_nums = request.POST.get('id')
queryset = User.objects.extra(where=["id IN(" + id_nums + ")"])
queryset.filter(is_active=False).update(is_active=True)
ret = {'result': 'True'}
return HttpResponse(json.dumps(ret), content_type='application/json')
class UserDisableView(LoginRequiredMixin, View):
"""
启用用户:单个或批量启用
"""
def post(self, request):
if 'id' in request.POST and request.POST['id']:
id_nums = request.POST.get('id')
queryset = User.objects.extra(where=["id IN(" + id_nums + ")"])
queryset.filter(is_active=True).update(is_active=False)
ret = {'result': 'True'}
return HttpResponse(json.dumps(ret), content_type='application/json')

Binary file not shown.

View File

@@ -8,7 +8,7 @@ scratch. This page gets rid of all links and provides the needed markup only.
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>SandBoxOA</title>
<title>SandBoxMP</title>
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'plugins/font-awesome/css/font-awesome.min.css' %}">
@@ -52,7 +52,7 @@ scratch. This page gets rid of all links and provides the needed markup only.
<div class="menu-info">
<h4 class="control-sidebar-subheading">SandBox</h4>
<p>沙盒协同办公平台</p>
<p>沙盒运维管理平台</p>
</div>
</a>
</li>

View File

@@ -0,0 +1,101 @@
{% extends 'base-layer.html' %}
{% load staticfiles %}
{% block css %}
<link rel="stylesheet" href="{% static 'plugins/select2/select2.min.css' %}">
<!-- iCheck for checkboxes and radio inputs -->
{% endblock %}
{% block main %}
<div class="box box-danger">
<form class="form-horizontal" id="addForm" method="post">
{% csrf_token %}
<div class="box-body">
<fieldset>
<legend>
<h4>添加菜单</h4>
</legend>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">名称</label>
<div class="col-sm-3">
<input class="form-control" name="name" type="text"/>
</div>
<label class="col-sm-2 control-label">代码</label>
<div class="col-sm-3">
<input class="form-control" name="code" type="text"/>
</div>
</div>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">图标</label>
<div class="col-sm-3">
<input class="form-control" name="icon" type="text" />
</div>
<label class="col-sm-2 control-label">父菜单</label>
<div class="col-sm-3">
<select class="form-control select2" name="parent">
<option value="{{ menu.parent.id }}">{{ menu.parent.name }}</option>
{% for parent_menu in menu_all %}
<option value={{ parent_menu.id }}> {{ parent_menu.name }} </option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">URL</label>
<div class="col-sm-8">
<input class="form-control" name="url" type="text" />
</div>
</div>
</fieldset>
</div>
<div class="box-footer ">
<div class="row span7 text-center ">
<button type="button" id="btnCancel" class="btn btn-default margin-right ">重置</button>
<button type="button" id="btnSave" class="btn btn-info margin-right ">保存</button>
</div>
</div>
</form>
</div>
{% endblock %}
{% block javascripts %}
<script src="{% static 'plugins/select2/select2.full.min.js' %}"></script>
<script type="text/javascript">
$("#btnSave").click(function () {
var data = $("#addForm").serialize();
$.ajax({
type: $("#addForm").attr('method'),
url: "{% url 'system:rbac-menu-create' %}",
data: data,
cache: false,
success: function (msg) {
if (msg.result) {
layer.alert('数据保存成功!', {icon: 1}, function (index) {
parent.layer.closeAll(); //关闭所有弹窗
});
} else {
layer.alert('数据保存失败', {icon: 5});
//$('errorMessage').html(msg.message)
}
return;
}
});
});
/*点取消刷新新页面*/
$("#btnCancel").click(function () {
window.location.reload();
});
$(function () {
//Initialize Select2 Elements
$(".select2").select2();
});
</script>
{% endblock %}

View File

@@ -0,0 +1,164 @@
{% extends "base-left.html" %}
{% load staticfiles %}
{% block css %}
<link rel="stylesheet" href="{% static 'plugins/datatables/jquery.dataTables.min.css' %}">
<link rel="stylesheet" href="{% static 'js/plugins/layer/skin/layer.css' %}">
<!-- iCheck for checkboxes and radio inputs -->
{% endblock %}
{% block content %}
<!-- Main content -->
<section class="content">
<div id="devlist">
<div class="box box-primary" id="liebiao">
<div class="box-header">
<div class="btn-group pull-left">
<button type="button" id="btnRefresh" class="btn btn-default">
<i class="glyphicon glyphicon-repeat"></i>刷新
</button>
</div>
<div class="btn-group pull-left">&nbsp</div>
<div class="btn-group pull-left">
<button type="button" id="btnCreate" class="btn btn-default">
<i class="glyphicon glyphicon-plus"></i>新增
</button>
</div>
</div>
<div class="box-body">
<table id="dtbList" class="display" cellspacing="0" width="100%">
<thead>
<tr valign="middle">
<th><input type="checkbox" id="checkAll"></th>
<th>ID</th>
<th>名称</th>
<th>代码</th>
<th>URL</th>
<th>图标</th>
<th>父菜单</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<br> <br>
</div>
</div>
</div>
</section>
<!-- /.content -->
{% endblock %}
{% block javascripts %}
<script src="{% static 'plugins/datatables/jquery.dataTables.min.js' %}"></script>
<script src="{% static 'plugins/datatables/dataTables.const.js' %}"></script>
<script src="{% static 'js/plugins/layer/layer.js' %}"></script>
<!-- iCheck 1.0.1 -->
<script type="text/javascript">
$(function () {
$('#SYSTEM-RBAC').addClass('active');
$('#SYSTEM-RBAC-MENU').addClass('active');
});
</script>
<script type="text/javascript">
var oDataTable = null;
var data = [
{% for menu in menu_all %}
{
"id": "{{ menu.id }}",
"name": "{{ menu.name }}",
"code": "{{ menu.code }}",
"url": "{{ menu.url | default_if_none:'' }}",
"icon": "{{ menu.icon | default_if_none:'' }}",
"parent": "{{ menu.parent.name }}"
},
{% endfor %}
];
$(function () {
oDataTable = initTable();
function initTable() {
var oTable = $('#dtbList').DataTable($.extend(true, {},
DATATABLES_CONSTANT.DATA_TABLES.DEFAULT_OPTION,
{
data: data,
columns: [
DATATABLES_CONSTANT.DATA_TABLES.COLUMN.CHECKBOX,
{
data: "id",
width: "5%",
},
{
data: "name",
},
{
data: "code",
},
{
data: "url",
},
{
data: "icon",
},
{
data: "parent",
},
{
data: "id",
bSortable: "false",
render: function (data, type, row, meta) {
var ret = "";
var ret = "<button title='详情-编辑' onclick='doUpdate("
+ data + ")'><i class='glyphicon glyphicon-pencil'></i></button>";
return ret;
}
}
],
}));
return oTable;
}
});
$("#btnRefresh").click(function () {
window.location.reload();
});
$("#btnCreate").click(function () {
layer.open({
type: 2,
title: '新增',
shadeClose: false,
maxmin: true,
area: ['800px', '400px'],
content: "{% url 'system:rbac-menu-create' %}",
end: function () {
//关闭时做的事情
window.location.reload();
}
});
});
function doUpdate(id) {
layer.open({
type: 2,
title: '编辑',
shadeClose: false,
maxmin: true,
area: ['800px', '400px'],
content: ["{% url 'system:rbac-menu-update' %}" + '?id=' + id, 'no'],
end: function () {
//关闭时做的事情
window.location.reload();
}
});
}
</script>
{% endblock %}

View File

@@ -0,0 +1,100 @@
{% extends 'base-layer.html' %}
{% load staticfiles %}
{% block css %}
<link rel="stylesheet" href="{% static 'plugins/select2/select2.min.css' %}">
{% endblock %}
{% block main %}
<div class="box box-danger">
<form class="form-horizontal" id="addForm" method="post">
{% csrf_token %}
<input type="hidden" name='id' value="{{ menu.id }}"/>
<div class="box-body">
<fieldset>
<legend>
<h4>修改菜单</h4>
</legend>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">名称</label>
<div class="col-sm-3">
<input class="form-control" name="name" type="text" value="{{ menu.name }}"/>
</div>
<label class="col-sm-2 control-label">代码</label>
<div class="col-sm-3">
<input class="form-control" name="code" type="text" value="{{ menu.code }}"/>
</div>
</div>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">图标</label>
<div class="col-sm-3">
<input class="form-control" name="icon" type="text" value="{{ menu.icon | default:'' }}"/>
</div>
<label class="col-sm-2 control-label">父菜单</label>
<div class="col-sm-3">
<select class="form-control select2" name="parent">
<option value="{{ menu.parent.id }}">{{ menu.parent.name }}</option>
{% for parent_menu in menu_all %}
<option value={{ parent_menu.id }}> {{ parent_menu.name }} </option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">URL</label>
<div class="col-sm-8">
<input class="form-control" name="url" type="text" value="{{ menu.url | default:'' }}"/>
</div>
</div>
</fieldset>
</div>
<div class="box-footer ">
<div class="row span7 text-center ">
<button type="button" id="btnCancel" class="btn btn-default margin-right ">重置</button>
<button type="button" id="btnSave" class="btn btn-info margin-right ">保存</button>
</div>
</div>
</form>
</div>
{% endblock %}
{% block javascripts %}
<script src="{% static 'plugins/select2/select2.full.min.js' %}"></script>
<script type="text/javascript">
$("#btnSave").click(function () {
var data = $("#addForm").serialize();
$.ajax({
type: $("#addForm").attr('method'),
url: "{% url 'system:rbac-menu-update' %}",
data: data,
cache: false,
success: function (msg) {
if (msg.result) {
layer.alert('数据保存成功!', {icon: 1}, function (index) {
parent.layer.closeAll(); //关闭所有弹窗
});
} else {
layer.alert('数据保存失败', {icon: 5});
//$('errorMessage').html(msg.message)
}
return;
}
});
});
/*点取消刷新新页面*/
$("#btnCancel").click(function () {
window.location.reload();
});
$(function () {
//Initialize Select2 Elements
$(".select2").select2();
});
</script>
{% endblock %}

View File

@@ -2,6 +2,7 @@
{% load staticfiles %}
{% block css %}
<link rel="stylesheet" href="{% static 'plugins/datatables/jquery.dataTables.min.css' %}">
<link rel="stylesheet" href="{% static 'js/plugins/layer/skin/layer.css' %}">
{% endblock %}
@@ -52,9 +53,73 @@
{% block javascripts %}
<script src="{% static 'plugins/datatables/jquery.dataTables.min.js' %}"></script>
<script src="{% static 'plugins/datatables/dataTables.const.js' %}"></script>
<script src="{% static 'js/plugins/layer/layer.js' %}"></script>
<script type="text/javascript">
var oDataTable = null;
$(function () {
oDataTable = initTable();
function initTable() {
var oTable = $('#dtbList').DataTable($.extend(true, {},
DATATABLES_CONSTANT.DATA_TABLES.DEFAULT_OPTION,
{
ajax: {
"url": "{% url 'system:basic-structure-list' %}",
},
columns: [
DATATABLES_CONSTANT.DATA_TABLES.COLUMN.CHECKBOX,
{
data: "id",
width: "5%",
},
{
data: "name",//parent
width: "20%",
},
{
data: "type",
render: function (data, type, row, meta) {
if (data == 'unit') {
return "单位";
} else if (data == 'department') {
return "部门";
}
}
},
{
data: "parent__name",
},
{
data: "id",
width: "12%",
bSortable: "false",
render: function (data, type, row, meta) {
var ret = "";
var ret = "<button title='详情-编辑' onclick='doUpdate("
+ data + ")'><i class='glyphicon glyphicon-pencil'></i></button>";
ret = ret + "<button title='关联用户' onclick='doAddUser("
+ data + ")'><i class='glyphicon glyphicon-user'></i></button>";
ret = ret + "<button title='删除' onclick='doDelete("
+ data + ")'><i class='glyphicon glyphicon-trash'></i></button>";
return ret;
}
}],
"order": [
[1, 'id']
],
}));
return oTable;
}
});
</script>
<script type="text/javascript">
$("#btnCreate").click(function () {
layer.open({
@@ -65,10 +130,123 @@
area: ['800px', '400px'],
content: "{% url 'system:basic-structure-create' %}",
end: function () {
//新增内容弹窗关闭后刷新oDatable
oDataTable.ajax.reload();
}
});
});
//checkbox全选
$("#checkAll").on("click", function () {
if ($(this).prop("checked") === true) {
$("input[name='checkList']").prop("checked", $(this).prop("checked"));
$('#example tbody tr').addClass('selected');
} else {
$("input[name='checkList']").prop("checked", false);
$('#example tbody tr').removeClass('selected');
}
});
//批量删除
$("#btnDelete").click(function () {
if ($("input[name='checkList']:checked").length == 0) {
layer.msg("请选择要删除的记录");
return;
}
var arrId = new Array();
$("input[name='checkList']:checked").each(function () {
//alert($(this).val());
arrId.push($(this).val());
});
sId = arrId.join(',');
layer.alert('确定删除吗?', {
title: '提示'
, icon: 3 //0:感叹号 1对号 2差号 3问号 4小锁 5哭脸 6笑脸
, time: 0 //不自动关闭
, btn: ['YES', 'NO']
, yes: function (index) {
layer.close(index);
$.ajax({
type: "POST",
url: "{% url 'system:basic-structure-delete' %}",
data: {"id": sId, csrfmiddlewaretoken: '{{ csrf_token }}'},
cache: false,
success: function (msg) {
if (msg.result) {
layer.alert("操作成功", {icon: 1});
oDataTable.ajax.reload();
} else {
//alert(msg.message);
layer.alert("操作失败", {icon: 2});
}
return;
}
});
}
});
});
//删除单个数据
function doDelete(id) {
layer.alert('确定删除吗?', {
title: '提示'
, icon: 3 //0:感叹号 1对号 2差号 3问号 4小锁 5哭脸 6笑脸
, time: 0 //不自动关闭
, btn: ['YES', 'NO']
, yes: function (index) {
layer.close(index);
$.ajax({
type: "POST",
url: "{% url 'system:basic-structure-delete' %}",
data: {"id": id, csrfmiddlewaretoken: '{{ csrf_token }}'}, //防止post数据时报 csrf_token 403
cache: false,
success: function (msg) {
if (msg.result) {
layer.alert('删除成功', {icon: 1});
oDataTable.ajax.reload();
} else {
//alert(msg.message);
layer.alert('删除失败', {icon: 2});
}
return;
}
});
}
});
}
function doUpdate(id) {
layer.open({
type: 2,
title: '编辑',
shadeClose: false,
maxmin: true,
area: ['800px', '400px'],
content: ["{% url 'system:basic-structure-create' %}" + '?id=' + id, 'no'],
end: function () {
oDataTable.ajax.reload();
}
});
}
function doAddUser(id) {
layer.open({
type: 2,
title: '编辑',
shadeClose: false,
maxmin: true,
area: ['800px', '600px'],
content: ["{% url 'system:basic-structure-add_user' %}" + '?id=' + id, 'no'],
end: function () {
window.location.reload();
}
});
}
</script>
{% endblock %}

View File

@@ -14,14 +14,16 @@
<legend>
<h4>组织架构信息</h4>
</legend>
<input type="hidden" name="id" value="{{ structure.id }}" />
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">名称</label>
<div class="col-sm-3">
<input class="form-control" name="name" type="text" />
<input class="form-control" name="name" type="text" value="{{ structure.name }}" />
</div>
<label class="col-sm-2 control-label">类别</label>
<div class="col-sm-3">
<select class="form-control" name="type">
<option value={{ structure.type }}> {{ structure.get_type_display|default:"--类别--" }} </option>
<option value="unit">单位</option>
<option value="department">部门</option>
</select>
@@ -33,6 +35,7 @@
<label class="col-sm-2 control-label">所属</label>
<div class="col-sm-3">
<select class="form-control" name="parent">
<option value={{ structure.parent_id|default_if_none:"" }}> {{ structure.parent.name|default:"" }}
<option></option>
{% for stru in structure_all %}
<option value={{ stru.id }}> {{ stru.name }} </option>

View File

@@ -0,0 +1,103 @@
{% extends 'base-layer.html' %}
{% load staticfiles %}
{% block css %}
<link rel="stylesheet" href="{% static 'plugins/select2/select2.min.css' %}">
{% endblock %}
{% block main %}
<div class="box box-danger">
<form class="form-horizontal" id="selectUsersForm" action="" method="post">
{% csrf_token %}
<input type="hidden" name='id' value="{{ structure.id }}"/>
<div class="box-body">
<div class="row">
<div class="col-xs-5">
<label class="control-label">可选用户:</label>
<select name="from" id="multiselect" class="form-control" size="18" multiple="multiple">
{% for item in un_add_users %}
<option value="{{ item.id }}">{{ item.name }}({{ item.username }})</option>
{% endfor %}
</select>
</div>
<div class="col-xs-2">
<br><br><br><br><br><br>
<button type="button" id="multiselect_rightAll" class="btn btn-block"><i
class="glyphicon glyphicon-forward"></i></button>
<button type="button" id="multiselect_rightSelected" class="btn btn-block"><i
class="glyphicon glyphicon-chevron-right"></i></button>
<button type="button" id="multiselect_leftSelected" class="btn btn-block"><i
class="glyphicon glyphicon-chevron-left"></i></button>
<button type="button" id="multiselect_leftAll" class="btn btn-block"><i
class="glyphicon glyphicon-backward"></i></button>
</div>
<div class="col-xs-5">
<label class="control-label">{{structure.name}}-已绑定用户:</label>
<select name="to" id="multiselect_to" class="form-control" size="18" multiple="multiple">
{% for item in added_users %}
<option value="{{ item.id }}">{{ item.name }}({{ item.username }})</option>
{% endfor %}
</select>
</div>
</div>
<div class="row">
<div class="col-xs-12 margin-top-5">
<p class="text-maroon">*注意:一个用户只能隶属一个部门,如果选择的用户已存在部门,用户将会从原有部门移出</p>
</div>
</div>
</div>
<div class="box-footer ">
<div class="row span7 text-center ">
<button type="button" id="btnCancel" class="btn btn-default margin-right ">重置</button>
<button type="button" id="btnSave" class="btn btn-info margin-right ">保存</button>
</div>
</div>
</form>
</div>
{% endblock %}
{% block javascripts %}
<script src="{% static 'plugins/select/multiselect.min.js' %}"></script>
<script type="text/javascript">
$(document).ready(function () {
//初始化多选列表
$('#multiselect').multiselect({
search: {
left: '<input type="text" class="form-control" placeholder="Search..." />',
right: '<input type="text" class="form-control" placeholder="Search..." />',
},
fireSearch: function (value) {
return value.length > 3;
}
});
});
$("#btnSave").click(function () {
$('#multiselect_to option').prop('selected', true);
var data = $("#selectUsersForm").serialize();
console.log(data);
$.ajax({
type: $("#selectUsersForm").attr('method'),
url: "{% url 'system:basic-structure-add_user' %}",
data: data,
cache: false,
success: function (msg) {
if (msg.result) {
layer.alert('操作成功', {icon: 1});
} else {
//alert(msg.message);
layer.alert('操作失败', {icon: 2});
}
return;
}
});
});
/*点取消刷新新页面*/
$("#btnCancel").click(function () {
window.location.reload();
});
</script>
{% endblock %}

View File

@@ -0,0 +1,95 @@
{% extends 'base-layer.html' %}
{% load staticfiles %}
{% block css %}
{% endblock %}
{% block main %}
<div class="box box-danger">
<form class="form-horizontal" id="addForm" method="post">
{% csrf_token %}
<input type="hidden" name='id' value="{{ user.id }}"/>
<input type="hidden" name='user' value="save"/>
<div class="box-body">
<fieldset>
<legend>
<h4>基本信息</h4>
</legend>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">姓名</label>
<div class="col-sm-3">
<input class="form-control" name="name" type="text" readonly="readonly"
value="{{ user.name }}"/>
</div>
<label class="col-sm-2 control-label">用户名</label>
<div class="col-sm-3">
<input type="text" class="form-control" name="username" readonly="readonly"
value="{{ user.username }}"/>
</div>
</div>
<h4>密码信息</h4>
</legend>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">密码</label>
<div class="col-sm-3">
<input class="form-control" name="password" type="password" value=""/>
</div>
<label class="col-sm-2 control-label">确认密码</label>
<div class="col-sm-3">
<input class="form-control" name="confirm_password" type="password" value=""/>
</div>
</div>
</fieldset>
</div>
<div class="box-footer ">
<div class="row span7 text-center ">
<button type="button" id="btnCancel" class="btn btn-default margin-right ">重置</button>
<button type="button" id="btnSave" class="btn btn-info margin-right ">确定</button>
</div>
</div>
</form>
</div>
{% endblock %}
{% block javascripts %}
<script src="{% static 'plugins/combo-select/jquery.combo.select.js' %}"></script>
<script src="{% static 'bootstrap/js/bootstrap-datetimepicker.js' %}"></script>
<script type="text/javascript">
$("#btnSave").click(function () {
var data = $("#addForm").serialize();
$.ajax({
type: $("#addForm").attr('method'),
url: "{% url 'system:basic-user-password_change' %}",
data: data,
cache: false,
success: function (msg) {
if (msg.status == 'success') {
layer.alert('密码修改成功!', {icon: 1}, function (index) {
parent.layer.closeAll();
});
} else if (msg.status == 'fail') {
layer.alert(msg.password_change_form_errors, {icon: 5});
//$('errorMessage').html(msg.message)
}
return;
}
});
});
/*点取消刷新页面*/
$("#btnCancel").click(function () {
window.location.reload();
})
</script>
{% endblock %}

View File

@@ -0,0 +1,396 @@
{% extends "base-left.html" %}
{% load staticfiles %}
{% block css %}
<link rel="stylesheet" href="{% static 'plugins/datatables/jquery.dataTables.min.css' %}">
<link rel="stylesheet" href="{% static 'js/plugins/layer/skin/layer.css' %}">
{% endblock %}
{% block content %}
<!-- Main content -->
<section class="content">
<div id="devlist">
<div class="box box-primary" id="liebiao">
<div class="box-header">
<div class="btn-group pull-left">
<button type="button" id="btnRefresh" class="btn btn-default">
<i class="glyphicon glyphicon-repeat"></i>刷新
</button>
</div>
<div class="btn-group pull-left">&nbsp</div>
<div class="btn-group pull-left">
<button type="button" id="btnCreate" class="btn btn-default">
<i class="glyphicon glyphicon-plus"></i>新增
</button>
</div>
<div class="btn-group pull-left">&nbsp</div>
<div class="btn-group pull-left">
<button type="button" id="btnDelete" class="btn btn-default">
<i class="glyphicon glyphicon-trash"></i>删除
</button>
</div>
<div class="btn-group pull-left">&nbsp</div>
<div class="btn-group pull-left">
<button type="button" id="btnEnable" class="btn btn-default">
<i class="glyphicon glyphicon-ok-circle"></i>启用
</button>
<button type="button" id="btnDisable" class="btn btn-default">
<i class="glyphicon glyphicon-ban-circle"></i>禁用
</button>
</div>
<div class="btn-group pull-right">
<form class="form-inline">
<div class="form-group">
<label>用户状态:</label>
<select id="select" name="select" class="form-control">
<option style='text-align:center' value=''>-----所有-----</option>
<option value="True">启用</option>
<option value="False">禁用</option>
</select>
</div>
</form>
</div>
</div>
<div class="box-body">
<table id="dtbList" class="display" cellspacing="0" width="100%">
<thead>
<tr valign="middle">
<th><input type="checkbox" id="checkAll"></th>
<th>ID</th>
<th>姓名</th>
<th>性别</th>
<th>手机</th>
<th>邮箱</th>
<th>部门</th>
<th>职位</th>
<th>上级</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<br> <br>
</div>
</div>
</div>
</section>
<!-- /.content -->
{% endblock %}
{% block javascripts %}
<script src="{% static 'plugins/datatables/jquery.dataTables.min.js' %}"></script>
<script src="{% static 'plugins/datatables/dataTables.const.js' %}"></script>
<script src="{% static 'js/plugins/layer/layer.js' %}"></script>
<script type="text/javascript">
var oDataTable = null;
$(function () {
oDataTable = initTable();
function initTable() {
var oTable = $('#dtbList').DataTable($.extend(true, {},
DATATABLES_CONSTANT.DATA_TABLES.DEFAULT_OPTION,
{
ajax: {
"url": "{% url 'system:basic-user-list' %}",
"data": function (d) {
d.select = $("#select").val();
}
},
columns: [
DATATABLES_CONSTANT.DATA_TABLES.COLUMN.CHECKBOX,
{
data: "id",
width: "5%",
},
{
data: "name",//parent
width: "10%",
},
{
data: "gender",
width: "10%",
render: function (data, type, row, meta) {
if (data == 'male') {
return "男";
} else {
return "女";
}
}
},
{
data: "mobile",
},
{
data: "email",
},
{
data: "department__name",
},
{
data: "post",
},
{
data: "superior__name",
},
{
data: "is_active",
render: function (data) {
if (data == true) {
return "启用";
} else {
return "禁用";
}
}
},
{
data: "id",
width: "12%",
bSortable: "false",
render: function (data, type, row, meta) {
var ret = "";
var ret = "<button title='详情-编辑' onclick='doUpdate("
+ data + ")'><i class='glyphicon glyphicon-pencil'></i></button>";
ret = ret + "<button name='btnChangepasswd' title='修改密码' onclick='doChangepasswd("
+ data + ")'><i class='glyphicon glyphicon-asterisk'></i></button>";
ret = ret + "<button name='btnConfig' title='删除' onclick='doDelete("
+ data + ")'><i class='glyphicon glyphicon-trash'></i></button>";
return ret;
}
}],
"order": [
[2, 'desc']
],
}));
return oTable;
}
});
</script>
<script type="text/javascript">
$("#btnCreate").click(function () {
var div = layer.open({
type: 2,
title: '新增',
shadeClose: false,
maxmin: true,
area: ['800px', '720px'],
content: '/system/basic/user/create',
end: function () {
//关闭时做的事情
oDataTable.ajax.reload();
}
});
layer.full(div)
});
// 跳转到用户详情页面
function doUpdate(id) {
var div = layer.open({
type: 2,
title: '编辑',
shadeClose: false,
maxmin: true,
area: ['800px', '650px'],
content: ["{% url 'system:basic-user-detail' %}" + '?id=' + id, 'no'],
end: function () {
oDataTable.ajax.reload();
}
});
layer.full(div)
}
function doChangepasswd(id) {
layer.open({
type: 2,
title: '编辑',
shadeClose: false,
maxmin: true,
area: ['850px', '350px'],
content: ["{% url 'system:basic-user-password_change' %}" + '?id=' + id, 'no'],
end: function () {
oDataTable.ajax.reload();
}
});
}
//checkbox全选
$("#checkAll").on("click", function () {
if ($(this).prop("checked") === true) {
$("input[name='checkList']").prop("checked", $(this).prop("checked"));
$('#example tbody tr').addClass('selected');
} else {
$("input[name='checkList']").prop("checked", false);
$('#example tbody tr').removeClass('selected');
}
});
//批量删除
$("#btnDelete").click(function () {
if ($("input[name='checkList']:checked").length == 0) {
layer.msg("请选择要删除的记录");
return;
}
var arrId = new Array();
$("input[name='checkList']:checked").each(function () {
//alert($(this).val());
arrId.push($(this).val());
});
sId = arrId.join(',');
layer.alert('确定删除吗?', {
title: '提示'
, icon: 3 //0:感叹号 1对号 2差号 3问号 4小锁 5哭脸 6笑脸
, time: 0 //不自动关闭
, btn: ['YES', 'NO']
, yes: function (index) {
layer.close(index);
$.ajax({
type: "POST",
url: "{% url 'system:basic-user-delete' %}",
data: {"id": sId, csrfmiddlewaretoken: '{{ csrf_token }}'},
cache: false,
success: function (msg) {
if (msg.result) {
layer.alert("操作成功");
oDataTable.ajax.reload();
} else {
//alert(msg.message);
layer.alert("操作失败");
}
return;
}
});
}
});
});
//批量启用
$("#btnEnable").click(function () {
if ($("input[name='checkList']:checked").length == 0) {
layer.msg("请选择要启用的用户");
return;
}
var arrId = new Array();
$("input[name='checkList']:checked").each(function () {
//alert($(this).val());
arrId.push($(this).val());
});
sId = arrId.join(',');
layer.alert('确定启用吗?', {
title: '提示'
, icon: 3 //0:感叹号 1对号 2差号 3问号 4小锁 5哭脸 6笑脸
, time: 0 //不自动关闭
, btn: ['YES', 'NO']
, yes: function (index) {
layer.close(index);
$.ajax({
type: "POST",
url: "{% url 'system:basic-user-enable' %}",
data: {"id": sId, csrfmiddlewaretoken: '{{ csrf_token }}'},
cache: false,
success: function (msg) {
if (msg.result) {
layer.alert("启用用户成功", {icon: 1});
oDataTable.ajax.reload();
} else {
//alert(msg.message);
layer.alert("启用用户失败", {icon: 5});
}
return;
}
});
}
});
});
//批量禁用
$("#btnDisable").click(function () {
if ($("input[name='checkList']:checked").length == 0) {
layer.msg("请选择要禁用的用户");
return;
}
var arrId = new Array();
$("input[name='checkList']:checked").each(function () {
//alert($(this).val());
arrId.push($(this).val());
});
sId = arrId.join(',');
layer.alert('确定禁用吗?', {
title: '提示'
, icon: 3 //0:感叹号 1对号 2差号 3问号 4小锁 5哭脸 6笑脸
, time: 0 //不自动关闭
, btn: ['YES', 'NO']
, yes: function (index) {
layer.close(index);
$.ajax({
type: "POST",
url: "{% url 'system:basic-user-disable' %}",
data: {"id": sId, csrfmiddlewaretoken: '{{ csrf_token }}'},
cache: false,
success: function (msg) {
if (msg.result) {
layer.alert("禁用用户成功", {icon: 1});
oDataTable.ajax.reload();
} else {
//alert(msg.message);
layer.alert("禁用用户失败", {icon: 5});
}
return;
}
});
}
});
});
//删除单个用户
function doDelete(id) {
layer.alert('确定删除吗?', {
title: '提示'
, icon: 3 //0:感叹号 1对号 2差号 3问号 4小锁 5哭脸 6笑脸
, time: 0 //不自动关闭
, btn: ['YES', 'NO']
, yes: function (index) {
layer.close(index);
$.ajax({
type: "POST",
url: "{% url 'system:basic-user-delete' %}",
data: {"id": id, csrfmiddlewaretoken: '{{ csrf_token }}'}, //防止post数据时报 csrf_token 403
cache: false,
success: function (msg) {
if (msg.result) {
layer.alert('删除成功', {icon: 1});
oDataTable.ajax.reload();
} else {
//alert(msg.message);
layer.alert('删除失败', {icon: 5});
}
return;
}
});
}
});
}
$("#select").change(function () {
//alert($("#select").val())
oDataTable.ajax.reload();
});
</script>
{% endblock %}

View File

@@ -0,0 +1,202 @@
{% extends 'base-layer.html' %}
{% load staticfiles %}
{% block css %}
<link rel="stylesheet" href="{% static 'js/plugins/layer/skin/layer.css' %}">
<link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap-datetimepicker.min.css' %}">
<link rel="stylesheet" href="{% static 'plugins/select2/select2.min.css' %}">
{% endblock %}
{% block main %}
<div class="box box-danger">
<form class="form-horizontal" id="addForm" method="post">
{% csrf_token %}
<input type="hidden" name='id' value="{{ user.id }}"/>
<input type="hidden" name='user' value="save"/>
<div class="box-body">
<fieldset>
<legend>
<h4>基本信息</h4>
</legend>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">姓名</label>
<div class="col-sm-3">
<input class="form-control" name="name" type="text" value=""/>
</div>
<label class="col-sm-2 control-label">性别</label>
<div class="col-sm-3">
<select class="form-control" name="gender">
<option value="male"></option>
<option value="famale"></option>
</select>
</div>
</div>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">生日</label>
<div class="col-sm-3">
<input type="text" class="form-control pull-right form_datetime" name="birthday"/>
</div>
<label class="col-sm-2 control-label">用户名</label>
<div class="col-sm-3">
<input type="text" class="form-control" name="username"/>
</div>
</div>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">状态</label>
<div class="col-sm-6">
<label class="control-label">
<input type="radio" class="minimal" name="is_active" value="True" checked>启用
</label>
<label class="control-label">
<input type="radio" class="minimal" name="is_active" value="False">禁用
</label>
</div>
</div>
<legend>
<h4>密码信息</h4>
</legend>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">密码</label>
<div class="col-sm-3">
<input class="form-control" name="password" type="password" value=""/>
</div>
<label class="col-sm-2 control-label">确认密码</label>
<div class="col-sm-3">
<input class="form-control" name="confirm_password" type="password" value=""/>
</div>
</div>
<legend>
<h4>联系信息</h4>
</legend>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">手机</label>
<div class="col-sm-3">
<input class="form-control" name="mobile" type="text"/>
</div>
<label class="col-sm-2 control-label">邮箱</label>
<div class="col-sm-3">
<input class="form-control" name="email" type="text"/>
</div>
</div>
<legend>
<h4>职员信息</h4>
</legend>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">入职日期</label>
<div class="col-sm-3">
<input type="text" class="form-control pull-right form_datetime" name="joined_date"/>
</div>
<label class="col-sm-2 control-label">部门</label>
<div class="col-sm-3">
<select class="form-control select2" style="width:100%;" name="department">
<option value="">--部门--</option>
{% for structure in structures %}
<option value="{{ structure.id }}">{{ structure.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">岗位</label>
<div class="col-sm-3">
<input class="form-control" name="post" type="text"/>
</div>
<label class="col-sm-2 control-label">上级</label>
<div class="col-sm-3">
<select class="form-control select2" style="width:100%;" name="superior">
<option value="">--上级--</option>
{% for user in users %}
<option value="{{ user.id }}">{{ user.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">所属角色组</label>
<div class="col-sm-6">
{% for role in roles %}
<label class="control-label">
<input type="checkbox" class="minimal" name="roles" value="{{ role.id }}"
{% if role in user_roles %}checked{% endif %}>
{{ role.name }}
</label>
{% endfor %}
</div>
</div>
</fieldset>
</div>
<div class="box-footer ">
<div class="row span7 text-center ">
<button type="button" id="btnCancel" class="btn btn-default margin-right ">重置</button>
<button type="button" id="btnSave" class="btn btn-info margin-right ">保存</button>
</div>
</div>
</form>
</div>
{% endblock %}
{% block javascripts %}
<script src="{% static 'bootstrap/js/bootstrap-datetimepicker.js' %}"></script>
<script src="{% static 'plugins/select2/select2.full.min.js' %}"></script>
<script type="text/javascript">
$("#btnSave").click(function () {
var data = $("#addForm").serialize();
$.ajax({
type: $("#addForm").attr('method'),
url: "{% url 'system:basic-user-create' %}",
data: data,
cache: false,
success: function (msg) {
if (msg.status == 'success') {
layer.alert('用户添加成功!', {icon: 1}, function (index) {
parent.layer.closeAll(); //关闭所有弹窗
});
} else if (msg.status == 'fail') {
layer.alert(msg.user_create_form_errors, {icon: 5});
//$('errorMessage').html(msg.message)
}
return;
}
});
});
/*点取消刷新新页面*/
$("#btnCancel").click(function () {
window.location.reload();
})
/*input 时间输入选择*/
$(".form_datetime").datetimepicker({
language: 'zh',
minView: 'month', //选择范围只到日期,不选择时分
//weekStart: 1,
//todayBtn: 1,
autoclose: 1,
todayHighlight: 1,
//startView: 2,
forceParse: 0,
showMeridian: 1,
format: 'yyyy-mm-dd'
}).on('changeDate', function (ev) {
$(this).datetimepicker('hide');
});
$(function () {
//Initialize Select2 Elements
$(".select2").select2();
});
</script>
{% endblock %}

View File

@@ -0,0 +1,192 @@
{% extends 'base-layer.html' %}
{% load staticfiles %}
{% block css %}
<link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap-datetimepicker.min.css' %}">
<link rel="stylesheet" href="{% static 'plugins/select2/select2.min.css' %}">
{% endblock %}
{% block main %}
<div class="box box-danger">
<form class="form-horizontal" id="addForm" method="post">
{% csrf_token %}
<input type="hidden" name='id' value="{{ user.id }}"/>
<input type="hidden" name='user' value="save"/>
<div class="box-body">
<fieldset>
<legend>
<h4>基本信息</h4>
</legend>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">姓名</label>
<div class="col-sm-3">
<input class="form-control" name="name" type="text" value="{{ user.name }}"/>
</div>
<label class="col-sm-2 control-label">性别</label>
<div class="col-sm-3">
<select class="form-control" name="gender">
<option value={{ user.gender }}> {{ user.get_gender_display }} </option>
<option value="male"></option>
<option value="famale"></option>
</select>
</div>
</div>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">生日</label>
<div class="col-sm-3">
<input type="text" class="form-control pull-right form_datetime" name="birthday"
value="{{ user.birthday|date:"Y-m-d" }}"/>
</div>
<label class="col-sm-2 control-label">用户名</label>
<div class="col-sm-3">
<input type="text" class="form-control" name="username" readonly="readonly"
value="{{ user.username }}"/>
</div>
</div>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">状态</label>
<div class="col-sm-6">
<label class="control-label">
<input type="radio" class="minimal" name="is_active" value="True"
{% ifequal user.is_active True %}checked{% endifequal %}>启用
</label>
<label class="control-label">
<input type="radio" class="minimal" name="is_active" value="False"
{% ifequal user.is_active False %}checked{% endifequal %}>禁用
</label>
</div>
</div>
<legend>
<h4 clase="">联系信息</h4>
</legend>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">手机</label>
<div class="col-sm-3">
<input class="form-control" name="mobile" readonly="readonly" type="text"
value="{{ user.mobile }}"/>
</div>
<label class="col-sm-2 control-label">邮箱</label>
<div class="col-sm-3">
<input class="form-control" name="email" type="text" value="{{ user.email }}"/>
</div>
</div>
<legend>
<h4>职员信息</h4>
</legend>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">入职日期</label>
<div class="col-sm-3">
<input type="text" class="form-control pull-right form_datetime" name="joined_date"
value="{{ user.joined_date|date:"Y-m-d" }}"/>
</div>
<label class="col-sm-2 control-label">部门</label>
<div class="col-sm-3">
<select class="form-control select2" style="width:100%;" name="department">
<option value="{{ user.department.id }}">{{ user.department.name|default:"--部门--" }}</option>
{% for structure in structures %}
<option value="{{ structure.id }}">{{ structure.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">岗位</label>
<div class="col-sm-3">
<input class="form-control" name="post" type="text"
value="{{ user.post|default_if_none:"" }}"/>
</div>
<label class="col-sm-2 control-label">上级</label>
<div class="col-sm-3">
<select class="form-control select2" style="width:100%;" name="superior">
<option value="{{ user.superior.id }}">{{ user.superior.name|default:"--上级--" }}</option>
{% for user in users %}
<option value="{{ user.id }}">{{ user.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">所属角色组</label>
<div class="col-sm-6">
{% for role in roles %}
<label class="control-label">
<input type="checkbox" class="minimal" name="roles" value="{{ role.id }}"
{% if role in user_roles %}checked{% endif %}>
{{ role.name }}
</label>
{% endfor %}
</div>
</div>
</fieldset>
</div>
<div class="box-footer ">
<div class="row span7 text-center ">
<button type="button" id="btnCancel" class="btn btn-default margin-right ">重置</button>
<button type="button" id="btnSave" class="btn btn-info margin-right ">保存</button>
</div>
</div>
</form>
</div>
{% endblock %}
{% block javascripts %}
<script src="{% static 'bootstrap/js/bootstrap-datetimepicker.js' %}"></script>
<script src="{% static 'plugins/select2/select2.full.min.js' %}"></script>
<script type="text/javascript">
/*点取消刷新新页面*/
$("#btnCancel").click(function () {
window.location.reload();
})
/*input 时间输入选择*/
$(".form_datetime").datetimepicker({
language: 'zh',
minView: 'month',
//weekStart: 1,
//todayBtn: 1,
autoclose: 1,
todayHighlight: 1,
//startView: 2,
forceParse: 0,
showMeridian: 1,
format: 'yyyy-mm-dd'
}).on('changeDate', function (ev) {
$(this).datetimepicker('hide');
});
$(function () {
//Initialize Select2 Elements
$(".select2").select2();
});
$("#btnSave").click(function () {
var data = $("#addForm").serialize();
$.ajax({
type: $("#addForm").attr('method'),
url: "{% url 'system:basic-user-update' %}",
data: data,
cache: false,
success: function (msg) {
if (msg.status == 'success') {
layer.alert('数据保存成功!', {icon: 1}, function (index) {
parent.layer.closeAll(); //关闭所有弹窗
});
} else if (msg.status == 'fail') {
layer.alert('数据保存失败', {icon: 5});
//$('errorMessage').html(msg.message)
}
return;
}
});
});
</script>
{% endblock %}