{% extends "base.html" %}
{% block content %}
<!-- 自定义操作按钮-->
<div style="position: relative">
<div id="toolbar" class="form-inline pull-left" style="position: absolute;top: 10px">
<div class="form-group">
<select id="filter_instance_id" class="form-control selectpicker"
data-live-search="true">
<option value="" selected="selected">全部实例</option>
{% for ins in ins_list %}
<option value="{{ ins.id }}">{{ ins.instance_name }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<select id="state" class="form-control selectpicker">
<option value="" selected="selected">启用状态</option>
<option value="true">启用</option>
<option value="false">未启用</option>
</select>
</div>
<div class="form-group">
<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>
{% if perms.sql.archive_mgt %}
<div class="form-group">
<button id="btn_add_config" type="button" class="btn btn-info"
onclick="window.open('/admin/sql/archiveconfig/add/')">
<span class="glyphicon glyphicon-arrow-up" aria-hidden="true"></span>
<span aria-hidden="true"></span>添加配置
</button>
</div>
{% endif %}
</div>
</div>
<!-- 申请列表的表格-->
<div class="table-responsive">
<table id="archive-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="src_instance_name" name="src_instance_name"
class="selectpicker show-tick form-control bs-select-hidden" data-live-search="true"
title="请选择源实例:"
data-placeholder="请选择实例:" required>
</select>
</div>
<div class="form-group">
<select id="src_db_name" name="src_db_name"
class="form-control selectpicker show-tick bs-select-hidden"
title="请选择源数据库:"
data-live-search="true" data-placeholder="请选择数据库:" required>
</select>
</div>
<div class="form-group">
<select id="src_table_name" name="src_table_name"
class="form-control selectpicker show-tick bs-select-hidden"
data-live-search="true"
data-name="请选择需要归档的表:"
title="请选择需要归档的表:"
data-placeholder="请选择需要归档的表:" required>
</select>
</div>
<div class="form-group">
<select id="mode" name="mode"
class="form-control selectpicker show-tick bs-select-hidden"
data-name="请选择归档模式:"
title="请选择归档模式:"
data-placeholder="请选择归档模式:" required>
<option value='file'>归档到文件</option>
<option value='dest'>归档到其他实例</option>
<option value='purge'>直接删除</option>
</select>
</div>
<div class="form-group" id="no_delete-div" style="display: none">
<div class="form-group">
<select id="no_delete" name="no_delete"
class="selectpicker show-tick form-control bs-select-hidden"
title="归档后是否保留源数据:"
data-placeholder="归档后是否保留源数据:" required>
<option value='' disabled>归档后是否保留源数据</option>
<option value='true' selected>保留</option>
<option value='false'>删除</option>
</select>
</div>
</div>
<div class="form-group" id="dest-div" style="display: none">
<div class="form-group">
<select id="dest_instance_name" name="dest_instance_name"
class="selectpicker show-tick form-control bs-select-hidden" data-live-search="true"
title="请选择目标实例:"
data-placeholder="请选择目标实例:" required>
</select>
</div>
<div class="form-group">
<select id="dest_db_name" name="dest_db_name"
class="form-control selectpicker show-tick bs-select-hidden"
title="请选择目标数据库:"
data-live-search="true" data-placeholder="请选择对应数据库:" required>
</select>
</div>
<div class="form-group">
<select id="dest_table_name" name="dest_table_name"
class="form-control selectpicker show-tick bs-select-hidden"
data-live-search="true"
data-name="请选择目标表:"
title="请选择目标表:"
data-placeholder="请选择需目标表:" required>
</select>
</div>
</div>
<div class="form-group">
<textarea id="condition" name="condition" class="form-control"
placeholder="请输入归档条件,就是SQL语句的WHERE条件"></textarea>
</div>
<div class="form-group">
<input type="number" autocomplete="off" name="sleep" class="form-control" id="sleep"
placeholder="归档10000行记录后的休眠秒数">
</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="archive_apply()">提交申请</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(),
db_type: 'mysql'
},
complete: function () {
},
success: function (data) {
if (data.status === 0) {
let result = data['data'];
$("#src_instance_name").empty();
$("#dest_instance_name").empty();
for (let i = 0; i < result.length; i++) {
let instance = "<option value=\"" + result[i]['instance_name'] + "\">" + result[i]['instance_name'] + "</option>";
$("#src_instance_name").append(instance);
$("#dest_instance_name").append(instance);
}
$('#src_instance_name').selectpicker('render');
$('#src_instance_name').selectpicker('refresh');
$('#dest_instance_name').selectpicker('render');
$('#dest_instance_name').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: 3
},
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>
//筛选变动自动刷新
$("#filter_instance_id").change(function () {
archive_apply_list();
});
//筛选变动自动刷新
$("#state").change(function () {
archive_apply_list();
});
//获取申请列表
function archive_apply_list() {
$('#archive-list').bootstrapTable('destroy').bootstrapTable({
escape: true,
method: 'get',
contentType: "application/x-www-form-urlencoded",
url: "/archive/list/",
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: false, //是否显示父子表
locale: 'zh-CN', //本地化
queryParamsType: 'limit',
//请求服务数据时所传参数
queryParams:
function (params) {
return {
filter_instance_id: $("#filter_instance_id").val(),
state: $("#state").val(),
limit: params.limit,
offset: params.offset,
search: params.search
}
},
columns: [{
title: 'ID',
field: 'id'
}, {
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=\"/archive/" + row.id + "/\">" + value.substr(0, 10) + '...';
+"</a>";
} else {
span.innerHTML = "<a href=\"/archive/" + row.id + "/\">" + value + "</a>";
}
return span.outerHTML;
}
}, {
title: '实例',
field: 'src_instance__instance_name'
}, {
title: '数据库',
field: 'src_db_name'
}, {
title: '表',
field: 'src_table_name'
}, {
title: '归档模式',
field: 'mode'
}, {
title: '源数据',
field: 'no_delete',
formatter: function (value, row, index) {
if (String(value) === 'true') {
return '保留'
} else {
return '删除'
}
}
}, {
title: '休眠(秒)',
field: 'sleep'
}, {
title: '启用状态',
field: 'state',
formatter: function (value, row, index) {
if (String(value) === 'true') {
return "<span class=\"label label-success\">" + '启用' + "</span>"
} else {
return "<span class=\"label label-danger\">" + '关闭' + "</span>"
}
}
}, {
title: '工单状态',
field: 'status',
formatter: function (value, row, index) {
return workflow_status_formatter(value)
},
visible: false // 默认不显示
}, {
title: '申请人',
field: 'user_display'
}, {
title: '申请时间',
field: 'create_time'
}, {
title: '组',
field: 'resource_group__group_name',
visible: false // 默认不显示
}, {
title: '操作',
field: 'operation',
formatter: function (value, row, index) {
return "<button class=\"btn btn-info btn-xs\" workflow_id=\"" + row.id + "\"\n" + "onclick=\"getLog(this)\" >操作日志\n" + "</button>"
}
}],
onLoadSuccess: function () {
},
onLoadError: onLoadErrorCallback,
onSearch: function (e) {
//传搜索参数给服务器
queryParams(e)
},
responseHandler: function (res) {
//在ajax获取到数据,渲染表格之前,修改数据源
return res;
}
});
}
//实例变更获取数据库列表
$("#src_instance_name").change(function () {
$.ajax({
type: "get",
url: "/instance/instance_resource/",
dataType: "json",
data: {
instance_name: $("#src_instance_name").val(),
resource_type: "database"
},
complete: function () {
},
success: function (data) {
if (data.status === 0) {
var result = data.data;
$("#src_db_name").empty();
for (var i = 0; i < result.length; i++) {
var name = "<option value=\"" + result[i] + "\">" + result[i] + "</option>";
$("#src_db_name").append(name);
}
$('#src_db_name').selectpicker('render');
$('#src_db_name').selectpicker('refresh');
} else {
alert(data.msg);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});
});
$("#dest_instance_name").change(function () {
$.ajax({
type: "get",
url: "/instance/instance_resource/",
dataType: "json",
data: {
instance_name: $("#dest_instance_name").val(),
resource_type: "database"
},
complete: function () {
},
success: function (data) {
if (data.status === 0) {
var result = data.data;
$("#dest_db_name").empty();
for (var i = 0; i < result.length; i++) {
var name = "<option value=\"" + result[i] + "\">" + result[i] + "</option>";
$("#dest_db_name").append(name);
}
$('#dest_db_name').selectpicker('render');
$('#dest_db_name').selectpicker('refresh');
} else {
alert(data.msg);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});
});
//数据库变更获取表名称
$("#src_db_name").change(function () {
$.ajax({
type: "get",
url: "/instance/instance_resource/",
dataType: "json",
data: {
instance_name: $("#src_instance_name").val(),
db_name: $("#src_db_name").val(),
resource_type: "table"
},
complete: function () {
},
success: function (data) {
if (data.status === 0) {
var result = data.data;
$("#src_table_name").empty();
for (var i = 0; i < result.length; i++) {
var name = "<option>" + result[i] + "</option>";
$("#src_table_name").append(name);
}
$('#src_table_name').selectpicker('render');
$('#src_table_name').selectpicker('refresh');
} else {
alert(data.msg);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});
});
$("#dest_db_name").change(function () {
$.ajax({
type: "get",
url: "/instance/instance_resource/",
dataType: "json",
data: {
instance_name: $("#dest_instance_name").val(),
db_name: $("#dest_db_name").val(),
resource_type: "table"
},
complete: function () {
},
success: function (data) {
if (data.status === 0) {
var result = data.data;
$("#dest_table_name").empty();
for (var i = 0; i < result.length; i++) {
var name = "<option>" + result[i] + "</option>";
$("#dest_table_name").append(name);
}
$('#dest_table_name').selectpicker('render');
$('#dest_table_name').selectpicker('refresh');
} else {
alert(data.msg);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});
});
//判断页面显示
$("#mode").change(function () {
//库权限
let mode = $("#mode").val();
if (mode === 'dest') {
$("#dest-div").show();
} else {
$("#dest-div").hide();
}
if (mode !== 'purge') {
$("#no_delete-div").show()
} else {
$("#no_delete-div").hide()
}
});
//提交权限申请
function archive_apply() {
//禁用按钮
$('button[type=button]').addClass('disabled');
$('button[type=button]').prop('disabled', true);
//提交请求
$.ajax({
type: "post",
url: "/archive/apply/",
dataType: "json",
data: {
title: $("#title").val(),
group_name: $("#group_name").val(),
src_instance_name: $("#src_instance_name").val(),
src_table_name: $("#src_table_name").val(),
src_db_name: $("#src_db_name").val(),
mode: $("#mode").val(),
dest_instance_name: $("#dest_instance_name").val(),
dest_db_name: $("#dest_db_name").val(),
dest_table_name: $("#dest_table_name").val(),
condition: $("#condition").val(),
no_delete: $("#no_delete").val(),
sleep: $("#sleep").val(),
},
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 = '/archive/'
} else {
alert(data.msg)
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});
}
// 获取操作日志
function getLog(obj) {
var workflow_id = $(obj).attr("workflow_id");
var workflow_type = 3;
$.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 () {
archive_apply_list();
});
</script>
{% endblock %}