Authored by wangtao

Merge branch 'master-500-dev' of http://113.200.75.45:82/monitor_v3/hg-monitor-w…

…eb into master-500-dev
<title>license</title>
<iframe class="layadmin-iframe" src="/vue3/index.html#/vue3/license" style="height: 99.5%!important;"/>
... ...
<el-tree-select
:filterable="filterable"
:size="$global.elementConfig.size.input"
node-key="nodeKey"
:placeholder="placeholderText"
:props="defaultProps"
v-model="value"
:data="data"
@change="change"
check-strictly
:render-after-expand="false"
>
<template #default="{ node, data }">
<!-- //lsq 菜单类型,1:监控菜单,2:巡检菜单,3:个人工作台,4:系统菜单,5:跳转菜单,6:报表菜单 可以删除和编辑 2022-08-26-->
<el-tag v-if="isTag" style="height: 18px;margin-right:6px;">
{{getTypeName(data.type)}}</el-tag>
<span>{{ node.label }}</span>
</template>
</el-tree-select>
... ...
/**
* 下拉树组件
*/
export default {
name: 'treeSelect',
template: '',
components: {},
props: {
// 选中的值
value: {
type: String,
default: ''
},
// 数据
data: {
type: Array,
default: []
},
//显示的提示语
placeholderText:{
type: String,
default: '请选择'
},
//指定标签,子树节点
defaultProps:{
type:Object,
default:{
children: 'subMenus',
label: 'name',
value: 'id'
}
},
//唯一标识
nodeKey:{
type: String,
default: 'id'
},
//是否有标签
isTag:{
type:Boolean,
default:false
},
//是否可搜索
filterable:{
type:Boolean,
default:false
}
},
data() {
return {}
},
setup(props, {attrs, slots, emit}) {
const {proxy} = Vue.getCurrentInstance();
let data=Vue.ref([]);
let change=(val)=>{
emit("changeSelect",val)
}
//获取菜单类型
let getTypeName=(type)=>{
switch (type) {
case 1:
return '监控菜单';
case 2:
return '巡检菜单';
case 3:
return '个人工作台';
case 4:
return '系统菜单';
case 5:
return '跳转菜单';
case 6:
return '报表菜单';
case 7:
return '资产菜单';
default:
return '';
}
}
let init=()=>{
//lsq 菜单树数据 2022-09-05
proxy.$http.get(`/api-user/menus/current`, {type: 1}, function (res) {
if(res && res.data){
data.value = res.data;
}
})
}
// 监听编辑状态
Vue.watch(() => props.value, (newValue, oldVlaue) => {
// 编辑
});
// 挂载完
Vue.onMounted(() => {
init()
})
return {
data,
change,
getTypeName,
init
}
}
}
... ...
... ... @@ -167,6 +167,12 @@ const routes = [{
name: 'snapshotOverview',
component: () => myImport('views/snapshotOverview/index')
},
//license
{
path: '/vue3/license',
name: 'license',
component: () => myImport('views/license/index')
}
];
// hash模式: createWebHashHistory
... ...
... ... @@ -103,21 +103,10 @@
<el-form-item label="父菜单" prop="menuPid" v-if="ajConfigFrom.type==0">
<el-select :reserve-keyword="false"
:size="$global.elementConfig.size.input"
allow-create
default-first-option
filterable
placeholder="请选择"
style="width: 100%;" v-model="ajConfigFrom.menuPid">
<el-option
:disabled="item.disabled"
:key="item.value"
:label="item.label"
:value="item.value"
v-for="item in menuOptions">
</el-option>
</el-select>
<!--lsq 引入菜单树公共组件 2022-09-05-->
<cm-tree-select-menu style="width: 80%" @changeSelect="dataFilter" :filterable="true"
:value="ajConfigFrom.menuPid" :placeholderText="'请选择菜单'" :isTag="true"></cm-tree-select-menu>
</el-form-item>
<el-form-item label="菜单名称" prop="menuName" v-if="ajConfigFrom.type==0">
... ...
... ... @@ -206,8 +206,6 @@ export default {
let radio = Vue.ref(0);
//下拉框
let options = Vue.ref([]);
//菜单下拉框
let menuOptions = Vue.ref([]);
let search = Vue.ref({
keyword: '',
type: '',
... ... @@ -250,7 +248,6 @@ export default {
clearForm();
cacheVisible.value = true;
pageList();
menuList();
}
//新增或修改aj配置信息
... ... @@ -329,7 +326,6 @@ export default {
cacheVisible.value = true;
disabled.value = true;
pageList();
menuList();
}
//预览
... ... @@ -357,21 +353,6 @@ export default {
})
}
//菜单
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"));
... ... @@ -456,7 +437,10 @@ export default {
ddicOS.value = res.data;
}
});
//lsq 菜单树change事件
let dataFilter = (val) => {
ajConfigFrom.value.menuPid = val;
}
return {
ddicProvider,
ddicOS,
... ... @@ -484,8 +468,6 @@ export default {
pageList,
radio,
options,
menuList,
menuOptions,
getResType,
configs,
typeOptions,
... ... @@ -494,7 +476,8 @@ export default {
butColumns,
detailColumns,
couponSelected,
disabled
disabled,
dataFilter
}
}
... ...
<div :style="{'height':height+'px','max-height':height+'px','background-color':'#fff'}" class="container">
<div :style="{'min-height':height+'px','max-height':height+'px','height':'100%','padding-top':'3px'}"
class="cm-card">
<div class="search" >
<div class="condition" style="width: 100%;justify-content: flex-end;">
<el-form-item>
<el-upload
:auto-upload="true"
:before-upload="beforeAvatarUpload"
:http-request="getFile"
:multiple="false"
:show-file-list="false"
class="upload-demo-license">
<el-button size="mini" type="primary">导入</el-button>
</el-upload>
</el-form-item>
</div>
</div>
<div class="search-table">
<el-row>
<el-col :span="24" class="license-detail">
<el-descriptions title="license文件信息" :column="3" border>
<el-descriptions-item label="授权状态" label-align="right" align="center">
正常
</el-descriptions-item>
<el-descriptions-item label="授权时间" label-align="right" align="center">
2022-08-23
</el-descriptions-item>
<el-descriptions-item label="剩余" label-align="right" align="center">
<el-tag size="small">2天</el-tag>
</el-descriptions-item>
</el-descriptions>
</el-col>
</el-row>
<el-row>
<el-col :span="24" style="text-align: left;padding: 10px 0;font-size: 16px;font-weight: bold;">授权详情</el-col>
</el-row>
<cm-table-page :columns="tableData.columns" :dataList="tableData.dataList"
:height="200"
:loading="false"
:showBorder="true"
:showIndex="false"
:showPage="false"
:showSelection="false"
:showTools="false"
>
<template #default="{row,prop,column}">
<div v-if="prop == 'resNum'">
<!-- <span class="" style="color:#1e9fff;text-decoration: underline;cursor: pointer;">{{row.resNum }}</span>-->
<span :style="{'color':row.resNum>=1000?'red':''}">{{row.resNum}}</span>
</div>
<div v-else>
{{row[prop]}}
<el-tooltip
effect="dark"
placement="bottom"
>
<template #content>
<div>
<span>该协议写包含</span>
<span style="word-break: break-all;">{{splitDetail(prop)}}</span>
</div>
</template>
<i v-if="row[prop] && prop !='usage'" style="margin-left:6px;" class="el-icon-info"></i>
</el-tooltip>
</div>
</template>
</cm-table-page>
</div>
</div>
</div>
... ...
export default {
name: 'license',
template: '',
components: {
},
props: [],
setup(props, {attrs, slots, emit}) {
const {proxy} = Vue.getCurrentInstance();
let height = Vue.ref(window.innerHeight);
//导入或者详细信息
let isExport=Vue.ref(false);
//表格字段
let tableData = Vue.ref({
count: 0,
dataList: [],
columns: [
{
prop: 'usage',
label: '使用情况',
sortable: true,
align: 'center',
width: '100'
},
{
prop: 'resNum',
label: '资源数量',
sortable: true,
align: 'center',
width: '100',
},
{
prop: 'protocolCate',
label: '协议',
align: 'center',
columns:[]
}
]
})
// license分类详细协议
let licenseCateData=Vue.ref([
{license:'SSH',protocolCode:'SSH'},
{license:'SSH',protocolCode:'SSHPUBKEY'},
{license:'SSH',protocolCode:'SSHLocalShellPlugin'},
{license:'SSH',protocolCode:'LOCALSSH'},
{license:'SSH',protocolCode:'ShellCommandPlugin'},
{license:'SNMP',protocolCode:'SNMP'},
{license:'SNMP',protocolCode:'SNMP V3'},
{license:'SNMP',protocolCode:'SNMP TRAP'},
{license:'SDK',protocolCode:'SDK'},
{license:'SDK',protocolCode:'SDK'},
{license:'SDK',protocolCode:'SDK'},
{license:'DB',protocolCode:'JDBC'},
{license:'DB',protocolCode:'MONGODB'},
{license:'DB',protocolCode:'REDISX_CLI'},
{license:'JMX',protocolCode:'TOMCAT_JMX'},
{license:'JMX',protocolCode:'ZOOKEEPER_JMX'},
{license:'JMX',protocolCode:'KAFKA_JMX'},
{license:'SYSLOG',protocolCode:'SYSLOG'},
{license:'SYSLOG',protocolCode:'SYSLOGD'},
{license:'HTTP',protocolCode:'HTTP'},
{license:'HTTP',protocolCode:'HTTPS'},
{license:'HTTP',protocolCode:'HUAWEI_CLOUD'},
{license:'HTTP',protocolCode:'ALI_CLOUD'},
{license:'HTTP',protocolCode:'HTTP-电子税务局大屏'},
{license:'HTTP',protocolCode:'HTTP-阿里回迁云'},
{license:'HTTP',protocolCode:'tongwebHttp'},
{license:'HTTP',protocolCode:'QuantumPlugin'},
{license:'HTTP',protocolCode:'CollHuaweiE9000Plugin'},
{license:'HTTP',protocolCode:'CollHuaweiCloudStackPlugin'},
{license:'HTTP',protocolCode:'Coll360'},
{license:'HTTP',protocolCode:'Ezsonar'},
{license:'HTTP',protocolCode:'RongcuoLibraryPlugin'},
{license:'HTTP',protocolCode:'AnGuanPinTaiPlugin'},
{license:'HTTP',protocolCode:'nginxPlugin'},
{license:'IPMI',protocolCode:'IPMI'},
])
//获取license分类下的字段
let cateColumn=Vue.ref([]);
let getLicenseColumn=()=>{
cateColumn.value=[
{
prop: 'SSH',
label: 'SSH',
sortable: true,
align: 'center',
},
{
prop: 'SNMP',
label: 'SNMP',
sortable: true,
align: 'center',
},
{
prop: 'SDK',
label: 'SDK',
sortable: true,
align: 'center',
},
{
prop: 'DB',
label: 'DB',
sortable: true,
align: 'center',
},
{
prop: 'JMX',
label: 'JMX',
sortable: true,
align: 'center',
},
{
prop: 'SYSLOG',
label: 'SYSLOG',
sortable: true,
align: 'center',
},
{
prop: 'HTTP',
label: 'HTTP',
sortable: true,
align: 'center',
},
{
prop: 'IPMI',
label: 'IPMI',
sortable: true,
align: 'center',
}
]
tableData.value.columns.map(item=>{
if(item.prop=='protocolCate'){
item.columns=cateColumn.value
}
})
}
//给列表数据追加相关的详细协议
// 获取列表
let getDataList = () => {
tableData.value.dataList = [
{usage:'授权数量',resNum:'2',SSH:'12'},
{usage:'剩余数量',resNum:'1000',SNMP:'1',HTTP:'23'},
];
return
let params = {
page: search.value.page,
limit: search.value.limit,
}
proxy.$http.list(`/license/list`, params, function (res) {
if (res && res.object) {
let dataList = res.object.content;
let arr = [];
dataList.map(item => {
arr.push(item[0])
})
tableData.value.dataList = arr;
tableData.value.count = parseInt(res.object.total);
} else {
tableData.value.dataList = [];
tableData.value.count = 0;
}
});
}
//拆分详细协议数组
let splitDetail=(propkey)=>{
let arr=[];
licenseCateData.value.map(v=>{
if(propkey==v.license){
arr.push(v.protocolCode)
}
})
let str='';
if(arr && arr.length>0){
str=arr.join(',')
}
return str;
}
// 下载license
let handleDownLoad=(row)=>{
proxy.$global.confirm("确定下载license?", function () {
proxy.$http.downloadFile("/api-web/export", row);
})
}
let beforeAvatarUpload = (file) => {
const isJPG = file.type.indexOf('image/') != -1
if (!isJPG) {
proxy.$global.showMsg('您上传的不是图片文件,请选择图片!', 'error');
}
return isJPG
}
let getFile = (param) => {
let fileObj = param.file
let params = {
file: fileObj,
code: param.data
}
// 上传文件
proxy.$http.uploadFile("/api-u/sysConf/uploadFile", params, function (res) {
if (res && res.success) {
proxy.$global.showMsg("上传成功!");
}
})
}
//获取license详情
let getLicenseDetail=()=>{
let params={}
proxy.$http.get(`/license/selectById`, params, function (res) {
if (res && res.object) {
let dataList = res.object.content;
}
});
}
// 挂载完
Vue.onMounted(() => {
getLicenseColumn();
getDataList();
})
return {
isExport,
beforeAvatarUpload,
getFile,
licenseCateData,
getLicenseColumn,
cateColumn,
splitDetail,
handleDownLoad,
height,
tableData,
getDataList,
}
}
}
... ...
... ... @@ -19,7 +19,8 @@ export default {
{name: "skin1", imageUrl: 'skin1-login-logo', imageUrlSkin: 'skin1-login-skin'},
{name: "skin2", imageUrl: 'skin2-login-logo', imageUrlSkin: 'skin2-login-skin'},
{name: "首页1", imageUrlIndex: 'home1-logo'},
{name: "首页2", imageUrlIndex: 'home2-logo'}
{name: "首页2", imageUrlIndex: 'home2-logo'},
{name: "拓扑视图", imageUrlIndex: 'topology-logo'}
])
//上传完后的图片预览
let imageUrl = Vue.ref('');
... ...
... ... @@ -262,6 +262,12 @@ const routes = [{
name: 'snapshotOverview',
component: () => myImport('views/snapshotOverview/index')
},
//license
{
path: '/vue3/license',
name: 'license',
component: () => myImport('views/license/index')
}
];
// hash模式: createWebHashHistory
... ...
... ... @@ -152,10 +152,8 @@
</div>
<div style="padding: 3px 10px 3px 39px" v-if="!isAdd ">
<span class="saab"> 菜单:</span>
<el-select :size="$global.elementConfig.size.input" @change="dataFilter" filterable
placeholder="请选择菜单" style="width: 80%" v-model="form.addFirstPId">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in firstMenu"/>
</el-select>
<cm-tree-select-menu style="width: 80%" :size="$global.elementConfig.size.input" @changeSelect="dataFilter"
:value="form.addFirstPId" :placeholderText="'请选择菜单'" :isTag="true"></cm-tree-select-menu>
</div>
<div style="padding: 3px 10px;" v-if="!isAdd ">
<span class="saab"> 场景分类:</span>
... ...
... ... @@ -159,7 +159,7 @@ export default {
let countFirst = Vue.ref(0);
let form = Vue.ref({
addFirstPId: '',
addFirstPId: '100130900',
parentId: '',
parentName: '',
desc: '',
... ... @@ -305,14 +305,15 @@ export default {
//根菜单选择事件
let dataFilter = (val) => {
form.value.addFirstPId=val;
if (val) { //val存在
this.options = this.firstMenu.filter((item) => {
if (!!~item.label.indexOf(val) || !!~item.label.toUpperCase().indexOf(val.toUpperCase())) {
firstMenu.value.filter((item) => {
if (!!~item.id.indexOf(val) || !!~item.id.toUpperCase().indexOf(val.toUpperCase())) {
return true
}
})
} else { //val为空时,还原数组
this.options = this.firstMenu;
// this.options = firstMenu.value;
}
}
... ... @@ -552,6 +553,7 @@ export default {
let resTypeList = Vue.ref([]);
let kpiList = Vue.ref([]);
let busTypeList = Vue.ref([]);
let init = () => {
/*
proxy.$http.get("/api-web/home/resType/getTree?typeParentFlag=1", {}, function(res) {
... ... @@ -584,20 +586,7 @@ export default {
}
})
//LH 加载新增树菜单
proxy.$http.get(`/api-web/ContrastAnalysis/getRootMenu`, {menuName: ''}, function (res) {
if (res.length > 0) {
firstMenu.value = res;
firstMenu.value.forEach(function (item, index) {
if (item.id == '100130900') {
form.value.addFirstPId = firstMenu.value[index].id;
return;
}
});
}
});
//LH
//LH
setTimeout(function () {
let arrs = timeRangeArr.value
timeRangeChange(arrs[0]);
... ...