feat: app交互

This commit is contained in:
chenjinsong
2022-07-26 13:54:09 +08:00
parent 4648af7f90
commit ef2ac4915c
5 changed files with 137 additions and 179 deletions

View File

@@ -79,12 +79,14 @@
margin-top: 10px; margin-top: 10px;
justify-content: space-between; justify-content: space-between;
.app-card-title-name { .app-card-title-name {
font-size: 12px; span {
color: #353636; font-size: 16px;
font-weight: 400; color: #046ECA;
span .cn-icon { }
font-size: 12px; i {
margin-right: 4px; color: #38ACD2;
font-size: 16px;
padding-right: 4px;
} }
} }
.app-card-title-more { .app-card-title-more {
@@ -139,11 +141,10 @@
.app-card__body-content-value { .app-card__body-content-value {
display: flex; display: flex;
.app-card__body-content-number { .app-card__body-content-number {
font-family: Helvetica-Bold; font-size: 14px;
font-size: 20px;
color: #353636; color: #353636;
font-weight: 700; font-weight: 700;
margin-right: 28px; margin-right: 6px;
} }
} }
.app-card__body-content-percent { .app-card__body-content-percent {

View File

@@ -1,131 +0,0 @@
<template>
<div class="left-menu">
<el-menu
:collapse="isShrink"
active-text-color="#ffffff"
class="header-logo"
text-color="#ffffff">
<el-menu-item index="logo">
<div id="home-to-overview" class="logo link">
<img alt="loading..." height="32" :src="logo?logo:require('../../assets/img/logo.svg')"/>
<span class="system-name">{{systemName && systemName !== 'undefined' ? systemName : 'dashboard.overview.contentTitle'}}</span>
</div>
</el-menu-item>
</el-menu>
<el-menu
:collapse="isShrink"
:default-active="route"
class="menu-list"
mode="vertical"
unique-opened
@select="jump">
<template v-for="(menu, index) in menuList">
<el-submenu
v-if="menu.children && menu.children.length > 0 && menu.state === 1"
:key="index"
:index="`${index}`">
<template #title>
<i :class="menu.icon"></i>
<span :title="$t(menu.i18n)">{{menu.i18n ? $t(menu.i18n) : menu.name}}</span>
</template>
<template v-for="(secondMenu, secondIndex) in menu.children">
<el-submenu
v-if="secondMenu.children && secondMenu.children.length > 0 && secondMenu.state === 1"
:key="secondIndex"
:index="`${index}-${secondIndex}`">
<template #title>
<span class="data-column__span">{{secondMenu.i18n ? $t(secondMenu.i18n) : secondMenu.name}}</span>
</template>
<template v-for="(thirdMenu, thirdIndex) in secondMenu.children" :key="`${index}-${secondIndex}-${thirdIndex}`">
<el-menu-item
:title="$t(thirdMenu.i18n)"
v-if="thirdMenu.state === 1"
:index="thirdMenu.route">
{{thirdMenu.i18n ? $t(thirdMenu.i18n) : thirdMenu.name}}
</el-menu-item>
</template>
</el-submenu>
<el-menu-item
:title="$t(secondMenu.i18n)"
v-else-if="secondMenu.state === 1"
:key="secondIndex * 100"
:index="secondMenu.route">
{{secondMenu.i18n ? $t(secondMenu.i18n) : secondMenu.name}}
</el-menu-item>
</template>
</el-submenu>
<el-menu-item
:title="menu.i18n"
v-else-if="menu.state === 1"
:key="index + 'a'"
:index="menu.route">
<i :class="menu.icon"></i>
<template #title>
<span class="data-column__span">{{menu.i18n ? $t(menu.i18n) : menu.name}}</span>
</template>
</el-menu-item>
</template>
</el-menu>
</div>
</template>
<script>
import { storageKey } from '@/utils/constants'
export default {
name: 'LeftMenu',
data () {
return {
systemName: localStorage.getItem(storageKey.sysName),
logo: ''
}
},
mounted () {
const self = this
window.addEventListener('setItemEvent', function (e) {
if (e.key === 'cn-sys-logo' && e.value) {
self.logo = e.value
}
})
},
computed: {
menuList () {
const allMenu = this.$store.getters.menuList
excludeButtonAndMenu(this.$store.getters.menuList)
return allMenu
function excludeButtonAndMenu (menu) {
for (let i = 0; i < menu.length; i++) {
if (menu[i].type === 2 || menu[i].type === 3) {
menu.splice(i, 1)
i--
} else {
if (menu[i].children && menu[i].children.length > 0) {
excludeButtonAndMenu(menu[i].children)
}
}
}
}
},
route () {
return this.$route.path
}
},
methods: {
jump (route) {
if (route === this.route) {
this.refresh()
return
}
this.$router.push({
path: route,
query: {
t: +new Date()
}
})
},
refresh () {
this.$emit('refresh')
}
}
}
</script>

View File

@@ -71,9 +71,12 @@ export default {
Chart Chart
}, },
watch: { watch: {
chartList (n) { chartList: {
if (!_.isEmpty(n)) { deep: true,
this.layout = [...n] handler (n) {
if (!_.isEmpty(n)) {
this.layout = [...n]
}
} }
} }
}, },

View File

@@ -57,6 +57,15 @@ export default {
}, },
async mounted () { async mounted () {
await this.init() await this.init()
const vm = this
this.emitter.on('reloadChartList', async function () {
vm.chartList = (await getChartList({ panelId: vm.panel.id, pageSize: -1 })).map(chart => {
chart.i = chart.id
// 递归初始化各属性
vm.initChartAttr(chart)
return chart
})
})
}, },
setup (props, ctx) { setup (props, ctx) {
const panel = ref({}) const panel = ref({})

View File

@@ -18,12 +18,12 @@
<div class="app-card" v-for="(app, index) in appData" :key="index"> <div class="app-card" v-for="(app, index) in appData" :key="index">
<div class="app-card-title"> <div class="app-card-title">
<div class="app-card-title-name"> <div class="app-card-title-name">
<span><i class="cn-icon cn-icon-social-network"></i></span> <i class="cn-icon" :class="app.type === 'provider' ? 'cn-icon-entity' : 'cn-icon-app2'"></i>
<span>{{app.name}}</span> <span>{{app.name}}</span>
</div> </div>
<div class="app-card-title-more"> <div class="app-card-title-more">
<span><i class="cn-icon cn-icon-more-dark" @click="moreChange(app.name)"></i></span> <span><i class="cn-icon cn-icon-more-dark" @click="moreChange(app)"></i></span>
<span class="app-card-title-more-delete" v-show="app.moreName"><i class="cn-icon cn-icon-delete"></i>{{$t('overall.delete')}}</span> <span class="app-card-title-more-delete" @click="del(app, index)" v-show="app.moreName"><i class="cn-icon cn-icon-delete"></i>{{$t('overall.delete')}}</span>
</div> </div>
</div> </div>
<div class="app-card__bodys"> <div class="app-card__bodys">
@@ -32,18 +32,16 @@
<div class="app-card__body-content-value"> <div class="app-card__body-content-value">
<div class="app-card__body-content-number">{{unitConvert(app.number, unitTypes.number).join(' ')}}</div> <div class="app-card__body-content-number">{{unitConvert(app.number, unitTypes.number).join(' ')}}</div>
<div class="app-card__body-content-percent" :class="app.trend === 'up' ? 'red' : 'green'"> <div class="app-card__body-content-percent" :class="app.trend === 'up' ? 'red' : 'green'">
<div> <span v-if="app.trend === 'up'">+</span><span v-else-if="app.trend === 'down'">-</span>{{unitConvert(app.value, unitTypes.percent).join('')}}
<span v-if="app.trend === 'up'">+</span><span v-else-if="app.trend === 'down'">-</span>{{unitConvert(app.value, unitTypes.percent).join('')}}
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="app-card__body-previous"> <div class="app-card__body-previous">
<div>previous 24 hours</div> <div>Total</div>
<div>{{unitConvert(app.number1, unitTypes.number).join(' ')}}</div> <div>{{unitConvert(app.number1, unitTypes.number).join(' ')}}</div>
</div> </div>
</div> </div>
<div class="chart__drawing" :id="`chart${app.name}`"></div> <div class="chart__drawing" :id="`chart-${app.name}-${app.type}`"></div>
</div> </div>
</div> </div>
<div class="app-card app-card--create"> <div class="app-card app-card--create">
@@ -63,7 +61,7 @@
<div class="header__title">{{$t('overall.add')}}</div> <div class="header__title">{{$t('overall.add')}}</div>
<div class="header__operations"> <div class="header__operations">
<div class="header__operation header__operation--cancel" @click="cancelApp">{{$t('overall.cancel')}}</div> <div class="header__operation header__operation--cancel" @click="cancelApp">{{$t('overall.cancel')}}</div>
<div class="header__operation header__operation--save">{{$t('overall.save')}}</div> <div class="header__operation header__operation--save" @click="save">{{$t('overall.save')}}</div>
</div> </div>
</div> </div>
<div class="add-app__body"> <div class="add-app__body">
@@ -98,7 +96,7 @@
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<div class="body__searcher"> <div class="body__searcher">
<el-input v-model="searcherApp" @input="searcherAppChange" size="mini" :placeholder="$t('networkOverview.searcher')" prefix-icon="el-icon-search"></el-input> <el-input v-model="searcherApp" @input="searcherAppChange" size="mini" :placeholder="$t('networkOverview.search')" prefix-icon="el-icon-search"></el-input>
</div> </div>
</div> </div>
</div> </div>
@@ -112,6 +110,10 @@ import { unitTypes } from '@/utils/constants'
import * as echarts from 'echarts' import * as echarts from 'echarts'
import { appListChartOption } from '@/views/charts2/charts/options/echartOption' import { appListChartOption } from '@/views/charts2/charts/options/echartOption'
import { shallowRef } from 'vue' import { shallowRef } from 'vue'
import { put } from '@/utils/http'
import { api } from '@/utils/api'
import _ from 'lodash'
export default { export default {
name: 'NetworkOverviewApps', name: 'NetworkOverviewApps',
props: { props: {
@@ -126,7 +128,6 @@ export default {
return { return {
metricFilter: '', metricFilter: '',
metricOptions: [], metricOptions: [],
chartOption: [],
appData: [], appData: [],
// 假数据 // 假数据
appTempData: [ appTempData: [
@@ -134,6 +135,11 @@ export default {
{ value: 1.8934, number: 382100000000, previous: 24, number1: 3675, trend: 'up', icon: 'cn-icon-fraudulent-ip' }, { value: 1.8934, number: 382100000000, previous: 24, number1: 3675, trend: 'up', icon: 'cn-icon-fraudulent-ip' },
{ value: 1.2054, number: 184600000000, previous: 24, number1: 3675, trend: 'up', icon: 'cn-icon-debug' }, { value: 1.2054, number: 184600000000, previous: 24, number1: 3675, trend: 'up', icon: 'cn-icon-debug' },
{ value: 1.2506, number: 584800000000, previous: 24, number1: 3675, trend: 'down', icon: 'cn-icon-language' }, { value: 1.2506, number: 584800000000, previous: 24, number1: 3675, trend: 'down', icon: 'cn-icon-language' },
{ value: 1.2506, number: 584800000000, previous: 24, number1: 3675, trend: 'down', icon: 'cn-icon-language' },
{ value: 1.2506, number: 584800000000, previous: 24, number1: 3675, trend: 'down', icon: 'cn-icon-language' },
{ value: 1.2506, number: 584800000000, previous: 24, number1: 3675, trend: 'down', icon: 'cn-icon-language' },
{ value: 1.2506, number: 584800000000, previous: 24, number1: 3675, trend: 'down', icon: 'cn-icon-language' },
{ value: 1.2506, number: 584800000000, previous: 24, number1: 3675, trend: 'down', icon: 'cn-icon-language' },
{ value: 1.6415, number: 734100000000, previous: 24, number1: 3675, trend: 'down', icon: 'cn-icon-authoritative-domain' } { value: 1.6415, number: 734100000000, previous: 24, number1: 3675, trend: 'down', icon: 'cn-icon-authoritative-domain' }
], ],
unitTypes, unitTypes,
@@ -148,6 +154,8 @@ export default {
appShowTypeTab: 0, appShowTypeTab: 0,
initialAppOptionsData: [], initialAppOptionsData: [],
initialProviderOptionsData: [], initialProviderOptionsData: [],
// 选中的app不区分app和provider
toSaveApp: [],
myChartArray: [] myChartArray: []
} }
}, },
@@ -156,8 +164,10 @@ export default {
init () { init () {
this.appData.forEach((app, i) => { this.appData.forEach((app, i) => {
// 根据app.name和app.type查除接口获取数据 // 根据app.name和app.type查除接口获取数据
this.appData[i] = { ...app, ...this.appTempData[i] } app.value = this.appTempData[i].value
this.appData[i].lineData = [ app.number = this.appTempData[i].number
app.number1 = this.appTempData[i].number1
app.lineData = [
[ [
'1658128320', '1658128320',
'0' '0'
@@ -563,17 +573,16 @@ export default {
'0' '0'
] ]
].map(v => [Number(v[0]) * 1000, Number(v[1]), 'time']) ].map(v => [Number(v[0]) * 1000, Number(v[1]), 'time'])
this.initChart(this.appData[i]) this.initChart(app)
}) })
}, },
initChart (obj) { initChart (obj) {
const dom = document.getElementById(`chart${obj.name}`) let chart = this.myChart.find(m => m.name === obj.name && m.type === obj.type)
this.myChart = echarts.init(dom) if (!chart) {
this.chartOption = appListChartOption chart = echarts.init(document.getElementById(`chart-${obj.name}-${obj.type}`))
const seriesTemplate = this.chartOption.series[0] const chartOption = _.cloneDeep(appListChartOption)
if (obj && obj.lineData) { chartOption.series = [{
this.chartOption.series[0] = { ...chartOption.series[0],
...seriesTemplate,
data: obj.lineData, data: obj.lineData,
lineStyle: { lineStyle: {
color: obj.trend === 'up' ? '#7FA054' : '#35ADDA' color: obj.trend === 'up' ? '#7FA054' : '#35ADDA'
@@ -591,9 +600,12 @@ export default {
} }
]) ])
} }
} }]
this.myChartArray.push(this.myChart) chart.setOption(chartOption)
this.myChart.setOption(this.chartOption) this.myChart.push(chart)
this.$nextTick(() => {
chart.resize()
})
} }
}, },
addApp () { addApp () {
@@ -614,10 +626,16 @@ export default {
provideShow: false provideShow: false
}) })
} }
this.appOptions = appOptions const oldApps = this.chart.params.app ? this.chart.params.app.filter(a => a.type === 'app') : []
this.providerOptions = providerOptions const oldProviders = this.chart.params.app ? this.chart.params.app.filter(a => a.type === 'provider') : []
this.initialAppOptionsData = this.appOptions this.appOptions = appOptions.filter(a => {
this.initialProviderOptionsData = this.providerOptions return !oldApps.some(o => o.name === a.name)
})
this.providerOptions = providerOptions.filter(a => {
return !oldProviders.some(o => o.name === a.name)
})
this.initialAppOptionsData = [...this.appOptions]
this.initialProviderOptionsData = [...this.providerOptions]
}, },
cancelApp () { cancelApp () {
this.showAddApp = false this.showAddApp = false
@@ -642,24 +660,82 @@ export default {
} }
} }
}, },
// 保存变更并且在增、删app后根据当前app数量更改整体高度
saveChart (toSaveChart, length) {
return new Promise(resolve => {
const actuallyLength = this.appData.length + length + 1
toSaveChart.h = actuallyLength % 3 > 0 ? (Math.floor(actuallyLength / 3) + 1) * 2 + 2 : Math.floor(actuallyLength / 3) * 2 + 2
put(api.chart, toSaveChart).then(res => {
if (res.code === 200) {
this.emitter.emit('reloadChartList')
resolve()
}
})
})
},
del (app, index) {
const appData = _.cloneDeep(this.appData)
appData.splice(index, 1)
const toSaveChart = {
...this.chart,
params: JSON.stringify({ app: appData })
}
this.saveChart(toSaveChart, -1).then(res => {
this.appData.splice(index, 1)
})
},
save () {
if (this.toSaveApp.length > 0) {
const toSaveParams = this.chart.params.app ? this.chart.params : { app: [] }
toSaveParams.app = [...toSaveParams.app, ...this.toSaveApp]
const toSaveChart = {
...this.chart,
params: JSON.stringify(toSaveParams)
}
this.saveChart(toSaveChart, this.toSaveApp.length).then(res => {
this.appData = _.cloneDeep(toSaveParams.app)
this.$nextTick(() => {
this.init()
this.showAddApp = false
this.toSaveApp = []
})
})
}
},
appCheckedChange (app, num) { appCheckedChange (app, num) {
if (num === 0) { if (num === 0) {
this.providerOptions.forEach(t => { this.providerOptions.forEach(t => {
if (t.name === app.name && t.desc === app.desc) { if (t.name === app.name) {
t.provideShow = !t.provideShow t.provideShow = !t.provideShow
if (t.provideShow) {
this.toSaveApp.push({ type: 'provider', name: app.name })
} else {
const index = this.toSaveApp.findIndex(a => a.name === app.name)
if (index > -1) {
this.toSaveApp.splice(index, 1)
}
}
} }
}) })
} else if (num === 1) { } else if (num === 1) {
this.appOptions.forEach(t => { this.appOptions.forEach(t => {
if (t.name === app.name && t.desc === app.desc) { if (t.name === app.name) {
t.appShow = !t.appShow t.appShow = !t.appShow
if (t.appShow) {
this.toSaveApp.push({ type: 'app', name: app.name })
} else {
const index = this.toSaveApp.findIndex(a => a.name === app.name)
if (index > -1) {
this.toSaveApp.splice(index, 1)
}
}
} }
}) })
} }
}, },
moreChange (name) { moreChange (app) {
this.appData.forEach((t) => { this.appData.forEach(t => {
if (t.name === name) { if (t.name === app.name && t.type === app.type) {
t.moreName = !t.moreName t.moreName = !t.moreName
} else { } else {
t.moreName = false t.moreName = false
@@ -667,14 +743,14 @@ export default {
}) })
}, },
resize () { resize () {
this.myChartArray.forEach(t => { this.myChart.forEach(t => {
t.resize() t.resize()
}) })
} }
}, },
mounted () { mounted () {
if (this.chart.params.app) { if (this.chart.params && this.chart.params.app) {
this.appData = this.chart.params.app this.appData = _.cloneDeep(this.chart.params.app)
} }
this.timer = setTimeout(() => { this.timer = setTimeout(() => {
this.init() this.init()