{% extends "base.html" %}
{% block content %}
<!-- 自定义操作按钮-->
<div id="toolbar" class="btn-group">
<a type="button" class="btn btn-default" href="/queryuserprivileges/">
<span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span>
<span aria-hidden="true"></span>权限管理</a>
<button id="btn_add" type="button" class="btn btn-default"
data-toggle="modal" data-target="#apply">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
<span aria-hidden="true"></span>权限申请
</button>
</div>
<!-- 申请列表的表格-->
<div class="table-responsive">
<table id="dbauthapply-list" data-toggle="table" class="table table-striped table-hover"
style="table-layout:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">
</table>
</div>
<!-- 申请权限的模态框-->
<div class="modal fade" id="apply" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">申请数据库查询权限</h4>
</div>
<div class="modal-body">
<div class="form-group">
<input type="text" autocomplete="off" class="form-control" id="title" placeholder="简单说明权限用途">
</div>
<div class="form-group">
<select id="group_name" name="group_name"
class="selectpicker show-tick form-control bs-select-hidden"
title="请选择组:"
data-live-search="true" required>
{% for group in group_list %}
<option value="{{ group.group_name }}">{{ group.group_name }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<select id="instance_name" name="instance_name"
class="selectpicker show-tick form-control bs-select-hidden"
title="请选择实例:"
data-live-search="true" required>
// TODO 使用models中的choices 渲染
{% for name, engine in engines.items %}
<optgroup id="optgroup-{{ name }}" label="{{ engine.name }}"></optgroup>
{% endfor %}
</select>
</div>
<div class="form-group">
<select id="priv_type" name="db_name" data-live-search="true"
title="权限级别:"
class="form-control selectpicker show-tick bs-select-hidden">
</select>
</div>
<div id="db_name_div" class="form-group">
<select id="db_name" name="db_name" data-live-search="true"
title="请选择数据库:"
class="form-control selectpicker show-tick bs-select-hidden ">
</select>
</div>
<div id="db_name_multiple_div" class="form-group" style="display: none">
<select id="db_name_multiple" name="db_name" data-live-search="true" multiple="multiple"
title="请选择数据库:" required
class="form-control selectpicker show-tick bs-select-hidden ">
</select>
</div>
<div id="table_div" class="form-group">
<select id="table_name" name="table_name"
class="form-control selectpicker show-tick bs-select-hidden" data-live-search="true"
multiple='multiple' data-max-options="999"
title="请选择表:" required>
</select>
</div>
<div class="form-group">
<select id="valid_date" name="valid_date"
title="请选择授权时间:"
class="form-control selectpicker show-tick bs-select-hidden ">
<option value="day">一天</option>
<option value="week">一周</option>
<option value="month">一月</option>
<option value="year">长期(一年)</option>
</select>
</div>
<div class="form-group">
<input id="limit_num" list="limits" type="number"
class="form-control "
placeholder="请选择查询限制行数:">
<datalist id="limits">
<option value=100>100</option>
<option value=500>500</option>
<option value=1000>1000</option>
</datalist>
</div>
<!--审批流程-->
<div id="div-workflow_auditors" class="form-group" style="display: none">
<p class="bg-primary">   审批流程:<b id="workflow_auditors"></b></p>
</div>
<p class="text-info">提示:权限审核通过后即可进行在线查询,请耐心等待。</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-success" onclick="applyforprivileges()">提交申请</button>
</div>
</div>
</div>
</div>
<!-- 日志信息-->
<div class="modal fade" id="logs">
<div class="modal-dialog">
<div class="modal-content message_align">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">×</span></button>
<h4 class="modal-title text-danger">工单日志</h4>
</div>
<div class="modal-body">
<div class="table-responsive">
<table id="log-list" data-toggle="table" class="table table-striped table-hover"
style="table-layout:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">
</table>
</div>
</div>
<div class="modal-footer">
</div>
</div>
</div>
</div>
{% endblock content %}
{% block js %}
<!--group -->
<script>
// 获取实例信息和审批流程
$("#group_name").change(function () {
$.ajax({
type: "post",
url: "/group/instances/",
dataType: "json",
data: {
group_name: $("#group_name").val(),
tag_code: 'can_read'
},
complete: function () {
},
success: function (data) {
if (data.status === 0) {
$("optgroup[id^='optgroup']").empty();
let result = data['data']
const supportDb = [ {% for name in engines.keys %}"{{ name }}", {% endfor %}]
for (let i of result) {
let instance = "<option value=\"" + i.instance_name + "\" instance-id=" + i.id + ">" + i.instance_name + "</option>";
if (supportDb.indexOf(i.db_type) !== -1) {
$("#optgroup-" + i.db_type).append(instance);
}
}
$('#instance_name').selectpicker('render').selectpicker('refresh');
} else {
alert(data.msg);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});
$.ajax({
type: "post",
url: "/group/auditors/",
dataType: "json",
data: {
group_name: $("#group_name").val(),
workflow_type: 1
},
complete: function () {
},
success: function (data) {
if (data.status === 0) {
var result = data.data;
$("#div-workflow_auditors").show();
$("#workflow_auditors").val(result['auditors']);
$("#workflow_auditors").text(result['auditors_display']);
} else {
alert(data.msg);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});
});
</script>
<script>
//选择控件初始化
$("#table_name").selectpicker({
actionsBox: true, //在下拉选项添加选中所有和取消选中的按钮
countSelectedText: "已选中{0}项",
selectedTextFormat: "count > 5"
});
$("#db_name_multiple").selectpicker({
actionsBox: true, //在下拉选项添加选中所有和取消选中的按钮
countSelectedText: "已选中{0}项",
selectedTextFormat: "count > 5"
});
//获取申请列表
function queryapplylist() {
//采取异步请求
//初始化table
$('#dbauthapply-list').bootstrapTable('destroy').bootstrapTable({
escape: true,
method: 'post',
contentType: "application/x-www-form-urlencoded",
url: "/query/applylist/",
striped: true, //是否显示行间隔色
cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
pagination: true, //是否显示分页(*)
sortable: true, //是否启用排序
sortOrder: "asc", //排序方式
sidePagination: "server", //分页方式:client客户端分页,server服务端分页(*)
pageNumber: 1, //初始化加载第一页,默认第一页,并记录
pageSize: 20, //每页的记录行数(*)
pageList: [20, 30, 50, 100], //可供选择的每页的行数(*)
search: true, //是否显示表格搜索
strictSearch: false, //是否全匹配搜索
showColumns: true, //是否显示所有的列(选择显示的列)
showRefresh: true, //是否显示刷新按钮
minimumCountColumns: 2, //最少允许的列数
clickToSelect: true, //是否启用点击选中行
uniqueId: "id", //每一行的唯一标识,一般为主键列
showToggle: true, //是否显示详细视图和列表视图的切换按钮
cardView: false, //是否显示详细视图
detailView: true, //是否显示父子表
locale: 'zh-CN', //本地化
toolbar: "#toolbar", //指明自定义的toolbar
queryParamsType: 'limit',
//请求服务数据时所传参数
queryParams:
function (params) {
return {
limit: params.limit,
offset: params.offset,
search: params.search
}
},
//格式化详情
detailFormatter: function (index, row) {
var html = [];
if (row.priv_type === 2) {
$.each(row, function (key, value) {
if (key === 'table_list') {
var sql = '表清单:<br>' + value;
//替换间隔符为换行符
sql = sql.replace(/,/g, "<br>");
html.push('<span>' + sql + '</span>');
}
});
return html.join('');
} else {
$.each(row, function (key, value) {
if (key === 'db_list') {
var sql = '数据库清单:<br>' + value;
//替换间隔符为换行符
sql = sql.replace(/,/g, "<br>");
html.push('<span>' + sql + '</span>');
}
});
return html.join('');
}
},
columns: [{
title: '工单名称',
field: 'title',
formatter: function (value, row, index) {
var span = document.createElement('span');
span.setAttribute('title', value);
if (value.length > 10) {
span.innerHTML = "<a href=\"/queryapplydetail/" + row.apply_id + "/\">" + value.substr(0, 10) + '...';
+"</a>";
} else {
span.innerHTML = "<a href=\"/queryapplydetail/" + row.apply_id + "/\">" + value + "</a>";
}
return span.outerHTML;
}
}, {
title: '实例',
field: 'instance__instance_name'
}, {
title: '数据库',
field: 'db_list',
formatter: function (value, row, index) {
if (value.length > 30) {
var db_list = value.substr(0, 30) + '...';
return db_list;
} else {
return value
}
}
}, {
title: '权限级别',
field: 'priv_type',
formatter: function (value, row, index) {
if (String(value) === '1') {
return 'DATABASE';
} else {
return 'TABLE';
}
}
}, {
title: '结果集',
field: 'limit_num'
}, {
title: '有效时间',
field: 'valid_date'
}, {
title: '工单状态',
field: 'status',
formatter: function (value, row, index) {
return workflow_status_formatter(value)
}
}, {
title: '申请人',
field: 'user_display'
}, {
title: '申请时间',
field: 'create_time'
}, {
title: '组',
field: 'group_name'
}, {
title: '操作',
field: 'operation',
formatter: function (value, row, index) {
return "<button class=\"btn btn-info btn-xs\" workflow_id=\"" + row.apply_id + "\"\n" + "onclick=\"getLog(this)\" >操作日志\n" + "</button>"
}
}],
onLoadSuccess: function () {
},
onLoadError: onLoadErrorCallback,
onSearch: function (e) {
//传搜索参数给服务器
queryParams(e)
},
responseHandler: function (res) {
//在ajax获取到数据,渲染表格之前,修改数据源
return res;
}
});
}
//实例变更获取数据库列表/权限类型
$("#instance_name").change(function () {
$.ajax({
type: "get",
url: "/instance/instance_resource/",
dataType: "json",
data: {
instance_name: $("#instance_name").val(),
resource_type: "database"
},
complete: function () {
// 仅MySQL支持限制到表级权限
var optgroup = $('#instance_name :selected').parent().attr('label');
$("#priv_type").empty();
if (optgroup === "MySQL") {
$('#priv_type').append("<option value=\"1\">DATABASE</option>");
$('#priv_type').append("<option value=\"2\" selected=\"selected\">TABLE</option>");
} else {
$('#priv_type').append("<option value=\"1\" selected=\"selected\">DATABASE</option>");
}
$('#priv_type').prepend("<option value=\"is-empty\" disabled=\"\">权限级别:</option>");
$('#priv_type').selectpicker('render');
$('#priv_type').selectpicker('refresh');
$('#priv_type').selectpicker().trigger("change")
},
success: function (data) {
if (data.status === 0) {
var result = data.data;
$("#db_name").empty();
$("#db_name_multiple").empty();
for (var i = 0; i < result.length; i++) {
var name = "<option value=\"" + result[i] + "\">" + result[i] + "</option>";
$("#db_name").append(name);
$("#db_name_multiple").append(name);
}
$('#db_name').selectpicker('render');
$('#db_name').selectpicker('refresh');
$('#db_name_multiple').selectpicker('render');
$('#db_name_multiple').selectpicker('refresh');
} else {
alert(data.msg);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});
});
//数据库变更获取表名称
$("#db_name").change(function () {
$.ajax({
type: "get",
url: "/instance/instance_resource/",
dataType: "json",
data: {
instance_name: $("#instance_name").val(),
db_name: $("#db_name").val(),
resource_type: "table"
},
complete: function () {
},
success: function (data) {
if (data.status === 0) {
var result = data.data;
$("#table_name").empty();
for (var i = 0; i < result.length; i++) {
var name = "<option>" + result[i] + "</option>";
$("#table_name").append(name);
}
$('#table_name').selectpicker('render');
$('#table_name').selectpicker('refresh');
} else {
alert(data.msg);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});
});
//判断页面显示
$("#priv_type").change(function () {
//库权限
if ($("#priv_type").val() === '1') {
$("#table_div").hide();
$("#db_name_div").hide();
$("#db_name_multiple_div").show();
}
//表权限
else if ($("#priv_type").val() === '2') {
$("#table_div").show();
$("#db_name_div").show();
$("#db_name_multiple_div").hide();
}
});
//时间计算
function addDate(date, days) {
var d = new Date(date);
d.setDate(d.getDate() + days);
var m = d.getMonth() + 1;
return d.getFullYear() + '-' + m + '-' + d.getDate();
}
//提交参数校验
function applyvalidate() {
var title = $("#title").val();
var priv_type = $("#priv_type").val();
var instance_name = $("#instance_name").val();
var db_name = $("#db_name").val();
var db_name_multiple = $("#db_name_multiple").val();
var table_name = $("#table_name").val();
var valid_date = $("#valid_date").val();
var limit_num = $("#limit_num").val();
var apply_remark = $("#apply_remark").val();
var workflow_auditors = $("#workflow_auditors").val();
var group_name = $("#group_name").val();
// 参数校验
if (priv_type) {
if (priv_type === '1') {
if (title && group_name && workflow_auditors && instance_name && db_name_multiple && valid_date && limit_num) {
return true
} else {
alert("信息填写不完整,或者未配置审批流程");
return false
}
} else if (priv_type === '2') {
if (title && group_name && workflow_auditors && instance_name && db_name && table_name && valid_date && limit_num) {
return true
} else {
alert("信息填写不完整,或者未配置审批流程");
return false
}
}
} else if (priv_type == null) {
alert("请选择权限类别");
return false
}
}
//提交权限申请
function applyforprivileges() {
var title = $("#title").val();
var priv_type = $("#priv_type").val();
var instance_name = $("#instance_name").val();
var db_name = $("#db_name").val();
var db_name_multiple = $("#db_name_multiple").val();
var table_list = $("#table_name").val();
var valid_date = $("#valid_date").val();
var limit_num = $("#limit_num").val();
var apply_remark = $("#apply_remark").val();
var workflow_auditors = $("#workflow_auditors").val();
var group_name = $("#group_name").val();
// 参数校验
if (applyvalidate()) {
//时间格式化
var date = new Date();
if (valid_date === 'day') {
valid_date = addDate(date, 1);
} else if (valid_date === 'week') {
valid_date = addDate(date, 7);
} else if (valid_date === 'month') {
valid_date = addDate(date, 30);
} else if (valid_date === 'year') {
valid_date = addDate(date, 365);
} else {
valid_date = addDate(date, 1);
}
//禁用按钮
$('button[type=button]').addClass('disabled');
$('button[type=button]').prop('disabled', true);
//提交请求
$.ajax({
type: "post",
url: "/query/applyforprivileges/",
dataType: "json",
data: {
title: title,
instance_name: instance_name,
priv_type: priv_type,
db_name: db_name,
db_list: db_name_multiple,
table_list: table_list,
valid_date: valid_date,
limit_num: limit_num,
apply_remark: apply_remark,
workflow_auditors: workflow_auditors,
group_name: group_name
},
complete: function () {
$('button[type=button]').removeClass('disabled');
$('button[type=button]').prop('disabled', false);
},
success: function (data) {
if (data.status === 0) {
$('#apply').modal('hide');
location.href = '/queryapplylist/'
} else {
alert(data.msg)
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});
}
}
// 获取操作日志
function getLog(obj) {
var workflow_id = $(obj).attr("workflow_id");
var workflow_type = 1;
$.ajax({
type: "post",
url: "/workflow/log/",
dataType: "json",
data: {
workflow_id: workflow_id,
workflow_type: workflow_type,
},
complete: function () {
},
success: function (data) {
//初始化table
$('#logs').modal('show');
$('#log-list').bootstrapTable('destroy').bootstrapTable({
escape: true,
striped: true, //是否显示行间隔色
cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
pagination: false, //是否显示分页(*)
sortable: false, //是否启用排序
sortOrder: "asc", //排序方式
sidePagination: "client", //分页方式:client客户端分页,server服务端分页(*)
pageNumber: 1, //初始化加载第一页,默认第一页,并记录
pageSize: 20, //每页的记录行数(*)
pageList: [20, 30, 50, 100], //可供选择的每页的行数(*)
search: false, //是否显示表格搜索
strictSearch: false, //是否全匹配搜索
showColumns: false, //是否显示所有的列(选择显示的列)
showRefresh: false, //是否显示刷新按钮
minimumCountColumns: 2, //最少允许的列数
clickToSelect: false, //是否启用点击选中行
uniqueId: "id", //每一行的唯一标识,一般为主键列
showToggle: false, //是否显示详细视图和列表视图的切换按钮
cardView: false, //是否显示详细视图
detailView: false, //是否显示父子表
locale: 'zh-CN', //本地化
data: data.rows,
columns: [{
title: '操作',
field: 'operation_type_desc'
}, {
title: '操作人',
field: 'operator_display'
}, {
title: '操作时间',
field: 'operation_time'
}, {
title: '操作信息',
field: 'operation_info'
}],
onLoadSuccess: function () {
},
onLoadError: onLoadErrorCallback,
});
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
})
}
//初始化数据
$(document).ready(function () {
queryapplylist();
});
</script>
{% endblock %}