CN-1396 intelligence learnings更新记录功能开发
This commit is contained in:
@@ -1676,7 +1676,8 @@ height:300px !important;
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding-bottom:0 !important;
|
padding-bottom:0 !important;
|
||||||
width: 1080px !important;
|
width: 1080px !important;
|
||||||
height: 75vh;
|
height: 90vh;
|
||||||
|
margin-top:5vh !important;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
&.update-knowledge--upload {
|
&.update-knowledge--upload {
|
||||||
height: auto;
|
height: auto;
|
||||||
@@ -1730,6 +1731,79 @@ height:300px !important;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.knowledge-update__tab {
|
||||||
|
position:relative;
|
||||||
|
.update-log-tab {
|
||||||
|
.el-tabs__header {
|
||||||
|
margin-bottom:10px;
|
||||||
|
.el-tabs__active-bar {
|
||||||
|
background-color:#046ECA;
|
||||||
|
height:2px;
|
||||||
|
}
|
||||||
|
.el-tabs__item {
|
||||||
|
font-family: NotoSansSC-Bold;
|
||||||
|
font-size: 14px;
|
||||||
|
//color: #353636;
|
||||||
|
font-weight: 700;
|
||||||
|
padding:0 16px 0 0;
|
||||||
|
}
|
||||||
|
.el-tabs__item:hover {
|
||||||
|
color:#353636;
|
||||||
|
}
|
||||||
|
.el-tabs__item.is-active {
|
||||||
|
color: #046ECA;
|
||||||
|
}
|
||||||
|
.el-tabs__nav-wrap::after {
|
||||||
|
height:1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.update-title {
|
||||||
|
line-height: 14px;
|
||||||
|
font-family: NotoSansSC-Bold;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #353636;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.update-operate {
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
right: 0px;
|
||||||
|
|
||||||
|
height:28px;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content:center;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
.top-tool-btn--update {
|
||||||
|
background-color: #38ACD2 !important;
|
||||||
|
padding-left:7px;
|
||||||
|
padding-right:7px;
|
||||||
|
color:#FFFFFF;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
border: 1px solid rgba(46,136,166,0.85);
|
||||||
|
border-radius: 2px;
|
||||||
|
line-height: 28px;
|
||||||
|
height:28px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
i {
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-size:14px !important;
|
||||||
|
margin-right:5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.top-tool-btn--update:hover {
|
||||||
|
background-color: #57B8D9 !important;
|
||||||
|
border-color: #2E88A6 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.knowledge-update {
|
.knowledge-update {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@@ -1820,13 +1894,14 @@ height:300px !important;
|
|||||||
.update-dialog__table {
|
.update-dialog__table {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
border-radius: 0.28571rem;
|
border-radius: 0.28571rem;
|
||||||
max-height:calc(75vh - 190px);
|
height:calc(90vh - 190px - 200px - 50px - 10px);//dialog为屏幕的90% - 表格以上内容的高度 - pishon3柱状图的高度 - 表格和柱状图之间的距离 - 底部留白的距离
|
||||||
|
max-height:calc(90vh - 190px - 200px - 50px - 10px);
|
||||||
|
//min-height:250px;
|
||||||
.el-table--border th, .el-table--border td {
|
.el-table--border th, .el-table--border td {
|
||||||
border-right: none;
|
border-right: none;
|
||||||
}
|
}
|
||||||
.el-table__body-wrapper {
|
.el-table__body-wrapper {
|
||||||
height:fit-content;
|
max-height: calc(90vh - 230px - 200px - 50px - 10px);
|
||||||
max-height: calc(75vh - 230px);
|
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1902,6 +1977,155 @@ height:300px !important;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.psiphon3{
|
||||||
|
display:flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-top:25px;
|
||||||
|
.psiphon3-title {
|
||||||
|
font-family: NotoSansSC-Medium;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #353636;
|
||||||
|
letter-spacing: 0;
|
||||||
|
line-height: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.psiphon3-bar {
|
||||||
|
height: 200px;
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
border: 1px solid #E2E5EC;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-top:10px;
|
||||||
|
//min-height:250px;
|
||||||
|
.chart-drawing {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
.echarts-tooltip.echarts-tooltip-dark {
|
||||||
|
.cn-chart-body {
|
||||||
|
display: flex;
|
||||||
|
.cn-chart-tooltip {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
.cn-chart-tooltip-box {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.cn-chart-tooltip-value.cn-chart-tooltip__color {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #353636;
|
||||||
|
line-height: 21px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bar-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
//height: 73px;
|
||||||
|
margin-right:20px;
|
||||||
|
.bar-select.bar-header-right {
|
||||||
|
display: flex;
|
||||||
|
//flex: 1;
|
||||||
|
.bar-select__operation {
|
||||||
|
.el-input__inner {
|
||||||
|
width: 132px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bar-select-time {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
.bar-select__operation {
|
||||||
|
height: 24px;
|
||||||
|
margin-left: 3px;
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 2px;
|
||||||
|
.cn-icon-Data {
|
||||||
|
color: #353636;
|
||||||
|
}
|
||||||
|
.el-input__inner {
|
||||||
|
padding-left: 4px;
|
||||||
|
line-height: 24px;
|
||||||
|
height: 24px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #353636;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
.el-input__suffix {
|
||||||
|
display: flex;
|
||||||
|
.el-input__suffix-inner {
|
||||||
|
line-height: 24px;
|
||||||
|
.el-select__caret {
|
||||||
|
line-height: 24px;
|
||||||
|
width: 16px;
|
||||||
|
color: #353636;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bar-header-left {
|
||||||
|
.bar-value-active {
|
||||||
|
position: absolute;
|
||||||
|
height: 4px;
|
||||||
|
border-radius: 4px 0 0 0;
|
||||||
|
background: #046ECA;
|
||||||
|
top: 0;
|
||||||
|
z-index: 1;
|
||||||
|
transition: all linear .2s;
|
||||||
|
}
|
||||||
|
.bar-value {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #717171;
|
||||||
|
font-weight: 400;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
.is-active {
|
||||||
|
color: #353636;
|
||||||
|
}
|
||||||
|
.bar-value-tabs.mousemove-cursor {
|
||||||
|
border-top: 4px solid #D3D0D8;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
.bar-value-tabs {
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 16px 0 0 20px;
|
||||||
|
border-top: 4px solid transparent;
|
||||||
|
width:88px;
|
||||||
|
.bar-value-tabs-name {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
.tabs-name {
|
||||||
|
flex: 1;
|
||||||
|
padding-left: 19px;
|
||||||
|
}
|
||||||
|
.total,.active,.new {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
border-radius: 50%;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
margin-top: -7px;
|
||||||
|
}
|
||||||
|
.total {
|
||||||
|
background: #00A7AB;
|
||||||
|
}
|
||||||
|
.active {
|
||||||
|
background: #7FA054;
|
||||||
|
}
|
||||||
|
.new {
|
||||||
|
background: #98709B;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
.knowledge-color {
|
.knowledge-color {
|
||||||
display:flex;
|
display:flex;
|
||||||
|
|||||||
@@ -122,7 +122,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import table from '@/mixins/table'
|
import table from '@/mixins/table'
|
||||||
import { knowledgeBaseCategory, knowledgeBaseSource, knowledgeBaseColor } from '@/utils/constants'
|
import { knowledgeBaseCategory, knowledgeBaseSource } from '@/utils/constants'
|
||||||
export default {
|
export default {
|
||||||
name: 'KnowledgeBaseTableForRow',
|
name: 'KnowledgeBaseTableForRow',
|
||||||
props: {
|
props: {
|
||||||
@@ -200,7 +200,23 @@ export default {
|
|||||||
width: 80
|
width: 80
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
knowledgeBaseColor
|
knowledgeBaseColor: [
|
||||||
|
{
|
||||||
|
label: this.$t('knowledge.info'),
|
||||||
|
value: 'rgb(119,131,145)',
|
||||||
|
name: 'info'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('knowledge.benign'),
|
||||||
|
value: 'rgb(116,159,77)',
|
||||||
|
name: 'benign'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('knowledge.malicious'),
|
||||||
|
value: 'rgb(226,97,84)',
|
||||||
|
name: 'malicious'
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@@ -235,14 +251,14 @@ export default {
|
|||||||
},
|
},
|
||||||
colorText () {
|
colorText () {
|
||||||
return function (color) {
|
return function (color) {
|
||||||
const t = knowledgeBaseColor.find(t => t.value === color)
|
const t = this.knowledgeBaseColor.find(t => t.value === color)
|
||||||
return t ? t.label : knowledgeBaseColor[0].label
|
return t ? t.label : this.knowledgeBaseColor[0].label
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
colorName () {
|
colorName () {
|
||||||
return function (color) {
|
return function (color) {
|
||||||
const t = knowledgeBaseColor.find(t => t.value === color)
|
const t = this.knowledgeBaseColor.find(t => t.value === color)
|
||||||
return t ? t.name : knowledgeBaseColor[0].name
|
return t ? t.name : this.knowledgeBaseColor[0].name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,6 @@
|
|||||||
<div class="card-title-name" :title="updateKnowledge.label">{{updateKnowledge.label}}</div>
|
<div class="card-title-name" :title="updateKnowledge.label">{{updateKnowledge.label}}</div>
|
||||||
</div>
|
</div>
|
||||||
<el-switch v-model="updateKnowledge.status"
|
<el-switch v-model="updateKnowledge.status"
|
||||||
v-if="showEnable"
|
|
||||||
active-color="#38ACD2"
|
active-color="#38ACD2"
|
||||||
inactive-color="#C0CEDB"
|
inactive-color="#C0CEDB"
|
||||||
:active-value="1"
|
:active-value="1"
|
||||||
@@ -91,9 +90,33 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="!showAddUpdateDialog">
|
<template v-if="!showAddUpdateDialog">
|
||||||
<div class="knowledge-update" >
|
<div class="knowledge-update__tab" v-if="showEnable">
|
||||||
<div class="update-title">
|
<el-tabs v-model="activeTab"
|
||||||
<div class="card-title-name">update record</div>
|
class="update-log-tab"
|
||||||
|
@tab-click="handleClick"
|
||||||
|
>
|
||||||
|
<el-tab-pane :label="$t('knowledgeBase.updateRecord')"
|
||||||
|
name="updateRecord"
|
||||||
|
key="updateRecord"
|
||||||
|
ref="knowledgeUpdateRecordTab">
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane :label="$t('knowledgeBase.learningEngineLogs')"
|
||||||
|
name="intelligenceLearning"
|
||||||
|
key="intelligenceLearning"
|
||||||
|
ref="knowledgeIntelligenceLearningTab">
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<div class="update-operate">
|
||||||
|
<button :title="$t('overall.update')" class="top-tool-btn--update"
|
||||||
|
@click="uploadRecord">
|
||||||
|
<i class="cn-icon-update-knowledge-base cn-icon"></i>
|
||||||
|
<span>{{$t('overall.update')}}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="knowledge-update" v-else>
|
||||||
|
<div class="update-title" >
|
||||||
|
<div class="card-title-name">{{$t('knowledgeBase.updateRecord')}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="update-operate">
|
<div class="update-operate">
|
||||||
<button :title="$t('overall.update')" class="top-tool-btn--update"
|
<button :title="$t('overall.update')" class="top-tool-btn--update"
|
||||||
@@ -120,6 +143,56 @@
|
|||||||
<el-table-column prop="commitVersion" label="Version information" width="150" ></el-table-column>
|
<el-table-column prop="commitVersion" label="Version information" width="150" ></el-table-column>
|
||||||
<el-table-column prop="description" label="Description"></el-table-column>
|
<el-table-column prop="description" label="Description"></el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
|
<div class="psiphon3">
|
||||||
|
<div class="psiphon3-title">{{$t('knowledgeBase.psiphon3IpCount')}}</div>
|
||||||
|
<div class="psiphon3-bar">
|
||||||
|
<chart-error v-if="showErrorForPsiphon3" :content="errorMsgForPsiphon3"/>
|
||||||
|
<div class="bar-header" v-if="!showErrorForPsiphon3">
|
||||||
|
<div class="bar-header-left">
|
||||||
|
<div class="bar-value-active" ></div>
|
||||||
|
<div class="bar-value">
|
||||||
|
<template v-for="(item, index) in tabs" :key="index">
|
||||||
|
<div class="bar-value-tabs"
|
||||||
|
:class=" {'is-active': tabType === item.class, 'mousemove-cursor': mousemoveCursor === item.class}"
|
||||||
|
@mouseenter="mouseenterTab(item)"
|
||||||
|
@mouseleave="mouseleaveTab(item)"
|
||||||
|
@click="activeChange(item, index,true)"
|
||||||
|
>
|
||||||
|
<div class="bar-value-tabs-name">
|
||||||
|
<div :class="item.class"></div>
|
||||||
|
<div class="tabs-name" >{{ $t(item.name) }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bar-select bar-header-right">
|
||||||
|
<div class="bar-select-time">
|
||||||
|
<div class="bar-select__operation">
|
||||||
|
<el-select
|
||||||
|
size="mini"
|
||||||
|
v-model="selectTime"
|
||||||
|
placeholder=" "
|
||||||
|
popper-class="common-select"
|
||||||
|
:popper-append-to-body="false"
|
||||||
|
@change="timeChange()"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<div class="calendar-popover-text"><i class="cn-icon cn-icon-Data"></i></div>
|
||||||
|
</template>
|
||||||
|
<el-option v-for="item in dateRangeArr" :key="item.value" :label="item.name" :value="item.value"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="height: calc(100% - 24px); position: relative">
|
||||||
|
<chart-no-data v-if="isNoDataForPsiphon3 && !showErrorForPsiphon3"></chart-no-data>
|
||||||
|
<div class="chart-drawing" v-show="!isNoDataForPsiphon3 && !showErrorForPsiphon3" ref="psiphonBarChart"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="showAddUpdateDialog">
|
<template v-if="showAddUpdateDialog">
|
||||||
<div class="update-knowledge-form">
|
<div class="update-knowledge-form">
|
||||||
@@ -199,11 +272,14 @@
|
|||||||
<script>
|
<script>
|
||||||
import table from '@/mixins/table'
|
import table from '@/mixins/table'
|
||||||
import Loading from '@/components/common/Loading'
|
import Loading from '@/components/common/Loading'
|
||||||
|
import { getSecond } from '@/utils/date-util'
|
||||||
import { knowledgeCategoryValue, unitTypes, storageKey, builtInKnowledgeBaseBasicInfo } from '@/utils/constants'
|
import { knowledgeCategoryValue, unitTypes, storageKey, builtInKnowledgeBaseBasicInfo } from '@/utils/constants'
|
||||||
import { ref } from 'vue'
|
import { ref, shallowRef } from 'vue'
|
||||||
import { api } from '@/utils/api'
|
import { api } from '@/utils/api'
|
||||||
|
import { xAxisTimeFormatter, xAxisTimeRich } from '@/utils/date-util'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
import * as echarts from 'echarts'
|
||||||
import unitConvert from '@/utils/unit-convert'
|
import unitConvert from '@/utils/unit-convert'
|
||||||
export default {
|
export default {
|
||||||
name: 'knowledgeBaseTableForCard',
|
name: 'knowledgeBaseTableForCard',
|
||||||
@@ -236,7 +312,60 @@ export default {
|
|||||||
currentVersion: 0,
|
currentVersion: 0,
|
||||||
uploadLoading: false,
|
uploadLoading: false,
|
||||||
showConfirmSwitch: false,
|
showConfirmSwitch: false,
|
||||||
switchKnowledgeId: ''
|
switchKnowledgeId: '',
|
||||||
|
activeTab: 'updateRecord',
|
||||||
|
isNoDataForPsiphon3:false,
|
||||||
|
showErrorForPsiphon3:false,
|
||||||
|
errorMsgForPsiphon3: '',
|
||||||
|
leftOffset: 0,
|
||||||
|
tabType:'total',
|
||||||
|
mousemoveCursor:'',
|
||||||
|
selectTime:1440,
|
||||||
|
timeFilter:{},
|
||||||
|
tabs: [
|
||||||
|
{
|
||||||
|
name: 'knowledgeBase.total',
|
||||||
|
class: 'total',
|
||||||
|
color: '#00A7AB',
|
||||||
|
data: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'knowledgeBase.active',
|
||||||
|
class: 'active',
|
||||||
|
color: '#7FA054',
|
||||||
|
data: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'knowledgeBase.new',
|
||||||
|
class: 'new',
|
||||||
|
color: '#98709B',
|
||||||
|
data: [],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
dateRangeArr: [
|
||||||
|
{ value: 1440, name: this.$t('dateTime.last1Day') },
|
||||||
|
{ value: 2880, name: this.$t('dateTime.last2Days') },
|
||||||
|
{ value: 10080, name: this.$t('dateTime.last7Days') },
|
||||||
|
{ value: 21600, name: this.$t('dateTime.last15Days') },
|
||||||
|
{ value: 43200, name: this.$t('dateTime.last30Days') },
|
||||||
|
],
|
||||||
|
tabsTemplate:[
|
||||||
|
{
|
||||||
|
name: 'knowledgeBase.total',
|
||||||
|
class: 'total',
|
||||||
|
data: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'knowledgeBase.active',
|
||||||
|
class: 'active',
|
||||||
|
data: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'knowledgeBase.new',
|
||||||
|
class: 'new',
|
||||||
|
data: [],
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setup () {
|
setup () {
|
||||||
@@ -251,10 +380,227 @@ export default {
|
|||||||
uploadErrorTip,
|
uploadErrorTip,
|
||||||
fileTypeLimit: '.csv',
|
fileTypeLimit: '.csv',
|
||||||
fileList: ref([]),
|
fileList: ref([]),
|
||||||
uploadFileSizeLimit: 1024 * 1024 * 1024
|
uploadFileSizeLimit: 1024 * 1024 * 1024,
|
||||||
|
myChart: shallowRef(null),
|
||||||
|
chartOption: shallowRef(null)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
echartsInit(echartsData){
|
||||||
|
echartsData = [
|
||||||
|
[1698318076,15],[1698338076,2],[1698358076,15],[1698378076,7],[1698398076,11],[1698418076,12],[1698438076,15],[1698458076,5]
|
||||||
|
]
|
||||||
|
const _this = this
|
||||||
|
let curTab = this.tabs.find(item => item.class === _this.tabType)
|
||||||
|
this.chartOption = {
|
||||||
|
color:curTab.color,
|
||||||
|
legend: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
show:true,
|
||||||
|
/*formatter: function (item) {
|
||||||
|
|
||||||
|
let str = '<div style="display:flex;flex-direction: row;align-items: center;">'
|
||||||
|
str += '<div style="width: 8px;\n' +
|
||||||
|
' height: 8px;\n' +
|
||||||
|
' margin: 3px 8px 0 0;\n' +
|
||||||
|
' border-radius: 1px;;background:'
|
||||||
|
str += item.color
|
||||||
|
str += ';"></div>'
|
||||||
|
str += item.name + ': ' + xAxisTimeFormatter(item.data[0]) + ' ' + item.data[1]
|
||||||
|
str += '</div>'
|
||||||
|
str += '</div>'
|
||||||
|
return item.data[1]
|
||||||
|
}*/
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
top: '12%',
|
||||||
|
left: '2%',
|
||||||
|
right: '2%',
|
||||||
|
bottom: 24,
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'time',
|
||||||
|
boundaryGap: ['1%', '3%'],
|
||||||
|
axisLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
formatter: xAxisTimeFormatter,
|
||||||
|
rich: xAxisTimeRich,
|
||||||
|
interval:0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: '#ECECEC'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
margin: 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name:curTab.class,
|
||||||
|
data: echartsData,
|
||||||
|
type: 'bar',
|
||||||
|
barWidth: 26
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.myChart) {
|
||||||
|
this.myChart.dispose()
|
||||||
|
}
|
||||||
|
this.myChart = echarts.init(this.$refs.psiphonBarChart)
|
||||||
|
this.myChart.setOption(this.chartOption)
|
||||||
|
|
||||||
|
this.myChart.dispatchAction({
|
||||||
|
type: 'takeGlobalCursor',
|
||||||
|
key: 'brush',
|
||||||
|
brushOption: {
|
||||||
|
brushType: 'lineX',
|
||||||
|
xAxisIndex: 'all',
|
||||||
|
brushMode: 'single',
|
||||||
|
throttleType: 'debounce'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.myChart.on('brushEnd', this.brushEcharts)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
init (val, show, active, n) {
|
||||||
|
const params = {
|
||||||
|
startTime: getSecond(this.timeFilter.startTime),
|
||||||
|
endTime: getSecond(this.timeFilter.endTime),
|
||||||
|
knowledgeId: this.updateKnowledge.knowledgeId,
|
||||||
|
type: this.tabType
|
||||||
|
}
|
||||||
|
let url = api.knowledgeBaseTimedistribution.replace('{{knowledgeId}}', this.updateKnowledge.knowledgeId).replace('{{type}}', this.tabType)
|
||||||
|
this.toggleLoading(true)
|
||||||
|
axios.get(url,{ params: params }).then(response => {
|
||||||
|
const res = response.data
|
||||||
|
|
||||||
|
if (response.status === 200) {
|
||||||
|
this.isNoDataForPsiphon3 = res.data.result.length === 0
|
||||||
|
this.showErrorForPsiphon3 = false
|
||||||
|
if (this.isNoDataForPsiphon3) {
|
||||||
|
this.tabType = ''
|
||||||
|
this.tabs = _.cloneDeep(this.tabsTemplate)
|
||||||
|
} else {
|
||||||
|
this.echartsInit(res.data.result)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.httpError(res)
|
||||||
|
}
|
||||||
|
}).catch(e => {
|
||||||
|
console.error(e)
|
||||||
|
this.httpError(e)
|
||||||
|
}).finally(() => {
|
||||||
|
this.toggleLoading(false)
|
||||||
|
//this.echartsInit()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
httpError (e) {
|
||||||
|
this.isNoDataForPsiphon3 = false
|
||||||
|
this.showErrorForPsiphon3 = true
|
||||||
|
this.errorMsgForPsiphon3 = this.errorMsgHandler(e)
|
||||||
|
},
|
||||||
|
handleActiveBar () {
|
||||||
|
if (document.querySelector('.psiphon3-bar .bar-value-tabs.is-active')) {
|
||||||
|
const {
|
||||||
|
offsetLeft,
|
||||||
|
clientWidth,
|
||||||
|
clientLeft
|
||||||
|
} = document.querySelector('.psiphon3-bar .bar-value-tabs.is-active')
|
||||||
|
const activeBar = document.querySelector('.psiphon3-bar .bar-value-active')
|
||||||
|
activeBar.style.cssText += `width: ${clientWidth}px; left: ${offsetLeft + this.leftOffset + clientLeft}px;`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resize () {
|
||||||
|
if (this.myChart) {
|
||||||
|
this.myChart.resize()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* echarts框选
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
brushEcharts (params) {
|
||||||
|
this.myChart.dispatchAction({
|
||||||
|
type: 'brush',
|
||||||
|
areas: [] // 删除选框
|
||||||
|
})
|
||||||
|
if (!this.mouseDownFlag) {
|
||||||
|
// 避免点击空白区域报错
|
||||||
|
if (params.areas && params.areas.length > 0) {
|
||||||
|
this.brushHistory.unshift({
|
||||||
|
startTime: _.cloneDeep(this.timeFilter.startTime) * 1000,
|
||||||
|
endTime: _.cloneDeep(this.timeFilter.endTime) * 1000
|
||||||
|
})
|
||||||
|
|
||||||
|
const rangeObj = {
|
||||||
|
startTime: Math.ceil(params.areas[0].coordRange[0]),
|
||||||
|
endTime: Math.ceil(params.areas[0].coordRange[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
// 暂定框选最小范围为5分钟,后续可能会变动
|
||||||
|
if (rangeObj.endTime - rangeObj.startTime < 5 * 60 * 1000) {
|
||||||
|
rangeObj.startTime = rangeObj.endTime - 5 * 60 * 1000
|
||||||
|
}
|
||||||
|
this.$store.commit('setRangeEchartsData', rangeObj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dispatchSelectAction (type, name) {
|
||||||
|
this.myChart && this.myChart.dispatchAction({
|
||||||
|
type: type,
|
||||||
|
name: name
|
||||||
|
})
|
||||||
|
},
|
||||||
|
legendSelectChange (item) {
|
||||||
|
this.dispatchSelectAction('legendSelect', item.name)
|
||||||
|
this.tabs.forEach((t) => {
|
||||||
|
if (t.name !== item.name) {
|
||||||
|
this.dispatchSelectAction('legendUnSelect', t.name)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
timeChange(){
|
||||||
|
this.timeFilter.endTime = window.$dayJs.tz().valueOf()
|
||||||
|
this.timeFilter.startTime = this.timeFilter.endTime - this.selectTime.value * 60 * 1000
|
||||||
|
this.init()
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.handleActiveBar()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
activeChange (item) { // isClick:代表是通过点击操作来的
|
||||||
|
if (this.isNoDataForPsiphon3) return
|
||||||
|
if(item) {
|
||||||
|
this.tabType = item.class
|
||||||
|
}
|
||||||
|
this.legendSelectChange(item)
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
mouseenterTab (item) {
|
||||||
|
if (this.isNoDataForPsiphon3) return
|
||||||
|
this.mousemoveCursor = item.class
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.handleActiveBar()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
mouseleaveTab () {
|
||||||
|
this.mousemoveCursor = ''
|
||||||
|
},
|
||||||
fileChange (file, fileList) {
|
fileChange (file, fileList) {
|
||||||
// 判断后缀,仅支持.csv
|
// 判断后缀,仅支持.csv
|
||||||
if (!_.endsWith(file.name, '.csv')) {
|
if (!_.endsWith(file.name, '.csv')) {
|
||||||
@@ -284,10 +630,7 @@ export default {
|
|||||||
if (response.code === 200) { */
|
if (response.code === 200) { */
|
||||||
this.$message.success(this.$t('tip.success'))
|
this.$message.success(this.$t('tip.success'))
|
||||||
this.showAddUpdateDialog = false
|
this.showAddUpdateDialog = false
|
||||||
axios.get(api.knowledgeBaseLog + '/' + this.updateKnowledge.knowledgeId, { params: { pageSize: 999 } }).then(res => {
|
this.getCurTabData()
|
||||||
this.updateHistoryList = res.data.data.list
|
|
||||||
this.currentVersion = this.updateHistoryList[0].commitVersion + 1
|
|
||||||
})
|
|
||||||
/* } else {
|
/* } else {
|
||||||
this.$message.error(this.$t('tip.uploadFailed', { msg: response.message }))
|
this.$message.error(this.$t('tip.uploadFailed', { msg: response.message }))
|
||||||
} */
|
} */
|
||||||
@@ -337,13 +680,14 @@ export default {
|
|||||||
this.showUpdateDialog = true
|
this.showUpdateDialog = true
|
||||||
this.showAddUpdateDialog = false
|
this.showAddUpdateDialog = false
|
||||||
},
|
},
|
||||||
jumpToUpdatePage (data, showEnable) {
|
async jumpToUpdatePage (data, showEnable) {
|
||||||
axios.get(api.knowledgeBaseLog + '/' + data.knowledgeId, { params: { pageSize: 999 } }).then(res => {
|
this.updateKnowledge = data
|
||||||
this.updateKnowledge = data
|
this.showEnable = showEnable
|
||||||
this.updateHistoryList = res.data.data.list
|
await this.getCurTabData()
|
||||||
this.currentVersion = this.updateHistoryList[0].commitVersion + 1
|
await this.init()
|
||||||
this.showEnable = showEnable
|
this.showUpdate()
|
||||||
this.showUpdate()
|
this.$nextTick(() => {
|
||||||
|
this.handleActiveBar()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
uploadRecord () {
|
uploadRecord () {
|
||||||
@@ -352,6 +696,35 @@ export default {
|
|||||||
this.updateObject.label = this.updateKnowledge.label
|
this.updateObject.label = this.updateKnowledge.label
|
||||||
this.updateObject.description = ''
|
this.updateObject.description = ''
|
||||||
},
|
},
|
||||||
|
getCurTabData(){//showEnable:true 为psiphon3的知识库,false为其它知识库
|
||||||
|
let params = {
|
||||||
|
pageSize: 999
|
||||||
|
}
|
||||||
|
if(this.showEnable) {
|
||||||
|
if(this.activeTab === 'updateRecord'){
|
||||||
|
params = {
|
||||||
|
...params,
|
||||||
|
opUser:-1
|
||||||
|
}
|
||||||
|
} else if(this.activeTab === 'intelligenceLearning'){
|
||||||
|
params = {
|
||||||
|
...params,
|
||||||
|
opUser:0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
axios.get(api.knowledgeBaseLog + '/' + this.updateKnowledge.knowledgeId, { params: params }).then(res => {
|
||||||
|
this.updateHistoryList = res.data.data.list
|
||||||
|
if(this.updateHistoryList[0]) {
|
||||||
|
this.currentVersion = this.updateHistoryList[0].commitVersion + 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 切换tab
|
||||||
|
handleClick (tab) {
|
||||||
|
let activeTab = tab.panelName
|
||||||
|
this.getCurTabData()
|
||||||
|
},
|
||||||
clearSelect () {
|
clearSelect () {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.checkList = []
|
this.checkList = []
|
||||||
@@ -410,6 +783,19 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
tabType (n) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.handleActiveBar()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
timeFilter: {
|
||||||
|
handler () {
|
||||||
|
this.init()
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.handleActiveBar()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
tableData: {
|
tableData: {
|
||||||
handler (n) {
|
handler (n) {
|
||||||
if (this.tableData && this.tableData.length > 0) {
|
if (this.tableData && this.tableData.length > 0) {
|
||||||
@@ -442,6 +828,10 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
this.myChart = null
|
||||||
|
this.chartOption = null
|
||||||
|
window.addEventListener('resize', this.resize)
|
||||||
|
|
||||||
this.aiTaggingList = []
|
this.aiTaggingList = []
|
||||||
this.websketchList = []
|
this.websketchList = []
|
||||||
this.tableData.forEach(item => {
|
this.tableData.forEach(item => {
|
||||||
@@ -453,6 +843,19 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
beforeUnmount () {
|
||||||
|
clearTimeout(this.timer)
|
||||||
|
window.removeEventListener('resize', this.resize)
|
||||||
|
|
||||||
|
let myChart = echarts.getInstanceByDom(this.$refs.psiphonBarChart)
|
||||||
|
if (myChart) {
|
||||||
|
echarts.dispose(myChart)
|
||||||
|
}
|
||||||
|
if (this.myChart) {
|
||||||
|
echarts.dispose(this.myChart)
|
||||||
|
}
|
||||||
|
myChart = null
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
uploadParams () {
|
uploadParams () {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ export const api = {
|
|||||||
knowledgeBaseStatistics: apiVersion + '/knowledgeBase/statistics',
|
knowledgeBaseStatistics: apiVersion + '/knowledgeBase/statistics',
|
||||||
updateKnowledgeUrl: apiVersion + '/knowledgeBase/items/batch',
|
updateKnowledgeUrl: apiVersion + '/knowledgeBase/items/batch',
|
||||||
knowledgeBaseLog: apiVersion + '/knowledgeBase/audit/log',
|
knowledgeBaseLog: apiVersion + '/knowledgeBase/audit/log',
|
||||||
|
knowledgeBaseTimedistribution: apiVersion + '/knowledgeBase/{{knowledgeId}}/{{type}}/timedistribution',
|
||||||
|
|
||||||
// 报告相关
|
// 报告相关
|
||||||
reportJob: '/report/job',
|
reportJob: '/report/job',
|
||||||
|
|||||||
@@ -346,25 +346,6 @@ export const knowledgeBaseType = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
export const knowledgeBaseColor = [
|
|
||||||
{
|
|
||||||
label: 'Info',
|
|
||||||
value: 'rgb(119,131,145)',
|
|
||||||
name: 'info'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Benign',
|
|
||||||
value: 'rgb(116,159,77)',
|
|
||||||
name: 'benign'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Malicious',
|
|
||||||
value: 'rgb(226,97,84)',
|
|
||||||
name: 'malicious'
|
|
||||||
}
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
export const knowledgeBaseCategory = [
|
export const knowledgeBaseCategory = [
|
||||||
{
|
{
|
||||||
name: 'WebSketch',
|
name: 'WebSketch',
|
||||||
|
|||||||
@@ -47,7 +47,7 @@
|
|||||||
<template v-for="color in knowledgeBaseColor" :key="color.name">
|
<template v-for="color in knowledgeBaseColor" :key="color.name">
|
||||||
<el-option :value="color.label" >
|
<el-option :value="color.label" >
|
||||||
<div class="knowledge-color">
|
<div class="knowledge-color">
|
||||||
<span class="knowledge-color__icon" :class="color.name"></span> <span>{{color.label}}</span>
|
<span class="knowledge-color__icon" :class="color.name"></span> <span>{{$t(color.label)}}</span>
|
||||||
</div>
|
</div>
|
||||||
</el-option>
|
</el-option>
|
||||||
</template>
|
</template>
|
||||||
@@ -236,7 +236,7 @@
|
|||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { nextTick, reactive, ref } from 'vue'
|
import { nextTick, reactive, ref } from 'vue'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import { knowledgeBaseType, storageKey, unitTypes, knowledgeSourceValue, itemListHeight, knowledgeCategoryValue, knowledgeBaseColor } from '@/utils/constants'
|
import { knowledgeBaseType, storageKey, unitTypes, knowledgeSourceValue, itemListHeight, knowledgeCategoryValue } from '@/utils/constants'
|
||||||
import Pagination from '@/components/common/Pagination'
|
import Pagination from '@/components/common/Pagination'
|
||||||
import ChartNoData from '@/views/charts/charts/ChartNoData'
|
import ChartNoData from '@/views/charts/charts/ChartNoData'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
@@ -515,12 +515,29 @@ export default {
|
|||||||
dataType: 'builtInList',
|
dataType: 'builtInList',
|
||||||
status: 1,
|
status: 1,
|
||||||
oldItemIds: [],
|
oldItemIds: [],
|
||||||
oldTagItem: {}
|
oldTagItem: {},
|
||||||
|
knowledgeBaseColor: [
|
||||||
|
{
|
||||||
|
label: this.$t('knowledge.info'),
|
||||||
|
value: 'rgb(119,131,145)',
|
||||||
|
name: 'info'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('knowledge.benign'),
|
||||||
|
value: 'rgb(116,159,77)',
|
||||||
|
name: 'benign'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('knowledge.malicious'),
|
||||||
|
value: 'rgb(226,97,84)',
|
||||||
|
name: 'malicious'
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
changeColor (label) {
|
changeColor (label) {
|
||||||
const curColorObj = knowledgeBaseColor.find(item => item.label === this.editObject.colorLabel)
|
const curColorObj = this.knowledgeBaseColor.find(item => item.label === this.editObject.colorLabel)
|
||||||
this.editObject.color = curColorObj.value
|
this.editObject.color = curColorObj.value
|
||||||
this.editObject.colorName = curColorObj.name
|
this.editObject.colorName = curColorObj.name
|
||||||
},
|
},
|
||||||
@@ -1216,14 +1233,14 @@ export default {
|
|||||||
}
|
}
|
||||||
this.editObject = response.data.data
|
this.editObject = response.data.data
|
||||||
if (response.data.data.color) {
|
if (response.data.data.color) {
|
||||||
const curColorObj = knowledgeBaseColor.find(item => item.value === response.data.data.color)
|
const curColorObj = this.knowledgeBaseColor.find(item => item.value === response.data.data.color)
|
||||||
this.editObject.color = curColorObj ? curColorObj.value : knowledgeBaseColor[0].value
|
this.editObject.color = curColorObj ? curColorObj.value : this.knowledgeBaseColor[0].value
|
||||||
this.editObject.colorName = curColorObj ? curColorObj.name : knowledgeBaseColor[0].name
|
this.editObject.colorName = curColorObj ? curColorObj.name : this.knowledgeBaseColor[0].name
|
||||||
this.editObject.colorLabel = curColorObj ? curColorObj.label : knowledgeBaseColor[0].label
|
this.editObject.colorLabel = curColorObj ? curColorObj.label : this.knowledgeBaseColor[0].label
|
||||||
} else {
|
} else {
|
||||||
this.editObject.color = knowledgeBaseColor[0].value
|
this.editObject.color = this.knowledgeBaseColor[0].value
|
||||||
this.editObject.colorName = knowledgeBaseColor[0].name
|
this.editObject.colorName = this.knowledgeBaseColor[0].name
|
||||||
this.editObject.colorLabel = knowledgeBaseColor[0].label
|
this.editObject.colorLabel = this.knowledgeBaseColor[0].label
|
||||||
}
|
}
|
||||||
this.importedData = this.handleSpeticalTypeData(this.editObject.itemList)
|
this.importedData = this.handleSpeticalTypeData(this.editObject.itemList)
|
||||||
this.importedData.forEach(item => {
|
this.importedData.forEach(item => {
|
||||||
@@ -1254,6 +1271,9 @@ export default {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
this.editObject.color = this.knowledgeBaseColor[0].value
|
||||||
|
this.editObject.colorName = this.knowledgeBaseColor[0].name
|
||||||
|
this.editObject.colorLabel = this.knowledgeBaseColor[0].label
|
||||||
this.stepHeightConstant.third = itemListHeight.noData// 进入新增时为250
|
this.stepHeightConstant.third = itemListHeight.noData// 进入新增时为250
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1322,9 +1342,9 @@ export default {
|
|||||||
description: '',
|
description: '',
|
||||||
updateTime: '',
|
updateTime: '',
|
||||||
status: 1,
|
status: 1,
|
||||||
color: knowledgeBaseColor[0].value,
|
color: '',
|
||||||
colorLabel: knowledgeBaseColor[0].label,
|
colorLabel: '',
|
||||||
colorName: knowledgeBaseColor[0].name
|
colorName: ''
|
||||||
}
|
}
|
||||||
/* 将组织后的数据还原拉平 */
|
/* 将组织后的数据还原拉平 */
|
||||||
const revertImportedData = (data) => {
|
const revertImportedData = (data) => {
|
||||||
@@ -1407,7 +1427,6 @@ export default {
|
|||||||
stepHeightConstant,
|
stepHeightConstant,
|
||||||
stepHeights,
|
stepHeights,
|
||||||
knowledgeBaseType,
|
knowledgeBaseType,
|
||||||
knowledgeBaseColor,
|
|
||||||
importedData,
|
importedData,
|
||||||
showImportedData,
|
showImportedData,
|
||||||
addItemList,
|
addItemList,
|
||||||
|
|||||||
Reference in New Issue
Block a user