Authored by 王涛

Merge branch 'master-v32-ztq' into 'master'

feat: 天津代码迁移(快照管理,快照概览,我的通知)



See merge request !1135
Showing 24 changed files with 2881 additions and 7 deletions
@@ -3859,7 +3859,11 @@ layui.define(['laytpl', 'admin', 'form', 'table', 'echarts', 'sessions', 'xmSele @@ -3859,7 +3859,11 @@ layui.define(['laytpl', 'admin', 'form', 'table', 'echarts', 'sessions', 'xmSele
3859 return; 3859 return;
3860 } 3860 }
3861 //url(/src/style/img/shutdown.png) 3861 //url(/src/style/img/shutdown.png)
3862 - title +=`<span id="title-shutdown" data-id=${resId} style="padding:0 5px;width:600px;display: inline-block;position: relative;top: 0px;left:20px;"></span>` 3862 + title +=`<span id="title-shutdown" data-id=${resId} style="flex:1;padding:0 5px;width:600px;display: inline-block;position: relative;top: 0px;left:20px;"></span>`
  3863 + // ztq 2023-06-01
  3864 + title += `<div style="width:60px;display:flex;justify-content: flex-end"><a class="layui-icon res-view-addSnapshot" data-id=${resId} lay-tips="创建快照" style=" margin:0 10px"> <img width="20" src="/src/style/img/snapshotadd.png" ></a>`;
  3865 + title += `<a class="layui-icon res-view-history" data-id=${resId} data-resname=${res.resName} data-ip=${ip} data-restypename=${res.resTypeName} data-adminname=${res.adminName} lay-tips="快照历史记录" style=""> <img width="20" src="/src/style/img/snapshothistory.png" ></a></div>`;
  3866 +
3863 obj.openNewWin(url, title, params, editFlag, fn, cancelfn, type,sign_); 3867 obj.openNewWin(url, title, params, editFlag, fn, cancelfn, type,sign_);
3864 }, 3868 },
3865 error: function () { 3869 error: function () {
@@ -3870,6 +3874,10 @@ layui.define(['laytpl', 'admin', 'form', 'table', 'echarts', 'sessions', 'xmSele @@ -3870,6 +3874,10 @@ layui.define(['laytpl', 'admin', 'form', 'table', 'echarts', 'sessions', 'xmSele
3870 title += `<a class="layui-icon layui-icon-rate" data-id=${resId} lay-tips="加入收藏夹"></a>`; 3874 title += `<a class="layui-icon layui-icon-rate" data-id=${resId} lay-tips="加入收藏夹"></a>`;
3871 title += `<a class="layui-icon filterList" data-id=${resId} lay-tips="指标过滤清单" style="margin-left: 10px"><i class="iconfont">&#XE516;</i></a>`; 3875 title += `<a class="layui-icon filterList" data-id=${resId} lay-tips="指标过滤清单" style="margin-left: 10px"><i class="iconfont">&#XE516;</i></a>`;
3872 title += `<a class="layui-icon res-view-relation-topo" data-id=${resId} lay-tips="查看资源关系拓扑" style="margin-left: 10px"><i class="iconfont">&#XE515;</i></a>`; 3876 title += `<a class="layui-icon res-view-relation-topo" data-id=${resId} lay-tips="查看资源关系拓扑" style="margin-left: 10px"><i class="iconfont">&#XE515;</i></a>`;
  3877 + // ztq 23-06-01
  3878 + title += `<a class="layui-icon res-view-ping" data-id=${resId} data-resname=${res.resName} data-ip=${ip} data-restypename=${res.resTypeName} data-adminname=${res.adminName} lay-tips="历史数据" style="margin-left: 10px;position:relative;top:-3px;"> <img width="20" src="./src/style/img/ping.png" ></a>`;
  3879 + title += `<div style="width:60px;display:flex;justify-content: flex-end"><a class="layui-icon res-view-addSnapshot" data-id=${resId} lay-tips="创建快照" style=" margin: 0 10px"> <img width="20" src="./src/style/img/snapshotadd.png" ></a>`;
  3880 + title += `<a class="layui-icon res-view-history" data-id=${resId} data-resname=${res.resName} data-ip=${ip} data-restypename=${res.resTypeName} data-adminname=${res.adminName} lay-tips="快照历史记录" style=""> <img width="20" src="./src/style/img/snapshothistory.png" ></a></div>`;
3873 if (resCategory === 'share' && hardwareFlag.endsWith("Y")) { 3881 if (resCategory === 'share' && hardwareFlag.endsWith("Y")) {
3874 title += `<a class="layui-icon res-view-assets-details" data-ip=${ip} data-name=${name} data-restype=${resType} data-id=${resId} lay-tips="资产配置信息"><i class="iconfont">&#XE517;</i></a>`; 3882 title += `<a class="layui-icon res-view-assets-details" data-ip=${ip} data-name=${name} data-restype=${resType} data-id=${resId} lay-tips="资产配置信息"><i class="iconfont">&#XE517;</i></a>`;
3875 } 3883 }
@@ -3921,7 +3929,7 @@ layui.define(['laytpl', 'admin', 'form', 'table', 'echarts', 'sessions', 'xmSele @@ -3921,7 +3929,7 @@ layui.define(['laytpl', 'admin', 'form', 'table', 'echarts', 'sessions', 'xmSele
3921 obj.loadResAlarm(params.resId); 3929 obj.loadResAlarm(params.resId);
3922 view('commonViewModel').render(url).then(function (res) { 3930 view('commonViewModel').render(url).then(function (res) {
3923 layer.open({ 3931 layer.open({
3924 - title: [name, 'font-size:20px;background-color: #d0ddec;'], 3932 + title: [name, 'font-size:20px;background-color: #d0ddec;display:flex;align-items: center; justify-content: flex-start;'],
3925 type: 1, 3933 type: 1,
3926 id: md5(url), 3934 id: md5(url),
3927 area: area , 3935 area: area ,
@@ -4129,6 +4137,43 @@ layui.define(['laytpl', 'admin', 'form', 'table', 'echarts', 'sessions', 'xmSele @@ -4129,6 +4137,43 @@ layui.define(['laytpl', 'admin', 'form', 'table', 'echarts', 'sessions', 'xmSele
4129 // layer.close(detailTips); 4137 // layer.close(detailTips);
4130 // } 4138 // }
4131 // }) 4139 // })
  4140 +
  4141 + // ztq 23-06-01
  4142 + $('a.res-view-addSnapshot').unbind('click').on('click', function () {
  4143 + var resId = $(this).data('id');
  4144 + layer.confirm('将创建该资源的所有快照信息,请确认', {
  4145 + btn: ['确定', '取消'] //按钮
  4146 + }, function () {
  4147 + admin.req({
  4148 + url: common.domainName + '/api-web/snapshot/his/add?access_token=' + layui.sessions.getToken().access_token +'&resId=' + resId
  4149 + , type: 'get'
  4150 + , done: function (res) {
  4151 + if (res.success) {
  4152 + layer.msg('操作成功!', {offset: '15px', icon: 1, time: 2000});
  4153 + } else {
  4154 + layer.msg(res.msg, {offset: '15px', icon: 7, time: 2000});
  4155 + }
  4156 + }
  4157 + });
  4158 + });
  4159 + });
  4160 + $('a.res-view-history').unbind('click').on('click', function () {
  4161 + let name = $(this).data('resname')+' |'+$(this).data('restypename')+' |'+$(this).data('ip')+' |'+'历史快照数据';
  4162 + let paramStr = '?resId=' + $(this).data('id');
  4163 + layer.open({
  4164 + title: [name, 'font-size:18px;'],
  4165 + type: 2,
  4166 + area: ['65%', '90%'],
  4167 + shadeClose: true,//开启遮罩层
  4168 + id: 'res-history',
  4169 + content: ['/vue3/index.html#/vue3/snapshot/history' + paramStr, 'no'],
  4170 + cancel: function () {
  4171 + clearTimeout();
  4172 + }
  4173 + });
  4174 + });
  4175 +
  4176 +
4132 //start lsq 增加停机状态跑马灯效果 2022-05-24 4177 //start lsq 增加停机状态跑马灯效果 2022-05-24
4133 let resId= $('#title-shutdown').data("id"); 4178 let resId= $('#title-shutdown').data("id");
4134 admin.req({ 4179 admin.req({
  1 +//通知查询
  2 +layui.define(['table', 'form', 'admin', 'layer', 'common','sessions', 'xmSelect', 'echarts','laydate'], function (exports) {
  3 + var $ = layui.$;
  4 + var form = layui.form;
  5 + var layer = layui.layer;
  6 + var admin = layui.admin;
  7 + var table = layui.table;
  8 + var common = layui.common;
  9 + var domainName = common.domainName;
  10 + var xmSelect = layui.xmSelect;
  11 + var echarts = layui.echarts;
  12 + var laydate = layui.laydate;
  13 +
  14 + //对外暴露的接口
  15 + exports('myNoticeIndex', function (data) {
  16 + var resTypeSelect = {}; //资源类型下拉框
  17 + var busIdSelect = {}; //业务类型下拉框
  18 + var userSelect = {}; //通知用户下拉框
  19 + var busId = '';
  20 + var resType = '';
  21 + var userNames = '';
  22 + var sessions = layui.sessions;
  23 + var accessToken = sessions.getToken()['access_token'];
  24 + var noticeUserChart = echarts.init(document.getElementById('my_notice_chart_user'));
  25 + var noticeTypeChart = echarts.init(document.getElementById('my_notice_chart_type'));
  26 + // var noticeUserChartNew = echarts.init(document.getElementById('my_notice_chart_user_new'));
  27 + // lsq 告警指标 2022-07-05
  28 + var alarmKpi= '';
  29 + //回车搜索
  30 + $('#notice_search_keyword').keydown(function (e) {
  31 + if (e.keyCode === 13) {
  32 + reloadData();
  33 + }
  34 + });
  35 + //查询按钮点击事件
  36 + $('#noticeSearchQueryBtn').on('click',function () {
  37 + reloadData();
  38 + })
  39 +
  40 + //发送状态
  41 + form.on('select(notice_search_isSend)', function(){
  42 + reloadData();
  43 + });
  44 +
  45 + $('#queryMore').on('click',function(){
  46 + queryData();
  47 + });
  48 +
  49 + $('button[data-period]').on('click',function(){
  50 + var that = $(this);
  51 + that.addClass('active');
  52 + that.removeClass('layui-btn-primary');
  53 + var currentVal = that.attr('data-period');
  54 + $.each($('button[data-period]'), function(index , el){
  55 + var itemEl = $(el);
  56 + var val = itemEl.attr('data-period');
  57 + if(currentVal != val){
  58 + itemEl.addClass('layui-btn-primary');
  59 + itemEl.removeClass('active');
  60 + }
  61 + });
  62 +
  63 + // yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm:ss
  64 + if(currentVal == 'custom'){
  65 + laydate.render({
  66 + elem: '#dataPeriodCustom', //指定元素
  67 + range: true,
  68 + type: 'datetime',
  69 + isInitValue: false,
  70 + isPreview: false,
  71 + value : new Date(),
  72 + format:'yyyy-MM-dd HH:mm:ss',
  73 + show: true, //直接显示
  74 + done: function(value, date, endDate){
  75 + that.attr('data-val',value);
  76 + reloadData();
  77 + }
  78 + });
  79 + return;
  80 + }
  81 + reloadData();
  82 + });
  83 +
  84 +
  85 +
  86 + form.render();
  87 +
  88 + getChartData();
  89 + //渲染表格
  90 + var noticeTable = table.render({
  91 + elem: '#myNoticeSearchTable'
  92 + , url: domainName + '/api-web/notice/myPage'
  93 + , where:{
  94 + access_token:accessToken,
  95 + keyword: $('#notice_search_keyword').val(),
  96 + busId: busId,
  97 + resType: resType,
  98 + usernames:userNames,
  99 + isSend: $('#notice_search_isSend').val(),
  100 + alarmKpi: $("#myNoticeAlarmKpiSearchBox").val(),
  101 + way:$('#myNoticeWaySearchBox').val(),
  102 + dataPeriod: $('button[data-period].active').attr('data-period'),
  103 + timeRange: $('button[data-period].active').attr('data-val')
  104 + }
  105 + , height: 'full-380'
  106 + , page: {
  107 + layout: ['count', 'prev', 'page', 'next', 'limit', 'skip']
  108 + ,theme: '#1E9FFF'//自定义分页主题颜色
  109 + }
  110 + , end: function(e){
  111 + form.render();
  112 + }
  113 + , even: true
  114 + , cols: [[
  115 + {title: '序号', align: "center", type: 'numbers',width: '3%'}
  116 + , {field: 'typeName', title: '通知类型', align: 'center', sort: true, width:130}
  117 + , {field: 'way', title: '通知方式', align: 'center', sort: true, width:120,
  118 + templet: function (d){
  119 + switch (d.way){
  120 + case 'wechat':
  121 + return '<div class="small-icon small-icon-wechat"></div>'
  122 + break;
  123 + case 'email':
  124 + return '<div class="small-icon small-icon-email"></div>'
  125 + break;
  126 + case 'message':
  127 + return '<div class="small-icon small-icon-msg"></div>'
  128 + break;
  129 + default:
  130 + return '<div class="small-icon small-icon-msg"></div>'
  131 + break;
  132 +
  133 + }
  134 + }}
  135 + // , {field: 'targetId', title: '通知对象', align: 'center', sort: true, width:180}
  136 + , {field: 'content', title: '通知内容', align: 'left', sort: true, minWidth: 300,}
  137 + , {field: 'nickname', title: '通知用户', align: 'center', sort: true, width:200}
  138 + , {field: 'noticeTime', title: '通知时间', align: 'center', sort: true, width:180}
  139 + // , {field: 'createTime',title: '入库时间',align: 'center', sort: true,width:180}
  140 + , {title: '操作', align: 'center',width: 80,fixed: 'right',
  141 + templet: function (d) {
  142 + var str = '';
  143 + if (d.ipAddr && d.ipAddr !== '') {
  144 + str += `ip地址 ${d.ipAddr}</br>`
  145 + }
  146 + if (d.resName && d.resName !== '') {
  147 + str += `资源名称 ${d.resName}</br>`
  148 + }
  149 + if (d.busName && d.busName !== '') {
  150 + str += `业务名称 ${d.busName}</br>`
  151 + }
  152 + if (d.kpiName && d.kpiName !== '') {
  153 + str += `指标名称 ${d.kpiName}</br>`
  154 + }
  155 + if (d.reportType && d.reportType !== '') {
  156 + str += `报表类型 ${d.reportType}</br>`
  157 + }
  158 + if (d.alarmTimes && d.alarmTimes !== '') {
  159 + str += `告警次数 ${d.alarmTimes}</br>`
  160 + }
  161 + if (str.trim() !== '') {
  162 + return `<div><button lay-tips="${str}" type="button" class="layui-btn layui-btn-xs layui-btn-normal"><i class="layui-icon layui-icon-star-fill"></i></button></div>`
  163 + } else {
  164 + return `<div><button type="button" class="layui-btn layui-btn-xs layui-btn-normal"><i class="layui-icon layui-icon-star-fill"></i></button></div>`
  165 +
  166 + }
  167 + }
  168 + }
  169 + ]],
  170 + done:function () {
  171 +
  172 + }
  173 + });
  174 + //用户下拉框 joke add 20211209
  175 + /*$.ajax({
  176 + url: `${common.domainName}/api-web/notice/getNoticeUsers?access_token=${accessToken}`,
  177 + method: 'GET',
  178 + success: function (response) {
  179 + if (response && response.success){
  180 + userSelect = xmSelect.render({
  181 + el: '#notice_user_list',
  182 + name: 'users',
  183 + tips: '=接收人=',
  184 + //开启搜索
  185 + filterable: true,
  186 + radio: true,
  187 + clickClose: true,
  188 + height: '170px',
  189 + tree: {
  190 + show: true,
  191 + showFolderIcon: true,
  192 + showLine: true,
  193 + strict: false,
  194 + indent: 20
  195 + },
  196 + model: {
  197 + label: {
  198 + type: 'text'
  199 + }
  200 + },
  201 + prop: {
  202 + name: 'nickname',
  203 + value: 'username'
  204 + },
  205 + data: response.data,
  206 + on: function (data) {
  207 + if (data.arr && data.arr.length > 0){
  208 + userNames = data.arr[0].username;
  209 + } else {
  210 + userNames = '';
  211 + }
  212 + reloadData();
  213 + }
  214 + });
  215 + }else{
  216 + layer.msg('获取资源类型失败', {icon: 2});
  217 + }
  218 + if(userSelect){
  219 + //追加样式
  220 + $('#notice_user_list').find('.xm-body').eq(0).css("width","230px");
  221 + }
  222 + }
  223 + });*/
  224 +
  225 + //绑定业务下拉选择数据 joke add 20211209
  226 + admin.req({
  227 + url: domainName + '/api-web/notice/getNoticeBusTypes',
  228 + success: function (response) {
  229 + if (response && response.success) {
  230 + var busTypeList = response.data;
  231 + // 影响业务下拉框
  232 + busIdSelect = xmSelect.render({
  233 + el: '#my_notice_search_busId',
  234 + name: 'bizId',
  235 + tips: '=业务类型=',
  236 + //开启搜索
  237 + filterable: true,
  238 + radio: true,
  239 + clickClose: true,
  240 + height: '170px',
  241 + tree: {
  242 + show: true,
  243 + showFolderIcon: true,
  244 + showLine: true,
  245 + strict: false,
  246 + indent: 20
  247 + },
  248 + model: {
  249 + label: {
  250 + type: 'text'
  251 + }
  252 + },
  253 + prop: {
  254 + name: 'busTypeName',
  255 + value: 'busId'
  256 + },
  257 + data: busTypeList,
  258 + on: function (data) {
  259 + if (data.isAdd){
  260 + busId = data.arr[0].busId;
  261 + } else {
  262 + busId = '';
  263 + }
  264 + reloadData();
  265 + }
  266 + });
  267 + if(busIdSelect){
  268 + //追加样式
  269 + $('#my_notice_search_busId').find('.xm-body').eq(0).css("width","230px");
  270 + }
  271 + } else {
  272 + layer.msg('获取业务失败', {icon: 2});
  273 + }
  274 + },
  275 + error: function () {
  276 + layer.msg('获取业务失败', {icon: 2});
  277 + }
  278 + });
  279 + //资源类型下拉框 joke add 20211209
  280 + $.ajax({
  281 + url: `${common.domainName}/api-web/notice/getNoticeResTypes?access_token=${accessToken}`,
  282 + method: 'GET',
  283 + success: function (res) {
  284 + // 资源类型下拉框
  285 + if (res && res.success){
  286 + var resTypeList = res.data;
  287 + resTypeSelect = xmSelect.render({
  288 + el: '#my_notice_search_resType',
  289 + name: "resType",
  290 + tips: '=资源类型=',
  291 + filterable: true,
  292 + radio: true,
  293 + clickClose: true,
  294 + prop: {
  295 + name: 'resTypeName',
  296 + value: 'resTypeCode'
  297 + },
  298 + tree: {
  299 + show: true,
  300 + showFolderIcon: true,
  301 + showLine: true,
  302 + strict: false,
  303 + indent: 20
  304 + },
  305 + model: {
  306 + label: {
  307 + type: 'text'
  308 + }
  309 + },
  310 + height: '170px',
  311 + data: resTypeList,
  312 + on: function (data) {
  313 + if (data.isAdd){
  314 + resType = data.arr[0].resTypeCode;
  315 + } else {
  316 + resType = '';
  317 + }
  318 + reloadData();
  319 + }
  320 + });
  321 + if(busIdSelect){
  322 + //追加样式
  323 + $('#my_notice_search_resType').find('.xm-body').eq(0).css("width","230px");
  324 + }
  325 + }else{
  326 + layer.msg('获取资源类型失败', {icon: 2});
  327 + }
  328 +
  329 + }
  330 + });
  331 + // lsq 告警指标下拉列表 2022-07-05
  332 + $.ajax({
  333 + url: common.domainName + '/api-web/manage/kpi/findKpiInAlarm?access_token='+accessToken+'&tableName=b_alarm',
  334 + type: "get",
  335 + success:function (res) {
  336 + var kpis = res.data;
  337 + var html = '<option value="">=指标名称=</option>'
  338 + $.each(kpis,function (i,e) {
  339 + html+='<option value="'+e.kpiId+'">'+e.kpiName+'</option>'
  340 + })
  341 + $("#myNoticeAlarmKpiSearchBox").html('');
  342 + $("#myNoticeAlarmKpiSearchBox").append(html);
  343 + form.render();
  344 + }
  345 + })
  346 + //lsq 通知方式下拉列表 2022-07-07
  347 + $.ajax({
  348 + url: domainName + '/api-web/manage/ddic/findSucDdics/notice_type?access_token='+accessToken,
  349 + type: "POST",
  350 + success:function (res) {
  351 + var ways = res.data;
  352 + var html = '<option value="">=通知方式=</option>'
  353 + $.each(ways,function (i,e) {
  354 + html+='<option value="'+e.ddicCode+'">'+e.ddicName+'</option>'
  355 + })
  356 + $("#myNoticeWaySearchBox").html('');
  357 + $("#myNoticeWaySearchBox").append(html);
  358 + form.render();
  359 + }
  360 + })
  361 +
  362 + //刷新表格
  363 + function reloadTable() {
  364 + noticeTable.reload({
  365 + page: {
  366 + curr: 1
  367 + },
  368 + where:{
  369 + access_token:accessToken,
  370 + keyword: $('#notice_search_keyword').val(),
  371 + busId: busId,
  372 + resType: resType,
  373 + isSend: $('#notice_search_isSend').val(),
  374 + usernames:userNames,
  375 + page: 1,
  376 + alarmKpi: $("#myNoticeAlarmKpiSearchBox").val(),
  377 + way:$('#myNoticeWaySearchBox').val(),
  378 + dataPeriod: $('button[data-period].active').attr('data-period'),
  379 + timeRange: $('button[data-period].active').attr('data-val')
  380 + }
  381 + });
  382 + }
  383 +
  384 + //未读人员
  385 + function loadNoticeChart(echartObject,xData,yData) {
  386 + var series = [{
  387 + name: '通知次数',
  388 + data: yData,
  389 + barWidth: 20,
  390 + type: 'bar',
  391 + label: {
  392 + show: true,
  393 + position: 'top',
  394 + textStyle: {
  395 + color: '#555'
  396 + },
  397 + },
  398 + itemStyle: {
  399 + normal: {
  400 + color: (params) => {
  401 + var colors = ['#b6c2ff', '#96edc1', '#fcb75b'];
  402 + return colors[params.dataIndex % 3]
  403 + }
  404 + }
  405 + },
  406 + emphasis: {
  407 + itemStyle: {
  408 + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  409 + { offset: 0, color: '#2378f7' },
  410 + { offset: 0.7, color: '#2378f7' },
  411 + { offset: 1, color: '#83bff6' }
  412 + ])
  413 + }
  414 + },
  415 + }]
  416 +
  417 + var option = {
  418 + tooltip: {
  419 + trigger: 'axis',
  420 + axisPointer: {
  421 + type: 'shadow'
  422 + }
  423 + },
  424 + grid: [{
  425 + top: 20,
  426 + bottom: 45,
  427 + left: 40,
  428 + right: 5
  429 + }],
  430 + xAxis: [{
  431 + type: 'category',
  432 + data: xData,
  433 + axisLabel: {
  434 + color: '#333',
  435 + show: true,
  436 + interval:0,
  437 + rotate:15
  438 + },
  439 + axisLine: {
  440 + lineStyle: {
  441 + color: '#e7e7e7'
  442 + }
  443 + },
  444 + axisTick: {
  445 + lineStyle: {
  446 + color: '#e7e7e7'
  447 + }
  448 + },
  449 + zlevel: 1
  450 + }],
  451 + yAxis: [{
  452 + type: 'value',
  453 + gridIndex: 0,
  454 + axisLabel: {
  455 + color: '#333'
  456 + },
  457 + splitLine: {
  458 + lineStyle: {
  459 + type: 'dashed'
  460 + }
  461 + },
  462 + axisLine: {
  463 + lineStyle: {
  464 + color: '#ccc'
  465 + }
  466 + },
  467 + axisTick: {
  468 + lineStyle: {
  469 + color: '#ccc'
  470 + }
  471 + }
  472 + }],
  473 + series: series,
  474 + dataZoom: [
  475 + {
  476 + type: 'inside'
  477 + }
  478 + ],
  479 + }
  480 + echartObject.setOption(option)
  481 + const zoomSize = 6;
  482 + echartObject.on('click', function (params) {
  483 + echartObject.dispatchAction({
  484 + type: 'dataZoom',
  485 + startValue: xData[Math.max(params.dataIndex - zoomSize / 2, 0)],
  486 + endValue:
  487 + xData[Math.min(params.dataIndex + zoomSize / 2, yData.length - 1)]
  488 + });
  489 + });
  490 + }
  491 + /********************单独加载更多****************************/
  492 + function loadNoticeMoreChart(echartObject,xData,yData) {
  493 + var series = [{
  494 + name: '通知次数',
  495 + data: yData,
  496 + barWidth: 20,
  497 + type: 'bar',
  498 + label: {
  499 + show: true,
  500 + position: 'top',
  501 + textStyle: {
  502 + color: '#555'
  503 + },
  504 + },
  505 + itemStyle: {
  506 + normal: {
  507 + color: (params) => {
  508 + var colors = ['#b6c2ff', '#96edc1', '#fcb75b'];
  509 + return colors[params.dataIndex % 3]
  510 + }
  511 + }
  512 + },
  513 + emphasis: {
  514 + itemStyle: {
  515 + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  516 + { offset: 0, color: '#2378f7' },
  517 + { offset: 0.7, color: '#2378f7' },
  518 + { offset: 1, color: '#83bff6' }
  519 + ])
  520 + }
  521 + },
  522 + }]
  523 +
  524 + var option = {
  525 + tooltip: {
  526 + trigger: 'axis',
  527 + axisPointer: {
  528 + type: 'shadow'
  529 + }
  530 + },
  531 + grid: [{
  532 + top: 20,
  533 + bottom: 70,
  534 + left: 30,
  535 + right: 5
  536 + }],
  537 + xAxis: [{
  538 + type: 'category',
  539 + data: xData,
  540 + axisLabel: {
  541 + color: '#333',
  542 + show: true,
  543 + interval:0,
  544 + rotate:15
  545 + },
  546 + axisLine: {
  547 + lineStyle: {
  548 + color: '#e7e7e7'
  549 + }
  550 + },
  551 + axisTick: {
  552 + lineStyle: {
  553 + color: '#e7e7e7'
  554 + }
  555 + },
  556 + zlevel: 1
  557 + }],
  558 + yAxis: [{
  559 + type: 'value',
  560 + gridIndex: 0,
  561 + axisLabel: {
  562 + color: '#333'
  563 + },
  564 + splitLine: {
  565 + lineStyle: {
  566 + type: 'dashed'
  567 + }
  568 + },
  569 + axisLine: {
  570 + lineStyle: {
  571 + color: '#ccc'
  572 + }
  573 + },
  574 + axisTick: {
  575 + lineStyle: {
  576 + color: '#ccc'
  577 + }
  578 + }
  579 + }],
  580 + series: series,
  581 + dataZoom: [
  582 + { type: 'slider',
  583 + show: true,
  584 + xAxisIndex: [0],
  585 + left: '1%',
  586 + bottom: -5,
  587 + start: 0,
  588 + end: 20 //初始化滚动条
  589 + }
  590 + ],
  591 + }
  592 + echartObject.setOption(option)
  593 + window.onresize=function(){
  594 + echartObject.resize();
  595 + }
  596 + // const zoomSize = 6;
  597 + // echartObject.on('click', function (params) {
  598 + // echartObject.dispatchAction({
  599 + // type: 'dataZoom',
  600 + // startValue: xData[Math.max(params.dataIndex - zoomSize / 2, 0)],
  601 + // endValue:
  602 + // xData[Math.min(params.dataIndex + zoomSize / 2, yData.length - 1)]
  603 + // });
  604 + // });
  605 + }
  606 + //获取图表数据
  607 + function getChartData() {
  608 + var where = {
  609 + access_token:accessToken,
  610 + keyword: $('#notice_search_keyword').val(),
  611 + busId: busId,
  612 + resType: resType,
  613 + isSend: $('#notice_search_isSend').val(),
  614 + alarmKpi: $("#myNoticeAlarmKpiSearchBox").val(),
  615 + way:$('#myNoticeWaySearchBox').val(),
  616 + dataPeriod: $('button[data-period].active').attr('data-period'),
  617 + timeRange: $('button[data-period].active').attr('data-val')
  618 + };
  619 +
  620 + $.ajax({
  621 + url: `${common.domainName}/api-web/notice/myGroupByType`,
  622 + method: 'GET',
  623 + data: where,
  624 + success: function (res) {
  625 + var xData = [];
  626 + var yData = [];
  627 + if (res && res.map) {
  628 + $.each(res.map.typeList,function (i,v) {
  629 + xData.push(v)
  630 + })
  631 + yData = res.map.countList;
  632 + }
  633 + loadNoticeChart(noticeTypeChart,xData,yData)
  634 + }
  635 + })
  636 +
  637 + $.ajax({
  638 + url: `${common.domainName}/api-web/notice/myGroupByUser`,
  639 + method: 'GET',
  640 + data: where,
  641 + success: function (res) {
  642 + if (res && res.data) {
  643 + var yData = res.data.map(item=>item.count);
  644 + var xData = res.data.map(item=>item.noticeTime);
  645 + //展示前20条数据 @Editor LH
  646 + loadNoticeChart(noticeUserChart,xData.slice(0, 15), yData.slice(0, 15));
  647 + }
  648 + }
  649 + })
  650 + }
  651 +
  652 + function reloadData(){
  653 + getChartData();
  654 + reloadTable();
  655 + }
  656 + function queryData(){
  657 + var $content = $('#more_info');
  658 + layer.open({
  659 + type: 1
  660 + , title: '人员分组统计' //不显示标题栏
  661 + , area: ["91%", "500px"]
  662 + , id: 'aaa' //设定一个id,防止重复弹出
  663 + , btn:['取消']
  664 + , content: $content.html()
  665 + , success: function (layero, index) {
  666 + var where = {
  667 + access_token:accessToken,
  668 + keyword: $('#notice_search_keyword').val(),
  669 + busId: busId,
  670 + resType: resType,
  671 + isSend: $('#notice_search_isSend').val(),
  672 + alarmKpi: $("#myNoticeAlarmKpiSearchBox").val(),
  673 + way:$('#myNoticeWaySearchBox').val(),
  674 + dataPeriod: $('button[data-period].active').attr('data-period'),
  675 + timeRange: $('button[data-period].active').attr('data-val')
  676 + };
  677 + var noticeTypeChartNew = echarts.init(document.getElementById('my_notice_chart_type_new'));
  678 + $.ajax({
  679 + url: `${common.domainName}/api-web/notice/myGroupByUser`,
  680 + method: 'GET',
  681 + data: where,
  682 + success: function (res) {
  683 + if (res && res.data) {
  684 + var yData = res.data.map(item=>item.count);
  685 + var xData = res.data.map(item=>item.noticeTime);
  686 + //展示前20条数据 @Editor LH
  687 + loadNoticeMoreChart(noticeTypeChartNew,xData, yData);
  688 + }
  689 + }
  690 + })
  691 + }
  692 + , yes: function (index, layero) {
  693 + layer.close(index); //执行关闭
  694 + // if (fn && fn()) {
  695 + // fn()
  696 + // layer.close(index); //如果设定了yes回调,需进行手工关闭
  697 + // }
  698 + }
  699 + });
  700 + }
  701 + });
  702 +});
  1 +layui.define(['commonDetail', 'common', 'sessions'], function (exports) {
  2 + var commonDetail = layui.commonDetail;
  3 + var $ = layui.$
  4 + , laytpl = layui.laytpl
  5 + //对外暴露的接口
  6 + exports('snapshot_detail', function (data) {
  7 + var common = layui.common;
  8 + var sessions = layui.sessions;
  9 + var table = layui.table;
  10 + var view = layui.view;
  11 + var laytpl = layui.laytpl;
  12 + var resId = '';
  13 + var batchNo = '';
  14 + var showFlag = common.getUrlParam("show");
  15 + if (showFlag && showFlag == '0') {
  16 + resId = common.getUrlParam("resId");
  17 + batchNo = common.getUrlParam("batchNo");
  18 + } else {
  19 + resId = data.resId;
  20 + batchNo = data.batchNo;
  21 + }
  22 + findAllSnapshot();
  23 +
  24 + commonDetail.bindTips();
  25 +
  26 + function findAllSnapshot() {
  27 + // 删除所有的子元素
  28 + $('#table_arr_body').empty();
  29 + let url = common.domainName + '/api-web/snapshot/info?resId='+ resId + '&batchNo='+batchNo +'&access_token='+sessions.getToken().access_token;
  30 + $.ajax({
  31 + url: url,
  32 + type: 'get',
  33 + async: false,
  34 + success: function (res) {
  35 + if (res.success){
  36 + if (res.object.snapshotResState){
  37 + commonDetail.snapshotRenderResHealth(res.object.snapshotResState);
  38 + }
  39 + commonDetail.anapshotRenderTextCols('hostminicomputerpartition_jbxx',res.object.snapshotBaseInformationList,2);
  40 + if (res.object.importantInformationList != null && res.object.importantInformationList.length > 0){
  41 + commonDetail.anapshotRenderTextCols('hostminicomputerpartition_sysfile',res.object.importantInformationList,2);
  42 + }else {
  43 + $("#hostminicomputerpartition_sysfile").html('<div style="text-align:center;"><span style="line-height: 150px; padding:20px;font-style:normal;">暂无数据</span></div>')
  44 + }
  45 + commonDetail.snapshotRenderActiveAlarms("告警列表","snapshow_active_alram", res.object.snapshotAlamList);
  46 + console.log(res.object.snapshotRecordList);
  47 + let tableArr = res.object.snapshotRecordList;
  48 + let domTableArr='';
  49 + // 渲染生成节点
  50 + tableArr.forEach((item,index)=>{
  51 + domTableArr+=`
  52 + <div class="lay-row">
  53 + <div class="lay-row-item">
  54 + <h5 class="lay-row-title">${item.name}
  55 + <span class="layui-table-link" id="snapshot_wkinfoDownload_${index}"
  56 + style="margin-left: 10px;">下载</span>
  57 + <span class="layui-table-link" id="snapshot_wkinfoMore_${index}">更多</span>
  58 + </h5>
  59 + <div id="snapshot_wkinfo_${index}"></div>
  60 + </div>
  61 + </div>
  62 + `
  63 + })
  64 + // console.log(domTableArr);
  65 + $('#table_arr_body').append(domTableArr)
  66 +
  67 + // 渲染节点表格数据
  68 + tableArr.forEach((item,index)=>{
  69 + let cols = [];
  70 + let datas = [];
  71 + item.header.map((headerItem,headerIndex)=>{
  72 + if (headerItem.unit){
  73 + cols.push({
  74 + field:headerItem.id,title:headerItem.name+'('+headerItem.unit+')',sort:true,align:"center",
  75 + })
  76 + }else {
  77 + cols.push({
  78 + field:headerItem.id,title:headerItem.name,sort:true,align:"center",
  79 + })
  80 + }
  81 + })
  82 + item.content.map((contItem,contIndex)=>{
  83 + let obj = {};
  84 + contItem.map((v,i)=>{
  85 + obj[v.kpiId] = v.kpiValue
  86 + })
  87 + datas.push(obj)
  88 + })
  89 +
  90 + /*console.log('cols--------------',cols);
  91 + console.log('datas--------------',datas);*/
  92 + // 创建渲染实例
  93 + table.render({
  94 + elem: `#snapshot_wkinfo_${index}`
  95 + ,page: false
  96 + ,data: datas
  97 + ,cols: [cols]
  98 + ,done(response, curr, count){
  99 + delete response.data[0].LAY_TABLE_INDEX //
  100 + let keys = response.data[0]
  101 + let params = {
  102 + kpiId:Object.keys(keys).join(','),
  103 + resId:resId,
  104 + batchNo:batchNo,
  105 + tableName:item.name,
  106 + flagPrefix:item.flagPrefix
  107 + }
  108 + // 点击下载的方法
  109 + $(`#snapshot_wkinfoDownload_${index}`).unbind('click').on('click',()=>{
  110 + let url = `${common.domainName}/api-web/snapshot/info/download?kpiId=${params.kpiId}&resId=${params.resId}&batchNo=${params.batchNo}&tableName=${params.tableName}&flagPrefix=${params.flagPrefix}&access_token=${sessions.getToken().access_token}`
  111 + window.open(url)
  112 + })
  113 + // 点击更多的方法
  114 + $(`#snapshot_wkinfoMore_${index}`).unbind('click').on('click',()=>{
  115 + view('commonViewModel').render("template/detail/snapshot_detail_more").then(function (res) {
  116 + layer.open({
  117 + title: ["更多", 'font-size:18px;'],
  118 + type: 1,
  119 + shadeClose: true,//开启遮罩层
  120 + area: ['90%', '690px'],
  121 + content: laytpl(res.body).render(JSON.stringify(params))
  122 + });
  123 + });
  124 + })
  125 + }
  126 + ,error(){
  127 +
  128 + }
  129 + })
  130 + })
  131 + }else {
  132 + layer.msg(res.msg, {
  133 + icon: 7, time: 2000
  134 + });
  135 + }
  136 + }
  137 + })
  138 + }
  139 +
  140 +
  141 +
  142 + //定时任务
  143 + // var timer = setInterval(function () {
  144 + // findAllSnapshot()
  145 + // }, commonDetail.timerTime);
  146 + // commonDetail.detailTimer.push(timer);
  147 +
  148 + });
  149 +});
  1 +<style>
  2 + .layui-card-echart .lay-row-title {
  3 + font-size: 14px;
  4 + line-height: 2;
  5 + padding: 2px 10px;
  6 + background: #f6f6f6;
  7 + margin: 0px 3px;
  8 + /*display: block;*/
  9 + /*float: left;*/
  10 +
  11 + }
  12 +</style>
  13 +
  14 +
  15 +<title>我的通知</title>
  16 +<article class="page-container">
  17 + <div class="page-panel">
  18 + <div class="main">
  19 + <div class="layui-card" style="overflow: hidden">
  20 + <div class="layui-card-header" style=" padding: 0 3px;">
  21 + <div class="layui-status search_panel">
  22 + <form style="padding:5px 0 0 0;" class="layui-form layui-card-header layuiadmin-card-header-auto" lay-filter="notice_search_form">
  23 + <div class="layui-form-item">
  24 + <div class="layui-inline">
  25 + <div class="layui-input-inline layui-input-inline--long">
  26 + <input type="text" id="notice_search_keyword" name="keyword" lay-tips="关键字检索包含 </br>资源名称</br>ip地址</br>通知内容" placeholder="输入关键字,回车搜索" autocomplete="off" class="layui-input">
  27 + </div>
  28 + </div>
  29 + <!--资源类型-->
  30 + <div class="layui-inline">
  31 + <div class="layui-input-inline layui-input-inline--long">
  32 + <div class="xm-select-demo" id="my_notice_search_resType"></div>
  33 + </div>
  34 + </div>
  35 + <!--用户列表-->
  36 +<!-- <div class="layui-inline">-->
  37 +<!-- <div class="layui-input-inline layui-input-inline&#45;&#45;long">-->
  38 +<!-- <div class="xm-select-demo" id="notice_user_list"></div>-->
  39 +<!-- </div>-->
  40 +<!-- </div>-->
  41 + <!--业务类型-->
  42 + <div class="layui-inline">
  43 + <div class="layui-input-inline layui-input-inline--long">
  44 + <div class="xm-select-demo" id="my_notice_search_busId"></div>
  45 + </div>
  46 + </div>
  47 + <!--发送状态-->
  48 + <!--<div class="layui-inline">
  49 + <div class="layui-input-inline layui-input-inline&#45;&#45;long">
  50 + <select id="notice_search_isSend" lay-filter="notice_search_isSend">
  51 + <option value="1">已发送</option>
  52 + <option value="">待发送</option>
  53 + </select>
  54 + </div>
  55 + </div>-->
  56 + <!--lsq 告警指标 2022-07-05-->
  57 + <div class="layui-inline">
  58 + <div class="layui-input-inline">
  59 + <select name="alarmKpi" lay-filter="alarmKpiSearch" lay-search="" id="myNoticeAlarmKpiSearchBox">
  60 + </select>
  61 + </div>
  62 + </div>
  63 + <!--lsq 通知方式 2022-07-05-->
  64 + <div class="layui-inline">
  65 + <div class="layui-input-inline">
  66 + <select name="way" lay-filter="noticeWaySearch" llay-search="" id="myNoticeWaySearchBox">
  67 + </select>
  68 + </div>
  69 + </div>
  70 + <div class="layui-inline">
  71 + <div class="layui-btn-group">
  72 + <button type="button" class="layui-btn layui-btn-primary" data-period="all">全部</button>
  73 + <button type="button" class="layui-btn active" data-period="today">今天</button>
  74 + <button type="button" class="layui-btn layui-btn-primary" data-period="week">本周</button>
  75 + <button type="button" class="layui-btn layui-btn-primary" data-period="month">本月</button>
  76 + <button type="button" class="layui-btn layui-btn-primary" data-period="custom" id="dataPeriodCustom">自定义</button>
  77 + </div>
  78 + </div>
  79 + <div class="layui-inline">
  80 + <button id="noticeSearchQueryBtn" type="button" class="layui-btn layui-btn-normal" ><i
  81 + class="layui-icon layui-icon-search"></i>查询
  82 + </button>
  83 + </div>
  84 + </div>
  85 + </form>
  86 +
  87 + </div>
  88 + </div>
  89 + <div style="display: flex" class="layui-card-echart">
  90 + <div style="flex-grow: 3;width: 66%!important;" >
  91 + <div class="lay-row-title" id="personTotal"> 人员分组统计 <div style=" float:right;"><button type="button" style="color:#1e9fff" id="queryMore">查看更多</button></div></div>
  92 +
  93 + <div class="pie-chart" id="my_notice_chart_user"></div>
  94 + </div>
  95 + <div style="flex-grow: 1">
  96 + <h5 class="lay-row-title">分类分组统计</h5>
  97 + <div class="pie-chart" id="my_notice_chart_type"></div>
  98 + </div>
  99 +<!-- <div style="flex-grow: 1">-->
  100 +<!-- <div class="layui-tab layui-tab-card" lay-filter="report-tab">-->
  101 +<!-- <ul class="layui-tab-title">-->
  102 +<!-- <li class="layui-this">未读信息</li>-->
  103 +<!-- <li>未报信息</li>-->
  104 +<!-- <li>未处理告警信息</li>-->
  105 +<!-- </ul>-->
  106 +<!-- <div class="layui-tab-content tab-content">-->
  107 +<!-- <div class="layui-tab-item layui-show">-->
  108 +<!-- <div class="pie-chart-clone" id="chart-noRead-report"></div>-->
  109 +<!-- </div>-->
  110 +<!-- <div class="layui-tab-item">-->
  111 +<!-- <div class="pie-chart-clone" id="chart-noReport-report"></div>-->
  112 +<!-- </div>-->
  113 +<!-- <div class="layui-tab-item">-->
  114 +<!-- <div class="pie-chart-clone" id="chart-noAlarm-report"></div>-->
  115 +<!-- </div>-->
  116 +<!-- </div>-->
  117 +<!-- </div>-->
  118 +<!-- </div>-->
  119 + </div>
  120 + <div class="layui-card-body" style="margin-top: 25px">
  121 + <table id="myNoticeSearchTable"></table>
  122 + </div>
  123 + </div>
  124 + </div>
  125 + </div>
  126 + <textarea class="hide" id="my-noticeIndex-params">{{d}}</textarea>
  127 +</article>
  128 +<!--上传弹框-->
  129 +<script id="more_info" type="text/html">
  130 + <div style="align:center;padding: 20px;height: 330px">
  131 + <div class="lay-row-title" lay-tips="灰色拖动条可以左右拉缩并拖动展示其它数据"> 人员分组统计 </div>
  132 + <div class="pie-chart" style="height: 100%" id="my_notice_chart_type_new"></div>
  133 + </div>
  134 +</script>
  135 +<script>
  136 + var params = document.getElementById("my-noticeIndex-params").value;
  137 + layui.use('myNoticeIndex', function (fn) {
  138 + if(params.indexOf("{{d") !== -1){
  139 + fn();
  140 + } else {
  141 + fn(JSON.parse(params));
  142 + }
  143 + });
  144 +</script>
  145 +
  1 +<title>快照管理</title>
  2 +<iframe src="/vue3/index.html#/vue3/snapshot" frameborder="0" class="layadmin-iframe" style="height: 99.5%!important;"/>
  1 +<title>快照概览</title>
  2 +<iframe src="/vue3/index.html#/vue3/snapshotOverview" frameborder="0" class="layadmin-iframe" style="height: 99.5%!important;"/>
  1 +<!--快照详细页面-->
  2 +<article class="page-container template">
  3 + <div class="page-panel">
  4 + <div class="main">
  5 + <div class="layui-card">
  6 + <div class="layui-card-body">
  7 + <div class="lay-row">
  8 + <div class="lay-row-item" style="max-width: 200px">
  9 + <h5 class="lay-row-title">资源状态</h5>
  10 + <div class="res-state" id="hostminicomputerpartition_resstate">
  11 + <div class="res-state-pie res-state-pie--good"></div>
  12 + <ul>
  13 + <li>严重告警:0</li>
  14 + <li>重要告警:0</li>
  15 + <li>一般告警:0</li>
  16 + </ul>
  17 + </div>
  18 + </div>
  19 + <div class="lay-row-item lay-row-item--half" style="width: calc(100% - 200px)">
  20 + <h5 class="lay-row-title">基本信息<i class="iconfont detail_base_info"
  21 + data-id="hostminicomputerpartition_jbxx">&#xe61e;</i></h5>
  22 + <ul class="info-table" id="hostminicomputerpartition_jbxx">
  23 + </ul>
  24 + </div>
  25 + </div>
  26 + <div class="lay-row">
  27 + <div class="lay-row-item lay-row-item--half" style="width: calc(100% - 10px)">
  28 + <h5 class="lay-row-title">性能信息<i class="iconfont detail_base_info"
  29 + data-id="hostminicomputerpartition_sysfile">&#xe61e;</i></h5>
  30 + <ul class="info-table" id="hostminicomputerpartition_sysfile"></ul>
  31 + </div>
  32 + </div>
  33 + <div id="table_arr_body">
  34 + </div>
  35 + <div class="lay-row">
  36 + <div class="lay-row-item">
  37 + <h5 class="lay-row-title">告警列表</h5>
  38 + <div id="snapshow_active_alram"></div>
  39 + </div>
  40 + </div>
  41 + </div>
  42 + </div>
  43 + </div>
  44 + </div>
  45 +</article>
  46 +<textarea id="snapshot_detail_param_id" style="display: none;">{{d}}</textarea>
  47 +<script>
  48 + layui.use('snapshot_detail', function (fn) {
  49 + var $ = layui.$;
  50 + var parm = $("#snapshot_detail_param_id").val();
  51 + if (parm.indexOf('{{d') != -1) {
  52 + fn();
  53 + } else {
  54 + fn(JSON.parse(parm));
  55 + }
  56 + });
  57 +</script>
@@ -51,7 +51,13 @@ @@ -51,7 +51,13 @@
51 .container .cm-card .search .condition div { 51 .container .cm-card .search .condition div {
52 margin-right: 2px !important; 52 margin-right: 2px !important;
53 margin-bottom: 3px !important; 53 margin-bottom: 3px !important;
54 - width: 250px !important; 54 + /*width: 250px !important;*/
  55 +}
  56 +.container .cm-card .search .condition.esData-conditon div {
  57 + margin-bottom: 0px !important;
  58 +}
  59 +.container .cm-card .search .condition.ping div {
  60 + margin-bottom: 0px !important;
55 } 61 }
56 62
57 .container .cm-card .search .btns { 63 .container .cm-card .search .btns {
1 <div> 1 <div>
2 <el-select @visible-change="selectClose" v-model="modelValueLabel" :filter-method="selectFilterMethod" 2 <el-select @visible-change="selectClose" v-model="modelValueLabel" :filter-method="selectFilterMethod"
3 - style="min-width: 120px;" :size="size" placeholder="所属系统" :filterable="isFilter" clearable 3 + style="min-width: 120px;" :size="$global.elementConfig.size.input" placeholder="所属系统" :filterable="isFilter" clearable
4 :collapse-tags="true" @change="selectChangeMethod"> 4 :collapse-tags="true" @change="selectChangeMethod">
5 <el-option :value="modelValue" style="height: auto;padding: 0;"> 5 <el-option :value="modelValue" style="height: auto;padding: 0;">
6 <el-tree ref="bizTree" :data="list" :check-on-click-node="true" :default-expand-all="isDefaultAll" 6 <el-tree ref="bizTree" :data="list" :check-on-click-node="true" :default-expand-all="isDefaultAll"
1 <div> 1 <div>
2 <el-select @visible-change="selectClose" v-model="modelValueLabel" :filter-method="selectFilterMethod" 2 <el-select @visible-change="selectClose" v-model="modelValueLabel" :filter-method="selectFilterMethod"
3 - style="min-width: 120px;" :size="size" placeholder="资源类型" :filterable="isFilter" clearable 3 + style="min-width: 120px;" :size="$global.elementConfig.size.input" placeholder="资源类型" :filterable="isFilter" clearable
4 :collapse-tags="true" @change="selectChangeMethod"> 4 :collapse-tags="true" @change="selectChangeMethod">
5 <el-option :value="modelValue" style="height: auto;padding: 0;"> 5 <el-option :value="modelValue" style="height: auto;padding: 0;">
6 <el-tree ref="resTypeTree" :data="list" :check-on-click-node="true" :default-expand-all="isDefaultAll" 6 <el-tree ref="resTypeTree" :data="list" :check-on-click-node="true" :default-expand-all="isDefaultAll"
  1 +<div>
  2 + <el-select :size="$global.elementConfig.size.input" :collapse-tags="true" :filter-method="selectFilterMethod" :filterable="isFilter"
  3 + @change="selectChangeMethod" @visible-change="selectClose" clearable placeholder="选择用户"
  4 + style="min-width: 120px;" v-model="modelValueLabel">
  5 + <el-option :value="modelValue" style="height: auto;padding: 0;">
  6 + <el-tree :check-on-click-node="true" :check-strictly="false" :data="list" :default-expand-all="isDefaultAll"
  7 + :empty-text="emptyText" :expand-on-click-node="true" :filter-node-method="filterNode"
  8 + :props="defaultProps" :show-checkbox="isMultiple" :show-checkbox="checkbox" @check-change="handleCheckChange"
  9 + node-key="id" node-key="id" ref="userTree">
  10 + </el-tree>
  11 + </el-option>
  12 + </el-select>
  13 +</div>
  1 +export default {
  2 + template: '',
  3 + name: 'user-tree-input',
  4 + props: {
  5 + // echoObj 可以用于回显,它的值为需要回显的对象,多个时可以使用数组
  6 + echoObj: {},
  7 + // 是否开启搜索
  8 + isFilter: {
  9 + default: true
  10 + },
  11 + // 尺寸
  12 + size: {
  13 + default: ''
  14 + },
  15 + placeholderText: {
  16 + default: '选择用户'
  17 + },
  18 + isTag: {
  19 + default: true
  20 + },
  21 + isDefaultAll: {
  22 + default: true
  23 + },
  24 + // 点击节点是否展开
  25 + expandClickNode: {
  26 + default: false
  27 + },
  28 + // 字段key,用于取出数据中的名字
  29 + fieldName: {
  30 + default: 'title'
  31 + },
  32 + emptyText: {
  33 + default: '无匹配项'
  34 + },
  35 + // 字段key, 数据中的id
  36 + fieldId: {
  37 + default: ''
  38 + },
  39 + // 配置是否可多选
  40 + isMultiple: {
  41 + type: Boolean,
  42 + default: true
  43 + },
  44 +
  45 + },
  46 + data() {
  47 + return {
  48 + defaultProps: {
  49 + children: 'children',
  50 + label: 'nickname'
  51 + },
  52 + list: [],
  53 + // 实际选中值
  54 + modelValue: [],
  55 + // 下拉框绑定值(选中值名字)
  56 + modelValueLabel: []
  57 + }
  58 + },
  59 + methods: {
  60 + selectClose(bool) {
  61 + if (bool) {
  62 + this.selectFilterMethod('')
  63 + }
  64 + },
  65 + selectFilterMethod(val) {
  66 + // 下拉框调用tree树筛选
  67 + this.$refs.userTree.filter(val)
  68 + },
  69 + selectChangeMethod(e) {
  70 + var arrNew = []
  71 + var dataLength = this.modelValue.length
  72 + var eLength = e.length
  73 + for (var i = 0; i < dataLength; i++) {
  74 + for (var j = 0; j < eLength; j++) {
  75 + if (e[j] === JSON.parse('this.modelValue[i].' + this.fieldName)) {
  76 + arrNew.push(this.modelValue[i])
  77 + }
  78 + }
  79 + }
  80 + // 设置勾选的值
  81 + this.$refs.userTree.setCheckedNodes(arrNew)
  82 + },
  83 + filterNode(value, data) {
  84 + if (!value) return true
  85 +
  86 + return data[this.fieldName].indexOf(value) !== -1
  87 + },
  88 + handleCheckChange(data, checked, indeterminate) {
  89 + let that = this;
  90 +
  91 + var selectArr = [];
  92 + selectArr.push(data);
  93 + // data[that.defaultProps.children].forEach(function (v) {
  94 + // selectArr.push(data);
  95 + // });
  96 +
  97 + if (checked) {
  98 + // 已选中
  99 + that.modelValue = that.modelValue.concat(selectArr)
  100 + } else {
  101 + that.modelValue.forEach(function (v, i) {
  102 + selectArr.forEach(function (v1) {
  103 + if (v.busId == v1.busId) {
  104 + that.modelValue.splice(i, 1);
  105 + }
  106 + })
  107 + })
  108 + }
  109 + that.modelValueLabel = that.modelValue.map(function (v) {
  110 + return v[that.defaultProps.label];
  111 + });
  112 + that.$emit('callback', this.modelValue)
  113 + }
  114 + },
  115 + watch: {},
  116 + mounted() {
  117 + let that = this;
  118 + //加载资源列表
  119 + const {proxy} = Vue.getCurrentInstance()
  120 + // 加载列表
  121 + proxy.$http.get("/api-user/users/getAll", {}, function (res) {
  122 + if (res) {
  123 + that.list = res;
  124 + }
  125 + })
  126 + },
  127 + created() {
  128 +
  129 +
  130 + }
  131 +}
@@ -46,7 +46,9 @@ Promise.all([ @@ -46,7 +46,9 @@ Promise.all([
46 //所属系统 46 //所属系统
47 .component('cm-biz-type-tree-input', Vue.defineAsyncComponent(() => myImport('components/common/inputbiztypetree/index'))) 47 .component('cm-biz-type-tree-input', Vue.defineAsyncComponent(() => myImport('components/common/inputbiztypetree/index')))
48 //时间范围组件 48 //时间范围组件
49 - .component('cm-date-range-influx', Vue.defineAsyncComponent(() => myImport('components/common/dateRange/indexInflux'))); 49 + .component('cm-date-range-influx', Vue.defineAsyncComponent(() => myImport('components/common/dateRange/indexInflux')))
  50 + //告警通知统计信息
  51 + .component('cm-user-type-tree-input', Vue.defineAsyncComponent(() => myImport('components/common/inputusertree/index')))
50 52
51 53
52 // // 自定义指令 54 // // 自定义指令
@@ -93,6 +93,24 @@ const routes = [{ @@ -93,6 +93,24 @@ const routes = [{
93 name: 'busyConfig', 93 name: 'busyConfig',
94 component: () => myImport('views/busyConfig/index') 94 component: () => myImport('views/busyConfig/index')
95 }, 95 },
  96 + //快照管理
  97 + {
  98 + path: '/vue3/snapshot',
  99 + name: 'snapshot',
  100 + component: () => myImport('views/snapshot/index')
  101 + },
  102 + //快照历史
  103 + {
  104 + path: '/vue3/snapshot/history',
  105 + name: 'snapshotHistory',
  106 + component: () => myImport('views/snapshot/history/index')
  107 + },
  108 + //快照概览
  109 + {
  110 + path: '/vue3/snapshotOverview',
  111 + name: 'snapshotOverview',
  112 + component: () => myImport('views/snapshotOverview/index')
  113 + },
96 //license 114 //license
97 { 115 {
98 path: '/vue3/license', 116 path: '/vue3/license',
@@ -287,7 +287,11 @@ global.openDetail = (resId, resType, proxy) => { @@ -287,7 +287,11 @@ global.openDetail = (resId, resType, proxy) => {
287 } 287 }
288 }) 288 })
289 } 289 }
290 - 290 +//跳转详情页
  291 +global.openNewWin = (url, name, params, editFlag, fn, cancelfn, type, sign) => {
  292 + let lyaui = global.layui;
  293 + lyaui.commonDetail.openNewWin(url, name, params, editFlag, fn, cancelfn, type, sign)
  294 +}
291 /** 295 /**
292 * @description 打开选择layUI弹窗 296 * @description 打开选择layUI弹窗
293 * @author XuHaoJie 297 * @author XuHaoJie
  1 +<div :style="{'height':height+'px','max-height':height+'px','padding':'10px 0 10px 10px','background':'#fff','box-sizing':'border-box'}"
  2 + class="container">
  3 + <div :style="{'height':'100%','padding-top':'3px'}"
  4 + class="cm-card">
  5 + <div class="search">
  6 + <div class="condition ping">
  7 + <el-form-item>
  8 + <el-date-picker
  9 + :size="$global.elementConfig.size.input"
  10 + end-placeholder="开始时间"
  11 + placeholder="开始时间"
  12 + type="datetime"
  13 + v-model="search.startTime"
  14 + value-format="YYYY-MM-DD HH:mm:ss"
  15 + />
  16 +
  17 + </el-form-item>
  18 + <el-form-item>
  19 + <el-date-picker
  20 + :size="$global.elementConfig.size.input"
  21 + end-placeholder="结束时间"
  22 + placeholder="结束时间"
  23 + type="datetime"
  24 + v-model="search.endTime"
  25 + value-format="YYYY-MM-DD HH:mm:ss"
  26 + />
  27 + </el-form-item>
  28 + <el-form-item>
  29 + <el-button :size="$global.elementConfig.size.button" type="primary" @click="getDataList">查询</el-button>
  30 + </el-form-item>
  31 + <el-form-item>
  32 + <el-button :size="$global.elementConfig.size.button" @click="deleteHistory">删除</el-button>
  33 + </el-form-item>
  34 + </div>
  35 + </div>
  36 + <div class="search-table">
  37 + <cm-table-page :columns="tableData.columns" :dataList="tableData.dataList" :height="(height - 110)"
  38 + :loading="false" :pageSize="search.pageSize" :showBorder="true"
  39 + :showIndex="true" :showPage="true" :showSelection="true"
  40 + :showTools="true" :total="tableData.count" @loaddata="loaddata" @selectionChange="selectionChange">
  41 + <template #default="{row,prop,column}">
  42 + <div v-if="prop == 'state'">
  43 + <div v-if="row.state == 0">
  44 + <el-tag>创建中</el-tag>
  45 + </div>
  46 + <div v-if="row.state == 1">
  47 + <el-tag type="success">已创建</el-tag>
  48 + </div>
  49 + <div v-if="row.state == 2">
  50 + <el-tag type="danger">创建失败</el-tag>
  51 + </div>
  52 + </div>
  53 + </template>
  54 + <template #tools="{scope}">
  55 + <div class="list-handle">
  56 + <span class="icon-bg">
  57 + <i @click="handleDetail(scope.row)" class="el-icon-document" title="查看详情"></i>
  58 + </span>
  59 + <span class="icon-bg">
  60 + <i @click="handleDelete(scope.row)" class="el-icon-delete" title="删除"></i>
  61 + </span>
  62 + </div>
  63 + </template>
  64 + </cm-table-page>
  65 + </div>
  66 + </div>
  67 +</div>
  68 +
  1 +export default {
  2 + name: 'snapshotHistory',
  3 + template: '',
  4 + components: {},
  5 + props: [],
  6 + setup(props, {attrs, slots, emit}) {
  7 + const {proxy} = Vue.getCurrentInstance();
  8 + let height = Vue.ref(window.innerHeight);
  9 + let resId = Vue.ref('');
  10 + //选择的数据
  11 + let selectionData = Vue.ref([]);
  12 + let search = Vue.ref({
  13 + pageNum: 1,
  14 + pageSize: 20,
  15 + startTime: '',
  16 + endTime: '',
  17 + keyWord: ''
  18 +
  19 + });
  20 + let selectionChange = (val) => {
  21 + selectionData.value = val;
  22 + }
  23 + //表格字段
  24 + let tableData = Vue.ref({
  25 + count: 0,
  26 + dataList: [],
  27 + columns: [
  28 + {
  29 + prop: 'createUser',
  30 + label: '快照创建人',
  31 + sortable: true,
  32 + align: 'center',
  33 + width: '250'
  34 + },
  35 + {
  36 + prop: 'createTime',
  37 + label: '快照创建时间',
  38 + sortable: true,
  39 + align: 'center',
  40 + width: '300'
  41 + },
  42 + {
  43 + prop: 'state',
  44 + label: '同步状态',
  45 + sortable: true,
  46 + align: 'center',
  47 + width: '170'
  48 + },
  49 + {
  50 + prop: 'batchNo',
  51 + label: '批次号',
  52 + sortable: true,
  53 + align: 'center',
  54 + }
  55 + ]
  56 + })
  57 + // 获取列表
  58 + let getDataList = () => {
  59 + let params = {
  60 + resId: resId.value,
  61 + startTime: search.value.startTime,
  62 + endTime: search.value.endTime,
  63 + keyWord: search.value.keyword,
  64 + pageNum:search.value.pageNum,
  65 + pageSize: search.value.pageSize
  66 + }
  67 + proxy.$http.get(`/api-web/snapshot/his/getList`, params, function (res) {
  68 + if (res.success) {
  69 + tableData.value.dataList = res.data;
  70 + tableData.value.count = res.count;
  71 + } else {
  72 + tableData.value.dataList = [];
  73 + tableData.value.count = 0;
  74 + }
  75 + });
  76 + }
  77 + //删除快照历史数据
  78 + let handleDelete = (row) =>{
  79 + let params = {
  80 + resId: resId.value,
  81 + batchNo: row.batchNo
  82 + }
  83 + deleteSnapshot(params);
  84 + }
  85 + //多选删除
  86 + let deleteHistory = () =>{
  87 + if (selectionData.value.length > 0) {
  88 + let id = [];
  89 + let batchNo = [];
  90 + selectionData.value.map(item => {
  91 + id.push(item.resId);
  92 + batchNo.push(item.batchNo);
  93 + })
  94 + let params = {
  95 + resId: id.toString(),
  96 + batchNo: batchNo.toString()
  97 + }
  98 + deleteSnapshot(params);
  99 + }else {
  100 + proxy.$global.showMsg("请选择需要删除的历史快照数据","warning");
  101 + }
  102 + }
  103 + //删除
  104 + let deleteSnapshot = (param) =>{
  105 + proxy.$global.confirm('确认删除吗?', function () {
  106 + proxy.$http.get(`/api-web/snapshot/his/delete`, param, function (res) {
  107 + if (res.success) {
  108 + proxy.$global.showMsg("删除成功","success");
  109 + getDataList();
  110 + } else {
  111 + proxy.$global.showMsg("删除失败","error");
  112 + }
  113 + });
  114 + });
  115 + }
  116 +
  117 +
  118 + //获取resId
  119 + let getResId = () => {
  120 + resId.value = proxy.$route.query.resId;
  121 + }
  122 + let loaddata = ({page, limit}) => {
  123 + search.value.pageNum = page;
  124 + search.value.pageSize = limit;
  125 + getDataList();
  126 + }
  127 + //快照详情
  128 + let handleDetail = (row)=>{
  129 + proxy.$global.openNewWin('template/detail/snapshot_detail', row.createUser+'在'+row.createTime+'创建的'+row.resName+'的快照', {resId:row.resId,'batchNo':row.batchNo},false);
  130 + }
  131 +
  132 + //查看资源详情
  133 + let goResDetail = (row) => {
  134 + proxy.$global.openDetail(row.resId, row.resType, proxy);
  135 + }
  136 + // 挂载完
  137 + Vue.onMounted(() => {
  138 + getResId();
  139 + getDataList();
  140 + })
  141 +
  142 +
  143 + return {
  144 + height,
  145 + resId,
  146 + getDataList,
  147 + tableData,
  148 + search,
  149 + loaddata,
  150 + goResDetail,
  151 + handleDelete,
  152 + handleDetail,
  153 + selectionChange,
  154 + deleteHistory,
  155 + deleteSnapshot
  156 + }
  157 + }
  158 +
  159 +}
  1 +<div class="container" :style="{'height':height+'px','max-height':height+'px','padding':'10px 0 10px 10px','background':'#fff','box-sizing':'border-box'}">
  2 + <div class="cm-card" :style="{'height':'100%','padding-top':'3px'}">
  3 + <div class="search">
  4 + <div class="condition esData-conditon" style="justify-content: space-between;width: 100%;">
  5 + <el-form :inline="true">
  6 + <el-form-item>
  7 + <el-tooltip placement="bottom-start">
  8 + <template #content> 资源名称 <br /> 资源ip <br /> 业务名称</template>
  9 + <el-input clearable :size="$global.elementConfig.size.input" v-model="queryParams.keyWord" placeholder="关键字检索" />
  10 + </el-tooltip>
  11 + </el-form-item>
  12 + <el-form-item>
  13 + <el-dropdown>
  14 + <cm-res-type-tree-input @callback="getResType" clearable collapseTags multiple/>
  15 + </el-dropdown>
  16 + </el-form-item>
  17 + <el-form-item>
  18 + <el-dropdown>
  19 + <cm-biz-type-tree-input @callback="getBizType" clearable collapseTags multiple/>
  20 + </el-dropdown>
  21 + </el-form-item>
  22 + <el-form-item>
  23 + <el-button @click="handleQuery" :size="$global.elementConfig.size.button" type="primary">查询</el-button>
  24 + </el-form-item>
  25 + </el-form>
  26 + <el-button-group>
  27 + <el-button @click="handleBtnGroup('today')" :type="queryParams.time=='today'?'primary':''">今天</el-button>
  28 + <el-button @click="handleBtnGroup('week')" :type="queryParams.time=='week'?'primary':''">近7天</el-button>
  29 + <el-button @click="handleBtnGroup('month')" :type="queryParams.time=='month'?'primary':''">近30天</el-button>
  30 + <el-button @click="handleBtnGroup('quarter')" :type="queryParams.time=='quarter'?'primary':''">近90天</el-button>
  31 + <el-popover
  32 + v-model:visible="visiblePopover"
  33 + :width="420"
  34 + placement="bottom-end">
  35 + <template #reference>
  36 + <el-button @click="handleBtnGroup(4)" :type="queryParams.time!='today' && queryParams.time!='week' && queryParams.time!='month' && queryParams.time!='quarter'?'primary':''">自定义</el-button>
  37 + </template>
  38 + <el-date-picker
  39 + format="YYYY-MM-DD HH:mm:ss"
  40 + value-format="YYYY-MM-DD HH:mm:ss"
  41 + @change="handleChangeDatetime"
  42 + v-model="datetimerange"
  43 + type="datetimerange"
  44 + range-separator="-"
  45 + start-placeholder="开始时间"
  46 + end-placeholder="结束时间"
  47 + />
  48 + </el-popover>
  49 + </el-button-group>
  50 + </div>
  51 + </div>
  52 +
  53 + <el-row :gutter="20" style="padding: 3px 10px;">
  54 + <el-col :span="8">
  55 + <h3 class="page-item-title-h3">资源类型快照量TOP5</h3>
  56 + <div ref="bizChartsRefs" style="width: 100%;height: 320px;border: 1px solid #e4e4e4;"></div>
  57 + </el-col>
  58 + <el-col :span="8">
  59 + <h3 class="page-item-title-h3">业务系统快照量TOP5</h3>
  60 + <div ref="devChartsRefs" style="width: 100%;height: 320px;border: 1px solid #e4e4e4;"></div>
  61 + </el-col>
  62 + <el-col :span="8">
  63 + <h3 class="page-item-title-h3">快照量</h3>
  64 + <div ref="snapshotChartsRefs" style="width: 100%;height: 320px;border: 1px solid #e4e4e4;"></div>
  65 + </el-col>
  66 + </el-row>
  67 +
  68 + <div class="search-table">
  69 + <h3 style="text-align: left;color:#2b9eef;">快照信息</h3>
  70 + <cm-table-page :columns="tableData.columns" :dataList="tableData.dataList"
  71 + :height="height - 550"
  72 + :loading="false"
  73 + :pageSize="queryParams.pageSize"
  74 + :showBorder="true"
  75 + :showIndex="true"
  76 + :showPage="true"
  77 + :showSelection="false"
  78 + :showTools="true"
  79 + :total="queryParams.count"
  80 + @loaddata="loaddata">
  81 + <template #default="{row,prop,column}">
  82 + <div v-if="prop == 'resName'">
  83 + <!-- 资源名称点击事件 -->
  84 + <el-tooltip placement="top">
  85 + <el-button @click.prevent="goResDetail(row)" size="small" type="text">
  86 + <span class="">{{row.resName}}</span>
  87 + </el-button>
  88 + <template #content>{{row.resName}}</template>
  89 + </el-tooltip>
  90 + </div>
  91 + <div v-if="prop == 'busTypeName'">
  92 + <div v-if="(row.busTypeName || '').split(',').length <= '3'">
  93 + <div v-if="row.busTypeName != null && row.busTypeName.indexOf(',') != -1" v-for="item in row.busTypeName.split(',')">
  94 + <el-tooltip placement="top">
  95 + <template #content>{{item}}</template>
  96 + <el-tag style="margin: 2px;" type="info" class="mx-1" effect="light">{{item}}</el-tag>
  97 + </el-tooltip>
  98 + </div>
  99 + <div v-else-if="row.busTypeName != null && row.busTypeName.indexOf(',') == -1 ">
  100 + <el-tooltip placement="top">
  101 + <template #content>{{row.busTypeName}}</template>
  102 + <el-tag type="info" class="mx-1" effect="light">{{row.busTypeName}}</el-tag>
  103 + </el-tooltip>
  104 + </div>
  105 + </div>
  106 + <div v-else>
  107 + <el-button @click="goBus(row)" size="small" type="text">
  108 + <span>共计:{{row.nickname.split(',').length}}个业务</span>
  109 + </el-button>
  110 + </div>
  111 + </div>
  112 + <div v-if="prop == 'nickname'">
  113 + <div v-if="(row.nickname || '').split(',').length <= '3'">
  114 + <div v-if="row.nickname != null && row.nickname.indexOf(',') != -1" v-for="item in row.nickname.split(',')">
  115 + <el-tooltip placement="top">
  116 + <template #content>{{item}}</template>
  117 + <el-tag style="margin: 2px;" type="info" class="mx-1" effect="light">{{item}}</el-tag>
  118 + </el-tooltip>
  119 + </div>
  120 + <div v-else-if="row.nickname != null && row.nickname.indexOf(',') == -1 ">
  121 + <el-tooltip placement="top">
  122 + <template #content>{{row.nickname}}</template>
  123 + <el-tag type="info" class="mx-1" effect="light">{{row.nickname}}</el-tag>
  124 + </el-tooltip>
  125 + </div>
  126 + </div>
  127 + <div v-else>
  128 + <el-button @click="goBus(row)" size="small" type="text">
  129 + <span>共计:{{row.nickname.split(',').length}}个业务负责人</span>
  130 + </el-button>
  131 + </div>
  132 + </div>
  133 + <div v-if="prop == 'admin'">
  134 + <div v-if="row.admin != null">
  135 + <el-tooltip placement="top">
  136 + <template #content>{{row.admin}}</template>
  137 + <el-tag type="info" class="mx-1" effect="light">{{row.admin}}</el-tag>
  138 + </el-tooltip>
  139 + </div>
  140 + </div>
  141 + <div v-if="prop == 'createUser'">
  142 + <div v-if="row.createUser != null">
  143 + <el-tooltip placement="top">
  144 + <template #content>{{row.createUser}}</template>
  145 + <el-tag type="info" class="mx-1" effect="light">{{row.createUser}}</el-tag>
  146 + </el-tooltip>
  147 + </div>
  148 + </div>
  149 + </template>
  150 + <template #tools="{scope}">
  151 + <div class="list-handle">
  152 + <span class="icon-bg" @click="handleDetail(scope.row)">
  153 + <i class="el-icon-document" title="详情"></i>
  154 + </span>
  155 + <span class="icon-bg"@click="handleDel(scope.row)">
  156 + <i class="el-icon-delete"></i>
  157 + </span>
  158 + </div>
  159 + </template>
  160 + </cm-table-page>
  161 + </div>
  162 + </div>
  163 +</div>
  164 +
  165 +<cm-dialog :showDialogVisible="showBus" :showFooter="false" :title="title" @hidedialog="cancelBtn"
  166 + width="700px">
  167 + <template v-slot>
  168 + <div class="dialog">
  169 + <div v-model="busType" v-for="item in busType" style="display: inline-block">
  170 + <el-tag type="info" class="mx-1" effect="light">{{item}}</el-tag>
  171 + </div>
  172 + </div>
  173 + </template>
  174 +</cm-dialog>
  1 +export default {
  2 + name:"snapshot",
  3 + template:"",
  4 + setup(props, {attrs, slots, emit}){
  5 + const {proxy} = Vue.getCurrentInstance();
  6 + let height = Vue.ref(window.innerHeight);
  7 + let formSize = Vue.ref('default');
  8 + let datetimerange = Vue.ref([]);
  9 + let visiblePopover = Vue.ref(false);
  10 + let queryParams = Vue.ref({
  11 + keyWord:'',
  12 + resType:'',
  13 + busId:'',
  14 + time:"week",
  15 + pageNum: 1,
  16 + pageSize: 10,
  17 + count:0,
  18 + })
  19 + let btnGroupType = Vue.ref(0);
  20 + //表格字段
  21 + let tableData = Vue.ref({
  22 + count: 0,
  23 + dataList: [],
  24 + columns: [
  25 + {
  26 + prop: 'resTypeName',
  27 + label: '资源类型',
  28 + sortable: true,
  29 + align: 'center',
  30 + width: '200',
  31 + },
  32 + {
  33 + prop: 'resName',
  34 + label: '资源名称',
  35 + sortable: true,
  36 + align: 'center'
  37 + },
  38 + {
  39 + prop: 'ip',
  40 + label: 'IP地址',
  41 + sortable: true,
  42 + align: 'center',
  43 + width: '130'
  44 + }, {
  45 + prop: 'admin',
  46 + label: '负责人',
  47 + sortable: true,
  48 + align: 'center',
  49 + width: '130'
  50 + }, {
  51 + prop: 'busTypeName',
  52 + label: '所属业务系统',
  53 + sortable: true,
  54 + align: 'center',
  55 + width: '270'
  56 + },
  57 + {
  58 + prop: 'nickname',
  59 + label: '业务系统负责人',
  60 + sortable: true,
  61 + align: 'center',
  62 + width: '150'
  63 + },
  64 + {
  65 + prop: 'createUser',
  66 + label: '快照创建人',
  67 + sortable: true,
  68 + align: 'center',
  69 + width: '130'
  70 + },
  71 + {
  72 + prop: 'createTime',
  73 + label: '快照创建时间',
  74 + sortable: true,
  75 + align: 'center',
  76 + width: '170'
  77 + },
  78 + ]
  79 + })
  80 +
  81 + let loaddata = ({page, limit}) => {
  82 + queryParams.value.pageNum = page;
  83 + queryParams.value.pageSize = limit;
  84 + getDataList();
  85 + getEchartsData();
  86 + }
  87 +
  88 + let getResType = (arr) => {
  89 + let types = arr.map(function (v) {
  90 + return v.id;
  91 + });
  92 + queryParams.value.resType = types.join(',');
  93 + }
  94 + let getBizType = (arr) => {
  95 + let types = arr.map(function (v) {
  96 + return v.busId;
  97 + });
  98 + queryParams.value.busId = types.join(',');
  99 + }
  100 +
  101 + // 获取列表
  102 + let getDataList = () => {
  103 + // console.log(queryParams.value);
  104 + proxy.$http.get(`/api-web/snapshot/manage/getList`,queryParams.value,(res)=>{
  105 + // console.log(res.data);
  106 + tableData.value.dataList = res.data;
  107 + queryParams.value.count = res.count;
  108 + },(err)=>{
  109 + console.log(err);
  110 + })
  111 + };
  112 + // 查询事件
  113 + let handleQuery = ()=> {
  114 + queryParams.value.pageSize=10;
  115 + queryParams.value.pageNum=1;
  116 + getDataList();
  117 + getEchartsData();
  118 + }
  119 + // 按钮组点击事件
  120 + let handleBtnGroup = (val)=>{
  121 + queryParams.value.time = val;
  122 + if (val == 4){
  123 + visiblePopover.value = !visiblePopover.value;
  124 + }else{
  125 + visiblePopover.value = false;
  126 + getDataList();
  127 + getEchartsData();
  128 + }
  129 + };
  130 +
  131 + // echarts
  132 + let bizChartsRefs = Vue.ref(null);
  133 + let devChartsRefs = Vue.ref(null);
  134 + let snapshotChartsRefs = Vue.ref(null);
  135 + let bizCharts = Vue.ref('')
  136 + let devCharts = Vue.ref('')
  137 + let snapshotCharts = Vue.ref('')
  138 + let showBus = Vue.ref(false);
  139 + let title = Vue.ref('');
  140 + let busType = Vue.ref();
  141 + let getEcharts = ()=>{
  142 + bizCharts = echarts.init(bizChartsRefs.value);
  143 + let bizOption = {
  144 + grid:{
  145 + top:"8%",
  146 + bottom:"8%",
  147 + left:"4%",
  148 + containLabel:true,
  149 + },
  150 + tooltip: {
  151 + trigger: 'axis',
  152 + axisPointer: {
  153 + type: 'shadow',
  154 + }
  155 + },
  156 + color:"#60a0f7",
  157 + xAxis: {
  158 + type: 'category',
  159 + data: [],
  160 + axisTick:false,
  161 + axisLabel: {
  162 + interval: 0,
  163 + formatter: val => {
  164 + // 一行字数
  165 + const max = 6
  166 + // 标签长度
  167 + const valLength = val.length
  168 + // 换行数
  169 + const rowNum = valLength / 6
  170 + if (valLength > 6) {
  171 + return val.slice(0,5) + '...';
  172 + } else {
  173 + return val
  174 + }
  175 + }
  176 + }
  177 + },
  178 + yAxis: {
  179 + type: 'value',
  180 + axisLine:{
  181 + show:true,
  182 + },
  183 + //分隔线样式
  184 + splitLine:{
  185 + show:true,
  186 + lineStyle:{
  187 + type:'dashed'
  188 + }
  189 + }
  190 + },
  191 + series: [
  192 + {
  193 + data: [],
  194 + type: 'bar',
  195 + barWidth: 26,//设置柱状图大小
  196 + itemStyle:{
  197 + borderRadius:[20,20,0,0]
  198 + }
  199 + }
  200 + ]
  201 + }
  202 + bizCharts.setOption(bizOption);
  203 +
  204 + devCharts = echarts.init(devChartsRefs.value);
  205 + let devOption = {
  206 + grid:{
  207 + top:"8%",
  208 + bottom:"8%",
  209 + left:"4%",
  210 + containLabel:true,
  211 + },
  212 + tooltip: {
  213 + trigger: 'axis',
  214 + axisPointer: {
  215 + type: 'shadow',
  216 + }
  217 + },
  218 + color:"#60a0f7",
  219 + xAxis: {
  220 + type: 'category',
  221 + data: [],
  222 + axisTick:false,
  223 + axisLabel: {
  224 + interval: 0,
  225 + formatter: val => {
  226 + // 一行字数
  227 + const max = 6
  228 + // 标签长度
  229 + const valLength = val.length
  230 + // 换行数
  231 + const rowNum = valLength / 6
  232 + if (valLength > 6) {
  233 + return val.slice(0,5) + '...';
  234 + } else {
  235 + return val
  236 + }
  237 + }
  238 + }
  239 + },
  240 + yAxis: {
  241 + type: 'value',
  242 + axisLine:{
  243 + show:true,
  244 + },
  245 + //分隔线样式
  246 + splitLine:{
  247 + show:true,
  248 + lineStyle:{
  249 + type:'dashed'
  250 + }
  251 + }
  252 + },
  253 + series: [
  254 + {
  255 + data: [],
  256 + type: 'bar',
  257 + barWidth: 26,//设置柱状图大小
  258 + itemStyle:{
  259 + borderRadius:[20,20,0,0]
  260 + }
  261 + }
  262 + ]
  263 + }
  264 + devCharts.setOption(devOption);
  265 +
  266 + snapshotCharts = echarts.init(snapshotChartsRefs.value);
  267 + let shapshotOption = {
  268 + grid:{
  269 + top:"8%",
  270 + bottom:"8%",
  271 + left:"4%",
  272 + containLabel:true,
  273 + },
  274 + tooltip: {
  275 + trigger: 'axis',
  276 + axisPointer: {
  277 + type: 'shadow',
  278 + }
  279 + },
  280 + color:"#60a0f7",
  281 + xAxis: {
  282 + type: 'category',
  283 + data: [],
  284 + axisTick:false,
  285 + },
  286 + yAxis: {
  287 + type: 'value',
  288 + axisLine:{
  289 + show:true,
  290 + },
  291 + //分隔线样式
  292 + splitLine:{
  293 + show:true,
  294 + lineStyle:{
  295 + type:'dashed'
  296 + }
  297 + }
  298 + },
  299 + series: [
  300 + {
  301 + data: [],
  302 + type: 'bar',
  303 + barWidth: 26,//设置柱状图大小
  304 + itemStyle:{
  305 + borderRadius:[20,20,0,0]
  306 + }
  307 + }
  308 + ]
  309 + }
  310 + snapshotCharts.setOption(shapshotOption);
  311 + }
  312 +
  313 + let getEchartsData = ()=>{
  314 + let resTypeData = {
  315 + xaxis:[],
  316 + yaxis:[],
  317 + }
  318 + proxy.$http.get(`/api-web/snapshot/manage/resTypeTop`,queryParams.value,(res)=>{
  319 + // console.log(res.object);
  320 + res.object.forEach(item=>{
  321 + resTypeData.xaxis.push(item.xaxis);
  322 + resTypeData.yaxis.push(item.yaxis)
  323 + })
  324 + bizCharts.setOption({
  325 + xAxis:{
  326 + data:resTypeData.xaxis,
  327 + },
  328 + series:[
  329 + {
  330 + data:resTypeData.yaxis
  331 + }
  332 + ]
  333 + });
  334 + },(err)=>{
  335 + console.log(err);
  336 + })
  337 +
  338 + let busTypeData = {
  339 + xaxis:[],
  340 + yaxis:[],
  341 + }
  342 + proxy.$http.get(`/api-web/snapshot/manage/busTop`,queryParams.value,(res)=>{
  343 + // console.log(res.object);
  344 + res.object.forEach(item=>{
  345 + busTypeData.xaxis.push(item.xaxis);
  346 + busTypeData.yaxis.push(item.yaxis)
  347 + })
  348 + devCharts.setOption({
  349 + xAxis:{
  350 + data:busTypeData.xaxis,
  351 + },
  352 + series:[
  353 + {
  354 + data:busTypeData.yaxis
  355 + }
  356 + ]
  357 + });
  358 + },(err)=>{
  359 + console.log(err);
  360 + })
  361 +
  362 + let snapshotNumData = {
  363 + xaxis:[],
  364 + yaxis:[],
  365 + }
  366 + proxy.$http.get(`/api-web/snapshot/manage/snapshotNum`,queryParams.value,(res)=>{
  367 + // console.log(res.object);
  368 + res.object.forEach(item=>{
  369 + snapshotNumData.xaxis.push(item.xaxis);
  370 + snapshotNumData.yaxis.push(item.yaxis)
  371 + })
  372 + snapshotCharts.setOption({
  373 + xAxis:{
  374 + data:snapshotNumData.xaxis,
  375 + },
  376 + series:[
  377 + {
  378 + data:snapshotNumData.yaxis
  379 + }
  380 + ]
  381 + });
  382 + },(err)=>{
  383 + console.log(err);
  384 + })
  385 + }
  386 +
  387 + // 时间范围快捷键 修改事件
  388 + let handleChangeDatetime = (value)=>{
  389 + visiblePopover.value = false;
  390 + queryParams.value.time = value.join(',');
  391 + getDataList();
  392 + getEchartsData();
  393 + }
  394 +
  395 + // 表格删除事件
  396 + let handleDel = (row)=>{
  397 + // console.log(row);
  398 + proxy.$global.confirm("确认删除吗?", function () {
  399 + deleteItems([row.resId],[row.batchNo]);
  400 + })
  401 + }
  402 + //删除
  403 + let deleteItems = (ids,nos) => {
  404 + let params = {
  405 + resId: ids.toString(),
  406 + batchNo:nos.toString(),
  407 + }
  408 + proxy.$http.get('/api-web/snapshot/his/delete', params, function (res) {
  409 + if (res && res.success) {
  410 + proxy.$global.showMsg('删除成功');
  411 + handleQuery()
  412 + }
  413 + })
  414 + }
  415 +
  416 + //快照详情
  417 + let handleDetail = (row)=>{
  418 + // console.log(row);
  419 + // proxy.$global.openNewWin('template/detail/snapshot_detail_v1', "快照详情", {resId:row.resId,'batchNo':row.batchNo},false);
  420 + proxy.$global.openNewWin('template/detail/snapshot_detail', row.createUser+'在'+row.createTime+'创建的'+row.resName+'的快照', {resId:row.resId,'batchNo':row.batchNo},false);
  421 + }
  422 +
  423 + //查看资源详情
  424 + let goResDetail = (row) => {
  425 + proxy.$global.openDetail(row.resId, row.resType, proxy);
  426 + }
  427 +
  428 + //查看业务系统
  429 + let goBus = (row) => {
  430 + title.value = row.resName+'所属业务系统信息';
  431 + let busTypeAdmin = [];
  432 + for (let i = 0; i < row.busTypeName.split(',').length; i++) {
  433 + for (let j = 0; j < row.nickname.split(',').length; j++) {
  434 + if (i==j){
  435 + busTypeAdmin.push(row.busTypeName.split(',')[i]+'('+row.nickname.split(',')[i]+')')
  436 + }
  437 + }
  438 + }
  439 + busType.value = busTypeAdmin;
  440 + showBus.value = true;
  441 +
  442 + }
  443 + //关闭弹框
  444 + let cancelBtn = () => {
  445 + showBus.value = false;
  446 + }
  447 +
  448 + Vue.onMounted(()=>{
  449 + getEcharts();
  450 + getDataList();
  451 + getEchartsData();
  452 + })
  453 +
  454 + return{
  455 + height,
  456 + formSize,
  457 + queryParams,
  458 + tableData,
  459 + btnGroupType,
  460 + bizChartsRefs,
  461 + devChartsRefs,
  462 + snapshotChartsRefs,
  463 + handleBtnGroup,
  464 + datetimerange,
  465 + visiblePopover,
  466 + handleChangeDatetime,
  467 + getResType,
  468 + getBizType,
  469 + handleQuery,
  470 + loaddata,
  471 + handleDel,
  472 + handleDetail,
  473 + goResDetail,
  474 + goBus,
  475 + showBus,
  476 + cancelBtn,
  477 + title,
  478 + busType
  479 + }
  480 + }
  481 +}
  1 +<div class="container" :style="{'height':height+'px','max-height':height+'px','padding':'10px 0 10px 10px','background':'#fff','box-sizing':'border-box'}">
  2 + <div class="cm-card" :style="{'height':'100%','padding-top':'3px'}">
  3 + <div class="search">
  4 + <div class="condition esData-conditon" style="justify-content: space-between;width: 100%;">
  5 + <el-form :inline="true">
  6 + <el-form-item>
  7 + <el-tooltip placement="bottom-start">
  8 + <template #content> 资源名称 <br /> 资源ip <br /> 业务名称</template>
  9 + <el-input clearable :size="$global.elementConfig.size.input" v-model="queryParams.keyWord" placeholder="关键字检索" />
  10 + </el-tooltip>
  11 + </el-form-item>
  12 + <el-form-item>
  13 + <el-dropdown>
  14 + <cm-res-type-tree-input @callback="getResType" clearable collapseTags multiple/>
  15 + </el-dropdown>
  16 + </el-form-item>
  17 + <el-form-item>
  18 + <el-dropdown>
  19 + <cm-biz-type-tree-input @callback="getBizType" clearable collapseTags multiple/>
  20 + </el-dropdown>
  21 + </el-form-item>
  22 + <el-form-item>
  23 + <el-dropdown>
  24 + <cm-user-type-tree-input @callback="getUser" clearable collapseTags multiple/>
  25 + </el-dropdown>
  26 + </el-form-item>
  27 + <el-form-item>
  28 + <el-button @click="handleQuery" :size="$global.elementConfig.size.button" type="primary">查询</el-button>
  29 + </el-form-item>
  30 + </el-form>
  31 + <el-button-group>
  32 + <el-button @click="handleBtnGroup('today')" :type="queryParams.time=='today'?'primary':''">今天</el-button>
  33 + <el-button @click="handleBtnGroup('week')" :type="queryParams.time=='week'?'primary':''">近7天</el-button>
  34 + <el-button @click="handleBtnGroup('month')" :type="queryParams.time=='month'?'primary':''">近30天</el-button>
  35 + <el-button @click="handleBtnGroup('quarter')" :type="queryParams.time=='quarter'?'primary':''">近90天</el-button>
  36 + <el-popover
  37 + v-model:visible="visiblePopover"
  38 + :width="420"
  39 + placement="bottom-end">
  40 + <template #reference>
  41 + <el-button @click="handleBtnGroup(4)" :type="queryParams.time!='today' && queryParams.time!='week' && queryParams.time!='month' && queryParams.time!='quarter'?'primary':''">自定义</el-button>
  42 + </template>
  43 + <el-date-picker
  44 + format="YYYY-MM-DD HH:mm:ss"
  45 + value-format="YYYY-MM-DD HH:mm:ss"
  46 + @change="handleChangeDatetime"
  47 + v-model="datetimerange"
  48 + type="datetimerange"
  49 + range-separator="-"
  50 + start-placeholder="开始时间"
  51 + end-placeholder="结束时间"
  52 + />
  53 + </el-popover>
  54 + </el-button-group>
  55 + </div>
  56 + </div>
  57 +
  58 + <el-row :gutter="20" style="padding: 3px 10px;">
  59 + <el-col :span="12">
  60 + <h3 style="text-align: left;color:#2b9eef;">资源类型快照量TOP5</h3>
  61 + <div ref="bizChartsRefs" style="width: 100%;height: 320px;border: 1px solid #e4e4e4;"></div>
  62 + </el-col>
  63 + <el-col :span="12">
  64 + <h3 style="text-align: left;color:#2b9eef;">业务系统快照量TOP5</h3>
  65 + <div ref="devChartsRefs" style="width: 100%;height: 320px;border: 1px solid #e4e4e4;"></div>
  66 + </el-col>
  67 + <el-col :span="12">
  68 + <h3 style="text-align: left;color:#2b9eef;">人员快照量</h3>
  69 + <div ref="peopleSSChartsRefs" style="width: 100%;height: 320px;border: 1px solid #e4e4e4;"></div>
  70 + </el-col>
  71 + <el-col :span="12">
  72 + <h3 style="text-align: left;color:#2b9eef;">快照量</h3>
  73 + <div ref="snapshotChartsRefs" style="width: 100%;height: 320px;border: 1px solid #e4e4e4;"></div>
  74 + </el-col>
  75 + </el-row>
  76 +
  77 +
  78 + <div class="search-table">
  79 + <h3 style="text-align: left;color:#2b9eef;">快照信息</h3>
  80 + <cm-table-page :columns="tableData.columns" :dataList="tableData.dataList"
  81 + :height="height - 365"
  82 + :loading="false"
  83 + :pageSize="queryParams.pageSize"
  84 + :showBorder="true"
  85 + :showIndex="true"
  86 + :showPage="true"
  87 + :showSelection="false"
  88 + :showTools="true"
  89 + :total="queryParams.count"
  90 + @loaddata="loaddata">
  91 + <template #default="{row,prop,column}">
  92 + <div v-if="prop == 'resName'">
  93 + <!-- 资源名称点击事件 -->
  94 + <el-tooltip placement="top">
  95 + <el-button @click.prevent="goResDetail(row)" size="small" type="text">
  96 + <span class="">{{row.resName}}</span>
  97 + </el-button>
  98 + <template #content>{{row.resName}}</template>
  99 + </el-tooltip>
  100 + </div>
  101 + <div v-if="prop == 'busTypeName'">
  102 + <div v-if="(row.busTypeName || '').split(',').length <= '3'">
  103 + <div v-if="row.busTypeName != null && row.busTypeName.indexOf(',') != -1" v-for="item in row.busTypeName.split(',')">
  104 + <el-tooltip placement="top">
  105 + <template #content>{{item}}</template>
  106 + <el-tag style="margin: 2px;" type="info" class="mx-1" effect="light">{{item}}</el-tag>
  107 + </el-tooltip>
  108 + </div>
  109 + <div v-else-if="row.busTypeName != null && row.busTypeName.indexOf(',') == -1 ">
  110 + <el-tooltip placement="top">
  111 + <template #content>{{row.busTypeName}}</template>
  112 + <el-tag type="info" class="mx-1" effect="light">{{row.busTypeName}}</el-tag>
  113 + </el-tooltip>
  114 + </div>
  115 + </div>
  116 + <div v-else>
  117 + <el-button @click="goBus(row)" size="small" type="text">
  118 + <span>共计:{{row.nickname.split(',').length}}个业务</span>
  119 + </el-button>
  120 + </div>
  121 + </div>
  122 + <div v-if="prop == 'nickname'">
  123 + <div v-if="(row.nickname || '').split(',').length <= '3'">
  124 + <div v-if="row.nickname != null && row.nickname.indexOf(',') != -1" v-for="item in row.nickname.split(',')">
  125 + <el-tooltip placement="top">
  126 + <template #content>{{item}}</template>
  127 + <el-tag style="margin: 2px;" type="info" class="mx-1" effect="light">{{item}}</el-tag>
  128 + </el-tooltip>
  129 + </div>
  130 + <div v-else-if="row.nickname != null && row.nickname.indexOf(',') == -1 ">
  131 + <el-tooltip placement="top">
  132 + <template #content>{{row.nickname}}</template>
  133 + <el-tag type="info" class="mx-1" effect="light">{{row.nickname}}</el-tag>
  134 + </el-tooltip>
  135 + </div>
  136 + </div>
  137 + <div v-else>
  138 + <el-button @click="goBus(row)" size="small" type="text">
  139 + <span>共计:{{row.nickname.split(',').length}}个业务负责人</span>
  140 + </el-button>
  141 + </div>
  142 + </div>
  143 + <div v-if="prop == 'admin'">
  144 + <div v-if="row.admin != null">
  145 + <el-tooltip placement="top">
  146 + <template #content>{{row.admin}}</template>
  147 + <el-tag type="info" class="mx-1" effect="light">{{row.admin}}</el-tag>
  148 + </el-tooltip>
  149 + </div>
  150 + </div>
  151 + <div v-if="prop == 'createUser'">
  152 + <div v-if="row.createUser != null">
  153 + <el-tooltip placement="top">
  154 + <template #content>{{row.createUser}}</template>
  155 + <el-tag type="info" class="mx-1" effect="light">{{row.createUser}}</el-tag>
  156 + </el-tooltip>
  157 + </div>
  158 + </div>
  159 + </template>
  160 + <template #tools="{scope}">
  161 + <div class="list-handle">
  162 + <span class="icon-bg" @click="handleDetail(scope.row)">
  163 + <i class="el-icon-document" title="详情"></i>
  164 + </span>
  165 + </div>
  166 + </template>
  167 + </cm-table-page>
  168 + </div>
  169 + </div>
  170 +</div>
  171 +
  172 +<cm-dialog :showDialogVisible="showBus" :showFooter="false" :title="title" @hidedialog="cancelBtn"
  173 + width="700px">
  174 + <template v-slot>
  175 + <div class="dialog">
  176 + <div v-model="busType" v-for="item in busType" style="display: inline-block">
  177 + <el-tag type="info" class="mx-1" effect="light">{{item}}</el-tag>
  178 + </div>
  179 + </div>
  180 + </template>
  181 +</cm-dialog>
  182 +
  1 +export default {
  2 + name:"snapshotOverview",
  3 + template:"",
  4 + setup(props,{attrs,slots,emit}){
  5 + const {proxy} = Vue.getCurrentInstance();
  6 + let height = Vue.ref(window.innerHeight);
  7 + let btnGroupType = Vue.ref(0);
  8 + let datetimerange = Vue.ref([]);
  9 + let visiblePopover = Vue.ref(false);
  10 + let queryParams = Vue.ref({
  11 + keyWord:'',
  12 + resType:'',
  13 + busId:'',
  14 + userName:'',
  15 + time:"week",
  16 + pageNum: 1,
  17 + pageSize: 10,
  18 + count:0,
  19 + })
  20 + //表格字段
  21 + let tableData = Vue.ref({
  22 + dataList: [],
  23 + columns: [
  24 + {
  25 + prop: 'resTypeName',
  26 + label: '资源类型',
  27 + sortable: true,
  28 + align: 'center',
  29 + width: '200',
  30 + },
  31 + {
  32 + prop: 'resName',
  33 + label: '资源名称',
  34 + sortable: true,
  35 + align: 'center'
  36 + },
  37 + {
  38 + prop: 'ip',
  39 + label: 'IP地址',
  40 + sortable: true,
  41 + align: 'center',
  42 + width: '130'
  43 + }, {
  44 + prop: 'admin',
  45 + label: '负责人',
  46 + sortable: true,
  47 + align: 'center',
  48 + width: '130'
  49 + }, {
  50 + prop: 'busTypeName',
  51 + label: '所属业务系统',
  52 + sortable: true,
  53 + align: 'center',
  54 + width: '270'
  55 + },
  56 + {
  57 + prop: 'nickname',
  58 + label: '业务系统负责人',
  59 + sortable: true,
  60 + align: 'center',
  61 + width: '150'
  62 + },
  63 + {
  64 + prop: 'createUser',
  65 + label: '快照创建人',
  66 + sortable: true,
  67 + align: 'center',
  68 + width: '130'
  69 + },
  70 + {
  71 + prop: 'createTime',
  72 + label: '快照创建时间',
  73 + sortable: true,
  74 + align: 'center',
  75 + width: '170'
  76 + },
  77 + ]
  78 + })
  79 +
  80 + let loaddata = ({page, limit}) => {
  81 + queryParams.value.pageNum = page;
  82 + queryParams.value.pageSize = limit;
  83 + getDataList();
  84 + }
  85 + // 获取列表
  86 + let getDataList = () => {
  87 + proxy.$http.get(`/api-web/snapshot/overview/getList`,queryParams.value,(res)=>{
  88 + tableData.value.dataList = res.data;
  89 + queryParams.value.count = res.count;
  90 + },(err)=>{
  91 + console.log(err);
  92 + })
  93 + };
  94 +
  95 + let getEchartsData = ()=>{
  96 + let resTypeData = {
  97 + xaxis:[],
  98 + yaxis:[],
  99 + }
  100 + proxy.$http.get(`/api-web/snapshot/overview/resTypeTop`,queryParams.value,(res)=>{
  101 + res.object.forEach(item=>{
  102 + resTypeData.xaxis.push(item.xaxis);
  103 + resTypeData.yaxis.push(item.yaxis)
  104 + })
  105 + bizCharts.setOption({
  106 + xAxis:{
  107 + data:resTypeData.xaxis,
  108 + },
  109 + series:[
  110 + {
  111 + data:resTypeData.yaxis
  112 + }
  113 + ]
  114 + });
  115 + },(err)=>{
  116 + console.log(err);
  117 + })
  118 +
  119 + let busTypeData = {
  120 + xaxis:[],
  121 + yaxis:[],
  122 + }
  123 + proxy.$http.get(`/api-web/snapshot/overview/busTop`,queryParams.value,(res)=>{
  124 + res.object.forEach(item=>{
  125 + busTypeData.xaxis.push(item.xaxis);
  126 + busTypeData.yaxis.push(item.yaxis)
  127 + })
  128 + devCharts.setOption({
  129 + xAxis:{
  130 + data:busTypeData.xaxis,
  131 + },
  132 + series:[
  133 + {
  134 + data:busTypeData.yaxis
  135 + }
  136 + ]
  137 + });
  138 + },(err)=>{
  139 + console.log(err);
  140 + })
  141 +
  142 + let snapshotNumData = {
  143 + xaxis:[],
  144 + yaxis:[],
  145 + }
  146 + proxy.$http.get(`/api-web/snapshot/overview/snapshotNum`,queryParams.value,(res)=>{
  147 + res.object.forEach(item=>{
  148 + snapshotNumData.xaxis.push(item.xaxis);
  149 + snapshotNumData.yaxis.push(item.yaxis)
  150 + })
  151 + snapshotCharts.setOption({
  152 + yAxis:{
  153 + data:snapshotNumData.xaxis,
  154 + },
  155 + series:[
  156 + {
  157 + data:snapshotNumData.yaxis
  158 + }
  159 + ]
  160 + });
  161 + },(err)=>{
  162 + console.log(err);
  163 + })
  164 +
  165 + var peopleSSChartsData = [];
  166 + proxy.$http.get(`/api-web/snapshot/overview/snapshotNumByUser`,queryParams.value,(res)=>{
  167 + res.object.forEach(item=>{
  168 + let list = {};
  169 + list.name = item.xaxis + '('+item.yaxis+ ')';
  170 + list.value = item.yaxis;
  171 + peopleSSChartsData.push(list);
  172 + })
  173 + console.log(peopleSSChartsData);
  174 + peopleSSCharts.setOption({
  175 + series:[
  176 + {
  177 + data:peopleSSChartsData
  178 + }
  179 + ]
  180 + });
  181 + },(err)=>{
  182 + console.log(err);
  183 + })
  184 + }
  185 + // 查询事件
  186 + let handleQuery = ()=> {
  187 + queryParams.value.pageSize=10;
  188 + queryParams.value.pageNum=1;
  189 + getDataList();
  190 + getEchartsData();
  191 + }
  192 + let getResType = (arr) => {
  193 + let types = arr.map(function (v) {
  194 + return v.id;
  195 + });
  196 + queryParams.value.resType = types.join(',');
  197 + }
  198 + let getBizType = (arr) => {
  199 + let types = arr.map(function (v) {
  200 + return v.busId;
  201 + });
  202 + queryParams.value.busId = types.join(',');
  203 + }
  204 + let getUser = (arr) => {
  205 + let types = arr.map(function (v) {
  206 + return v.username;
  207 + });
  208 + queryParams.value.userName = types.join(',');
  209 + }
  210 +
  211 + // 按钮组点击事件
  212 + let handleBtnGroup = (val)=>{
  213 + queryParams.value.time = val;
  214 + if (val == 4){
  215 + visiblePopover.value = !visiblePopover.value;
  216 + }else{
  217 + visiblePopover.value = false;
  218 + getDataList();
  219 + getEchartsData();
  220 + }
  221 + };
  222 +
  223 + // echarts
  224 + let bizChartsRefs = Vue.ref(null);
  225 + let devChartsRefs = Vue.ref(null);
  226 + let snapshotChartsRefs = Vue.ref(null);
  227 + let peopleSSChartsRefs = Vue.ref(null);
  228 + let bizCharts = Vue.ref('');
  229 + let devCharts = Vue.ref('');
  230 + let snapshotCharts = Vue.ref('');
  231 + let peopleSSCharts = Vue.ref('');
  232 + let showBus = Vue.ref(false);
  233 + let title = Vue.ref('');
  234 + let busType = Vue.ref();
  235 + let getEcharts = ()=>{
  236 + bizCharts = echarts.init(bizChartsRefs.value);
  237 + let bizOption = {
  238 + grid:{
  239 + top:"8%",
  240 + bottom:"4%",
  241 + left:"2%",
  242 + containLabel:true,
  243 + },
  244 + tooltip: {
  245 + trigger: 'axis',
  246 + axisPointer: {
  247 + type: 'shadow',
  248 + }
  249 + },
  250 + color:"#60a0f7",
  251 + xAxis: {
  252 + type: 'category',
  253 + data: [],
  254 + axisTick:false,
  255 + axisLabel: {
  256 + interval: 0,
  257 + formatter: val => {
  258 + // 标签长度
  259 + const valLength = val.length
  260 + if (valLength > 8) {
  261 + return val.slice(0,7) + '...';
  262 + } else {
  263 + return val
  264 + }
  265 + }
  266 + }
  267 + },
  268 + yAxis: {
  269 + type: 'value',
  270 + axisLine:{
  271 + show:true,
  272 + },
  273 + //分隔线样式
  274 + splitLine:{
  275 + show:true,
  276 + lineStyle:{
  277 + type:'dashed'
  278 + }
  279 + }
  280 + },
  281 + series: [
  282 + {
  283 + data: [],
  284 + type: 'bar',
  285 + barWidth: 26,//设置柱状图大小
  286 + itemStyle:{
  287 + borderRadius:[20,20,0,0]
  288 + }
  289 + }
  290 + ]
  291 + }
  292 + bizCharts.setOption(bizOption);
  293 +
  294 + devCharts = echarts.init(devChartsRefs.value);
  295 + let devOption = {
  296 + grid:{
  297 + top:"8%",
  298 + bottom:"4%",
  299 + left:"2%",
  300 + containLabel:true,
  301 + },
  302 + tooltip: {
  303 + trigger: 'axis',
  304 + axisPointer: {
  305 + type: 'shadow',
  306 + }
  307 + },
  308 + color:"#60a0f7",
  309 + xAxis: {
  310 + type: 'category',
  311 + data: [],
  312 + axisTick:false,
  313 + axisLabel: {
  314 + interval: 0,
  315 + formatter: val => {
  316 + // 标签长度
  317 + const valLength = val.length
  318 + if (valLength > 8) {
  319 + return val.slice(0,7) + '...';
  320 + } else {
  321 + return val
  322 + }
  323 + }
  324 + }
  325 + },
  326 + yAxis: {
  327 + type: 'value',
  328 + axisLine:{
  329 + show:true,
  330 + },
  331 + //分隔线样式
  332 + splitLine:{
  333 + show:true,
  334 + lineStyle:{
  335 + type:'dashed'
  336 + }
  337 + }
  338 + },
  339 + series: [
  340 + {
  341 + data: [],
  342 + type: 'bar',
  343 + barWidth: 26,//设置柱状图大小
  344 + itemStyle:{
  345 + borderRadius:[20,20,0,0]
  346 + }
  347 + }
  348 + ]
  349 + }
  350 + devCharts.setOption(devOption);
  351 +
  352 + snapshotCharts = echarts.init(snapshotChartsRefs.value);
  353 + let shapshotOption = {
  354 + grid:{
  355 + top:"8%",
  356 + bottom:"8%",
  357 + left:"2%",
  358 + containLabel:true,
  359 + },
  360 + tooltip: {
  361 + trigger: 'axis',
  362 + axisPointer: {
  363 + type: 'shadow',
  364 + }
  365 + },
  366 + color:"#EF8166",
  367 + xAxis: {
  368 + type: 'value',
  369 + axisLine:{
  370 + show:true,
  371 + },
  372 + //分隔线样式
  373 + splitLine:{
  374 + show:true,
  375 + lineStyle:{
  376 + type:'dashed'
  377 + }
  378 + }
  379 + },
  380 + yAxis: {
  381 + type: 'category',
  382 + data: [],
  383 + axisTick:false,
  384 + },
  385 + series: [
  386 + {
  387 + data: [],
  388 + type: 'bar',
  389 + barWidth: 26,//设置柱状图大小
  390 + itemStyle:{
  391 + borderRadius:[0,20,20,0]
  392 + }
  393 + }
  394 + ]
  395 + }
  396 + snapshotCharts.setOption(shapshotOption);
  397 +
  398 + peopleSSCharts = echarts.init(peopleSSChartsRefs.value);
  399 + let peopleOption = {
  400 + grid:{
  401 + top:"14%",
  402 + bottom:"8%"
  403 + },
  404 + //color:"#60a0f7",
  405 + tooltip: {
  406 + trigger: 'item'
  407 + },
  408 + legend: {
  409 + orient: 'vertical',
  410 + top:"middle",
  411 + right:"10%",
  412 + itemWidth:35,
  413 + icon:"rect",
  414 + },
  415 + series: [
  416 + {
  417 + data: [],
  418 + center: ['40%', '50%'],
  419 + type: 'pie',
  420 + //高亮状态的扇区和标签样式。
  421 + emphasis: {
  422 + label: {
  423 + show: true
  424 + },
  425 + itemStyle: {
  426 + shadowBlur: 10,
  427 + shadowOffsetX: 0,
  428 + shadowColor: 'rgba(0, 0, 0, 0.5)'
  429 + }
  430 + },
  431 + label: {
  432 + show: false
  433 + },
  434 + }
  435 + ]
  436 + }
  437 + peopleSSCharts.setOption(peopleOption);
  438 + }
  439 + // 表格删除事件
  440 + let handleDel = (row)=>{
  441 + // console.log(row);
  442 + proxy.$global.confirm("确认删除吗?", function () {
  443 + deleteItems([row.resId],[row.batchNo]);
  444 + })
  445 + }
  446 + //删除
  447 + let deleteItems = (ids,nos) => {
  448 + let params = {
  449 + resId: ids.toString(),
  450 + batchNo:nos.toString(),
  451 + }
  452 + proxy.$http.get('/api-web/snapshot/his/delete', params, function (res) {
  453 + if (res && res.success) {
  454 + proxy.$global.showMsg('删除成功');
  455 + handleQuery();
  456 + }
  457 + })
  458 + }
  459 + //快照详情
  460 + let handleDetail = (row)=>{
  461 + proxy.$global.openNewWin('template/detail/snapshot_detail', row.createUser+'在'+row.createTime+'创建的'+row.resName+'的快照', {resId:row.resId,'batchNo':row.batchNo},false);
  462 + }
  463 +
  464 +
  465 + //查看业务系统
  466 + let goBus = (row) => {
  467 + title.value = row.resName+'所属业务系统信息';
  468 + let busTypeAdmin = [];
  469 + for (let i = 0; i < row.busTypeName.split(',').length; i++) {
  470 + for (let j = 0; j < row.nickname.split(',').length; j++) {
  471 + if (i==j){
  472 + busTypeAdmin.push(row.busTypeName.split(',')[i]+'('+row.nickname.split(',')[i]+')')
  473 + }
  474 + }
  475 + }
  476 + busType.value = busTypeAdmin;
  477 + showBus.value = true;
  478 +
  479 + }
  480 + //关闭弹框
  481 + let cancelBtn = () => {
  482 + showBus.value = false;
  483 + }
  484 +
  485 + //查看资源详情
  486 + let goResDetail = (row) => {
  487 + proxy.$global.openDetail(row.resId, row.resType, proxy);
  488 + }
  489 +
  490 + // 时间范围快捷键 修改事件
  491 + let handleChangeDatetime = (value)=>{
  492 + visiblePopover.value = false;
  493 + queryParams.value.time = value.join(',');
  494 + getDataList();
  495 + getEchartsData();
  496 + }
  497 +
  498 +
  499 +
  500 + Vue.onMounted(()=>{
  501 + getEcharts();
  502 + getEchartsData();
  503 + getDataList();
  504 + })
  505 +
  506 + return {
  507 + height,
  508 + tableData,
  509 + queryParams,
  510 + btnGroupType,
  511 + loaddata,
  512 + handleBtnGroup,
  513 + bizChartsRefs,
  514 + devChartsRefs,
  515 + snapshotChartsRefs,
  516 + peopleSSChartsRefs,
  517 + datetimerange,
  518 + visiblePopover,
  519 + handleChangeDatetime,
  520 + handleDel,
  521 + goResDetail,
  522 + handleDetail,
  523 + goBus,
  524 + showBus,
  525 + cancelBtn,
  526 + title,
  527 + busType,
  528 + getResType,
  529 + getBizType,
  530 + handleQuery,
  531 + getUser
  532 + }
  533 + }
  534 +}