Authored by 袁晋鹏

fix:服务器备份、数据库恢复验证概况、指标预测分析功能迁移

//备份失败列表
layui.define(['table', 'form', 'admin', 'layer', 'common', 'sessions', 'soulTable'], function (exports) {
var $ = layui.$;
var form = layui.form;
var table = layui.table;
var common = layui.common;
var admin = layui.admin;
var session = layui.sessions
//对外暴露的接口
exports("backDingjiaList", function (d) {
var accessToken = localStorage.getItem("accessToken");
var busId = d.busId === null ? '' : d.busId;
var flag = d.flag === null ? '' : d.flag;
createFailTable();
$("#dingjia-detail-export-excel").on('click', function () {
var href = common.domainName + "/api-web/backupview/exportDingjiaBackDetails?accessToken=" + accessToken + "&busId=" + busId + "&flag=" + flag;
window.open(href)
})
//渲染附件表格
function createFailTable() {
var loading = layer.load(2)
var url = common.domainName + '/api-web/backupview/dingjiaBackDetails'
$.ajax({
url: url,
type: 'get',
data: {accessToken: accessToken, busId: busId, flag: flag},
success: function (res) {
layer.close(loading);
var data = res.data;
$("#backDingjiaListTable").find("tbody").empty();
$.each(data, function (i, e) {
var tr = '';
var rowspan = e.jobs != null && e.jobs.length > 1 ? e.jobs.length : 1;
var str = '<td rowspan="' + rowspan + '">' + (i + 1) + '</td><td rowspan="' + rowspan + '">' + e.resName + '</td><td rowspan="' + rowspan + '">' + e.ip + '</td>'
tr += '<tr data-id="' + e.resId + '">' + str
if (e.jobs != null && e.jobs.length > 0) {
$.each(e.jobs, function (j, f) {
var lastRunResult = f.lastRunResult === "" ? "未知" : f.lastRunResult;
var totalSize = (Number(f.totalSize) / 1024 / 1024 / 1024).toFixed(2);
var speed = (Number(f.speed) / 1024 / 1024).toFixed(2);
tr += '<td class="jobid" data-jobid ="' + f.id + '">' + f.subtype + '</td>' +
'<td>' + f.status + '</td>' +
'<td>' + f.resName + '</td>' +
'<td>' + totalSize + '</td>' +
'<td>' + speed + '</td>' +
'<td>' + f.lastRunTime + '</td>' +
'<td>' + f.lastCompletedTime + '</td>' +
'<td>' + lastRunResult + '</td>' +
'<td>' + f.nextRunTime + '</td>' +
'<td><input type="button" value="编辑" class="edit" style="background-color: #1E9FFF;"/></td>' +
'</tr>'
});
} else {
tr += '<td></td>' +
'<td></td>' +
'<td></td>' +
'<td></td>' +
'<td></td>' +
'<td></td>' +
'<td></td>' +
'<td></td>' +
'<td></td>' +
'<td><input type="button" value="移除资源" class="remove" style="background-color: #1E9FFF;"/></td>' +
'</tr>'
}
$("#backDingjiaListTable").find("tbody").append(tr);
});
$('#backDingjiaListTable :button.edit').click(function () {
var toEdit = this.value == '编辑';
this.value = toEdit ? '确定' : '编辑';
var tdArr = []
var jobId = $(this).closest('tr').find('td.jobid').attr("data-jobid");
$(this).closest('tr').find('td').not('[rowspan]').not(':last').each(function (t, index) {
if (toEdit) {
this.innerHTML = '<input type="text" value="' + this.innerHTML.replace(/"/g, '&quot;').replace(/<\/?.+?>/g, '').replace(/ /g, '') + '"/>';
} else {
if (this.firstChild != null) {
if (this.firstChild.value != undefined) {
this.innerHTML = this.firstChild.value.replace(/</g, '&lt;').replace(/>/g, '&gt;');
} else {
this.innerHTML = this.firstChild.data.replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
}else {
this.innerHTML = this.value.replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
tdArr.push(this.innerHTML)
}
});
if (!toEdit) {
var param = {
'id': jobId,
'subtype': tdArr[0],
'status': tdArr[1],
'resName': tdArr[2],
'totalSize': (Number(tdArr[3]) * 1024 * 1024 * 1024),
'speed': (Number(tdArr[4]) * 1024 * 1024),
'lastRunTime': tdArr[5],
'lastCompletedTime': tdArr[6],
'lastRunResult': tdArr[7],
'nextRunTime': tdArr[8]
};
if (param.resName == '') {
layer.msg('备份类型不能为空!', {icon: 1});
return;
} else if (param.status == '') {
layer.msg('状态不能为空!', {icon: 1});
return;
} else if (param.lastRunTime == '') {
layer.msg('上次备份时间不能为空!', {icon: 1});
return;
} else {
var url = common.domainName + '/api-web/backupview/dingjiaJobEdit?accessToken=' + accessToken
layer.load(2);
admin.req({
url: url,
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(param),
success: function (response) {
layer.closeAll('loading');
if (response.success) {
layer.msg('修改成功!', {icon: 1});
createFailTable()
return true;
} else {
layer.msg('修改失败!', {icon: 2});
}
},
error: function () {
layer.closeAll('loading');
}
});
}
}
});
$('#backDingjiaListTable :button.remove').click(function () {
var resId = $(this).closest('tr').attr("data-id");
layer.confirm('确定要将此资源移除备份嘛?', {
btn: ['确定', '取消'] //按钮
}, function () {
$.ajax({
url: common.domainName + `/api-web/backupview/removeDingjiaRes?accessToken=` + accessToken + `&busId=` + busId + `&resId=` + resId,
type: "get",
}).done(function (res) {
layer.msg('移除成功', {
offset: '15px'
, icon: 1
, time: 1000
});
}).error(function (error) {
console.log(error);
});
});
});
}
})
}
})
})
\ No newline at end of file
... ...
... ... @@ -138,6 +138,8 @@ layui.define(['common', 'admin', 'echarts', 'common', 'table', 'sessions', 'layd
tr += '<td><span style="color:#ffe40e">' + n + '</span></td>'
} else if (/未备份/.test(n)) {
tr += '<td><span style="color:magenta">' + n + '</span></td>'
} else if (/已失效/.test(n)) {
tr += '<td><span style="color:rgba(72,72,72,0.77)">' + n + '</span></td>'
} else {
tr += '<td>' + n + '</td>'
}
... ...
layui.define(['table', 'admin', 'form', 'laydate', 'common', 'sessions', 'view', 'element'], function (exports) {
var $ = layui.$;
var form = layui.form;
var table = layui.table;
var common = layui.common;
//对外暴露的接口
exports('backupDingjia', function () {
var sessions = layui.sessions;
var accessToken = localStorage.getItem("accessToken");
loadConditionSelect();
reloadAllChange();
//发送状态
// 下拉框改变搜索
form.on('select(slt-dingjia-biz)', reloadAllChange);
// 加载查询条件下拉框
function loadConditionSelect() {
//绑定业务下拉选择数据
common.bizTypeSelect("slt-dingjia-biz", function () {
form.render("select");
});
}
$("#btn-dingjia-export-excel").on('click', function () {
var href = common.domainName + "/api-web/backupview/exportDingjiaBacks?accessToken=" + accessToken + "&busId=" + $("#slt-dingjia-biz").val();
window.open(href)
})
//表格数据
function renderBackupDingjiaListTable() {
var loading = layer.load(2);
var url = common.domainName + '/api-web/backupview/dingjiaBacks';
$.ajax({
url: url,
type: 'get',
data: {accessToken: accessToken, busId: $("#slt-dingjia-biz").val()},
success: function (res) {
layer.close(loading);
var data = res.data;
$("#dingjia_table_id").find("tbody").empty();
$.each(data, function (i, e) {
var tr = '';
var rowspan = e.children!=null && e.children.length > 1 ? e.children.length : 1;
var str = '<td rowspan="' + rowspan + '">' + (i + 1) + '</td><td rowspan="' + rowspan + '">' + e.busTypeName + '</td>'
tr += '<tr data-id="' + e.busId + '">' + str
if (e.children!=null && e.children.length > 1){
$.each(e.children, function (j, f) {
var resNumhtml = '0';
if (f.resNum>0) {
var resNum = f.resNum
resNumhtml = '<div><span data-busid="' + f.busId + '" data-flag="" class="layui-table-link view-backed-collectValue" style="color: #1E9FFF;font-size: 14px">'+resNum+'</span></div>';
}
var backedhtml = '0';
if (f.backed>0) {
var backed = f.backed
backedhtml = '<div><span data-busid="' + f.busId + '" data-flag="backed" class="layui-table-link view-backed-collectValue" style="color: green;font-size: 14px">'+backed+'</span></div>';
}
var nobackhtml = '0';
if (f.noback>0) {
var noback = f.noback
nobackhtml = '<div><span data-busid="' + f.busId + '" data-flag="noback" class="layui-table-link view-backed-collectValue" style="color: red;font-size: 14px">'+noback+'</span></div>';
}
var totalSize = (Number(f.totalSize)/1024/1024/1024).toFixed(2);
var phone = f.phone===null?"":f.phone
tr += '<td >' + f.busTypeName + '</td>' +
'<td>' + resNumhtml + '</td>' +
'<td>' + backedhtml+ '</td>' +
'<td>' + nobackhtml + '</td>' +
'<td>' + totalSize + '</td>' +
'<td>' + f.leader + '</td>' +
'<td>' + phone + '</td>' +
'<td>' + e.opUser + '</td>' +
'<td>' + f.lastBackupTime + '</td>' +
'</tr>'
});
}else{
var resNumhtml = '0';
if (e.resNum>0) {
var resNum = e.resNum
resNumhtml = '<div><span data-busid="' + e.busId + '" data-flag="" class="layui-table-link view-backed-collectValue" style="color: #1E9FFF;font-size: 14px">'+resNum+'</span></div>';
}
var backedhtml = '0';
if (e.backed>0) {
var backed = e.backed
backedhtml = '<div><span data-busid="' + e.busId + '" data-flag="backed" class="layui-table-link view-backed-collectValue" style="color: green;font-size: 14px">'+backed+'</span></div>';
}
var nobackhtml = '0';
if (e.noback>0) {
var noback = e.noback
nobackhtml = '<div><span data-busid="' + e.busId + '" data-flag="noback" class="layui-table-link view-backed-collectValue" style="color: red;font-size: 14px">'+noback+'</span></div>';
}
var totalSize = (Number(e.totalSize)/1024/1024/1024).toFixed(2);
var phone = e.phone===null?"":e.phone
tr += '<td>' + e.busTypeName + '</td>' +
'<td>' + resNumhtml + '</td>' +
'<td>' + backedhtml+ '</td>' +
'<td>' + nobackhtml + '</td>' +
'<td>' + totalSize + '</td>' +
'<td>' + e.leader + '</td>' +
'<td>' + phone + '</td>' +
'<td>' + e.opUser + '</td>' +
'<td>' + e.lastBackupTime + '</td>' +
'</tr>'
}
$("#dingjia_table_id").find("tbody").append(tr);
})
$('.view-backed-collectValue').on('click', function () {
var busId = $(this).data("busid");
var flag = $(this).data("flag");
var title = '备份服务器列表'
common.openWin('backup/backDingjiaList', title, {
busId: busId,
flag: flag
}, ['确定', '取消'])
});
}
})
}
// 图表,表格重新加载
function reloadAllChange() {
renderBackupDingjiaListTable();
loadConditionSelect();
}
});
});
\ No newline at end of file
... ...
/** 应急演练 */
layui.define(['table', 'form', 'sessions', 'admin', 'common', 'echarts', 'laydate', 'element'], function (exports) {
var $ = layui.$;
var form = layui.form;
var common = layui.common;
exports('recoverycount', function () {
var sessions = layui.sessions;
var accessToken = localStorage.getItem("accessToken");
var createTime ="year";
var period = new Date().getFullYear().toString();
form.render();
renderrecoverycountListTable();
loadConditionSelect();
$('button[data-period="year"]').click();
// 日期方式选择
$('#btns-recoverycount-time button').on("click",function () {
$.each($("button.date"), function (i, e) {
var $dom = $(e);
if ($dom.hasClass("active")) {
$dom.removeClass("active")
}
})
$("#btns-recoverycount-time button").removeClass("active");
$(this).addClass("active");
createTime = ($(this).data("period"))
if(createTime=='lastYear'){
period = (new Date().getFullYear()-1).toString();
}else {
period = new Date().getFullYear().toString();
}
reloadAllChange();
});
// 回车搜索
$('[lay-filter="form-recoverycount-condition"] input').keydown(function (e) {
if (e.keyCode === 13) {
reloadAllChange();
}
});
// 下拉框改变搜索
form.on('select(slt-recoverycount-biz)', reloadAllChange);
function renderStyle(number){
if(number>0){
return '<div><span style="color: #0BAC33" >'+number+'</span></div>';
}else {
return '<div><span style="color: #aa2222">'+number+'</span></div>';
}
}
function renderIsDiscovery(isRecovery) {
if(isRecovery=="1"){
return '<i class="layui-icon layui-icon-ok" style="font-size: 30px; color: #1dff1c;"></i>';
}else {
return '<i class="layui-icon layui-icon-close" style="font-size: 30px; color: #ff252c;"></i>';
}
}
// 加载设备出入表格
function renderrecoverycountListTable() {
var conditions = form.val('form-recoverycount-condition');
Object.assign(conditions, {
access_token: accessToken,
period: period,
busId: $("#slt-recoverycount-biz").val()
});
var loading = layer.load(2)
var url = common.domainName + '/api-web/recoveryverify/recoveryCount'
$.ajax({
url: url,
type: 'get',
data: conditions,
success: function (res) {
layer.close(loading);
var data = res.data;
$("#recoverycount-table").find("tbody").empty();
$.each(data, function (i, e) {
var tr = '';
var rowspan =e.children!=null && e.children.length > 1 ? e.children.length : 1;
var str = '<td rowspan="' + rowspan + '">' + (i + 1) + '</td><td rowspan="' + rowspan + '">' + e.busTypeName + '</td><td rowspan="' + rowspan + '">'+ e.evaluationLevel + '</td>'
tr += '<tr data-id="' + e.busId + '">' + str
if (e.children!=null && e.children.length > 0){
$.each(e.children, function (j, f) {
tr += '<td >' + f.resName + '</td>' +
'<td>' + f.ip + '</td>' +
'<td>' + renderIsDiscovery(f.isRecovery)+ '</td>' +
'<td>' + renderStyle(f.dece)+ '</td>' +
'<td>' + renderStyle(f.nov) + '</td>' +
'<td>' + renderStyle(f.oct) + '</td>' +
'<td>' + renderStyle(f.sep) + '</td>' +
'<td>' + renderStyle(f.aug) + '</td>' +
'<td>' + renderStyle(f.jul) + '</td>' +
'<td>' + renderStyle(f.jun) + '</td>' +
'<td>' + renderStyle(f.may) + '</td>' +
'<td>' + renderStyle(f.apr) + '</td>' +
'<td>' + renderStyle(f.mar) + '</td>' +
'<td>' + renderStyle(f.feb) + '</td>' +
'<td>' + renderStyle(f.jan) + '</td>' +
'</tr>'
});
}else{
tr += '<td ></td>' +
'<td></td>' +
'<td></td>' +
'<td></td>' +
'<td></td>' +
'<td></td>' +
'<td></td>' +
'<td></td>' +
'<td></td>' +
'<td></td>' +
'<td></td>' +
'<td></td>' +
'<td></td>' +
'<td></td>' +
'</tr>'
}
$("#recoverycount-table").find("tbody").append(tr);
})
}
})
}
// 加载查询条件下拉框
function loadConditionSelect() {
//绑定业务下拉选择数据
common.bizTypeSelect("slt-recoverycount-biz", function () {
form.render("select");
});
}
$("#recoverycount-export-excel").on('click', function () {
let href = common.domainName + '/api-web/recoverycount/export?access_token=' + accessToken + "&createtime=" + createTime + '&dateLimit=' + dateLimit + '&limit=1000';
window.open(href)
})
// 图表,表格重新加载
function reloadAllChange() {
renderrecoverycountListTable();
}
});
});
\ No newline at end of file
... ...
... ... @@ -23,7 +23,7 @@ layui.define(['table', 'form', 'admin', 'layer', 'common', 'commonDetail','sessi
var attachmentIds = []
var id = data.id
var viewType = data && data.viewType ? data.viewType : '';
var busId='';
//渲染表单
form.render(null, 'add-recoveryverify-form')
init()
... ... @@ -189,7 +189,24 @@ layui.define(['table', 'form', 'admin', 'layer', 'common', 'commonDetail','sessi
initViewMode();
}
}
form.on('select(slt-biz-add)', function (data) {
busId = data.value;
//初始化业务下数据库资源
admin.req({
url: domainName + '/api-web/recoveryverify/loadresListforBiz?busId='+busId +'&resType=DATABASE_ORACLE'
}).done(function (response) {
var options = "<option value=''>=选择数据库=</option>";
$.each(response.data, function (i, v) {
options += "<option value='" + v.resId + "'>" + v.resName + "</option>"
});
$('#slt-resId').html(options);
form.render();
});
});
form.on('select(slt-resId)', function (data) {
var databaseName =$("select#slt-resId").find("option:selected").text();
$("input#databaseName").val(databaseName);
})
// 初始化下拉框
function loadSelect() {
admin.req({
... ... @@ -541,7 +558,20 @@ layui.define(['table', 'form', 'admin', 'layer', 'common', 'commonDetail','sessi
}
});
}
form.val('add-recoveryverify-form', res.object);
busId = res.object.bizId;
//初始化业务下数据库资源
admin.req({
url: domainName + '/api-web/recoveryverify/loadresListforBiz?busId='+busId +'&resType=DATABASE_ORACLE'
}).done(function (response) {
var options = "<option value=''>=选择数据库=</option>";
$.each(response.data, function (i, v) {
options += "<option value='" + v.resId + "'>" + v.resName + "</option>"
});
$('#slt-resId').html(options);
form.render();
form.val('add-recoveryverify-form', res.object);
});
if (res.object.attachmentList) {
$.each(res.object.attachmentList, function (i, v) {
writeTagsInfo(v.id, v.originalName)
... ...
<article class="page-container">
<div class="page-panel">
<div class="main">
<div class="layui-card">
<div class="layui-card-header">
</div>
<div class="layui-card-body" >
<div style="display: block;height: 35px">
<button class="layui-btn layui-btn-sm layui-btn-normal active"
id="dingjia-detail-export-excel" style="float: right">
<i class="layui-icon">&#xe60a;</i>导出到Excel
</button>
</div>
<table id="backDingjiaListTable" class="layui-table" lay-filter="backDingjiaListTable">
<thead>
<tr>
<th>序号</th>
<th>资源名称</th>
<th>IP地址</th>
<th>备份等级</th>
<th>备份状态</th>
<th>备份类型</th>
<th>数据量(GB)</th>
<th>速率(MB/s)</th>
<th>上次备份时间</th>
<th>上次完成时间</th>
<th>上次执行结果</th>
<th>下次执行时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</article>
<script>
layui.use('backDingjiaList', function (fn) {
fn({{d}})
});
</script>
\ No newline at end of file
... ...
<style type="text/css">
td input{
width: 70px;
border: 1px;
}
element.style {
}
.layui-table td, .layui-table th {
position: relative;
padding: 9px 15px;
min-height: 20px;
line-height: 20px;
font-size: 14px;
}
.layui-table td, .layui-table th, .layui-table-col-set, .layui-table-fixed-r, .layui-table-grid-down, .layui-table-header, .layui-table-page, .layui-table-tips-main, .layui-table-tool, .layui-table-total, .layui-table-view, .layui-table[lay-skin=line], .layui-table[lay-skin=row] {
border-width: 1px;
border-style: solid;
border-color: #e6e6e6;
}
.layui-table th{
min-width: 35px;
text-align: center;
background-color: cornflowerblue;
}
</style>
<title>服务器备份概况</title>
<article class="page-container template">
<div class="page-panel">
<div class="main" style="background-color: #fff">
<div class="layui-card-header">
<div class="layui-status">
<form class="layui-form layui-card-header" onsubmit="return false"
lay-filter="dingjia-index-form">
<div class="layui-form-item">
<div class="layui-inline">
<div class="layui-input-inline">
<select name="busId" id="slt-dingjia-biz"
lay-filter="slt-dingjia-biz" lay-search>
<option value="">=业务系统=</option>
</select>
</div>
</div>
</div>
</form>
</div>
</div>
<div class="layui-card" style="height: 100%">
<div class="layui-card-body">
<div class="layui-tab layui-tab-card" lay-filter="insp-tab">
<ul class="layui-tab-title">
<button class="layui-btn layui-btn-sm layui-btn-normal tab-button"
id="btn-dingjia-export-excel">
<i class="layui-icon">&#xe60a;</i>导出到Excel
</button>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<div id="dingjia-head-info" class="statistics-top-head"></div>
<table id="dingjia_table_id" class="layui-table">
<thead>
<tr>
<th>序号</th>
<th>系统名称</th>
<th>子系统名称</th>
<th>资源数</th>
<th>已备份</th>
<th>未备份</th>
<th>数据量(GB)</th>
<th>甲方负责人</th>
<th>联系方式</th>
<th>乙方负责人</th>
<th>上次备份时间</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</article>
<script>
layui.use('backupDingjia', function (fn) {
fn();
});
</script>
\ No newline at end of file
... ...
... ... @@ -24,7 +24,7 @@
background-color: cornflowerblue;
}
</style>
<title>资源备份概况</title>
<title>数据库备份概况</title>
<article class="page-container template">
<div class="page-panel">
<div class="main" style="background-color: #fff">
... ... @@ -52,8 +52,12 @@
<div class="layui-card-body">
<div class="layui-tab layui-tab-card" lay-filter="insp-tab">
<ul class="layui-tab-title">
<!--
<li class="layui-this">数据库备份</li>
-->
<!--
<li>虚拟机备份</li>
-->
<button class="layui-btn layui-btn-sm layui-btn-normal tab-button"
id="btn-inspStatistics-export-excel">
<i class="layui-icon">&#xe60a;</i>导出到Excel
... ... @@ -103,4 +107,4 @@
layui.use('backupmain', function (fn) {
fn();
});
</script>
</script>
\ No newline at end of file
... ...
... ... @@ -20,7 +20,10 @@
<label class="layui-form-label"><span
style="color: red;font-size: 16px">*</span>数据库名称</label>
<div class="layui-input-inline">
<input type="text" class="layui-input" name="databaseName" id="databaseName" lay-verify="required">
<input type="text" class="layui-input" name="databaseName" id="databaseName" style="display: none">
<select name="resId" id="slt-resId" lay-verify="required" lay-filter ="slt-resId">
<option value="">=选择数据库=</option>
</select>
</div>
</div>
<div class="layui-inline inline-onethird">
... ...
<title>数据库恢复验证概况</title>
<article class="page-container">
<div class="page-panel ">
<div class="main">
<div class="layui-card">
<div class="layui-card-body" style="margin-top: 10px;">
<div class="layui-btn-group time-group" id="btns-recoverycount-time" style="float: right;">
<button type="button" class="layui-btn layui-btn-primary layui-btn-xs date"
data-period="lastYear">去年
</button>
<button type="button" class="layui-btn layui-btn-primary layui-btn-xs active date"
data-period="year">今年
</button>
</div>
<div style="display: flex">
<form class="layui-form layui-card-header" onsubmit="return false"
lay-filter="form-recoverycount-condition">
<div class="layui-form-item">
<div class="layui-inline">
<div class="layui-input-inline">
<select name="busId" id="slt-recoverycount-biz"
lay-filter="slt-recoverycount-biz" lay-search>
<option value="">=业务系统=</option>
</select>
</div>
<!-- <button class="layui-btn layui-btn-sm layui-btn-normal active"
id="recoverycount-export-excel" style="float: right;">
<i class="layui-icon">&#xe60a;</i>导出到Excel
</button>-->
</div>
</div>
</form>
</div>
<table id="recoverycount-table" class="layui-table" lay-filter="recoverycount-table">
<thead>
<tr>
<th>序号</th>
<th>业务名称</th>
<th>等保等级</th>
<th>数据库名称</th>
<th>IP地址</th>
<th>是否恢复过</th>
<th>12月</th>
<th>11月</th>
<th>10月</th>
<th>9月</th>
<th>8月</th>
<th>7月</th>
<th>6月</th>
<th>5月</th>
<th>4月</th>
<th>3月</th>
<th>2月</th>
<th>1月</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</article>
<script>
layui.use('recoverycount', function (fn) {
fn();
});
</script>
\ No newline at end of file
... ...