CN-1223 fix: score改版

This commit is contained in:
chenjinsong
2023-10-22 20:21:32 +08:00
parent 40d43acb6c
commit c5c7b58720
24 changed files with 617 additions and 123 deletions

View File

@@ -128,7 +128,7 @@ $blue: #046ECA;
} }
} }
} }
.link-statistical-dimension {
.row-dot { .row-dot {
margin-top: 5px; margin-top: 5px;
margin-right: 5px; margin-right: 5px;
@@ -147,6 +147,7 @@ $blue: #046ECA;
border-radius: 50%; border-radius: 50%;
background: #E26154; background: #E26154;
} }
}
.item-popover-up, .item-popover-down { .item-popover-up, .item-popover-down {
font-size: 17px; font-size: 17px;

View File

@@ -349,6 +349,24 @@
.data-score-green { .data-score-green {
background: #749F4D; background: #749F4D;
} }
.score-dot {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 50%;
background-color: #CBCBCB;
margin-right: 4px;
&.score-dot--red {
background-color: #E26154;
}
&.score-dot--yellow {
background-color: #E5A219;
}
&.score-dot--green {
background-color: #749F4D;
}
}
height:24px; height:24px;
font-size: 14px; font-size: 14px;
color: #046ECA; color: #046ECA;

View File

@@ -174,6 +174,25 @@
font-size: 14px; font-size: 14px;
color: #353636; color: #353636;
font-weight: 400; font-weight: 400;
.score-dot {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 50%;
background-color: #CBCBCB;
margin-right: 4px;
&.score-dot--red {
background-color: #E26154;
}
&.score-dot--yellow {
background-color: #E5A219;
}
&.score-dot--green {
background-color: #749F4D;
}
}
} }
} }
} }

View File

@@ -257,8 +257,6 @@ export default {
}, },
methods: { methods: {
fileChange (file, fileList) { fileChange (file, fileList) {
console.info(!_.endsWith(file.name, '.csv'))
console.info(file.size > this.uploadFileSizeLimit)
// 判断后缀,仅支持.csv // 判断后缀,仅支持.csv
if (!_.endsWith(file.name, '.csv')) { if (!_.endsWith(file.name, '.csv')) {
this.fileList = [] this.fileList = []

View File

@@ -96,5 +96,41 @@ export default {
this.relationshipShowMoreTwo = false this.relationshipShowMoreTwo = false
this.relationshipShowMoreOne = false this.relationshipShowMoreOne = false
} }
},
computed: {
scoreDot () {
const dots = []
if (this.score === '-') {
for (let i = 0; i < 6; i++) {
dots.push({
class: 'score-dot'
})
}
} else {
for (let i = 0; i < 6; i++) {
if (i < this.score) {
dots.push({
class: `score-dot ${handleClass(this.score)}`
})
} else {
dots.push({
class: 'score-dot'
})
}
}
}
return dots
function handleClass (score) {
if (score <= 2) {
return 'score-dot--red'
} else if (score <= 4) {
return 'score-dot--yellow'
} else if (score <= 6) {
return 'score-dot--green'
}
return ''
}
}
} }
} }

View File

@@ -60,6 +60,29 @@ const panel = {
routerHistoryList: [], // 路由跳转记录列表 routerHistoryList: [], // 路由跳转记录列表
dnsQtypeMapData: [], dnsQtypeMapData: [],
dnsRcodeMapData: [], dnsRcodeMapData: [],
scoreBase: {
isReady: false,
establishLatencyMs: {
p10: null,
p90: null
},
httpResponseLatency: {
p10: null,
p90: null
},
sslConLatency: {
p10: null,
p90: null
},
tcpLostlenPercent: {
p10: null,
p90: null
},
pktRetransPercent: {
p10: null,
p90: null
}
},
chartTabList: null // chartTabs组件的tab状态点击列表初始化为null方便原有逻辑计算 chartTabList: null // chartTabs组件的tab状态点击列表初始化为null方便原有逻辑计算
}, },
mutations: { mutations: {
@@ -153,6 +176,56 @@ const panel = {
setRouterHistoryList (state, list) { setRouterHistoryList (state, list) {
state.routerHistoryList = list state.routerHistoryList = list
}, },
resetScoreBase (state) {
state.scoreBase = {
isReady: false,
establishLatencyMs: {
p10: null,
p90: null
},
httpResponseLatency: {
p10: null,
p90: null
},
sslConLatency: {
p10: null,
p90: null
},
tcpLostlenPercent: {
p10: null,
p90: null
},
pktRetransPercent: {
p10: null,
p90: null
}
}
},
setScoreBase (state, scoreBase) {
state.scoreBase = {
isReady: true,
establishLatencyMs: {
p10: scoreBase.establishLatencyMsP10,
p90: scoreBase.establishLatencyMsP90
},
httpResponseLatency: {
p10: scoreBase.httpResponseLatencyP10,
p90: scoreBase.httpResponseLatencyP90
},
sslConLatency: {
p10: scoreBase.sslConLatencyP10,
p90: scoreBase.sslConLatencyP90
},
tcpLostlenPercent: {
p10: scoreBase.tcpLostlenPercentP10,
p90: scoreBase.tcpLostlenPercentP90
},
pktRetransPercent: {
p10: scoreBase.pktRetransPercentP10,
p90: scoreBase.pktRetransPercentP90
}
}
},
setChartTabList (state, list) { setChartTabList (state, list) {
state.chartTabList = list state.chartTabList = list
} }
@@ -232,6 +305,12 @@ const panel = {
}, },
getChartTabList (state) { getChartTabList (state) {
return state.chartTabList return state.chartTabList
},
scoreBaseReady (state) {
return state.scoreBase.isReady
},
getScoreBase (state) {
return state.scoreBase
} }
}, },
actions: { actions: {

View File

@@ -784,12 +784,13 @@ export function getChainRatio (current, prev) {
} }
} }
export function computeScore (data) { export function computeScore (data, scoreBase) {
let score = 0 let score = 0
let k = 0 let k = 0
let totalScore = 0 let totalScore = 0
const scoreArr = [] const scoreArr = []
let num = 0 let num = 0
console.info(data, scoreBase)
Object.keys(data).forEach(t => { Object.keys(data).forEach(t => {
if (!data[t] && data[t] !== 0) { if (!data[t] && data[t] !== 0) {
num += 1 num += 1
@@ -799,26 +800,14 @@ export function computeScore (data) {
} else if (t === 'httpResponseLatency' || t === 'sslConLatency') { } else if (t === 'httpResponseLatency' || t === 'sslConLatency') {
k = 0.05 k = 0.05
} }
if (t === 'establishLatencyMs' || t === 'httpResponseLatency' || t === 'sslConLatency') {
if (!data[t] && data[t] !== 0) { if (!data[t] && data[t] !== 0) {
score = 1 score = 1
} else if (data[t] <= 50) { } else if (data[t] <= scoreBase[t].p10) {
score = 1 score = 1
} else if (data[t] > 200) { } else if (data[t] >= scoreBase[t].p90) {
score = 0 score = 0
} else { } else {
score = (data[t] - 200) / (50 - 200) score = (data[t] - scoreBase[t].p90) / (scoreBase[t].p10 - scoreBase[t].p90)
}
} else if (t === 'tcpLostlenPercent' || t === 'pktRetransPercent') {
if (!data[t] && data[t] !== 0) {
score = 1
} else if (data[t] <= 0.01) {
score = 1
} else if (data[t] > 0.05) {
score = 0
} else {
score = (data[t] - 0.05) / (0.01 - 0.05)
}
} }
scoreArr.push(score * k) scoreArr.push(score * k)
}) })
@@ -1319,9 +1308,9 @@ export function numberWithCommas (num) {
*/ */
export function switchStatus (status) { export function switchStatus (status) {
switch (status) { switch (status) {
case 0: case '0':
return 'detection.create.disabled' return 'detection.create.disabled'
case 1: case '1':
return 'detection.create.enabled' return 'detection.create.enabled'
} }
} }

View File

@@ -104,7 +104,9 @@ export default {
dnsRcodeMapData: [], dnsRcodeMapData: [],
dnsQtypeMapData: [], dnsQtypeMapData: [],
score: null, score: null,
curTabState: curTabState curTabState: curTabState,
performanceData: {},
scoreDataState: false // 评分数据是否加载完成
} }
}, },
computed: { computed: {
@@ -114,24 +116,34 @@ export default {
// 显示顶部的Metric单位选项标识 // 显示顶部的Metric单位选项标识
showMetric () { showMetric () {
return this.panelType === panelTypeAndRouteMapping.networkOverview || this.panelType === panelTypeAndRouteMapping.networkOverviewDrillDown return this.panelType === panelTypeAndRouteMapping.networkOverview || this.panelType === panelTypeAndRouteMapping.networkOverviewDrillDown
},
scoreBaseState () {
return this.$store.getters.scoreBaseReady
} }
}, },
watch: { watch: {
// npmThirdLevelMenuScore: {
// deep: true,
// immediate: true,
// handler (n) {
// this.score = n
// }
// }
timeFilter: { timeFilter: {
handler () { handler () {
if (this.$route.path === '/panel/networkAppPerformance' && (this.lineQueryCondition || this.networkOverviewBeforeTab)) { if (this.$route.path === '/panel/networkAppPerformance') {
this.$store.commit('resetScoreBase')
this.queryScoreBase()
if (this.lineQueryCondition || this.networkOverviewBeforeTab) {
this.scoreCalculation() this.scoreCalculation()
} }
} }
} }
}, },
scoreBaseState (n) {
if (n && this.scoreDataState) {
this.handleScoreData()
}
},
scoreDataState (n) {
if (n && this.scoreBaseState) {
this.handleScoreData()
}
}
},
async mounted () { async mounted () {
// this.panelName = this.$store.getters.getPanelName // this.panelName = this.$store.getters.getPanelName
const pName = this.$route.query.panelName ? this.$t(this.$route.query.panelName) : '' const pName = this.$route.query.panelName ? this.$t(this.$route.query.panelName) : ''
@@ -212,9 +224,15 @@ export default {
return chart return chart
}) })
}) })
if (this.$route.path === '/panel/networkAppPerformance' && (this.lineQueryCondition || this.networkOverviewBeforeTab)) { if (this.$route.path === '/panel/networkAppPerformance') {
if (this.lineQueryCondition || this.networkOverviewBeforeTab) {
this.scoreCalculation() this.scoreCalculation()
} }
}
if (this.$route.path === '/panel/networkAppPerformance' || this.$route.path === '/panel/linkMonitor') {
this.$store.commit('resetScoreBase')
this.queryScoreBase()
}
}, },
setup (props) { setup (props) {
// router引入store会报错故在panel里调用 // router引入store会报错故在panel里调用
@@ -396,6 +414,44 @@ export default {
}) })
overwriteUrl(newUrl) overwriteUrl(newUrl)
}, },
// 动态查询评分基准
queryScoreBase () {
const params = {
startTime: this.timeFilter.startTime,
endTime: this.timeFilter.endTime
}
const tcp = axios.get(api.npm.overview.tcpSessionDelay, { params: params })
const http = axios.get(api.npm.overview.httpResponseDelay, { params: params })
const ssl = axios.get(api.npm.overview.sslConDelay, { params: params })
const tcpPercent = axios.get(api.npm.overview.tcpLostlenPercent, { params: params })
const packetPercent = axios.get(api.npm.overview.packetRetransPercent, { params: params })
Promise.all([tcp, http, ssl, tcpPercent, packetPercent]).then(res => {
const scoreBase = {}
res.forEach((t, i) => {
if (t.status === 200) {
if (i === 0) {
scoreBase.establishLatencyMsP10 = _.get(t.data, 'data.result.establishLatencyMsP10', null)
scoreBase.establishLatencyMsP90 = _.get(t.data, 'data.result.establishLatencyMsP90', null)
} else if (i === 1) {
scoreBase.httpResponseLatencyP10 = _.get(t.data, 'data.result.httpResponseLatencyP10', null)
scoreBase.httpResponseLatencyP90 = _.get(t.data, 'data.result.httpResponseLatencyP90', null)
} else if (i === 2) {
scoreBase.sslConLatencyP10 = _.get(t.data, 'data.result.sslConLatencyP10', null)
scoreBase.sslConLatencyP90 = _.get(t.data, 'data.result.sslConLatencyP90', null)
} else if (i === 3) {
scoreBase.tcpLostlenPercentP10 = _.get(t.data, 'data.result.tcpLostlenPercentP10', null)
scoreBase.tcpLostlenPercentP90 = _.get(t.data, 'data.result.tcpLostlenPercentP90', null)
} else if (i === 4) {
scoreBase.pktRetransPercentP10 = _.get(t.data, 'data.result.pktRetransPercentP10', null)
scoreBase.pktRetransPercentP90 = _.get(t.data, 'data.result.pktRetransPercentP90', null)
}
}
})
this.$store.commit('setScoreBase', scoreBase)
}).catch((e) => {
}).finally(() => {
})
},
scoreCalculation () { scoreCalculation () {
let condition = '' let condition = ''
let url = '' let url = ''
@@ -443,18 +499,21 @@ export default {
url = api.npm.overview.networkAnalysis url = api.npm.overview.networkAnalysis
} }
if ((type && condition) || type) { if ((type && condition) || type) {
this.scoreDataState = false
this.performanceData = {}
params.type = params.type || type params.type = params.type || type
axios.get(url, { params }).then(res => { axios.get(url, { params }).then(res => {
if (res.status === 200) { if (res.status === 200) {
const data = { this.performanceData = {
establishLatencyMs: _.get(res, 'data.data.result.establishLatencyMsAvg', null), establishLatencyMs: _.get(res, 'data.data.result.establishLatencyMsAvg', null),
httpResponseLatency: _.get(res, 'data.data.result.httpResponseLatencyAvg', null), httpResponseLatency: _.get(res, 'data.data.result.httpResponseLatencyAvg', null),
sslConLatency: _.get(res, 'data.data.result.sslConLatencyAvg', null), sslConLatency: _.get(res, 'data.data.result.sslConLatencyAvg', null),
tcpLostlenPercent: _.get(res, 'data.data.result.tcpLostlenPercentAvg', null), tcpLostlenPercent: _.get(res, 'data.data.result.tcpLostlenPercentAvg', null),
pktRetransPercent: _.get(res, 'data.data.result.pktRetransPercentAvg', null) pktRetransPercent: _.get(res, 'data.data.result.pktRetransPercentAvg', null)
} }
this.score = computeScore(data)
} }
}).finally(() => {
this.scoreDataState = true
}) })
} }
}, },
@@ -467,6 +526,9 @@ export default {
} }
}) })
window.open(href, '_blank') window.open(href, '_blank')
},
handleScoreData () {
this.score = computeScore(this.performanceData, this.$store.getters.getScoreBase)
} }
}, },
/** /**

View File

@@ -30,7 +30,8 @@ export default {
isLinkShowError: false, // 显示左侧链路报错标识 isLinkShowError: false, // 显示左侧链路报错标识
linkErrorMsg: '', // 左侧链路的报错信息 linkErrorMsg: '', // 左侧链路的报错信息
isNextShowError: false, // 显示右侧下一跳报错标识 isNextShowError: false, // 显示右侧下一跳报错标识
nextErrorMsg: '' // 右侧下一跳的报错信息 nextErrorMsg: '', // 右侧下一跳的报错信息
scoreDataState: false // 评分数据是否加载完成
} }
}, },
components: { components: {
@@ -41,6 +42,23 @@ export default {
handler () { handler () {
this.init() this.init()
} }
},
scoreBaseState (n) {
if (n && this.scoreDataState) {
this.handleScoreData(this.linkGridData)
this.handleScoreData(this.nextGridData)
}
},
scoreDataState (n) {
if (n && this.scoreBaseState) {
this.handleScoreData(this.linkGridData)
this.handleScoreData(this.nextGridData)
}
}
},
computed: {
scoreBaseState () {
return this.$store.getters.scoreBaseReady
} }
}, },
mounted () { mounted () {
@@ -48,6 +66,7 @@ export default {
}, },
methods: { methods: {
init () { init () {
this.scoreDataState = false
// 链路基本信息 // 链路基本信息
let linkInfo = localStorage.getItem(storageKey.linkInfo) let linkInfo = localStorage.getItem(storageKey.linkInfo)
linkInfo = JSON.parse(linkInfo) linkInfo = JSON.parse(linkInfo)
@@ -117,9 +136,9 @@ export default {
d.usageMore90 = outUsage >= 0.9 || inUsage >= 0.9 d.usageMore90 = outUsage >= 0.9 || inUsage >= 0.9
// 计算npm分数 // 计算npm分数
// 分数低于3分赋红点 // 分数低于3分赋红点
d.score = this.localComputeScore(d) // d.score = this.localComputeScore(d)
d.scoreLow3 = d.score < 3 || d.score === '-' // d.scoreLow3 = d.score < 3 || d.score === '-'
const xAxis = inLink.linkId.split('Hundredgige').pop() - 1 const xAxis = inLink.linkId.split('Hundredgige').pop() - 1
const yAxis = outLink.linkId.split('Hundredgige').pop() - 1 const yAxis = outLink.linkId.split('Hundredgige').pop() - 1
@@ -210,9 +229,9 @@ export default {
d.usageMore90 = outUsage >= 0.9 || inUsage >= 0.9 d.usageMore90 = outUsage >= 0.9 || inUsage >= 0.9
// 计算npm分数 // 计算npm分数
// 分数低于3分赋红点 // 分数低于3分赋红点
d.score = this.localComputeScore(d) // d.score = this.localComputeScore(d)
d.scoreLow3 = d.score < 3 || d.score === '-' // d.scoreLow3 = d.score < 3 || d.score === '-'
const xAxis = inLink.linkId const xAxis = inLink.linkId
const yAxis = outLink.linkId const yAxis = outLink.linkId
@@ -254,6 +273,7 @@ export default {
} }
} }
}).finally(() => { }).finally(() => {
this.scoreDataState = true
this.toggleLoading(false) this.toggleLoading(false)
}) })
}, },
@@ -282,6 +302,23 @@ export default {
score = computeScore(dataScore) score = computeScore(dataScore)
return score return score
}, },
handleScoreData (data) {
data.forEach(d => {
if (d.out) {
d.out.forEach(t => {
const data = {
establishLatencyMs: t.establishLatencyMs,
httpResponseLatency: t.httpResponseLatency,
sslConLatency: t.sslConLatency,
tcpLostlenPercent: t.tcpLostlenPercent,
pktRetransPercent: t.pktRetransPercent
}
t.score = computeScore(data, this.$store.getters.getScoreBase)
t.scoreLow3 = t.score < 3 || t.score === '-'
})
}
})
},
/** /**
* 计算popover弹窗和右侧数据模块的宽度 * 计算popover弹窗和右侧数据模块的宽度
* 弹窗最小宽度为360px右侧数据最小宽度为75px右侧数据每大一位popover弹窗宽度增加7px * 弹窗最小宽度为360px右侧数据最小宽度为75px右侧数据每大一位popover弹窗宽度增加7px

View File

@@ -87,7 +87,14 @@ export default {
bandWidth: 0, bandWidth: 0,
loading: false, loading: false,
showError: false, showError: false,
errorMsg: '' errorMsg: '',
scoreDataState: false,
performanceData: {}
}
},
computed: {
scoreBaseState () {
return this.$store.getters.scoreBaseReady
} }
}, },
watch: { watch: {
@@ -95,6 +102,16 @@ export default {
handler (n) { handler (n) {
this.linkTrafficData() this.linkTrafficData()
} }
},
scoreBaseState (n) {
if (n && this.scoreDataState) {
this.handleScoreData()
}
},
scoreDataState (n) {
if (n && this.scoreBaseState) {
this.handleScoreData()
}
} }
}, },
methods: { methods: {
@@ -103,6 +120,9 @@ export default {
startTime: getSecond(this.timeFilter.startTime), startTime: getSecond(this.timeFilter.startTime),
endTime: getSecond(this.timeFilter.endTime) endTime: getSecond(this.timeFilter.endTime)
} }
this.loading = true
this.performanceData = {}
this.scoreDataState = false
if (this.queryCondition) { if (this.queryCondition) {
const condition = this.queryCondition.split(' or ') const condition = this.queryCondition.split(' or ')
if (condition.length > 1) { if (condition.length > 1) {
@@ -142,7 +162,6 @@ export default {
this.bandWidth = bandwidthAll this.bandWidth = bandwidthAll
} }
} }
this.loading = true
axios.get(api.linkMonitor.networkAnalysis, { params: params }).then(response => { axios.get(api.linkMonitor.networkAnalysis, { params: params }).then(response => {
const res = response.data const res = response.data
if (response.status === 200) { if (response.status === 200) {
@@ -152,7 +171,7 @@ export default {
this.linkTrafficListData = {} this.linkTrafficListData = {}
this.linkTrafficListData.npmScore = '-' this.linkTrafficListData.npmScore = '-'
} else { } else {
const data = { this.performanceData = {
establishLatencyMs: _.get(res.data.result[0], 'establishLatencyMs', null), establishLatencyMs: _.get(res.data.result[0], 'establishLatencyMs', null),
httpResponseLatency: _.get(res.data.result[0], 'httpResponseLatency', null), httpResponseLatency: _.get(res.data.result[0], 'httpResponseLatency', null),
sslConLatency: _.get(res.data.result[0], 'sslConLatency', null), sslConLatency: _.get(res.data.result[0], 'sslConLatency', null),
@@ -160,19 +179,24 @@ export default {
pktRetransPercent: _.get(res.data.result[0], 'pktRetransPercent', null) pktRetransPercent: _.get(res.data.result[0], 'pktRetransPercent', null)
} }
this.linkTrafficListData = res.data.result[0] this.linkTrafficListData = res.data.result[0]
this.linkTrafficListData.npmScore = computeScore(data) // this.linkTrafficListData.npmScore = computeScore(data)
} }
} else { } else {
this.showError = true this.showError = true
this.errorMsg = res.message this.errorMsg = res.message
} }
}).catch(e => { }).catch(e => {
console.error(e)
this.showError = true this.showError = true
this.errorMsg = e.message this.errorMsg = e.message
this.isNoData = false this.isNoData = false
}).finally(() => { }).finally(() => {
this.loading = false this.loading = false
this.scoreDataState = true
}) })
},
handleScoreData () {
this.linkTrafficListData.npmScore = computeScore(this.performanceData, this.$store.getters.getScoreBase)
} }
}, },
mounted () { mounted () {

View File

@@ -379,12 +379,25 @@ export default {
timeFilter: { timeFilter: {
handler (n) { handler (n) {
const queryParams = this.getQueryParams() const queryParams = this.getQueryParams()
this.changeUrlTabState()
this.getChartData(queryParams) this.getChartData(queryParams)
this.changeUrlTabState()
} }
}, },
metric (n) { metric (n) {
this.changeMetric() this.changeMetric()
},
scoreBaseState (n) {
if (n && Object.keys(_.get(this.tableData, '[0].scoreGroup', {})).length >= 5) {
this.handleScoreData()
}
},
tableData: {
deep: true,
handler (n) {
if (Object.keys(_.get(n, '[0].scoreGroup', {})).length >= 5 && this.scoreBaseState) {
this.handleScoreData()
}
}
} }
}, },
computed: { computed: {
@@ -399,6 +412,9 @@ export default {
className = 'tab-table tab-table__no-bottom' className = 'tab-table tab-table__no-bottom'
} }
return className return className
},
scoreBaseState () {
return this.$store.getters.scoreBaseReady
} }
}, },
mixins: [chartMixin], mixins: [chartMixin],
@@ -468,8 +484,8 @@ export default {
return excludeName.indexOf(title.name) > -1 ? false : 'custom' return excludeName.indexOf(title.name) > -1 ? false : 'custom'
}, },
searchColumnWidth (columnType) { searchColumnWidth (columnType) {
let checkedGroup = this.customTableTitles.filter(item => item.checked) const checkedGroup = this.customTableTitles.filter(item => item.checked)
let checkedNum = checkedGroup.length const checkedNum = checkedGroup.length
if (columnType === 'dillDown') { if (columnType === 'dillDown') {
if (checkedNum === 1) { if (checkedNum === 1) {
return 'auto' return 'auto'
@@ -1038,12 +1054,12 @@ export default {
} else { } else {
item.scoreGroup[self.columnNameGroup[tableColumn.prop]] = 0 item.scoreGroup[self.columnNameGroup[tableColumn.prop]] = 0
} }
if (Object.keys(item.scoreGroup).length >= 5) { /* if (Object.keys(item.scoreGroup).length >= 5) {
item.score = computeScore(item.scoreGroup) item.score = computeScore(item.scoreGroup)
if (!_.isNumber(item.score)) { if (!_.isNumber(item.score)) {
item.score = '-' item.score = '-'
} }
} } */
}) })
} else { } else {
tableColumn.showError = true tableColumn.showError = true
@@ -2223,6 +2239,18 @@ export default {
this.orderBy = 'sessions' this.orderBy = 'sessions'
this.metricUnit = 'sessions' this.metricUnit = 'sessions'
} }
},
handleScoreData () {
this.tableData.forEach(t => {
const data = {
establishLatencyMs: t.scoreGroup ? t.scoreGroup.establishLatencyMs : null,
httpResponseLatency: t.scoreGroup ? t.scoreGroup.httpResponseLatency : null,
sslConLatency: t.scoreGroup ? t.scoreGroup.sslConLatency : null,
tcpLostlenPercent: t.scoreGroup ? t.scoreGroup.tcpLostlenPercent : null,
pktRetransPercent: t.scoreGroup ? t.scoreGroup.pktRetransPercent : null
}
t.score = computeScore(data, this.$store.getters.getScoreBase)
})
} }
}, },
async mounted () { async mounted () {

View File

@@ -172,7 +172,8 @@ export default {
curTabState: curTabState, curTabState: curTabState,
urlChangeParams: {}, urlChangeParams: {},
showError: false, showError: false,
errorMsg: '' errorMsg: '',
scoreDataState: false // 评分数据是否加载完成
} }
}, },
components: { components: {
@@ -185,6 +186,21 @@ export default {
handler () { handler () {
this.init() this.init()
} }
},
scoreBaseState (n) {
if (n && this.scoreDataState) {
this.handleScoreData()
}
},
scoreDataState (n) {
if (n && this.scoreBaseState) {
this.handleScoreData()
}
}
},
computed: {
scoreBaseState () {
return this.$store.getters.scoreBaseReady
} }
}, },
methods: { methods: {
@@ -197,6 +213,7 @@ export default {
const currentTrafficRequest = axios.get(api.npm.overview.appTrafficAnalysis, { params: { ...params, cycle: 0 } }) const currentTrafficRequest = axios.get(api.npm.overview.appTrafficAnalysis, { params: { ...params, cycle: 0 } })
const lastCycleTrafficRequest = axios.get(api.npm.overview.appTrafficAnalysis, { params: { ...params, cycle: 1 } }) const lastCycleTrafficRequest = axios.get(api.npm.overview.appTrafficAnalysis, { params: { ...params, cycle: 1 } })
this.toggleLoading(true) this.toggleLoading(true)
this.scoreDataState = false
Promise.all([currentTrafficRequest, lastCycleTrafficRequest]).then(res => { Promise.all([currentTrafficRequest, lastCycleTrafficRequest]).then(res => {
if (res[0].status === 200 && res[1].status === 200) { if (res[0].status === 200 && res[1].status === 200) {
this.showError = false this.showError = false
@@ -239,6 +256,9 @@ export default {
t[keyPre[i] + 'Score'] = r.data.data.result.find(d => d.appSubcategory === t.appSubcategory) t[keyPre[i] + 'Score'] = r.data.data.result.find(d => d.appSubcategory === t.appSubcategory)
}) })
} else { } else {
tableData.forEach(t => {
t[keyPre[i] + 'Score'] = null
})
this.showError = true this.showError = true
msg = msg + ',' + r.data.data.message msg = msg + ',' + r.data.data.message
if (msg.indexOf(',') === 0) { if (msg.indexOf(',') === 0) {
@@ -250,7 +270,7 @@ export default {
this.errorMsg = msg this.errorMsg = msg
} }
}) })
tableData.forEach(t => { /* tableData.forEach(t => {
const data = { const data = {
establishLatencyMs: t.tcpScore ? t.tcpScore.establishLatencyMs : null, establishLatencyMs: t.tcpScore ? t.tcpScore.establishLatencyMs : null,
httpResponseLatency: t.httpScore ? t.httpScore.httpResponseLatency : null, httpResponseLatency: t.httpScore ? t.httpScore.httpResponseLatency : null,
@@ -259,10 +279,11 @@ export default {
pktRetransPercent: t.packetRetransScore ? t.packetRetransScore.pktRetransPercent : null pktRetransPercent: t.packetRetransScore ? t.packetRetransScore.pktRetransPercent : null
} }
t.score = computeScore(data) t.score = computeScore(data)
}) }) */
this.tableData = tableData this.tableData = tableData
}).finally(() => { }).finally(() => {
this.toggleLoading(false) this.toggleLoading(false)
this.scoreDataState = true
}) })
} else { } else {
this.tableData = [] this.tableData = []
@@ -382,6 +403,18 @@ export default {
overwriteUrl(newUrl) overwriteUrl(newUrl)
} }
this.urlChangeParams = {} this.urlChangeParams = {}
},
handleScoreData () {
this.tableData.forEach(t => {
const data = {
establishLatencyMs: t.tcpScore ? t.tcpScore.establishLatencyMs : null,
httpResponseLatency: t.httpScore ? t.httpScore.httpResponseLatency : null,
sslConLatency: t.sslScore ? t.sslScore.sslConLatency : null,
tcpLostlenPercent: t.tcpLostScore ? t.tcpLostScore.tcpLostlenPercent : null,
pktRetransPercent: t.packetRetransScore ? t.packetRetransScore.pktRetransPercent : null
}
t.score = computeScore(data, this.$store.getters.getScoreBase)
})
} }
}, },
mounted () { mounted () {

View File

@@ -43,21 +43,38 @@ export default {
trafficDirection: 'Server', trafficDirection: 'Server',
curTabState: curTabState, curTabState: curTabState,
showError: false, showError: false,
errorMsg: '' errorMsg: '',
scoreDataState: false
} }
}, },
mixins: [chartMixin], mixins: [chartMixin],
computed: {
scoreBaseState () {
return this.$store.getters.scoreBaseReady
}
},
watch: { watch: {
timeFilter: { timeFilter: {
handler () { handler () {
this.loadAm4ChartMap(this.polygonSeries, this.worldImageSeries) this.loadAm4ChartMap(this.polygonSeries, this.worldImageSeries)
} }
},
scoreBaseState (n) {
if (n && this.scoreDataState) {
this.handleScoreData()
}
},
scoreDataState (n) {
if (n && this.scoreBaseState) {
this.handleScoreData()
}
} }
}, },
methods: { methods: {
async initMap () { async initMap () {
// 初始化插件 // 初始化插件
this.toggleLoading(true) this.toggleLoading(true)
this.scoreDataState = false // 重置评分数据状态
const geoData = await getGeoData(storageKey.iso36112WorldLow) const geoData = await getGeoData(storageKey.iso36112WorldLow)
const chart = am4Core.create('npmDrillDownMap', am4Maps.MapChart) const chart = am4Core.create('npmDrillDownMap', am4Maps.MapChart)
chart.geodata = geoData chart.geodata = geoData
@@ -81,6 +98,7 @@ export default {
// 清除数据 // 清除数据
// polygonSeries.data.splice(0) // polygonSeries.data.splice(0)
this.toggleLoading(true) this.toggleLoading(true)
this.scoreDataState = false // 重置评分数据状态
// 清除legend // 清除legend
this.myChart.children.each((s, i) => { this.myChart.children.each((s, i) => {
if (s && s.className !== 'Container') { if (s && s.className !== 'Container') {
@@ -140,10 +158,11 @@ export default {
tcpLostlenPercent: valueToRangeValue(data.tcpLostlenPercent, unitTypes.percent).join(' '), tcpLostlenPercent: valueToRangeValue(data.tcpLostlenPercent, unitTypes.percent).join(' '),
pktRetransPercent: valueToRangeValue(data.pktRetransPercent, unitTypes.percent).join(' ') pktRetransPercent: valueToRangeValue(data.pktRetransPercent, unitTypes.percent).join(' ')
} }
t.tooltip.data.score = computeScore(data) t.performanceData = data
/* t.tooltip.data.score = computeScore(data)
if (t.tooltip.data.score === '-') { if (t.tooltip.data.score === '-') {
t.tooltip.data.score = '' t.tooltip.data.score = ''
} } */
t.tooltip.data.total = valueToRangeValue(t.totalBitsRate, unitTypes.bps).join(' ') t.tooltip.data.total = valueToRangeValue(t.totalBitsRate, unitTypes.bps).join(' ')
t.tooltip.data.inbound = valueToRangeValue(t.inboundBitsRate, unitTypes.bps).join(' ') t.tooltip.data.inbound = valueToRangeValue(t.inboundBitsRate, unitTypes.bps).join(' ')
t.tooltip.data.outbound = valueToRangeValue(t.outboundBitsRate, unitTypes.bps).join(' ') t.tooltip.data.outbound = valueToRangeValue(t.outboundBitsRate, unitTypes.bps).join(' ')
@@ -161,6 +180,7 @@ export default {
sslConLatency: this.$t('networkAppPerformance.sslResponseLatency') sslConLatency: this.$t('networkAppPerformance.sslResponseLatency')
} }
}) })
this.scoreDataState = true
this.loadMarkerData(imageSeries, mapData) this.loadMarkerData(imageSeries, mapData)
}) })
} else { } else {
@@ -180,14 +200,10 @@ export default {
} }
}, },
loadMarkerData (imageSeries, data) { loadMarkerData (imageSeries, data) {
const _data = data.filter(d => d.tooltip.data.score || d.tooltip.data.score === 0) imageSeries.data = data.map(r => ({
imageSeries.data = _data.map(r => ({
...r, ...r,
score: r.tooltip.data.score,
name: r.superAdminArea || r.countryRegion, name: r.superAdminArea || r.countryRegion,
id: r.serverId, id: r.serverId
color: this.scoreColor(r.tooltip.data.score),
border: this.scoreColor(r.tooltip.data.score)
})) }))
}, },
scoreColor (score) { scoreColor (score) {
@@ -307,6 +323,22 @@ export default {
}) })
return imageSeries return imageSeries
},
handleScoreData () {
const imageSeries = this.location ? this.countryImageSeries : this.worldImageSeries
imageSeries.data = imageSeries.data.map(d => {
let score = computeScore(d.performanceData, this.$store.getters.getScoreBase)
if (score === '-') {
score = ''
}
d.tooltip.data.score = score
return {
...d,
score,
color: this.scoreColor(score),
border: this.scoreColor(score)
}
})
} }
}, },
mounted () { mounted () {

View File

@@ -75,14 +75,21 @@ export default {
trafficDirection: 'Server', trafficDirection: 'Server',
location: '', location: '',
showError: false, showError: false,
errorMsg: '' errorMsg: '',
scoreDataState: false
} }
}, },
mixins: [chartMixin], mixins: [chartMixin],
computed: {
scoreBaseState () {
return this.$store.getters.scoreBaseReady
}
},
methods: { methods: {
async initMap () { async initMap () {
// 初始化插件 // 初始化插件
this.toggleLoading(true) this.toggleLoading(true)
this.scoreDataState = false // 重置评分数据状态
const geoData = await getGeoData(storageKey.iso36112WorldLow) const geoData = await getGeoData(storageKey.iso36112WorldLow)
const chart = am4Core.create('npmMap', am4Maps.MapChart) const chart = am4Core.create('npmMap', am4Maps.MapChart)
chart.geodata = geoData chart.geodata = geoData
@@ -101,14 +108,13 @@ export default {
this.worldImageSeries.mapImages.template.events.on('hit', async ev => { this.worldImageSeries.mapImages.template.events.on('hit', async ev => {
this.$store.commit('setNpmLocationCountry', ev.target.dataItem.dataContext.name) this.$store.commit('setNpmLocationCountry', ev.target.dataItem.dataContext.name)
this.location = ev.target.dataItem.dataContext.name this.location = ev.target.dataItem.dataContext.name
const countryId = ev.target.dataItem.dataContext.id
ev.target.isHover = false ev.target.isHover = false
await this.drill(countryId)
}) })
}, },
loadAm4ChartMap (polygonSeries, imageSeries) { loadAm4ChartMap (polygonSeries, imageSeries) {
try { try {
this.toggleLoading(true) this.toggleLoading(true)
this.scoreDataState = false // 重置评分数据状态
// 清除legend // 清除legend
this.myChart.children.each((s, i) => { this.myChart.children.each((s, i) => {
if (s && s.className !== 'Container') { if (s && s.className !== 'Container') {
@@ -172,10 +178,11 @@ export default {
tcpLostlenPercent: valueToRangeValue(data.tcpLostlenPercent, unitTypes.percent).join(' '), tcpLostlenPercent: valueToRangeValue(data.tcpLostlenPercent, unitTypes.percent).join(' '),
pktRetransPercent: valueToRangeValue(data.pktRetransPercent, unitTypes.percent).join(' ') pktRetransPercent: valueToRangeValue(data.pktRetransPercent, unitTypes.percent).join(' ')
} }
t.tooltip.data.score = computeScore(data) t.performanceData = data
/* t.tooltip.data.score = computeScore(data)
if (t.tooltip.data.score === '-') { if (t.tooltip.data.score === '-') {
t.tooltip.data.score = '' t.tooltip.data.score = ''
} } */
t.tooltip.data.total = valueToRangeValue(t.totalBitsRate, unitTypes.bps).join(' ') t.tooltip.data.total = valueToRangeValue(t.totalBitsRate, unitTypes.bps).join(' ')
t.tooltip.data.inbound = valueToRangeValue(t.inboundBitsRate, unitTypes.bps).join(' ') t.tooltip.data.inbound = valueToRangeValue(t.inboundBitsRate, unitTypes.bps).join(' ')
t.tooltip.data.outbound = valueToRangeValue(t.outboundBitsRate, unitTypes.bps).join(' ') t.tooltip.data.outbound = valueToRangeValue(t.outboundBitsRate, unitTypes.bps).join(' ')
@@ -193,6 +200,7 @@ export default {
sslConLatency: this.$t('networkAppPerformance.sslResponseLatency') sslConLatency: this.$t('networkAppPerformance.sslResponseLatency')
} }
}) })
this.scoreDataState = true
this.loadMarkerData(imageSeries, mapData) this.loadMarkerData(imageSeries, mapData)
}).catch(e => { }).catch(e => {
this.showError = true this.showError = true
@@ -219,17 +227,13 @@ export default {
} }
}, },
loadMarkerData (imageSeries, data) { loadMarkerData (imageSeries, data) {
const _data = data.filter(d => d.tooltip.data.score || d.tooltip.data.score === 0) imageSeries.data = data.map(r => ({
imageSeries.data = _data.map(r => ({
...r, ...r,
score: r.tooltip.data.score,
name: r.superAdminArea || r.countryRegion, name: r.superAdminArea || r.countryRegion,
id: r.serverId, id: r.serverId
color: this.scoreColor(r.tooltip.data.score),
border: this.scoreColor(r.tooltip.data.score)
})) }))
if (!this.location) { if (!this.location) {
this.filterLocationOptions(_data) this.filterLocationOptions(data)
} }
}, },
filterLocationOptions (data) { filterLocationOptions (data) {
@@ -391,6 +395,23 @@ export default {
this.$message.warning(this.$t('tip.noDetailMap')) this.$message.warning(this.$t('tip.noDetailMap'))
} }
} }
},
handleScoreData () {
const imageSeries = this.location ? this.countryImageSeries : this.worldImageSeries
imageSeries.data = imageSeries.data.map(d => {
let score = computeScore(d.performanceData, this.$store.getters.getScoreBase)
if (score === '-') {
score = ''
}
d.tooltip.data.score = score
return {
...d,
score,
color: this.scoreColor(score),
border: this.scoreColor(score)
}
})
// this.myChart.invalidateData()
} }
}, },
watch: { watch: {
@@ -430,6 +451,16 @@ export default {
this.loadAm4ChartMap(this.polygonSeries, this.worldImageSeries) this.loadAm4ChartMap(this.polygonSeries, this.worldImageSeries)
} }
} }
},
scoreBaseState (n) {
if (n && this.scoreDataState) {
this.handleScoreData()
}
},
scoreDataState (n) {
if (n && this.scoreBaseState) {
this.handleScoreData()
}
} }
}, },
mounted () { mounted () {

View File

@@ -7,7 +7,7 @@ import {
chartColorForBehaviorPattern, chartColorForBehaviorPattern,
unitTypes unitTypes
} from '@/utils/constants' } from '@/utils/constants'
import unitConvert, { valueToRangeValue } from '@/utils/unit-convert' import unitConvert from '@/utils/unit-convert'
import { axisFormatter } from '@/views/charts/charts/tools' import { axisFormatter } from '@/views/charts/charts/tools'
import { xAxisTimeFormatter, xAxisTimeRich } from '@/utils/date-util' import { xAxisTimeFormatter, xAxisTimeRich } from '@/utils/date-util'

View File

@@ -17,7 +17,7 @@
@search="search" @search="search"
></explorer-search> ></explorer-search>
<!-- 内容区 --> <!-- 内容区 -->
<div v-if="showList" style="display: flex;flex-direction: row;"> <div v-if="showList" style="display: flex;flex-direction: row;padding-bottom: 20px;">
<entity-filter <entity-filter
:filter-data="newFilterData" :filter-data="newFilterData"
:loading-left="loadingLeft" :loading-left="loadingLeft"
@@ -689,6 +689,44 @@ export default {
} else { } else {
this.search({ q: '', str: '', metaList: [] }) this.search({ q: '', str: '', metaList: [] })
} }
},
queryScoreBase () {
const { startTime, endTime } = getNowTime(60 * 24)
const params = {
startTime: getSecond(startTime),
endTime: getSecond(endTime)
}
const tcp = axios.get(api.npm.overview.tcpSessionDelay, { params: params })
const http = axios.get(api.npm.overview.httpResponseDelay, { params: params })
const ssl = axios.get(api.npm.overview.sslConDelay, { params: params })
const tcpPercent = axios.get(api.npm.overview.tcpLostlenPercent, { params: params })
const packetPercent = axios.get(api.npm.overview.packetRetransPercent, { params: params })
Promise.all([tcp, http, ssl, tcpPercent, packetPercent]).then(res => {
const scoreBase = {}
res.forEach((t, i) => {
if (t.status === 200) {
if (i === 0) {
scoreBase.establishLatencyMsP10 = _.get(t.data, 'data.result.establishLatencyMsP10', null)
scoreBase.establishLatencyMsP90 = _.get(t.data, 'data.result.establishLatencyMsP90', null)
} else if (i === 1) {
scoreBase.httpResponseLatencyP10 = _.get(t.data, 'data.result.httpResponseLatencyP10', null)
scoreBase.httpResponseLatencyP90 = _.get(t.data, 'data.result.httpResponseLatencyP90', null)
} else if (i === 2) {
scoreBase.sslConLatencyP10 = _.get(t.data, 'data.result.sslConLatencyP10', null)
scoreBase.sslConLatencyP90 = _.get(t.data, 'data.result.sslConLatencyP90', null)
} else if (i === 3) {
scoreBase.tcpLostlenPercentP10 = _.get(t.data, 'data.result.tcpLostlenPercentP10', null)
scoreBase.tcpLostlenPercentP90 = _.get(t.data, 'data.result.tcpLostlenPercentP90', null)
} else if (i === 4) {
scoreBase.pktRetransPercentP10 = _.get(t.data, 'data.result.pktRetransPercentP10', null)
scoreBase.pktRetransPercentP90 = _.get(t.data, 'data.result.pktRetransPercentP90', null)
}
}
})
this.$store.commit('setScoreBase', scoreBase)
}).catch((e) => {
}).finally(() => {
})
} }
}, },
mounted () { mounted () {
@@ -709,6 +747,9 @@ export default {
} }
this.initSearch(q) this.initSearch(q)
this.listMode = listMode this.listMode = listMode
// 查询评分基准
this.$store.commit('resetScoreBase')
this.queryScoreBase()
} }
}, },
watch: { watch: {

View File

@@ -39,7 +39,7 @@
</div> </div>
<div @click="showMoreFilter(item, index)" <div @click="showMoreFilter(item, index)"
:class="item.showNum === item.data.length ? 'filter-no-show-more' : 'filter-show-more'"> :class="item.showNum === item.data.length ? 'filter-no-show-more' : 'filter-show-more'">
{{ $t('entity.showMore') }} {{ $t('overall.showMore') }}
</div> </div>
<div class="filter-hr"></div> <div class="filter-hr"></div>
</div> </div>

View File

@@ -678,7 +678,6 @@ export default {
// 手动高亮listNode // 手动高亮listNode
const _listNode = _this.graph.findById(listNode.id) const _listNode = _this.graph.findById(listNode.id)
_this.graph.emit('node:click', { item: _listNode, target: _listNode.getKeyShape() }) _this.graph.emit('node:click', { item: _listNode, target: _listNode.getKeyShape() })
console.info(_this.stackData)
if (_this.stackData.justUndo) { if (_this.stackData.justUndo) {
_this.stackData.justUndo = false _this.stackData.justUndo = false
_this.stackData.redo = [] _this.stackData.redo = []

View File

@@ -143,7 +143,10 @@
<div class="row-item-label"> <div class="row-item-label">
<span class="row-item-label">{{ $t('network.score') }}&nbsp;:&nbsp;&nbsp;</span> <span class="row-item-label">{{ $t('network.score') }}&nbsp;:&nbsp;&nbsp;</span>
<span class="row-item-value" style="position: relative;"> <span class="row-item-value" style="position: relative;">
<span v-if="!loadingNetworkQuality">{{ score }}</span> <template v-if="!loadingNetworkQuality && score !=='-'">
<span v-for="(dot, i) in scoreDot" :key="i" :class="dot.class"></span>
</template>
<template v-else-if="score ==='-'"><span>-</span></template>
<loading :loading="loadingNetworkQuality" size="small"></loading> <loading :loading="loadingNetworkQuality" size="small"></loading>
</span> </span>
</div> </div>

View File

@@ -68,12 +68,8 @@
<div class="row__label row__label--width130">{{$t('entities.networkQualityRating')}}</div> <div class="row__label row__label--width130">{{$t('entities.networkQualityRating')}}</div>
<div style="position: relative;"> <div style="position: relative;">
<div class="entity-score" v-if="!loadingNetworkQuality"> <div class="entity-score" v-if="!loadingNetworkQuality">
<div v-if="score !== '-'"> <span v-for="(dot, i) in scoreDot" :key="i" :class="dot.class"></span>
<div class="circle-icon" v-if="score <= 2 || score === '-'" :class="{'data-score-red': score <= 2 || score === '-'}" ></div> <span style="padding-left: 4px;">{{score}}</span>
<div class="circle-icon" v-else-if="score <= 4" :class="{'data-score-yellow': score <= 4}" ></div>
<div class="circle-icon" v-else-if="score <= 6" :class="{'data-score-green': score <= 6}" ></div>
</div>
{{score}}
</div> </div>
<loading :loading="loadingNetworkQuality" size="small" style="left: 1rem;width: 50%;"></loading> <loading :loading="loadingNetworkQuality" size="small" style="left: 1rem;width: 50%;"></loading>
</div> </div>

View File

@@ -76,12 +76,8 @@
<div class="row__label row__label--width130">{{$t('entities.networkQualityRating')}}</div> <div class="row__label row__label--width130">{{$t('entities.networkQualityRating')}}</div>
<div style="position: relative;"> <div style="position: relative;">
<div class="entity-score" v-if="!loadingNetworkQuality"> <div class="entity-score" v-if="!loadingNetworkQuality">
<div v-if="score !== '-'"> <span v-for="(dot, i) in scoreDot" :key="i" :class="dot.class"></span>
<div class="circle-icon" v-if="score <= 2 || score === '-'" :class="{'data-score-red': score <= 2 || score === '-'}" ></div> <span style="padding-left: 4px;">{{score}}</span>
<div class="circle-icon" v-else-if="score <= 4" :class="{'data-score-yellow': score <= 4}" ></div>
<div class="circle-icon" v-else-if="score <= 6" :class="{'data-score-green': score <= 6}" ></div>
</div>
{{score}}
</div> </div>
<loading :loading="loadingNetworkQuality" size="small" style="left: 1rem;width: 50%;"></loading> <loading :loading="loadingNetworkQuality" size="small" style="left: 1rem;width: 50%;"></loading>
</div> </div>

View File

@@ -107,12 +107,8 @@
<div class="row__label row__label--width130">{{$t('entities.networkQualityRating')}}</div> <div class="row__label row__label--width130">{{$t('entities.networkQualityRating')}}</div>
<div style="position: relative;"> <div style="position: relative;">
<div class="entity-score" v-if="!loadingNetworkQuality"> <div class="entity-score" v-if="!loadingNetworkQuality">
<div v-if="score !== '-'"> <span v-for="(dot, i) in scoreDot" :key="i" :class="dot.class"></span>
<div class="circle-icon" v-if="score <= 2 || score === '-'" :class="{'data-score-red': score <= 2 || score === '-'}" ></div> <span style="padding-left: 4px;">{{score}}</span>
<div class="circle-icon" v-else-if="score <= 4" :class="{'data-score-yellow': score <= 4}" ></div>
<div class="circle-icon" v-else-if="score <= 6" :class="{'data-score-green': score <= 6}" ></div>
</div>
{{score}}
</div> </div>
<loading :loading="loadingNetworkQuality" size="small" style="left: 1rem;width: 50%;"></loading> <loading :loading="loadingNetworkQuality" size="small" style="left: 1rem;width: 50%;"></loading>
</div> </div>

View File

@@ -48,7 +48,9 @@ export default {
score: '-', // 网络质量评分 score: '-', // 网络质量评分
performanceMetricEndTimeInterval: 3600, // 服务质量事件指标的结束时间与开始时间的秒间隔 performanceMetricEndTimeInterval: 3600, // 服务质量事件指标的结束时间与开始时间的秒间隔
isShowMoreApp: false, // related App 展示更多时 isShowMoreApp: false, // related App 展示更多时
isShowMoreDomain: false // related Domain 展示更多时 isShowMoreDomain: false, // related Domain 展示更多时
scoreDataState: false, // 性能数据加载情况true 表示加载完成
performanceScoreData: {} // 用来计算评分的性能数据
} }
}, },
computed: { computed: {
@@ -92,6 +94,21 @@ export default {
} }
return className return className
} }
},
scoreBaseState () {
return this.$store.getters.scoreBaseReady
}
},
watch: {
scoreBaseState (n) {
if (n && this.scoreDataState) {
this.handleScoreData()
}
},
scoreDataState (n) {
if (n && this.scoreBaseState) {
this.handleScoreData()
}
} }
}, },
methods: { methods: {
@@ -258,17 +275,18 @@ export default {
queryEntityDetailNetworkQuantity () { queryEntityDetailNetworkQuantity () {
this.loadingNetworkQuality = true this.loadingNetworkQuality = true
this.performanceScoreData = {}
this.scoreDataState = false
if (this.networkQuantityUrl) { if (this.networkQuantityUrl) {
axios.get(this.networkQuantityUrl, { params: this.getQueryParams() }).then(response => { axios.get(this.networkQuantityUrl, { params: this.getQueryParams() }).then(response => {
if (response.status === 200) { if (response.status === 200) {
const data = { this.performanceScoreData = {
establishLatencyMs: response.data.data.result.establishLatencyMsAvg || null, establishLatencyMs: response.data.data.result.establishLatencyMsAvg || null,
httpResponseLatency: response.data.data.result.httpResponseLatencyAvg || null, httpResponseLatency: response.data.data.result.httpResponseLatencyAvg || null,
sslConLatency: response.data.data.result.sslConLatencyAvg || null, sslConLatency: response.data.data.result.sslConLatencyAvg || null,
tcpLostlenPercent: response.data.data.result.tcpLostlenPercentAvg || null, tcpLostlenPercent: response.data.data.result.tcpLostlenPercentAvg || null,
pktRetransPercent: response.data.data.result.pktRetransPercentAvg || null pktRetransPercent: response.data.data.result.pktRetransPercentAvg || null
} }
this.score = computeScore(data)
this.entityData.establishLatencyMsAvg = response.data.data.result.establishLatencyMsAvg this.entityData.establishLatencyMsAvg = response.data.data.result.establishLatencyMsAvg
this.entityData.establishLatencyP50 = response.data.data.result.establishLatencyP50 this.entityData.establishLatencyP50 = response.data.data.result.establishLatencyP50
this.entityData.establishLatencyP90 = response.data.data.result.establishLatencyP90 this.entityData.establishLatencyP90 = response.data.data.result.establishLatencyP90
@@ -321,6 +339,8 @@ export default {
this.singleValues.chartDatas.splice(4, 1, pktRetransPercent) this.singleValues.chartDatas.splice(4, 1, pktRetransPercent)
} }
this.loadingNetworkQuality = false this.loadingNetworkQuality = false
}).finally(() => {
this.scoreDataState = true
}) })
} }
}, },
@@ -472,6 +492,9 @@ export default {
document.body.addEventListener('click', showBlock) document.body.addEventListener('click', showBlock)
}) })
} }
},
handleScoreData () {
this.score = computeScore(this.performanceScoreData, this.$store.getters.getScoreBase)
} }
}, },
setup () { setup () {

View File

@@ -30,7 +30,9 @@ export default {
eventNum: 0, // 性能事件和安全事件数量之和 eventNum: 0, // 性能事件和安全事件数量之和
loadingEvent: false, // event的loading loadingEvent: false, // event的loading
performanceEventUrl: '', // 性能事件接口url performanceEventUrl: '', // 性能事件接口url
securityEventUrl: '' // 安全事件接口url securityEventUrl: '', // 安全事件接口url
performanceScoreData: {},
scoreDataState: false
} }
}, },
computed: { computed: {
@@ -77,6 +79,43 @@ export default {
resource: this.entityData.entityValue resource: this.entityData.entityValue
} }
return params return params
},
scoreBaseState () {
return this.$store.getters.scoreBaseReady
},
scoreDot () {
const dots = []
if (this.score === '-') {
for (let i = 0; i < 6; i++) {
dots.push({
class: 'score-dot'
})
}
} else {
for (let i = 0; i < 6; i++) {
if (i < this.score) {
dots.push({
class: `score-dot ${handleClass(this.score)}`
})
} else {
dots.push({
class: 'score-dot'
})
}
}
}
return dots
function handleClass (score) {
if (score <= 2) {
return 'score-dot--red'
} else if (score <= 4) {
return 'score-dot--yellow'
} else if (score <= 6) {
return 'score-dot--green'
}
return ''
}
} }
}, },
methods: { methods: {
@@ -221,20 +260,21 @@ export default {
/** 获取网络评分 */ /** 获取网络评分 */
queryNetworkQuantity () { queryNetworkQuantity () {
this.loadingNetworkQuality = true this.loadingNetworkQuality = true
this.performanceScoreData = {}
this.scoreDataState = false
axios.get(this.scoreUrl, { params: this.getQueryParams() }).then(response => { axios.get(this.scoreUrl, { params: this.getQueryParams() }).then(response => {
if (response.status === 200) { if (response.status === 200) {
const data = { this.performanceScoreData = {
establishLatencyMs: _.get(response, 'data.data.result.establishLatencyMsAvg', null), establishLatencyMs: _.get(response, 'data.data.result.establishLatencyMsAvg', null),
httpResponseLatency: _.get(response, 'data.data.result.httpResponseLatencyAvg', null), httpResponseLatency: _.get(response, 'data.data.result.httpResponseLatencyAvg', null),
sslConLatency: _.get(response, 'data.data.result.sslConLatencyAvg', null), sslConLatency: _.get(response, 'data.data.result.sslConLatencyAvg', null),
tcpLostlenPercent: _.get(response, 'data.data.result.tcpLostlenPercentAvg', null), tcpLostlenPercent: _.get(response, 'data.data.result.tcpLostlenPercentAvg', null),
pktRetransPercent: _.get(response, 'data.data.result.pktRetransPercentAvg', null) pktRetransPercent: _.get(response, 'data.data.result.pktRetransPercentAvg', null)
} }
this.score = computeScore(data)
} }
}).finally(() => { }).finally(() => {
this.loadingNetworkQuality = false this.loadingNetworkQuality = false
this.scoreDataState = true
}) })
}, },
/** 获取事件数量 */ /** 获取事件数量 */
@@ -251,6 +291,9 @@ export default {
}).finally(() => { }).finally(() => {
this.loadingEvent = false this.loadingEvent = false
}) })
},
handleScoreData () {
this.score = computeScore(this.performanceScoreData, this.$store.getters.getScoreBase)
} }
}, },
watch: { watch: {
@@ -259,6 +302,16 @@ export default {
handler (n) { handler (n) {
this.initUrl() this.initUrl()
} }
},
scoreBaseState (n) {
if (n && this.scoreDataState) {
this.handleScoreData()
}
},
scoreDataState (n) {
if (n && this.scoreBaseState) {
this.handleScoreData()
}
} }
}, },
mounted () { mounted () {