Authored by 王涛

Merge branch 'master' of http://192.168.1.136:82/monitor_v3/hg-monitor-web

 Conflicts:
	hg-monitor-web-base/src/main/resources/static/src/controller/commonDetail.js
... ... @@ -2288,7 +2288,7 @@ layui.define(['laytpl', 'admin', 'form', 'table', 'echarts', 'sessions', 'xmSele
* @param resId
*/
renderActiveAlarms: function (tableId, resId) {
//$('#'+tableId).prev().text('实时告警Top5')
$('#'+tableId).prev().text('实时告警Top5')
var alarmlist = table.render({
elem: '#' + tableId
, url: common.domainName + '/api-web/home/alarm/alarmListPage'
... ... @@ -2298,7 +2298,7 @@ layui.define(['laytpl', 'admin', 'form', 'table', 'echarts', 'sessions', 'xmSele
}
, height: 'auto'
, page: {
layout: ['count', 'prev', 'page', 'next', 'limit', 'skip']
layout: ['count', 'prev', 'page', 'next', 'skip']
,theme: '#1E9FFF'
}
, limit: 5
... ...
... ... @@ -134,11 +134,35 @@ layui.extend({
}
});
var tabName;
//start lsq 页面刷新后名称改变,把aj得存储到localStorage中 2022-04-18
let routerPath=router.path;
if(routerPath.indexOf('ajConfig')!=-1 && routerPath.indexOf('view')!=-1 && !localStorage.getItem(router.search.ajConfig)){
localStorage.setItem(router.search.ajConfig,admin.tabsPage.elem.text());
}
try {
let el = admin.tabsPage.elem;
if(el && el.attr('lay-href-type')){
if(el.attr('lay-href-type') == 'menu' && !matchTo){
tabName= admin.tabsPage.elem.text();
}
}
} catch (e){
}
if(!tabName){
if(routerPath.indexOf('ajConfig')!=-1 && routerPath.indexOf('view')!=-1){
tabName=localStorage.getItem(router.search.ajConfig);
}else{
tabName= res.title
}
}
//end lsq 页面刷新后名称改变 2022-04-18
//如果未在选项卡中匹配到,则追加选项卡
if(setter.pageTabs && pathURL !== '/'){
if(!matchTo){
var tabName='' // tab标签名
/*var tabName='' // tab标签名
var url=pathURL.substring(1)
tabList.forEach((e) =>{
if(url === e.path){
... ... @@ -147,7 +171,7 @@ layui.extend({
});
if(!tabName){
tabName= res.title
}
}*/
$(APP_BODY).append('<div class="layadmin-tabsbody-item layui-show"></div>');
tabsPage.index = tabs.length;
element.tabAdd(FILTER_TAB_TBAS, {
... ... @@ -164,7 +188,9 @@ layui.extend({
//定位当前tabs
element.tabChange(FILTER_TAB_TBAS, pathURL);
admin.tabsBodyChange(tabsPage.index);
// 修改为当前菜单名称 lsq 2022-04-18
$('* [lay-id="' + pathURL + '"] span').text(tabName)
admin.tabsBodyChange(tabsPage.index);
}).done(function(){
layui.use('common', layui.cache.callback.common);
... ...
<title>设计器配置信息</title>
<iframe src="/vue3/index.html#/vue3/ajConfig" class="layadmin-iframe" style="height: 99.5%!important;"/>
... ...
<title>设计器预览</title>
<script type="text/html" template>
{{#
var viewURL = window.location.origin + '/vue3/index.html#/ajConfig/view';
layui.use(['sessions','common','admin'], function () {
var $ = layui.$;
var common = layui.common;
var admin = layui.admin;
var arr = [];
window.location.hash.split('/').forEach(function (v, i) {
if (v.indexOf('=') != -1) {
arr.push(v);
}
});
if (arr.length > 0) {
viewURL += "?" + arr.join("&");
}
$('#actionListIframe').attr('src',viewURL);
});
}}
<iframe id="actionListIframe" src="{{viewURL}}" frameborder="0" class="layadmin-iframe" style="height: 99.5%!important;"></iframe>
</script>
... ...
... ... @@ -68,6 +68,16 @@ const routes = [{
name: 'cacheData',
component: () => myImport('views/cacheData/index')
},
{
path: '/vue3/ajConfig',
name: 'ajConfig',
component: () => myImport('views/ajConfig/index')
},
{
path: '/ajConfig/view',
name: 'ajConfigView',
component: () => myImport('views/ajConfig/view/index')
},
];
// hash模式: createWebHashHistory
... ...
<div class="container" :style="{'height':height+'px','max-height':height+'px'}">
<div class="cm-card" :style="{'min-height':height+'px','max-height':height+'px','height':'100%'}">
<div class="search">
<div class="keyword" style="padding-left: 10px">
<el-form-item >
<el-input v-model="search.keyword" placeholder="请输入关键字,回车搜索" @keydown.enter.native="getDataList"></el-input>
</el-form-item>
</div>
<div class="selectType" style="padding-left: 10px;width: 120px;">
<el-select v-model="couponSelected" class="m-2" placeholder="请选择" size="large" @change="onChangeStripe">
<el-option
v-for="item in typeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<div class="adds" style="">
<el-form-item>
<el-button @click="addAj()" style="margin-left: 10px">新增</el-button>
</el-form-item>
</div>
<div class="design" style="float:right;padding-left: 1200px">
<el-form-item>
<el-button type="primary" @click="handleView()" style="margin-left: 10px">设计</el-button>
</el-form-item>
</div>
</div>
<div class="search-table">
<cm-table-page :columns="columns" :dataList="tableDataList" @loaddata="loadTableDataList"
:showIndex="true" :total="count" :showSelection="true"
:showBorder="true" :loading="false" :pageSize="pageSize"
:showPage="true" :showTools="true" :height="(height - 130)" >
<template #default="{row,prop,column}">
<div v-if="prop == 'type'">
<div v-if="row.type == 0">
<el-tag>菜单</el-tag>
</div>
<div v-if="row.type == 1">
<el-tag>按钮</el-tag>
</div>
<div v-if="row.type == 2">
<el-tag>详情页</el-tag>
</div>
</div>
</template>
<template #tools="{scope}">
<div class="list-handle">
<span class="icon-bg">
<i class="el-icon-delete" title="删除" @click="handleDelete(scope.row)"></i>
</span>
<span class="icon-bg">
<i class="el-icon-edit-outline" title="修改" @click="handleUpdate(scope.row)"></i>
</span>
<span class="icon-bg">
<i class="el-icon-view" title="预览" @click="preview(scope.row)"></i>
</span>
</div>
</template>
</cm-table-page>
</div>
</div>
</div>
<!--新增编辑弹框-->
<cm-dialog :title="titleName" width="40%" :showDialogVisible="cacheVisible" @hidedialog="cancelBtn" :showFooter="false">
<template v-slot>
<el-form
label-width="120px"
ref="ruleForm"
:model="ajConfigFrom"
:rules="docRulesForm"
label-position="right"
label-width="120px">
<el-form-item label="编号" prop="id">
<el-input :size="$global.elementSize" v-model="ajConfigFrom.id" clearable></el-input>
</el-form-item>
<el-form-item label="类型" prop="type">
<div style="width: 240px">
<el-radio v-model="ajConfigFrom.type" label="0" size="large">菜单</el-radio>
<el-radio v-model="ajConfigFrom.type" label="1" size="large">按钮</el-radio>
<el-radio v-model="ajConfigFrom.type" label="2" size="large">详情页</el-radio>
</div>
<!-- <div style="height: 15px; color: darkgrey">说明:参数中间用'&'拼接</div>-->
</el-form-item>
<el-form-item label="父菜单" prop="menuPid" v-if="ajConfigFrom.type==0">
<el-select v-model="ajConfigFrom.menuPid"
filterable
allow-create
default-first-option
:reserve-keyword="false"
placeholder="请选择" style="width: 555px;">
<el-option
v-for="item in menuOptions"
:key="item.value"
:label="item.label"
:value="item.value"
:disabled="item.disabled">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="菜单名称" prop="menuName" v-if="ajConfigFrom.type==0">
<el-input :size="$global.elementSize" v-model="ajConfigFrom.menuName" clearable></el-input>
</el-form-item>
<el-form-item label="弹框标题" prop="title" v-if="ajConfigFrom.type==1">
<el-input :size="$global.title" v-model="ajConfigFrom.title" clearable></el-input>
</el-form-item>
<el-form-item label="设计页面" prop="designPage">
<el-select v-model="ajConfigFrom.designPage"
filterable
allow-create
default-first-option
:reserve-keyword="false"
placeholder="请选择" style="width: 510px;">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
:disabled="item.disabled">
</el-option>
</el-select>
<el-tag @click="preview(ajConfigFrom.designPage)" style="padding-top:4px;height: 38px; cursor:pointer">预览</el-tag>
</el-form-item>
<el-form-item label="传递参数" prop="param">
<el-input :size="$global.elementSize" v-model="ajConfigFrom.param" clearable></el-input>
<div style="color: darkgrey">
<div>
<el-collapse>
<el-collapse-item name="1">
<template #title>
示例:&resId=#resId&access_token=#access_token
</el-icon>
</template>
<div style="font-size: 12px;text-align: left">可配置字段:</div>
<el-descriptions :column="2" size="mini" border >
<el-descriptions-item v-for="item in configs">
<template #label>
<div class="cell-item">
{{ item.desc }}
</div>
</template>
{{ item.name }}
</el-descriptions-item>
</el-descriptions>
</el-collapse-item>
</el-collapse>
</div>
</div>
</el-form-item>
<el-form-item label="资源类型" prop="resType" v-if="ajConfigFrom.type==2" style="text-align: left">
<!--<el-input :size="$global.elementSize" v-model="ajConfigFrom.resType" clearable></el-input>-->
<el-dropdown>
<cm-res-type-tree-input multiple clearable collapseTags @callback="getResType"/>
</el-dropdown>
</el-form-item>
<el-form-item label="厂商" prop="provider" v-if="ajConfigFrom.type==2" style="text-align: left">
<!--<el-input :size="$global.elementSize" v-model="ajConfigFrom.firm" clearable></el-input>-->
<el-select v-model="ajConfigFrom.provider" filterable clearable collapse-tags placeholder="请选择厂商" style="width: 550px">
<el-option
v-for="item in ddicProvider"
:label="item.ddicName" :value="item.ddicCode"></el-option>
</el-select>
</el-form-item>
<el-form-item label="操作系统" prop="os" v-if="ajConfigFrom.type==2" style="text-align: left">
<!--<el-input :size="$global.elementSize" v-model="ajConfigFrom.firm" clearable></el-input>-->
<el-select v-model="ajConfigFrom.os" filterable clearable collapse-tags placeholder="请选择操作类型" style="width: 550px">
<el-option
v-for="item in ddicOS"
:label="item.ddicName" :value="item.ddicCode"></el-option>
</el-select>
</el-form-item>
<!--<el-form-item label="绑定资源" prop="resource" v-if="ajConfigFrom.type==2">
<el-input :size="$global.elementSize" v-model="ajConfigFrom.resource" clearable></el-input>
</el-form-item>-->
<el-form-item label="备注" prop="remark">
<el-input :size="$global.elementSize" v-model="ajConfigFrom.remark" clearable></el-input>
</el-form-item>
<el-form-item>
<el-button :size="$global.elementSize" type="primary" @click="addAjConfig('ruleForm')">保存</el-button>
<el-button :size="$global.elementSize" @click="cancelBtn">取消</el-button>
</el-form-item>
</el-form>
</template>
</cm-dialog>
... ...
export default {
name: 'ajConfig',
template: '',
components: {},
props:[],
data () {
return {
radio:'0',
docRulesForm: {
id: [
{
required: true,
message: '请填写配置编号!',
trigger: 'blur',
}
],
type:[{
required: true,
message: '请选择类型!',
trigger: 'blur',
}],
menuPid:[{
required: true,
message: '请选择父菜单!',
trigger: 'blur',
}],
menuName:[{
required: true,
message: '请填写菜单名称!',
trigger: 'blur',
}],
title:[{
required: true,
message: '请填写弹框标题!',
trigger: 'blur',
}],
designPage:[{
required: true,
message: '请选择设计页面!',
trigger: 'blur',
}],
resType:[{
required: true,
message: '请选择资源类型!',
trigger: 'blur',
}],
/*resource:[{
required: true,
message: '请填写绑定资源!',
trigger: 'blur',
}],*/
}
}
},
setup(props, {attrs, slots, emit}){
const {proxy} = Vue.getCurrentInstance();
let height = Vue.ref(window.innerHeight - 10);
let configs = Vue.ref([{
name:'resId',
desc:'资源ID(资源列表可用)'
},{
name:'access_token',
desc:'Token'
},{
name:'lgn',
desc:'登录账号'
},{
name:'user_id',
desc:'用户id'
}]);
//表格字段
let columns=Vue.ref([]);
let detailColumns=Vue.ref([
{
prop: 'id',
label: '编号',
sortable: true,
align: 'center',
width:'250'
},
{
prop: 'type',
label: '类型',
sortable: true,
align: 'center',
width:'250',
},
{
prop: 'resType',
label: '资源类型',
sortable: true,
align: 'center',
width:'250'
},{
prop: 'provider',
label: '品牌',
sortable: true,
align: 'center',
width:'250'
},{
prop: 'designPage',
label: '设计器编码',
sortable: true,
align: 'center',
width:'250'
},{
prop: 'param',
label: '参数',
sortable: true,
align: 'left'
}
])
let menuColumns=Vue.ref([
{
prop: 'id',
label: '编号',
sortable: true,
align: 'center',
width:'250'
},
{
prop: 'type',
label: '类型',
sortable: true,
align: 'center',
width:'250',
},
{
prop: 'menuName',
label: '菜单名称',
sortable: true,
align: 'center',
width:'250'
},
{
prop: 'designPage',
label: '设计器编码',
sortable: true,
align: 'center',
width:'250'
},{
prop: 'param',
label: '参数',
sortable: true,
align: 'center',
width:'300'
},{
prop: 'creatTime',
label: '创建时间',
sortable: true,
align: 'left'
}
])
let butColumns=Vue.ref([
{
prop: 'id',
label: '编号',
sortable: true,
align: 'center',
width:'250'
},
{
prop: 'type',
label: '类型',
sortable: true,
align: 'center',
width:'250',
},
{
prop: 'title',
label: '弹框标题',
sortable: true,
align: 'center',
width:'250'
},
{
prop: 'designPage',
label: '设计器编码',
sortable: true,
align: 'center',
width:'250'
},{
prop: 'param',
label: '参数',
sortable: true,
align: 'center',
width:'300'
},{
prop: 'creatTime',
label: '创建时间',
sortable: true,
align: 'left'
}
])
let currentPage=Vue.ref(1);
let pageSize=Vue.ref(10);
let keyword=Vue.ref();
let count=Vue.ref(0);
let tableDataList=Vue.ref([]);
let checkedId = Vue.ref(0);
let titleName=Vue.ref('新增配置信息')
let cacheVisible=Vue.ref(false);
let viewData=Vue.ref();
let addOrUpdate=Vue.ref(false)
let radio=Vue.ref(0);
//下拉框
let options=Vue.ref([]);
//菜单下拉框
let menuOptions=Vue.ref([]);
let search = Vue.ref({
keyword:'',
type:'',
page:1,
limit:10,
});
//按钮下拉框
let typeOptions=Vue.ref([
{
value: '0',
label: '菜单',
},
{
value: '1',
label: '按钮',
},
{
value: '2',
label: '详情页',
}]);
let couponSelected = Vue.ref();
let ajConfigFrom = Vue.ref({
id:'',
type: 0,
designPage: '',
param: '&resId=#resId&access_token=#access_token',
resType: '',
remark:'',
creatTime:'',
createName:'',
state:'',
title:'',
menuPid:'',
menuName:''
});
//新增弹框
const addAj=()=>{
clearForm();
cacheVisible.value=true;
pageList();
menuList();
}
//新增或修改aj配置信息
let addAjConfig=(ruleForm)=>{
let params={};
params= ajConfigFrom.value;
let msg = '';
if (addOrUpdate.value){
proxy.$http.post(`/api-web/ajConfig/updateAj`, params, function (res) {
if (res && res.success == true) {
msg = res.msg;
cacheVisible.value=false;
proxy.$global.showMsg(msg);
clearForm();
getDataList();
}
})
}else{
proxy.$http.post(`/api-web/ajConfig/addAj`, params, function (res) {
if (res && res.success == true) {
msg = res.msg;
cacheVisible.value=false;
proxy.$global.showMsg(msg);
if (params.type==0){
window.history.go(0);
}
clearForm();
getDataList();
}
})
}
}
//清理表单
let clearForm=()=>{
ajConfigFrom.value={
id:'',
type: '0',
designPage: '',
param: '',
resType: '',
remark:'',
creatTime:'',
createName:'',
state:'',
title:'',
menuPid:'',
menuName:''
}
addOrUpdate.value=false;
}
//删除
let handleDelete=(row)=>{
let param={
id:row.id
}
proxy.$http.get(`/api-web/ajConfig/deleteById`, param, function (res) {
if (res && res.success == true) {
let msg = res.msg;
if (!msg) {
msg = "删除失败";
}
if (row.type==0){
history.go(0);
}
proxy.$global.showMsg(msg);
getDataList();
}
})
}
let handleUpdate=(row)=>{
addOrUpdate.value =true;
ajConfigFrom.value=row;
cacheVisible.value=true;
pageList();
menuList();
}
//预览
let preview=(row)=>{
if (row instanceof Object){
proxy.$global.viewAjView(row.id,'80%','80%');
}else if (row){
proxy.$global.viewAjView(row,'80%','80%');
}
}
//aj报表管理信息
let pageList=()=>{
proxy.$http.get(`/api-web/ajConfig/pageList`, null, function (res) {
if (res && res.success == true) {
let params=res.object.data.records;
params.forEach(function(e){
let report={}
report.label=e.reportName;
report.value=e.reportCode;
options.value.push(report)
});
}
})
}
//菜单
let menuList=()=>{
proxy.$http.get(`/api-user/menus/findAlls`, null, function (res) {
if (res && res.count>0) {
let params=res.data;
params.forEach(function(e){
let menu={}
menu.label=e.name;
menu.value=e.id;
menuOptions.value.push(menu)
});
}
})
}
//AJ设计登录
let handleView=()=>{
window.open(sessionStorage.getItem("ajWeb") + '/#/login?access_token=' + localStorage.getItem("access_token"));
}
//重新加载表格数据
let loadTableDataList = ({page, limit}) => {
search.value.page = page;
search.value.limit = limit;
getDataList()
}
let onChangeStripe = (e)=>{
if(e =='0'){
columns.value=menuColumns.value;
}
if (e =='1'){
columns.value=butColumns.value;
}
if (e =='2'){
columns.value=detailColumns.value;
}
search.value.type=e;
getDataList()
}
//获取aj配置信息
let getDataList=()=>{
let params={
page:search.value.page,
limit:search.value.limit,
type:search.value.type,
keyword:search.value.keyword
}
proxy.$http.get(`/api-web/ajConfig/ajConfigList`,params, function (res) {
if (res && res.data) {
count.value = res.count;
tableDataList.value = res.data;
}else{
count.value = 0;
tableDataList.value='暂无数据';
}
});
}
//关闭弹框
let cancelBtn=()=>{
cacheVisible.value=false;
}
// 挂载完
Vue.onMounted(() => {
couponSelected.value = typeOptions.value[0].label;
columns.value=menuColumns.value;
search.value.type=typeOptions.value[0].value;
getDataList();
})
let getResType = (arr) => {
var types = arr.map(function (v) {
return v.id;
});
ajConfigFrom.value.resType = types[0];
}
// 加载字典项
let ddicProvider = Vue.ref([]);
let ddicOS = Vue.ref([]);
// let ddicProvider = Vue.ref([]);
proxy.$http.post(`/api-web/manage/ddic/findSucDdics/provider`, {}, function (res) {
if (res && res.data) {
ddicProvider.value = res.data;
}
});
proxy.$http.post(`/api-web/manage/ddic/findSucDdics/os`, {}, function (res) {
if (res && res.data) {
ddicOS.value = res.data;
}
});
return {
ddicProvider,
ddicOS,
height,
columns,
currentPage,
count,
pageSize,
keyword,
tableDataList,
checkedId,
addAj,
addAjConfig,
loadTableDataList,
getDataList,
cacheVisible,
titleName,
viewData,
cancelBtn,
ajConfigFrom,
handleDelete,
handleUpdate,
preview,
handleView,
pageList,
radio,
options,
menuList,
menuOptions,
getResType,
configs,
typeOptions,
onChangeStripe,
search,
butColumns,
detailColumns,
couponSelected
}
}
}
... ...
<div class="container" :style="{'height':height+'px','max-height':height+'px','background':'#fff'}">
<iframe :src="getSrc" width="100%" height="100%" ></iframe>
</div>
... ...
export default {
name: 'ajConfigViewIndex',
template: '',
components: {},
setup() {
const {proxy} = Vue.getCurrentInstance();
let getSrc = Vue.ref('');
let height = Vue.ref(window.innerHeight - 10);
let ajConfig = proxy.$global.getQueryVariable('ajConfig');
let getUrl=()=>{
let param={
id:ajConfig
}
let params='';
let designPage='';
proxy.$http.get(`/api-web/ajConfig/findOneById`, param, function (res) {
if (res && res.success == true && res.object) {
// 参数替换
params = replaceParams(res.object.param);
designPage = res.object.designPage;
}
getSrc.value=sessionStorage.getItem("ajWeb")+'/#/bigscreen/viewer?reportCode='+designPage+params+'&access_token=' + localStorage.getItem("access_token");
})
}
const replaceParams = (params) => {
let userId = sessionStorage.getItem('user_id');
if(!userId){
userId = localStorage.getItem('user_id');
}
return params.replace(/#lgn/g,localStorage.getItem('lgn')).replace(/#user_id/g,userId).replace(/#access_token/g,localStorage.getItem("access_token"))
}
const getParamValue = (code) => {
// 获取url参数
// 获取路由参数
// 获取sessionStorage
// 获取localStorage
}
// 挂载完
Vue.onMounted(() => {
getUrl();
//start lsq 监听跨域iframe子页面向父页面发送数据(子页面点击名称进入详情页) 2022-03-15
window.addEventListener('message',function(e){
if(e.data.type=='detail'){
proxy.$global.openDetail(e.data.data.resId, e.data.data.resType, proxy);
}else if(e.data.type=='topology'){
//子页面点击拓扑图标进入拓扑页面
proxy.$global.viewResTopo(e.data.data.resId);
}else{
}
})
//end lsq 2022-03-15
})
return {
height,
getSrc,
}
}
}
... ...
... ... @@ -39,6 +39,7 @@
sessionStorage.setItem('graphEditorOrigin', res1[0].mxgraph_editor);
sessionStorage.setItem('tingyun', res1[0].tingyun);
sessionStorage.setItem('bigScreen', res1[0].bigScreen);
sessionStorage.setItem('ajWeb', res1[0].ajWeb);//lsq 2022-04-07 设置ajWeb的地址
sessionStorage.setItem('sxView', res1[0].sxView);
sessionStorage.setItem('workflow', res1[0].workflow);
sessionStorage.setItem('mp3', res2[0].mp3);
... ...
... ... @@ -20,6 +20,8 @@ export default {
let kpiName = Vue.ref('');//指标名称
let startTime=Vue.ref('');
let endTime=Vue.ref('');
let startSlide=Vue.ref(0);
let endSlide=Vue.ref(100);
let colorsArr=Vue.ref([
{
start: '#46d6d8',
... ... @@ -226,6 +228,11 @@ export default {
const changeInterval=(val)=>{
interval.value=val;
if (val=='DAY'){
startSlide.value=0;
}else {
startSlide.value=75;
}
if(val=='custom'){
}else{
getLineChart();
... ... @@ -372,8 +379,8 @@ export default {
type: "slider",
realtime: true, //拖动滚动条时是否动态的更新图表数据
height: 25, //滚动条高度
start: 40, //滚动条开始位置(共100等份)
end: 65 //结束位置(共100等份)
start: startSlide, //滚动条开始位置(共100等份)
end: endSlide //结束位置(共100等份)
}
],
series:series.value
... ...