Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b822015daa |
@@ -29,7 +29,7 @@ npm run lint
|
||||
|
||||
### 3.图表组件库
|
||||
图表:echarts5.0
|
||||
地图:amCharts4
|
||||
地图:amCharts
|
||||
拖拽 & Resize:Vue-grid-layout https://jbaysolutions.github.io/vue-grid-layout/guide/
|
||||
|
||||
### 4.响应式方案
|
||||
@@ -51,7 +51,7 @@ https://www.lodashjs.com/
|
||||
多个单词时,应该以高阶的 (通常是一般化描述的) 单词开头,以描述性的修饰词结尾
|
||||
eg:`SearchButtonClear.vue` 反例:`ClearSearchButton.vue`
|
||||
- **文件夹**
|
||||
使用小写,单词间使用连字符`-`连接,或使用驼峰格式
|
||||
使用小写,单词间使用连字符`-`连接,或使用驼峰格式
|
||||
eg:`right-box`、`rightBox`
|
||||
|
||||
|
||||
|
||||
@@ -12,8 +12,7 @@ module.exports = {
|
||||
],
|
||||
plugins: [
|
||||
'@vue/babel-plugin-jsx',
|
||||
['@babel/proposal-class-properties', { loose: true }],
|
||||
['@babel/plugin-proposal-private-methods', { loose: true }],
|
||||
'@babel/proposal-class-properties',
|
||||
'@babel/transform-runtime',
|
||||
'lodash'
|
||||
],
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"analyz": "cross-env NODE_ENV=production npm_config_report=true npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@amcharts/amcharts4": "^4.10.24",
|
||||
"@amcharts/amcharts4": "^4.10.20",
|
||||
"@amcharts/amcharts4-geodata": "^4.1.20",
|
||||
"axios": "^0.21.1",
|
||||
"babel-plugin-lodash": "^3.3.4",
|
||||
|
||||
45
public/assets/echarts.min.js
vendored
45
public/assets/echarts.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -4,12 +4,11 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { storageKey } from '@/utils/constants'
|
||||
export default {
|
||||
name: 'App',
|
||||
setup () {
|
||||
// 处理刷新后 $dayJs的时区变为默认的问题
|
||||
const timezone = localStorage.getItem(storageKey.sysTimezone) || ''
|
||||
const timezone = localStorage.getItem('cn-sys-timezone') || ''
|
||||
if (timezone) {
|
||||
window.$dayJs.tz.setDefault(timezone)
|
||||
} else {
|
||||
|
||||
@@ -39,11 +39,7 @@
|
||||
|
||||
<script>
|
||||
import { mapActions } from 'vuex'
|
||||
import { post, get } from '@/utils/http'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { storageKey } from '@/utils/constants'
|
||||
import { api } from '@/utils/api'
|
||||
|
||||
import { post } from '@/utils/http'
|
||||
export default {
|
||||
|
||||
name: 'Login',
|
||||
@@ -66,18 +62,11 @@ export default {
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
post(api.login, { username: this.username, pin: this.pin }).then(
|
||||
post('sys/login', { username: this.username, pin: this.pin }).then(
|
||||
res => {
|
||||
if (res.code === 200) {
|
||||
if (!this.$_.isEmpty(res.data.lang)) {
|
||||
localStorage.setItem(storageKey.language, res.data.lang)
|
||||
}
|
||||
if (!this.$_.isEmpty(res.data.theme)) {
|
||||
localStorage.setItem(storageKey.theme, res.data.theme)
|
||||
}
|
||||
res.loginSuccessPath = this.loginSuccessPath
|
||||
this.loginSuccess(res)
|
||||
localStorage.setItem(storageKey.username, this.username)
|
||||
localStorage.setItem('cn-username', this.username)
|
||||
} else if (res.code === 518005) {
|
||||
this.$message.error(this.$t('Incorrect username or password'))
|
||||
this.loading = false
|
||||
@@ -93,36 +82,6 @@ export default {
|
||||
this.blockOperation.query = false
|
||||
this.$message.error(this.$t('tip.unknownError'))
|
||||
})
|
||||
},
|
||||
appearance () {
|
||||
get(api.appearance).then(res => {
|
||||
if (res.code === 200) {
|
||||
this.appearanceOut(res.data)
|
||||
}
|
||||
})
|
||||
},
|
||||
appearanceOut (data) {
|
||||
if (this.$_.isEmpty(localStorage.getItem(storageKey.language))) {
|
||||
localStorage.setItem(storageKey.language, data.lang)
|
||||
}
|
||||
if (this.$_.isEmpty(localStorage.getItem(storageKey.sysTimezone))) {
|
||||
localStorage.setItem(storageKey.sysTimezone, data.timezone)
|
||||
}
|
||||
if (this.$_.isEmpty(localStorage.getItem(storageKey.theme))) {
|
||||
localStorage.setItem(storageKey.theme, data.theme)
|
||||
}
|
||||
if (this.$_.isEmpty(localStorage.getItem(storageKey.dateFormat))) {
|
||||
localStorage.setItem(storageKey.dateFormat, data.dateFormat)
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.appearance()
|
||||
},
|
||||
setup (props) {
|
||||
const { currentRoute } = useRouter()
|
||||
return {
|
||||
loginSuccessPath: currentRoute.value.query.redirect
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,10 +21,3 @@ body {
|
||||
font-size: 14px;
|
||||
position: fixed;
|
||||
}
|
||||
.icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
border: 1px solid #E6EAED;
|
||||
|
||||
}
|
||||
.top-tool-search {
|
||||
.top-tool-search.margin-r-20 {
|
||||
.top-tool-btn {
|
||||
border-left: none;
|
||||
}
|
||||
@@ -247,7 +247,7 @@
|
||||
box-shadow: 1px 0 $--right-box-border-color;
|
||||
}
|
||||
.el-table:not(.no-operation):not(.chart-table).el-table--border .el-table__header-wrapper th:nth-last-child(3) {
|
||||
//border-right: none !important;
|
||||
border-right: none !important;
|
||||
box-shadow: 1px 0 $--right-box-border-color;
|
||||
}
|
||||
.el-table__fixed-body-wrapper {
|
||||
|
||||
@@ -66,11 +66,3 @@
|
||||
border-color: rgba(154,154,154,0.20);
|
||||
}
|
||||
}
|
||||
.entity__pagination .pagination {
|
||||
.el-pager li.more + li {
|
||||
display: none;
|
||||
}
|
||||
.el-pager li.number:not(:last-of-type) {
|
||||
display: inline-block !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
@import './views/charts/chartAlarmInfo';
|
||||
@import './views/chartHeader';
|
||||
@import './views/charts/chartMap';
|
||||
@import './views/report/builtinReport';
|
||||
|
||||
|
||||
//@import '../chart';
|
||||
|
||||
@@ -1,82 +1,42 @@
|
||||
.cn-chart-header-button {
|
||||
.cn-chart-header-button{
|
||||
display: flex;
|
||||
.cn-chart-header-button-group {
|
||||
display: flex;
|
||||
.el-button {
|
||||
border-radius: 0%;
|
||||
}
|
||||
|
||||
.el-button:hover {
|
||||
background: #FFFFFF;
|
||||
border-color: #0091FF;
|
||||
}
|
||||
|
||||
.el-button:last-of-type {
|
||||
border-radius: 0 2px 2px 0;
|
||||
|
||||
}
|
||||
.el-button:first-of-type{
|
||||
border-radius: 2px 0 0 2px;
|
||||
|
||||
}
|
||||
.cn-chart-header-button-all {
|
||||
border-color: #0091FF;
|
||||
color: #0091FF;
|
||||
background-color: #FFFFFF;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.cn-chart-header-button-critical {
|
||||
border-color: #0091FF;
|
||||
color: #0091FF;
|
||||
background-color: #FFFFFF;
|
||||
z-index: 1;
|
||||
|
||||
}
|
||||
|
||||
.cn-chart-header-button-high {
|
||||
border-color: #0091FF;
|
||||
background-color: #FFFFFF;
|
||||
z-index: 1;
|
||||
color: #0091FF;
|
||||
}
|
||||
|
||||
.cn-chart-header-button-low {
|
||||
border-color: #0091FF;
|
||||
background-color: #FFFFFF;
|
||||
z-index: 1;
|
||||
color: #0091FF;
|
||||
}
|
||||
|
||||
.cn-chart-header-button-info {
|
||||
border-color: #0091FF;
|
||||
background-color: #FFFFFF;
|
||||
z-index: 1;
|
||||
color: #0091FF;
|
||||
}
|
||||
|
||||
.cn-chart-header-button-medium {
|
||||
border-color: #0091FF;
|
||||
background-color: #FFFFFF;
|
||||
z-index: 1;
|
||||
color: #0091FF;
|
||||
}
|
||||
|
||||
.el-button--default {
|
||||
height: 24px;
|
||||
min-height: 24px;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
font-family: Roboto-Regular;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
}
|
||||
.cn-chart-header-button-all{
|
||||
border: 1px solid #0091FF;
|
||||
color: #0091FF;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
.cn-chart-header-button-critical{
|
||||
border: 1px solid #0091FF;
|
||||
color: #0091FF;
|
||||
background-color: #FFFFFF;
|
||||
|
||||
.header__operation-btn {
|
||||
margin-left: 12px;
|
||||
cursor: pointer;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
.cn-chart-header-button-high{
|
||||
border: 1px solid #0091FF;
|
||||
background-color: #FFFFFF;
|
||||
color: #0091FF;
|
||||
}
|
||||
.cn-chart-header-button-low{
|
||||
border: 1px solid #0091FF;
|
||||
background-color: #FFFFFF;
|
||||
color: #0091FF;
|
||||
}
|
||||
.cn-chart-header-button-info{
|
||||
border: 1px solid #0091FF;
|
||||
background-color: #FFFFFF;
|
||||
color: #0091FF;
|
||||
}
|
||||
.cn-chart-header-button-medium{
|
||||
border: 1px solid #0091FF;
|
||||
background-color: #FFFFFF;
|
||||
color: #0091FF;
|
||||
}
|
||||
.el-button--default{
|
||||
height: 24px;
|
||||
border-radius: 2px 0 0 2px;
|
||||
min-height:24px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
.cn-chart__one-situation-statistics{
|
||||
height: 100%;
|
||||
.one-situation-statistics__box {
|
||||
.chart-one-situation-statistics{
|
||||
padding-top: 22px;
|
||||
.situation-statistics-main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 33px;
|
||||
height: 100%;
|
||||
.box__progress{
|
||||
.situation-statistics-main-left{
|
||||
display: block;
|
||||
width: 76px;
|
||||
height: 76px;
|
||||
@@ -13,7 +12,7 @@
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
.box__count{
|
||||
.situation-statistics-main-right{
|
||||
margin-left: 22px;
|
||||
:first-child{
|
||||
font-size: 18px;
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
|
||||
.cn-chart__two-situation-statistics{
|
||||
.chart-two-situation-statistics{
|
||||
padding-top: 22px;
|
||||
.box__body {
|
||||
.situation-statistics-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 33px;
|
||||
padding-top: 22px;
|
||||
.body__progress{
|
||||
.situation-statistics-main-left{
|
||||
display: block;
|
||||
.el-progress__text span{
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
.body__count{
|
||||
.situation-statistics-main-right{
|
||||
margin-left: 22px;
|
||||
:first-child{
|
||||
font-size: 18px;
|
||||
|
||||
@@ -277,26 +277,22 @@
|
||||
.map-tooltip {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 3px 3px 0;
|
||||
|
||||
.map-tooltip__title {
|
||||
padding-bottom: 10px;
|
||||
color: #fff;
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
}
|
||||
.map-tooltip__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
|
||||
.content-row {
|
||||
.row__label {
|
||||
color: #ddd;
|
||||
padding-right: 5px;
|
||||
}
|
||||
.row__value {
|
||||
color: #fff;
|
||||
}
|
||||
span {
|
||||
line-height: 35px;
|
||||
}
|
||||
span:first-of-type {
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,26 @@
|
||||
.cn-chart__alarm-info {
|
||||
.cn-chart-alarm-info {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-left: 30px;
|
||||
position: relative;
|
||||
|
||||
.alarm-info__box {
|
||||
height: calc(100% - 40px);
|
||||
.cn-chart-alarm-info-mainContent{
|
||||
height: calc(100% - 40px) ;
|
||||
width: 100%;
|
||||
|
||||
.box__body {
|
||||
.cn-chart-alarm-content {
|
||||
display: flex;
|
||||
margin-left: 30px;
|
||||
margin-right: 30px;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: calc(100% / 9);
|
||||
border-bottom: 1px solid #E7EAED;
|
||||
|
||||
.body__content {
|
||||
border-bottom: 1px solid #E7EAED ;
|
||||
.cn-alarm-info-main {
|
||||
display: flex;
|
||||
|
||||
.content__icon-box {
|
||||
.cn-alarm-info-main-left{
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.icon-box__icon {
|
||||
.cn-chart-alarm-info-icon {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 50%;
|
||||
@@ -33,123 +28,71 @@
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.cn-icon-alert {
|
||||
.cn-icon-alert{
|
||||
width: 12px;
|
||||
position: absolute;
|
||||
top: calc(50% - 8px);
|
||||
left: calc(50% - 8px);
|
||||
top: 13px;
|
||||
left: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
.content__text-box {
|
||||
.cn-alarm-info-textContent{
|
||||
margin-left: 17px;
|
||||
|
||||
.text-box__title {
|
||||
font-size: 16px;
|
||||
.cn-alarm-info-main-title {
|
||||
font-size: 19px;
|
||||
line-height: 19px;
|
||||
font-family: Roboto-Regular;
|
||||
color: #333333;
|
||||
max-width: 30%;
|
||||
font-weight: 400;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.text-box__text {
|
||||
font-size: 12px;
|
||||
.cn-alarm-info-bottom {
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
line-height: 14px;
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
&>div {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.text__time-box {
|
||||
|
||||
|
||||
.cn-alarm-info-bottom-middle {
|
||||
display: flex;
|
||||
margin-left: 20px;
|
||||
height: 14px;
|
||||
|
||||
.cn-icon-time2 {
|
||||
color: #8FA1BE;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.time-box__start-time {
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 12px;
|
||||
.cn-alarm-info-bottom-time {
|
||||
color: #999999;
|
||||
line-height: 14px;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.text__duration-box {
|
||||
height: 14px;
|
||||
|
||||
.cn-alarm-info-bottom-right {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.cn-icon-time2 {
|
||||
color: #8FA1BE;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.time-box__start-time {
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 12px;
|
||||
margin-left: 17px;
|
||||
.cn-alarm-info-bottom-time {
|
||||
color: #999999;
|
||||
line-height: 17px;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
.text__type {
|
||||
|
||||
.cn-alarm-info-bottom-type {
|
||||
width: auto;
|
||||
font-family: Roboto-Regular;
|
||||
line-height: 16px;
|
||||
height: 16px;
|
||||
font-size: 12px;
|
||||
border: 1px solid;
|
||||
font-weight: 400;
|
||||
max-width: 150px;
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.duration-box__circle {
|
||||
|
||||
.cn-alarm-info-bottom-circle {
|
||||
display: inline-block;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
border-radius: 50%;
|
||||
font-family: Roboto-Black;
|
||||
font-size: 12px;
|
||||
color: #666666;
|
||||
line-height: 17px;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.alarm-info__pagination {
|
||||
height: 40px !important;
|
||||
.cn-chart-alarm-info-pagination{
|
||||
height: 40px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
flex: 0 0 25%;
|
||||
overflow: auto;
|
||||
padding-bottom: 20px;
|
||||
//border-bottom: 1px solid $--right-box-border-color;
|
||||
border-bottom: 1px solid $--right-box-border-color;
|
||||
|
||||
.related-domain__list-title {
|
||||
padding: 13px 30px 0;
|
||||
@@ -65,7 +65,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.cn-panel2 .chart-list > .vue-grid-layout > .vue-grid-item > .panel-chart .chart-header,.cn-panel2 .chart-list > .dns-screen> .panel-chart .chart-header {
|
||||
.cn-panel2 .chart-list > .vue-grid-layout > .vue-grid-item > .panel-chart .chart-header {
|
||||
border-bottom: 1px solid $--right-box-border-color;
|
||||
}
|
||||
.cn-panel2 .chart-list > .vue-grid-layout > .vue-grid-item > .panel-chart .chart-header.is-group-collapse {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
.chart-list {
|
||||
.vue-grid-layout>.vue-grid-item {
|
||||
.cn-chart {
|
||||
height: 100% !important;
|
||||
.cn-chart__echarts {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
.cn-chart__single-value {
|
||||
.single-value__unit {
|
||||
padding-left: 6px;
|
||||
}
|
||||
|
||||
&.cn-chart__single-value--detail-overview.cn-chart__single-value--icon-left {
|
||||
width: unset;
|
||||
flex: 0 0 240px;
|
||||
@@ -11,42 +7,35 @@
|
||||
.single-value__icon {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
|
||||
i {
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.single-value__content {
|
||||
.content__data {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
|
||||
.single-value__unit {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.content__title {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.cn-chart__single-value--icon-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
.single-value-icon__box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 0 0 40%;
|
||||
}
|
||||
|
||||
.single-value__icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
@@ -54,7 +43,6 @@
|
||||
height: 72px;
|
||||
background-color: $--chart-single-value-icon-background-color;
|
||||
border-radius: 50%;
|
||||
|
||||
i {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -62,20 +50,17 @@
|
||||
color: $--color-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.single-value__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 60%;
|
||||
padding-right: 10px;
|
||||
|
||||
.content__data {
|
||||
padding-bottom: 7%;
|
||||
font-size: 20px;
|
||||
font-size: 24px;
|
||||
color: #333333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.content__title {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
@@ -83,13 +68,11 @@
|
||||
font-size: 16px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
&.single-value__content--with-chart {
|
||||
.content__title {
|
||||
border-bottom: 1px solid $--content-right-background-color;
|
||||
}
|
||||
}
|
||||
|
||||
.single-value__unit {
|
||||
font-weight: normal;
|
||||
padding-left: 10px;
|
||||
@@ -98,7 +81,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.cn-chart__single-value--icon-right {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
@@ -106,34 +88,29 @@
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
.single-value-icon__box {
|
||||
flex: 0 0 80px;
|
||||
}
|
||||
|
||||
.single-value__icon {
|
||||
background-color: $--chart-single-value-icon-background-color;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
|
||||
i {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
transform: translate(-50%,-50%);
|
||||
font-size: 24px;
|
||||
color: $--color-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.single-value__content {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
padding: 0 10px;
|
||||
|
||||
.content__title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -141,7 +118,6 @@
|
||||
font-size: 16px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.content__data {
|
||||
display: flex;
|
||||
padding-top: 5%;
|
||||
@@ -153,7 +129,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.cn-chart__single-value--icon-right--color {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
@@ -161,7 +136,6 @@
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
.single-value__content {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
@@ -186,32 +160,28 @@
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
i {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
transform: translate(-50%,-50%);
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.single-value__data {
|
||||
.single-value__data{
|
||||
display: flex;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
padding-left: 20px;
|
||||
|
||||
.content__title {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
align-items: end;
|
||||
height: 50%;
|
||||
font-size: 16px;
|
||||
color: #666666;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.content__data {
|
||||
display: flex;
|
||||
padding-top: 5%;
|
||||
@@ -224,19 +194,16 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.cn-chart__single-value--chart {
|
||||
display: flex;
|
||||
padding: 13px 20px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
.single-value__content {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
|
||||
.content__title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -244,7 +211,6 @@
|
||||
font-size: 16px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.content__data {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -253,423 +219,10 @@
|
||||
color: #333333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.content__chart {
|
||||
flex: auto
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.cn-chart__single-value--icon-doh {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #E7EAED;
|
||||
box-shadow: 0 2px 4px 0 rgba(51, 51, 51, 0.02);
|
||||
border-radius: 2px;
|
||||
|
||||
.single-value-icon__box {
|
||||
flex: 0 0 80px;
|
||||
}
|
||||
|
||||
.single-value__icon {
|
||||
background-color: $--chart-single-value-icon-background-color;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
|
||||
i {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 24px;
|
||||
color: $--color-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.single-value__content {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 10px;
|
||||
margin-left: 20px;
|
||||
|
||||
.content__title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 16px 0 27px 0;
|
||||
font-family: PingFangSC-Medium;
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
line-height: 22px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.content__data {
|
||||
display: flex;
|
||||
padding-top: 5%;
|
||||
height: 50%;
|
||||
flex: auto;
|
||||
font-size: 24px;
|
||||
color: #333333;
|
||||
font-weight: bold;
|
||||
|
||||
.content__data__doh {
|
||||
.content__data__doh__count {
|
||||
font-family: Roboto-Medium;
|
||||
font-size: 30px;
|
||||
color: #333333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.content__data__doh__percent {
|
||||
margin-top: 10px;
|
||||
font-family: Roboto-Black;
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
font-weight: 400;
|
||||
|
||||
span {
|
||||
font-family: Roboto-Medium;
|
||||
font-size: 14px;
|
||||
color: #FC8157;
|
||||
font-weight: 500;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.cn-chart__single-value--protocol {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
.single-value__content {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
.single-value__data {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 10px 20px 10px 18px;
|
||||
.content__title {
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
.content__data {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
.content__data-protocol:nth-of-type(1) {
|
||||
margin-bottom: 50px;
|
||||
span:nth-of-type(2) {
|
||||
font-size: 12px;
|
||||
color: #FC8157;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
.content__data-protocol:nth-of-type(2) {
|
||||
span:nth-of-type(2) {
|
||||
font-size: 12px;
|
||||
color: #FBA342;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
.content__data-protocol {
|
||||
display: flex;
|
||||
height: 68px;
|
||||
text-align: left;
|
||||
.content__data-protocol-all {
|
||||
flex: 1.5;
|
||||
}
|
||||
.content__data-protocol-icon {
|
||||
display: flex;
|
||||
width: 68px;
|
||||
height: 100%;
|
||||
margin: auto;
|
||||
line-height: 68px;
|
||||
border-radius: 100%;
|
||||
justify-content: center;
|
||||
i {
|
||||
font-size: 26px;
|
||||
}
|
||||
}
|
||||
.content__data-protocol-value {
|
||||
flex: 2;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
.content__data-protocol-value-title {
|
||||
margin-bottom: 7px;
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
font-weight: 400;
|
||||
}
|
||||
.content__data-protocol-value-num {
|
||||
font-size: 26px;
|
||||
color: #333333;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
.content__data-protocol-percent {
|
||||
flex: 2;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 68px;
|
||||
text-align: left;
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
font-weight: 400;
|
||||
line-height: 95px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.cn-chart__single-value--percentile-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: left;
|
||||
height: 100%;
|
||||
flex: 0 0 auto;
|
||||
flex-wrap: nowrap;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.single-value-icon__box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: left;
|
||||
margin-right: 5px;
|
||||
flex: 0 0 80;
|
||||
}
|
||||
|
||||
.single-value__icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background-color: $--chart-single-value-icon-background-color;
|
||||
border-radius: 50%;
|
||||
|
||||
i {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 20px;
|
||||
color: $--color-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.single-value__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 60%;
|
||||
padding-right: 10px;
|
||||
|
||||
.data__title-in-one {
|
||||
display:flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.content__data {
|
||||
margin-bottom: 5px;
|
||||
font-size: 12px;
|
||||
color: #333333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.content__title {
|
||||
white-space: nowrap;
|
||||
font-size: 12px !important;
|
||||
color: #7e8081;
|
||||
margin-bottom: 5px;
|
||||
padding: 3px 4px 3px 3px;
|
||||
}
|
||||
|
||||
.title-background-color {
|
||||
background-color: #EFF6FE;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.content__percentile {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 12px;
|
||||
color: #666666;
|
||||
display:flex;
|
||||
flex-direction: row;
|
||||
|
||||
.circle__content {
|
||||
display:flex;
|
||||
flex-display:row;
|
||||
margin-right:4px;
|
||||
|
||||
.percentile__title-color {
|
||||
color:#9b9b9b
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.circle {
|
||||
position: relative;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
line-height: 6px;
|
||||
border-radius: 50%;
|
||||
-moz-border-radius: 50%;
|
||||
margin: auto;
|
||||
margin-right: 4px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.circle.circle-p50 {
|
||||
background: #ffa200;
|
||||
|
||||
}
|
||||
.circle.circle-p90 {
|
||||
background: #23bf9a;
|
||||
}
|
||||
|
||||
&.single-value__content--with-chart {
|
||||
.content__title {
|
||||
border-bottom: 1px solid $--content-right-background-color;
|
||||
}
|
||||
}
|
||||
|
||||
.single-value__unit {
|
||||
padding-left:0px;
|
||||
padding-right: 5px;
|
||||
color: #333333;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.cn-chart__single-value--percentile-left {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
width: unset;
|
||||
|
||||
.single-value-icon__box {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: right;
|
||||
margin-right:25px;
|
||||
flex: 0 0 80;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.single-value__icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
background-color: $--chart-single-value-icon-background-color;
|
||||
border-radius: 50%;
|
||||
|
||||
i {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 28px;
|
||||
color: $--color-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.single-value__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 60%;
|
||||
padding-right: 10px;
|
||||
margin-left:25px;
|
||||
|
||||
.content__data {
|
||||
margin-bottom: 7%;
|
||||
font-size: 22px;
|
||||
color: #333333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.content__title {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 14px !important;
|
||||
color: #7e8081;
|
||||
margin-bottom: 7%;
|
||||
font-weight:400;
|
||||
}
|
||||
|
||||
.content__percentile {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 12px;
|
||||
color: #666666;
|
||||
display:flex;
|
||||
flex-direction: row;
|
||||
font-weight: bold;
|
||||
|
||||
.circle__content {
|
||||
display:flex;
|
||||
flex-display:row;
|
||||
margin-right:15px;
|
||||
|
||||
.percentile__title-color {
|
||||
color:#9b9b9b;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.circle {
|
||||
position: relative;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
line-height: 7px;
|
||||
border-radius: 50%;
|
||||
-moz-border-radius: 50%;
|
||||
margin: auto;
|
||||
margin-right: 4px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.circle.circle-p50 {
|
||||
background: #ffa200;
|
||||
|
||||
}
|
||||
.circle.circle-p90 {
|
||||
background: #23bf9a;
|
||||
}
|
||||
|
||||
&.single-value__content--with-chart {
|
||||
.content__title {
|
||||
border-bottom: 1px solid $--content-right-background-color;
|
||||
}
|
||||
}
|
||||
|
||||
.single-value__unit {
|
||||
color: #333333;
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
.cn-chart__ip-basic {
|
||||
display: flex;
|
||||
padding: 30px 60px 0 30px;
|
||||
.cn-chart__ip-basic-info {
|
||||
padding-right: 80px;
|
||||
.el-descriptions {
|
||||
padding-top: 30px;
|
||||
}
|
||||
&>.el-descriptions {
|
||||
flex: 0 0 350px;
|
||||
padding: 30px 36px;
|
||||
}
|
||||
.chart-location {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
}
|
||||
.el-descriptions :not(.is-bordered) td {
|
||||
padding-bottom: 5px !important;
|
||||
padding: 0 20px 20px 0;
|
||||
}
|
||||
.el-descriptions__content {
|
||||
color: #3976CB;
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
z-index: 2;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
&>div {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
.chart-list {
|
||||
&>.vue-grid-layout>.vue-grid-item, &>.dns-screen {
|
||||
&>.vue-grid-layout>.vue-grid-item {
|
||||
&>.panel-chart {
|
||||
border: 1px solid $--chart-box-border-color;
|
||||
background-color: #FFFFFF;
|
||||
@@ -30,7 +30,7 @@
|
||||
justify-content:space-between;
|
||||
align-items:center;
|
||||
padding: 10px 20px 10px 18px;
|
||||
flex: 0 0 40px;
|
||||
height: 47px;
|
||||
|
||||
font-size: 16px;
|
||||
color: $--color-text-primary;
|
||||
@@ -131,7 +131,7 @@
|
||||
}
|
||||
.header__operations {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
justify-content: end;
|
||||
align-items: center;
|
||||
|
||||
.header__operation-btn {
|
||||
@@ -213,8 +213,7 @@
|
||||
&>.cn-chart {
|
||||
position: relative;
|
||||
border-radius: 2px;
|
||||
flex-grow: 1;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
.chart-drawing {
|
||||
height: 100%;
|
||||
@@ -225,7 +224,7 @@
|
||||
border-bottom: 1px solid $--content-right-background-color;
|
||||
.header__operations {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
justify-content: end;
|
||||
align-items: center;
|
||||
|
||||
.header__operation.header__operation--echarts {
|
||||
@@ -469,12 +468,12 @@
|
||||
flex-shrink: 1;
|
||||
flex-grow: 1;
|
||||
overflow: hidden;
|
||||
min-width: calc(50% - 37px);
|
||||
min-width: 200px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.table__below-statistics {
|
||||
width: calc((50% + 10px)/4);
|
||||
width: 80px;
|
||||
flex-shrink: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
.cn-detection--list {
|
||||
display: flex;
|
||||
|
||||
.cn-detection__collapse {
|
||||
margin-bottom: 1px;
|
||||
padding-top: 18px;
|
||||
@@ -20,7 +19,6 @@
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
span:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -30,7 +28,6 @@
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.cn-detection__case {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
@@ -51,7 +48,6 @@
|
||||
height: 20px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.cn-detection__row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -67,40 +63,26 @@
|
||||
padding-bottom: 3px;
|
||||
color: #333333;
|
||||
align-items: center;
|
||||
|
||||
i {
|
||||
color: #7b8fa2;
|
||||
color:#7b8fa2;
|
||||
margin-right: 5px;
|
||||
font-size: 18px;
|
||||
font-size:18px;
|
||||
}
|
||||
|
||||
.line {
|
||||
color: #da5656;
|
||||
margin-left: 12px;
|
||||
color:#da5656;
|
||||
margin-left:12px;
|
||||
font-size: xx-small;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.circle {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border: 2px solid #da5656;
|
||||
width:10px;
|
||||
height:10px;
|
||||
border:2px solid #da5656;
|
||||
border-radius: 10px;
|
||||
margin-top: 4px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.domain {
|
||||
background: #EFF2F5;
|
||||
border-radius: 2px;
|
||||
font-size: 14px;
|
||||
color: #333333;
|
||||
letter-spacing: 0;
|
||||
line-height: 14px;
|
||||
margin-left: 5px;
|
||||
margin-right:12px;
|
||||
}
|
||||
}
|
||||
|
||||
.cn-detection__body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -119,27 +101,22 @@
|
||||
padding-right: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
i {
|
||||
padding-right: 6px;
|
||||
color: #8FA1BE;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
span:first-of-type {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
span:last-of-type {
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.show-detail {
|
||||
flex-shrink: 0;
|
||||
padding: 0 30px;
|
||||
@@ -153,7 +130,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cn-detection__detail-overview {
|
||||
flex-basis: 100%;
|
||||
padding: 0 10px;
|
||||
@@ -164,71 +140,3 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.security.cn-detection--list,.service.cn-detection--list {
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
.cn-detection__case {
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #E7EAED;
|
||||
border-radius: 2px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.cn-detection__case {
|
||||
padding: 18px 0;
|
||||
flex: unset;
|
||||
}
|
||||
.cn-detection__header {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.cn-detection-table {
|
||||
overflow: auto;
|
||||
}
|
||||
.cn-detection__case-severity {
|
||||
display: flex;
|
||||
width: 38px;
|
||||
height: 34px;
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
margin-right: 20px;
|
||||
margin-left: 29px;
|
||||
line-height: 34px;
|
||||
i {
|
||||
font-size: 40px;
|
||||
}
|
||||
}
|
||||
.el-pagination__jump {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
.cn-detection__footer {
|
||||
background: #FFFFFF;
|
||||
position: relative;
|
||||
box-shadow: 0 0 4px 0 rgba(0,0,0,0.06);
|
||||
.el-pagination__total {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
.domain.cn-detection-domain {
|
||||
height: 20px;
|
||||
line-height: 20px !important;
|
||||
padding: 0 4px;
|
||||
font-style: italic;
|
||||
}
|
||||
.critical {
|
||||
color: #D84C4C !important;
|
||||
}
|
||||
.high {
|
||||
color: #FF9A79 !important;
|
||||
}
|
||||
.info {
|
||||
color: #D1BD50 !important;
|
||||
}
|
||||
.medium {
|
||||
color: #FFB65A !important;
|
||||
}
|
||||
.low {
|
||||
color: #FFD82D !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,18 +8,6 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.overview__metric {
|
||||
display:flex;
|
||||
flex-direction: row;
|
||||
padding-top: 10px;
|
||||
|
||||
.metric__column {
|
||||
display:flex;
|
||||
flex-direction: column;
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.overview__title {
|
||||
padding: 10px 0;
|
||||
color: #333;
|
||||
@@ -45,39 +33,16 @@
|
||||
color: #6B717B;
|
||||
}
|
||||
|
||||
.row__charts {
|
||||
height: 20px;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.row__content--metric {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
color: #666666;
|
||||
font-size:14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.row__content {
|
||||
display: flex;
|
||||
color: #3976CB;
|
||||
|
||||
|
||||
&.row__content--link {
|
||||
font-style: italic;
|
||||
text-decoration: underline;
|
||||
color: #1890FF;
|
||||
cursor: pointer;
|
||||
}
|
||||
.row__content--link{
|
||||
font-style: italic;
|
||||
text-decoration: underline;
|
||||
color: #1890FF;
|
||||
cursor: pointer;
|
||||
}
|
||||
span{
|
||||
font-style: italic;
|
||||
color: #1890FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,7 +62,6 @@
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-basis: 16px;
|
||||
font-size: 12px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
justify-content:space-between;
|
||||
align-items:center;
|
||||
padding: 10px 20px 10px 0px;
|
||||
flex: 0 0 40px;
|
||||
height: 40px;
|
||||
|
||||
font-size: 14px;
|
||||
color: $--color-text-primary;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
background-color: #F3F7FA;
|
||||
|
||||
i {
|
||||
font-size: 26px;
|
||||
font-size: 22px;
|
||||
color: #4E84B4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
.body__detail {
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
color: #3976CB;
|
||||
color: #8FA1BE;
|
||||
position: absolute;
|
||||
right: 30px;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
right: 50px;
|
||||
top: 0;
|
||||
width: 550px;
|
||||
height: 320px;
|
||||
height: 350px;
|
||||
|
||||
&.overview-map--ip {
|
||||
height: 210px;
|
||||
@@ -54,12 +54,6 @@
|
||||
color: #8FA1BE;
|
||||
cursor: pointer;
|
||||
}
|
||||
&.overview__row--single-value {
|
||||
flex-wrap: nowrap;
|
||||
.cn-chart__single-value--detail-overview {
|
||||
margin-right: 60px;
|
||||
}
|
||||
}
|
||||
.row__label {
|
||||
color: #6B717B;
|
||||
padding-right: 20px;
|
||||
@@ -76,8 +70,6 @@
|
||||
.row__content {
|
||||
display: flex;
|
||||
color: #3976CB;
|
||||
word-wrap: break-word;
|
||||
max-width: 30%;
|
||||
|
||||
.alert-level-tag {
|
||||
display: flex;
|
||||
@@ -106,7 +98,6 @@
|
||||
|
||||
.row__content {
|
||||
padding: 2px 0;
|
||||
max-width: unset;
|
||||
|
||||
&:first-of-type {
|
||||
padding-top: 0;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
.cn-entity--list {
|
||||
display: flex;
|
||||
|
||||
.cn-entity__collapse {
|
||||
margin-bottom: 1px;
|
||||
padding-top: 30px;
|
||||
@@ -20,7 +19,6 @@
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
span:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -30,7 +28,6 @@
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.cn-entity__case {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
@@ -54,11 +51,10 @@
|
||||
background-color: #F3F7FA;
|
||||
|
||||
i {
|
||||
font-size: 26px;
|
||||
font-size: 22px;
|
||||
color: #4E84B4;
|
||||
}
|
||||
}
|
||||
|
||||
.cn-entity__row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -71,7 +67,6 @@
|
||||
padding-bottom: 3px;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.cn-entity__body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -88,60 +83,22 @@
|
||||
|
||||
.basic-info__item {
|
||||
padding-right: 40px;
|
||||
|
||||
.item__box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
|
||||
i {
|
||||
padding-right: 6px;
|
||||
color: #8FA1BE;
|
||||
font-size: 12px;
|
||||
height: 13px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
span:first-of-type {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
span:last-of-type {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.row__charts {
|
||||
height: 19px;
|
||||
width: 60px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
i {
|
||||
padding-right: 6px;
|
||||
color: #8FA1BE;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
span:first-of-type {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
span:last-of-type {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.show-detail {
|
||||
flex-shrink: 0;
|
||||
padding: 0 30px;
|
||||
@@ -155,7 +112,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cn-entity__detail-overview {
|
||||
flex-basis: 100%;
|
||||
padding: 0 10px;
|
||||
@@ -166,4 +122,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
.cn-builtin {
|
||||
background: #fff;
|
||||
margin: 10px;
|
||||
height: calc(100% - 20px) !important;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.cn-builtin-left {
|
||||
width: 288px;
|
||||
height: 100%;
|
||||
border-right: 1px solid #E7EAED;
|
||||
.cn-builtin-left-title {
|
||||
padding: 28px 0 26px 13px;
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
.cn-builtin-left-menu {
|
||||
width: 250px;
|
||||
height: 46px;
|
||||
margin: auto;
|
||||
font-size: 14px;
|
||||
color: #333333;
|
||||
letter-spacing: 0;
|
||||
line-height: 46px;
|
||||
padding-left: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.cn-builtin-left-menu.cn-active {
|
||||
background: #F4FAFF;
|
||||
border-radius: 2px;
|
||||
color: #0091FF;
|
||||
}
|
||||
}
|
||||
.cn-builtin-right {
|
||||
flex: 1;
|
||||
.list-page .main-container {
|
||||
padding: 0;
|
||||
.cn-table {
|
||||
height: calc(100% - 62px) !important;
|
||||
.el-table--fit.el-table--border {
|
||||
height: calc(100% - 55px) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-table__header th:first-of-type .el-checkbox:last-of-type {
|
||||
border-left: none;
|
||||
display: none;
|
||||
}
|
||||
.table-operation-all {
|
||||
width: 300px;
|
||||
position: absolute;
|
||||
bottom: 17px;
|
||||
z-index: 2;
|
||||
left: 20px;
|
||||
line-height: 24px;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
.el-checkbox {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
padding: 0;
|
||||
.el-checkbox__input,.el-checkbox__inner {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-width: unset;
|
||||
}
|
||||
}
|
||||
.table-operation-all-span {
|
||||
height: 24px;
|
||||
display: flex;
|
||||
span {
|
||||
margin: 0 10px;
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
letter-spacing: 0;
|
||||
font-weight: 400;
|
||||
}
|
||||
.table-operation-back-down {
|
||||
font-weight: 500;
|
||||
height: 24px;
|
||||
background: #D7D7D7;
|
||||
border-radius: 2px;
|
||||
line-height: 21px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
span {
|
||||
margin: 3px 8px;
|
||||
font-size: 12px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
.table-operation-back-down div {
|
||||
color: #FFFFFF;
|
||||
height: 24px;
|
||||
background: #D7D7D7;
|
||||
border-radius: 2px;
|
||||
i {
|
||||
font-size: 25px;
|
||||
top: calc(50% - 12px);
|
||||
}
|
||||
}
|
||||
.table-operation-back-down.table-operation-all-checkbox {
|
||||
background: #0091ff;
|
||||
}
|
||||
.table-operation-back-down.table-operation-all-loading {
|
||||
background: #D7D7D7;
|
||||
}
|
||||
}
|
||||
}
|
||||
.table-operation-items {
|
||||
.table-operation-item--down {
|
||||
margin-right: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.table-operation-item--down,.table-operation-item--preview {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
.chart__loading {
|
||||
.el-icon-loading {
|
||||
font-size: 12px;
|
||||
left: calc(50% - 6px);
|
||||
top: calc(50% - 6px);
|
||||
}
|
||||
}
|
||||
.icon {
|
||||
height: 25px;
|
||||
width: 25px;
|
||||
}
|
||||
}
|
||||
.table-operation-item--preview {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "cn-icon"; /* Project id 2614877 */
|
||||
src: url('iconfont.woff2?t=1649728125883') format('woff2'),
|
||||
url('iconfont.woff?t=1649728125883') format('woff'),
|
||||
url('iconfont.ttf?t=1649728125883') format('truetype');
|
||||
src: url('iconfont.woff2?t=1645687921203') format('woff2'),
|
||||
url('iconfont.woff?t=1645687921203') format('woff'),
|
||||
url('iconfont.ttf?t=1645687921203') format('truetype');
|
||||
}
|
||||
|
||||
.cn-icon {
|
||||
@@ -13,62 +13,6 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.cn-icon-report:before {
|
||||
content: "\e76f";
|
||||
}
|
||||
|
||||
.cn-icon-shezhi:before {
|
||||
content: "\e76c";
|
||||
}
|
||||
|
||||
.cn-icon-preview:before {
|
||||
content: "\e76d";
|
||||
}
|
||||
|
||||
.cn-icon-download2:before {
|
||||
content: "\e76e";
|
||||
}
|
||||
|
||||
.cn-icon-requests:before {
|
||||
content: "\e76a";
|
||||
}
|
||||
|
||||
.cn-icon-traffic:before {
|
||||
content: "\e76b";
|
||||
}
|
||||
|
||||
.cn-icon-domain2:before {
|
||||
content: "\e767";
|
||||
}
|
||||
|
||||
.cn-icon-ip2:before {
|
||||
content: "\e768";
|
||||
}
|
||||
|
||||
.cn-icon-app2:before {
|
||||
content: "\e769";
|
||||
}
|
||||
|
||||
.cn-icon-intercept:before {
|
||||
content: "\e600";
|
||||
}
|
||||
|
||||
.cn-icon-fraudulent-app:before {
|
||||
content: "\e601";
|
||||
}
|
||||
|
||||
.cn-icon-fraudulent-ip:before {
|
||||
content: "\e602";
|
||||
}
|
||||
|
||||
.cn-icon-fraudulent-domain:before {
|
||||
content: "\e603";
|
||||
}
|
||||
|
||||
.cn-icon-partly-cloudy:before {
|
||||
content: "\e604";
|
||||
}
|
||||
|
||||
.cn-icon-detection:before {
|
||||
content: "\e766";
|
||||
}
|
||||
@@ -77,7 +21,7 @@
|
||||
content: "\e764";
|
||||
}
|
||||
|
||||
.cn-icon-clear:before {
|
||||
.cn-icon-qingchu:before {
|
||||
content: "\e765";
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -20,6 +20,7 @@
|
||||
@changeMode="changeMode"
|
||||
@search="search"
|
||||
></tag-mode>
|
||||
<!-- <div class="search-tip--error">something error...</div>-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -101,20 +102,8 @@ export default {
|
||||
ElMessage.error(this.$t('tip.invalidExpression'))
|
||||
}
|
||||
}
|
||||
},
|
||||
enterListener (event) {
|
||||
if (event.keyCode === 13) {
|
||||
this.$refs.tagMode && this.$refs.tagMode.search()
|
||||
this.$refs.textMode && this.$refs.textMode.search()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
document.addEventListener('keydown', this.enterListener)
|
||||
},
|
||||
unmounted () {
|
||||
document.removeEventListener('keydown', this.enterListener)
|
||||
},
|
||||
setup (props) {
|
||||
// 默认为文本模式
|
||||
let searchMode = ref('text')
|
||||
|
||||
@@ -308,12 +308,6 @@ export default {
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
const vm = this
|
||||
this.emitter.on('advanced-search', function () {
|
||||
vm.search()
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
convertMetaList: {
|
||||
immediate: true,
|
||||
|
||||
@@ -23,7 +23,6 @@ import CodeMirror from 'codemirror'
|
||||
import { toRaw } from 'vue'
|
||||
import { columnType } from '@/components/advancedSearch/meta/meta'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { reg } from '@/utils/constants'
|
||||
|
||||
export default {
|
||||
name: 'TextMode',
|
||||
@@ -46,38 +45,15 @@ export default {
|
||||
lineNumbers: false
|
||||
})
|
||||
this.codeMirror.setOption('extraKeys', {
|
||||
Enter: (cm) => {}
|
||||
Enter: (cm) => {
|
||||
this.search()
|
||||
}
|
||||
})
|
||||
},
|
||||
search () {
|
||||
let originalSql = this.codeMirror.getValue().trim()
|
||||
let originalSql = this.codeMirror.getValue()
|
||||
if (originalSql) {
|
||||
originalSql = originalSql.replaceAll(/"/g, '')
|
||||
// 为解决ip无法校验通过的问题,先将带引号的ip转为不带引号的,再把不带引号的转为带引号的
|
||||
originalSql = originalSql.replaceAll(reg.notStrictWithQuotIpv4, function (word) {
|
||||
return word.replaceAll(/'/g, '')
|
||||
})
|
||||
originalSql = originalSql.replaceAll(reg.notStrictIpv4, function (word) {
|
||||
return `'${word}'`
|
||||
})
|
||||
originalSql = originalSql.replaceAll(reg.notStrictWithQuotIpv6, function (word) {
|
||||
return word.replaceAll(/'/g, '')
|
||||
})
|
||||
originalSql = originalSql.replaceAll(reg.notStrictIpv6, function (word) {
|
||||
return `'${word}'`
|
||||
})
|
||||
|
||||
let tempArr = originalSql.split(' ')
|
||||
tempArr = tempArr.map(t => {
|
||||
if (t.lastIndexOf("'") !== (t.length - 1) && t.indexOf("'") !== 0) {
|
||||
if (reg.containChinese.test(t)) {
|
||||
return `'${t}'`
|
||||
}
|
||||
}
|
||||
return t
|
||||
})
|
||||
originalSql = tempArr.join(' ')
|
||||
|
||||
originalSql = originalSql.replace(/"/g, '')
|
||||
const parser = new SqlParser(originalSql, this.columnList)
|
||||
const errorList = parser.validate()
|
||||
if (this.$_.isEmpty(errorList)) {
|
||||
@@ -126,7 +102,7 @@ export default {
|
||||
const column = this.columnList.find(c => c.name === param.column)
|
||||
current = `${current ? current + ' AND ' : ''}${param.column}${handleOperatorSpace(param.operator)}${this.handleValue(param.value, column, param.operator)}`
|
||||
})
|
||||
toRaw(this.codeMirror).setValue(current.trim())
|
||||
toRaw(this.codeMirror).setValue(current)
|
||||
},
|
||||
removeParams (params) {
|
||||
let current = this.codeMirror.getValue()
|
||||
@@ -139,7 +115,7 @@ export default {
|
||||
current = current.replace(piece, '')
|
||||
})
|
||||
})
|
||||
toRaw(this.codeMirror).setValue(current.trim())
|
||||
toRaw(this.codeMirror).setValue(current)
|
||||
},
|
||||
changeParams (params) {
|
||||
let current = this.codeMirror.getValue()
|
||||
@@ -151,7 +127,7 @@ export default {
|
||||
const newSqlPiece = `${param.newParam.column}${handleOperatorSpace(param.newParam.operator)}${this.handleValue(param.newParam.value, newColumn, param.newParam.operator)}`.trim()
|
||||
current = current.replace(oldSqlPiece, newSqlPiece)
|
||||
})
|
||||
toRaw(this.codeMirror).setValue(current.trim())
|
||||
toRaw(this.codeMirror).setValue(current)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -168,10 +144,6 @@ export default {
|
||||
},
|
||||
mounted () {
|
||||
this.initCodeMirror()
|
||||
const vm = this
|
||||
this.emitter.on('advanced-search', function () {
|
||||
vm.search()
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
:current-page="pageObj.pageNo"
|
||||
:page-sizes="pageSizes?pageSizes:[20, 50, 100]"
|
||||
:page-size="Number(pageObj.pageSize)"
|
||||
:layout="layout"
|
||||
layout="total, prev, pager, next, slot"
|
||||
:total="pageObj.total"
|
||||
>
|
||||
<el-select v-model="pageSize" :placeholder="pageSize+$t('pageSize')" size="mini" :popper-append-to-body="appendToBody" class="pagination-size-select" @change="size" :popper-class="popClass" @visible-change="popperVisible">
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
<script>
|
||||
import { defaultPageSize } from '@/utils/constants'
|
||||
import { storageKey } from '@/utils/constants'
|
||||
|
||||
export default {
|
||||
name: 'pagination',
|
||||
@@ -32,11 +31,7 @@ export default {
|
||||
tableId: {},
|
||||
postPageSizes: {},
|
||||
appendToBody: { default: true },
|
||||
popClass: {},
|
||||
layout: {
|
||||
type: String,
|
||||
default: 'total, prev, pager, next, slot'
|
||||
}
|
||||
popClass: {}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
@@ -133,7 +128,7 @@ export default {
|
||||
this.pageSize = this.postPageSizes[0]
|
||||
this.resetPageSizes()
|
||||
} else {
|
||||
const pageSize = localStorage.getItem(storageKey.pageSize + '-' + localStorage.getItem(storageKey.username) + '-' + this.tableId)
|
||||
const pageSize = localStorage.getItem('cn-pageSize-' + localStorage.getItem('cn-username') + '-' + this.tableId)
|
||||
if (pageSize != 'undefined' && pageSize != null) {
|
||||
this.pageSize = parseInt(pageSize)
|
||||
}
|
||||
@@ -157,15 +152,6 @@ export default {
|
||||
deep: true,
|
||||
handler (n, o) {
|
||||
}
|
||||
},
|
||||
tableData: {
|
||||
immediate: true,
|
||||
deep: true,
|
||||
handler (n, o) {
|
||||
if (n) {
|
||||
this.checkbox = n
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,6 @@
|
||||
<script>
|
||||
import { ref, computed } from 'vue'
|
||||
import MyDatePicker from '../MyDatePicker'
|
||||
import { storageKey } from '@/utils/constants'
|
||||
|
||||
export default {
|
||||
name: 'DateTimeRange',
|
||||
@@ -92,9 +91,6 @@ export default {
|
||||
endTime: {
|
||||
type: Number,
|
||||
default: window.$dayJs.tz().valueOf()
|
||||
},
|
||||
dateRange: {
|
||||
type: Number
|
||||
}
|
||||
/* useRefresh: {
|
||||
type: Boolean,
|
||||
@@ -114,10 +110,11 @@ export default {
|
||||
const myStartTime = ref(props.startTime)
|
||||
const myEndTime = ref(props.endTime)
|
||||
const timeArr = ref([myStartTime.value, myEndTime.value])
|
||||
const address = localStorage.getItem(storageKey.sysTimezone)
|
||||
const utc = localStorage.getItem(storageKey.timezoneOffset)
|
||||
const rangeHistory = ref(localStorage.getItem(storageKey.dataRangeHistory) ? JSON.parse(localStorage.getItem(storageKey.dataRangeHistory)) : [])
|
||||
const dateRangeValue = props.dateRange ? ref(props.dateRange) : ref(60)
|
||||
const address = localStorage.getItem('cn-sys-timezone')
|
||||
const utc = localStorage.getItem('cn-timezone-offset')
|
||||
const rangeHistory = ref(localStorage.getItem('date-range-history') ? JSON.parse(localStorage.getItem('date-range-history')) : [])
|
||||
const dateRangeValue = ref(60)
|
||||
dateRangeValue.value = 60
|
||||
const isCustom = ref(false)
|
||||
const dateRangeArr = [
|
||||
{
|
||||
@@ -236,7 +233,7 @@ export default {
|
||||
start: myStartTime.value,
|
||||
end: myEndTime.value
|
||||
})
|
||||
localStorage.setItem(storageKey.dataRangeHistory, JSON.stringify(rangeHistory.value))
|
||||
localStorage.setItem('date-range-history', JSON.stringify(rangeHistory.value))
|
||||
ctx.emit('change', myStartTime.value, myEndTime.value, dateRangeValue)
|
||||
dropdownFlag.value = false
|
||||
}
|
||||
|
||||
@@ -59,8 +59,6 @@
|
||||
<script>
|
||||
import axios from 'axios'
|
||||
import { post } from '@/utils/http'
|
||||
import { storageKey } from '@/utils/constants'
|
||||
|
||||
export default {
|
||||
name: 'TopToolMoreOptions',
|
||||
props: {
|
||||
@@ -109,7 +107,7 @@ export default {
|
||||
if (this.paramsType) {
|
||||
form.append('type', this.paramsType)
|
||||
}
|
||||
form.append('language', localStorage.getItem(storageKey.language) ? localStorage.getItem(storageKey.language) : 'en')
|
||||
form.append('language', localStorage.getItem('cn-language') ? localStorage.getItem('cn-language') : 'en')
|
||||
post(this.importUrl, form, { 'Content-Type': 'multipart/form-data' }).then(response => {
|
||||
if (response.code == 200 && response.msg == 'success') {
|
||||
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.importSuccess') })
|
||||
@@ -129,7 +127,7 @@ export default {
|
||||
this.importFile = null
|
||||
},
|
||||
downloadTemplate () {
|
||||
const language = localStorage.getItem(storageKey.language) || 'en' // 初始未选择默认 en 英文
|
||||
const language = localStorage.getItem('cn-language') || 'en' // 初始未选择默认 en 英文
|
||||
const fileName = this.exportFileName + '-' + this.$t('overall.template') + '-' + this.getTimeString() + '.json'
|
||||
|
||||
let url = null
|
||||
@@ -160,7 +158,7 @@ export default {
|
||||
})
|
||||
}
|
||||
params.pageSize = -1
|
||||
params.language = localStorage.getItem(storageKey.language) || 'en'
|
||||
params.language = localStorage.getItem('cn-language') || 'en'
|
||||
|
||||
this.export(this.exportUrl, params, this.exportFileName + '-' + this.getTimeString() + '.json')
|
||||
this.closeDialog()
|
||||
|
||||
@@ -171,15 +171,15 @@ export default {
|
||||
let className
|
||||
switch (this.from) {
|
||||
case ('ip'): {
|
||||
className = 'cn-icon cn-icon-ip2 ip-green'
|
||||
className = 'cn-icon cn-icon-ip ip-green'
|
||||
break
|
||||
}
|
||||
case ('domain'): {
|
||||
className = 'cn-icon cn-icon-domain2 domain-blue'
|
||||
className = 'cn-icon cn-icon-domain domain-blue'
|
||||
break
|
||||
}
|
||||
case ('app'): {
|
||||
className = 'cn-icon cn-icon-app2 app-orange'
|
||||
className = 'cn-icon cn-icon-app app-orange'
|
||||
break
|
||||
}
|
||||
default: break
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<el-option v-for="(value, key) in entityType" :label="value" :key="key" :value="key">
|
||||
<template v-if="value === entityType.ip"><i style="color: #23BF9A;" class="cn-icon cn-icon-ip"></i></template>
|
||||
<template v-else-if="value === entityType.domain"><i style="color: #23BF9A;" class="cn-icon cn-icon-domain"></i></template>
|
||||
<template v-else-if="value === entityType.app"><i style="color: #23BF9A;" class="cn-icon cn-icon-app2"></i></template>
|
||||
<template v-else-if="value === entityType.app"><i style="color: #23BF9A;" class="cn-icon cn-icon-app"></i></template>
|
||||
{{value}}
|
||||
</el-option>
|
||||
<template #prefix>
|
||||
@@ -91,7 +91,6 @@
|
||||
import { useRoute } from 'vue-router'
|
||||
import { get, put } from '@/utils/http'
|
||||
import { entityType, storageKey } from '@/utils/constants'
|
||||
import { api } from '@/utils/api'
|
||||
|
||||
export default {
|
||||
name: 'Header',
|
||||
@@ -105,7 +104,7 @@ export default {
|
||||
}
|
||||
return {
|
||||
username: 'admin', // sessionStorage.getItem('cn-username'),
|
||||
language: localStorage.getItem(storageKey.language) ? localStorage.getItem(storageKey.language) : 'en',
|
||||
language: localStorage.getItem('cn-language') ? localStorage.getItem('cn-language') : 'en',
|
||||
showChangePin: false,
|
||||
from: '', // entity类型
|
||||
changePassForm: {
|
||||
@@ -172,8 +171,8 @@ export default {
|
||||
this.showChangePin = false
|
||||
},
|
||||
changeLocal (lang) {
|
||||
if (lang !== localStorage.getItem(storageKey.language)) {
|
||||
localStorage.setItem(storageKey.language, lang)
|
||||
if (lang !== localStorage.getItem('cn-language')) {
|
||||
localStorage.setItem('cn-language', lang)
|
||||
window.location.reload()
|
||||
}
|
||||
},
|
||||
@@ -182,10 +181,10 @@ export default {
|
||||
},
|
||||
logout () {
|
||||
localStorage.removeItem(storageKey.token)
|
||||
get(api.logout)
|
||||
get('/logout')
|
||||
},
|
||||
refreshLang () {
|
||||
this.language = localStorage.getItem(storageKey.language)
|
||||
this.language = localStorage.getItem('cn-language')
|
||||
this.$i18n.locale = this.language
|
||||
this.$nextTick(() => {
|
||||
window.location.reload()
|
||||
@@ -197,7 +196,7 @@ export default {
|
||||
submit () {
|
||||
this.$refs.changePassForm.validate((valid) => {
|
||||
if (valid) {
|
||||
put(api.pin, { oldPin: this.changePassForm.oldPwd, newPin: this.changePassForm.newPwd }).then(res => {
|
||||
put('sys/user/pin', { oldPin: this.changePassForm.oldPwd, newPin: this.changePassForm.newPwd }).then(res => {
|
||||
if (res.code === 200) {
|
||||
this.$message.success('Success')
|
||||
this.showChangePin = false
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="cn-home">
|
||||
<left-menu @refresh="refresh"></left-menu>
|
||||
<left-menu @refresh="refresh" v-show="showMenus"></left-menu>
|
||||
<main ref="body" class="cn-body">
|
||||
<cn-header></cn-header>
|
||||
<cn-header v-show="showHeader"></cn-header>
|
||||
<cn-container v-if="containerShow" ref="container"></cn-container>
|
||||
</main>
|
||||
<!-- 临时文本dom,用来计算文本长度 -->
|
||||
@@ -21,6 +21,14 @@ export default {
|
||||
'cn-header': Header,
|
||||
'cn-container': Container
|
||||
},
|
||||
computed: {
|
||||
showHeader () {
|
||||
return this.$store.getters.getShowMenu
|
||||
},
|
||||
showMenus () {
|
||||
return this.$store.getters.getShowMenu
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
containerShow: true
|
||||
|
||||
@@ -70,13 +70,11 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { storageKey } from '@/utils/constants'
|
||||
|
||||
export default {
|
||||
name: 'LeftMenu',
|
||||
data () {
|
||||
return {
|
||||
systemName: localStorage.getItem(storageKey.sysName),
|
||||
systemName: localStorage.getItem('cn-sys-name'),
|
||||
logo: ''
|
||||
}
|
||||
},
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
<script>
|
||||
import rightBoxMixin from '@/mixins/right-box'
|
||||
import { get, post, put } from '@/utils/http'
|
||||
import { panelTypeAndRouteMapping, storageKey } from '@/utils/constants'
|
||||
import { panelTypeAndRouteMapping } from '@/utils/constants'
|
||||
import { api } from '@/utils/api'
|
||||
import { VAceEditor } from 'vue3-ace-editor'
|
||||
import 'ace-builds/src-noconflict/mode-javascript'
|
||||
@@ -149,7 +149,7 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
url: api.chart,
|
||||
loginName: localStorage.getItem(storageKey.username),
|
||||
loginName: localStorage.getItem('cn-username'),
|
||||
panelTypeAndRouteMapping: panelTypeAndRouteMapping,
|
||||
rules: { // 表单校验规则
|
||||
name: [
|
||||
@@ -355,7 +355,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
isCurrentUser (username) {
|
||||
return localStorage.getItem(storageKey.username) === username
|
||||
return localStorage.getItem('cn-username') === username
|
||||
},
|
||||
/* 密码失去焦点 检验确认密码 */
|
||||
pinBlur () {
|
||||
@@ -397,7 +397,7 @@ export default {
|
||||
})
|
||||
},
|
||||
async getChartData (value) {
|
||||
await get(api.chart, { panelId: value }).then(response => {
|
||||
await get('/visual/chart?panelId=' + value).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.chartData = response.data.list
|
||||
}
|
||||
|
||||
@@ -57,16 +57,13 @@
|
||||
<script>
|
||||
import rightBoxMixin from '@/mixins/right-box'
|
||||
import { get, post, put } from '@/utils/http'
|
||||
import { storageKey } from '@/utils/constants'
|
||||
import { api } from '@/utils/api'
|
||||
|
||||
export default {
|
||||
name: 'I18nBox',
|
||||
mixins: [rightBoxMixin],
|
||||
data () {
|
||||
return {
|
||||
url: api.i18nSys,
|
||||
loginName: localStorage.getItem(storageKey.username),
|
||||
url: 'sys/i18n',
|
||||
loginName: localStorage.getItem('cn-username'),
|
||||
rules: { // 表单校验规则
|
||||
name: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||
@@ -91,7 +88,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
isCurrentUser (username) {
|
||||
return localStorage.getItem(storageKey.username) === username
|
||||
return localStorage.getItem('cn-username') === username
|
||||
},
|
||||
/* 密码失去焦点 检验确认密码 */
|
||||
pinBlur () {
|
||||
@@ -133,7 +130,7 @@ export default {
|
||||
})
|
||||
},
|
||||
getLangData () {
|
||||
get(api.dict, { type: 'lang', pageSize: -1 }).then(response => {
|
||||
get('sys/dict?type=lang&pageSize=-1').then(response => {
|
||||
if (response.code === 200) {
|
||||
this.langData = response.data.list
|
||||
}
|
||||
|
||||
@@ -50,8 +50,6 @@
|
||||
<script>
|
||||
import rightBoxMixin from '@/mixins/right-box'
|
||||
import { get, post, put } from '@/utils/http'
|
||||
import { api } from '@/utils/api'
|
||||
|
||||
export default {
|
||||
name: 'userBox',
|
||||
mixins: [rightBoxMixin],
|
||||
@@ -66,7 +64,7 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
editRole: {},
|
||||
url: api.role,
|
||||
url: 'sys/role',
|
||||
rightBox: { model: { show: false } },
|
||||
rules: { // 表单校验规则
|
||||
name: [
|
||||
@@ -112,7 +110,7 @@ export default {
|
||||
return new Promise(resolve => {
|
||||
self.menus = []
|
||||
if (self.editRole.id) {
|
||||
get(api.menu + self.editRole.id).then(response => {
|
||||
get('/sys/role/menu/' + self.editRole.id).then(response => {
|
||||
if (response.code == 200) {
|
||||
self.menus = response.data.menus
|
||||
self.selectedIds = response.data.selectedIds
|
||||
@@ -122,7 +120,7 @@ export default {
|
||||
resolve()
|
||||
})
|
||||
} else {
|
||||
get(api.sysMenu).then(response => {
|
||||
get('/sys/menu').then(response => {
|
||||
if (response.code == 200) {
|
||||
self.menus = response.data.list
|
||||
} else {
|
||||
|
||||
@@ -54,36 +54,6 @@
|
||||
</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!--i18n-->
|
||||
<el-form-item :label="$t('config.i18n.lang')" prop="i18n">
|
||||
<el-select id="account-input-roleIds"
|
||||
v-model="editObject.lang"
|
||||
class="right-box__select"
|
||||
clearable
|
||||
collapse-tags
|
||||
placeholder=""
|
||||
popper-class="right-box-select-dropdown prevent-clickoutside"
|
||||
size="small">
|
||||
<template v-for="lang in langData" :key="lang.value">
|
||||
<el-option :label="lang.label" :value="lang.value"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!--theme-->
|
||||
<el-form-item :label="$t('config.user.theme')" prop="i18n">
|
||||
<el-select id="account-input-roleIds"
|
||||
v-model="editObject.theme"
|
||||
class="right-box__select"
|
||||
clearable
|
||||
collapse-tags
|
||||
placeholder=""
|
||||
popper-class="right-box-select-dropdown prevent-clickoutside"
|
||||
size="small">
|
||||
<template v-for="theme in themeData" :key="theme.value">
|
||||
<el-option :label="theme.label" :value="theme.value"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!--enable-->
|
||||
<el-form-item :label="$t('config.user.enable')">
|
||||
<el-switch
|
||||
@@ -116,9 +86,6 @@
|
||||
<script>
|
||||
import rightBoxMixin from '@/mixins/right-box'
|
||||
import { get, post, put } from '@/utils/http'
|
||||
import { themeData, langData, storageKey } from '@/utils/constants'
|
||||
import { api } from '@/utils/api'
|
||||
|
||||
export default {
|
||||
name: 'UserBox',
|
||||
mixins: [rightBoxMixin],
|
||||
@@ -133,8 +100,8 @@ export default {
|
||||
}
|
||||
}
|
||||
return {
|
||||
url: api.user,
|
||||
loginName: localStorage.getItem(storageKey.username),
|
||||
url: 'sys/user',
|
||||
loginName: localStorage.getItem('cn-username'),
|
||||
rules: { // 表单校验规则
|
||||
name: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||
@@ -170,9 +137,7 @@ export default {
|
||||
{ type: 'email', message: this.$t('validate.email') }
|
||||
]
|
||||
},
|
||||
roleData: [],
|
||||
themeData,
|
||||
langData
|
||||
roleData: []
|
||||
}
|
||||
},
|
||||
setup () {
|
||||
@@ -182,7 +147,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
isCurrentUser (username) {
|
||||
return localStorage.getItem(storageKey.username) === username
|
||||
return localStorage.getItem('cn-username') === username
|
||||
},
|
||||
/* 密码失去焦点 检验确认密码 */
|
||||
pinBlur () {
|
||||
@@ -224,7 +189,7 @@ export default {
|
||||
})
|
||||
},
|
||||
getRoleData () {
|
||||
get(api.role, { pageSize: -1 }).then(response => {
|
||||
get('sys/role?pageSize=-1').then(response => {
|
||||
if (response.code === 200) {
|
||||
this.roleData = response.data.list
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<div class="top-tool-right">
|
||||
<!-- <el-input v-model="keyWord" value="keyWord"></el-input>
|
||||
<el-button @click="onsearch" icon="el-icon-search" type="info" size="mini" style="margin-right: 10px"></el-button>-->
|
||||
<div v-if="showLayout.indexOf('search') > -1" class="top-tool-search" :class="{'margin-r-20': from !== fromRoute.builtinReport}">
|
||||
<div v-if="showLayout.indexOf('search') > -1" class="top-tool-search margin-r-20">
|
||||
<div style="display: flex">
|
||||
<el-input
|
||||
v-model="keyWord" size="small" @keyup.enter="onsearch"></el-input>
|
||||
@@ -69,9 +69,6 @@ export default {
|
||||
tableId: {
|
||||
type: String
|
||||
},
|
||||
builtinId: {
|
||||
type: Number
|
||||
},
|
||||
tableTitle: {
|
||||
type: Array
|
||||
},
|
||||
@@ -98,11 +95,7 @@ export default {
|
||||
this.$emit('update:customTableTitle', custom)
|
||||
},
|
||||
onsearch () {
|
||||
const params = {
|
||||
q: this.keyWord,
|
||||
id: this.builtinId
|
||||
}
|
||||
this.$emit('search', params)
|
||||
this.$emit('search', this.keyWord)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { storageKey } from '@/utils/constants'
|
||||
export default {
|
||||
props: {
|
||||
customTableTitle: Array, // 自定义的title
|
||||
@@ -52,9 +51,9 @@ export default {
|
||||
}
|
||||
},
|
||||
created () {
|
||||
const localStorageTitle = JSON.parse(localStorage.getItem(storageKey.tableTitle + '-' + localStorage.getItem(storageKey.username) + '-' + this.tableId))
|
||||
const localStorageTitle = JSON.parse(localStorage.getItem('cn-tableTitle-' + localStorage.getItem('cn-username') + '-' + this.tableId))
|
||||
if (localStorageTitle) {
|
||||
localStorage.setItem(storageKey.tableTitle + '-' + localStorage.getItem(storageKey.username) + '-' + this.tableId, JSON.stringify(localStorageTitle))
|
||||
localStorage.setItem('cn-tableTitle-' + localStorage.getItem('cn-username') + '-' + this.tableId, JSON.stringify(localStorageTitle))
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -93,8 +92,10 @@ export default {
|
||||
// 点击第二个cancel
|
||||
save () {
|
||||
this.$emit('update', this.custom)
|
||||
localStorage.setItem(storageKey.tableTitle + '-' + localStorage.getItem(storageKey.username) + '-' + this.tableId,
|
||||
JSON.stringify(this.custom))
|
||||
localStorage.setItem(
|
||||
'cn-tableTitle-' + localStorage.getItem('cn-username') + '-' + this.tableId,
|
||||
JSON.stringify(this.custom)
|
||||
)
|
||||
this.esc()
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
<template>
|
||||
<el-table
|
||||
id="userTable"
|
||||
ref="dataTable"
|
||||
:data="tableData"
|
||||
:height="height"
|
||||
border
|
||||
@header-dragend="dragend"
|
||||
@sort-change="tableDataSort"
|
||||
@selection-change="selectionChange"
|
||||
>
|
||||
<el-table-column
|
||||
:resizable="false"
|
||||
align="center"
|
||||
type="selection"
|
||||
width="55">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-for="(item, index) in customTableTitles"
|
||||
:key="`col-${index}`"
|
||||
:fixed="item.fixed"
|
||||
:label="item.label"
|
||||
:min-width="`${item.minWidth}`"
|
||||
:prop="item.prop"
|
||||
:resizable="true"
|
||||
:sort-orders="['ascending', 'descending']"
|
||||
:sortable="item.sortable"
|
||||
:width="`${item.width}`"
|
||||
>
|
||||
<template #header>
|
||||
<span class="data-column__span">{{item.label}}</span>
|
||||
<div class="col-resize-area"></div>
|
||||
</template>
|
||||
<template #default="scope" :column="item">
|
||||
<span v-if="item.prop === 'dataRange'">
|
||||
<template v-if="scope.row.startTime && scope.row.endTime">
|
||||
{{scope.row.startTime}}-{{scope.row.endTime}}
|
||||
</template>
|
||||
</span>
|
||||
<span v-if="item.prop === 'type'">
|
||||
{{scope.row.reportTemp.name}}
|
||||
</span>
|
||||
<span v-else>{{scope.row[item.prop]}}</span>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:resizable="false"
|
||||
:width="operationWidth"
|
||||
fixed="right">
|
||||
<template #header>
|
||||
<div class="table-operation-title">{{$t('overall.option')}}</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="table-operation-items">
|
||||
<div class="table-operation-item--down" @click="tableOperation(['download', scope.row, 1])">
|
||||
<loading :loading="loadingTableId === scope.row.id"></loading>
|
||||
<svg class="icon" aria-hidden="true" :class="{'table-operation-all-loading': loadingTableId}">
|
||||
<use xlink:href="#cn-icon-download2"></use>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="table-operation-item--preview" @click="tableOperation(['preview', scope.row])">
|
||||
<loading :loading="loadingPreviewId === scope.row.id"></loading>
|
||||
<svg class="icon" aria-hidden="true" :class="{'table-operation-all-loading': loadingPreviewId}">
|
||||
<use xlink:href="#cn-icon-preview"></use>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="table-operation-all">
|
||||
<el-checkbox v-model="checkboxAll" @change="selectAll(tableData)"></el-checkbox>
|
||||
<div class="table-operation-all-span">
|
||||
<span>{{ $t('overall.all') }}</span>
|
||||
<div class="table-operation-back-down" :class="{'table-operation-all-checkbox': batchDow, 'table-operation-all-loading': loading}" @click="tableOperation(['download', this.checkboxIds, 2])">
|
||||
<loading :loading="loading"></loading>
|
||||
<span>{{$t('report.batchDow')}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import table from '@/mixins/table'
|
||||
import Loading from '@/components/common/Loading'
|
||||
export default {
|
||||
name: 'builtinReportTable',
|
||||
mixins: [table],
|
||||
components: {
|
||||
Loading
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
tableTitle: [ // 原始table列
|
||||
{
|
||||
label: this.$t('config.user.name'),
|
||||
prop: 'name',
|
||||
show: true,
|
||||
sortable: 'custom'
|
||||
}, {
|
||||
label: this.$t('config.chart.remark'),
|
||||
prop: 'remark',
|
||||
show: true
|
||||
}, {
|
||||
label: this.$t('overall.type'),
|
||||
prop: 'type',
|
||||
show: true,
|
||||
sortable: 'custom'
|
||||
}, {
|
||||
label: this.$t('report.dataRange'),
|
||||
prop: 'dataRange',
|
||||
show: true,
|
||||
minWidth: 110
|
||||
}
|
||||
],
|
||||
checkboxAll: false,
|
||||
checkboxIds: '',
|
||||
batchDow: false,
|
||||
builtinId: '',
|
||||
indeterminate: false,
|
||||
loading: false,
|
||||
loadingTableId: '',
|
||||
loadingPreviewId: ''
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selectionChange (objs) {
|
||||
this.$emit('selectionChange', objs)
|
||||
this.checkboxIds = objs.map(item => { return item.id }).join(',')
|
||||
this.checkboxAll = objs.length > 0 || objs.length === this.tableData.length
|
||||
this.batchDow = objs.length > 0
|
||||
},
|
||||
selectAll (objs) {
|
||||
if (objs) {
|
||||
objs.forEach(item => {
|
||||
this.$refs.dataTable.toggleAllSelection(item)
|
||||
})
|
||||
} else {
|
||||
this.$refs.dataTable.clearSelection()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -70,7 +70,7 @@ export default {
|
||||
mixins: [table],
|
||||
data () {
|
||||
return {
|
||||
url: api.i18nLang,
|
||||
url: api.i18n,
|
||||
tableTitle: [ // 原始table列
|
||||
{
|
||||
label: 'ID',
|
||||
|
||||
@@ -82,14 +82,13 @@
|
||||
<script>
|
||||
import table from '@/mixins/table'
|
||||
import { put } from '@/utils/http'
|
||||
import { storageKey } from '@/utils/constants'
|
||||
|
||||
export default {
|
||||
name: 'userTable',
|
||||
mixins: [table],
|
||||
data () {
|
||||
return {
|
||||
loginName: localStorage.getItem(storageKey.username),
|
||||
loginName: localStorage.getItem('cn-username'),
|
||||
tableTitle: [ // 原始table列
|
||||
{
|
||||
label: 'ID',
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { createApp } from 'vue'
|
||||
import '@/assets/css/font/iconfont.css'
|
||||
import '@/assets/css/font/iconfont.js'
|
||||
import router from '@/router'
|
||||
import store from '@/store'
|
||||
import App from '@/App.vue'
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { hasButton } from '@/permission'
|
||||
import { getMillisecond } from '@/utils/date-util'
|
||||
import { storageKey } from '@/utils/constants'
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
@@ -43,7 +42,7 @@ export default {
|
||||
utcTimeToSysTime (str) { // utc 0 到系统设置的时区
|
||||
let date = ''
|
||||
if (isNaN(str)) {
|
||||
date = window.$dayJs(str).valueOf() + localStorage.getItem(storageKey.timezoneLocalOffset) * 60 * 60 * 1000
|
||||
date = window.$dayJs(str).valueOf() + localStorage.getItem('cn-timezone-local-offset') * 60 * 60 * 1000
|
||||
} else {
|
||||
date = str
|
||||
}
|
||||
|
||||
@@ -3,10 +3,6 @@ import { defaultPageSize, fromRoute, position } from '@/utils/constants'
|
||||
import { get, del } from '@/utils/http'
|
||||
import { ref } from 'vue'
|
||||
import pagination from '@/components/common/Pagination'
|
||||
import axios from 'axios'
|
||||
import { api } from '@/utils/api'
|
||||
import { storageKey } from '@/utils/constants'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
pagination
|
||||
@@ -45,7 +41,7 @@ export default {
|
||||
asce: tableSort.asce,
|
||||
desc: tableSort.desc,
|
||||
strToDate: tableSort.strToDate,
|
||||
tableOperation ([command, row, param]) {
|
||||
tableOperation ([command, row]) {
|
||||
switch (command) {
|
||||
case 'edit': {
|
||||
this.edit(row)
|
||||
@@ -59,14 +55,6 @@ export default {
|
||||
this.copy(row)
|
||||
break
|
||||
}
|
||||
case 'download': {
|
||||
this.download(row, param)
|
||||
break
|
||||
}
|
||||
case 'preview': {
|
||||
this.preview(row)
|
||||
break
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
@@ -78,7 +66,7 @@ export default {
|
||||
if (params) {
|
||||
this.searchLabel = { ...this.searchLabel, ...params }
|
||||
}
|
||||
this.searchLabel = { ...this.searchLabel, ...this.pageObj}
|
||||
this.searchLabel = { ...this.searchLabel, ...this.pageObj }
|
||||
this.tools.loading = true
|
||||
delete this.searchLabel.total
|
||||
let listUrl = this.url
|
||||
@@ -123,7 +111,7 @@ export default {
|
||||
},
|
||||
pageSize (val) {
|
||||
this.pageObj.pageSize = val
|
||||
localStorage.setItem(storageKey.pageSize + '-' + localStorage.getItem(storageKey.username) + '-' + this.tableId, val)
|
||||
localStorage.setItem('cn-pageSize-' + localStorage.getItem('cn-username') + '-' + this.tableId, val)
|
||||
this.getTableData()
|
||||
},
|
||||
add () {
|
||||
@@ -149,101 +137,6 @@ export default {
|
||||
this.object = { ...u, name: 'Copy from ' + u.name, id: '' }
|
||||
this.rightBox.show = true
|
||||
},
|
||||
download (u, n) {
|
||||
if (this.$refs.dataTable.loading && n === 2) { // 批量下载
|
||||
return
|
||||
} else if (this.$refs.dataTable.loadingTableId === u.id && n === 1) { // 列表单个下载
|
||||
return
|
||||
}
|
||||
let fileName = ''
|
||||
let url = ''
|
||||
let params = {}
|
||||
if (n === 2) { // 批量下载
|
||||
fileName = 'builtinReport' + '-' + this.getTimeString() + '.zip' // 文件名称
|
||||
url = api.reportBatchDownloadPdf // 批量 zip 下载
|
||||
params = {
|
||||
ids: u
|
||||
}
|
||||
} else if (n === 1) {
|
||||
fileName = u.name + '.pdf' // 文件名称
|
||||
url = api.reportDownloadPdf // 单个 pdf 下载
|
||||
params = {
|
||||
id: u.id
|
||||
}
|
||||
}
|
||||
if (n === 2) { // 批量下载
|
||||
this.$refs.dataTable.loading = true
|
||||
} else if (n === 1) { // 列表单个下载
|
||||
this.$refs.dataTable.loadingTableId = u.id // 列表单个下载
|
||||
}
|
||||
if (!u && n === 2) { // 批量下载
|
||||
return this.$refs.dataTable.loading = false
|
||||
} else if (!u && n === 1) { // 列表单个下载
|
||||
return this.$refs.dataTable.loadingTableId = u.id
|
||||
}
|
||||
axios.get(url, { responseType: 'blob', params: params }).then(res => {
|
||||
if (window.navigator.msSaveOrOpenBlob) {
|
||||
// 兼容ie11
|
||||
const blobObject = new Blob([res.data])
|
||||
window.navigator.msSaveOrOpenBlob(blobObject, fileName)
|
||||
} else {
|
||||
const url = URL.createObjectURL(new Blob([res.data]))
|
||||
const a = document.createElement('a')
|
||||
document.body.appendChild(a) // 此处增加了将创建的添加到body当中
|
||||
a.href = url
|
||||
a.download = fileName
|
||||
a.target = '_blank'
|
||||
a.click()
|
||||
a.remove() // 将a标签移除
|
||||
}
|
||||
if (n === 2) { // 批量下载
|
||||
this.$refs.dataTable.loading = false
|
||||
} else if (n === 1) { // 列表单个下载
|
||||
this.$refs.dataTable.loadingTableId = !u.id
|
||||
}
|
||||
}, error => {
|
||||
const $self = this
|
||||
const reader = new FileReader()
|
||||
reader.onload = function (event) {
|
||||
const responseText = reader.result
|
||||
const exception = JSON.parse(responseText)
|
||||
if (exception.message) {
|
||||
$self.$message.error(exception.message)
|
||||
} else {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
reader.readAsText(error.response.data)
|
||||
if (n === 2) { // 批量下载
|
||||
this.$refs.dataTable.loading = false
|
||||
} else if (n === 1) { // 列表单个下载
|
||||
this.$refs.dataTable.loadingTableId = !u.id
|
||||
}
|
||||
}).catch(() => {
|
||||
if (n === 2) { // 批量下载
|
||||
this.$refs.dataTable.loading = false
|
||||
} else if (n === 1) { // 列表单个下载
|
||||
this.$refs.dataTable.loadingTableId = !u.id
|
||||
}
|
||||
})
|
||||
},
|
||||
preview (u) {
|
||||
if (this.$refs.dataTable.loadingPreviewId === u.id) { // 列表单个下载
|
||||
return
|
||||
}
|
||||
const params = {
|
||||
id: u.id
|
||||
}
|
||||
this.$refs.dataTable.loadingPreviewId = u.id
|
||||
axios.get(api.reportView, { params: params }).then(res => {
|
||||
const prevWindow = window.open('', '')
|
||||
prevWindow.document.write(res.data)
|
||||
prevWindow.focus()
|
||||
this.$refs.dataTable.loadingPreviewId = !u.id
|
||||
}).catch(() => {
|
||||
this.$refs.dataTable.loadingPreviewId = !u.id
|
||||
})
|
||||
},
|
||||
esc () {
|
||||
this.rightBox.show = false
|
||||
},
|
||||
@@ -258,21 +151,7 @@ export default {
|
||||
},
|
||||
search (params) {
|
||||
this.pageObj.pageNo = 1
|
||||
this.getTableData(params)
|
||||
},
|
||||
getTimeString () {
|
||||
const split = '-'
|
||||
const date = new Date()
|
||||
const year = date.getFullYear()
|
||||
const month = this.formatNum(date.getMonth() + 1)
|
||||
const day = this.formatNum(date.getDate())
|
||||
const hours = this.formatNum(date.getHours())
|
||||
const minutes = this.formatNum(date.getMinutes())
|
||||
const seconds = this.formatNum(date.getSeconds())
|
||||
return year + split + month + split + day + ' ' + hours + split + minutes + split + seconds
|
||||
},
|
||||
formatNum (num) {
|
||||
return num > 9 ? num : '0' + num
|
||||
this.getTableData({ q: params })
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -293,11 +172,11 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
const pageSize = localStorage.getItem(storageKey.pageSize + '-' + localStorage.getItem(storageKey.username) + '-' + this.tableId)
|
||||
const pageSize = localStorage.getItem('cn-pageSize-' + localStorage.getItem('cn-username') + '-' + this.tableId)
|
||||
if (pageSize && pageSize !== 'undefined') {
|
||||
this.pageObj.pageSize = pageSize
|
||||
}
|
||||
let localStorageTableTitle = localStorage.getItem(storageKey.tableTitle + '-' + localStorage.getItem(storageKey.username) + '-' + this.tableId)
|
||||
let localStorageTableTitle = localStorage.getItem('cn-tableTitle-' + localStorage.getItem('cn-username') + '-' + this.tableId)
|
||||
localStorageTableTitle = localStorageTableTitle ? JSON.parse(localStorageTableTitle) : this.$refs.dataTable.tableTitle
|
||||
this.tools.customTableTitle = this.$refs.dataTable.tableTitle.map((item, index) => { // 修复切换中英文的问题
|
||||
if (localStorageTableTitle[index]) {
|
||||
|
||||
@@ -24,7 +24,7 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
getRelatedServerDataTwo (relationshipUrlTow, refTow) {
|
||||
getRelatedServerDataTow (relationshipUrlTow, refTow) {
|
||||
get(relationshipUrlTow, this.getQueryParams()).then(response => {
|
||||
if (response.code === 200) {
|
||||
const relationshipDataTwo = response.data.result
|
||||
|
||||
@@ -41,7 +41,7 @@ export default {
|
||||
tableOperation ([command, row, param]) {
|
||||
switch (command) {
|
||||
default:
|
||||
this.$emit(command, row, param)
|
||||
this.$emit(command, row)
|
||||
break
|
||||
}
|
||||
},
|
||||
|
||||
@@ -7,7 +7,7 @@ import axios from 'axios'
|
||||
import { storageKey } from '@/utils/constants'
|
||||
import { loadI18n } from '@/i18n'
|
||||
|
||||
const loginWhiteList = ['/login', '/'] // 免登陆白名单
|
||||
const loginWhiteList = ['/login', '/', '/largeScreen'] // 免登陆白名单
|
||||
const permissionWhiteList = [...loginWhiteList, '/entityDetail'] // 权限白名单
|
||||
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
@@ -45,7 +45,7 @@ router.beforeEach(async (to, from, next) => {
|
||||
if (loginWhiteList.indexOf(to.path) !== -1) {
|
||||
next()
|
||||
} else {
|
||||
next({ path: '/login', query: { redirect: to.fullPath } })
|
||||
next({ path: '/login' })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -30,10 +30,6 @@ const routes = [
|
||||
path: '/i18n',
|
||||
component: () => import('@/views/settings/I18n')
|
||||
},
|
||||
{
|
||||
path: '/report/builtIn',
|
||||
component: () => import('@/views/report/builtinReport')
|
||||
},
|
||||
{
|
||||
path: '/operationLog',
|
||||
component: () => import('@/views/settings/OperationLog')
|
||||
@@ -55,8 +51,8 @@ const routes = [
|
||||
component: () => import('@/views/settings/Chart')
|
||||
},
|
||||
{
|
||||
path: '/temp',
|
||||
component: () => import('@/views/Temp')
|
||||
path: '/largeScreen',
|
||||
component: () => import('@/views/largeScreen/largeScreen')
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import { createStore } from 'vuex'
|
||||
import user from './modules/user'
|
||||
import panel from './modules/panel'
|
||||
import { storageKey } from '@/utils/constants'
|
||||
import largeScreen from './modules/largeScreen'
|
||||
|
||||
const store = createStore({
|
||||
modules: {
|
||||
user,
|
||||
panel
|
||||
panel,
|
||||
largeScreen
|
||||
},
|
||||
state () {
|
||||
return {
|
||||
isShrink: localStorage.getItem(storageKey.leftMenuShrink) === 'true',
|
||||
isShrink: localStorage.getItem('cn-left-menu-shrink') === 'true',
|
||||
i18n: false,
|
||||
|
||||
showEntityTypeSelector: false, // 在entity explore页面时,控制header显示实体类型选择框
|
||||
@@ -34,7 +35,7 @@ const store = createStore({
|
||||
mutations: {
|
||||
isShrink (state) {
|
||||
state.isShrink = !state.isShrink
|
||||
localStorage.setItem(storageKey.leftMenuShrink, state.isShrink)
|
||||
localStorage.setItem('cn-left-menu-shrink', state.isShrink)
|
||||
},
|
||||
loadI18n (state) {
|
||||
state.i18n = true
|
||||
|
||||
24
src/store/modules/largeScreen.js
Normal file
24
src/store/modules/largeScreen.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import dayjs from 'dayjs'
|
||||
const largeScreen = {
|
||||
state () {
|
||||
return {
|
||||
showMenu: true
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
setShowMenu (state, showMenu) {
|
||||
state.showMenu = showMenu
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
getShowMenu (state) {
|
||||
return state.showMenu
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
hideMenuHeader (state, res) {
|
||||
state.commit('setShowMenu', false)
|
||||
}
|
||||
}
|
||||
}
|
||||
export default largeScreen
|
||||
@@ -14,8 +14,7 @@ const panel = {
|
||||
chartLastPosition: {
|
||||
x: 0,
|
||||
y: 0
|
||||
},
|
||||
chartList: []
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
setShowRightBox (state, flag) {
|
||||
@@ -56,12 +55,6 @@ const panel = {
|
||||
},
|
||||
setChartListId (state, id) {
|
||||
state.chartListId = id
|
||||
},
|
||||
setChartList (state, chart) {
|
||||
state.chartList.push(chart)
|
||||
},
|
||||
cleanChartList (state) {
|
||||
state.chartList = []
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
@@ -100,9 +93,6 @@ const panel = {
|
||||
},
|
||||
getChartListId (state, id) {
|
||||
return state.chartListId
|
||||
},
|
||||
getChartList (state) {
|
||||
return state.chartList
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
|
||||
@@ -4,9 +4,6 @@ import { sortByOrderNum, getWelcomeMenu } from '@/permission'
|
||||
import dayjs from 'dayjs'
|
||||
import utc from 'dayjs/plugin/utc'
|
||||
import { ElMessage } from 'element-plus' // dependent on utc plugin
|
||||
import { storageKey } from '@/utils/constants'
|
||||
import { api } from '@/utils/api'
|
||||
|
||||
dayjs.extend(utc)
|
||||
|
||||
const user = {
|
||||
@@ -46,56 +43,38 @@ const user = {
|
||||
},
|
||||
actions: {
|
||||
loginSuccess (store, res) {
|
||||
console.info(res)
|
||||
window.$dayJs.tz.setDefault(res.data.timezone)
|
||||
localStorage.setItem(storageKey.token, res.data.token)
|
||||
localStorage.setItem(storageKey.sysName, res.data.systemName)
|
||||
localStorage.setItem('cn-token', res.data.token)
|
||||
localStorage.setItem('cn-sys-name', res.data.systemName)
|
||||
if (res.systemLogo) {
|
||||
localStorage.setItem(storageKey.sysLogo, res.data.systemLogo)
|
||||
localStorage.setItem('cn-sys-logo', res.data.systemLogo)
|
||||
}
|
||||
localStorage.setItem(storageKey.sysTimezone, res.data.timezone)
|
||||
localStorage.setItem(storageKey.timezoneOffset, dayjs.tz().utcOffset() / 60)
|
||||
localStorage.setItem(storageKey.timezoneLocalOffset, dayjs().utcOffset() / 60)
|
||||
post(api.permissions, { token: res.data.token }).then(res2 => {
|
||||
const menuList = sortByOrderNum(res2.data.menus)
|
||||
localStorage.setItem('cn-sys-timezone', res.data.timezone)
|
||||
localStorage.setItem('cn-timezone-offset', dayjs.tz().utcOffset() / 60)
|
||||
localStorage.setItem('cn-timezone-local-offset', dayjs().utcOffset() / 60)
|
||||
post('/sys/user/permissions', { token: res.data.token }).then(res => {
|
||||
const menuList = sortByOrderNum(res.data.menus)
|
||||
store.commit('setMenuList', menuList)
|
||||
store.commit('setButtonList', res2.data.buttons)
|
||||
store.commit('setRoleList', res2.data.roles)
|
||||
store.commit('setButtonList', res.data.buttons)
|
||||
store.commit('setRoleList', res.data.roles)
|
||||
|
||||
if (res.loginSuccessPath) {
|
||||
let tempArr = res.loginSuccessPath.split('?')
|
||||
const path = tempArr[0]
|
||||
const query = {}
|
||||
if (tempArr[1]) {
|
||||
tempArr = tempArr[1].split('&')
|
||||
tempArr.forEach(t => {
|
||||
const kv = t.split('=')
|
||||
query[kv[0]] = kv[1]
|
||||
})
|
||||
}
|
||||
const welcomeMenu = getWelcomeMenu(menuList)
|
||||
if (welcomeMenu) {
|
||||
router.push({
|
||||
path: path,
|
||||
query: query
|
||||
path: welcomeMenu.route,
|
||||
query: {
|
||||
t: +new Date()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
const welcomeMenu = getWelcomeMenu(menuList)
|
||||
if (welcomeMenu) {
|
||||
router.push({
|
||||
path: welcomeMenu.route,
|
||||
query: {
|
||||
t: +new Date()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
ElMessage.error('No menu')
|
||||
}
|
||||
ElMessage.error('No menu') // TODO 国际化
|
||||
}
|
||||
})
|
||||
},
|
||||
logoutSuccess (store, res) {
|
||||
localStorage.removeItem(storageKey.username)
|
||||
localStorage.removeItem(storageKey.username)
|
||||
localStorage.removeItem(storageKey.token)
|
||||
localStorage.removeItem('cn-username')
|
||||
localStorage.removeItem('cn-username')
|
||||
localStorage.removeItem('cn-token')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,33 +11,13 @@ import { storageKey } from '@/utils/constants'
|
||||
export const api = {
|
||||
// 系统相关
|
||||
permission: '/sys/user/permissions',
|
||||
i18n: '/sys/i18n/lang',
|
||||
dict: '/sys/dict',
|
||||
logout: '/logout',
|
||||
pin: 'sys/user/pin',
|
||||
appearance: '/sys/appearance',
|
||||
permissions: '/sys/user/permissions',
|
||||
operationLog: '/sys/log',
|
||||
login: '/sys/login',
|
||||
// user
|
||||
user: '/sys/user',
|
||||
// role
|
||||
role: '/sys/role',
|
||||
menu: '/sys/role/menu/',
|
||||
sysMenu: '/sys/menu/',
|
||||
// i18n
|
||||
i18nLang: '/sys/i18n/lang',
|
||||
i18nSys: '/sys/i18n',
|
||||
// chart
|
||||
chartList: '/visual/chart/list',
|
||||
// galaxyProxy
|
||||
galaxyProxy: '/galaxy/setting',
|
||||
|
||||
// 报告相关
|
||||
reportJob: '/report/job',
|
||||
reportTemp: '/report/temp',
|
||||
reportBatchDownloadPdf: '/report/job/batchDownloadPdf',
|
||||
reportDownloadPdf: '/report/job/downloadPdf',
|
||||
reportView: '/report/job/view',
|
||||
operationLog: '/sys/log',
|
||||
chartList: '/visual/chart/list',
|
||||
// 业务
|
||||
panel: '/visual/panel',
|
||||
chart: '/visual/chart',
|
||||
@@ -54,6 +34,8 @@ export const api = {
|
||||
entityNew: '/interface/entity/index/new',
|
||||
entityActive: '/interface/entity/index/active',
|
||||
entityTraffic: '/interface/entity/list/traffic',
|
||||
entityAlertNum: '/interface/entity/list/alertNum',
|
||||
entitySecurityNum: '/interface/entity/list/detectionNum',
|
||||
ipBytes: '/interface/entity/detail/ip/bytes',
|
||||
domainBytes: '/interface/entity/detail/domain/bytes',
|
||||
appBytes: '/interface/entity/detail/app/bytes',
|
||||
@@ -63,8 +45,8 @@ export const api = {
|
||||
entityAppDetailNetworkQuantity: '/interface/entity/detail/overview/app/networkQuantity',
|
||||
entityAppDetailLinkIn: '/interface/entity/detail/overview/app/linkIn',
|
||||
entityAppDetailLinkOut: '/interface/entity/detail/overview/app/linkOut',
|
||||
entityAppDetailPerformance: '/interface/entity/detail/overview/app/performanceEvent',
|
||||
entityAppDetailSecurity: '/interface/entity/detail/overview/app/securityEvent',
|
||||
entityAppDetailAlert: '/interface/entity/detail/overview/app/alert',
|
||||
entityAppDetailSecurity: '/interface/entity/detail/overview/app/security',
|
||||
entityAppRelatedServerDomain: '/interface/entity/detail/overview/app/relatedDomain',
|
||||
entityAppRelatedServerIp: '/interface/entity/detail/overview/app/relatedServerIp',
|
||||
// domain detail
|
||||
@@ -74,12 +56,10 @@ export const api = {
|
||||
entityDomainDetailNetworkQuantity: '/interface/entity/detail/overview/domain/networkQuantity',
|
||||
entityDomainDetailLinkIn: '/interface/entity/detail/overview/domain/linkIn',
|
||||
entityDomainDetailLinkOut: '/interface/entity/detail/overview/domain/linkOut',
|
||||
entityDomainDetailPerformance: '/interface/entity/detail/overview/domain/performanceEvent',
|
||||
entityDomainDetailSecurity: '/interface/entity/detail/overview/domain/securityEvent',
|
||||
entityDomainDetailAlert: '/interface/entity/detail/overview/domain/alert',
|
||||
entityDomainDetailSecurity: '/interface/entity/detail/overview/domain/security',
|
||||
entityDomainRelatedServerIp: '/interface/entity/detail/overview/domain/relatedServerIp',
|
||||
entityDomainRelatedServerApp: '/interface/entity/detail/overview/domain/relatedApp',
|
||||
entityDetectionsIp: '/interface/entity/detail/overview/ip/dnsInfo',
|
||||
entityDetectionsIpQueryRate: '/interface/entity/detail/overview/ip/dnsQueryRate',
|
||||
// ip detail
|
||||
entityIpDetailTraffic: '/interface/entity/detail/overview/ip/traffic',
|
||||
entityIpDetailTrafficMap: '/interface/entity/detail/ip/trafficMap',
|
||||
@@ -89,8 +69,8 @@ export const api = {
|
||||
entityIpDetailNetworkQuantity: '/interface/entity/detail/overview/ip/networkQuantity',
|
||||
entityIpDetailLinkIn: '/interface/entity/detail/overview/ip/linkIn',
|
||||
entityIpDetailLinkOut: '/interface/entity/detail/overview/ip/linkOut',
|
||||
entityIpDetailPerformance: '/interface/entity/detail/overview/ip/performanceEvent',
|
||||
entityIpDetailSecurity: '/interface/entity/detail/overview/ip/securityEvent',
|
||||
entityIpDetailAlert: '/interface/entity/detail/overview/ip/alert',
|
||||
entityIpDetailSecurity: '/interface/entity/detail/overview/ip/security',
|
||||
entityIpRelatedServerDomain: '/interface/entity/detail/overview/ip/relatedDomain',
|
||||
entityIpRelatedServerApp: '/interface/entity/detail/overview/ip/relatedApp',
|
||||
// detection
|
||||
@@ -115,16 +95,9 @@ export const api = {
|
||||
activeEntity: '/interface/detection/performance/filter/activeEntity',
|
||||
listBasic: '/interface/detection/performance/list/basic',
|
||||
listCount: '/interface/detection/performance/list/count',
|
||||
overviewBasic: '/interface/detection/performance/detail/overview/basic',
|
||||
metric: '/interface/detection/performance/detail/overview/metric'
|
||||
overviewBasic: '/interface/detection/performance/detail/overview/basic'
|
||||
}
|
||||
},
|
||||
// Dashboard
|
||||
dashboard: {
|
||||
DnsServiceInsights: {
|
||||
alarmInfoCount: '/interface/dns/alarmInfoCount'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* panel */
|
||||
@@ -157,21 +130,13 @@ export async function getEntityFilter (params) {
|
||||
export async function getDictList (params) {
|
||||
return await getData(api.dict, params, true)
|
||||
}
|
||||
function handleResult (response) {
|
||||
if (response.data.list || response.data.result) {
|
||||
return response.data.list || response.data.result
|
||||
} else if (response.data.result === 0) {
|
||||
return response.data.result
|
||||
} else {
|
||||
return response.data
|
||||
}
|
||||
}
|
||||
|
||||
export async function getData (url, params = {}, isQueryList) {
|
||||
const request = new Promise((resolve, reject) => {
|
||||
try {
|
||||
get(url, params).then(response => {
|
||||
if (response.code === 200) {
|
||||
resolve(handleResult(response))
|
||||
resolve(isQueryList ? response.data.list || response.data.result : response.data.result || response.data)
|
||||
} else {
|
||||
reject(response)
|
||||
}
|
||||
@@ -196,7 +161,7 @@ export async function getConfigJson () {
|
||||
|
||||
export async function getPermission () {
|
||||
const request = new Promise(resolve => {
|
||||
post(api.permission, { token: localStorage.getItem(storageKey.token) }).then(response => {
|
||||
post(api.permission, { token: localStorage.getItem('cn-token') }).then(response => {
|
||||
resolve({
|
||||
menuList: sortByOrderNum(response.data.menus),
|
||||
buttonList: response.data.buttons,
|
||||
@@ -212,7 +177,7 @@ export async function getI18n () {
|
||||
const langs = dictData.map(d => d.value).join(',')
|
||||
localStorage.setItem(storageKey.languages, langs)
|
||||
const request = new Promise(resolve => {
|
||||
get(api.i18nLang, { l: langs }).then(response => {
|
||||
get(api.i18n, { l: langs }).then(response => {
|
||||
response.data.cn = response.data.zh
|
||||
resolve(response.data)
|
||||
})
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -42,5 +42,5 @@ export function getNowTime (interval) {
|
||||
}
|
||||
// 日期格式转换
|
||||
export function rTime (date) {
|
||||
return window.$dayJs.tz(new Date(date)).format('MM-DD HH:mm')
|
||||
return window.$dayJs.tz(new Date(date)).format('YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import axios from 'axios'
|
||||
import { storageKey } from '@/utils/constants'
|
||||
|
||||
axios.interceptors.request.use(config => {
|
||||
const token = localStorage.getItem(storageKey.token)
|
||||
const token = localStorage.getItem('cn-token')
|
||||
if (token) {
|
||||
config.headers.Authorization = token // 请求头token
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ElMessageBox, ElMessage } from 'element-plus'
|
||||
import i18n from '@/i18n'
|
||||
import _ from 'lodash'
|
||||
import { storageKey, iso36112, topDomain } from '@/utils/constants'
|
||||
import { storageKey, iso36112 } from '@/utils/constants'
|
||||
import { getIso36112JsonData } from '@/utils/api'
|
||||
import { format } from 'echarts'
|
||||
import router from '@/router'
|
||||
@@ -442,17 +442,14 @@ export function lineToHump (name) {
|
||||
return letter.toUpperCase()
|
||||
})
|
||||
}
|
||||
// 驼峰转空格,首字母小写
|
||||
export function humpToSpace (name) {
|
||||
const str = name.replace(/([A-Z])/g, ' $1')
|
||||
return str.split(' ').map(s => _.lowerFirst(s)).join(' ')
|
||||
}
|
||||
// 下划线转换空格
|
||||
// 下划线转换空格首位大写
|
||||
export function lineToSpace (name) {
|
||||
if (_.isEmpty(name)) {
|
||||
return ''
|
||||
}
|
||||
return name.replace(/\_(\w)/g, ' ')
|
||||
return _.upperFirst(name.replace(/\_(\w)/g, function (all, letter) {
|
||||
return ` ${letter.toUpperCase()}`
|
||||
}))
|
||||
}
|
||||
// 驼峰转换下划线
|
||||
export function humpToLine (name) {
|
||||
@@ -461,71 +458,6 @@ export function humpToLine (name) {
|
||||
}
|
||||
return name.replace(/([A-Z])/g, '_$1').toLowerCase()
|
||||
}
|
||||
// 排序功能:从大到小,降序排列
|
||||
export function reverseSortBy (i) {
|
||||
return function (a, b) {
|
||||
return b[i] - a[i]
|
||||
}
|
||||
}
|
||||
|
||||
// 排序功能:从小到大,升序排列
|
||||
export function sortBy (i) {
|
||||
return function (a, b) {
|
||||
return a[i] - b[i]
|
||||
}
|
||||
}
|
||||
|
||||
// echart图标,y轴鼠标悬浮时,显示标签所有内容
|
||||
export function extensionEchartY (chart) {
|
||||
// 判断是否创建过div框,如果创建过就不再创建了
|
||||
// 该div用来盛放文本显示内容的,方便对其悬浮位置进行处理
|
||||
const id = document.getElementById('extension')
|
||||
if (!id) {
|
||||
const div = "<div id = 'extension' style=\"display:block\"></div>"
|
||||
const contentDiv = document.createElement('div')
|
||||
contentDiv.setAttribute('id', 'extension')
|
||||
contentDiv.setAttribute('style', 'display:block')
|
||||
document.documentElement.append(contentDiv)
|
||||
}
|
||||
chart.on('mouseover', function (params) {
|
||||
// 注意这里,我是以Y轴显示内容过长为例,如果是x轴的话,需要改为xAxis
|
||||
if (params.componentType === 'yAxis') {
|
||||
// 设置悬浮文本的位置以及样式
|
||||
const extEle = document.getElementById('extension')
|
||||
extEle.style.cssText = 'display:inline;position:absolute;' +
|
||||
' padding: 12px;' +
|
||||
' max-width: 400px !important;' +
|
||||
' color: #666;' +
|
||||
' background-color: rgb(255, 255, 255);' +
|
||||
' font-size: 14px;' +
|
||||
' line-height: 20px;' +
|
||||
' font-weight:400; ' +
|
||||
' font-family: "Microsoft YaHei"' +
|
||||
' border-style: solid;' +
|
||||
' border-width: 1px;' +
|
||||
' border-radius: 4px;' +
|
||||
' border-color: transparent !important;' +
|
||||
' box-shadow: rgb(0 0 0 / 30%) 0px 0px 3px;' +
|
||||
' white-space: nowrap;' +
|
||||
' z-index: 99999999;'
|
||||
|
||||
extEle.innerHTML = params.value
|
||||
document.documentElement.onmousemove = function (event) {
|
||||
const extEle = document.getElementById('extension')
|
||||
const xx = event.pageX - extEle.offsetWidth - 20
|
||||
const yy = event.pageY + 20
|
||||
extEle.style.cssText = extEle.style.cssText + 'top:' + yy + 'px;left:' + xx + 'px;'
|
||||
}
|
||||
}
|
||||
})
|
||||
chart.on('mouseout', function (params) {
|
||||
// 注意这里,我是以Y轴显示内容过长为例,如果是x轴的话,需要改为xAxis
|
||||
if (params.componentType == 'yAxis') {
|
||||
const extEle = document.getElementById('extension')
|
||||
extEle.style.cssText = 'display:none;'
|
||||
}
|
||||
})
|
||||
}
|
||||
// 搜索功能:对象转字符串
|
||||
export function objToStr (obj) {
|
||||
return Object.keys(obj).map(k => {
|
||||
@@ -606,31 +538,6 @@ export function copyValue (item) {
|
||||
ElMessage.success(i18n.global.t('tip.copySuccess'))
|
||||
}
|
||||
|
||||
export function computeSecondaryDomain (name) {
|
||||
// 命中的顶级域名
|
||||
let hitTopDomain = ''
|
||||
// 同顶级域名比对
|
||||
const hits = []
|
||||
topDomain.forEach(td => {
|
||||
const hitIndex = name.lastIndexOf(td)
|
||||
if (hitIndex > -1 && hitIndex + td.length === name.length) {
|
||||
hits.push(td)
|
||||
}
|
||||
})
|
||||
if (hits.length > 0) {
|
||||
hits.sort((a, b) => {
|
||||
return b.split('.').length - a.split('.').length
|
||||
})
|
||||
hitTopDomain = hits[0]
|
||||
} else {
|
||||
const arr = name.split('.')
|
||||
hitTopDomain = arr[arr.length - 1]
|
||||
}
|
||||
const index = name.lastIndexOf(hitTopDomain)
|
||||
const preArr = name.substring(0, index).split('.')
|
||||
return [preArr[preArr.length - 2], hitTopDomain].join('.')
|
||||
}
|
||||
|
||||
export function getCurrentRoute () {
|
||||
return router.currentRoute && router.currentRoute.path
|
||||
}
|
||||
@@ -652,35 +559,3 @@ export function arrayIsEqual (arr1, arr2) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function scrollToTop (dom, toTop, duration, direction) {
|
||||
const clientHeight = dom.clientHeight
|
||||
const currentTop = dom.scrollTop
|
||||
const totalScrollDistance = Math.abs(currentTop - toTop)
|
||||
let scrollY = currentTop
|
||||
let oldTimestamp = null
|
||||
|
||||
function step (newTimestamp) {
|
||||
if (oldTimestamp !== null) {
|
||||
if (direction === 'up') {
|
||||
scrollY -= totalScrollDistance * (newTimestamp - oldTimestamp) / duration
|
||||
console.info(scrollY)
|
||||
if (scrollY < 0) {
|
||||
dom.scrollTop = 0
|
||||
return
|
||||
}
|
||||
dom.scrollTop = scrollY
|
||||
} else if (direction === 'down') {
|
||||
scrollY += totalScrollDistance * (newTimestamp - oldTimestamp) / duration
|
||||
if (scrollY > clientHeight) {
|
||||
dom.scrollTop = clientHeight
|
||||
return
|
||||
}
|
||||
dom.scrollTop = scrollY
|
||||
}
|
||||
}
|
||||
oldTimestamp = newTimestamp
|
||||
window.requestAnimationFrame(step)
|
||||
}
|
||||
window.requestAnimationFrame(step)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ import _ from 'lodash'
|
||||
|
||||
const numberUnit = ['', 'K', 'M', 'G', 'T', 'P', 'E']
|
||||
const byteUnit = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB']
|
||||
const bpsUnit = ['bps', 'Kbps', 'Mbps', 'Gbps', 'Tbps', 'Pbps', 'Ebps']
|
||||
const timeUnit = [ // 时间单位步进倍数,以ms为基数
|
||||
{ unit: 'ms', step: 1 },
|
||||
{ unit: 's', step: 1000 },
|
||||
@@ -32,10 +31,7 @@ function asciiCompute (num, ascii = 1000, units, dot = 2) {
|
||||
export function numberUnitConvert (value, sourceUnit, targetUnit, dot = 2) {
|
||||
return asciiCompute(value, 1000, numberUnit, dot)
|
||||
}
|
||||
export function bpsUnitConvert (value, sourceUnit, targetUnit, dot = 2) {
|
||||
return asciiCompute(value, 1000, bpsUnit, dot)
|
||||
}
|
||||
export function byteUnitConvert (value, unitType, sourceUnit = 'B', targetUnit, dot = 2) {
|
||||
export function byteUnitConvert (value, sourceUnit = 'B', targetUnit, dot = 2) {
|
||||
return asciiCompute(value, 1024, byteUnit, dot)
|
||||
}
|
||||
/* 时间单位转换,例如将ms转为h */
|
||||
@@ -90,24 +86,12 @@ export default function unitConvert (value, unitType, sourceUnit, targetUnit, do
|
||||
case unitTypes.time: {
|
||||
return timeUnitFormatter(value, sourceUnit, targetUnit, dot)
|
||||
}
|
||||
case unitTypes.percent: {
|
||||
const r = (value * 100).toFixed(dot)
|
||||
if (_.isNaN(r)) {
|
||||
return ['-', '']
|
||||
} else if (r == 0) {
|
||||
return [0, '%']
|
||||
} else {
|
||||
return [r, '%']
|
||||
}
|
||||
}
|
||||
case unitTypes.percent:
|
||||
case unitTypes.number: {
|
||||
return numberUnitConvert(value, sourceUnit, targetUnit, dot)
|
||||
}
|
||||
case unitTypes.bps: {
|
||||
return bpsUnitConvert(value, sourceUnit, targetUnit, dot)
|
||||
}
|
||||
case unitTypes.byte: {
|
||||
return byteUnitConvert(value, unitType, sourceUnit, targetUnit, dot)
|
||||
return byteUnitConvert(value, sourceUnit, targetUnit, dot)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,7 +118,7 @@ export function getUnitType (column) {
|
||||
|
||||
/* 单位转换,返回转换后的[value, unit],type=time时若value<1ms,返回<1ms,type=percent时若value<0.01%,返回<0.01% */
|
||||
export function valueToRangeValue (value, unitType) {
|
||||
const values = unitConvert(Number(value), unitType)
|
||||
const values = unitConvert(value, unitType)
|
||||
if (values[0] || values[0] === 0) {
|
||||
switch (unitType) {
|
||||
case unitTypes.time: {
|
||||
@@ -145,7 +129,7 @@ export function valueToRangeValue (value, unitType) {
|
||||
}
|
||||
case unitTypes.percent: {
|
||||
if (values[0] < 0.01) {
|
||||
return ['<0.01', '%']
|
||||
return ['<0.01', '']
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
<template>
|
||||
<div style="overflow: auto;height: 100%;">
|
||||
<div style="height: 8000px; overflow: auto; width: 100%; display: flex; flex-direction: column; align-content: center; background-color: white;">
|
||||
<!-- <div style="padding-left: 30px; font-size: 18px; font-weight: bold; color: #666;">session/s</div>
|
||||
<div id="lineCanvas1" style="margin-bottom: 100px; height: 500px; width: 100%;"></div>
|
||||
<div style="padding-left: 30px; font-size: 18px; font-weight: bold; color: #666;">bytes</div>
|
||||
<div id="lineCanvas2" style="margin-bottom: 100px; height: 500px; width: 100%;"></div>
|
||||
<div style="padding-left: 30px; font-size: 18px; font-weight: bold; color: #666;">rate</div>
|
||||
<div id="lineCanvas3" style="margin-bottom: 100px; height: 500px; width: 100%;"></div>
|
||||
<div style="padding-left: 30px; font-size: 18px; font-weight: bold; color: #666;">行程卡流量数据 rate</div>
|
||||
<div id="lineCanvas6" style="margin-bottom: 100px; height: 500px; width: 100%;"></div>-->
|
||||
<div style="padding-left: 30px; font-size: 18px; font-weight: bold; color: #666;">流量变化曲线</div>
|
||||
<div id="lineCanvas" style="margin-bottom: 100px; height: 500px; width: 100%;"></div>
|
||||
<!-- <div style="padding-left: 30px; font-size: 18px; font-weight: bold; color: #666;">协议占比</div>
|
||||
<div id="pieCanvas0" style="margin-bottom: 100px; height: 500px; width: 100%;"></div>
|
||||
<div style="padding-left: 30px; font-size: 18px; font-weight: bold; color: #666;">APP占比</div>
|
||||
<div id="pieCanvas1" style="margin-bottom: 100px; height: 500px; width: 100%;"></div>
|
||||
<div style="padding-left: 30px; font-size: 18px; font-weight: bold; color: #666;">域名占比</div>
|
||||
<div id="pieCanvas2" style="margin-bottom: 100px; height: 500px; width: 100%;"></div>
|
||||
<div style="padding-left: 30px; font-size: 18px; font-weight: bold; color: #666;">IP占比</div>
|
||||
<div id="pieCanvas3" style="margin-bottom: 100px; height: 500px; width: 100%;"></div>
|
||||
<div style="padding-left: 30px; font-size: 18px; font-weight: bold; color: #666;">出占比</div>
|
||||
<div id="pieCanvas4" style="margin-bottom: 100px; height: 500px; width: 100%;"></div>
|
||||
<div style="padding-left: 30px; font-size: 18px; font-weight: bold; color: #666;">入占比</div>
|
||||
<div id="pieCanvas5" style="margin-bottom: 100px; height: 500px; width: 100%;"></div>-->
|
||||
<div style="padding-left: 30px; font-size: 18px; font-weight: bold; color: #666;">入</div>
|
||||
<div id="sunCanvas1" style="margin-bottom: 100px; height: 500px; width: 100%;"></div>
|
||||
<div style="padding-left: 30px; font-size: 18px; font-weight: bold; color: #666;">出</div>
|
||||
<div id="sunCanvas2" style="margin-bottom: 100px; height: 500px; width: 100%;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { lineData, lineOption, sunData1, sunData2, sunOption } from './testData'
|
||||
import * as echarts from 'echarts'
|
||||
import { getMillisecond } from '@/utils/date-util'
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
import { unitTypes } from '@/utils/constants'
|
||||
export default {
|
||||
name: 'Temp',
|
||||
methods: {
|
||||
/* initLine (lineData, index) {
|
||||
const data = lineData.map(d => {
|
||||
return [getMillisecond(new Date(d[0]).getTime()), d[index]]
|
||||
})
|
||||
const option = this.$_.cloneDeep(lineOption2)
|
||||
option.series.data = data
|
||||
if (index === 1) {
|
||||
option.yAxis.axisLabel.formatter = function (params) {
|
||||
return unitConvert(params, unitTypes.number).join(' ')
|
||||
}
|
||||
} else if (index === 2) {
|
||||
option.yAxis.axisLabel.formatter = function (params) {
|
||||
return unitConvert(params, unitTypes.byte).join(' ')
|
||||
}
|
||||
} else if (index === 3) {
|
||||
option.yAxis.axisLabel.formatter = function (params) {
|
||||
const arr = unitConvert(params, unitTypes.byte).join(' ')
|
||||
return arr.replace(/B/g, 'bps')
|
||||
}
|
||||
} else if (index === 6) {
|
||||
option.yAxis.axisLabel.formatter = function (params) {
|
||||
const arr = unitConvert(params, unitTypes.byte).join(' ')
|
||||
return arr.replace(/B/g, 'Mbps')
|
||||
}
|
||||
}
|
||||
const dom = document.getElementById(`lineCanvas${index}`)
|
||||
const lineChart = echarts.init(dom)
|
||||
this.$nextTick(() => {
|
||||
lineChart.setOption(option)
|
||||
})
|
||||
}, */
|
||||
initLineChart () {
|
||||
// 数据转为需要的格式:[[timestamp, value]]
|
||||
const data = lineData.map(d => {
|
||||
return [getMillisecond(new Date(d[2]).getTime()), d[1]]
|
||||
})
|
||||
const option = this.$_.cloneDeep(lineOption)
|
||||
option.series.data = data
|
||||
const dom = document.getElementById('lineCanvas')
|
||||
const lineChart = echarts.init(dom)
|
||||
this.$nextTick(() => {
|
||||
lineChart.setOption(option)
|
||||
})
|
||||
},
|
||||
initSunChart (index) {
|
||||
const option = this.$_.cloneDeep(sunOption)
|
||||
const data = index === 1 ? sunData1 : sunData2
|
||||
option.series.data = data
|
||||
const dom = document.getElementById('sunCanvas' + index)
|
||||
const lineChart = echarts.init(dom)
|
||||
this.$nextTick(() => {
|
||||
lineChart.setOption(option)
|
||||
})
|
||||
}
|
||||
/* initPie (index) {
|
||||
const data = pieData[index].map(p => {
|
||||
return {
|
||||
value: parseFloat(p[1].replace('%', '')).toFixed(2),
|
||||
name: p[0]
|
||||
}
|
||||
})
|
||||
const option = this.$_.cloneDeep(pieOption)
|
||||
option.series[0].data = data
|
||||
const dom = document.getElementById(`pieCanvas${index}`)
|
||||
const pieChart = echarts.init(dom)
|
||||
this.$nextTick(() => {
|
||||
pieChart.setOption(option)
|
||||
})
|
||||
} */
|
||||
},
|
||||
mounted () {
|
||||
/* this.initLine(lineData2, 1)
|
||||
this.initLine(lineData2, 2)
|
||||
this.initLine(lineData2, 3)
|
||||
this.initLine(lineData3, 6) */
|
||||
this.initLineChart()
|
||||
this.initSunChart(1)
|
||||
this.initSunChart(2)
|
||||
/* this.initPie(0)
|
||||
this.initPie(1)
|
||||
this.initPie(2)
|
||||
this.initPie(3)
|
||||
this.initPie(4)
|
||||
this.initPie(5) */
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -4,10 +4,8 @@
|
||||
<chart-no-data v-if="isNoData"></chart-no-data>
|
||||
<template v-else>
|
||||
<chart-tabs
|
||||
ref="chart"
|
||||
v-if="isTabs"
|
||||
:chart-info="chartInfo"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
:entity="entity"
|
||||
></chart-tabs>
|
||||
@@ -16,10 +14,9 @@
|
||||
v-else-if="isMap && !isIpBasicInfo"
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
:entity="entity"
|
||||
@getChartData="getChartData"
|
||||
@query="query"
|
||||
@showLoading="showLoading"
|
||||
></chart-map>
|
||||
|
||||
@@ -27,26 +24,22 @@
|
||||
v-else-if="isSingleValue"
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
@showLoading="showLoading"
|
||||
></chart-single-value>
|
||||
|
||||
<chart-block
|
||||
ref="chart"
|
||||
v-else-if="isBlock"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
ref="chart"
|
||||
:timeFilter="queryParams"
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:entity="entity"
|
||||
></chart-block>
|
||||
|
||||
<chart-group
|
||||
ref="chart"
|
||||
v-else-if="isGroup"
|
||||
:query-params="queryParams"
|
||||
:time-filter="timeFilter"
|
||||
:timeFilter="queryParams"
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:entity="entity"
|
||||
@@ -54,8 +47,6 @@
|
||||
|
||||
<ip-basic-info
|
||||
v-else-if="isIpBasicInfo"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:entity="entity"
|
||||
@@ -66,7 +57,6 @@
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:result-type="resultType"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
@showLoading="showLoading"
|
||||
></chart-time-bar>
|
||||
@@ -76,7 +66,6 @@
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:result-type="resultType"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
@showLoading="showLoading"
|
||||
></chart-category-bar>
|
||||
@@ -86,7 +75,6 @@
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:result-type="resultType"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
@showLoading="showLoading"
|
||||
></chart-ip-open-port-bar>
|
||||
@@ -96,7 +84,6 @@
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:table="table"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
@showLoading="showLoading"
|
||||
></chart-table>
|
||||
@@ -106,7 +93,6 @@
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:table="table"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
></chart-active-ip-table>
|
||||
|
||||
@@ -114,7 +100,6 @@
|
||||
v-else-if="isAppBasicInfo"
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
></chart-app-basic-info>
|
||||
|
||||
@@ -122,7 +107,6 @@
|
||||
v-else-if="isDomainWhois"
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
></chart-domain-whois>
|
||||
|
||||
@@ -130,7 +114,6 @@
|
||||
v-else-if="isDomainDnsRecord"
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
></chart-domain-dns-record>
|
||||
|
||||
@@ -138,7 +121,6 @@
|
||||
v-else-if="isCryptocurrencyEventList"
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
></chart-cryptocurrency-event-list>
|
||||
|
||||
@@ -146,7 +128,6 @@
|
||||
v-else-if="isRelationShip"
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
></chart-relation-ship>
|
||||
|
||||
@@ -154,7 +135,6 @@
|
||||
v-else-if="isSankey"
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
:entity="entity"
|
||||
></chart-san-key>
|
||||
@@ -164,8 +144,6 @@
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:result-type="resultType"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
@showLoading="showLoading"
|
||||
></chart-echart>
|
||||
|
||||
@@ -174,8 +152,6 @@
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:result-type="resultType"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
@showLoading="showLoading"
|
||||
></chart-echart-with-statistics>
|
||||
|
||||
@@ -184,7 +160,6 @@
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:query-params="queryParams"
|
||||
:time-filter="timeFilter"
|
||||
:result-type="resultType"
|
||||
:order-pie-table="orderPieTable"
|
||||
@showLoading="showLoading"
|
||||
@@ -192,10 +167,8 @@
|
||||
|
||||
<chart-echart-ip-hosted-domain
|
||||
v-else-if="isIpHostedDomain"
|
||||
:chart-data="chartData"
|
||||
:chart-info="chartInfo"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
:chart-data="chartData"
|
||||
@showLoading="showLoading"
|
||||
:entity="entity"
|
||||
></chart-echart-ip-hosted-domain>
|
||||
@@ -206,67 +179,36 @@
|
||||
:chart-data="chartData"
|
||||
@showLoading="showLoading"
|
||||
:entity="entity"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
></chart-echart-app-relate-domain>
|
||||
|
||||
<chart-one-situation-statistics
|
||||
<chart-one-Situation-Statistics
|
||||
v-else-if="isSingleSupportStatistics"
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:query-params="queryParams"
|
||||
:time-filter="timeFilter"
|
||||
:entity="entity"
|
||||
@showLoading="showLoading"
|
||||
></chart-one-situation-statistics>
|
||||
:entity="entity"
|
||||
></chart-one-Situation-Statistics>
|
||||
|
||||
<chart-two-situation-statistics
|
||||
<chart-two-Situation-Statistics
|
||||
v-else-if="isTwoSupportStatistics"
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
@showLoading="showLoading"
|
||||
:entity="entity"
|
||||
></chart-two-situation-statistics>
|
||||
></chart-two-Situation-Statistics>
|
||||
|
||||
<chart-alarm-info
|
||||
v-else-if="isAlarmInfo"
|
||||
v-else-if="isAlarmInfo"
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
@showLoading="showLoading"
|
||||
:tabHandleClickType="tabHandleClickType"
|
||||
@getAlarmInfo="getAlarmInfo"
|
||||
:entity="entity"
|
||||
>
|
||||
:entity="entity">
|
||||
</chart-alarm-info>
|
||||
<chart-domain-recursive-resolve
|
||||
:chart-data="chartData"
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
v-else-if="isDomainRecursiveResolve"
|
||||
></chart-domain-recursive-resolve>
|
||||
|
||||
<chart-detection-security
|
||||
:chart-data="chartData"
|
||||
:time-filter="timeFilter"
|
||||
:chart-info="chartInfo"
|
||||
:query-params="queryParams"
|
||||
v-else-if="isDetectionSecurity"
|
||||
@getDetectionData="getDetectionData"
|
||||
></chart-detection-security>
|
||||
|
||||
<chart-detection-service
|
||||
:chart-data="chartData"
|
||||
:time-filter="timeFilter"
|
||||
:chart-info="chartInfo"
|
||||
:query-params="queryParams"
|
||||
v-else-if="isDetectionService"
|
||||
@getDetectionData="getDetectionData"
|
||||
></chart-detection-service>
|
||||
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
@@ -299,9 +241,6 @@ import ChartSanKey from '@/views/charts/charts/ChartSanKey'
|
||||
import ChartOneSituationStatistics from '@/views/charts/charts/ChartOneSituationStatistics'
|
||||
import ChartTwoSituationStatistics from '@/views/charts/charts/ChartTwoSituationStatistics'
|
||||
import ChartAlarmInfo from '@/views/charts/charts/ChartAlarmInfo'
|
||||
import ChartDomainRecursiveResolve from '@/views/charts/charts/ChartDomainRecursiveResolve'
|
||||
import chartDetectionSecurity from '@/views/charts/charts/chartDetectionSecurity'
|
||||
import chartDetectionService from '@/views/charts/charts/chartDetectionService'
|
||||
import {
|
||||
isEcharts,
|
||||
isEchartsLine,
|
||||
@@ -321,12 +260,13 @@ import {
|
||||
isMapLine,
|
||||
isMapBlock,
|
||||
isSingleValueWithEcharts,
|
||||
isSingleValueWithPercent,
|
||||
isSingleValueWithEchartsTemp,
|
||||
isRelationShip,
|
||||
isTabs,
|
||||
isGroup,
|
||||
isSankey,
|
||||
isIpBasicInfo,
|
||||
isIpOpenPort,
|
||||
isIpHostedDomain,
|
||||
isDomainWhois,
|
||||
isDomainDnsRecord,
|
||||
@@ -336,11 +276,7 @@ import {
|
||||
isBlock,
|
||||
isSingleSupportStatistics,
|
||||
isTwoSupportStatistics,
|
||||
isAlarmInfo,
|
||||
isDomainRecursiveResolve,
|
||||
isDetectionSecurity,
|
||||
isDetectionService,
|
||||
isDetectionsProtocol
|
||||
isAlarmInfo
|
||||
} from './charts/tools'
|
||||
import _ from 'lodash'
|
||||
|
||||
@@ -373,14 +309,11 @@ export default {
|
||||
ChartEchartAppRelateDomain,
|
||||
ChartOneSituationStatistics,
|
||||
ChartTwoSituationStatistics,
|
||||
ChartAlarmInfo,
|
||||
ChartDomainRecursiveResolve,
|
||||
chartDetectionSecurity,
|
||||
chartDetectionService
|
||||
ChartAlarmInfo
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
tabHandleClickType: ''
|
||||
data(){
|
||||
return{
|
||||
tabHandleClickType:''
|
||||
}
|
||||
},
|
||||
props: {
|
||||
@@ -395,19 +328,16 @@ export default {
|
||||
entity: Object,
|
||||
isError: Boolean,
|
||||
table: Object,
|
||||
timeFilter: Object,
|
||||
orderPieTable: Object,
|
||||
tabHandleClickType: String
|
||||
tabHandleClickType:String
|
||||
},
|
||||
computed: {
|
||||
isNoData () {
|
||||
return (
|
||||
!this.loading &&
|
||||
(!this.chartData || _.isEmpty(this.chartData) || this.isError) &&
|
||||
(_.isEmpty(this.chartData) || this.isError) &&
|
||||
!this.isSingleValue &&
|
||||
!this.isTabs &&
|
||||
!this.isBlock &&
|
||||
!this.isGroup &&
|
||||
!this.isDomainDnsRecord &&
|
||||
!this.isCryptocurrencyEventList &&
|
||||
!this.isActiveIpTable &&
|
||||
@@ -423,7 +353,7 @@ export default {
|
||||
} else {
|
||||
return getOption(this.chartInfo.type)
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
resize () {
|
||||
@@ -433,14 +363,8 @@ export default {
|
||||
showLoading (show) {
|
||||
this.$emit('showLoading', show)
|
||||
},
|
||||
getAlarmInfo (url, extraParams, isRefresh, timeFilter) {
|
||||
this.$emit('getChartData', url, extraParams, isRefresh, timeFilter)
|
||||
},
|
||||
getChartData (url, extraParams) {
|
||||
this.$emit('getChartData', url, extraParams)
|
||||
},
|
||||
getDetectionData (url, extraParams, isRefresh, timeFilter) {
|
||||
this.$emit('getChartData', url, extraParams, isRefresh, timeFilter)
|
||||
getAlarmInfo(url,extraParams){
|
||||
this.$emit('getChartData',url,extraParams)
|
||||
},
|
||||
initEchartsWithTable () {
|
||||
this.$refs['chart' + this.chartInfo.id] &&
|
||||
@@ -453,9 +377,13 @@ export default {
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
tabHandleClickType: {
|
||||
chartData: {
|
||||
deep: true,
|
||||
handler (n) {
|
||||
handler (n) {}
|
||||
},
|
||||
tabHandleClickType:{
|
||||
deep:true,
|
||||
handler(n){
|
||||
this.tabHandleClickType = n
|
||||
}
|
||||
}
|
||||
@@ -472,7 +400,9 @@ export default {
|
||||
isEchartsWithStatistics: isEchartsWithStatistics(props.chartInfo.type),
|
||||
isSingleValue: isSingleValue(props.chartInfo.type),
|
||||
isSingleValueWithEcharts: isSingleValueWithEcharts(props.chartInfo.type),
|
||||
isSingleValueWithPercent: isSingleValueWithPercent(props.chartInfo.type),
|
||||
isSingleValueWithEchartsTemp: isSingleValueWithEchartsTemp(
|
||||
props.chartInfo.type
|
||||
),
|
||||
isRelationShip: isRelationShip(props.chartInfo.type),
|
||||
isTable: isTable(props.chartInfo.type),
|
||||
isBasicTable: isBasicTable(props.chartInfo.type),
|
||||
@@ -487,6 +417,7 @@ export default {
|
||||
isSankey: isSankey(props.chartInfo.type),
|
||||
isIpBasicInfo: isIpBasicInfo(props.chartInfo.type),
|
||||
isIpHostedDomain: isIpHostedDomain(props.chartInfo.type),
|
||||
isIpOpenPort: isIpOpenPort(props.chartInfo.type),
|
||||
isDomainWhois: isDomainWhois(props.chartInfo.type),
|
||||
isDomainDnsRecord: isDomainDnsRecord(props.chartInfo.type),
|
||||
isCryptocurrencyEventList: isCryptocurrencyEventList(
|
||||
@@ -494,16 +425,10 @@ export default {
|
||||
),
|
||||
isAppBasicInfo: isAppBasicInfo(props.chartInfo.type),
|
||||
isAppRelatedDomain: isAppRelatedDomain(props.chartInfo.type),
|
||||
isSingleSupportStatistics: isSingleSupportStatistics(
|
||||
props.chartInfo.type
|
||||
),
|
||||
isSingleSupportStatistics: isSingleSupportStatistics(props.chartInfo.type),
|
||||
isTwoSupportStatistics: isTwoSupportStatistics(props.chartInfo.type),
|
||||
isAlarmInfo: isAlarmInfo(props.chartInfo.type),
|
||||
isDomainRecursiveResolve: isDomainRecursiveResolve(props.chartInfo.type),
|
||||
isDetectionSecurity: isDetectionSecurity(props.chartInfo.type),
|
||||
isDetectionService: isDetectionService(props.chartInfo.type),
|
||||
isDetectionsProtocol: isDetectionsProtocol(props.chartInfo.type)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
:class="{
|
||||
'chart-header--title-chart': isTitle,
|
||||
'is-group-collapse': isGroup,
|
||||
'panel-chart-block': isBlock
|
||||
'panel-chart-block': isBlock,
|
||||
}"
|
||||
>
|
||||
<div class="chart-header__title" v-if="isGroup">
|
||||
@@ -18,14 +18,7 @@
|
||||
</span>
|
||||
{{ chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name }}
|
||||
</div>
|
||||
<div
|
||||
class="chart-header__title"
|
||||
v-else-if="!isBasicTable"
|
||||
:class="{ 'chart-header__title--block': isBlock }"
|
||||
:title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name"
|
||||
>
|
||||
{{ chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name }}
|
||||
</div>
|
||||
<div class="chart-header__title" v-else-if="!isBasicTable" :class="{'chart-header__title--block': isBlock}" :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</div>
|
||||
<template v-if="isBasicTable">
|
||||
<div class="chart-header__title">
|
||||
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{
|
||||
@@ -81,13 +74,12 @@
|
||||
@change="tableLimitChange"
|
||||
>
|
||||
<template
|
||||
v-for="(item, index) in table.tableColumns.order"
|
||||
v-for="(item, index) in table.tableColumns"
|
||||
:key="item.prop"
|
||||
>
|
||||
<el-option
|
||||
:value="item"
|
||||
:label="$t(chartTableColumnMapping[item])"
|
||||
></el-option>
|
||||
<el-option v-if="index > 0" :value="item.prop">{{
|
||||
item.prop
|
||||
}}</el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</div>
|
||||
@@ -145,31 +137,21 @@
|
||||
|
||||
<template v-else-if="isAlarmInfo">
|
||||
<div class="cn-chart-header-button">
|
||||
<el-button-group class="cn-chart-header-button-group">
|
||||
<el-button
|
||||
:class="isFocusAll ? 'cn-chart-header-button-all' : ''"
|
||||
@click="tabHandleClick('All')"
|
||||
size="small"
|
||||
>{{ $t('dns.all') }}</el-button
|
||||
>
|
||||
<el-button
|
||||
:label="value"
|
||||
:name="value"
|
||||
plain:true
|
||||
v-for="(value, key) in eventSeverity"
|
||||
:key="key"
|
||||
size="small"
|
||||
:class="isFocus === value ? 'cn-chart-header-button-' + value : ''"
|
||||
@click="tabHandleClick(value)"
|
||||
>
|
||||
{{ value }}
|
||||
</el-button>
|
||||
</el-button-group>
|
||||
<div>
|
||||
<span class="header__operation-btn" @click="refresh"
|
||||
><i class="cn-icon cn-icon-refresh"></i
|
||||
></span>
|
||||
</div>
|
||||
<el-button
|
||||
:class="isFocusAll ? 'cn-chart-header-button-all' : ''"
|
||||
@click="tabHandleClick('All')"
|
||||
>{{ $t('dns.all') }}</el-button
|
||||
>
|
||||
<el-button
|
||||
:label="value"
|
||||
:name="value"
|
||||
v-for="(value, key) in eventSeverity"
|
||||
:key="key"
|
||||
:class=" isFocus === value ? 'cn-chart-header-button-' + value : ''"
|
||||
@click="tabHandleClick(value)"
|
||||
>
|
||||
{{ value }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -193,7 +175,6 @@
|
||||
class="date-time-range"
|
||||
:start-time="chartTimeFilter.startTime"
|
||||
:end-time="chartTimeFilter.endTime"
|
||||
:date-range="chartTimeFilter.dateRangeValue"
|
||||
ref="dateTimeRange"
|
||||
@change="reload"
|
||||
/>
|
||||
@@ -247,9 +228,8 @@ import {
|
||||
chartActiveIpTableOrderOptions,
|
||||
chartPieTableTopOptions,
|
||||
eventSeverity,
|
||||
chartTableColumnMapping, panelTypeAndRouteMapping
|
||||
chartTableColumnMapping
|
||||
} from '@/utils/constants'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
export default {
|
||||
name: 'ChartHeader',
|
||||
@@ -257,24 +237,24 @@ export default {
|
||||
chartInfo: Object,
|
||||
errorInfo: {
|
||||
type: String,
|
||||
default: ''
|
||||
default: '',
|
||||
},
|
||||
isError: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
default: false,
|
||||
},
|
||||
table: Object,
|
||||
orderPieTable: Object
|
||||
orderPieTable: Object,
|
||||
},
|
||||
components: {
|
||||
ChartError
|
||||
ChartError,
|
||||
},
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
chartTableColumnMapping,
|
||||
dropdownMenuShow: false,
|
||||
errorText: '',
|
||||
isFocus: false,
|
||||
isFocus:false,
|
||||
isFocusAll: true,
|
||||
activeIpTable: {
|
||||
// ActiveIpTable select
|
||||
@@ -282,96 +262,95 @@ export default {
|
||||
tableData: [
|
||||
{
|
||||
name: '192.168.20.21',
|
||||
num: 111
|
||||
num: 111,
|
||||
},
|
||||
{
|
||||
name: '192.168.20.22',
|
||||
num: 345
|
||||
num: 345,
|
||||
},
|
||||
{
|
||||
name: '192.168.20.23',
|
||||
num: 111
|
||||
num: 111,
|
||||
},
|
||||
{
|
||||
name: '192.168.20.24',
|
||||
num: 345
|
||||
num: 345,
|
||||
},
|
||||
{
|
||||
name: '192.168.20.25',
|
||||
num: 111
|
||||
num: 111,
|
||||
},
|
||||
{
|
||||
name: '192.168.20.26',
|
||||
num: 345
|
||||
}
|
||||
] // table的所有数据
|
||||
}
|
||||
num: 345,
|
||||
},
|
||||
], // table的所有数据
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
refresh () {
|
||||
refresh() {
|
||||
this.$emit('refresh')
|
||||
},
|
||||
timeRefreshChange () {
|
||||
// 不是自选时间
|
||||
timeRefreshChange() {
|
||||
if (!this.$refs.dateTimeRange.isCustom) {
|
||||
const value = this.chartTimeFilter.dateRangeValue
|
||||
this.$refs.dateTimeRange.quickChange(value)
|
||||
} else {
|
||||
this.$emit('refresh', this.chartTimeFilter)
|
||||
this.$emit('refresh')
|
||||
}
|
||||
},
|
||||
reload (s, e, v) {
|
||||
reload(s, e, v) {
|
||||
this.dateTimeRangeChange(s, e, v)
|
||||
},
|
||||
groupShow () {
|
||||
groupShow() {
|
||||
this.$emit('groupShow', this.chartInfo)
|
||||
},
|
||||
dateTimeRangeChange (s, e, v) {
|
||||
dateTimeRangeChange(s, e, v) {
|
||||
this.chartTimeFilter = { startTime: s, endTime: e, dateRangeValue: v }
|
||||
this.$emit('refresh', this.chartTimeFilter)
|
||||
},
|
||||
tableLimitChange () {
|
||||
tableLimitChange() {
|
||||
this.$emit('tableChange')
|
||||
},
|
||||
activeIpTableLimitChange () {
|
||||
activeIpTableLimitChange() {
|
||||
this.$emit('tableChange')
|
||||
},
|
||||
orderPieTableChange () {
|
||||
orderPieTableChange() {
|
||||
this.$emit('orderPieTableChange', this.orderPieTable)
|
||||
},
|
||||
tabHandleClick (item) {
|
||||
tabHandleClick(item) {
|
||||
this.isFocus = item
|
||||
if (item === 'All') {
|
||||
this.isFocusAll = false
|
||||
if(item === 'All'){
|
||||
this.isFocusAll = true
|
||||
} else {
|
||||
}else{
|
||||
this.isFocusAll = false
|
||||
}
|
||||
this.$emit('tabHandleClick', item)
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
isFocus: {
|
||||
deep: true,
|
||||
handler (n) {}
|
||||
beforeCreate() {
|
||||
this.$emit('tabHandleClick', 'All')
|
||||
},
|
||||
watch:{
|
||||
isFocus:{
|
||||
deep:true,
|
||||
handler(n){
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
showRefreshButton () {
|
||||
showRefreshButton() {
|
||||
// 自己是group且父元素是block时,不显示刷新按钮
|
||||
// TODO 父元素是block,且只有自己一个子元素时,不显示刷新按钮
|
||||
const isGroupAndParentIsBlock =
|
||||
this.$_.get(this.chartInfo.parent, 'type') === 95 && this.isGroup
|
||||
return !isGroupAndParentIsBlock
|
||||
}
|
||||
},
|
||||
},
|
||||
setup (props) {
|
||||
const { currentRoute } = useRouter()
|
||||
|
||||
function isEntityDetail (r) {
|
||||
return r.indexOf('entityDetail') > -1
|
||||
}
|
||||
const dateRangeValue = isEntityDetail(currentRoute.value.path) ? 60 * 24 : 60
|
||||
setup(props) {
|
||||
const dateRangeValue = 60
|
||||
const { startTime, endTime } = getNowTime(dateRangeValue)
|
||||
// entity详情内的chart时间工具不是公共的,需要单独定义
|
||||
const chartTimeFilter = ref({ startTime, endTime, dateRangeValue })
|
||||
@@ -389,8 +368,8 @@ export default {
|
||||
isActiveIpTable: isActiveIpTable(props.chartInfo.type),
|
||||
isEchartsWithTable: isEchartsWithTable(props.chartInfo.type),
|
||||
isGroup: isGroup(props.chartInfo.type),
|
||||
isAlarmInfo: isAlarmInfo(props.chartInfo.type)
|
||||
isAlarmInfo: isAlarmInfo(props.chartInfo.type),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div style="padding: 10px 10px 20px 10px; overflow: auto" v-if="!isEntityDetail" @scroll="wholeScreenScroll">
|
||||
<div style="padding: 10px 10px 20px 10px; overflow: auto" v-if="!isEntityDetail">
|
||||
<div id="cn-panel" class="cn-panel2">
|
||||
<div class="panel__time">
|
||||
<date-time-range class="date-time-range" :start-time="timeFilter.startTime" :end-time="timeFilter.endTime" :date-range="timeFilter.dateRangeValue" ref="dateTimeRange" @change="reload"/>
|
||||
<date-time-range class="date-time-range" :start-time="timeFilter.startTime" :end-time="timeFilter.endTime" ref="dateTimeRange" @change="reload"/>
|
||||
<time-refresh class="date-time-range" @change="timeRefreshChange" :end-time="timeFilter.endTime"/>
|
||||
</div>
|
||||
<panel-chart-list
|
||||
@@ -11,7 +11,6 @@
|
||||
:data-list="chartList"
|
||||
:panel-lock="panelLock"
|
||||
:entity="entity"
|
||||
:whole-screen-scroll="panel.params && panel.params.wholeScreenScroll"
|
||||
>
|
||||
</panel-chart-list>
|
||||
</div>
|
||||
@@ -27,6 +26,14 @@
|
||||
:entity="entity"
|
||||
>
|
||||
</panel-chart-list>
|
||||
<!-- <template v-for="chart in chartList" :key="chart.id">
|
||||
<chart
|
||||
:chart="chart"
|
||||
:ref="`chart-${chart.id}`"
|
||||
:entity="entity"
|
||||
@getCurrentTimeRange="getCurrentTimeRange"
|
||||
></chart>
|
||||
</template>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -38,12 +45,7 @@ import { ref } from 'vue'
|
||||
import { panelTypeAndRouteMapping } from '@/utils/constants'
|
||||
import { api, getPanelList, getChartList } from '@/utils/api'
|
||||
import { getNowTime } from '@/utils/date-util'
|
||||
import { scrollToTop } from '@/utils/tools'
|
||||
import {
|
||||
isGroup,
|
||||
isBlock,
|
||||
getGroupHeight
|
||||
} from './charts/tools'
|
||||
import { getGroupHeight, getTypeCategory } from '@/views/charts/charts/tools'
|
||||
|
||||
export default {
|
||||
name: 'Panel',
|
||||
@@ -60,11 +62,7 @@ export default {
|
||||
detailTabs: [],
|
||||
detailChartList: [],
|
||||
currentTab: '',
|
||||
isCryptocurrency: false, // 是否为挖矿列表
|
||||
scroll: {
|
||||
prevent: false, // 阻止滚动
|
||||
prevScrollTop: 0 // 前一次滚动条位置
|
||||
}
|
||||
isCryptocurrency: false// 是否为挖矿列表
|
||||
}
|
||||
},
|
||||
async mounted () {
|
||||
@@ -76,18 +74,14 @@ export default {
|
||||
}
|
||||
},
|
||||
setup (props, ctx) {
|
||||
// data
|
||||
const dateRangeValue = 60
|
||||
const { startTime, endTime } = getNowTime(dateRangeValue)
|
||||
const timeFilter = ref({ startTime, endTime, dateRangeValue })
|
||||
const panel = ref({})
|
||||
let panelType = 1 // 取得panel的type
|
||||
const { params } = useRoute()
|
||||
panelType = props.entity ? props.entity.type : panelTypeAndRouteMapping[params.typeName]
|
||||
|
||||
function isEntityDetail (t) {
|
||||
return [4, 5, 6].indexOf(t) > -1
|
||||
}
|
||||
// date
|
||||
const dateRangeValue = isEntityDetail(panelType) ? 60 * 24 : 60
|
||||
const { startTime, endTime } = getNowTime(dateRangeValue)
|
||||
const timeFilter = ref({ startTime, endTime, dateRangeValue })
|
||||
return {
|
||||
panelType,
|
||||
panel,
|
||||
@@ -102,11 +96,6 @@ export default {
|
||||
this.panel = panels[0]
|
||||
}
|
||||
if (this.panel.id) {
|
||||
if (this.panel.params) {
|
||||
this.panel.params = JSON.parse(this.panel.params)
|
||||
} else {
|
||||
this.panel.params = {}
|
||||
}
|
||||
const allCharts = (await getChartList({ panelId: this.panel.id, pageSize: -1 })).map(chart => {
|
||||
chart.i = chart.id
|
||||
this.recursionParamsConvert(chart)
|
||||
@@ -126,7 +115,7 @@ export default {
|
||||
recursionParamsConvert (chart) {
|
||||
chart.params = chart.params ? JSON.parse(chart.params) : {}
|
||||
chart.firstShow = false
|
||||
if (isGroup(chart.type)) {
|
||||
if (chart.type === 94) {
|
||||
chart.oldH = chart.h
|
||||
/* chart.params = {
|
||||
collapse: false
|
||||
@@ -136,10 +125,10 @@ export default {
|
||||
chart.h = 1
|
||||
}
|
||||
}
|
||||
if (isBlock(chart.type)) {
|
||||
if (chart.type === 95) {
|
||||
let sumGroup = 0
|
||||
chart.children.forEach(item => {
|
||||
if (isGroup(item.type)) {
|
||||
if (item.type === 94) {
|
||||
sumGroup++
|
||||
}
|
||||
})
|
||||
@@ -157,7 +146,6 @@ export default {
|
||||
callback({ startTime: myStartTime, endTime: myEndTime })
|
||||
},
|
||||
timeRefreshChange () {
|
||||
// 不是自选时间
|
||||
if (!this.$refs.dateTimeRange.isCustom) {
|
||||
const value = this.timeFilter.dateRangeValue
|
||||
this.$refs.dateTimeRange.quickChange(value)
|
||||
@@ -183,37 +171,6 @@ export default {
|
||||
},
|
||||
groupParentCalcHeight (params) {
|
||||
this.$refs.panelChartList.groupParentCalcHeight(params.chart, params.childrenList)
|
||||
},
|
||||
wholeScreenScroll (e) {
|
||||
if (this.scroll.prevent) {
|
||||
return
|
||||
}
|
||||
this.scroll.prevent = true
|
||||
const clientHeight = e.target.clientHeight
|
||||
const currentScrollTop = e.target.scrollTop
|
||||
if (currentScrollTop > this.scroll.prevScrollTop) {
|
||||
// 向下滚动,若top在clientHeight内,则整屏滚动下去
|
||||
this.scroll.prevScrollTop = currentScrollTop
|
||||
if (currentScrollTop < clientHeight) {
|
||||
scrollToTop(e.target, clientHeight, 200, 'down')
|
||||
setTimeout(() => {
|
||||
this.scroll.prevScrollTop = e.target.scrollTop
|
||||
}, 210)
|
||||
}
|
||||
} else if (currentScrollTop < this.scroll.prevScrollTop) {
|
||||
// 向上滚动,若top在clientHeight内,则滚动到最顶部
|
||||
this.scroll.prevScrollTop = currentScrollTop
|
||||
if (currentScrollTop < clientHeight) {
|
||||
scrollToTop(e.target, 0, 200, 'up')
|
||||
setTimeout(() => {
|
||||
this.scroll.prevScrollTop = e.target.scrollTop
|
||||
}, 210)
|
||||
}
|
||||
}
|
||||
const vm = this
|
||||
setTimeout(() => {
|
||||
vm.scroll.prevent = false
|
||||
}, 210)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
>
|
||||
<!-- title和工具栏,支持浮动 -->
|
||||
<chart-header
|
||||
v-if="!isFullscreen && showHeader && !isSingleValue && !isTabs && !isDetectionSecurity && !isDetectionService"
|
||||
v-if="!isFullscreen && showHeader && !isSingleValue && !isTabs"
|
||||
:is-error="isError"
|
||||
:error-info="errorInfo"
|
||||
:chart-data="chartData"
|
||||
@@ -26,7 +26,7 @@
|
||||
<!-- 数据查询后传入chart组件,chart组件内不查询,只根据接传递的数据来渲染 -->
|
||||
<chart
|
||||
ref="chart"
|
||||
v-if="(!isGroup || !(chartInfo.params && chartInfo.params.collapse)) && !isTitle "
|
||||
v-if="((!isGroup) || !(chartInfo.params && chartInfo.params.collapse)) && !isTitle"
|
||||
:chart-data="chartData"
|
||||
:result-type="resultType"
|
||||
:chart-info="chartInfo"
|
||||
@@ -38,7 +38,6 @@
|
||||
:table="table"
|
||||
:is-fullscreen="isFullscreen"
|
||||
:order-pie-table="orderPieTable"
|
||||
:time-filter="timeFilter"
|
||||
@getChartData="getChartData"
|
||||
@showLoading="showLoading"
|
||||
:tabHandleClickType="tabHandleClickType"
|
||||
@@ -54,7 +53,6 @@ import {
|
||||
isEcharts,
|
||||
isSingleValue,
|
||||
isTable,
|
||||
isBasicTable,
|
||||
isActiveIpTable,
|
||||
isTitle,
|
||||
isMap,
|
||||
@@ -65,23 +63,20 @@ import {
|
||||
isMapLine,
|
||||
isMapBlock,
|
||||
isSingleValueWithEcharts,
|
||||
isSingleValueWithPercent,
|
||||
isSingleValueWithEchartsTemp,
|
||||
isRelationShip,
|
||||
isTabs,
|
||||
isGroup,
|
||||
isSankey,
|
||||
isIpBasicInfo,
|
||||
isIpOpenPortBar,
|
||||
isIpOpenPort,
|
||||
isIpHostedDomain,
|
||||
isDomainWhois,
|
||||
isDomainDnsRecord,
|
||||
isCryptocurrencyEventList,
|
||||
isAppBasicInfo,
|
||||
isAppRelatedDomain,
|
||||
isBlock,
|
||||
isAlarmInfo,
|
||||
isDetectionSecurity,
|
||||
isDetectionService
|
||||
isBlock
|
||||
} from './charts/tools'
|
||||
import { tableTitleMapping, legendMapping } from '@/views/charts/charts/chart-table-title'
|
||||
import { replaceUrlPlaceholder } from '@/utils/tools'
|
||||
@@ -102,7 +97,11 @@ export default {
|
||||
timeFilter: Object, // 时间范围
|
||||
isFullscreen: Boolean,
|
||||
panelLock: Boolean,
|
||||
entity: Object
|
||||
entity: Object,
|
||||
showHeader: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
@@ -150,7 +149,15 @@ export default {
|
||||
}
|
||||
] // table的所有数据
|
||||
},
|
||||
tabHandleClickType: ''
|
||||
table: {
|
||||
pageSize: chartTableDefaultPageSize,
|
||||
limit: chartTableTopOptions[0], // top-n
|
||||
orderBy: 'sessions',
|
||||
tableColumns: [], // table字段
|
||||
tableData: [], // table的所有数据
|
||||
currentPageData: [] // table当前页的数据
|
||||
},
|
||||
tabHandleClickType:''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -159,41 +166,26 @@ export default {
|
||||
},
|
||||
headerHPadding () {
|
||||
return this.$store.getters.getHeaderHPadding
|
||||
},
|
||||
showHeader () {
|
||||
return this.chartInfo.params && this.chartInfo.params.showHeader
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/* 参数 extraParams 额外请求参数 */
|
||||
getChartData (url, extraParams = {}, chartTimeFilter, num) {
|
||||
/* 参数 extraParams 额外请求参数,isRefresh 是否是刷新 */
|
||||
getChartData (url, extraParams = {}, isRefresh, chartTimeFilter) {
|
||||
const vm = this
|
||||
this.loading = true
|
||||
this.standaloneTimeRange.use = !!isRefresh
|
||||
try {
|
||||
// 单个图表刷新时,使用单独的时间
|
||||
if (chartTimeFilter) {
|
||||
// 图表自带timeFilter刷新时
|
||||
this.queryTimeRange = { startTime: getSecond(chartTimeFilter.startTime), endTime: getSecond(chartTimeFilter.endTime), dateRangeValue: chartTimeFilter.dateRangeValue }
|
||||
this.queryTimeRange = { startTime: getSecond(chartTimeFilter.startTime), endTime: getSecond(chartTimeFilter.endTime) }
|
||||
} else if (this.standaloneTimeRange.use) {
|
||||
// 单个图表刷新时,使用单独的时间
|
||||
this.queryTimeRange = { startTime: getSecond(this.standaloneTimeRange.startTime), endTime: getSecond(this.standaloneTimeRange.endTime), dateRangeValue: this.timeFilter.dateRangeValue }
|
||||
this.queryTimeRange = { startTime: getSecond(this.standaloneTimeRange.startTime), endTime: getSecond(this.standaloneTimeRange.endTime) }
|
||||
} else if (this.timeFilter) {
|
||||
this.queryTimeRange = { startTime: getSecond(this.timeFilter.startTime), endTime: getSecond(this.timeFilter.endTime), dateRangeValue: this.timeFilter.dateRangeValue }
|
||||
this.queryTimeRange = { startTime: getSecond(this.timeFilter.startTime), endTime: getSecond(this.timeFilter.endTime) }
|
||||
} else {
|
||||
this.queryTimeRange = { startTime: getSecond(this.chartTimeFilter.startTime), endTime: getSecond(this.chartTimeFilter.endTime), dateRangeValue: this.chartTimeFilter.dateRangeValue }
|
||||
this.queryTimeRange = { startTime: getSecond(this.chartTimeFilter.startTime), endTime: getSecond(this.chartTimeFilter.endTime) }
|
||||
}
|
||||
const chartParams = this.chartInfo.params
|
||||
if (this.isAlarmInfo && JSON.stringify(extraParams) === '{}') {
|
||||
extraParams = {
|
||||
pageNo: 1,
|
||||
pageSize: 9
|
||||
}
|
||||
}
|
||||
if (this.isDetectionService || this.isDetectionSecurity) {
|
||||
extraParams = {
|
||||
pageNo: 1,
|
||||
pageSize: 6
|
||||
}
|
||||
}
|
||||
// 接口查询参数
|
||||
this.queryParams = {
|
||||
...this.handleQueryParams(),
|
||||
@@ -206,9 +198,34 @@ export default {
|
||||
if (requestUrl && requestUrl.indexOf('dnsServerRole') > -1) {
|
||||
this.queryParams.dnsServerRole = extraParams.dnsServerRole || dnsServerRole.RTDNS
|
||||
}
|
||||
|
||||
if (requestUrl) {
|
||||
get(replaceUrlPlaceholder(requestUrl, this.queryParams)).then(response => {
|
||||
// if (this.chartInfo.type === 23 && testData) {
|
||||
// response = testData.data
|
||||
// } else if (this.chartInfo.type === 24 && testData) {
|
||||
// response = testData.data2
|
||||
// }
|
||||
if (this.chartInfo.type === 3) {
|
||||
response = {
|
||||
code: 200,
|
||||
data: {
|
||||
result: [
|
||||
{
|
||||
dnsServerRole: extraParams.dnsServerRole || dnsServerRole.RTDNS,
|
||||
ipLocationCountry: 'China',
|
||||
ipLocationId: 'CN',
|
||||
count: 161
|
||||
},
|
||||
{
|
||||
dnsServerRole: extraParams.dnsServerRole || dnsServerRole.RTDNS,
|
||||
ipLocationCountry: 'Japan',
|
||||
ipLocationId: 'JP',
|
||||
count: 222
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
if (response.code === 200) {
|
||||
if (Array.isArray(response.data.result)) {
|
||||
response.data.result.forEach(item => {
|
||||
@@ -219,7 +236,7 @@ export default {
|
||||
}
|
||||
this.chartData = response.data.result
|
||||
this.resultType = response.data.resultType
|
||||
if (isEchartsWithStatistics(this.chartInfo.type)) {
|
||||
if (this.chartInfo.type === 12) {
|
||||
const newArr = []
|
||||
_.forEach(this.chartData, function (value, key) {
|
||||
_.forEach(value.values, function (value, key) {
|
||||
@@ -238,19 +255,13 @@ export default {
|
||||
}
|
||||
if (this.isTable) {
|
||||
this.table.tableData = response.data.result
|
||||
this.table.tableColumns = chartParams.columns
|
||||
// this.table.tableColumns = chartParams.columns
|
||||
// this.table.tableColumns = this.getTableTitle(response.data.result)
|
||||
this.table.currentPageData = this.getTargetPageData(1, this.table.pageSize, this.table.tableData)
|
||||
} else if (this.isSingleValue) {
|
||||
if (chartParams && chartParams.dataKey) {
|
||||
if (response.data.result && (response.data.result[chartParams.dataKey] || response.data.result[chartParams.dataKey] === 0)) {
|
||||
this.chartData = response.data.result[chartParams.dataKey]
|
||||
} else if (response.data.result && (response.data.result[chartParams.dataKey + 'Value'] || response.data.result[chartParams.dataKey + 'Value'] === 0)) {
|
||||
this.chartData = {
|
||||
value: response.data.result[chartParams.dataKey + 'Value'],
|
||||
p50: response.data.result[chartParams.dataKey + 'P50'],
|
||||
p90: response.data.result[chartParams.dataKey + 'P90']
|
||||
}
|
||||
} else {
|
||||
this.chartData = null
|
||||
}
|
||||
@@ -263,11 +274,13 @@ export default {
|
||||
this.errorInfo = response.msg || response.message || 'Unknown'
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
setTimeout(() => {
|
||||
this.loading = false
|
||||
}, 200)
|
||||
})
|
||||
} else if (this.isGroup || this.isTabs) {
|
||||
this.$refs.chart.$refs.chart.reload()
|
||||
} else if (this.isBlock) {
|
||||
} else if (this.chartInfo.type === 94) {
|
||||
this.chartInfo.children = [...this.chartInfo.children]
|
||||
} else if (this.chartInfo.type === 95) {
|
||||
if (!this.chartInfo.firstShow) {
|
||||
this.chartInfo.firstShow = true
|
||||
} else {
|
||||
@@ -300,26 +313,15 @@ export default {
|
||||
this.$refs.chart.resize()
|
||||
},
|
||||
refresh (chartTimeFilter) {
|
||||
if (chartTimeFilter) {
|
||||
this.timeFilter.startTime = chartTimeFilter.startTime
|
||||
this.timeFilter.endTime = chartTimeFilter.endTime
|
||||
this.timeFilter.dateRangeValue = chartTimeFilter.dateRangeValue
|
||||
this.getChartData(null, {}, chartTimeFilter)
|
||||
} else {
|
||||
if (this.timeFilter.dateRangeValue && this.timeFilter.dateRangeValue > 0) {
|
||||
const myEndTime = window.$dayJs.tz().valueOf()
|
||||
const myStartTime = myEndTime - this.timeFilter.dateRangeValue * 60 * 1000
|
||||
this.standaloneTimeRange.use = true
|
||||
this.standaloneTimeRange.startTime = myStartTime
|
||||
this.standaloneTimeRange.endTime = myEndTime
|
||||
} else {
|
||||
this.standaloneTimeRange.use = false
|
||||
}
|
||||
this.emitter.emit('chart-pageNo')
|
||||
this.getChartData(null, {})
|
||||
}
|
||||
const myEndTime = window.$dayJs.tz().valueOf()
|
||||
const myStartTime = myEndTime - this.chartTimeFilter.dateRangeValue * 60 * 1000
|
||||
this.standaloneTimeRange.use = true
|
||||
this.standaloneTimeRange.startTime = myStartTime
|
||||
this.standaloneTimeRange.endTime = myEndTime
|
||||
this.emitter.emit('chart-pageNo')
|
||||
this.getChartData(null, {}, true, chartTimeFilter)
|
||||
},
|
||||
tabHandleClick (value) {
|
||||
tabHandleClick(value){
|
||||
this.tabHandleClickType = value
|
||||
},
|
||||
showFullscreen (show) {
|
||||
@@ -394,14 +396,16 @@ export default {
|
||||
mounted () {
|
||||
this.showLoading(true)
|
||||
this.getChartData()
|
||||
this.$store.commit('cleanChartList')
|
||||
// setTimeout(() => {
|
||||
// this.getChartData()
|
||||
// }, 200)
|
||||
},
|
||||
setup (props) {
|
||||
const dateRangeValue = 60
|
||||
const { startTime, endTime } = getNowTime(dateRangeValue)
|
||||
const chartTimeFilter = ref({ startTime, endTime, dateRangeValue })
|
||||
let table = {}
|
||||
if (isBasicTable(props.chartInfo.type)) {
|
||||
if (isTable(props.chartInfo.type)) {
|
||||
table = {
|
||||
pageSize: chartTableDefaultPageSize,
|
||||
limit: chartTableTopOptions[0], // top-n
|
||||
@@ -421,7 +425,7 @@ export default {
|
||||
isEchartsWithStatistics: isEchartsWithStatistics(props.chartInfo.type),
|
||||
isSingleValue: isSingleValue(props.chartInfo.type),
|
||||
isSingleValueWithEcharts: isSingleValueWithEcharts(props.chartInfo.type),
|
||||
isSingleValueWithPercent: isSingleValueWithPercent(props.chartInfo.type),
|
||||
isSingleValueWithEchartsTemp: isSingleValueWithEchartsTemp(props.chartInfo.type),
|
||||
isRelationShip: isRelationShip(props.chartInfo.type),
|
||||
isTable: isTable(props.chartInfo.type),
|
||||
isActiveIpTable: isActiveIpTable(props.chartInfo.type),
|
||||
@@ -435,15 +439,12 @@ export default {
|
||||
isSankey: isSankey(props.chartInfo.type),
|
||||
isIpBasicInfo: isIpBasicInfo(props.chartInfo.type),
|
||||
isIpHostedDomain: isIpHostedDomain(props.chartInfo.type),
|
||||
isIpOpenPortBar: isIpOpenPortBar(props.chartInfo.type),
|
||||
isIpOpenPort: isIpOpenPort(props.chartInfo.type),
|
||||
isDomainWhois: isDomainWhois(props.chartInfo.type),
|
||||
isDomainDnsRecord: isDomainDnsRecord(props.chartInfo.type),
|
||||
isCryptocurrencyEventList: isCryptocurrencyEventList(props.chartInfo.type),
|
||||
isAppBasicInfo: isAppBasicInfo(props.chartInfo.type),
|
||||
isAppRelatedDomain: isAppRelatedDomain(props.chartInfo.type),
|
||||
isAlarmInfo: isAlarmInfo(props.chartInfo.type),
|
||||
isDetectionService: isDetectionService(props.chartInfo.type),
|
||||
isDetectionSecurity: isDetectionSecurity(props.chartInfo.type)
|
||||
isAppRelatedDomain: isAppRelatedDomain(props.chartInfo.type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,9 @@
|
||||
<template>
|
||||
<div style="height: calc(100vh - 70px);width: 100%;" v-if="wholeScreenScroll">
|
||||
<dns-screen v-if="currentPath === wholeScreenRouterMapping.dns"
|
||||
:copy-data-list="copyDataList"
|
||||
ref="dnsScreen"
|
||||
:time-filter="timeFilter"
|
||||
:entity="entity">
|
||||
</dns-screen>
|
||||
</div>
|
||||
<div :id='`chartList${(isGroup ? "Group" : "") + timestamp}`' class="chart-list" ref="layoutBox">
|
||||
<grid-layout
|
||||
ref="layout"
|
||||
v-if="gridLayoutShow"
|
||||
v-model:layout="normalCopyDataList"
|
||||
v-model:layout="copyDataList"
|
||||
:col-num="30"
|
||||
:is-draggable="!panelLock"
|
||||
:is-resizable="!panelLock"
|
||||
@@ -21,7 +13,7 @@
|
||||
:use-css-transforms="false"
|
||||
>
|
||||
<grid-item
|
||||
v-for="item in normalCopyDataList"
|
||||
v-for="item in copyDataList"
|
||||
:key="item.id"
|
||||
:h="item.h"
|
||||
:i="item.i"
|
||||
@@ -30,7 +22,7 @@
|
||||
:y="item.y"
|
||||
:static="item.static"
|
||||
:ref="'grid-item' + item.id"
|
||||
:isResizable="isGroup ? false: null"
|
||||
:isResizable = "item.type === 'group' ? false: null"
|
||||
dragAllowFrom=".chart-header"
|
||||
dragIgnoreFrom=".chart-header__tools"
|
||||
v-bind="anchorPoint(item)"
|
||||
@@ -38,6 +30,7 @@
|
||||
<panel-chart
|
||||
:ref="'chart' + item.id"
|
||||
:chart-info="item"
|
||||
:show-header="true"
|
||||
:time-filter="timeFilter"
|
||||
:entity="entity"
|
||||
@groupShow="groupShow"
|
||||
@@ -73,24 +66,19 @@
|
||||
<script>
|
||||
import PanelChart from '@/views/charts/PanelChart'
|
||||
import VueGridLayout from 'vue-grid-layout'
|
||||
import { getGroupHeight, getTypeCategory, isGroup } from './charts/tools'
|
||||
import { getGroupHeight, getTypeCategory } from './charts/tools'
|
||||
import _ from 'lodash'
|
||||
import { useRouter } from 'vue-router'
|
||||
import DnsScreen from '@/views/charts/wholeScreenScroll/DnsScreen'
|
||||
import { wholeScreenRouterMapping } from '@/utils/constants'
|
||||
|
||||
export default {
|
||||
name: 'PanelChartList',
|
||||
components: {
|
||||
PanelChart,
|
||||
DnsScreen,
|
||||
GridLayout: VueGridLayout.GridLayout,
|
||||
GridItem: VueGridLayout.GridItem
|
||||
},
|
||||
props: {
|
||||
timeFilter: Object, // 时间范围
|
||||
panelLock: { type: Boolean, default: true },
|
||||
wholeScreenScroll: { type: Boolean, default: false },
|
||||
isGroup: Boolean,
|
||||
entity: Object,
|
||||
dataList: Array // 看板中所有图表信息
|
||||
@@ -100,8 +88,7 @@ export default {
|
||||
gridLayoutLoading: false,
|
||||
gridLayoutShow: false,
|
||||
rowHeight: 40,
|
||||
copyDataList: [], // 所有的图表
|
||||
normalCopyDataList: [], // 非整屏滚动的图表
|
||||
copyDataList: [],
|
||||
noData: false, // no data
|
||||
tempDom: { height: '', width: '' },
|
||||
stepWidth: null,
|
||||
@@ -113,8 +100,7 @@ export default {
|
||||
chartInfo: {}
|
||||
},
|
||||
scrollTop: 0,
|
||||
scrollTopTimer: null,
|
||||
wholeScreenRouterMapping
|
||||
scrollTopTimer: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -126,12 +112,8 @@ export default {
|
||||
},
|
||||
reload () {
|
||||
this.copyDataList.forEach(item => {
|
||||
if (this.$refs['chart' + item.id]) {
|
||||
this.$refs['chart' + item.id].getChartData()
|
||||
}
|
||||
this.$refs['chart' + item.id].getChartData()
|
||||
})
|
||||
|
||||
this.$refs.dnsScreen.reload()
|
||||
},
|
||||
showFullscreen (show, chartInfo) {
|
||||
this.fullscreen.chartInfo = chartInfo
|
||||
@@ -144,14 +126,11 @@ export default {
|
||||
if (item.params.collapse) {
|
||||
item.h = 1
|
||||
} else {
|
||||
item.h = getGroupHeight(item.children) + 0.4 + 1
|
||||
item.h = getGroupHeight(item.children) + 1.5
|
||||
}
|
||||
}
|
||||
})
|
||||
this.copyDataList = [...this.copyDataList]
|
||||
this.normalCopyDataList = this.copyDataList.filter(function (item) {
|
||||
return item.y >= -1
|
||||
})
|
||||
this.emitter.emit('groupParentCalcHeight', { chart, childrenList: this.copyDataList })
|
||||
},
|
||||
groupParentCalcHeight (chart, childrenList) {
|
||||
@@ -160,16 +139,17 @@ export default {
|
||||
const children = parent.children.find(item => item.id === chart.id)
|
||||
children.h = chart.h
|
||||
children.params = chart.params
|
||||
// 第二个是空隙,第三个是标题的高度
|
||||
parent.h = getGroupHeight(childrenList) + 0.4 + 1
|
||||
this.copyDataList = [...this.copyDataList]
|
||||
this.normalCopyDataList = this.copyDataList.filter(function (item) {
|
||||
return item.y >= -1
|
||||
let sumGroup = 0
|
||||
childrenList.forEach(item => {
|
||||
if (item.type === 94) {
|
||||
sumGroup++
|
||||
}
|
||||
})
|
||||
parent.h = getGroupHeight(childrenList) + sumGroup * 0.5
|
||||
this.copyDataList = [...this.copyDataList]
|
||||
}, 100)
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
anchorPoint () {
|
||||
return function (chart) {
|
||||
@@ -181,12 +161,6 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
setup (props) {
|
||||
const { currentRoute } = useRouter()
|
||||
return {
|
||||
currentPath: currentRoute.value.path
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
dataList: {
|
||||
deep: true,
|
||||
@@ -214,20 +188,25 @@ export default {
|
||||
})
|
||||
this.$nextTick(() => {
|
||||
this.copyDataList = JSON.parse(JSON.stringify(tempList))
|
||||
this.normalCopyDataList = this.copyDataList.filter(function (item) {
|
||||
return item.y >= -1
|
||||
})
|
||||
setTimeout(() => {
|
||||
this.gridLayoutShow = true
|
||||
})
|
||||
setTimeout(() => {
|
||||
this.copyDataList.forEach(item => {
|
||||
if (isGroup(item.type) && !item.firstShow) {
|
||||
// if (item.type === 95) {
|
||||
// console.log(item.h, item.name)
|
||||
// item.children.forEach(children => {
|
||||
// console.log(children.name, children.h, children.y)
|
||||
// })
|
||||
// let parentH = 1.5
|
||||
// parentH += getGroupHeight(item.children)
|
||||
// if (parentH !== item.h) {
|
||||
// item.h = parentH
|
||||
// }
|
||||
// }
|
||||
if (item.type === 94 && !item.firstShow) {
|
||||
item.firstShow = true
|
||||
this.copyDataList = [...this.copyDataList]
|
||||
this.normalCopyDataList = this.copyDataList.filter(function (item) {
|
||||
return item.y >= -1
|
||||
})
|
||||
this.emitter.emit('groupParentCalcHeight', { chart: item, childrenList: this.copyDataList })
|
||||
}
|
||||
})
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
v-for="(c, i) in table.tableColumns"
|
||||
show-overflow-tooltip
|
||||
:key="i"
|
||||
:label="c"
|
||||
:label="$t(chartTableOrderOptionsMapping[c])"
|
||||
:prop="c"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
|
||||
@@ -1,107 +1,85 @@
|
||||
<template>
|
||||
<div class="cn-chart__alarm-info">
|
||||
<div class="no-data" v-if="isNoData">No data</div>
|
||||
<template v-else>
|
||||
<div class="alarm-info__box">
|
||||
<div
|
||||
class="box__body"
|
||||
v-for="(value, index) in chartData ? chartData : []"
|
||||
:key="index"
|
||||
>
|
||||
<div class="body__content">
|
||||
<div class="content__icon-box">
|
||||
<div
|
||||
class="icon-box__icon"
|
||||
:style="{
|
||||
background: eventSeverityColor[value.eventSeverity],
|
||||
opacity: 0.1,
|
||||
}"
|
||||
></div>
|
||||
<i
|
||||
class="cn-icon cn-icon-alert"
|
||||
:style="{
|
||||
color: eventSeverityColor[value.eventSeverity],
|
||||
opacity: 1,
|
||||
}"
|
||||
></i>
|
||||
<div class="cn-chart-alarm-info">
|
||||
<div class="cn-chart-alarm-info-mainContent">
|
||||
<div
|
||||
class="cn-chart-alarm-content"
|
||||
v-for="(value, index) in chartData"
|
||||
:key="index"
|
||||
>
|
||||
<div class="cn-alarm-info-main">
|
||||
<div class="cn-alarm-info-main-left">
|
||||
<div
|
||||
class="cn-chart-alarm-info-icon"
|
||||
:style="{
|
||||
background: eventSeverityColor[value.eventSeverity],
|
||||
opacity: 0.1,
|
||||
}"
|
||||
></div>
|
||||
<i
|
||||
class="cn-icon cn-icon-alert"
|
||||
:style="{
|
||||
color: eventSeverityColor[value.eventSeverity],
|
||||
opacity: 1,
|
||||
}"
|
||||
></i>
|
||||
</div>
|
||||
<div class="cn-alarm-info-textContent">
|
||||
<div class="cn-alarm-info-main-title">
|
||||
<!-- <span v-if="value.entityType === 'domain'">{{ value.domain }}</span>
|
||||
<span v-if="value.entityType === 'app'">{{ value.appName }}</span>
|
||||
<span v-if="value.entityType === 'ip'">{{ value.serverIp }}</span> -->
|
||||
111.111.1.1
|
||||
</div>
|
||||
|
||||
<div class="cn-alarm-info-bottom">
|
||||
<div
|
||||
class="cn-alarm-info-bottom-type"
|
||||
:style="{ 'color': eventSeverityColor[value.eventSeverity] ,'border-color':eventSeverityColor[value.eventSeverity]}"
|
||||
>
|
||||
<!-- {{$t(`${value.eventType}`)}} -->
|
||||
{{ value.eventType }}
|
||||
</div>
|
||||
<div class="content__text-box">
|
||||
<div class="text-box__title">
|
||||
<div v-if="value.entityType === 'domain'" :title="value.domain">
|
||||
<span>{{ value.domain }}</span>
|
||||
</div>
|
||||
<div v-if="value.entityType === 'app'" :title="value.appName">
|
||||
<span>{{ value.appName }}</span>
|
||||
</div>
|
||||
<div v-if="value.entityType === 'ip'" :title="value.serverIp">
|
||||
<span>{{ value.serverIp }}</span>
|
||||
</div>
|
||||
|
||||
<div class="cn-alarm-info-bottom-middle">
|
||||
<i class="cn-icon cn-icon-time2"></i>
|
||||
|
||||
<div class="cn-alarm-info-bottom-time">
|
||||
{{ $t(`dns.startTime`) }}:
|
||||
</div>
|
||||
<div>{{ changeDate(value.startTime) }}</div>
|
||||
</div>
|
||||
|
||||
<div class="cn-alarm-info-bottom-right">
|
||||
<i class="cn-icon cn-icon-time2"></i>
|
||||
<div class="cn-alarm-info-bottom-time">
|
||||
{{ $t(`dns.duration`) }}:
|
||||
</div>
|
||||
|
||||
<div class="text-box__text">
|
||||
<div
|
||||
class="text__type"
|
||||
:style="{
|
||||
color: eventSeverityColor[value.eventSeverity],
|
||||
'border-color': eventSeverityColor[value.eventSeverity],
|
||||
}"
|
||||
:title="value.eventType"
|
||||
>
|
||||
{{ value.eventType }}
|
||||
</div>
|
||||
<div class="text__time-box">
|
||||
<i class="cn-icon cn-icon-time2"></i>
|
||||
|
||||
<div class="time-box__start-time">
|
||||
{{ $t(`dns.startTime`) }}:
|
||||
</div>
|
||||
<div>
|
||||
{{
|
||||
value.startTime
|
||||
? dayJs
|
||||
.tz(getMillisecond(value.startTime))
|
||||
.format('YYYY-MM-DD HH:mm:ss')
|
||||
: '-'
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="text__duration-box">
|
||||
<i class="cn-icon cn-icon-time2"></i>
|
||||
<div class="time-box__start-time">
|
||||
{{ $t(`dns.duration`) }}:
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="duration-box__circle"
|
||||
:style="{
|
||||
background: eventSeverityColor[value.eventSeverity],
|
||||
}"
|
||||
></div>
|
||||
|
||||
<div>
|
||||
{{
|
||||
unitConvert(value.endTime - value.startTime, 'time').join(
|
||||
' ',
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="cn-alarm-info-bottom-circle"
|
||||
:style="{ background: eventSeverityColor[value.eventSeverity] }"
|
||||
></div>
|
||||
|
||||
<div>
|
||||
{{
|
||||
unitConvert(value.endTime - value.startTime, 'time').join(' ')
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<chart-table-pagination
|
||||
ref="tablePagination"
|
||||
class="alarm-info__pagination"
|
||||
:total="alarmInfoCount.result"
|
||||
:pageSizeForAlarm="pageSizeForAlarm"
|
||||
v-model:currentPage="pageNo"
|
||||
@pageJump="pageJump"
|
||||
></chart-table-pagination>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<chart-table-pagination
|
||||
ref="tablePagination"
|
||||
class="cn-chart-alarm-info-pagination"
|
||||
:total="alarmInfoCount.result"
|
||||
:pageSizeForAlarm="pageSizeForAlarm"
|
||||
v-model:currentPage="pageNo"
|
||||
@pageJump="pageJump"
|
||||
></chart-table-pagination>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -111,8 +89,6 @@ import _ from 'lodash'
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
import ChartTablePagination from '@/views/charts/charts/ChartTablePagination'
|
||||
import { get } from '@/utils/http'
|
||||
import { getMillisecond } from '@/utils/date-util'
|
||||
import { api } from '@/utils/api'
|
||||
|
||||
export default {
|
||||
name: 'isAlarmInfo',
|
||||
@@ -120,119 +96,65 @@ export default {
|
||||
chartInfo: Object,
|
||||
chartData: [Array, Object],
|
||||
tabHandleClickType: String,
|
||||
queryParams: Object
|
||||
},
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
pageSizeForAlarm: 9,
|
||||
eventSeverityColor: eventSeverityColor,
|
||||
pageNo: 1,
|
||||
alarmInfoCount: {},
|
||||
fromChartData: '',
|
||||
isNoData: false
|
||||
// result: [
|
||||
// {
|
||||
// entityType: 'ip',
|
||||
// serverIp: '1.2.3.41.2.3.41.2.3.41.2.3.41.2.3.41.2.3.4',
|
||||
// domain: '',
|
||||
// appName: 'wechat',
|
||||
// eventSeverity: 'high',
|
||||
// eventType: 'type',
|
||||
// startTime: 1111111111,
|
||||
// durationMs: 60000,
|
||||
// endTime: 1111111112,
|
||||
// },
|
||||
// ],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isNoData () {
|
||||
let isNoData = true
|
||||
if (!this.$_.isEmpty(this.chartData)) {
|
||||
isNoData = false
|
||||
}
|
||||
return isNoData
|
||||
alarmInfoCount: {
|
||||
|
||||
},
|
||||
fromChartData:''
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
tabHandleClickType: {
|
||||
deep: true,
|
||||
handler (n) {
|
||||
this.$nextTick(() => {
|
||||
this.getData(1, n)
|
||||
})
|
||||
}
|
||||
handler(n) {
|
||||
this.getData(1,n)
|
||||
},
|
||||
},
|
||||
alarmInfoCount: {
|
||||
deep: true,
|
||||
handler (n) {}
|
||||
},
|
||||
queryParams: {
|
||||
deep: true,
|
||||
handler (n) {
|
||||
if (n.startTime && n.endTime) {
|
||||
this.getCount(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.getData(1,'All')
|
||||
},
|
||||
components: {
|
||||
ChartTablePagination
|
||||
ChartTablePagination,
|
||||
},
|
||||
methods: {
|
||||
unitConvert,
|
||||
getMillisecond,
|
||||
getCount () {
|
||||
const countQuery = {
|
||||
startTime: this.queryParams.startTime,
|
||||
endTime: this.queryParams.endTime,
|
||||
eventSeverity:
|
||||
this.tabHandleClickType === 'All' ? '' : this.tabHandleClickType
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
get(api.dashboard.DnsServiceInsights.alarmInfoCount, {
|
||||
...countQuery
|
||||
}).then((response) => {
|
||||
if (response.code === 200) {
|
||||
this.alarmInfoCount = response.data
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
getData (val, n) {
|
||||
getData(val,n) {
|
||||
this.pageNo = val
|
||||
const now = window.$dayJs.tz().valueOf()
|
||||
const extraParams = {
|
||||
pageNo: val,
|
||||
pageSize: this.pageSizeForAlarm,
|
||||
eventSeverity: n
|
||||
? n === 'All'
|
||||
? ''
|
||||
: n
|
||||
: this.tabHandleClickType === 'All'
|
||||
? ''
|
||||
: this.tabHandleClickType
|
||||
eventSeverity: n? (n==='All'?'':n ): this.tabHandleClickType === 'All'?'':this.tabHandleClickType
|
||||
}
|
||||
const query = {
|
||||
startTime: this.queryParams.startTime,
|
||||
endTime: this.queryParams.endTime,
|
||||
console.log('extraParams',extraParams);
|
||||
this.$emit('getAlarmInfo', null, extraParams)
|
||||
const queryParams = {
|
||||
startTime: Math.floor(now / 1000 - 3600),
|
||||
endTime: Math.floor(now / 1000),
|
||||
eventSeverity:
|
||||
this.tabHandleClickType === 'All' ? '' : this.tabHandleClickType
|
||||
this.tabHandleClickType === 'All' ? '' : this.tabHandleClickType,
|
||||
}
|
||||
this.$emit('getAlarmInfo', null, extraParams, false, {
|
||||
startTime: query.startTime,
|
||||
endTime: query.endTime
|
||||
})
|
||||
get(api.dashboard.DnsServiceInsights.alarmInfoCount, {
|
||||
...query
|
||||
|
||||
get('/interface/dns/alarmInfoCount', {
|
||||
...queryParams,
|
||||
}).then((response) => {
|
||||
if (response.code === 200) {
|
||||
this.alarmInfoCount = response.data
|
||||
}
|
||||
})
|
||||
},
|
||||
pageJump (val) {
|
||||
changeDate(value) {
|
||||
return window.$dayJs.tz(value).format('YYYY-MM-DD HH:mm:ss')
|
||||
},
|
||||
pageJump(val) {
|
||||
this.getData(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
<div style="display: flex; justify-content: space-between; width: 100%;">
|
||||
<el-descriptions :column="1" style="padding: 20px 30px;">
|
||||
<el-descriptions-item :label="$t('overall.appName') + ':'">{{$_.get(chartData, "name") || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('overall.appFullName') + ':'">{{$_.get(chartData, "appLongname") || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('overall.technology') + ':'">{{$_.get(chartData, "appTechnology") || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('overall.remark') + ':'">{{$_.get(chartData, "appDescription") || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('overall.appFullName') + ':'">{{$_.get(chartData, "allName") || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('overall.technology') + ':'">{{$_.get(chartData, "tech") || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('overall.remark') + ':'">{{$_.get(chartData, "description") || '-'}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div class="cn-chart__body-single">
|
||||
<div class="cn-chart__body-single-table">
|
||||
@@ -15,10 +15,10 @@
|
||||
</div>
|
||||
<div class="single-value__content">
|
||||
<div>
|
||||
<span style="color: #666;">{{$t('entities.category')}}</span>
|
||||
<span>{{$t('entities.category')}}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span style="color: #333; font-weight: bold;">{{$_.get(chartData, "category") || '-'}}</span>
|
||||
<span>{{$_.get(chartData, "category") || '-'}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -28,10 +28,10 @@
|
||||
</div>
|
||||
<div class="single-value__content">
|
||||
<div>
|
||||
<span style="color: #666;">{{$t('entities.subcategory')}}</span>
|
||||
<span>{{$t('entities.subcategory')}}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span style="color: #333; font-weight: bold;">{{$_.get(chartData, "subcategory") || '-'}}</span>
|
||||
<span>{{$_.get(chartData, "subcategory") || '-'}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -41,10 +41,10 @@
|
||||
</div>
|
||||
<div class="single-value__content">
|
||||
<div>
|
||||
<span style="color: #666;">{{$t('entities.reputationLevel')}}</span>
|
||||
<span>{{$t('entities.reputationLevel')}}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span style="color: #333; font-weight: bold;">{{$_.get(chartData, "risk") || '-'}}</span>
|
||||
<span>{{$_.get(chartData, "risk") || '-'}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,36 +10,30 @@
|
||||
|
||||
<script>
|
||||
import chartMixin from '@/views/charts/charts/chart-mixin'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'ChartBlock',
|
||||
mixins: [chartMixin],
|
||||
props: {
|
||||
timeFilter: Object
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
dataList: [],
|
||||
time: {},
|
||||
firstShow: false
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.dataList = JSON.parse(JSON.stringify(this.chartInfo.children))
|
||||
// this.time = JSON.parse(JSON.stringify(this.timeFilter))
|
||||
this.firstShow = true
|
||||
},
|
||||
methods: {
|
||||
reload () {
|
||||
this.dataList = _.cloneDeep(this.dataList)
|
||||
}
|
||||
},
|
||||
setup (props) {
|
||||
const copyAndSort = dataList => {
|
||||
const list = _.cloneDeep(dataList)
|
||||
return list.sort((data1, data2) => {
|
||||
return data1.x - data2.x
|
||||
})
|
||||
}
|
||||
const dataList = copyAndSort(props.chartInfo.children)
|
||||
return {
|
||||
copyAndSort,
|
||||
dataList
|
||||
console.log(123132)
|
||||
this.dataList = JSON.parse(JSON.stringify(this.chartInfo.children))
|
||||
// this.time = JSON.parse(JSON.stringify(this.timeFilter))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
<template>
|
||||
<div style="overflow-y: auto; height: 100%; color: #555; white-space: pre;">{{linuxLineSymbolConvert}}</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ChartDomainRecursiveResolve',
|
||||
props: {
|
||||
chartInfo: Object,
|
||||
chartData: String,
|
||||
resultType: Object,
|
||||
queryParams: Object
|
||||
},
|
||||
computed: {
|
||||
linuxLineSymbolConvert () {
|
||||
return this.chartData ? this.chartData.replaceAll(/\n/g, '\r\n') : ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -4,27 +4,26 @@
|
||||
|
||||
<script>
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
import { lineToSpace, reverseSortBy, humpToSpace } from '@/utils/tools'
|
||||
import * as echarts from 'echarts'
|
||||
import { lineToSpace } from '@/utils/tools'
|
||||
import { unitTypes } from '@/utils/constants'
|
||||
import chartEchartMixin from './chart-echart-mixin'
|
||||
import { isEchartsLine, isEchartsPie } from './tools'
|
||||
import { getOption, isEchartsPie } from './tools'
|
||||
import { legendMapping } from '@/views/charts/charts/chart-table-title'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'ChartEchart',
|
||||
mixins: [chartEchartMixin],
|
||||
data () {
|
||||
return {}
|
||||
return {
|
||||
}
|
||||
},
|
||||
props: {
|
||||
resultType: Object,
|
||||
chartInfo: Object
|
||||
resultType: Object
|
||||
},
|
||||
setup (props) {
|
||||
return {
|
||||
isEchartsPie: isEchartsPie(props.chartInfo.type),
|
||||
isEchartsLine: isEchartsLine(props.chartInfo.type)
|
||||
isEchartsPie: isEchartsPie(props.chartInfo.type)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -37,303 +36,47 @@ export default {
|
||||
this.handleYaxis()
|
||||
|
||||
if (this.isEchartsPie) {
|
||||
if (chartParams.size && chartParams.size === 'small') {
|
||||
this.chartOption.series[0] = {
|
||||
...this.chartOption.series[0],
|
||||
radius: ['30%', '45%'],
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
}
|
||||
this.chartOption.series[0].data = this.chartData.map(d => {
|
||||
return {
|
||||
name: lineToSpace(d.name),
|
||||
data: d,
|
||||
value: parseInt(d.num),
|
||||
unitType: chartParams.unitType ? chartParams.unitType : 'number'
|
||||
}
|
||||
this.chartOption.legend = {
|
||||
...this.chartOption.legend,
|
||||
left: '60%',
|
||||
itemGap: 5,
|
||||
itemWidth: 8,
|
||||
itemHeight: 8,
|
||||
formatter: function (name) {
|
||||
return name.length > 9 ? name.substr(0, 9) + '...' : name
|
||||
// return echarts.format.truncateText(name, 6, '…');
|
||||
},
|
||||
tooltip: {
|
||||
show: true
|
||||
},
|
||||
textStyle: {
|
||||
// 图例文字的样式
|
||||
color: '#666666',
|
||||
fontSize: 12,
|
||||
fontWeight: 400
|
||||
}
|
||||
}
|
||||
let chartDataTmp = []
|
||||
let otherData = []
|
||||
this.chartData.sort(reverseSortBy('num'))
|
||||
|
||||
if (this.chartData.length > 5) {
|
||||
chartDataTmp = this.chartData.slice(0, 5)
|
||||
chartDataTmp.forEach((data) => {
|
||||
if (data.name === '') {
|
||||
data.name = ' '
|
||||
}
|
||||
})
|
||||
let otherSum = 0
|
||||
otherData = this.chartData.slice(5)
|
||||
otherData.forEach((data) => {
|
||||
otherSum = otherSum + data.num
|
||||
})
|
||||
chartDataTmp.push({ num: otherSum, name: 'other' })
|
||||
} else if (this.chartData.length <= 5) {
|
||||
chartDataTmp = this.chartData.slice(0, this.chartData.length)
|
||||
chartDataTmp.forEach((data) => {
|
||||
if (data.name === '') {
|
||||
data.name = ' '
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.chartOption.series[0].data = chartDataTmp.map((d) => {
|
||||
return {
|
||||
name: lineToSpace(d.name),
|
||||
data: d,
|
||||
value: parseInt(d.num),
|
||||
unitType: chartParams.unitType ? chartParams.unitType : 'number'
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.chartOption.series[0].data = this.chartData.map((d) => {
|
||||
return {
|
||||
name: lineToSpace(d.name),
|
||||
data: d,
|
||||
value: parseInt(d.num),
|
||||
unitType: chartParams.unitType ? chartParams.unitType : 'number'
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
const seriesTemplate = this.chartOption.series[0]
|
||||
this.chartOption.series = this.chartData.map((r) => {
|
||||
const serie = {
|
||||
this.chartOption.series = this.chartData.map(r => {
|
||||
return {
|
||||
...seriesTemplate,
|
||||
name: legendMapping[
|
||||
`${this.entity && this.entity.ip ? 'ip_' : ''}${r.legend}`
|
||||
]
|
||||
? legendMapping[
|
||||
`${this.entity && this.entity.ip ? 'ip_' : ''}${r.legend}`
|
||||
]
|
||||
: humpToSpace(r.legend),
|
||||
data: r.values.map((v) => [
|
||||
Number(v[0]) * 1000,
|
||||
Number(v[1]),
|
||||
chartParams.unitType
|
||||
])
|
||||
name: legendMapping[`${this.entity && this.entity.ip ? 'ip_' : ''}${r.legend}`] ? legendMapping[`${this.entity && this.entity.ip ? 'ip_' : ''}${r.legend}`] : lineToSpace(r.legend),
|
||||
data: r.values.map(v => [Number(v[0]) * 1000, Number(v[1]), chartParams.unitType])
|
||||
}
|
||||
if (this.isEchartsLine) {
|
||||
serie.data = serie.data.slice(1, serie.data.length - 2)
|
||||
if (this.chartData.length === 1) { // 只有一条曲线
|
||||
if (!_.isNaN(parseFloat(this.chartData[0].aggregation.p50)) && !_.isNaN(parseFloat(this.chartData[0].aggregation.p90))) {
|
||||
serie.markLine = {
|
||||
silent: true,
|
||||
symbol: 'none',
|
||||
label: {
|
||||
distance: [-50, 0],
|
||||
formatter (params) {
|
||||
const arr = unitConvert(Number(params.value), chartParams.unitType).join(' ')
|
||||
let desc = ''
|
||||
switch (params.dataIndex) {
|
||||
case 0: {
|
||||
desc = 'P50'
|
||||
break
|
||||
}
|
||||
case 1: {
|
||||
desc = 'P90'
|
||||
break
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
return `${arr} (${desc})`
|
||||
}
|
||||
},
|
||||
data: [
|
||||
{
|
||||
name: 'P50',
|
||||
yAxis: this.chartData[0].aggregation.p50
|
||||
},
|
||||
{
|
||||
name: 'P90',
|
||||
yAxis: this.chartData[0].aggregation.p90
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
} else if (this.chartData.length > 1) { // 有多条曲线
|
||||
this.handleLegendClick()// 自定义legend的点击事件
|
||||
}
|
||||
}
|
||||
return serie
|
||||
})
|
||||
}
|
||||
|
||||
const rows = (this.chartData.length - 1) / 4 + 1 // 根据legend个数动态预留legend空间
|
||||
const gridTop = 10 + 27 * rows
|
||||
|
||||
const gridTemplate = this.chartOption.grid
|
||||
// option中默认单位是数字,当单位是字节、百分比、时间时,额外处理
|
||||
if (chartParams.unitType === unitTypes.byte) {
|
||||
this.chartOption.yAxis.axisLabel.formatter = function (value) {
|
||||
return unitConvert(value, unitTypes.byte).join('')
|
||||
this.chartOption.yAxis.axisLabel.formatter = function (value, index, a, b) {
|
||||
return unitConvert(value, unitTypes.byte).join(' ')
|
||||
}
|
||||
this.chartOption.grid = {
|
||||
...gridTemplate,
|
||||
top: gridTop,
|
||||
left: 75
|
||||
}
|
||||
} else if (chartParams.unitType === unitTypes.percent) {
|
||||
this.chartOption.yAxis.axisLabel.formatter = function (value) {
|
||||
return unitConvert(value, unitTypes.percent).join('')
|
||||
}
|
||||
} else if (chartParams.unitType === unitTypes.time) {
|
||||
this.chartOption.yAxis.axisLabel.formatter = function (value) {
|
||||
return unitConvert(value, unitTypes.time).join('')
|
||||
}
|
||||
}
|
||||
|
||||
if (chartParams.showLegend) {
|
||||
const rows = (this.chartData.length - 1) / 4 + 1 // 根据legend个数动态预留legend空间
|
||||
} else {
|
||||
this.chartOption.grid = {
|
||||
...this.chartOption.grid,
|
||||
top: 10 + 27 * rows
|
||||
...gridTemplate,
|
||||
top: gridTop
|
||||
}
|
||||
}
|
||||
|
||||
this.loadEchart()
|
||||
},
|
||||
|
||||
// 点击前,高亮legend个数
|
||||
getSelectedNum (params) {
|
||||
let selectedNum = 0
|
||||
const legendItem = params.selected
|
||||
for (const name in legendItem) {
|
||||
if (name === params.name) {
|
||||
if (!legendItem[name]) {
|
||||
selectedNum = selectedNum + 1
|
||||
}
|
||||
} else {
|
||||
if (legendItem[name]) {
|
||||
selectedNum = selectedNum + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return selectedNum
|
||||
},
|
||||
// 点击后:高亮legend个数
|
||||
getAfterSelectedNum (params) {
|
||||
let selectedNum = 0
|
||||
const legendItem = params.selected
|
||||
for (const name in legendItem) {
|
||||
if (legendItem[name]) {
|
||||
selectedNum = selectedNum + 1
|
||||
}
|
||||
}
|
||||
return selectedNum
|
||||
},
|
||||
|
||||
// 自定义legend的点击事件:此方法只处理多条曲线的情况(单条曲线正常切换legend和曲线)
|
||||
handleLegendClick () {
|
||||
const self = this
|
||||
// legend点击事件
|
||||
this.myChart.off('legendselectchanged')
|
||||
this.myChart.on('legendselectchanged', function (params) {
|
||||
const legendNum = Object.keys(params.selected).length
|
||||
const selectedNum = self.getSelectedNum(params)
|
||||
|
||||
const legendItem = params.selected
|
||||
if (selectedNum === legendNum) { // 点击前:全部曲线高亮
|
||||
for (const name in legendItem) {
|
||||
if (name === params.name) {
|
||||
legendItem[name] = true
|
||||
} else {
|
||||
legendItem[name] = false
|
||||
}
|
||||
}
|
||||
} else if (selectedNum === 1 && !params.selected[params.name]) { // 点击前:多条曲线,且只有一条曲线高亮时
|
||||
for (const name in legendItem) {
|
||||
legendItem[name] = true
|
||||
}
|
||||
}
|
||||
self.myChart.setOption({
|
||||
legend: {
|
||||
selected: legendItem
|
||||
}
|
||||
})
|
||||
|
||||
if (self.getAfterSelectedNum(params) === 1) { // 点击后只有一条曲线高亮
|
||||
const chartParams = self.chartInfo.params
|
||||
// 多条曲线,且只有一条曲线高亮时,显示P50 P90 分位值,不止一个时隐藏标线
|
||||
let selectedName = ''
|
||||
for (const name in legendItem) {
|
||||
if (legendItem[name]) {
|
||||
selectedName = name
|
||||
}
|
||||
}
|
||||
|
||||
const serieArray = []
|
||||
self.chartOption.series.forEach((item, i) => {
|
||||
if (item.name === selectedName) {
|
||||
if (!_.isNaN(parseFloat(self.chartData[i].aggregation.p50)) && !_.isNaN(parseFloat(self.chartData[i].aggregation.p90))) {
|
||||
const markLine = {
|
||||
silent: true,
|
||||
symbol: 'none',
|
||||
label: {
|
||||
distance: [-50, 0],
|
||||
formatter (params) {
|
||||
const arr = unitConvert(Number(params.value), chartParams.unitType).join(' ')
|
||||
let desc = ''
|
||||
switch (params.dataIndex) {
|
||||
case 0: {
|
||||
desc = 'P50'
|
||||
break
|
||||
}
|
||||
case 1: {
|
||||
desc = 'P90'
|
||||
break
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
return `${arr} (${desc})`
|
||||
}
|
||||
},
|
||||
data: [
|
||||
{
|
||||
name: 'P50',
|
||||
yAxis: self.chartData[i].aggregation.p50
|
||||
},
|
||||
{
|
||||
name: 'P90',
|
||||
yAxis: self.chartData[i].aggregation.p90
|
||||
}
|
||||
]
|
||||
}
|
||||
item.markLine = markLine
|
||||
}
|
||||
}
|
||||
serieArray.push(item)
|
||||
})
|
||||
self.myChart.setOption({
|
||||
series: serieArray
|
||||
})
|
||||
} else { // 不止一条线高亮时隐藏标线
|
||||
const serieArray = []
|
||||
self.chartOption.series.forEach((item, i) => {
|
||||
item.markLine = []
|
||||
serieArray.push(item)
|
||||
})
|
||||
self.myChart.setOption({
|
||||
series: serieArray
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -25,8 +25,6 @@ import {
|
||||
ipHostedDomain
|
||||
} from '@/views/charts/charts/options/pie'
|
||||
import chartEchartMixin from './chart-echart-mixin'
|
||||
import { get, post } from '@/utils/http'
|
||||
import { reverseSortBy } from '@/utils/tools'
|
||||
|
||||
export default {
|
||||
name: 'ChartEchartAppRelateDomain',
|
||||
@@ -40,65 +38,26 @@ export default {
|
||||
methods: {
|
||||
initEcharts (id) {
|
||||
this.initDom(id, 2)
|
||||
const chartParams = this.chartInfo.params
|
||||
const domains = this.chartData.toString()
|
||||
// const domains = "office.com,dbank.com"
|
||||
this.$emit('showLoading', true)
|
||||
|
||||
const typeUrl = chartParams.byCategoryUrl.slice(0, chartParams.byCategoryUrl.indexOf('?'))
|
||||
const reputationUrlUrl = chartParams.byReputationUrl.slice(0, chartParams.byReputationUrl.indexOf('?'))
|
||||
|
||||
const byType = new Promise(resolve => {
|
||||
get(typeUrl, { domains: domains }).then(response => {
|
||||
// post(replaceUrlPlaceholder(chartParams.byCategoryUrl, { domains: domains })).then(response => {
|
||||
if (response.code === 200) {
|
||||
if (this.$_.isEmpty(response.data.result)) {
|
||||
// this.noData0 = true
|
||||
} else {
|
||||
// this.noData0 = false
|
||||
// const chartOption = this.$_.cloneDeep(this.chartOption)
|
||||
const data = response.data.result.sort(reverseSortBy('uniqDomains')).map(d => {
|
||||
return {
|
||||
data: d,
|
||||
name: d.categoryName,
|
||||
value: parseInt(d.uniqDomains),
|
||||
unitType: chartParams.unitType
|
||||
}
|
||||
})
|
||||
this.chartOption.series[0].data = data
|
||||
}
|
||||
}
|
||||
}).finally(() => {
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
const byReputation = new Promise(resolve => {
|
||||
get(reputationUrlUrl, { domains: domains }).then(response => {
|
||||
if (response.code === 200) {
|
||||
if (this.$_.isEmpty(response.data.result)) {
|
||||
// this.noData1 = true
|
||||
} else {
|
||||
// this.noData1 = false
|
||||
// const chartOption = this.$_.cloneDeep(this.chartOption)
|
||||
const data = response.data.result.sort(reverseSortBy('uniqDomains')).map(d => {
|
||||
return {
|
||||
data: d,
|
||||
name: d.reputationLevel,
|
||||
value: parseInt(d.uniqDomains),
|
||||
unitType: chartParams.unitType
|
||||
}
|
||||
})
|
||||
this.chartOption2.series[0].data = data
|
||||
// this.myChart2.setOption(chartOption)
|
||||
}
|
||||
}
|
||||
}).finally(() => {
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
Promise.all([byType, byReputation]).finally(response => {
|
||||
this.loadEchart(2)
|
||||
})
|
||||
this.chartOption.series[0].data = [
|
||||
{
|
||||
name: 'test1',
|
||||
value: 32
|
||||
},
|
||||
{
|
||||
name: 'test2',
|
||||
value: 21
|
||||
},
|
||||
{
|
||||
name: 'test3',
|
||||
value: 20
|
||||
},
|
||||
{
|
||||
name: 'test4',
|
||||
value: 7
|
||||
}
|
||||
]
|
||||
this.loadEchart(2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="hosted-domain__list">
|
||||
<div class="hosted-domain__list-title">{{$t('overall.domain')}}</div>
|
||||
<div class="hosted-domain__list-body">
|
||||
<div class="hosted-domain__list-row" v-for="(data, i) in chartData" :key="i">{{data.domain}}</div>
|
||||
<div class="hosted-domain__list-row" v-for="(data, i) in chartData" :key="i">{{data}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hosted-domain__chart">
|
||||
@@ -21,7 +21,11 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { replaceUrlPlaceholder, reverseSortBy } from '@/utils/tools'
|
||||
import * as echarts from 'echarts'
|
||||
import {
|
||||
ipHostedDomain
|
||||
} from '@/views/charts/charts/options/pie'
|
||||
import { replaceUrlPlaceholder } from '@/utils/tools'
|
||||
import { get } from '@/utils/http'
|
||||
import chartEchartMixin from './chart-echart-mixin'
|
||||
|
||||
@@ -39,59 +43,57 @@ export default {
|
||||
initEcharts (id) {
|
||||
this.initDom(id, 2)
|
||||
const chartParams = this.chartInfo.params
|
||||
const domains = this.chartData.map(function (item, i) {
|
||||
return item.domain
|
||||
}).join(',')
|
||||
|
||||
this.$emit('showLoading', true)
|
||||
const byType = new Promise(resolve => {
|
||||
get(replaceUrlPlaceholder(chartParams.byCategoryUrl, { domains: domains })).then(response => {
|
||||
get(replaceUrlPlaceholder(chartParams.byTypeUrl, { ip: this.entity.ip })).then(response => {
|
||||
if (response.code === 200) {
|
||||
if (this.$_.isEmpty(response.data.result)) {
|
||||
// this.noData0 = true
|
||||
} else {
|
||||
// this.noData0 = false
|
||||
// chartOption = this.$_.cloneDeep(this.chartOption)
|
||||
const data = response.data.result.sort(reverseSortBy('uniqDomains')).map(d => {
|
||||
const chartOption = this.$_.cloneDeep(this.chartOption)
|
||||
const data = response.data.result.map(d => {
|
||||
return {
|
||||
data: d,
|
||||
name: d.categoryName,
|
||||
value: parseInt(d.uniqDomains),
|
||||
name: d.category,
|
||||
value: parseInt(d.count),
|
||||
unitType: chartParams.unitType
|
||||
}
|
||||
})
|
||||
this.chartOption.series[0].data = data
|
||||
// this.myChart.setOption(this.chartOption)
|
||||
chartOption.series[0].data = data
|
||||
this.myChart.setOption(chartOption)
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
const byCredit = new Promise(resolve => {
|
||||
get(replaceUrlPlaceholder(chartParams.byReputationUrl, { domains: domains })).then(response => {
|
||||
get(replaceUrlPlaceholder(chartParams.byCreditUrl, { ip: this.entity.ip })).then(response => {
|
||||
if (response.code === 200) {
|
||||
if (this.$_.isEmpty(response.data.result)) {
|
||||
// this.noData1 = true
|
||||
} else {
|
||||
// this.noData1 = false
|
||||
// this.chartOption2 = this.$_.cloneDeep(this.chartOption)
|
||||
const data = response.data.result.sort(reverseSortBy('uniqDomains')).map(d => {
|
||||
const chartOption = this.$_.cloneDeep(this.chartOption)
|
||||
const data = response.data.result.map(d => {
|
||||
return {
|
||||
data: d,
|
||||
name: d.reputationLevel,
|
||||
value: parseInt(d.uniqDomains),
|
||||
name: d.reputation,
|
||||
value: parseInt(d.count),
|
||||
unitType: chartParams.unitType
|
||||
}
|
||||
})
|
||||
this.chartOption2.series[0].data = data
|
||||
// this.myChart2.setOption(this.chartOption2)
|
||||
chartOption.series[0].data = data
|
||||
this.myChart2.setOption(chartOption)
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
|
||||
Promise.all([byType, byCredit]).finally(response => {
|
||||
this.loadEchart(2)
|
||||
setTimeout(() => {
|
||||
this.$emit('showLoading', false)
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,6 @@ import {
|
||||
getChartColor
|
||||
} from '@/views/charts/charts/tools'
|
||||
import chartEchartMixin from './chart-echart-mixin'
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
import {unitTypes} from "@/utils/constants";
|
||||
|
||||
export default {
|
||||
name: 'ChartEchartWithStatistics',
|
||||
@@ -58,246 +56,23 @@ export default {
|
||||
}
|
||||
}
|
||||
})
|
||||
if (this.statisticsData.length === 1) {
|
||||
const markLine = {
|
||||
silent: true,
|
||||
symbol: 'none',
|
||||
label: {
|
||||
distance: [-50, 0],
|
||||
formatter (params) {
|
||||
const arr = unitConvert(
|
||||
Number(params.value),
|
||||
chartParams.unitType
|
||||
).join(' ')
|
||||
let desc = ''
|
||||
switch (params.dataIndex) {
|
||||
case 0: {
|
||||
desc = 'P50'
|
||||
break
|
||||
}
|
||||
case 1: {
|
||||
desc = 'P90'
|
||||
break
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
return `${arr} (${desc})`
|
||||
}
|
||||
},
|
||||
data: [
|
||||
{
|
||||
name: 'P50',
|
||||
yAxis: this.chartData[0].aggregation.p50
|
||||
? this.chartData[0].aggregation.p50
|
||||
: 50
|
||||
},
|
||||
{
|
||||
name: 'P90',
|
||||
yAxis: this.chartData[0].aggregation.p90
|
||||
? this.chartData[0].aggregation.p90
|
||||
: 90
|
||||
}
|
||||
]
|
||||
}
|
||||
const serieTmp = this.chartOption.series[0]
|
||||
this.chartOption.series[0] = {
|
||||
...serieTmp,
|
||||
markLine: markLine
|
||||
}
|
||||
}
|
||||
const gridTemplate = this.chartOption.grid
|
||||
// option中默认单位是数字,当单位是字节、百分比、时间时,额外处理
|
||||
if (chartParams.unitType === unitTypes.byte) {
|
||||
this.chartOption.yAxis.axisLabel.formatter = function (value) {
|
||||
return unitConvert(value, unitTypes.byte).join('')
|
||||
}
|
||||
this.chartOption.grid = {
|
||||
...gridTemplate,
|
||||
left: 75
|
||||
}
|
||||
} else if (chartParams.unitType === unitTypes.percent) {
|
||||
this.chartOption.yAxis.axisLabel.formatter = function (value) {
|
||||
return unitConvert(value, unitTypes.percent).join('')
|
||||
}
|
||||
} else if (chartParams.unitType === unitTypes.time) {
|
||||
this.chartOption.yAxis.axisLabel.formatter = function (value) {
|
||||
return unitConvert(value, unitTypes.time).join('')
|
||||
}
|
||||
}
|
||||
this.loadEchart(1, true)
|
||||
this.loadEchart()
|
||||
},
|
||||
|
||||
dispatchLegendSelectAction (name) {
|
||||
this.myChart.dispatchAction({
|
||||
type: 'legendSelect',
|
||||
name: name
|
||||
})
|
||||
},
|
||||
|
||||
dispatchLegendUnSelectAction (name) {
|
||||
this.myChart.dispatchAction({
|
||||
type: 'legendUnSelect',
|
||||
name: name
|
||||
})
|
||||
},
|
||||
|
||||
toggleStatisticsLegend (index) {
|
||||
const legendNum = this.statisticsData.length
|
||||
const chartParams = this.chartInfo.params
|
||||
if (legendNum > 1) {
|
||||
const selectedNum = this.statisticsData.filter(item => { return item.active === true }).length // 点击前,高亮legend个数
|
||||
if (selectedNum === legendNum) { // 全部曲线高亮时
|
||||
this.statisticsData.forEach((item, indexTmp) => {
|
||||
if (indexTmp === index) {
|
||||
item.active = true
|
||||
this.dispatchLegendSelectAction(item.legend)
|
||||
} else {
|
||||
item.active = false
|
||||
this.dispatchLegendUnSelectAction(item.legend)
|
||||
}
|
||||
})
|
||||
} else if (selectedNum === 1 && this.statisticsData[index].active) { // 多条曲线,且只有一条曲线高亮, 且点击的曲线为高亮曲线时
|
||||
this.statisticsData.forEach((item) => {
|
||||
item.active = true
|
||||
this.dispatchLegendSelectAction(item.legend)
|
||||
this.statisticsData[index].active = !this.statisticsData[index].active
|
||||
this.statisticsData.forEach((d, i) => {
|
||||
if (d.active) {
|
||||
this.myChart.dispatchAction({
|
||||
type: 'legendSelect',
|
||||
name: d.legend
|
||||
})
|
||||
} else {
|
||||
this.statisticsData[index].active = !this.statisticsData[index].active
|
||||
this.statisticsData.forEach((item, i) => {
|
||||
if (item.active) {
|
||||
this.dispatchLegendSelectAction(item.legend)
|
||||
} else {
|
||||
this.dispatchLegendUnSelectAction(item.legend)
|
||||
}
|
||||
this.myChart.dispatchAction({
|
||||
type: 'legendUnSelect',
|
||||
name: d.legend
|
||||
})
|
||||
}
|
||||
|
||||
const selectedAfterNum = this.statisticsData.filter((item, i) => { return item.active === true }).length // 点击后,高亮legend个数
|
||||
if (selectedAfterNum === 1) { // 点击后只有一条曲线高亮
|
||||
const chartParams = this.chartInfo.params
|
||||
// 多条曲线,且只有一条曲线高亮时,显示P50 P90 分位值,不止一个时隐藏标线
|
||||
const selectedName = this.statisticsData.filter((item, i) => { return item.active === true })[0].legend
|
||||
|
||||
const serieArray = []
|
||||
this.chartOption.series.forEach((item, i) => {
|
||||
if (item.name === selectedName) {
|
||||
const markLine = {
|
||||
silent: true,
|
||||
symbol: 'none',
|
||||
label: {
|
||||
distance: [-50, 0],
|
||||
formatter (params) {
|
||||
const arr = unitConvert(
|
||||
Number(params.value),
|
||||
chartParams.unitType
|
||||
).join(' ')
|
||||
let desc = ''
|
||||
switch (params.dataIndex) {
|
||||
case 0: {
|
||||
desc = 'P50'
|
||||
break
|
||||
}
|
||||
case 1: {
|
||||
desc = 'P90'
|
||||
break
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
return `${arr} (${desc})`
|
||||
}
|
||||
},
|
||||
data: [
|
||||
{
|
||||
name: 'P50',
|
||||
yAxis: this.chartData[i].aggregation.p50
|
||||
? this.chartData[i].aggregation.p50
|
||||
: 50
|
||||
},
|
||||
{
|
||||
name: 'P90',
|
||||
yAxis: this.chartData[i].aggregation.p90
|
||||
? this.chartData[i].aggregation.p90
|
||||
: 90
|
||||
}
|
||||
]
|
||||
}
|
||||
item.markLine = markLine
|
||||
}
|
||||
serieArray.push(item)
|
||||
})
|
||||
this.myChart.setOption({
|
||||
series: serieArray
|
||||
})
|
||||
} else { // 不止一条线高亮时隐藏标线
|
||||
const serieArray = []
|
||||
this.chartOption.series.forEach((item, i) => {
|
||||
item.markLine = []
|
||||
serieArray.push(item)
|
||||
})
|
||||
this.myChart.setOption({
|
||||
series: serieArray
|
||||
})
|
||||
}
|
||||
} else {
|
||||
this.statisticsData[index].active = !this.statisticsData[index].active
|
||||
this.statisticsData.forEach((item, i) => {
|
||||
if (item.active) {
|
||||
this.dispatchLegendSelectAction(item.legend)
|
||||
} else {
|
||||
this.dispatchLegendUnSelectAction(item.legend)
|
||||
}
|
||||
})
|
||||
|
||||
const selectedAfterNum = this.statisticsData.filter((item, i) => { return item.active === true }).length // 点击后,高亮legend个数
|
||||
if (selectedAfterNum === 1) { // 点击后只有一条曲线高亮
|
||||
const markLine = {
|
||||
silent: true,
|
||||
symbol: 'none',
|
||||
label: {
|
||||
distance: [-50, 0],
|
||||
formatter (params) {
|
||||
const arr = unitConvert(
|
||||
Number(params.value),
|
||||
chartParams.unitType
|
||||
).join(' ')
|
||||
let desc = ''
|
||||
switch (params.dataIndex) {
|
||||
case 0: {
|
||||
desc = 'P50'
|
||||
break
|
||||
}
|
||||
case 1: {
|
||||
desc = 'P90'
|
||||
break
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
return `${arr} (${desc})`
|
||||
}
|
||||
},
|
||||
data: [
|
||||
{
|
||||
name: 'P50',
|
||||
yAxis: this.chartData[0].aggregation.p50
|
||||
? this.chartData[0].aggregation.p50
|
||||
: 50
|
||||
},
|
||||
{
|
||||
name: 'P90',
|
||||
yAxis: this.chartData[0].aggregation.p90
|
||||
? this.chartData[0].aggregation.p90
|
||||
: 90
|
||||
}
|
||||
]
|
||||
}
|
||||
this.chartOption.series[0].markLine = markLine
|
||||
} else {
|
||||
this.chartOption.series[0].markLine = []
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
@@ -47,7 +47,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
handleQueryParams (queryParams) {
|
||||
return this.timeFilter = {
|
||||
this.timeFilter = {
|
||||
startTime: Number(queryParams.startTime) * 1000,
|
||||
endTime: Number(queryParams.endTime) * 1000
|
||||
}
|
||||
@@ -106,11 +106,7 @@ export default {
|
||||
dataIndex: index
|
||||
})
|
||||
self.selectPieChartName = params.name
|
||||
if (self.chartInfo.params.riskMapping) {
|
||||
self.loadPieTableData(riskLevelMapping.find(m => params.name === m.name).value)
|
||||
} else {
|
||||
self.loadPieTableData(params.name)
|
||||
}
|
||||
self.loadPieTableData(params.name)
|
||||
} else {
|
||||
self.myChart.dispatchAction({
|
||||
type: 'unselect',
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<template>
|
||||
<panel-chart-list
|
||||
:time-filter="timeFilter"
|
||||
:query-params="queryParams"
|
||||
:data-list="dataList"
|
||||
:data-list="chartInfo.children"
|
||||
:panel-lock="true"
|
||||
:entity="entity"
|
||||
>
|
||||
@@ -11,25 +10,15 @@
|
||||
|
||||
<script>
|
||||
import chartMixin from '@/views/charts/charts/chart-mixin'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'ChartGroup',
|
||||
mixins: [chartMixin],
|
||||
props: {
|
||||
timeFilter: Object,
|
||||
queryParams: Object
|
||||
timeFilter: Object
|
||||
},
|
||||
methods: {
|
||||
reload () {
|
||||
this.dataList = _.cloneDeep(this.dataList)
|
||||
}
|
||||
},
|
||||
setup (props) {
|
||||
const dataList = [...props.chartInfo.children]
|
||||
return {
|
||||
dataList
|
||||
}
|
||||
mounted () {
|
||||
console.info(this.chartInfo)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,286 +1,76 @@
|
||||
<template>
|
||||
<div class="cn-chart__map">
|
||||
<div class="map-back" v-show="showMapBackButton" @click="mapBack">< back</div>
|
||||
<div class="map-drawing" :id="`chart${chartInfo.id}`"></div>
|
||||
<div class="map-chart__legends" v-if="chartInfo.params.hasLegend">
|
||||
<div
|
||||
class="map-chart__legend"
|
||||
:class="`${currentLegendIndex === index ? 'map-chart__legend--active' : ''}`"
|
||||
v-for="(legend, index) in legends"
|
||||
:key="index"
|
||||
@click="changeLegend(index)"
|
||||
>
|
||||
<div
|
||||
class="legend__circle-marker"
|
||||
:style="`background-color:${markerColors[index].background};border: 1px solid ${markerColors[index].border};`"
|
||||
></div>
|
||||
<div class="legend__value">{{unitConvert(legend.value, unitTypes.number).join(' ')}}</div>
|
||||
<div class="legend__name">{{legend.name}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="map-back" v-show="showMapBackButton" @click="mapBack">< back</div>
|
||||
<div class="chart-drawing" :id="`chart${chartInfo.id}`"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as am4Core from '@amcharts/amcharts4/core'
|
||||
import * as am4Maps from '@amcharts/amcharts4/maps'
|
||||
import { getGeoData, replaceUrlPlaceholder } from '@/utils/tools'
|
||||
import { storageKey, dnsServerRole, unitTypes } from '@/utils/constants'
|
||||
import { storageKey, dnsServerRole } from '@/utils/constants'
|
||||
import { isMapBlock, isMapPoint } from './tools'
|
||||
import unitConvert, { valueToRangeValue } from '@/utils/unit-convert'
|
||||
import { HeatLegend } from '@/components/amcharts/heatLegend'
|
||||
import { getData } from '@/utils/api'
|
||||
import chartMixin from './chart-mixin'
|
||||
import _ from 'lodash'
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
export default {
|
||||
name: 'ChartMap',
|
||||
data () {
|
||||
return {
|
||||
unitTypes,
|
||||
myChart: null,
|
||||
mapPictureUrl: '/Tiles/{z}/{x}/{y}.png',
|
||||
showMapBackButton: false,
|
||||
polygonSeries: null, // 世界地图series
|
||||
countrySeries: null, // 下钻国家series
|
||||
worldImageSeries: null, // 世界地图圆点series
|
||||
countryImageSeries: null, // 下钻国家圆点series
|
||||
currentLegendIndex: 0,
|
||||
legends: [
|
||||
{
|
||||
name: this.$t('dns.rootDomainServers'),
|
||||
type: dnsServerRole.RTDNS,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dns.topLevelDomainServers'),
|
||||
type: dnsServerRole.TLDNS,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dns.authoritativeDomainServers'),
|
||||
type: dnsServerRole.ADNS,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dns.publicRecursiveDomainServers'),
|
||||
type: dnsServerRole.OPRDNS,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dns.selfBuiltDomainServers'),
|
||||
type: dnsServerRole.SBDNS,
|
||||
value: 0
|
||||
}
|
||||
],
|
||||
markerColors: [
|
||||
{
|
||||
background: '#C0DEFE',
|
||||
border: '#68AFFC'
|
||||
},
|
||||
{
|
||||
background: '#DBCFFA',
|
||||
border: '#AA8CF2'
|
||||
},
|
||||
{
|
||||
background: '#A0E8E0',
|
||||
border: '#1CC9B5'
|
||||
},
|
||||
{
|
||||
background: '#FFE1B5',
|
||||
border: '#FFB84E'
|
||||
},
|
||||
{
|
||||
background: '#FDC6C6',
|
||||
border: '#FA7777'
|
||||
},
|
||||
{
|
||||
background: '#ECC6F7',
|
||||
border: '#B620E0'
|
||||
}
|
||||
],
|
||||
keyMapping: [
|
||||
{
|
||||
key: 'sessions',
|
||||
label: this.$t('overall.sessions'),
|
||||
unitType: unitTypes.number
|
||||
},
|
||||
{
|
||||
key: 'establishLatency',
|
||||
label: this.$t('networkAppPerformance.tripTime'),
|
||||
unitType: unitTypes.time
|
||||
},
|
||||
{
|
||||
key: 'httpResponseLatency',
|
||||
label: this.$t('networkAppPerformance.httpResponse'),
|
||||
unitType: unitTypes.time
|
||||
},
|
||||
{
|
||||
key: 'sslConLatency',
|
||||
label: this.$t('networkAppPerformance.sslResponse'),
|
||||
unitType: unitTypes.time
|
||||
},
|
||||
{
|
||||
key: 'sequenceGapLossPercent',
|
||||
label: this.$t('networkAppPerformance.packetLossRate'),
|
||||
unitType: unitTypes.percent
|
||||
},
|
||||
{
|
||||
key: 'pktRetransPercent',
|
||||
label: this.$t('networkAppPerformance.retransmissionRate'),
|
||||
unitType: unitTypes.percent
|
||||
},
|
||||
{
|
||||
key: 'packets',
|
||||
label: this.$t('overall.packets'),
|
||||
unitType: unitTypes.number
|
||||
},
|
||||
{
|
||||
key: 'sentBytes',
|
||||
label: this.$t('overall.sent'),
|
||||
unitType: unitTypes.byte
|
||||
},
|
||||
{
|
||||
key: 'receivedBytes',
|
||||
label: this.$t('overall.received'),
|
||||
unitType: unitTypes.byte
|
||||
},
|
||||
{
|
||||
key: 'count',
|
||||
label: this.$t('overall.count'),
|
||||
unitType: unitTypes.number
|
||||
}
|
||||
]
|
||||
countrySeries: null // 下钻国家series
|
||||
}
|
||||
},
|
||||
mixins: [chartMixin],
|
||||
methods: {
|
||||
unitConvert,
|
||||
initMap (id) {
|
||||
const chart = am4Core.create(id, am4Maps.MapChart)
|
||||
chart.geodata = getGeoData(storageKey.iso36112WorldLow)
|
||||
chart.projection = new am4Maps.projections.Miller()
|
||||
this.myChart = shallowRef(chart)
|
||||
this.polygonSeries = shallowRef(this.polygonSeriesFactory())
|
||||
|
||||
if (this.isMapPoint) {
|
||||
this.worldImageSeries = shallowRef(this.imageSeriesFactory())
|
||||
}
|
||||
|
||||
this.loadAm4ChartMap(this.polygonSeries, this.worldImageSeries)
|
||||
|
||||
// 地图点击事件
|
||||
if (this.isMapBlock) {
|
||||
this.polygonSeries.mapPolygons.template.events.on('hit', async ev => {
|
||||
const countryId = ev.target.dataItem.dataContext.id
|
||||
if (countryId) {
|
||||
ev.target.series.chart.zoomToMapObject(ev.target)
|
||||
ev.target.isHover = false
|
||||
const geoData = getGeoData(countryId)
|
||||
if (geoData) {
|
||||
this.countrySeries = shallowRef(this.polygonSeriesFactory())
|
||||
this.countrySeries.geodata = geoData
|
||||
this.polygonSeries.hide()
|
||||
const country = ev.target.dataItem.dataContext.serverCountry
|
||||
const queryParams = { ...this.queryParams, country }
|
||||
const chartData = await getData(replaceUrlPlaceholder(this.chartInfo.params.url, queryParams))
|
||||
this.loadAm4ChartMap(this.countrySeries, null, country, chartData)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else if (this.isMapPoint) {
|
||||
this.worldImageSeries.mapImages.template.events.on('hit', async ev => {
|
||||
const countryId = ev.target.dataItem.dataContext.id
|
||||
ev.target.isHover = false
|
||||
if (countryId) {
|
||||
const targetMapObject = this.polygonSeries.getPolygonById(countryId)
|
||||
targetMapObject.series.chart.zoomToMapObject(targetMapObject)
|
||||
const geoData = getGeoData(countryId)
|
||||
if (geoData) {
|
||||
this.countrySeries = shallowRef(this.polygonSeriesFactory())
|
||||
this.countrySeries.geodata = geoData
|
||||
this.countryImageSeries = shallowRef(this.imageSeriesFactory())
|
||||
this.polygonSeries.hide()
|
||||
this.worldImageSeries.hide()
|
||||
const country = ev.target.dataItem.dataContext.name
|
||||
const queryParams = { ...this.queryParams, ipLocationCountry: country }
|
||||
const chartData = await getData(replaceUrlPlaceholder(this.chartInfo.params.url, queryParams))
|
||||
this.loadAm4ChartMap(this.countrySeries, this.countryImageSeries, country, chartData)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
// dns地图legend上的数据
|
||||
if (!_.isEmpty(this.chartInfo.params.legendUrl)) {
|
||||
setTimeout(() => {
|
||||
this.chartInfo.params.legendUrl.forEach((url, i) => {
|
||||
getData(url).then(data => {
|
||||
this.legends[i].value = data
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
polygonSeriesFactory () {
|
||||
const polygonSeries = this.myChart.series.push(new am4Maps.MapPolygonSeries())
|
||||
this.myChart = chart
|
||||
const polygonSeries = chart.series.push(new am4Maps.MapPolygonSeries())
|
||||
polygonSeries.useGeodata = true
|
||||
polygonSeries.exclude = ['AQ'] // 排除南极洲
|
||||
polygonSeries.tooltip.getFillFromObject = false
|
||||
polygonSeries.tooltip.background.fill = am4Core.color('#41495D')
|
||||
polygonSeries.tooltip.background.filters.clear()
|
||||
polygonSeries.tooltip.background.stroke = '#41495D'
|
||||
polygonSeries.tooltip.background.fill = am4Core.color('#FFFFFF')
|
||||
this.polygonSeries = polygonSeries
|
||||
const polygonTemplate = polygonSeries.mapPolygons.template
|
||||
polygonTemplate.tooltipHTML = this.generatePolygonTooltipHTML()
|
||||
polygonTemplate.tooltipHTML = this.generateTooltipHTML()
|
||||
polygonTemplate.nonScalingStroke = true
|
||||
polygonTemplate.strokeWidth = 0.5
|
||||
polygonTemplate.fill = am4Core.color('rgba(176,196,222,.5)')
|
||||
return polygonSeries
|
||||
},
|
||||
imageSeriesFactory (dataField) {
|
||||
const vm = this
|
||||
const imageSeries = this.myChart.series.push(new am4Maps.MapImageSeries())
|
||||
imageSeries.dataFields.value = dataField || 'count'
|
||||
|
||||
const imageTemplate = imageSeries.mapImages.template
|
||||
imageTemplate.nonScaling = true
|
||||
|
||||
imageTemplate.adapter.add('latitude', function (latitude, target) {
|
||||
const polygon = vm.polygonSeries.getPolygonById(target.dataItem.dataContext.id)
|
||||
if (polygon) {
|
||||
return polygon.visualLatitude
|
||||
this.loadAm4ChartMap(this.polygonSeries)
|
||||
// 地图点击事件
|
||||
polygonTemplate.events.on('hit', async ev => {
|
||||
const countryId = ev.target.dataItem.dataContext.id
|
||||
if (countryId) {
|
||||
ev.target.series.chart.zoomToMapObject(ev.target)
|
||||
ev.target.isHover = false
|
||||
this.countrySeries = chart.series.push(new am4Maps.MapPolygonSeries())
|
||||
this.countrySeries.tooltip.getFillFromObject = false
|
||||
this.countrySeries.tooltip.background.fill = am4Core.color('#FFFFFF')
|
||||
const countryTemplate = this.countrySeries.mapPolygons.template
|
||||
countryTemplate.tooltipHTML = this.generateTooltipHTML()
|
||||
countryTemplate.nonScalingStroke = true
|
||||
countryTemplate.strokeWidth = 0.5
|
||||
countryTemplate.fill = am4Core.color('rgba(176,196,222,.5)')
|
||||
const geoData = getGeoData(countryId)
|
||||
if (geoData) {
|
||||
this.countrySeries.geodata = geoData
|
||||
this.polygonSeries.hide()
|
||||
const country = ev.target.dataItem.dataContext.serverCountry
|
||||
const queryParams = { ...this.queryParams, country }
|
||||
const chartData = await getData(replaceUrlPlaceholder(this.chartInfo.params.url, queryParams))
|
||||
this.loadAm4ChartMap(this.countrySeries, ev.target.dataItem.dataContext.serverCountry, chartData)
|
||||
}
|
||||
}
|
||||
return latitude
|
||||
})
|
||||
|
||||
imageTemplate.adapter.add('longitude', function (longitude, target) {
|
||||
const polygon = vm.polygonSeries.getPolygonById(target.dataItem.dataContext.id)
|
||||
if (polygon) {
|
||||
return polygon.visualLongitude
|
||||
}
|
||||
return longitude
|
||||
})
|
||||
|
||||
const circle = imageTemplate.createChild(am4Core.Circle)
|
||||
circle.propertyFields.fill = 'color'
|
||||
circle.propertyFields.stroke = 'border'
|
||||
circle.strokeWidth = 1
|
||||
circle.tooltipHTML = this.generatePolygonTooltipHTML()
|
||||
imageSeries.tooltip.getFillFromObject = false
|
||||
imageSeries.tooltip.background.fill = am4Core.color('#41495D')
|
||||
imageSeries.tooltip.background.filters.clear()
|
||||
imageSeries.tooltip.background.stroke = '#41495D'
|
||||
|
||||
imageSeries.heatRules.push({
|
||||
target: circle,
|
||||
property: 'radius',
|
||||
min: 6,
|
||||
max: 25,
|
||||
dataField: 'value'
|
||||
})
|
||||
|
||||
return imageSeries
|
||||
},
|
||||
loadAm4ChartMap (polygonSeries, imageSeries, country, chartData) {
|
||||
loadAm4ChartMap (polygonSeries, country, chartData) {
|
||||
// chartData不为空是下钻
|
||||
if (chartData) {
|
||||
this.$emit('showLoading', true)
|
||||
@@ -288,7 +78,6 @@ export default {
|
||||
try {
|
||||
// 清除数据
|
||||
polygonSeries.data.splice(0)
|
||||
|
||||
// 清除legend
|
||||
this.myChart.children.each((s, i) => {
|
||||
if (s && s.className !== 'Container') {
|
||||
@@ -300,14 +89,27 @@ export default {
|
||||
const chartParams = this.chartInfo.params
|
||||
const data = chartData || this.chartData
|
||||
if (data && this.isMapBlock) {
|
||||
const seriesData = data.map(r => {
|
||||
return {
|
||||
...this.convertMapData(r),
|
||||
id: r.serverId,
|
||||
serverCountry: r.serverCountry,
|
||||
value: r[chartParams.valueColumn]
|
||||
const sumData = []
|
||||
data.forEach(r => {
|
||||
const hit = sumData.find(s => s.id === r.serverId)
|
||||
const { key, labelText } = this.getDataKey(r)
|
||||
const value = Number(r[key]) || 0
|
||||
if (hit) {
|
||||
hit.value += value
|
||||
} else {
|
||||
sumData.push({
|
||||
id: r.serverId,
|
||||
serverCountry: r.serverCountry,
|
||||
key,
|
||||
labelText,
|
||||
value
|
||||
})
|
||||
}
|
||||
})
|
||||
const seriesData = sumData.map(r => ({
|
||||
...r,
|
||||
showValue: (r.value || r.value === 0) ? valueToRangeValue(r.value, chartParams.unitType).join(' ') : ''
|
||||
}))
|
||||
!this.$_.isEmpty(seriesData) && (polygonSeries.data = [...seriesData])
|
||||
// 数据全为0的情况,legend只显示1个颜色
|
||||
const sorted = seriesData.sort((a, b) => b.value - a.value)
|
||||
@@ -342,15 +144,55 @@ export default {
|
||||
return ''
|
||||
})
|
||||
} else if (data && this.isMapPoint) {
|
||||
imageSeries.data = data.map(r => ({
|
||||
...this.convertMapData(r),
|
||||
id: r.ipLocationId,
|
||||
dnsServerRole: r.dnsServerRole,
|
||||
name: r.ipLocationCity || r.ipLocationProvince || r.ipLocationCountry,
|
||||
desc: this.$t(this.dnsTypeI18n(r.dnsServerRole)),
|
||||
color: this.circleColor[r.dnsServerRole.toUpperCase()].background,
|
||||
border: this.circleColor[r.dnsServerRole.toUpperCase()].border
|
||||
}))
|
||||
const seriesData = []
|
||||
data.forEach(d => {
|
||||
seriesData.push({
|
||||
id: d.ipLocationId,
|
||||
count: d.count,
|
||||
dnsServerRole: d.dnsServerRole,
|
||||
location: d.ipLocationCity || d.ipLocationProvince || d.ipLocationCountry,
|
||||
desc: this.$t(this.dnsTypeI18n(d.dnsServerRole)),
|
||||
color: this.circleColor[d.dnsServerRole].background,
|
||||
border: this.circleColor[d.dnsServerRole].border
|
||||
})
|
||||
})
|
||||
console.info(seriesData)
|
||||
const imageSeries = this.myChart.series.push(new am4Maps.MapImageSeries())
|
||||
imageSeries.data = seriesData
|
||||
imageSeries.dataFields.value = 'count'
|
||||
|
||||
const imageTemplate = imageSeries.mapImages.template
|
||||
imageTemplate.nonScaling = true
|
||||
|
||||
imageTemplate.adapter.add('latitude', function (latitude, target) {
|
||||
const polygon = polygonSeries.getPolygonById(target.dataItem.dataContext.id)
|
||||
if (polygon) {
|
||||
return polygon.visualLatitude
|
||||
}
|
||||
return latitude
|
||||
})
|
||||
|
||||
imageTemplate.adapter.add('longitude', function (longitude, target) {
|
||||
const polygon = polygonSeries.getPolygonById(target.dataItem.dataContext.id)
|
||||
if (polygon) {
|
||||
return polygon.visualLongitude
|
||||
}
|
||||
return longitude
|
||||
})
|
||||
|
||||
const circle = imageTemplate.createChild(am4Core.Circle)
|
||||
circle.propertyFields.fill = 'color'
|
||||
circle.propertyFields.stroke = 'border'
|
||||
circle.strokeWidth = 1
|
||||
circle.tooltipText = '[bold]{location}[/]\n{desc}: {count}'
|
||||
|
||||
imageSeries.heatRules.push({
|
||||
target: circle,
|
||||
property: 'radius',
|
||||
min: 6,
|
||||
max: 25,
|
||||
dataField: 'value'
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
@@ -364,25 +206,15 @@ export default {
|
||||
},
|
||||
mapBack () {
|
||||
this.countrySeries.hide()
|
||||
if (this.isMapPoint) {
|
||||
this.countryImageSeries.hide()
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.showMapBackButton = false
|
||||
this.polygonSeries.show()
|
||||
if (this.isMapPoint) {
|
||||
this.worldImageSeries.show()
|
||||
}
|
||||
this.myChart.goHome()
|
||||
})
|
||||
},
|
||||
changeLegend (index) {
|
||||
this.currentLegendIndex = index
|
||||
this.$emit('getChartData', null, { dnsServerRole: this.legends[index].type })
|
||||
},
|
||||
dnsTypeI18n (role) {
|
||||
let i18n = ''
|
||||
switch (role.toUpperCase()) {
|
||||
switch (role) {
|
||||
case dnsServerRole.RTDNS: {
|
||||
i18n = 'dns.rootDomainServers'
|
||||
break
|
||||
@@ -411,23 +243,16 @@ export default {
|
||||
}
|
||||
return i18n
|
||||
},
|
||||
generatePolygonTooltipHTML () {
|
||||
let html = `
|
||||
generateTooltipHTML () {
|
||||
return `
|
||||
<div class="map-tooltip" style="padding-bottom: 10px;">
|
||||
<div class="map-tooltip__title">{name}</div>
|
||||
<div class="map-tooltip__content">`
|
||||
this.keyMapping.forEach(mapping => {
|
||||
html += `
|
||||
<div class="content-row" style="display: none; display: {${mapping.key}Display}">
|
||||
<span class="row__label">{${mapping.key}Label}:</span>
|
||||
<span class="row__value">{${mapping.key}ShowValue}</span>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
html += `
|
||||
<div class="map-tooltip__content">
|
||||
<span>{labelText}</span>
|
||||
<span>{showValue}</span>
|
||||
</div>
|
||||
</div>`
|
||||
return html
|
||||
</div>
|
||||
`
|
||||
},
|
||||
getDataKey (r) {
|
||||
let key = ''
|
||||
@@ -452,22 +277,6 @@ export default {
|
||||
labelText = this.$t('overall.sessions')
|
||||
}
|
||||
return { key, labelText }
|
||||
},
|
||||
convertMapData (data) {
|
||||
const converted = {}
|
||||
this.keyMapping.forEach(mapping => {
|
||||
if (data[mapping.key] || data[mapping.key] === 0) {
|
||||
converted[mapping.key] = Number(data[mapping.key])
|
||||
converted[`${mapping.key}Label`] = mapping.label
|
||||
converted[`${mapping.key}ShowValue`] = valueToRangeValue(data[mapping.key], mapping.unitType).join(' ')
|
||||
converted[`${mapping.key}Display`] = 'block'
|
||||
} else {
|
||||
converted[mapping.key] = ''
|
||||
converted[`${mapping.key}Label`] = ''
|
||||
converted[`${mapping.key}Display`] = 'none'
|
||||
}
|
||||
})
|
||||
return converted
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -505,7 +314,6 @@ export default {
|
||||
border: '#BF49DF'
|
||||
}
|
||||
return {
|
||||
myChart: shallowRef(null),
|
||||
circleColor,
|
||||
isMapBlock: isMapBlock(props.chartInfo.type),
|
||||
isMapPoint: isMapPoint(props.chartInfo.type)
|
||||
|
||||
@@ -1,29 +1,28 @@
|
||||
<template>
|
||||
<div class="cn-chart__one-situation-statistics">
|
||||
<div class="one-situation-statistics__box">
|
||||
<div class="box__progress">
|
||||
<div class="chart-one-situation-statistics">
|
||||
<div class="situation-statistics-main">
|
||||
<div class="situation-statistics-main-left">
|
||||
<el-progress
|
||||
type="circle"
|
||||
:color="chartInfo.params.color"
|
||||
width="76"
|
||||
:percentage="Math.floor(($_.get(chartData, 'percent', '-') * 100) * 100) / 100"
|
||||
:percentage="chartData ? chartData.percent : 0"
|
||||
/>
|
||||
</div>
|
||||
<div class="box__count">
|
||||
<div> {{ $_.get(chartData, 'count', '-') }} </div>
|
||||
<div>{{ $t(`dns.numberOfNodes`) }}</div>
|
||||
<div class="situation-statistics-main-right">
|
||||
<div>{{ chartData ? (chartData.count || '-') : '-' }}</div>
|
||||
<div class="situation-statistic-main-right-font">{{ $t(`dns.numberOfNodes`) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
export default {
|
||||
name: 'ChartOneSituationStatistics',
|
||||
props: {
|
||||
chartInfo: Object,
|
||||
chartData: [Array, Object]
|
||||
}
|
||||
chartData: [Array, Object],
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,147 +1,43 @@
|
||||
<template>
|
||||
<div
|
||||
class="cn-chart__single-value chart-header-position"
|
||||
:class="singleValueClass(type)"
|
||||
:style="{ backgroundColor: color }"
|
||||
>
|
||||
<div class="single-value-icon__box" v-if="!isCommon3SingleValue(type) && !isDetectionsProtocol(type) ">
|
||||
<div
|
||||
class="single-value__icon"
|
||||
:style="`background-color: ${
|
||||
chartInfo.params.iconBackgroundColor || ''
|
||||
}`"
|
||||
>
|
||||
<i
|
||||
:class="icon"
|
||||
:style="`color: ${chartInfo.params.iconColor || ''}`"
|
||||
></i>
|
||||
</div>
|
||||
<div class="cn-chart__single-value chart-header-position" :class="singleValueClass(type)" :style="{backgroundColor:color}">
|
||||
<div class="single-value-icon__box" v-if="type !== 54">
|
||||
<div class="single-value__icon" :style="`background-color: ${chartInfo.params.iconBackgroundColor || ''}`"><i :class="icon" :style="`color: ${chartInfo.params.iconColor || ''}`"></i></div>
|
||||
</div>
|
||||
<div class="single-value__content" v-if="isCommonSingleValue(type)">
|
||||
<div class="single-value__content" v-if="type === 51">
|
||||
<div class="content__data">
|
||||
<span>{{
|
||||
handleSingleValue[0] || handleSingleValue[0] === 0
|
||||
? handleSingleValue[0]
|
||||
: '-'
|
||||
}}</span>
|
||||
<span class="single-value__unit">{{ handleSingleValue[1] }}</span>
|
||||
<span>{{handleSingleValue[0] || handleSingleValue[0] === 0 ? handleSingleValue[0] : '-'}}</span>
|
||||
<span class="single-value__unit">{{handleSingleValue[1]}}</span>
|
||||
</div>
|
||||
<div class="content__title">
|
||||
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{
|
||||
chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name
|
||||
}}</span>
|
||||
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="single-value__content" v-if="isSingleValueWithPercentileRight(type)">
|
||||
<div class="data__title-in-one">
|
||||
<div class="content__data">
|
||||
<span style="white-space: nowrap;">{{
|
||||
handleSingleValue[0] || handleSingleValue[0] === 0
|
||||
? handleSingleValue[0]
|
||||
: '-'
|
||||
}}</span><span class="single-value__unit">{{handleSingleValue[1] }}</span>
|
||||
</div>
|
||||
<div class="content__title title-background-color">
|
||||
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{
|
||||
chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content__percentile">
|
||||
<div class="circle__content">
|
||||
<div class="circle circle-p50"></div>
|
||||
<div><span class="percentile__title-color">P50: </span><span>
|
||||
{{(handleSingleValue[2] || handleSingleValue[2] === 0)
|
||||
?handleSingleValue[2]
|
||||
:'-'}}
|
||||
</span></div>
|
||||
</div>
|
||||
<div class="circle__content">
|
||||
<div class="circle circle-p90"></div>
|
||||
<div><span class="percentile__title-color">P90: </span><span>
|
||||
{{(handleSingleValue[3]|| handleSingleValue[3] === 0)
|
||||
?handleSingleValue[3]
|
||||
:'-'}}
|
||||
</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="single-value__content" v-if="isSingleValueWithPercentileLeft(type)">
|
||||
<div class="single-value__content single-value__content--with-chart" v-if="type === 52">
|
||||
<div class="content__title">
|
||||
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{
|
||||
chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="content__data">
|
||||
<span>{{
|
||||
handleSingleValue[0] || handleSingleValue[0] === 0
|
||||
? handleSingleValue[0]
|
||||
: '-'
|
||||
}}</span>
|
||||
<span class="single-value__unit">{{ handleSingleValue[1] }}</span>
|
||||
</div>
|
||||
<div class="content__percentile">
|
||||
<div class="circle__content">
|
||||
<div class="circle circle-p50"></div>
|
||||
<div><span class="percentile__title-color">P50: </span><span>
|
||||
{{(handleSingleValue[2]|| handleSingleValue[2] === 0)
|
||||
?handleSingleValue[2]
|
||||
:'-'}}
|
||||
</span></div>
|
||||
</div>
|
||||
<div class="circle__content">
|
||||
<div class="circle circle-p90"></div>
|
||||
<div><span class="percentile__title-color">P90: </span><span>
|
||||
{{(handleSingleValue[3]|| handleSingleValue[3] === 0)
|
||||
?handleSingleValue[3]
|
||||
:'-'}}
|
||||
</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="single-value__content single-value__content--with-chart" v-if="isSingleValueWithEcharts(type)">
|
||||
<div class="content__title">
|
||||
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{
|
||||
chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name
|
||||
}}</span>
|
||||
<span
|
||||
v-if="chartInfo.params && chartInfo.params.as"
|
||||
class="ip-detail-as"
|
||||
>
|
||||
as <span style="text-transform: capitalize">{{
|
||||
chartInfo.params.as
|
||||
}}</span>
|
||||
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</span>
|
||||
<span v-if="chartInfo.params && chartInfo.params.as" class="ip-detail-as">
|
||||
as <span style="text-transform: capitalize">{{chartInfo.params.as}}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="content__data">
|
||||
<span>{{
|
||||
handleSingleValue[0] || handleSingleValue[0] === 0
|
||||
? handleSingleValue[0]
|
||||
: '-'
|
||||
}}</span>
|
||||
<span class="single-value__unit">{{ handleSingleValue[1] }}</span>
|
||||
<span>{{handleSingleValue[0] || handleSingleValue[0] === 0 ? handleSingleValue[0] : '-'}}</span>
|
||||
<span class="single-value__unit">{{handleSingleValue[1]}}</span>
|
||||
</div>
|
||||
<div class="content__chart">
|
||||
<div class="chart-drawing" :id="`chart${chartInfo.id}`"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="single-value__content" v-if="isCommon2SingleValue(type)">
|
||||
<div class="single-value__content" v-if="type === 53">
|
||||
<div class="content__title">
|
||||
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{
|
||||
chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name
|
||||
}}</span>
|
||||
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</span>
|
||||
</div>
|
||||
<div class="content__data">
|
||||
<span>{{
|
||||
handleSingleValue[0] || handleSingleValue[0] === 0
|
||||
? handleSingleValue[0]
|
||||
: '-'
|
||||
}}</span>
|
||||
<span class="single-value__unit">{{ handleSingleValue[1] }}</span>
|
||||
<span>{{handleSingleValue[0] || handleSingleValue[0] === 0 ? handleSingleValue[0] : '-'}}</span>
|
||||
<span class="single-value__unit">{{handleSingleValue[1]}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="single-value__content" v-if="isCommon3SingleValue(type)">
|
||||
<div class="single-value-icon__box">
|
||||
<div class="single-value__content" v-if="type === 54" >
|
||||
<div class="single-value-icon__box" >
|
||||
<div class="single-value__icon">
|
||||
<!-- 使用图标-->
|
||||
<svg class="cn-icon-svg" aria-hidden="true">
|
||||
@@ -151,98 +47,27 @@
|
||||
</div>
|
||||
<div class="single-value__data">
|
||||
<div class="content__title">
|
||||
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{
|
||||
chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name
|
||||
}}</span>
|
||||
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</span>
|
||||
</div>
|
||||
<div class="content__data">
|
||||
<span>{{
|
||||
handleSingleValue[0] || handleSingleValue[0] === 0
|
||||
? handleSingleValue[0]
|
||||
: '-'
|
||||
}}</span>
|
||||
<span class="single-value__unit">{{ handleSingleValue[1] }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="single-value__content" v-if="isSingleValueWithPercent(type)">
|
||||
<div>
|
||||
<div class="content__title">
|
||||
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{
|
||||
chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="content__data">
|
||||
<div class="content__data__doh">
|
||||
<div class="content__data__doh__count">
|
||||
{{ $_.get(chartData, 'count', '-') }}
|
||||
</div>
|
||||
<div class="content__data__doh__percent">
|
||||
{{$t('protocol.proportion')}}<span>{{ $_.get(chartData, 'percent', '-') }}%</span>
|
||||
</div>
|
||||
<span>{{handleSingleValue[0] || handleSingleValue[0] === 0 ? handleSingleValue[0] : '-'}}</span>
|
||||
<span class="single-value__unit">{{handleSingleValue[1]}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="single-value__content" v-if="isDetectionsProtocol(type)">
|
||||
<div class="single-value__data">
|
||||
<div class="content__title">
|
||||
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">
|
||||
{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content__data">
|
||||
<div class="content__data-protocol">
|
||||
<div class="content__data-protocol-all">
|
||||
<div class="content__data-protocol-icon" :style="{backgroundColor: chartInfo.params.iconBackgroundColor[0]}">
|
||||
<i :class="chartInfo.params.icon[0]" :style="{color: chartInfo.params.iconColor[0]}"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content__data-protocol-value">
|
||||
<div class="content__data-protocol-value-title">{{$t('protocol.requestVolume')}}</div>
|
||||
<div class="content__data-protocol-value-num">{{unitConvert($_.get(chartData, 'bytes'), chartInfo.params.unitType).join('')}}</div>
|
||||
</div>
|
||||
<div class="content__data-protocol-percent"><span>{{$t('protocol.proportion')}}</span> <span>{{unitConvert($_.get(chartData, 'bytesPercent'), unitTypes.percent).join('')}}</span></div>
|
||||
</div>
|
||||
<div class="content__data-protocol">
|
||||
<div class="content__data-protocol-all">
|
||||
<div class="content__data-protocol-icon" :style="{backgroundColor: chartInfo.params.iconBackgroundColor[1]}">
|
||||
<i :class="chartInfo.params.icon[1]" :style="{color: chartInfo.params.iconColor[1]}"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content__data-protocol-value">
|
||||
<div class="content__data-protocol-value-title">{{$t('protocol.totalFlow')}}</div>
|
||||
<div class="content__data-protocol-value-num">{{unitConvert($_.get(chartData, 'count'), chartInfo.params.unitType).join('')}}</div>
|
||||
</div>
|
||||
<div class="content__data-protocol-percent"><span>{{$t('protocol.proportion')}}</span> <span>{{unitConvert($_.get(chartData, 'countPercent'), unitTypes.percent).join('')}}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
import {
|
||||
unitTypes
|
||||
} from '@/utils/constants'
|
||||
import { get } from '@/utils/http'
|
||||
import { unitTypes } from '@/utils/constants'
|
||||
import { replaceUrlPlaceholder } from '@/utils/tools'
|
||||
import * as echarts from 'echarts'
|
||||
import {
|
||||
getOption,
|
||||
getChartColor,
|
||||
isCommonSingleValue,
|
||||
isSingleValueWithEcharts,
|
||||
isSingleValueWithPercentileLeft,
|
||||
isSingleValueWithPercentileRight,
|
||||
isCommon2SingleValue,
|
||||
isSingleValueWithPercent,
|
||||
isCommon3SingleValue,
|
||||
isDetectionsProtocol
|
||||
} from '@/views/charts/charts/tools'
|
||||
|
||||
import { getOption, getChartColor } from '@/views/charts/charts/tools'
|
||||
export default {
|
||||
name: 'chartSingleValue',
|
||||
props: {
|
||||
@@ -252,8 +77,6 @@ export default {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
unitConvert,
|
||||
unitTypes,
|
||||
icon: '',
|
||||
color: '',
|
||||
type: 0,
|
||||
@@ -274,113 +97,76 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
handleSingleValue () {
|
||||
let value = null
|
||||
if (this.isSingleValueWithPercentileLeft(this.chartInfo.type) || this.isSingleValueWithPercentileRight(this.chartInfo.type)) {
|
||||
value = (this.chartData && (this.chartData.value || this.chartData.value === 0)) ? this.chartData.value : ''
|
||||
} else {
|
||||
value = (this.chartData || this.chartData === 0)
|
||||
? this.chartData
|
||||
: ''
|
||||
}
|
||||
|
||||
const value = this.$_.isEmpty(this.chartData) || this.$_.get(this, 'chartData') ? this.chartData : ''
|
||||
const unitType = this.chartInfo.params.unitType
|
||||
const result = unitConvert(value, unitType)
|
||||
|
||||
let p50 = ''
|
||||
let p90 = ''
|
||||
if (this.isSingleValueWithPercentileLeft(this.chartInfo.type) || this.isSingleValueWithPercentileRight(this.chartInfo.type)) {
|
||||
p50 = this.chartData ? unitConvert(this.chartData.p50, unitType) : ''
|
||||
p90 = this.chartData ? unitConvert(this.chartData.p90, unitType) : ''
|
||||
}
|
||||
|
||||
switch (unitType) {
|
||||
case unitTypes.percent: {
|
||||
result[0] = result[0] < 0.01 ? '< 0.01' : result[0]
|
||||
result[2] = (p50 && (p50[0] || Number(p50[0]) === 0)) ? p50[0] + p50[1] : ''
|
||||
result[3] = (p90 && (p90[0] || Number(p90[0]) === 0)) ? p90[0] + p90[1] : ''
|
||||
break
|
||||
}
|
||||
case unitTypes.time: {
|
||||
result[0] = result[0] < 1 ? '< 1' : result[0]
|
||||
result[2] = (p50 && (p50[0] || Number(p50[0]) === 0)) ? p50[0] + p50[1] : ''
|
||||
result[3] = (p90 && (p90[0] || Number(p90[0]) === 0)) ? p90[0] + p90[1] : ''
|
||||
break
|
||||
}
|
||||
default:
|
||||
break
|
||||
default: break
|
||||
}
|
||||
return result
|
||||
},
|
||||
singleValueClass () {
|
||||
return function (type) {
|
||||
let c
|
||||
if (this.isCommonSingleValue(type)) {
|
||||
c = 'cn-chart__single-value--icon-left'
|
||||
} else if (this.isSingleValueWithEcharts(type)) {
|
||||
c = 'cn-chart__single-value--chart'
|
||||
} else if (this.isSingleValueWithPercentileLeft(type)) {
|
||||
c = 'cn-chart__single-value--percentile-left'
|
||||
} else if (this.isSingleValueWithPercentileRight(type)) {
|
||||
c = 'cn-chart__single-value--percentile-right'
|
||||
} else if (this.isCommon2SingleValue(type)) {
|
||||
c = 'cn-chart__single-value--icon-right'
|
||||
} else if (this.isCommon3SingleValue(type)) {
|
||||
c = 'cn-chart__single-value--icon-right--color'
|
||||
} else if (this.isSingleValueWithPercent(type)) {
|
||||
c = 'cn-chart__single-value--icon-doh'
|
||||
} else if (this.isDetectionsProtocol(type)) {
|
||||
c = 'cn-chart__single-value--protocol'
|
||||
switch (type) {
|
||||
case 51: {
|
||||
c = 'cn-chart__single-value--icon-left'
|
||||
break
|
||||
}
|
||||
case 55:
|
||||
case 52: {
|
||||
c = 'cn-chart__single-value--chart'
|
||||
break
|
||||
}
|
||||
case 53: {
|
||||
c = 'cn-chart__single-value--icon-right'
|
||||
break
|
||||
}
|
||||
case 54: {
|
||||
c = 'cn-chart__single-value--icon-right--color'
|
||||
break
|
||||
}
|
||||
default: break
|
||||
}
|
||||
return c
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isCommonSingleValue,
|
||||
isSingleValueWithEcharts,
|
||||
isSingleValueWithPercentileLeft,
|
||||
isSingleValueWithPercentileRight,
|
||||
isCommon2SingleValue,
|
||||
isCommon3SingleValue,
|
||||
isSingleValueWithPercent,
|
||||
isDetectionsProtocol,
|
||||
chartSingleValueTotal () {
|
||||
const chartParams = this.$_.get(this.chartInfo, 'params') || {}
|
||||
if (isSingleValueWithEcharts(this.type)) {
|
||||
if (this.type === 52) {
|
||||
const dom = document.getElementById(`chart${this.chartInfo.id}`)
|
||||
const myChart = echarts.init(dom)
|
||||
this.chartOption = this.$_.cloneDeep(getOption(this.type))
|
||||
get(replaceUrlPlaceholder(chartParams.urlChart, this.queryParams)).then(
|
||||
(response) => {
|
||||
const seriesTemplate = this.chartOption.series[0]
|
||||
const result = response.data.result
|
||||
this.chartOption.series = result.map((r, i) => {
|
||||
return {
|
||||
...seriesTemplate,
|
||||
name: r.legend,
|
||||
data: r.values.map((v) => [
|
||||
Number(v[0]) * 1000,
|
||||
Number(v[1]),
|
||||
chartParams.unitType
|
||||
]),
|
||||
lineStyle: {
|
||||
color: getChartColor[i]
|
||||
}
|
||||
get(replaceUrlPlaceholder(chartParams.urlChart, this.queryParams)).then(response => {
|
||||
const seriesTemplate = this.chartOption.series[0]
|
||||
const result = response.data.result
|
||||
this.chartOption.series = result.map((r, i) => {
|
||||
return {
|
||||
...seriesTemplate,
|
||||
name: r.legend,
|
||||
data: r.values.map(v => [Number(v[0]) * 1000, Number(v[1]), chartParams.unitType]),
|
||||
lineStyle: {
|
||||
color: getChartColor[i]
|
||||
}
|
||||
})
|
||||
myChart.setOption(this.chartOption)
|
||||
}
|
||||
)
|
||||
}
|
||||
})
|
||||
myChart.setOption(this.chartOption)
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.$nextTick(
|
||||
() =>
|
||||
(this.timer = setTimeout(() => {
|
||||
this.chartSingleValueTotal()
|
||||
}, 200))
|
||||
)
|
||||
this.$nextTick(() => this.timer = setTimeout(() => { this.chartSingleValueTotal() }, 200))
|
||||
},
|
||||
deactivated () {
|
||||
clearTimeout(this.timer)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
v-for="(c, i) in table.tableColumns.common"
|
||||
show-overflow-tooltip
|
||||
:key="i"
|
||||
:label="$t(chartTableColumnMapping[c] || c)"
|
||||
:label="$t(chartTableColumnMapping[c])"
|
||||
:prop="c"
|
||||
>
|
||||
</el-table-column>
|
||||
@@ -20,10 +20,10 @@
|
||||
v-for="(c, i) in table.tableColumns.order"
|
||||
show-overflow-tooltip
|
||||
:key="i"
|
||||
:label="$t(chartTableColumnMapping[c] || c)"
|
||||
:label="$t(chartTableColumnMapping[c])"
|
||||
:prop="c"
|
||||
>
|
||||
<template #header>{{$t(chartTableColumnMapping[c] || c)}}</template>
|
||||
<template #header>{{$t(chartTableColumnMapping[c])}}</template>
|
||||
<template #default="{ row }">
|
||||
<span v-if="c === 'bytes'">
|
||||
{{unitConvert(row[c], unitTypes.byte).join(' ')}}
|
||||
@@ -31,12 +31,6 @@
|
||||
<span v-else-if="c === 'packets' || c === 'sessions'">
|
||||
{{unitConvert(row[c], unitTypes.number).join(' ')}}
|
||||
</span>
|
||||
<span v-else-if="c === 'responseFailRate'">
|
||||
{{unitConvert(row[c], unitTypes.percent).join(' ')}}
|
||||
</span>
|
||||
<span v-else-if="c === 'dnsLatency'">
|
||||
{{unitConvert(row[c], unitTypes.time).join(' ')}}
|
||||
</span>
|
||||
<span v-else>
|
||||
{{row[c]}}
|
||||
</span>
|
||||
|
||||
@@ -19,16 +19,17 @@ export default {
|
||||
name: 'ChartTablePagination',
|
||||
props: {
|
||||
total: Number,
|
||||
pageSizeForAlarm: Number
|
||||
pageSizeForAlarm:Number
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
pageSize: this.pageSizeForAlarm ? this.pageSizeForAlarm : chartTableDefaultPageSize,
|
||||
pageSize: this.pageSizeForAlarm?this.pageSizeForAlarm:chartTableDefaultPageSize,
|
||||
pageNo: 1
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
totalPage () {
|
||||
console.log(this.total,this.pageSize);
|
||||
const remainder = this.total % this.pageSize
|
||||
if (remainder) {
|
||||
return parseInt(this.total / this.pageSize) + 1
|
||||
@@ -37,14 +38,6 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
pageSizeForAlarm: {
|
||||
deep: true
|
||||
},
|
||||
total: {
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
current (val) {
|
||||
this.$emit('pageJump', val)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
:ref="`chart-${chartInfo.id}`"
|
||||
>
|
||||
<el-tab-pane
|
||||
v-for="tab in dataList"
|
||||
v-for="tab in chartInfo.children"
|
||||
:label="tab.i18n ? $t(tab.i18n) : tab.name" :name="`${tab.id}`"
|
||||
:key="tab.id"
|
||||
:ref="`chart-${chartInfo.id}`"
|
||||
@@ -29,6 +29,14 @@ import chartMixin from '@/views/charts/charts/chart-mixin'
|
||||
|
||||
export default {
|
||||
name: 'ChartTabs',
|
||||
computed: {
|
||||
timeFilter () {
|
||||
return {
|
||||
startTime: this.queryParams.startTime,
|
||||
endTime: this.queryParams.endTime
|
||||
}
|
||||
}
|
||||
},
|
||||
mixins: [chartMixin],
|
||||
methods: {
|
||||
showFullscreen () {
|
||||
@@ -36,9 +44,6 @@ export default {
|
||||
},
|
||||
changeTab (tab) {
|
||||
this.activeTab = tab.paneName
|
||||
},
|
||||
reload () {
|
||||
this.dataList = _.cloneDeep(this.dataList)
|
||||
}
|
||||
},
|
||||
setup (props) {
|
||||
@@ -46,10 +51,8 @@ export default {
|
||||
if (!_.isEmpty(props.chartInfo.children)) {
|
||||
activeTab = `${props.chartInfo.children[0].id}`
|
||||
}
|
||||
const dataList = [...props.chartInfo.children]
|
||||
return {
|
||||
activeTab,
|
||||
dataList
|
||||
activeTab
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
<template>
|
||||
<div class="cn-chart__two-situation-statistics">
|
||||
<div class="chart-two-situation-statistics">
|
||||
<div
|
||||
class="two-situation-statistics__box"
|
||||
v-for="(value, key,index) in result ? result : []"
|
||||
class="situation-statistics-main"
|
||||
v-for="(value, index) in chartData"
|
||||
:key="index"
|
||||
>
|
||||
<div class="box__body">
|
||||
<div class="body__progress">
|
||||
<div class="situation-statistics-top">
|
||||
<div class="situation-statistics-main-left">
|
||||
<el-progress
|
||||
type="circle"
|
||||
:color="chartInfo.params.color[index]"
|
||||
:color="chartInfo.params.color[0]"
|
||||
width="76"
|
||||
:percentage="value.percent ? value.percent : 0"
|
||||
:percentage="value.percent"
|
||||
/>
|
||||
</div>
|
||||
<div class="body__count">
|
||||
<div>{{ value.count ? value.count : '-' }}</div>
|
||||
<div>{{ $t(`dns.numberOfNodesSupporting${key}Protocol`) }}</div>
|
||||
<div class="situation-statistics-main-right">
|
||||
<div>{{ value.count }}</div>
|
||||
<div>{{ $t(`dns.numberOfNodesSupporting${index}Protocol`)}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -28,21 +28,8 @@ export default {
|
||||
name: 'ChartTwoSituationStatistics',
|
||||
props: {
|
||||
chartInfo: Object,
|
||||
chartData: [Array, Object]
|
||||
chartData: [Array, Object],
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
result: {
|
||||
doh: {
|
||||
count: 111,
|
||||
percent: 0.85
|
||||
},
|
||||
dot: {
|
||||
count: 111,
|
||||
percent: 80.85
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,21 +1,12 @@
|
||||
<template>
|
||||
<div class="cn-chart__ip-basic">
|
||||
<div class="cn-chart__ip-basic-info">
|
||||
<el-descriptions :column="1">
|
||||
<el-descriptions-item label="ASN:">{{(chartData && chartData.asn) || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item label="AS Org:">{{(chartData && chartData.asOrganization) || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('entities.asSubnet') + ':'">{{(chartData && chartData.asSubnet) || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item label="ISP:">{{(chartData && chartData.isp) || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item label="DNS PTR:">{{(chartData && chartData.dnsPtr) || '-'}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions :column="1" v-if="detectionsData.dnsServerRole">
|
||||
<el-descriptions-item :label="$t('overall.dnsServerInfo.role') + ':'">{{$_.get(detectionsData, 'dnsServerRole') || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('overall.dnsServerInfo.mechanism') + ':'">{{$_.get(detectionsData, 'dnsServerOrg') || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('overall.dnsServerInfo.software') + ':'">{{$_.get(detectionsData, 'dnsServerSoftware') || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('overall.dnsServerInfo.system') + ':'">{{$_.get(detectionsData, 'dnsServerOs') || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('overall.dnsServerInfo.protocol') + ':'">{{detectionIpSupporting(detectionsData)}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
<el-descriptions :column="1">
|
||||
<el-descriptions-item label="ASN:">{{(chartData && chartData.asn) || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item label="AS Org:">{{(chartData && chartData.asOrganization) || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('entities.asSubnet') + ':'">{{(chartData && chartData.asSubnet) || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item label="ISP:">{{(chartData && chartData.isp) || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item label="DNS PTR:">{{(chartData && chartData.dnsPtr) || '-'}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div class="chart-location">
|
||||
<el-descriptions :column="1">
|
||||
<el-descriptions-item :label="$t('overall.location') + ':'">{{location}}</el-descriptions-item>
|
||||
@@ -31,22 +22,18 @@ import * as L from 'leaflet'
|
||||
import icon from 'leaflet/dist/images/marker-icon.png'
|
||||
import iconShadow from 'leaflet/dist/images/marker-shadow.png'
|
||||
import 'leaflet/dist/leaflet.css'
|
||||
import { get } from '@/utils/http'
|
||||
import { api } from '@/utils/api'
|
||||
|
||||
export default {
|
||||
name: 'IpBasicInfo',
|
||||
mixins: [chartMixin],
|
||||
data () {
|
||||
return {
|
||||
myChart: null,
|
||||
mapPictureUrl: '/Tiles/{z}/{x}/{y}.png',
|
||||
entityDetectionsIpUrl: api.entityDetectionsIp,
|
||||
detectionsData: {}
|
||||
mapPictureUrl: '/Tiles/{z}/{x}/{y}.png'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
location () {
|
||||
this.$_.get()
|
||||
let location = ''
|
||||
if (this.chartInfo) {
|
||||
if (this.chartInfo.country) {
|
||||
@@ -70,25 +57,6 @@ export default {
|
||||
}
|
||||
}
|
||||
return location
|
||||
},
|
||||
detectionIpSupporting () {
|
||||
return function (detectionsData) {
|
||||
let result = ''
|
||||
if (detectionsData.dnssecSupport) {
|
||||
result += 'DNSSec/'
|
||||
}
|
||||
if (detectionsData.dohSupport) {
|
||||
result += 'DoH/'
|
||||
}
|
||||
if (detectionsData.dotSupport) {
|
||||
result += 'Dot/'
|
||||
}
|
||||
result = result.substr(0, result.length - 1)
|
||||
if (!result) {
|
||||
result = '-'
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -133,20 +101,8 @@ export default {
|
||||
})
|
||||
L.marker([this.chartData.latitude, this.chartData.longitude], { icon: myIcon }).addTo(this.myChart)
|
||||
}
|
||||
},
|
||||
queryDetection () {
|
||||
get(this.entityDetectionsIpUrl, this.queryParams).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.detectionsData = response.data.result
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.$nextTick(() => {
|
||||
this.queryDetection()
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
chartData: {
|
||||
deep: true,
|
||||
|
||||
@@ -5,17 +5,13 @@
|
||||
<div class="table__below-title">Name</div>
|
||||
<div class="table__below-statistics">Avg</div>
|
||||
<div class="table__below-statistics">Max</div>
|
||||
<div class="table__below-statistics">P50</div>
|
||||
<div class="table__below-statistics">P90</div>
|
||||
</div>
|
||||
<div class="chart__table-below">
|
||||
<div v-for="(item, index) in data" :key="index" class="table-below-box" :class="{'table-below-box--inactivated': !item.active}" @click="toggleLegend(index)">
|
||||
<div class="table__below-color"><div :style="{backgroundColor: getChartColor(index)}"></div></div>
|
||||
<div class="table__below-title" :title="item.legend">{{item.legend}}</div>
|
||||
<div class="table__below-statistics" :title="valueToRangeValue(item.aggregation.avg, chartInfo.params.unitType).join('')">{{valueToRangeValue(item.aggregation.avg, chartInfo.params.unitType).join('')}}</div>
|
||||
<div class="table__below-statistics" :title="valueToRangeValue(item.aggregation.max, chartInfo.params.unitType).join('')">{{valueToRangeValue(item.aggregation.max, chartInfo.params.unitType).join('')}}</div>
|
||||
<div class="table__below-statistics" :title="valueToRangeValue(item.aggregation.p50, chartInfo.params.unitType).join('')">{{valueToRangeValue(item.aggregation.p50, chartInfo.params.unitType).join('')}}</div>
|
||||
<div class="table__below-statistics" :title="valueToRangeValue(item.aggregation.p90, chartInfo.params.unitType).join('')">{{valueToRangeValue(item.aggregation.p90, chartInfo.params.unitType).join('')}}</div>
|
||||
<div class="table__below-statistics" :title="item.aggregation.avg">{{valueToRangeValue(item.aggregation.avg, chartInfo.params.unitType).join(' ')}}</div>
|
||||
<div class="table__below-statistics" :title="item.aggregation.max">{{valueToRangeValue(item.aggregation.max, chartInfo.params.unitType).join(' ')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -31,8 +31,7 @@ export default {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
chartOption: null,
|
||||
chartOption2: null
|
||||
chartOption: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -42,7 +41,6 @@ export default {
|
||||
const dom2 = document.getElementById(id + '-1')
|
||||
!this.myChart && (this.myChart = echarts.init(dom))
|
||||
!this.myChart2 && (this.myChart2 = echarts.init(dom2))
|
||||
this.chartOption2 = this.$_.cloneDeep(getOption(this.chartInfo.type))
|
||||
} else {
|
||||
const dom = document.getElementById(id)
|
||||
!this.myChart && (this.myChart = echarts.init(dom))
|
||||
@@ -77,23 +75,13 @@ export default {
|
||||
return allZero
|
||||
}
|
||||
},
|
||||
loadEchart (chartNum, refresh = false) {
|
||||
loadEchart (chartNum) {
|
||||
this.$emit('showLoading', true)
|
||||
try {
|
||||
this.myChart.setOption(this.chartOption, refresh)
|
||||
this.$store.commit('setChartList', this.$_.cloneDeep(this.myChart))
|
||||
this.myChart.setOption(this.chartOption)
|
||||
if (chartNum && chartNum == 2) {
|
||||
this.myChart2.setOption(this.chartOption2, refresh)
|
||||
this.$store.commit('setChartList', this.$_.cloneDeep(this.myChart2))
|
||||
this.myChart2.setOption(this.chartOption)
|
||||
}
|
||||
const _this = this
|
||||
window.addEventListener('resize', function () {
|
||||
_this.$store.getters.getChartList.forEach(chart => {
|
||||
if (chart) {
|
||||
chart.resize()
|
||||
}
|
||||
})
|
||||
})
|
||||
} finally {
|
||||
setTimeout(() => {
|
||||
this.$emit('showLoading', false)
|
||||
|
||||
@@ -3,7 +3,6 @@ export default {
|
||||
chartInfo: Object,
|
||||
chartData: [Object, Array, String], // 数据在父组件查询后传入,本组件内不查询,只根据接传递的数据来渲染
|
||||
entity: Object,
|
||||
timeFilter: Object,
|
||||
queryParams: Object // 接口请求参数
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
<template>
|
||||
<el-pagination
|
||||
small
|
||||
ref="pagination"
|
||||
:current-page="pageObj.pageNo"
|
||||
:page-size="pageObj.pageSize"
|
||||
layout="total,prev,jumper,slot,next"
|
||||
class="chart-table-pagination"
|
||||
:total="pageObj.total"
|
||||
@current-change="currentChange"
|
||||
>
|
||||
<span>/ {{totalPage}}</span>
|
||||
</el-pagination>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'chartDetectionPagination',
|
||||
props: {
|
||||
pageObj: Object
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
totalPage () {
|
||||
const remainder = this.pageObj.total % this.pageObj.pageSize
|
||||
if (remainder) {
|
||||
return parseInt(this.pageObj.total / this.pageObj.pageSize) + 1
|
||||
} else {
|
||||
return parseInt(this.pageObj.total / this.pageObj.pageSize)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
currentChange: function (val) {
|
||||
this.$emit('pageJump', val)
|
||||
this.pageObj.pageNo = val
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.$el.querySelector('.el-pagination__jump').childNodes[0].nodeValue = ''
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,85 +0,0 @@
|
||||
<template>
|
||||
<div class="security cn-detection--list">
|
||||
<div class="cn-detection-table">
|
||||
<chart-detections-table
|
||||
v-for="(data, index) in chartData"
|
||||
:detection="data"
|
||||
:timeFilter="timeFilter"
|
||||
:key="index"
|
||||
:security="true"
|
||||
:ref="`detectionRow${index}`"
|
||||
:index="index"
|
||||
></chart-detections-table>
|
||||
</div>
|
||||
<div class="cn-detection__footer">
|
||||
<chart-detection-pagination
|
||||
ref="pagination"
|
||||
:page-obj="pageObj"
|
||||
@pageJump="pageJump"
|
||||
:pageSizeForAlarm="pageObj.pageSize"
|
||||
></chart-detection-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import chartDetectionsTable from '@/views/charts/charts/chartDetectionsTable'
|
||||
import chartDetectionPagination from '@/views/charts/charts/chartDetectionPagination'
|
||||
import { get } from '@/utils/http'
|
||||
import { replaceUrlPlaceholder } from '@/utils/tools'
|
||||
export default {
|
||||
name: 'chartDetectionSecurity',
|
||||
props: {
|
||||
chartInfo: Object,
|
||||
chartData: Array,
|
||||
resultType: Object,
|
||||
queryParams: Object,
|
||||
timeFilter: Object
|
||||
},
|
||||
components: {
|
||||
chartDetectionPagination,
|
||||
chartDetectionsTable
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
pageObj: {
|
||||
pageNo: 1,
|
||||
pageSize: 6,
|
||||
total: 0,
|
||||
resetPageNo: true
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
securityCount () {
|
||||
const requestUrl = this.chartInfo.params.countUrl
|
||||
get(replaceUrlPlaceholder(requestUrl, this.queryParams)).then(response => {
|
||||
this.pageObj.total = response.data.result
|
||||
})
|
||||
},
|
||||
getDetectionData (val) {
|
||||
this.pageObj.pageNo = val
|
||||
const extraParams = {
|
||||
pageNo: val,
|
||||
pageSize: this.pageSize
|
||||
}
|
||||
this.$emit('getDetectionData', this.chartInfo.params.url, extraParams, false, {
|
||||
startTime: this.queryParams.startTime,
|
||||
endTime: this.queryParams.endTime
|
||||
})
|
||||
const requestUrl = this.chartInfo.params.countUrl
|
||||
get(replaceUrlPlaceholder(requestUrl, this.queryParams)).then(response => {
|
||||
this.pageObj.total = response.data.result
|
||||
})
|
||||
},
|
||||
pageJump (val) {
|
||||
this.getDetectionData(val)
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.securityCount()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user