Authored by XuHaoJie

Merge branch 'master' of http://113.200.75.45:82/monitor_v3/hg-monitor-web into master-V32-XuHaoJie

 Conflicts:
	hg-monitor-web-zj/src/main/resources/static/vue3/src/router/index.js
@@ -809,17 +809,36 @@ layui.define(['xmSelect', 'md5'], function (exports) { @@ -809,17 +809,36 @@ layui.define(['xmSelect', 'md5'], function (exports) {
809 }, 809 },
810 //打开性能曲线图 810 //打开性能曲线图
811 openLineChart: function (title, params) { 811 openLineChart: function (title, params) {
  812 + // Start 将对象转成key=value&key1=value1 LSQ 2022/1/17
  813 + let urlParams='';
  814 + for(let key in params){
  815 + if(params[key]){
  816 + urlParams+=key+'='+params[key]+'&'
  817 + }
  818 + }
  819 + urlParams=urlParams.substr(0,urlParams.length-1)
  820 + //End LSQ 2022/1/17
812 if (!title) { 821 if (!title) {
813 title = "性能曲线图"; 822 title = "性能曲线图";
814 } 823 }
815 view('commonViewModel').render("template/detail/line").then(function (res) { 824 view('commonViewModel').render("template/detail/line").then(function (res) {
  825 + // Start ident==1为性能趋势 LSQ 2022/1/17
  826 + let type=1;
  827 + let content=laytpl(res.body).render(JSON.stringify(params));
  828 + if(params.ident && params.ident == 1){
  829 + type=2;
  830 + content=['/vue3/index.html#/vue3/pieDetailLine?'+urlParams, 'no'];
  831 + }
  832 + //End LSQ 2022/1/17
816 layer.open({ 833 layer.open({
817 title: [title, 'font-size:18px;'], 834 title: [title, 'font-size:18px;'],
818 - type: 1, 835 + // type: 1,
  836 + type: type,
819 area: ['80%', '90%'], 837 area: ['80%', '90%'],
820 shadeClose: true,//开启遮罩层 838 shadeClose: true,//开启遮罩层
821 id: 'line_chart_div', 839 id: 'line_chart_div',
822 - content: laytpl(res.body).render(JSON.stringify(params)), 840 + // content: laytpl(res.body).render(JSON.stringify(params)),
  841 + content: content,
823 cancel: function () { 842 cancel: function () {
824 clearTimeout(obj.lineTimer); 843 clearTimeout(obj.lineTimer);
825 } 844 }
@@ -1808,7 +1827,6 @@ layui.define(['xmSelect', 'md5'], function (exports) { @@ -1808,7 +1827,6 @@ layui.define(['xmSelect', 'md5'], function (exports) {
1808 } 1827 }
1809 } 1828 }
1810 }); 1829 });
1811 -  
1812 //对外暴露的接口 1830 //对外暴露的接口
1813 exports('common', obj); 1831 exports('common', obj);
1814 }); 1832 });
@@ -136,11 +136,13 @@ layui.define(['laytpl', 'layer'], function(exports){ @@ -136,11 +136,13 @@ layui.define(['laytpl', 'layer'], function(exports){
136 return; 136 return;
137 } 137 }
138 if(e.status == '401'){ 138 if(e.status == '401'){
139 - layer.msg("登录凭证失效,请重新登录验证!", {  
140 - icon: 7, time: 3000  
141 - },function () {  
142 - view.exit();  
143 - }); 139 + if(localStorage.getItem('access_token')) {
  140 + layer.msg("登录凭证失效,请重新登录验证!", {
  141 + icon: 7, time: 3000
  142 + }, function () {
  143 + view.exit();
  144 + });
  145 + }
144 }else if(e.status == '500'){ 146 }else if(e.status == '500'){
145 layer.msg("服务异常,请联系管理员!</br>错误信息:"+e.responseJSON["resp_msg"], { 147 layer.msg("服务异常,请联系管理员!</br>错误信息:"+e.responseJSON["resp_msg"], {
146 icon: 7, time: 5000 148 icon: 7, time: 5000
@@ -254,7 +256,15 @@ layui.define(['laytpl', 'layer'], function(exports){ @@ -254,7 +256,15 @@ layui.define(['laytpl', 'layer'], function(exports){
254 } 256 }
255 257
256 if(e.status === 404){ 258 if(e.status === 404){
257 - that.render('template/tips/404'); 259 + if(!localStorage.getItem('access_token')) {
  260 + layer.msg("登录凭证失效,请重新登录验证!", {
  261 + icon: 7, time: 3000
  262 + }, function () {
  263 + view.exit()
  264 + });
  265 + } else {
  266 + that.render('template/tips/404');
  267 + }
258 } else { 268 } else {
259 that.render('template/tips/error'); 269 that.render('template/tips/error');
260 } 270 }
@@ -85,7 +85,8 @@ @@ -85,7 +85,8 @@
85 data-name="{{item.favName}}" data-res="{{item.resNum}}"> 85 data-name="{{item.favName}}" data-res="{{item.resNum}}">
86 </div> 86 </div>
87 </div> 87 </div>
88 - <div class="layui-card-header favorite-title" data-id="{{item.favId}}" id="title_{{item.favId}}">{{item.favName}}</div> 88 +<!-- LH 我的收藏夹文件名过长省略并悬浮提示-->
  89 + <div style="white-space:nowrap;text-overflow: ellipsis;overflow: hidden;word-break: break-all;" class="layui-card-header favorite-title" data-id="{{item.favId}}" id="title_{{item.favId}}" lay-tips="{{item.favName}}">{{item.favName}}</div>
89 </div> 90 </div>
90 </div> 91 </div>
91 {{# }); }} 92 {{# }); }}
@@ -64,3 +64,64 @@ @@ -64,3 +64,64 @@
64 .userright .roles{ 64 .userright .roles{
65 border: solid 1px rgb(251, 196, 196); 65 border: solid 1px rgb(251, 196, 196);
66 } 66 }
  67 +/*时间范围组件 // Start LSQ 2022/1/17*/
  68 +.drop-active{
  69 + background-color: #ecf5ff;
  70 + color: #66b1ff;
  71 +}
  72 +.select-div{
  73 + margin-left: 10px;
  74 +}
  75 +.date-flex-div-around{
  76 + display: flex;
  77 +}
  78 +
  79 +/* 性能趋势图 */
  80 +.pie-detail-title{
  81 + border-bottom: 1px solid #f6f6f6;
  82 + height: 42px;
  83 + display: flex;
  84 + align-items: center;
  85 + padding:0 20px;
  86 +}
  87 +.pie-detail-title-active{
  88 + min-width: 65px;
  89 + border-bottom: 2px solid #5FB878;
  90 + line-height: 43px;
  91 +}
  92 +.pie-detail-content{
  93 + margin:20px;
  94 + padding:20px;
  95 + border:1px solid #f6f6f6;
  96 +}
  97 +.pie-line-filter{
  98 + margin-left: 20px;
  99 +}
  100 +.detail-content{
  101 + margin-top:20px;
  102 +}
  103 +.detail_linechart {
  104 + height: 400px !important;
  105 +}
  106 +.line-filter-content{
  107 + display: flex;
  108 + justify-content: end;
  109 +}
  110 +.line-filter-item.active{
  111 + background: #1E9FFF;
  112 + color: #fff;
  113 +}
  114 +.line-filter-item{
  115 + padding: 0 8px;
  116 + border-radius: 2px;
  117 + line-height: 30px;
  118 + letter-spacing: 3px;
  119 + cursor: pointer;
  120 +}
  121 +.pie-flex-end{
  122 + display: flex;
  123 + justify-content: end;
  124 + align-items: center;
  125 +}
  126 +
  127 +/* //End LSQ 2022/1/17*/
  1 +<el-row class="dataRange-container">
  2 + <el-col :span="24">
  3 + <div class="tabs-div date-flex-div-around">
  4 + <el-col :span="18">
  5 + <el-date-picker
  6 + class="picker-div"
  7 + v-model="dateValue"
  8 + type="datetimerange"
  9 + range-separator="--"
  10 + start-placeholder="开始时间"
  11 + end-placeholder="结束时间"
  12 + format="YYYY-MM-DD hh:mm:ss"
  13 + value-format="YYYY-MM-DD hh:mm:ss"
  14 + :shortcuts="shortcuts"
  15 + @change="changeDate"
  16 + size="small"
  17 + >
  18 + </el-date-picker>
  19 + </el-col>
  20 + <el-col :span="6" class="select-div">
  21 + <!-- <el-select v-model="checkedId" class="m-2" placeholder="聚合频率" size="large">
  22 + <el-option
  23 + v-for="item in frequencyData"
  24 + :key="item.ddicDesc"
  25 + :label="item.ddicName"
  26 + :value="item.ddicDesc"
  27 + @change="changeItem"
  28 + >
  29 + </el-option>
  30 + </el-select>-->
  31 +
  32 + <el-dropdown split-button type="primary" size="small">
  33 + 聚合频率
  34 + <template #dropdown>
  35 + <el-dropdown-menu>
  36 + <el-dropdown-item :class="{'drop-active':checkedId==item.ddicDesc}" v-for="item in frequencyData" @click="changeItem(item.ddicDesc,item.ddicName)"
  37 + :key="item.ddicId"
  38 + :command="item.ddicDesc">
  39 + {{item.ddicName}}
  40 + </el-radio>
  41 + </el-dropdown-item>
  42 + </el-dropdown-menu>
  43 + </template>
  44 + </el-dropdown>
  45 + </el-col>
  46 + </div>
  47 + </el-col>
  48 +</el-row>
  1 +export default {
  2 + name: 'dateRange',
  3 + template: '',
  4 + components: {},
  5 + props: {
  6 + keys:{
  7 + type:String,
  8 + default: 'C620C1D453B79095A64314C8215335D5:KPI7054BC34:cpu'
  9 + },
  10 + dateValueData:{
  11 + type:Array,
  12 + default:[]
  13 + },
  14 + intervalGroup:{
  15 + type:String,
  16 + default:''
  17 + }
  18 + },
  19 + data () {
  20 + return {
  21 +
  22 + }
  23 + },
  24 + setup(props, {attrs, slots, emit}){
  25 + const {proxy} = Vue.getCurrentInstance();
  26 + //接口参数-开始结束时间
  27 + let timeScope=Vue.ref();
  28 + //接口参数-聚合频率
  29 + // let intervalGroup=Vue.ref(60);
  30 + //接口参数-资源id:指标id:flag,资源id:指标id:flag
  31 + let keysVal=props.keys;
  32 + //聚合频率数据
  33 + let frequencyData=Vue.ref([
  34 + {
  35 + name:'5分钟聚合',
  36 + val:5,
  37 + id:'001'
  38 + },{
  39 + name:'15分钟聚合',
  40 + val:15,
  41 + id:'002'
  42 + },{
  43 + name:'1小时聚合',
  44 + val:60,
  45 + id:'003'
  46 + },{
  47 + name:'12小时聚合',
  48 + val:720,
  49 + id:'004'
  50 + },{
  51 + name:'1天聚合',
  52 + val:1440,
  53 + id:'005'
  54 + },{
  55 + name:'不聚合',
  56 + val:0,
  57 + id:'006'
  58 + }
  59 + ])
  60 +
  61 + //自定义选择时间
  62 + let dateValue=Vue.ref();
  63 + //选中的聚合频率
  64 + let checkedId=Vue.ref();
  65 + let commandVal=Vue.ref('聚合频率')
  66 + //聚合频率选择
  67 + const changeItem=(val,name)=>{
  68 + checkedId.value=val;
  69 + commandVal.value=name;
  70 + loadPerformance();
  71 + emit('callbackrate',val)
  72 + }
  73 + //时间控件左侧
  74 + let shortcuts=Vue.ref([
  75 + {
  76 + text: '最近30分钟',
  77 + value: () => {
  78 + const end = new Date();
  79 + const start = formatDate(30,'m');
  80 + return [start, end]
  81 + },
  82 + },
  83 + {
  84 + text: '最近1小时',
  85 + value: () => {
  86 + const end = new Date();
  87 + const start = formatDate(1,'h');
  88 + return [start, end]
  89 + },
  90 + },
  91 + {
  92 + text: '最近1天',
  93 + value: () => {
  94 + const end = new Date();
  95 + const start = formatDate(1,'d');
  96 + return [start, end]
  97 + },
  98 + },
  99 + {
  100 + text: '最近3天',
  101 + value: () => {
  102 + const end = new Date();
  103 + const start = formatDate(3,'d');
  104 + return [start, end]
  105 + },
  106 + },
  107 + {
  108 + text: '最近7天',
  109 + value: () => {
  110 + const end = new Date();
  111 + const start = formatDate(7,'d');
  112 + return [start, end]
  113 + },
  114 + },
  115 + {
  116 + text: '最近15天',
  117 + value: () => {
  118 + const end = new Date();
  119 + const start = formatDate(15,'d');
  120 + return [start, end]
  121 + },
  122 + },
  123 + {
  124 + text: '最近1个月',
  125 + value: () => {
  126 + const end = new Date();
  127 + const start = formatDate(1,'M');
  128 + return [start, end]
  129 + },
  130 + },
  131 + {
  132 + text: '最近2个月',
  133 + value: () => {
  134 + const end = new Date();
  135 + const start = formatDate(2,'M');
  136 + return [start, end]
  137 + },
  138 + },
  139 + {
  140 + text: '最近3个月',
  141 + value: () => {
  142 + const end = new Date();
  143 + const start = formatDate(3,'M');
  144 + return [start, end]
  145 + },
  146 + },
  147 + {
  148 + text: '半年内',
  149 + value: () => {
  150 + const end = new Date();
  151 + const start = formatDate(6,'M');
  152 + return [start, end]
  153 + },
  154 + },
  155 + {
  156 + text: '1年内',
  157 + value: () => {
  158 + const end = new Date();
  159 + const start = formatDate(12,'M');
  160 + return [start, end]
  161 + },
  162 + },
  163 + {
  164 + text: '全部',
  165 + value: () => {
  166 + const end = new Date();
  167 + const start = ''
  168 + return [start, end]
  169 + },
  170 + },
  171 + ])
  172 + //开始时间
  173 + let startTime=Vue.ref();
  174 + //结束时间
  175 + let endTime=Vue.ref();
  176 + //相差天数
  177 + let calcDayNum=Vue.ref(0);
  178 + //时间范围改变选中
  179 + const changeDate=(val)=>{
  180 + calcDayNum.value=calcDay(val[0],val[1]);
  181 + getRate(calcCode(calcDayNum.value))
  182 + emit('callbacktime',val)
  183 +
  184 + }
  185 + //计算两个日期相差天数
  186 + const calcDay=(start,end)=>{
  187 + let endTime = new Date(end).getTime() / 1000 - parseInt(new Date(start).getTime() / 1000);
  188 + let timeDay = parseInt(endTime / 60 / 60 / 24); //相差天数
  189 + return timeDay;
  190 + }
  191 + //计算需要传参的code值
  192 + const calcCode=(val)=>{
  193 + let code='';
  194 + if(val>0 && val<7){
  195 + code='time_scope_DAY';
  196 + }else if(val>=7 && val<30){
  197 + code='time_scope_WEEK';
  198 + }else if(val>=30 && val<90){
  199 + code='time_scope_MONTH';
  200 + }else if(val>=90 && val<180){
  201 + code='time_scope_QUARTER';
  202 + }else if(val>=180 && val<365){
  203 + code='time_scope_SEMESTER';
  204 + }else if(val>=365){
  205 + code='time_scope_YEAR';
  206 + }
  207 + return code;
  208 + }
  209 +
  210 + //确定
  211 + const sureBtn=()=>{
  212 + let dateValueArr=dateValue.value;
  213 + if(dateValueArr && dateValueArr.length>0){
  214 + timeScope.value=dateValueArr.join(',');
  215 + }else{
  216 + timeScope.value='';
  217 + }
  218 +
  219 + loadPerformance();
  220 +
  221 + }
  222 + //查询性能数据-自定义视图
  223 + const loadPerformance=()=>{
  224 + let params={
  225 + timeScope:timeScope.value,
  226 + intervalGroup:checkedId.value,
  227 + keys:keysVal
  228 + }
  229 + proxy.$http.get(`/api-web/cm-data-range/loadPerformanceCustom`, params, function (res) {
  230 + emit('callbacksure',res)
  231 + })
  232 + }
  233 + //转换个位数为 00
  234 + let timeFormat =(number)=> {
  235 + return number.length == 1 ? ('0' + number) : number
  236 + }
  237 + //获取时间点 转年月日的方法
  238 + const getDateTime=(newDate)=>{
  239 + let dateTime='';
  240 + let year=newDate.getFullYear();//获取当前年
  241 + let month=timeFormat(newDate.getMonth()+1);//获取当前月
  242 + let day=timeFormat(newDate.getDate());//获取当前日
  243 + let hours=timeFormat(newDate.getHours()+'');//获取当前时
  244 + let minutes=timeFormat(newDate.getMinutes()+'');//获取当前分
  245 + let seconds=timeFormat(newDate.getSeconds()+'');//获取当前秒
  246 + dateTime= year+'-'+month+'-'+day+' '+hours+':'+minutes+':'+seconds;
  247 + return dateTime;
  248 + }
  249 + //获取前n段时间的时间点
  250 + const formatDate=(num,code)=>{
  251 + let m=num;
  252 + let myDate=new Date();
  253 + let lowData='';//当前年月日往前推m个月后获取到的年月日
  254 + if(code=='m'){
  255 + //当前时间前n分钟
  256 + myDate.setMinutes(myDate.getMinutes()-m);
  257 + lowData =getDateTime(myDate); //用了上面转年月日的方法
  258 +
  259 + }else if(code=='h'){
  260 + //当前时间前n小时
  261 + myDate.setHours(myDate.getHours()-m)
  262 + lowData =getDateTime(myDate); //用了上面转年月日的方法
  263 + }else if(code=='d'){
  264 + //当前时间前n天
  265 + myDate.setDate(myDate.getDate() - m);
  266 + lowData =getDateTime(myDate); //用了上面转年月日的方法
  267 + }else if(code=='M'){
  268 + //当前时间前n月
  269 + myDate.setMonth(myDate.getMonth()-m);
  270 + lowData =getDateTime(myDate); //用了上面转年月日的方法
  271 +
  272 + }else{
  273 +
  274 + }
  275 + return lowData;
  276 +
  277 + }
  278 + //判断是否传值进来
  279 + const isDetail=()=>{
  280 + if(props.dateValueData && props.dateValueData.length>0){
  281 + dateValue.value=props.dateValueData
  282 + changeDate(dateValue.value);
  283 + }
  284 + checkedId.value=props.intervalGroup;
  285 + }
  286 +
  287 + //获取聚合频率数据
  288 + const getRate=(defCode)=>{
  289 + let param = {
  290 + ddicName: defCode
  291 + }
  292 + proxy.$http.get(`/api-web/ContrastAnalysis/selectTogetherRate`, param, function (res) {
  293 + if (res && res.data) {
  294 + frequencyData.value = res.data;
  295 +
  296 + }
  297 + sureBtn();
  298 + });
  299 + }
  300 +
  301 + // 挂载完
  302 + Vue.onMounted(() => {
  303 + isDetail();
  304 +
  305 + })
  306 + return {
  307 + commandVal,
  308 + calcDayNum,
  309 + calcDay,
  310 + shortcuts,
  311 + timeScope,
  312 + keysVal,
  313 + startTime,
  314 + endTime,
  315 + frequencyData,
  316 + dateValue,
  317 + changeItem,
  318 + checkedId,
  319 + changeDate,
  320 + sureBtn,
  321 + timeFormat,
  322 + formatDate,
  323 + getDateTime,
  324 + loadPerformance
  325 + }
  326 +
  327 + }
  328 +
  329 +}
@@ -103,7 +103,7 @@ @@ -103,7 +103,7 @@
103 </el-row> 103 </el-row>
104 104
105 <cm-table-page :columns="columns" :dataList="dataList" @loaddata="getPage" :showIndex="true" 105 <cm-table-page :columns="columns" :dataList="dataList" @loaddata="getPage" :showIndex="true"
106 - :showBorder="false" :showSelection="false" :showTools="isEditName" 106 + :showBorder="false" :showSelection="true" :showTools="isEditName" @selectionChange="selectionChange"
107 :showPage="false" :height="height - 84"> 107 :showPage="false" :height="height - 84">
108 <template #default="{row,prop,column}"> 108 <template #default="{row,prop,column}">
109 <!--<div class="fileName-div" style="display: flex; align-items: center;" v-if="isEditName && prop == 'fileName'" @click="getFile(row)"> 109 <!--<div class="fileName-div" style="display: flex; align-items: center;" v-if="isEditName && prop == 'fileName'" @click="getFile(row)">
@@ -678,7 +678,22 @@ export default { @@ -678,7 +678,22 @@ export default {
678 } 678 }
679 let uploadCallBack = ({document, fileInfo}) => { 679 let uploadCallBack = ({document, fileInfo}) => {
680 reload(false); 680 reload(false);
681 - props.fileIds.push(document.id) 681 + if (document.category.toUpperCase() == document.category){
  682 + props.fileIds.push(document.id);
  683 + }
  684 + // Start 上传成功后弹出授权弹框 LSQ 2022/1/12
  685 + setTimeout(function (){
  686 + if(dataList.value && dataList.value.length>0){
  687 + dataList.value.map(v=>{
  688 + if(v.id==document.id){
  689 + v.checked=true;
  690 + }
  691 + })
  692 + showUserDialog(true);
  693 + }
  694 +
  695 + },1500)
  696 + //End LSQ 2022/1/12
682 // 执行回调 697 // 执行回调
683 emit('callback', {document, fileInfo}); 698 emit('callback', {document, fileInfo});
684 } 699 }
@@ -886,7 +901,32 @@ export default { @@ -886,7 +901,32 @@ export default {
886 isInput.value=item.id; 901 isInput.value=item.id;
887 } 902 }
888 903
  904 + // Start 列表模式增加多选框 LSQ 2022/1/12
  905 + //表格全选事件
  906 + let selectionChange=(val)=>{
  907 + let tableDataList=dataList.value;
  908 + tableDataList.map((v,i)=>{
  909 + v.checked=false;
  910 + })
  911 + let selectData=val;
  912 + if(selectData.length>0){
  913 + selectData.map((item,index)=>{
  914 + tableDataList.map((v,i)=>{
  915 + if(item.id==v.id){
  916 + v.checked=true;
  917 + }
  918 + })
  919 + })
  920 +
  921 + }else{
  922 + tableDataList.map((v,i)=>{
  923 + v.checked=false;
  924 + })
  925 + }
  926 + }
  927 + //End LSQ 2022/1/12
889 return { 928 return {
  929 + selectionChange,
890 /* viewEdit,*/ 930 /* viewEdit,*/
891 breadcrumbList, 931 breadcrumbList,
892 editFileName, 932 editFileName,
@@ -40,7 +40,9 @@ Promise.all([ @@ -40,7 +40,9 @@ Promise.all([
40 //指标类型数 40 //指标类型数
41 .component('cm-kpi-type-tree-input', Vue.defineAsyncComponent(() => myImport('components/common/inputkpitree/index'))) 41 .component('cm-kpi-type-tree-input', Vue.defineAsyncComponent(() => myImport('components/common/inputkpitree/index')))
42 //所属系统 42 //所属系统
43 - .component('cm-biz-type-tree-input', Vue.defineAsyncComponent(() => myImport('components/common/inputbiztypetree/index'))); 43 + .component('cm-biz-type-tree-input', Vue.defineAsyncComponent(() => myImport('components/common/inputbiztypetree/index')))
  44 + //时间范围组件
  45 + .component('cm-date-range', Vue.defineAsyncComponent(() => myImport('components/common/dateRange/index')));
44 46
45 47
46 // // 自定义指令 48 // // 自定义指令
@@ -29,7 +29,7 @@ layui.define(['table', 'form', 'admin', 'layer', 'laytpl', 'common', 'view', 'se @@ -29,7 +29,7 @@ layui.define(['table', 'form', 'admin', 'layer', 'laytpl', 'common', 'view', 'se
29 var oldBusTypeCode = data && data.busTypeCode ? data.busTypeCode : ''; 29 var oldBusTypeCode = data && data.busTypeCode ? data.busTypeCode : '';
30 30
31 var busType; 31 var busType;
32 - 32 +
33 // 父业务下拉框 33 // 父业务下拉框
34 admin.req({ 34 admin.req({
35 url: domainName + '/api-web/manage/bustype/page', 35 url: domainName + '/api-web/manage/bustype/page',
@@ -71,10 +71,16 @@ layui.define(['table', 'form', 'admin', 'layer', 'laytpl', 'common', 'view', 'se @@ -71,10 +71,16 @@ layui.define(['table', 'form', 'admin', 'layer', 'laytpl', 'common', 'view', 'se
71 busType = response.data[0]; 71 busType = response.data[0];
72 form.val('form-bustype-edit', busType); 72 form.val('form-bustype-edit', busType);
73 $('form[lay-filter="form-bustype-edit"] input[name="busTypeCode"]').attr('readonly', true); 73 $('form[lay-filter="form-bustype-edit"] input[name="busTypeCode"]').attr('readonly', true);
74 - userSelect.setValue([busType.admin]); 74 + setTimeout(function (){
  75 + userSelect.setValue([busType.admin]);
  76 + },2000)
  77 +
75 let principal = busType.principal; 78 let principal = busType.principal;
76 let principalLi = principal ? principal.split(",") : []; 79 let principalLi = principal ? principal.split(",") : [];
77 - opsSelect.setValue(principalLi); 80 + setTimeout(function (){
  81 + opsSelect.setValue(principalLi);
  82 + },2000)
  83 +
78 84
79 //是否启用 1启用 0不启用 85 //是否启用 1启用 0不启用
80 let isUse = busType.isUse || busType.isUse == 0 ? busType.isUse : 1; 86 let isUse = busType.isUse || busType.isUse == 0 ? busType.isUse : 1;
@@ -209,6 +215,7 @@ layui.define(['table', 'form', 'admin', 'layer', 'laytpl', 'common', 'view', 'se @@ -209,6 +215,7 @@ layui.define(['table', 'form', 'admin', 'layer', 'laytpl', 'common', 'view', 'se
209 function initUserSelect() { 215 function initUserSelect() {
210 $.ajax({ 216 $.ajax({
211 url: domainName + '/api-user/users/getAll?access_token=' + accessToken, 217 url: domainName + '/api-user/users/getAll?access_token=' + accessToken,
  218 + sync: false,
212 success: function (res) { 219 success: function (res) {
213 userSelect = xmSelect.render({ 220 userSelect = xmSelect.render({
214 el: '.adminUser', 221 el: '.adminUser',
@@ -231,6 +238,7 @@ layui.define(['table', 'form', 'admin', 'layer', 'laytpl', 'common', 'view', 'se @@ -231,6 +238,7 @@ layui.define(['table', 'form', 'admin', 'layer', 'laytpl', 'common', 'view', 'se
231 function initUserSelectOps() { 238 function initUserSelectOps() {
232 $.ajax({ 239 $.ajax({
233 url: domainName + '/api-user/users/getAll?access_token=' + accessToken, 240 url: domainName + '/api-user/users/getAll?access_token=' + accessToken,
  241 + sync: false,
234 success: function (res) { 242 success: function (res) {
235 opsSelect = xmSelect.render({ 243 opsSelect = xmSelect.render({
236 el: '#opsProject-username-select', 244 el: '#opsProject-username-select',
@@ -254,4 +262,4 @@ layui.define(['table', 'form', 'admin', 'layer', 'laytpl', 'common', 'view', 'se @@ -254,4 +262,4 @@ layui.define(['table', 'form', 'admin', 'layer', 'laytpl', 'common', 'view', 'se
254 }); 262 });
255 263
256 }); 264 });
257 -});  
  265 +});
@@ -106,7 +106,6 @@ body{ @@ -106,7 +106,6 @@ body{
106 align-items: center; 106 align-items: center;
107 width: 20px; 107 width: 20px;
108 height: 20px; 108 height: 20px;
109 - background:rgb(30,159,255);  
110 border-radius: 2px; 109 border-radius: 2px;
111 cursor: pointer; 110 cursor: pointer;
112 } 111 }
@@ -176,4 +175,5 @@ body{ @@ -176,4 +175,5 @@ body{
176 .list-handle{ 175 .list-handle{
177 display: flex; 176 display: flex;
178 justify-content: space-around; 177 justify-content: space-around;
  178 + color:rgb(30,159,255);
179 } 179 }
@@ -156,6 +156,11 @@ const routes = [{ @@ -156,6 +156,11 @@ const routes = [{
156 component: () => myImport('views/portSenseConfig/index') 156 component: () => myImport('views/portSenseConfig/index')
157 }, 157 },
158 { 158 {
  159 + path: '/vue3/pieDetailLine',
  160 + name: 'pieDetailLine',
  161 + component: () => myImport('views/pieDetailLine/index')
  162 + },
  163 + {
159 path: '/vue3/portSenseSelect', 164 path: '/vue3/portSenseSelect',
160 name: 'portSenseSelect', 165 name: 'portSenseSelect',
161 component: () => myImport('views/portSenseSelect/index') 166 component: () => myImport('views/portSenseSelect/index')
@@ -46,7 +46,7 @@ @@ -46,7 +46,7 @@
46 <template #default="scope"> 46 <template #default="scope">
47 <div class="list-handle"> 47 <div class="list-handle">
48 <span class="icon-bg"> 48 <span class="icon-bg">
49 - <i class="icon-list icon-list-delete" title="删除" @click="handleDelete(scope.row)"></i> 49 + <i class="el-icon-delete" title="删除" @click="handleDelete(scope.row)"></i>
50 </span> 50 </span>
51 <span class="icon-bg"> 51 <span class="icon-bg">
52 <i class="el-icon-edit-outline" title="修改" @click="handleUpdate(scope.row)"></i> 52 <i class="el-icon-edit-outline" title="修改" @click="handleUpdate(scope.row)"></i>
@@ -61,7 +61,6 @@ export default { @@ -61,7 +61,6 @@ export default {
61 //点击标签进行搜索 61 //点击标签进行搜索
62 const changeTag = (status) => { 62 const changeTag = (status) => {
63 currentPage.value=1; 63 currentPage.value=1;
64 - pageSize.value=10;  
65 checkedId.value = status; 64 checkedId.value = status;
66 keyword.value=status; 65 keyword.value=status;
67 getDataList(); 66 getDataList();
@@ -136,7 +135,6 @@ export default { @@ -136,7 +135,6 @@ export default {
136 // 点击按钮搜索 135 // 点击按钮搜索
137 let onBtnSearch = () => { 136 let onBtnSearch = () => {
138 currentPage.value=1; 137 currentPage.value=1;
139 - pageSize.value=10;  
140 getDataList(); 138 getDataList();
141 } 139 }
142 //获取缓存数据 140 //获取缓存数据
@@ -151,6 +149,8 @@ export default { @@ -151,6 +149,8 @@ export default {
151 if (res && res.data) { 149 if (res && res.data) {
152 count.value = res.count; 150 count.value = res.count;
153 tableDataList.value = res.data; 151 tableDataList.value = res.data;
  152 + }else{
  153 + tableDataList.value='暂无数据';
154 } 154 }
155 }); 155 });
156 } 156 }
  1 +<div class="pie-detail-line-container" >
  2 + <div class="pie-detail-title">
  3 + <span class="pie-detail-title-active">性能走势</span>
  4 + </div>
  5 + <!-- 趋势分析 预警分析-->
  6 + <div class="pie-detail-content">
  7 + <el-row class="detail-content-title">
  8 + <el-col :span="8"></el-col>
  9 + <el-col :span="16" class="pie-flex-end">
  10 + <cm-date-range v-if="interval=='custom'" @callbacksure="getOptionData" @callbacktime="callbacktime" @callbackrate="callbackrate"></cm-date-range>
  11 + <div class="line-filter pie-line-filter">
  12 + <div class="linechartfrequency line-filter-content">
  13 + <div v-if="interval!='custom'" @click="changeInterval('DAY')" :class="['line-filter-item', {'active':interval=='DAY'}]" data-value="DAY" >一天</div>
  14 + <div v-if="interval!='custom'" @click="changeInterval('WEEK')" :class="['line-filter-item', {'active':interval=='WEEK'}]" data-value="WEEK">一周</div>
  15 + <div v-if="interval!='custom'" @click="changeInterval('MONTH')" :class="['line-filter-item', {'active':interval=='MONTH'}]" data-value="MONTH">一月</div>
  16 + <div v-if="interval!='custom'" @click="changeInterval('YEAR')" :class="['line-filter-item', {'active':interval=='YEAR'}]" data-value="YEAR">一年</div>
  17 + <div v-if="interval!='custom'" @click="changeInterval('custom')" :class="['line-filter-item', {'active':interval=='custom'}]" data-value="custom">自定义</div>
  18 + <div v-if="interval=='custom'" @click="changeInterval('DAY')" :class="['line-filter-item', {'active':interval=='custom'}]" data-value="custom">取消自定义</div>
  19 + </div>
  20 + </div>
  21 +
  22 + </el-col>
  23 +
  24 + </el-row>
  25 + <el-row class="detail-content">
  26 + <el-col :span="24" class="detail_linechart">
  27 + <LineChart :optionData="optionData" v-if="optionData"></LineChart>
  28 +
  29 +<!-- <div class="detail_linechart" id="indentKpiLineChart"></div>-->
  30 + <!-- <div class="detail_linechart" id="warningKpiLineChart" style="margin-top:35px;"></div>-->
  31 + <!-- <div class="detail_linechart" id="line-tingyun-trendKpiLineChart" style="margin-top:35px;"></div>-->
  32 +
  33 +
  34 + </el-col>
  35 + </el-row>
  36 + </div>
  37 +
  38 +</div>
  39 +
  1 +export default {
  2 + name: 'pieDetailLine',
  3 + template: '',
  4 + components:{
  5 + 'LineChart': Vue.defineAsyncComponent(
  6 + () => myImport('views/zjdaping/components/lineChart/index')
  7 + )
  8 + },
  9 + data() {
  10 + return{}
  11 + },
  12 + setup(props, {attrs, slots, emit}) {
  13 + const {proxy} = Vue.getCurrentInstance();
  14 + let interval=Vue.ref('DAY');
  15 + let optionData=Vue.ref({});
  16 + let names = Vue.ref(['00:00', '01:00', '02:00', '03:00', '04:00', '05:00', '06:00', '07:00', '08:00', '09:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00', '21:00', '22:00', '23:00']);
  17 + let series = Vue.ref([]);
  18 + let rateData = Vue.ref([]);
  19 + let kpiUnit = Vue.ref('');
  20 + let kpiName = Vue.ref('');//指标名称
  21 + let startTime=Vue.ref('');
  22 + let endTime=Vue.ref('');
  23 + let colorsArr=Vue.ref([
  24 + {
  25 + start: '#46d6d8',
  26 + end: '#2883d0'
  27 + },
  28 + {
  29 + start: '#facf5b',
  30 + end: '#f77623'
  31 + },
  32 + {
  33 + start: '#C04DD8',
  34 + end: '#D81F72'
  35 + },
  36 + {
  37 + start: '#F5A1EB',
  38 + end: '#A04DE2'
  39 + },
  40 + {
  41 + start: '#F36093',
  42 + end: '#FF465C'
  43 + },
  44 + {
  45 + start: '#C2E74D',
  46 + end: '#00AE8B'
  47 + },
  48 + {
  49 + start: '#3DC3FF',
  50 + end: '#01FFFF'
  51 + },
  52 + {
  53 + start: '#B850ED',
  54 + end: '#9062EF'
  55 + },
  56 + {
  57 + start: '#305be6',
  58 + end: '#36a7d3'
  59 + },
  60 + {
  61 + start: '#FFA500',
  62 + end: '#FFEE00'
  63 + },
  64 + {
  65 + start: '#C4E64C',
  66 + end: '#2de078'
  67 + },
  68 + {
  69 + start: '#30ffb3',
  70 + end: '#01FFFF'
  71 + },
  72 + {
  73 + start: '#FF4488',
  74 + end: '#F13EFF'
  75 + },
  76 + {
  77 + start: '#A64CE2',
  78 + end: '#625AE7'
  79 + },
  80 + {
  81 + start: '#5AEBC7',
  82 + end: '#5FC9F8'
  83 + },
  84 + {
  85 + start: '#FFA500',
  86 + end: '#FFEE00'
  87 + },
  88 + {
  89 + start: '#00AAD6',
  90 + end: '#625AE7'
  91 + },
  92 + {
  93 + start: '#E48BDE',
  94 + end: '#FF9262'
  95 + },
  96 + {
  97 + start: '#B2797B',
  98 + end: '#FF4B51'
  99 + },
  100 + {
  101 + start: '#ffe393',
  102 + end: '#feff5b'
  103 + }
  104 + ])
  105 + let keys=Vue.ref('');
  106 + let getOptionData=(res)=>{
  107 + let nameArr=[];
  108 + let dataArr=[];
  109 + if(res && res.success){
  110 + if(res.map){
  111 + let resData=res.map;
  112 + kpiUnit.value = resData.kpiUnit == null ? "" : resData.kpiUnit;
  113 + Object.keys(resData).forEach(function(key){
  114 + Object.keys(resData[key]).sort(function (a, b) {
  115 + return a<b?1:-1;
  116 + }).forEach(function(time){
  117 + nameArr.push(time);
  118 + dataArr.push(resData[key][time])
  119 + })
  120 + })
  121 + rateData.value = {
  122 + names: nameArr,
  123 + series: [{
  124 + "data": dataArr,
  125 + "name": '平均值'
  126 + }],
  127 + kpiUnit: kpiUnit.value
  128 + }
  129 +
  130 + }
  131 +
  132 + }else{
  133 + proxy.$global.showMsg(res.msg,'warning');
  134 + }
  135 +
  136 +
  137 + setSeries();
  138 +
  139 + }
  140 + const changeInterval=(val)=>{
  141 + interval.value=val;
  142 + if(val=='custom'){
  143 + }else{
  144 + getLineChart();
  145 +
  146 + }
  147 + }
  148 +
  149 + const getLineChart=()=>{
  150 + let params=proxy.$route.query
  151 + let resourceId=params.resId;//资源ID
  152 + let kpiId =params.kpiId; //指标ID
  153 + let flag =params.flag;//二级资源标识
  154 + let warning =params.warning;//预警指标标识
  155 + let ident =params.ident;//性能指标标识
  156 + let trend =params.trend;//趋势指标标识
  157 + keys.value=resourceId+":"+kpiId+":"+flag;
  158 + kpiName.value = params.name;//指标名称
  159 + let url = '/api-web/detail/performance/line/chart?interval=' + interval.value + '&startTime='
  160 + + startTime.value + '&endTime=' + endTime.value + '&resId=' + resourceId + '&kpiIds=' + kpiId + '&subResId=' + flag;
  161 + proxy.$http.get(url, {},function (res){
  162 + kpiUnit.value = res.data.kpiUnit == null ? "" : res.data.kpiUnit;
  163 + if (res.data && res.data.names.length == 0) {
  164 + rateData.value = {
  165 + names: ['00:00', '01:00', '02:00', '03:00', '04:00', '05:00', '06:00', '07:00', '08:00', '09:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00', '21:00', '22:00', '23:00'],
  166 + series: [{
  167 + "data": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  168 + "name": kpiName.value
  169 + }],
  170 + kpiUnit: kpiUnit.value
  171 + }
  172 + } else {
  173 + rateData.value = res.data;
  174 + }
  175 + setSeries();
  176 + },function (error){
  177 + rateData.value = {
  178 + names: ['00:00', '01:00', '02:00', '03:00', '04:00', '05:00', '06:00', '07:00', '08:00', '09:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00', '21:00', '22:00', '23:00'],
  179 + series: [{
  180 + "data": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  181 + "name": kpiName.value
  182 + }],
  183 + kpiUnit: kpiUnit.value
  184 + }
  185 + setSeries();
  186 + })
  187 +
  188 + }
  189 + const setSeries=()=>{
  190 + series.value=[];
  191 + $.each(rateData.value.series,function (i,v) {
  192 + series.value.push({
  193 + name: v.name,
  194 + type: 'line',
  195 + data: v.data,
  196 + symbolSize: 12,
  197 + symbol: 'circle',
  198 + itemStyle: {
  199 + normal: {
  200 + color: colorsArr.value[i].start //图标颜色
  201 + }
  202 + },
  203 + lineStyle: {
  204 + normal: {
  205 + width: 3, //连线粗细
  206 + color: colorsArr.value[i].end //连线颜色
  207 + }
  208 + }
  209 + })
  210 + });
  211 + optionDataInit();
  212 + }
  213 + const optionDataInit=()=>{
  214 +
  215 + optionData.value = {
  216 + tooltip: {
  217 + trigger: 'axis',
  218 + formatter:function (param) {
  219 + var tips = kpiName.value+" "+param[0].name +"<br/>";
  220 + $.each(param,function (i,v) {
  221 + tips += v.marker+" "+v.seriesName + ":"+v.value +kpiUnit.value+"</br>"
  222 + });
  223 + return tips;
  224 + }
  225 + },
  226 + legend: {
  227 + show: true
  228 + },
  229 + grid: {
  230 + top: '10%',
  231 + left: '3%',
  232 + right: '4%',
  233 + bottom: '3%',
  234 + containLabel: true
  235 + },
  236 + toolbox: {
  237 + feature: {
  238 + saveAsImage: {
  239 + show: false
  240 + }
  241 + }
  242 + },
  243 + xAxis: {
  244 + type: 'category',
  245 + data: rateData.value.names,
  246 + axisLine: {
  247 + lineStyle: {
  248 + color: '#c9c9c9'
  249 + }
  250 + },
  251 + axisLabel: {
  252 + color: '#232425',
  253 + showMaxLabel: true
  254 + },
  255 + splitArea: {
  256 + show: true,
  257 + areaStyle: {
  258 + color: ['rgba(200,200,200,0.1)', 'transparent'
  259 + ]
  260 + }
  261 + }
  262 + },
  263 + yAxis: {
  264 + type: 'value',
  265 + scale: true,
  266 + boundaryGap: ['10%', '10%'],
  267 + axisLine: {
  268 + lineStyle: {
  269 + color: '#232425'
  270 + },
  271 + show: false
  272 + },
  273 + axisTick: {
  274 + show: false
  275 + },
  276 + splitLine: {
  277 + lineStyle: {
  278 + color: ['#ccc']
  279 + }
  280 + }
  281 + },
  282 + series:series.value
  283 + };
  284 + }
  285 + //时间范围组件回调函数--时间范围
  286 + const callbacktime=(val)=>{
  287 +
  288 + }
  289 + //时间范围组件回调函数--聚合频率
  290 + const callbackrate=(val)=>{
  291 +
  292 + }
  293 + // 挂载完
  294 + Vue.onMounted(() => {
  295 + getLineChart();
  296 + })
  297 + return {
  298 + interval,
  299 + optionData,
  300 + names,
  301 + series,
  302 + rateData,
  303 + kpiUnit,
  304 + kpiName,
  305 + keys,
  306 + optionDataInit,
  307 + getOptionData,
  308 + getLineChart,
  309 + changeInterval
  310 + }
  311 + }
  312 +}